0.76: please submit patches for this section with actual code/doc
patches!
+* pam_unix: removed superfluous use of static variables in md5 and bigcrypt
+ routines, bringing us a step closer to thread-safeness. Eliminated
+ some variable indirection along the way. (Bug 440107 - vorlon)
* pam_tally: remove #include of stdlib.h, which isn't needed by anything
found in this module. Can be readded if we find a real need for it at
a later date. (Bug 436432 - vorlon)
*/
#include <string.h>
+#include <stdlib.h>
#include <security/_pam_macros.h>
char *crypt(const char *key, const char *salt);
char *bigcrypt(const char *key, const char *salt)
{
- static char dec_c2_cryptbuf[CBUF_SIZE]; /* static storage area */
+ char *dec_c2_cryptbuf;
unsigned long int keylen, n_seg, j;
char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr;
D(("called with key='%s', salt='%s'.", key, salt));
/* reset arrays */
+ dec_c2_cryptbuf = malloc(CBUF_SIZE);
+ if (!dec_c2_cryptbuf) {
+ return NULL;
+ }
memset(keybuf, 0, KEYBUF_SIZE + 1);
memset(dec_c2_cryptbuf, 0, CBUF_SIZE);
*/
#include <string.h>
+#include <stdlib.h>
#include "md5.h"
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
const char *magic = "$1$";
/* This string is magic for this algorithm. Having
* it this way, we can get get better later on */
- static char passwd[120], *p;
- static const char *sp, *ep;
+ char *passwd, *p;
+ const char *sp, *ep;
unsigned char final[16];
int sl, pl, i, j;
MD5_CTX ctx, ctx1;
/* Refine the Salt first */
sp = salt;
+ /* TODO: now that we're using malloc'ed memory, get rid of the
+ strange constant buffer size. */
+ passwd = malloc(120);
+
/* If it starts with the magic string, then skip that */
if (!strncmp(sp, magic, strlen(magic)))
sp += strlen(magic);
char *cp = (char *) result;
unsigned char tmp[16];
int i;
- char *x, *e = NULL;
+ char *x = NULL;
GoodMD5Init(&ctx);
gettimeofday(&tv, (struct timezone *) 0);
*cp = '\0';
/* no longer need cleartext */
- e = Goodcrypt_md5(pass_new, (const char *) result);
- x = x_strdup(e); /* put e in malloc()ed memory */
- _pam_overwrite(e); /* clean up */
+ x = Goodcrypt_md5(pass_new, (const char *) result);
return x;
}
s_npas = strtok(NULL, ":,");
s_pas = strtok(NULL, ":,");
while (s_pas != NULL) {
- if (!strcmp(Goodcrypt_md5(newpass, s_pas), s_pas)) {
+ char *md5pass = Goodcrypt_md5(newpass, s_pas);
+ if (!strcmp(md5pass, s_pas)) {
+ _pam_delete(md5pass);
retval = PAM_AUTHTOK_ERR;
break;
}
s_pas = strtok(NULL, ":,");
+ _pam_delete(md5pass);
}
break;
}
sprintf(nbuf, "%s:%s:%d:%s\n", s_luser, s_uid, npas, pass);
else
sprintf(nbuf, "%s:%s:%d:%s,%s\n", s_luser, s_uid, npas, s_pas, pass);
+ _pam_delete(pass);
if (fputs(nbuf, pwfile) < 0) {
retval = PAM_AUTHTOK_ERR;
err = 1;
} else {
pass = crypt_md5_wrapper(oldpass);
sprintf(nbuf, "%s:%d:1:%s\n", forwho, pwd->pw_uid, pass);
+ _pam_delete(pass);
if (fputs(nbuf, pwfile) < 0) {
retval = PAM_AUTHTOK_ERR;
err = 1;
* function we truncate the newly entered password
*/
char *temp = malloc(9);
- char *e;
if (temp == NULL) {
_log_err(LOG_CRIT, pamh,
temp[8] = '\0';
/* no longer need cleartext */
- e = bigcrypt(temp, salt);
- tpass = x_strdup(e);
+ tpass = bigcrypt(temp, salt);
- _pam_overwrite(e);
_pam_delete(temp); /* tidy up */
} else {
- char *e;
-
- /* no longer need cleartext */
- e = bigcrypt(pass_new, salt);
- tpass = x_strdup(e);
-
- _pam_overwrite(e);
+ tpass = bigcrypt(pass_new, salt);
}
}
if (!strncmp(salt, "$1$", 3)) {
pp = Goodcrypt_md5(p, salt);
if (strcmp(pp, salt) != 0) {
+ _pam_delete(pp);
pp = Brokencrypt_md5(p, salt);
}
} else {
if (salt)
_pam_delete(salt);
if (pp)
- _pam_overwrite(pp);
+ _pam_delete(pp);
D(("done [%d].", retval));
{
int authtok_flag;
int retval;
- const char *item;
char *token;
D(("called"));
*/
if (on(UNIX_TRY_FIRST_PASS, ctrl) || on(UNIX_USE_FIRST_PASS, ctrl)) {
- retval = pam_get_item(pamh, authtok_flag, (const void **) &item);
+ retval = pam_get_item(pamh, authtok_flag, (const void **) pass);
if (retval != PAM_SUCCESS) {
/* very strange. */
_log_err(LOG_ALERT, pamh
,"pam_get_item returned error to unix-read-password"
);
return retval;
- } else if (item != NULL) { /* we have a password! */
- *pass = item;
- item = NULL;
+ } else if (*pass != NULL) { /* we have a password! */
return PAM_SUCCESS;
} else if (on(UNIX_USE_FIRST_PASS, ctrl)) {
return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
_pam_delete(token); /* clean it up */
if (retval != PAM_SUCCESS
|| (retval = pam_get_item(pamh, authtok_flag
- ,(const void **) &item))
+ ,(const void **) pass))
!= PAM_SUCCESS) {
+ *pass = NULL;
_log_err(LOG_CRIT, pamh, "error manipulating password");
return retval;
_pam_delete(token);
return retval;
}
- item = token;
+ *pass = token;
token = NULL; /* break link to password */
}
- *pass = item;
- item = NULL; /* break link to password */
-
return PAM_SUCCESS;
}
if (pp != NULL) {
while (tp && *tp)
*tp++ = '\0';
+ free(pp);
}
pp = tp = NULL;
}