diff options
| -rw-r--r-- | include/unistd.h | 2 | ||||
| -rw-r--r-- | lib/libcrypt/Makefile | 1 | ||||
| -rw-r--r-- | lib/libcrypt/crypt.3 | 51 | ||||
| -rw-r--r-- | lib/libcrypt/crypt.c | 59 | ||||
| -rw-r--r-- | lib/libcrypt/crypt.h | 1 | ||||
| -rw-r--r-- | lib/libutil/Makefile | 6 | ||||
| -rw-r--r-- | lib/libutil/login_cap.3 | 22 | ||||
| -rw-r--r-- | lib/libutil/login_cap.h | 1 | ||||
| -rw-r--r-- | lib/libutil/login_crypt.c | 5 | ||||
| -rw-r--r-- | secure/lib/libcrypt/Makefile | 1 | ||||
| -rw-r--r-- | usr.bin/passwd/local_passwd.c | 27 | ||||
| -rw-r--r-- | usr.sbin/pw/Makefile | 4 | ||||
| -rw-r--r-- | usr.sbin/pw/pw_user.c | 21 |
13 files changed, 164 insertions, 37 deletions
diff --git a/include/unistd.h b/include/unistd.h index dd6bf212ffb8..855185034c9a 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -121,6 +121,8 @@ char *brk __P((const char *)); int chroot __P((const char *)); size_t confstr __P((int, char *, size_t)); char *crypt __P((const char *, const char *)); +const char *crypt_get_format __P((void)); +int crypt_set_format __P((const char *)); int des_cipher __P((const char *, char *, long, int)); int des_setkey __P((const char *key)); int encrypt __P((char *, int)); diff --git a/lib/libcrypt/Makefile b/lib/libcrypt/Makefile index 17c978ef6b70..dc6311e1696c 100644 --- a/lib/libcrypt/Makefile +++ b/lib/libcrypt/Makefile @@ -20,6 +20,7 @@ SRCS= crypt.c crypt-md5.c misc.c STATICSRCS= md5c.c STATICOBJS= ${STATICSRCS:S/.c/.o/g} MAN3= crypt.3 +MLINKS= crypt.3 crypt_get_format.3 crypt.3 crypt_set_format.3 CFLAGS+= -I${.CURDIR}/../libmd CFLAGS+= -DLIBC_SCCS -Wall PRECIOUSLIB= yes diff --git a/lib/libcrypt/crypt.3 b/lib/libcrypt/crypt.3 index 8e667dca09b0..9bb38f72e22d 100644 --- a/lib/libcrypt/crypt.3 +++ b/lib/libcrypt/crypt.3 @@ -43,6 +43,10 @@ .Fd #include <unistd.h> .Ft char * .Fn crypt "const char *key" "const char *salt" +.Ft const char * +.Fn crypt_get_format "void" +.Ft int +.Fn crypt_set_format "const char *string" .Sh DESCRIPTION The .Fn crypt @@ -58,10 +62,12 @@ Currently these include the .Tn NBS .Tn Data Encryption Standard (DES) , and .Tn MD5 . -The algorithm used will depend upon the format of the Salt--following -the Modular Crypt Format (MCF)--and if +The algorithm used will depend upon the format of the Salt (following +the Modular Crypt Format (MCF)), if .Tn DES -is installed or not. +is installed or not, and whether +.Fn crypt_set_format +has been called to change the default. .Pp The first argument to .Nm @@ -176,10 +182,15 @@ Other crypt formats may be easilly added. An example salt would be: .Ss "Traditional" crypt: .Pp The algorithm used will depend upon whether +.Fn crypt_set_format +has been called and whether .Tn DES -is installed or not. If it is, +is installed or not. If .Tn DES -will be used. Otherwise, the best algorithm is used, which is currently +is installed and +.Fn crypt_set_format +has not set the format to something else, it will be used. +Otherwise, the best algorithm is used, which is currently .\" .\" NOTICE: Also make sure to update this .\" @@ -187,6 +198,23 @@ MD5. .Pp How the salt is used will depend upon the algorithm for the hash. For best results, specify at least two characters of salt. +.Pp +The +.Fn crypt_get_format +function returns a constant string that represents the name of the +algorithm currently used. +Valid values are +.\" +.\" NOTICE: Also make sure to update this, too, as well +.\" +.Ql des +and +.Ql md5 . +.Pp +The +.Fn crypt_set_format +function sets the default encoding format according to the supplied +.Fa string . .Sh RETURN VALUES .Pp .Fn crypt @@ -194,6 +222,10 @@ returns a pointer to the encrypted value on success, and NULL on failure. Note: this is not a standard behaviour, AT&T .Fn crypt will always return a pointer to a string. +.Pp +.Fn crypt_set_format +will return 1 if the supplied encoding format was valid. +Otherwise, a value of 0 is returned. .Sh SEE ALSO .Xr login 1 , .Xr passwd 1 , @@ -205,7 +237,9 @@ The .Fn crypt function returns a pointer to static data, and subsequent calls to .Fn crypt -will modify the same data. +will modify the same data. Likewise, +.Fn crypt_set_format +modifies static data. .Sh HISTORY A rotor-based .Fn crypt @@ -229,6 +263,7 @@ Originally written by .An David Burren Aq davidb@werj.com.au , later additions and changes by .An Poul-henning Kamp , -.An Mark R V Murray -and +.An Mark R V Murray , .An Kris Kennaway . +and +.An Brian Feldman . diff --git a/lib/libcrypt/crypt.c b/lib/libcrypt/crypt.c index e040be1986ee..abb1ef379c18 100644 --- a/lib/libcrypt/crypt.c +++ b/lib/libcrypt/crypt.c @@ -34,14 +34,59 @@ static char rcsid[] = "$FreeBSD$"; #include <string.h> #include "crypt.h" +static const struct { + const char *const name; + char *(*const func)(const char *, const char *); + const char *const magic; +} crypt_types[] = { +#ifdef NONEXPORTABLE_CRYPT + { + "des", + crypt_des, + NULL + }, +#endif + { + "md5", + crypt_md5, + "$1$" + }, + { + NULL, + NULL + } +}; + +static int crypt_type = 0; + +const char * +crypt_get_format(void) { + + return (crypt_types[crypt_type].name); +} + +int +crypt_set_format(char *type) { + int i; + + for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) { + if (strcmp(type, crypt_types[i].name) == 0) { + crypt_type = i; + return (1); + } + } + return (0); +} + char * crypt(char *passwd, char *salt) { - if (!strncmp(salt, "$1$", 3)) - return crypt_md5(passwd, salt); -#ifdef NONEXPORTABLE_CRYPT - return crypt_des(passwd, salt); -#else - return crypt_md5(passwd, salt); -#endif + int i; + + for (i = 0; i < sizeof(crypt_types) / sizeof(crypt_types[0]) - 1; i++) { + if (crypt_types[i].magic != NULL && strncmp(salt, + crypt_types[i].magic, strlen(crypt_types[i].magic)) == 0) + return (crypt_types[i].func(passwd, salt)); + } + return (crypt_types[crypt_type].func(passwd, salt)); } diff --git a/lib/libcrypt/crypt.h b/lib/libcrypt/crypt.h index 8920986c2998..3544f896563d 100644 --- a/lib/libcrypt/crypt.h +++ b/lib/libcrypt/crypt.h @@ -29,7 +29,6 @@ /* magic sizes */ #define MD5_SIZE 16 -#define SHS_SIZE 20 char *crypt_des(const char *pw, const char *salt); char *crypt_md5(const char *pw, const char *salt); diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile index e65a47cb9b64..70fd9d2b8e98 100644 --- a/lib/libutil/Makefile +++ b/lib/libutil/Makefile @@ -8,8 +8,10 @@ CFLAGS+=-Wall -DLIBC_SCCS -I${.CURDIR} -I${.CURDIR}/../../sys CFLAGS+=-DINET6 SRCS= login.c login_tty.c logout.c logwtmp.c pty.c \ login_cap.c login_class.c login_auth.c login_times.c login_ok.c \ - _secure_path.c uucplock.c property.c auth.c realhostname.c fparseln.c + login_crypt.c _secure_path.c uucplock.c property.c auth.c \ + realhostname.c fparseln.c INCS= libutil.h login_cap.h + MAN3+= login.3 login_auth.3 login_tty.3 logout.3 logwtmp.3 pty.3 \ login_cap.3 login_class.3 login_times.3 login_ok.3 \ _secure_path.3 uucplock.3 property.3 auth.3 realhostname.3 \ @@ -25,7 +27,7 @@ MLINKS+=login_cap.3 login_getclassbyname.3 login_cap.3 login_close.3 \ login_cap.3 login_getstyle.3 login_cap.3 login_getcaptime.3 \ login_cap.3 login_getcapnum.3 login_cap.3 login_getcapsize.3 \ login_cap.3 login_getcapbool.3 login_cap.3 login_getpath.3 \ - login_cap.3 login_getpwclass.3 + login_cap.3 login_getpwclass.3 login_cap.3 login_setcryptfmt.3 MLINKS+=login_class.3 setusercontext.3 login_class.3 setclasscontext.3 \ login_class.3 setclassenvironment.3 login_class.3 setclassresources.3 MLINKS+=login_times.3 parse_lt.3 login_times.3 in_ltm.3 \ diff --git a/lib/libutil/login_cap.3 b/lib/libutil/login_cap.3 index aab53da9d628..32661a2ddd4c 100644 --- a/lib/libutil/login_cap.3 +++ b/lib/libutil/login_cap.3 @@ -34,7 +34,8 @@ .Nm login_getclassbyname , .Nm login_getpwclass , .Nm login_getstyle , -.Nm login_getuserclass +.Nm login_getuserclass , +.Nm login_setcryptfmt .Nd functions for accessing the login class capabilities database. .Sh LIBRARY .Lb libutil @@ -67,6 +68,8 @@ .Fn login_getcapbool "login_cap_t *lc" "const char *cap" "int def" .Ft char * .Fn login_getstyle "login_cap_t *lc" "char *style" "const char *auth" +.Ft const char * +.Fn login_setcryptfmt "login_cap_t *lc" "const char *def" "const char *error" .Sh DESCRIPTION These functions represent a programming interface to the login classes database provided in @@ -393,8 +396,25 @@ the authentication method used for access to the system via the network, and standard methods via direct dialup or console logins, significantly reducing the risk of password discovery by "snooping" network packets. +.It Fn login_setcryptfmt +The +.Fn login_setcryptfmt +function is used to set the +.Xr crypt 3 +format using the +.Ql passwd_format +configuration entry. +If no entry is found, +.Fa def +is taken to be used as the fallback. +If calling +.Xr crypt_set_format 3 +on the specifier fails, +.Fa error +is returned to indicate this. .El .Sh SEE ALSO +.Xr crypt 3 , .Xr getcap 3 , .Xr login_class 3 , .Xr login.conf 5 , diff --git a/lib/libutil/login_cap.h b/lib/libutil/login_cap.h index f4b382519770..1320278e074a 100644 --- a/lib/libutil/login_cap.h +++ b/lib/libutil/login_cap.h @@ -110,6 +110,7 @@ rlim_t login_getcapnum __P((login_cap_t *, const char *, rlim_t, rlim_t)); rlim_t login_getcapsize __P((login_cap_t *, const char *, rlim_t, rlim_t)); char *login_getpath __P((login_cap_t *, const char *, char *)); int login_getcapbool __P((login_cap_t *, const char *, int)); +const char *login_setcryptfmt __P((login_cap_t *, const char *, const char *)); int setclasscontext __P((const char*, unsigned int)); int setusercontext __P((login_cap_t*, const struct passwd*, uid_t, unsigned int)); diff --git a/lib/libutil/login_crypt.c b/lib/libutil/login_crypt.c index b291100e335d..56b741a0c5cb 100644 --- a/lib/libutil/login_crypt.c +++ b/lib/libutil/login_crypt.c @@ -31,9 +31,14 @@ #include <login_cap.h> #include <unistd.h> +/* + * Stub out what's in -lcrypt. + */ + #pragma weak crypt_set_format int crypt_set_format(const char *f) { + return (0); } diff --git a/secure/lib/libcrypt/Makefile b/secure/lib/libcrypt/Makefile index 0721f5548cd1..b46df113346b 100644 --- a/secure/lib/libcrypt/Makefile +++ b/secure/lib/libcrypt/Makefile @@ -21,6 +21,7 @@ STATICSRCS= md5c.c STATICOBJS= ${STATICSRCS:S/.c/.o/g} SRCS+= crypt-des.c MAN3= crypt.3 +MLINKS= crypt.3 crypt_get_format.3 crypt.3 crypt_set_format.3 CFLAGS+= -I${.CURDIR}/../../../lib/libmd CFLAGS+= -I${.CURDIR}/../../../lib/libcrypt CFLAGS+= -DNONEXPORTABLE_CRYPT diff --git a/usr.bin/passwd/local_passwd.c b/usr.bin/passwd/local_passwd.c index 6508529bf253..ccf8bbbb6889 100644 --- a/usr.bin/passwd/local_passwd.c +++ b/usr.bin/passwd/local_passwd.c @@ -132,7 +132,6 @@ getnewpasswd(pw, nis) } /* mixpasswordcase capability */ force_mix_case = login_getcapbool(lc, "mixpasswordcase", 1); - login_close(lc); } #endif @@ -172,20 +171,18 @@ getnewpasswd(pw, nis) #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'; - } +#ifdef LOGIN_CAP + if (login_setcryptfmt(lc, "md5", NULL) == NULL) + pw_error("cannot set password cipher", 1, 1); + login_close(lc); +#else + (void)crypt_set_format("md5"); +#endif + /* Salt suitable for anything */ + to64(&salt[0], random(), 3); + to64(&salt[3], tv.tv_usec, 3); + to64(&salt[6], tv.tv_sec, 2); + salt[8] = '\0'; #endif return (crypt(buf, salt)); } diff --git a/usr.sbin/pw/Makefile b/usr.sbin/pw/Makefile index bee05ccd5502..bb82d3aa0fa3 100644 --- a/usr.sbin/pw/Makefile +++ b/usr.sbin/pw/Makefile @@ -11,8 +11,8 @@ MAN8= pw.8 #RND= -DUSE_MD5RAND CFLAGS+= -W -Wall $(CDB) $(RND) -LDADD= -lcrypt -DPADD= ${LIBCRYPT} +LDADD= -lcrypt -lutil +DPADD= ${LIBCRYPT} ${LIBUTIL} BINMODE=0555 diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 2c491fdc8cfc..c4e66b4ec879 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -42,6 +42,7 @@ static const char rcsid[] = #include <sys/resource.h> #include <unistd.h> #include <utmp.h> +#include <login_cap.h> #if defined(USE_MD5RAND) #include <md5.h> #endif @@ -544,11 +545,19 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) } if ((arg = getarg(args, 'w')) != NULL && getarg(args, 'h') == NULL) { + login_cap_t *lc; + + lc = login_getpwclass(pwd); + if (lc == NULL || + login_setcryptfmt(lc, "md5", NULL) == NULL) + warn("setting crypt(3) format"); + login_close(lc); pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name); edited = 1; } } else { + login_cap_t *lc; /* * Add code @@ -565,13 +574,17 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) pwd = &fakeuser; pwd->pw_name = a_name->val; pwd->pw_class = cnf->default_class ? cnf->default_class : ""; - pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name); pwd->pw_uid = pw_uidpolicy(cnf, args); pwd->pw_gid = pw_gidpolicy(cnf, args, pwd->pw_name, (gid_t) pwd->pw_uid); pwd->pw_change = pw_pwdpolicy(cnf, args); pwd->pw_expire = pw_exppolicy(cnf, args); pwd->pw_dir = pw_homepolicy(cnf, args, pwd->pw_name); pwd->pw_shell = pw_shellpolicy(cnf, args, NULL); + lc = login_getpwclass(pwd); + if (lc == NULL || login_setcryptfmt(lc, "md5", NULL) == NULL) + warn("setting crypt(3) format"); + login_close(lc); + pwd->pw_passwd = pw_password(cnf, args, pwd->pw_name); edited = 1; if (pwd->pw_uid == 0 && strcmp(pwd->pw_name, "root") != 0) @@ -600,6 +613,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) int b; int istty = isatty(fd); struct termios t; + login_cap_t *lc; if (istty) { if (tcgetattr(fd, &t) == -1) @@ -629,6 +643,11 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) *p = '\0'; if (!*line) errx(EX_DATAERR, "empty password read on file descriptor %d", fd); + lc = login_getpwclass(pwd); + if (lc == NULL || + login_setcryptfmt(lc, "md5", NULL) == NULL) + warn("setting crypt(3) format"); + login_close(lc); pwd->pw_passwd = pw_pwcrypt(line); edited = 1; } |
