From: Todd C. Miller Date: Wed, 27 Jan 2016 22:36:50 +0000 (-0700) Subject: auth_getpass() returns a dynamically allocated copy of the plaintext X-Git-Tag: SUDO_1_8_16^2~38 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ab11cdde2cb1be407f3c720d74c2294518d68dea;p=sudo auth_getpass() returns a dynamically allocated copy of the plaintext password which needs to be freed after checking (and clearing) it. --- diff --git a/plugins/sudoers/auth/aix_auth.c b/plugins/sudoers/auth/aix_auth.c index 4bc3ae5e2..78c4f6086 100644 --- a/plugins/sudoers/auth/aix_auth.c +++ b/plugins/sudoers/auth/aix_auth.c @@ -144,6 +144,7 @@ sudo_aix_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_co message = NULL; result = authenticate(pw->pw_name, pass, &reenter, &message); memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass)); + free(pass); prompt = message; } while (reenter); diff --git a/plugins/sudoers/auth/bsdauth.c b/plugins/sudoers/auth/bsdauth.c index 438ba2dfb..412f476eb 100644 --- a/plugins/sudoers/auth/bsdauth.c +++ b/plugins/sudoers/auth/bsdauth.c @@ -141,6 +141,7 @@ bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_con log_warningx(0, N_("unable to allocate memory")); debug_return_int(AUTH_FATAL); } + free(pass); pass = auth_getpass(s, def_passwd_timeout * 60, SUDO_CONV_PROMPT_ECHO_ON, callback); free(s); @@ -150,6 +151,7 @@ bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_con if (pass) { authok = auth_userresponse(as, pass, 1); memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass)); + free(pass); } /* restore old signal handler */ diff --git a/plugins/sudoers/auth/fwtk.c b/plugins/sudoers/auth/fwtk.c index e144d3cdf..eddd51a35 100644 --- a/plugins/sudoers/auth/fwtk.c +++ b/plugins/sudoers/auth/fwtk.c @@ -93,6 +93,7 @@ restart: (void) snprintf(buf, sizeof(buf), "%s\nResponse: ", &resp[10]); pass = auth_getpass(buf, def_passwd_timeout * 60, SUDO_CONV_PROMPT_ECHO_OFF, callback); if (pass && *pass == '\0') { + free(pass); pass = auth_getpass("Response [echo on]: ", def_passwd_timeout * 60, SUDO_CONV_PROMPT_ECHO_ON, callback); } @@ -132,8 +133,9 @@ restart: sudo_warnx("%s", resp); error = AUTH_FAILURE; done: - memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass)); memset_s(buf, sizeof(buf), 0, sizeof(buf)); + memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass)); + free(pass); debug_return_int(error); } diff --git a/plugins/sudoers/auth/pam.c b/plugins/sudoers/auth/pam.c index afb05392a..8543c7f0b 100644 --- a/plugins/sudoers/auth/pam.c +++ b/plugins/sudoers/auth/pam.c @@ -443,14 +443,10 @@ converse(int num_msg, PAM_CONST struct pam_message **msg, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "password longer than %d", PAM_MAX_RESP_SIZE); ret = PAM_CONV_ERR; + memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass)); goto done; } - if ((pr->resp = strdup(pass)) == NULL) { - sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - ret = PAM_BUF_ERR; - goto done; - } - memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass)); + pr->resp = pass; /* auth_getpass() malloc's a copy */ break; case PAM_TEXT_INFO: if (pm->msg) diff --git a/plugins/sudoers/auth/securid5.c b/plugins/sudoers/auth/securid5.c index 41eec085f..a822addc1 100644 --- a/plugins/sudoers/auth/securid5.c +++ b/plugins/sudoers/auth/securid5.c @@ -177,6 +177,10 @@ sudo_securid_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_ /* Sometimes (when current token close to expire?) ACE challenges for the next token displayed (entered without the PIN) */ + if (pass != NULL) { + memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass)); + free(pass); + } pass = auth_getpass("\ !!! ATTENTION !!!\n\ Wait for the token code to change, \n\ @@ -212,6 +216,11 @@ then enter the new token code.\n", \ /* Free resources */ SD_Close(*sd); + if (pass != NULL) { + memset_s(pass, SUDO_PASS_MAX, 0, strlen(pass)); + free(pass); + } + /* Return stored state to calling process */ debug_return_int(rval); } diff --git a/plugins/sudoers/auth/sia.c b/plugins/sudoers/auth/sia.c index 7856f22d5..8fbd49132 100644 --- a/plugins/sudoers/auth/sia.c +++ b/plugins/sudoers/auth/sia.c @@ -92,6 +92,7 @@ sudo_sia_verify(struct passwd *pw, char *prompt, sudo_auth *auth, /* Check password and zero out plaintext copy. */ rc = sia_ses_authent(NULL, pass, siah); memset_s(pass, SUDO_CONV_REPL_MAX, 0, strlen(pass)); + free(pass); if (rc == SIASUCCESS) debug_return_int(AUTH_SUCCESS); diff --git a/plugins/sudoers/auth/sudo_auth.c b/plugins/sudoers/auth/sudo_auth.c index e03af6fdc..ff5059717 100644 --- a/plugins/sudoers/auth/sudo_auth.c +++ b/plugins/sudoers/auth/sudo_auth.c @@ -296,8 +296,10 @@ verify_user(struct passwd *pw, char *prompt, int validated, if (success != AUTH_FAILURE) break; } - if (!standalone) + if (!standalone) { memset_s(p, SUDO_CONV_REPL_MAX, 0, strlen(p)); + free(p); + } if (success != AUTH_FAILURE) goto done; @@ -387,6 +389,11 @@ sudo_auth_end_session(struct passwd *pw) debug_return_int(status == AUTH_FATAL ? -1 : 1); } +/* + * Prompts the user for a password using the conversation function. + * Returns the plaintext password or NULL. + * The user is responsible for freeing the returned value. + */ char * auth_getpass(const char *prompt, int timeout, int type, struct sudo_conv_callback *callback)