From 0fc2529e04530093e7725f4dc47bc4eba531a13b Mon Sep 17 00:00:00 2001 From: Georgy A. Shepelev Date: Tue, 22 Sep 2009 16:58:40 +0400 Subject: [PATCH:app/xdm] Adding an option to show stars instead of the password itself. The behaviour can be controlled via 'xlogin*echoPasswd' option in Xresource file. The default option value is 'false'. Signed-off-by: Georgy A. Shepelev Tested-by: Georgy A. Shepelev --- greeter/Login.c | 74 +++++++++++++++++++++++++++++++++++++++++++++-------- greeter/Login.h | 2 + greeter/LoginP.h | 3 ++ greeter/greet.c | 11 ++++++-- 4 files changed, 75 insertions(+), 15 deletions(-) diff --git a/greeter/Login.c b/greeter/Login.c index 49dab2b..035e515 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 @@ -355,12 +357,33 @@ static inline int max (int a, int b) { return a > b ? a : b; } 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); @@ -372,15 +395,16 @@ realizeValue (LoginWidget w, int cursor, int promptNum, GC gc) #ifdef XPM width -= (w->login.logoWidth + 2*(w->login.logoPadding)); #endif - if (cursor > VALUE_SHOW_START(w, promptNum)) - curoff = TEXT_WIDTH (text, text, cursor); - else + if (cursor > VALUE_SHOW_START(w, promptNum)) { + curoff = TEXT_WIDTH(text, text, cursor); + } else { curoff = 0; + } if (gc == w->login.bgGC) { if (curoff < width) { - XFillRectangle (XtDisplay (w), XtWindow (w), gc, + XFillRectangle (XtDisplay(w), XtWindow(w), gc, x + curoff, y - TEXT_Y_INC(w), width - curoff, height); } @@ -417,6 +441,13 @@ realizeValue (LoginWidget w, int cursor, int promptNum, GC gc) 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 @@ -455,15 +486,27 @@ realizeCursor (LoginWidget w, GC gc) 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) ); + 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 */ @@ -1800,7 +1843,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..2e79e5e 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..ff77b2c 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 */ + Boolean echo_passwd; /* allow password to be rendered as '**...' */ + + 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..8823b9d 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 { \ @@ -715,6 +715,11 @@ static int pamconv(int num_msg, 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')) { SetPrompt(login, LOGIN_PROMPT_USERNAME, -- 1.5.6.5