From 18844525b681b18eec1f18bbfaeb5577c96b28c0 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 24 Jan 2008 16:42:58 +0000 Subject: Relevant BUGIDs: 1836981 Purpose of commit: bugfix Commit summary: --------------- 2008-01-24 Tomas Mraz * modules/pam_unix/bigcrypt.c (bigcrypt): Use crypt_r() when available. * modules/pam_unix/passverify.c (strip_hpux_aging): New function to strip HP/UX aging info from password hash. (verify_pwd_hash): Call strip_hpux_aging(), use crypt_r() when available. --- ChangeLog | 12 ++++++++++++ modules/pam_unix/bigcrypt.c | 26 +++++++++++++++++++++++--- modules/pam_unix/passverify.c | 38 +++++++++++++++++++++++++++++++++++--- modules/pam_unix/passverify.h | 2 +- 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index a1fee209..415c2ae8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ +2008-01-24 Tomas Mraz + + * modules/pam_unix/bigcrypt.c (bigcrypt): Use crypt_r() when + available. + * modules/pam_unix/passverify.c (strip_hpux_aging): New function + to strip HP/UX aging info from password hash. + (verify_pwd_hash): Call strip_hpux_aging(), use crypt_r() when + available. + 2008-01-23 Tomas Mraz + * configure.in: Add test for crypt_r(). Add setting/disabling random + device support. + * modules/pam_unix/Makefile.am: Add unix_update.8 manpage generated from XML, generate also unix_chkpwd.8 from XML. * modules/pam_unix/pam_unix_acct.c: Add rounds parameter to _set_ctrl(). diff --git a/modules/pam_unix/bigcrypt.c b/modules/pam_unix/bigcrypt.c index d825bc71..9cd55384 100644 --- a/modules/pam_unix/bigcrypt.c +++ b/modules/pam_unix/bigcrypt.c @@ -51,7 +51,9 @@ char *bigcrypt(const char *key, const char *salt) { char *dec_c2_cryptbuf; - +#ifdef HAVE_CRYPT_R + struct crypt_data *cdata; +#endif unsigned long int keylen, n_seg, j; char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr; char keybuf[KEYBUF_SIZE + 1]; @@ -63,6 +65,14 @@ char *bigcrypt(const char *key, const char *salt) if (!dec_c2_cryptbuf) { return NULL; } +#ifdef HAVE_CRYPT_R + cdata = malloc(sizeof(*cdata)); + if(!cdata) { + free(dec_c2_cryptbuf); + return NULL; + } + cdata->initialized = 0; +#endif memset(keybuf, 0, KEYBUF_SIZE + 1); memset(dec_c2_cryptbuf, 0, CBUF_SIZE); @@ -92,8 +102,11 @@ char *bigcrypt(const char *key, const char *salt) plaintext_ptr = keybuf; /* do the first block with supplied salt */ +#ifdef HAVE_CRYPT_R + tmp_ptr = crypt_r(plaintext_ptr, salt, cdata); /* libc crypt_r() */ +#else tmp_ptr = crypt(plaintext_ptr, salt); /* libc crypt() */ - +#endif /* and place in the static area */ strncpy(cipher_ptr, tmp_ptr, 13); cipher_ptr += ESEGMENT_SIZE + SALT_SIZE; @@ -110,7 +123,11 @@ char *bigcrypt(const char *key, const char *salt) if (n_seg > 1) { for (j = 2; j <= n_seg; j++) { +#ifdef HAVE_CRYPT_R + tmp_ptr = crypt_r(plaintext_ptr, salt_ptr, cdata); +#else tmp_ptr = crypt(plaintext_ptr, salt_ptr); +#endif /* skip the salt for seg!=0 */ strncpy(cipher_ptr, (tmp_ptr + SALT_SIZE), ESEGMENT_SIZE); @@ -122,7 +139,10 @@ char *bigcrypt(const char *key, const char *salt) } D(("key=|%s|, salt=|%s|\nbuf=|%s|\n", key, salt, dec_c2_cryptbuf)); - /* this is the terminated encrypted password */ +#ifdef HAVE_CRYPT_R + free(cdata); +#endif + /* this is the terminated encrypted password */ return dec_c2_cryptbuf; } diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 6fc4dcce..9b9f0a42 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -19,6 +19,9 @@ #include #include #include +#ifdef HAVE_CRYPT_H +#include +#endif #include "md5.h" #include "bigcrypt.h" @@ -44,14 +47,32 @@ # include "./lckpwdf.-c" #endif +static void +strip_hpux_aging(char *hash) +{ + static const char valid[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789./"; + if ((*hash != '$') && (strlen(hash) > 13)) { + for (hash += 13; *hash != '\0'; hash++) { + if (strchr(valid, *hash) == NULL) { + *hash = '\0'; + break; + } + } + } +} + int -verify_pwd_hash(const char *p, const char *hash, unsigned int nullok) +verify_pwd_hash(const char *p, char *hash, unsigned int nullok) { - size_t hash_len = strlen(hash); + size_t hash_len; char *pp = NULL; int retval; D(("called")); + strip_hpux_aging(hash); + hash_len = strlen(hash); if (!hash_len) { /* the stored password is NULL */ if (nullok) { /* this means we've succeeded */ @@ -78,9 +99,20 @@ verify_pwd_hash(const char *p, const char *hash, unsigned int nullok) } else { /* * Ok, we don't know the crypt algorithm, but maybe - * libcrypt nows about it? We should try it. + * libcrypt knows about it? We should try it. */ +#ifdef HAVE_CRYPT_R + struct crypt_data *cdata; + cdata = malloc(sizeof(*cdata)); + if (cdata != NULL) { + cdata->initialized = 0; + pp = x_strdup(crypt_r(p, hash, cdata)); + memset(cdata, '\0', sizeof(*cdata)); + free(cdata); + } +#else pp = x_strdup(crypt(p, hash)); +#endif } p = NULL; /* no longer needed here */ diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h index 196e0e33..e8e112d0 100644 --- a/modules/pam_unix/passverify.h +++ b/modules/pam_unix/passverify.h @@ -13,7 +13,7 @@ #define OLD_PASSWORDS_FILE "/etc/security/opasswd" int -verify_pwd_hash(const char *p, const char *hash, unsigned int nullok); +verify_pwd_hash(const char *p, char *hash, unsigned int nullok); int is_pwd_shadowed(const struct passwd *pwd); -- cgit v1.2.3