summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Mraz <tm@t8m.info>2008-01-24 16:42:58 +0000
committerTomas Mraz <tm@t8m.info>2008-01-24 16:42:58 +0000
commit18844525b681b18eec1f18bbfaeb5577c96b28c0 (patch)
treec8be26715848e99c32372a0ad116706922c1dfb1
parent459e97431e99fa2c32e30e957993f95794b98dd0 (diff)
Relevant BUGIDs: 1836981
Purpose of commit: bugfix Commit summary: --------------- 2008-01-24 Tomas Mraz <t8m@centrum.cz> * 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.
-rw-r--r--ChangeLog12
-rw-r--r--modules/pam_unix/bigcrypt.c26
-rw-r--r--modules/pam_unix/passverify.c38
-rw-r--r--modules/pam_unix/passverify.h2
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 <t8m@centrum.cz>
+
+ * 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 <t8m@centrum.cz>
+ * 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 <NUL> terminated encrypted password */
+#ifdef HAVE_CRYPT_R
+ free(cdata);
+#endif
+ /* this is the <NUL> 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 <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#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);