Added support for multiple hash formats, and new salt generation code.
It selects which hash format to use by checking /etc/auth.conf for auth_default. Leaving auth_default disabled will give the current behaviour (use the same format as is currently used in the password, or if a new password default to what crypt likes best--des if it exists). Now you can set it to one of: des, best, md5 or sha1. best is a synonym for sha1, currently.
This commit is contained in:
parent
854de4f06a
commit
669892b239
@ -30,7 +30,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: local_passwd.c,v 1.19 1998/03/07 21:42:07 ache Exp $
|
||||
* $Id: local_passwd.c,v 1.20 1998/05/19 03:48:07 jkoshy Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
@ -49,6 +49,7 @@ static const char sccsid[] = "@(#)local_passwd.c 8.3 (Berkeley) 4/2/94";
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <libutil.h>
|
||||
|
||||
#include <pw_copy.h>
|
||||
#include <pw_util.h>
|
||||
@ -89,6 +90,146 @@ to64(s, v, n)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** used in generating new salt
|
||||
*/
|
||||
char * gen_des_salt(char * salt, int htype, struct timeval * tvp);
|
||||
char * gen_mcf_salt(char * salt, int htype, struct timeval * tvp);
|
||||
|
||||
#define DES_CRYPT 0 /* which index is the 'des' crypt. Do not change */
|
||||
#define BEST_CRYPT 1 /* which index is the 'best' crypt. Do not change
|
||||
the index, change the crypt_token for the index */
|
||||
#define DEFAULT_CRYPT BEST_CRYPT /* or 0 for old behaviour */
|
||||
struct hash_type {
|
||||
char * auth_token;
|
||||
char * crypt_token;
|
||||
char * (*gensalt)(char *, int, struct timeval *);
|
||||
} hash_types[] = {
|
||||
{ "des", "", gen_des_salt },
|
||||
{ "best", "SHA1", gen_mcf_salt },
|
||||
{ "md5", "MD5", gen_mcf_salt },
|
||||
{ "sha1", "SHA1", gen_mcf_salt },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
char * gen_long_salt(char * salt, struct timeval * tvp) {
|
||||
char * s, * p;
|
||||
int r, x;
|
||||
|
||||
s = p = salt;
|
||||
|
||||
to64(s, random(), 2);
|
||||
to64(s+2, tvp->tv_usec, 2);
|
||||
s += 4;
|
||||
for (x = 0; x < 3; x++) {
|
||||
to64(s, random(), 4);
|
||||
s+=4;
|
||||
}
|
||||
r = (random()%9) + 8;
|
||||
p[r] = '\0';
|
||||
|
||||
return &salt[0];
|
||||
}
|
||||
|
||||
char * gen_des_salt(char * salt, int htype, struct timeval * tvp) {
|
||||
#ifdef NEWSALT
|
||||
salt[0] = _PASSWORD_EFMT1;
|
||||
to64(&salt[1], (long)(29 * 25), 4);
|
||||
to64(&salt[5], random(), 4);
|
||||
salt[9] = '\0';
|
||||
return &salt[0];
|
||||
#else
|
||||
return gen_long_salt(salt, tvp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Make a good size salt for algoritms that can use it,
|
||||
** infact randomize it from 8 to 16 chars in length too
|
||||
*/
|
||||
char * gen_mcf_salt(char * salt, int htype, struct timeval * tvp) {
|
||||
char * s;
|
||||
|
||||
sprintf(salt, "$%s$", hash_types[htype].crypt_token);
|
||||
s = &salt[strlen(salt)];
|
||||
gen_long_salt(s, tvp);
|
||||
return salt;
|
||||
}
|
||||
|
||||
char * generate_salt(char * salt, char * curpwd) {
|
||||
int x;
|
||||
char * p, *s;
|
||||
char * v = auth_getval("auth_default");
|
||||
char sbuf[32];
|
||||
short descrypt = 0;
|
||||
struct timeval tv;
|
||||
|
||||
if (!randinit) {
|
||||
randinit = 1;
|
||||
srandomdev();
|
||||
}
|
||||
gettimeofday(&tv,0);
|
||||
|
||||
/* see if DES crypt is crypt()'s default */
|
||||
p = crypt("a", "bc");
|
||||
if (p[0] != '$')
|
||||
descrypt = 1;
|
||||
|
||||
/* nothing defined, default to old behaviour */
|
||||
if (v == NULL) {
|
||||
if (curpwd && curpwd[0] == '$') {
|
||||
salt[0] = '$';
|
||||
s = &salt[1];
|
||||
p = &curpwd[1];
|
||||
for (;*p && isalnum(*p); s++, p++) {
|
||||
*s = *p;
|
||||
}
|
||||
*s++ = '$';
|
||||
} else {
|
||||
s = &salt[0];
|
||||
}
|
||||
gen_long_salt(s, &tv);
|
||||
return salt;
|
||||
}
|
||||
|
||||
/* cleanup the auth token */
|
||||
for (p = &v[strlen(v) - 1]; p >= v; p--) {
|
||||
if (isalnum(*p))
|
||||
break;
|
||||
*p = (char) NULL;
|
||||
}
|
||||
|
||||
for (x = 0; hash_types[x].crypt_token != NULL; x++) {
|
||||
if (strcasecmp(v, hash_types[x].auth_token) == 0) {
|
||||
if (x == DES_CRYPT && !descrypt) {
|
||||
if (strlen(hash_types[DEFAULT_CRYPT].crypt_token))
|
||||
x = DEFAULT_CRYPT;
|
||||
else
|
||||
x = BEST_CRYPT;
|
||||
printf("WARNING: DES crypt specified in /etc/auth.conf, but crypt(3) library does\nnot have DES hash support installed. Will use default (%s) instead!\n", hash_types[x].crypt_token);
|
||||
return (hash_types[x].gensalt)(salt, x, &tv);
|
||||
}
|
||||
|
||||
/* we have a match, verify it is valid */
|
||||
if (!strlen(hash_types[x].crypt_token))
|
||||
return (hash_types[x].gensalt)(salt, x, &tv);
|
||||
|
||||
sprintf(sbuf, "$%s$", hash_types[x].crypt_token);
|
||||
p = crypt(hash_types[x].auth_token, sbuf);
|
||||
if (strncmp(&p[1], hash_types[x].crypt_token,
|
||||
strlen(hash_types[x].crypt_token)))
|
||||
{
|
||||
printf("WARNING: Specified auth default (%s) in /etc/auth.conf is not supported\nby crypt(3) library, using best (%s) instead.\n",
|
||||
hash_types[x].auth_token, hash_types[BEST_CRYPT].crypt_token);
|
||||
return (hash_types[BEST_CRYPT].gensalt)(salt, BEST_CRYPT, &tv);
|
||||
}
|
||||
return (hash_types[x].gensalt)(salt, x, &tv);
|
||||
}
|
||||
}
|
||||
printf("WARNING: Specified auth default (%s) in /etc/auth.conf is not recognized.\nUsing best type (%s) instead.\n", v, hash_types[BEST_CRYPT].crypt_token);
|
||||
return (hash_types[BEST_CRYPT].gensalt)(salt, BEST_CRYPT, &tv);
|
||||
}
|
||||
|
||||
char *
|
||||
getnewpasswd(pw, nis)
|
||||
struct passwd *pw;
|
||||
@ -100,7 +241,6 @@ getnewpasswd(pw, nis)
|
||||
login_cap_t * lc;
|
||||
#endif
|
||||
char buf[_PASSWORD_LEN+1], salt[10];
|
||||
struct timeval tv;
|
||||
|
||||
if (!nis)
|
||||
(void)printf("Changing local password for %s.\n", pw->pw_name);
|
||||
@ -152,34 +292,7 @@ getnewpasswd(pw, nis)
|
||||
break;
|
||||
(void)printf("Mismatch; try again, EOF to quit.\n");
|
||||
}
|
||||
/* grab a random printable character that isn't a colon */
|
||||
if (!randinit) {
|
||||
randinit = 1;
|
||||
srandomdev();
|
||||
}
|
||||
#ifdef NEWSALT
|
||||
salt[0] = _PASSWORD_EFMT1;
|
||||
to64(&salt[1], (long)(29 * 25), 4);
|
||||
to64(&salt[5], random(), 4);
|
||||
salt[9] = '\0';
|
||||
#else
|
||||
/* Make a good size salt for algoritms that can use it. */
|
||||
gettimeofday(&tv,0);
|
||||
if (strncmp(pw->pw_passwd, "$1$", 3)) {
|
||||
/* DES Salt */
|
||||
to64(&salt[0], random(), 3);
|
||||
to64(&salt[3], tv.tv_usec, 3);
|
||||
to64(&salt[6], tv.tv_sec, 2);
|
||||
salt[8] = '\0';
|
||||
}
|
||||
else {
|
||||
/* MD5 Salt */
|
||||
strncpy(&salt[0], "$1$", 3);
|
||||
to64(&salt[3], random(), 3);
|
||||
to64(&salt[6], tv.tv_usec, 3);
|
||||
salt[8] = '\0';
|
||||
}
|
||||
#endif
|
||||
generate_salt(salt, pw->pw_passwd);
|
||||
return (crypt(buf, salt));
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)passwd.1 8.1 (Berkeley) 6/6/93
|
||||
.\" $Id: passwd.1,v 1.10 1998/10/09 06:38:33 markm Exp $
|
||||
.\" $Id: passwd.1,v 1.11 1998/11/30 22:41:58 billf Exp $
|
||||
.\"
|
||||
.Dd June 6, 1993
|
||||
.Dt PASSWD 1
|
||||
@ -173,6 +173,14 @@ Do not automatically override the password authentication checks for the
|
||||
super-user on the NIS master server; assume 'old' mode instead. This
|
||||
flag is of limited practical use but is useful for testing.
|
||||
.El
|
||||
.Sh PASSWORD HASH FORMATS
|
||||
.Pp
|
||||
The type of password hash which is stored is configured through the file
|
||||
.Pa /etc/auth.conf
|
||||
using the variable auth_default. Furthermore, passwd can only support
|
||||
hash formats which are supported by your
|
||||
.Xr crypt 3
|
||||
library.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/master.passwd -compact
|
||||
.It Pa /etc/master.passwd
|
||||
@ -191,6 +199,8 @@ configure authentication services
|
||||
.Xr kerberos 1 ,
|
||||
.Xr kinit 1 ,
|
||||
.Xr login 1 ,
|
||||
.Xr crypt 3 ,
|
||||
.Xr auth.conf 5 ,
|
||||
.Xr login.conf 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr kpasswdd 8 ,
|
||||
|
Loading…
Reference in New Issue
Block a user