From f326d04ccd16631d57134487e56bb73074f0dd0e Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Wed, 3 Dec 2008 14:16:33 +0000 Subject: Relevant BUGIDs: Purpose of commit: new feature Commit summary: --------------- 2008-12-03 Thorsten Kukuk * doc/man/Makefile.am: Add pam_get_authtok.3.xml. * doc/man/pam_get_authtok.3.xml: New. * libpam/Makefile.am: Add pam_get_authtok.c. * libpam/libpam.map: Export pam_get_authtok. * libpam/pam_get_authtok.c: New. * libpam/pam_private.h: Add mod_argc and mod_argv to pam_handle. * libpam_include/security/pam_ext.h: Add pam_get_authtok prototype. * modules/pam_cracklib/pam_cracklib.c: Use pam_get_authtok. * modules/pam_pwhistory/pam_pwhistory.c: Likewise. * po/POTFILES.in: Add libpam/pam_get_authtok.c. * xtests/tst-pam_cracklib1.c: Adjust error codes. * modules/pam_timestamp/Makefile.am: Remove hmactest.c from EXTRA_DIST. * po/*.po: Regenerated. --- libpam/pam_get_authtok.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 libpam/pam_get_authtok.c (limited to 'libpam/pam_get_authtok.c') diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c new file mode 100644 index 00000000..83b3f530 --- /dev/null +++ b/libpam/pam_get_authtok.c @@ -0,0 +1,166 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, and the entire permission notice in its entirety, + * including the disclaimer of warranties. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * ALTERNATIVELY, this product may be distributed under the terms of + * the GNU Public License, in which case the provisions of the GPL are + * required INSTEAD OF the above restrictions. (This clause is + * necessary due to a potential bad interaction between the GPL and + * the restrictions contained in a BSD-style copyright.) + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "pam_private.h" + +#include + +#define PROMPT _("Password: ") +/* For Translators: "%s%s" could be replaced with " " or "". */ +#define PROMPT1 _("New %s%spassword: ") +/* For Translators: "%s%s" could be replaced with " " or "". */ +#define PROMPT2 _("Retype new %s%spassword: ") +#define MISTYPED_PASS _("Sorry, passwords do not match.") + +static const char * +get_option (pam_handle_t *pamh, const char *option) +{ + int i; + size_t len; + + + if (option == NULL || pamh == NULL || + pamh->mod_argc == 0 || pamh->mod_argv == NULL) + return NULL; + + len = strlen (option); + + for (i = 0; i < pamh->mod_argc; i++) + { + if (strncmp (option, pamh->mod_argv[i], len) == 0) + { + if (pamh->mod_argv[i][len] == '=') + return &(pamh->mod_argv[i][len+1]); + else if (pamh->mod_argv[i][len] == '\0') + return ""; + } + } + return NULL; +} + + +int +pam_get_authtok (pam_handle_t *pamh, int item, const char **authtok, + const char *prompt) + +{ + char *resp[2] = {NULL, NULL}; + const void* prevauthtok; + const char *type = ""; + int ask_twice = 0; /* Password change, ask twice for it */ + int retval; + + if (authtok == NULL) + return PAM_SYSTEM_ERR; + + /* PAM_AUTHTOK in password stack returns new password, + which needs to be verified. */ + if (item == PAM_AUTHTOK && pamh->choice == PAM_CHAUTHTOK) + { + ask_twice = 1; + type = get_option (pamh, "type"); + if (type == NULL) + type = ""; + } + + retval = pam_get_item (pamh, item, &prevauthtok); + if (retval == PAM_SUCCESS && prevauthtok != NULL) + { + *authtok = prevauthtok; + return PAM_SUCCESS; + } + else if (get_option (pamh, "use_first_pass") || + (ask_twice && get_option (pamh, "use_authtok"))) + { + if (prevauthtok == NULL) + { + if (ask_twice) + return PAM_AUTHTOK_ERR; + else + return PAM_AUTH_ERR; + } + else + return retval; + } + + if (prompt != NULL) + { + retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0], + "%s", prompt); + if (retval == PAM_SUCCESS && ask_twice && resp[0] != NULL) + retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[1], + _("Retype %s"), prompt); + } + else if (ask_twice) + { + retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0], + PROMPT1, type, + strlen (type) > 0?" ":""); + if (retval == PAM_SUCCESS && ask_twice && resp[0] != NULL) + retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[1], + PROMPT2, type, + strlen (type) > 0?" ":""); + } + else + retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0], "%s", + PROMPT); + + if (resp[0] == NULL || (ask_twice && resp[1] == NULL)) + { + /* We want to abort the password change */ + pam_error (pamh, _("Password change aborted.")); + return PAM_AUTHTOK_ERR; + } + + if (ask_twice && strcmp (resp[0], resp[1]) != 0) + { + pam_error (pamh, MISTYPED_PASS); + _pam_overwrite (resp[0]); + _pam_drop (resp[0]); + _pam_overwrite (resp[1]); + _pam_drop (resp[1]); + return PAM_TRY_AGAIN; + } + + _pam_overwrite (resp[1]); + _pam_drop (resp[1]); + + retval = pam_set_item (pamh, item, resp[0]); + _pam_overwrite (resp[0]); + _pam_drop (resp[0]); + if (retval != PAM_SUCCESS) + return retval; + + return pam_get_item(pamh, item, (const void **)authtok); +} -- cgit v1.2.3 From a1131337d71a61da5b3b5e129545d3257a709480 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Thu, 11 Dec 2008 19:41:49 +0000 Subject: Relevant BUGIDs: Purpose of commit: new feature Commit summary: --------------- 2008-12-10 Thorsten Kukuk * doc/man/pam_item_types_ext.inc.xml: Document PAM_AUTHTOK_TYPE. * libpam/pam_end.c (pam_end): Free authtok_type. * tests/tst-pam_get_item.c: Add PAM_AUTHTOK_TYPE as test case. * tests/tst-pam_set_item.c: Likewise. * libpam/pam_start.c (pam_start): Initialize xdisplay, xauth and authtok_type. * libpam/pam_get_authtok.c (pam_get_authtok): Rename "type" to "authtok_type". * modules/pam_cracklib/pam_cracklib.8.xml: Replace "type=" with "authtok_type=". * doc/man/pam_get_authtok.3.xml: Document authtok_type argument. * modules/pam_cracklib/pam_cracklib.c (pam_sm_chauthtok): Set type= argument as PAM_AUTHTOK_TYPE item. * libpam/pam_get_authtok.c (pam_get_authtok): If no type argument given, use PAM_AUTHTOK_TYPE item. * libpam/pam_item.c (pam_get_item): Fetch PAM_AUTHTOK_TYPE item. (pam_set_item): Store PAM_AUTHTOK_TYPE item. * libpam/pam_private.h: Add authtok_type to pam_handle. * libpam/include/security/_pam_types.h (PAM_AUTHTOK_TYPE): New. --- libpam/pam_get_authtok.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'libpam/pam_get_authtok.c') diff --git a/libpam/pam_get_authtok.c b/libpam/pam_get_authtok.c index 83b3f530..9e9f8409 100644 --- a/libpam/pam_get_authtok.c +++ b/libpam/pam_get_authtok.c @@ -77,7 +77,7 @@ pam_get_authtok (pam_handle_t *pamh, int item, const char **authtok, { char *resp[2] = {NULL, NULL}; const void* prevauthtok; - const char *type = ""; + const char *authtok_type = ""; int ask_twice = 0; /* Password change, ask twice for it */ int retval; @@ -89,9 +89,13 @@ pam_get_authtok (pam_handle_t *pamh, int item, const char **authtok, if (item == PAM_AUTHTOK && pamh->choice == PAM_CHAUTHTOK) { ask_twice = 1; - type = get_option (pamh, "type"); - if (type == NULL) - type = ""; + authtok_type = get_option (pamh, "authtok_type"); + if (authtok_type == NULL) + { + retval = pam_get_item (pamh, PAM_AUTHTOK_TYPE, (const void **)&authtok_type); + if (retval != PAM_SUCCESS || authtok_type == NULL) + authtok_type = ""; + } } retval = pam_get_item (pamh, item, &prevauthtok); @@ -125,12 +129,12 @@ pam_get_authtok (pam_handle_t *pamh, int item, const char **authtok, else if (ask_twice) { retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0], - PROMPT1, type, - strlen (type) > 0?" ":""); + PROMPT1, authtok_type, + strlen (authtok_type) > 0?" ":""); if (retval == PAM_SUCCESS && ask_twice && resp[0] != NULL) retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[1], - PROMPT2, type, - strlen (type) > 0?" ":""); + PROMPT2, authtok_type, + strlen (authtok_type) > 0?" ":""); } else retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp[0], "%s", -- cgit v1.2.3