From 9294376ea62c694c04363e0018bd496cf2850411 Mon Sep 17 00:00:00 2001 From: Georgy A. Shepelev Date: Tue, 22 Sep 2009 16:58:40 +0400 Subject: [PATCH] [PATCH] xdm: The whole widget borders width could not be set to zero. [PATCH] xdm: This 'bug' was fixed. Adding an option to show stars [PATCH] xdm: instead of the password itself. The behaviour can be [PATCH] xdm: controlled via 'xlogin*echoPasswd' option in Xresource [PATCH] xdm: file. The default option value is 'false'. Signed-off-by: Georgy A. Shepelev Tested-by: Georgy A. Shepelev --- greeter/Login.c | 227 +++++++++++++++++++++++++++++++++--------------------- greeter/Login.h | 2 + greeter/LoginP.h | 3 + greeter/greet.c | 11 ++- 4 files changed, 152 insertions(+), 91 deletions(-) diff --git a/greeter/Login.c b/greeter/Login.c index 4903ea2..27bd215 100644 --- a/greeter/Login.c +++ b/greeter/Login.c @@ -224,7 +224,9 @@ static XtResource resources[] = { {XtNallowNullPasswd, XtCAllowNullPasswd, XtRBoolean, sizeof (Boolean), offset(allow_null_passwd), XtRImmediate, (XtPointer) False}, {XtNallowRootLogin, XtCAllowRootLogin, XtRBoolean, sizeof(Boolean), - offset(allow_root_login), XtRImmediate, (XtPointer) True} + offset(allow_root_login), XtRImmediate, (XtPointer) True}, + {XtNechoPasswd, XtCEchoPasswd, XtRBoolean, sizeof(Boolean), + offset(echo_passwd), XtRImmediate, (XtPointer)False} }; #undef offset @@ -352,14 +354,35 @@ XmuXftTextWidth(Display *dpy, XftFont *font, FcChar8 *string, int len); static inline int max (int a, int b) { return a > b ? a : b; } #endif -static void -realizeValue (LoginWidget w, int cursor, int promptNum, GC gc) +static void realizeValue(LoginWidget w, int cursor, int promptNum, GC gc) { - loginPromptState state = w->login.prompts[promptNum].state; + loginPromptState state = PROMPT_STATE(w, promptNum); char *text = VALUE_TEXT(w, promptNum); int x, y, height, width, curoff; XDM_ASSERT(promptNum >= 0 && promptNum <= LAST_PROMPT); + /* replace all password characters with asterisks */ + if ((promptNum == LOGIN_PROMPT_PASSWORD) && (state == LOGIN_PROMPT_ECHO_ON)) + { + Cardinal length = strlen(text); + Cardinal i = 0; + + text = XtMalloc(length + 1); + + if (text == NULL) + { + LogOutOfMem("realizeValue"); + + return; + } + + while (i < length) + { + text[i++] = '*'; + } + + text[i] = 0; + } x = VALUE_X (w,promptNum); y = PROMPT_Y (w,promptNum); @@ -373,54 +396,69 @@ realizeValue (LoginWidget w, int cursor, int promptNum, GC gc) width -= (w->login.logoWidth + 2*(w->login.logoPadding)); #endif if (cursor > VALUE_SHOW_START(w, promptNum)) - curoff = TEXT_WIDTH (text, text, cursor); + { + curoff = TEXT_WIDTH(text, text, cursor); + } else - curoff = 0; + { + curoff = 0; + } - if (gc == w->login.bgGC) { - if (curoff < width) { - XFillRectangle (XtDisplay (w), XtWindow (w), gc, - x + curoff, y - TEXT_Y_INC(w), - width - curoff, height); - } - } else if ((state == LOGIN_PROMPT_ECHO_ON) || (state == LOGIN_TEXT_INFO)) { - int textwidth; - int offset = max(cursor, VALUE_SHOW_START(w, promptNum)); - int textlen = strlen (text + offset); - - textwidth = TEXT_WIDTH (text, text + offset, textlen); - - if (textwidth > (width - curoff)) { - /* Recalculate amount of text that can fit in field */ - offset = VALUE_SHOW_START(w, promptNum); - textlen = strlen (text + offset); - - while ((textlen > 0) && (textwidth > width)) - { - if (offset < PROMPT_CURSOR(w, promptNum)) { - offset++; + if (gc == w->login.bgGC) + { + if (curoff < width) + { + XFillRectangle(XtDisplay(w), XtWindow(w), gc, x + curoff, y - TEXT_Y_INC(w), + width - curoff, height); } - textlen--; + } + else if ((state == LOGIN_PROMPT_ECHO_ON) || (state == LOGIN_TEXT_INFO)) + { + int textwidth; + int offset = max(cursor, VALUE_SHOW_START(w, promptNum)); + int textlen = strlen(text + offset); + textwidth = TEXT_WIDTH (text, text + offset, textlen); - } - VALUE_SHOW_START(w, promptNum) = offset; - VALUE_SHOW_END(w, promptNum) = offset + textlen; + if (textwidth > (width - curoff)) + { + /* Recalculate amount of text that can fit in field */ + offset = VALUE_SHOW_START(w, promptNum); + textlen = strlen(text + offset); + + while ((textlen > 0) && (textwidth > width)) + { + if (offset < PROMPT_CURSOR(w, promptNum)) + { + offset++; + } + textlen--; + textwidth = TEXT_WIDTH(text, text + offset, textlen); + } - /* Erase old string */ - XFillRectangle (XtDisplay (w), XtWindow (w), w->login.bgGC, - x, y - TEXT_Y_INC(w), width, height); + VALUE_SHOW_START(w, promptNum) = offset; + VALUE_SHOW_END(w, promptNum) = offset + textlen; - DRAW_STRING(text, x, y, text + offset, textlen); - } else { - DRAW_STRING(text, x + curoff, y, text + offset, textlen); - } + /* Erase old string */ + XFillRectangle(XtDisplay(w), XtWindow(w), w->login.bgGC, x, y - TEXT_Y_INC(w), + width, height); + + DRAW_STRING(text, x, y, text + offset, textlen); + } + else + { + DRAW_STRING(text, x + curoff, y, text + offset, textlen); + } } + /* free memory */ + if ((promptNum == LOGIN_PROMPT_PASSWORD) && (state == LOGIN_PROMPT_ECHO_ON)) + { + XtFree(text); + } } -static void -EraseValue (LoginWidget w, int cursor, int promptNum) +static void EraseValue(LoginWidget w, int cursor, int promptNum) { realizeValue(w, cursor, promptNum, w->login.bgGC); } @@ -436,14 +474,14 @@ DrawValue (LoginWidget w, int cursor, int promptNum) #endif /* DANCING */ } -static void -realizeCursor (LoginWidget w, GC gc) +static void realizeCursor(LoginWidget w, GC gc) { int x, y; int height, width; - if (w->login.state != PROMPTING) { - return; + if (w->login.state != PROMPTING) + { + return; } x = VALUE_X (w, w->login.activePrompt); @@ -451,46 +489,54 @@ realizeCursor (LoginWidget w, GC gc) height = (F_ASCENT(text) + F_DESCENT(text)); width = 1; - switch (PROMPT_STATE(w, w->login.activePrompt)) { - case LOGIN_PROMPT_NOT_SHOWN: - case LOGIN_TEXT_INFO: - return; - case LOGIN_PROMPT_ECHO_ON: - if (CUR_PROMPT_CURSOR(w) > 0) { - x += TEXT_WIDTH (text, - VALUE_TEXT(w, w->login.activePrompt) - + VALUE_SHOW_START(w, w->login.activePrompt), - PROMPT_CURSOR(w, w->login.activePrompt) - - VALUE_SHOW_START(w, w->login.activePrompt) ); + switch (PROMPT_STATE(w, w->login.activePrompt)) + { + case LOGIN_PROMPT_NOT_SHOWN: + case LOGIN_TEXT_INFO: + return; + + case LOGIN_PROMPT_ECHO_ON: + { + if (CUR_PROMPT_CURSOR(w) > 0) + { + if (w->login.activePrompt == LOGIN_PROMPT_PASSWORD) + { + int len = PROMPT_CURSOR(w, w->login.activePrompt) - + VALUE_SHOW_START(w, w->login.activePrompt); + + x += len*TEXT_WIDTH(text, "*", 1); + } + else + { + x += TEXT_WIDTH(text, VALUE_TEXT(w, w->login.activePrompt) + + VALUE_SHOW_START(w, w->login.activePrompt), + PROMPT_CURSOR(w, w->login.activePrompt) - + VALUE_SHOW_START(w, w->login.activePrompt)); + } + } + break; + } + + case LOGIN_PROMPT_ECHO_OFF: + { + /* Move cursor one pixel per character to give some feedback without + giving away the password length */ + x += PROMPT_CURSOR(w, w->login.activePrompt); + break; + } } - break; - case LOGIN_PROMPT_ECHO_OFF: - /* Move cursor one pixel per character to give some feedback without - giving away the password length */ - x += PROMPT_CURSOR(w, w->login.activePrompt); - break; - } - XFillRectangle (XtDisplay (w), XtWindow (w), gc, - x, y+1 - F_ASCENT(text), width, height-1); - XDrawPoint (XtDisplay (w), XtWindow (w), gc, - x-1 , y - F_ASCENT(text)); - XDrawPoint (XtDisplay (w), XtWindow (w), gc, - x+1 , y - F_ASCENT(text)); - XDrawPoint (XtDisplay (w), XtWindow (w), gc, - x-1 , y - F_ASCENT(text)+height); - XDrawPoint (XtDisplay (w), XtWindow (w), gc, - x+1 , y - F_ASCENT(text)+height); - XDrawPoint (XtDisplay (w), XtWindow (w), gc, - x-2 , y - F_ASCENT(text)); - XDrawPoint (XtDisplay (w), XtWindow (w), gc, - x+2 , y - F_ASCENT(text)); - XDrawPoint (XtDisplay (w), XtWindow (w), gc, - x-2 , y - F_ASCENT(text)+height); - XDrawPoint (XtDisplay (w), XtWindow (w), gc, - x+2 , y - F_ASCENT(text)+height); - - XFlush (XtDisplay(w)); + XFillRectangle(XtDisplay(w), XtWindow(w), gc, x, y + 1 - F_ASCENT(text), width, height - 1); + XDrawPoint(XtDisplay(w), XtWindow(w), gc, x - 1, y - F_ASCENT(text)); + XDrawPoint(XtDisplay(w), XtWindow(w), gc, x + 1, y - F_ASCENT(text)); + XDrawPoint(XtDisplay(w), XtWindow(w), gc, x - 1, y - F_ASCENT(text) + height); + XDrawPoint(XtDisplay(w), XtWindow(w), gc, x + 1, y - F_ASCENT(text) + height); + XDrawPoint(XtDisplay(w), XtWindow(w), gc, x - 2, y - F_ASCENT(text)); + XDrawPoint(XtDisplay(w), XtWindow(w), gc, x + 2, y - F_ASCENT(text)); + XDrawPoint(XtDisplay(w), XtWindow(w), gc, x - 2, y - F_ASCENT(text) + height); + XDrawPoint(XtDisplay(w), XtWindow(w), gc, x + 2, y - F_ASCENT(text) + height); + + XFlush(XtDisplay(w)); } static void @@ -669,9 +715,7 @@ draw_it (LoginWidget w) int gr_line_x, gr_line_y, gr_line_w; EraseCursor (w); - - if( (w->login.outframewidth) < 1 ) - w->login.outframewidth = 1; + /* draw window borders */ for(i=1;i<=(w->login.outframewidth);i++) { XDrawLine(XtDisplay (w), XtWindow (w), w->login.hiGC, @@ -726,7 +770,7 @@ draw_it (LoginWidget w) } else { topLeftGC = botRightGC = w->login.bgGC; } - + /* draw borders of editboxes */ for (i=1; i<=(w->login.inframeswidth); i++) { /* Make top/left sides */ @@ -1800,7 +1844,14 @@ SkipXpmLoad: VALUE_TEXT_MAX(w, LOGIN_PROMPT_PASSWORD) = sizeof(w->login.data.passwd); VALUE_SHOW_START(w, LOGIN_PROMPT_PASSWORD) = 0; - SetPrompt(gnew, LOGIN_PROMPT_PASSWORD, NULL, LOGIN_PROMPT_ECHO_OFF, False); + if (w->login.echo_passwd == False) + { + SetPrompt(gnew, LOGIN_PROMPT_PASSWORD, NULL, LOGIN_PROMPT_ECHO_OFF, False); + } + else + { + SetPrompt(gnew, LOGIN_PROMPT_PASSWORD, NULL, LOGIN_PROMPT_ECHO_ON, False); + } SetPrompt(gnew, LOGIN_PROMPT_USERNAME, NULL, LOGIN_PROMPT_ECHO_ON, False); if (w->core.width == 0) diff --git a/greeter/Login.h b/greeter/Login.h index 7d04a1a..84ed762 100644 --- a/greeter/Login.h +++ b/greeter/Login.h @@ -105,6 +105,7 @@ from The Open Group. # define XtNallowAccess "allowAccess" # define XtNallowNullPasswd "allowNullPasswd" # define XtNallowRootLogin "allowRootLogin" +# define XtNechoPasswd "echoPasswd" # define XtNface "face" # define XtCFace "Face" @@ -145,6 +146,7 @@ from The Open Group. # define XtCAllowAccess "AllowAccess" # define XtCAllowNullPasswd "AllowNullPasswd" # define XtCAllowRootLogin "AllowRootLogin" +# define XtCEchoPasswd "EchoPasswd" # define XtNchangePasswdMessage "changePasswdMessage" # define XtCChangePasswdMessage "ChangePasswdMessage" diff --git a/greeter/LoginP.h b/greeter/LoginP.h index d73a9a1..6d6f6a7 100644 --- a/greeter/LoginP.h +++ b/greeter/LoginP.h @@ -135,6 +135,9 @@ typedef struct { Boolean allow_access; /* disable access control on login */ Boolean allow_null_passwd; /* allow null password on login */ Boolean allow_root_login; /* allow root login */ + /* allow password to be rendered as '**...' */ + Boolean echo_passwd; + XIC xic; /* input method of input context */ loginPromptData prompts[NUM_PROMPTS]; time_t msgTimeout; diff --git a/greeter/greet.c b/greeter/greet.c index 17d21c8..b28b900 100644 --- a/greeter/greet.c +++ b/greeter/greet.c @@ -78,7 +78,7 @@ from The Open Group. #include "dm.h" #include "dm_error.h" #include "greet.h" -#include "Login.h" +#include "LoginP.h" #if defined(HAVE_OPENLOG) && defined(HAVE_SYSLOG_H) # define USE_SYSLOG @@ -507,9 +507,9 @@ greet_user_rtn GreetUser( const char * login_prompt; - SetPrompt(login, 0, NULL, LOGIN_PROMPT_NOT_SHOWN, False); + SetPrompt(login, LOGIN_PROMPT_USERNAME, NULL, LOGIN_PROMPT_NOT_SHOWN, False); login_prompt = GetPrompt(login, LOGIN_PROMPT_USERNAME); - SetPrompt(login, 1, NULL, LOGIN_PROMPT_NOT_SHOWN, False); + SetPrompt(login, LOGIN_PROMPT_PASSWORD, NULL, LOGIN_PROMPT_NOT_SHOWN, False); # define RUN_AND_CHECK_PAM_ERROR(function, args) \ do { \ @@ -714,6 +714,11 @@ static int pamconv(int num_msg, char *username; int promptId = 0; loginPromptState pStyle = LOGIN_PROMPT_ECHO_OFF; + + if (((LoginWidget)login)->login.echo_passwd == True) + { + pStyle = LOGIN_PROMPT_ECHO_ON; + } if ((pam_get_item(*pamhp, PAM_USER, (void *) &username) == PAM_SUCCESS) && (username != NULL) && (*username != '\0')) { -- 1.6.0.3