summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/unistd.h2
-rw-r--r--lib/libcrypt/Makefile3
-rw-r--r--lib/libcrypt/crypt.351
-rw-r--r--lib/libcrypt/crypt.c57
-rw-r--r--lib/libcrypt/crypt.h1
-rw-r--r--lib/libutil/Makefile6
-rw-r--r--lib/libutil/login_cap.322
-rw-r--r--lib/libutil/login_cap.c13
-rw-r--r--lib/libutil/login_cap.h1
-rw-r--r--secure/lib/libcrypt/Makefile1
-rw-r--r--usr.bin/passwd/local_passwd.c21
-rw-r--r--usr.sbin/pw/Makefile4
-rw-r--r--usr.sbin/pw/pw_user.c21
13 files changed, 167 insertions, 36 deletions
diff --git a/include/unistd.h b/include/unistd.h
index 45679e5..274c98d 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -120,6 +120,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 17c978e..1c54fa6 100644
--- a/lib/libcrypt/Makefile
+++ b/lib/libcrypt/Makefile
@@ -17,9 +17,10 @@ SONAME= ${LCRYPTSO}
.PATH: ${.CURDIR}/../libmd
SRCS= crypt.c crypt-md5.c misc.c
-STATICSRCS= md5c.c
+STATICSRCS= md5c.c sha1c.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 e9f98c1..81f6261 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
@@ -59,10 +63,12 @@ Currently these include the
.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
@@ -177,10 +183,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
.\"
@@ -188,6 +199,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
@@ -195,6 +223,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 ,
@@ -206,7 +238,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
@@ -230,6 +264,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 e040be1..7a61b42 100644
--- a/lib/libcrypt/crypt.c
+++ b/lib/libcrypt/crypt.c
@@ -34,14 +34,57 @@ 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[] = {
+ {
+ "des",
+ crypt_des,
+ NULL
+ },
+ {
+ "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 8920986c..3544f89 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 3b83b41e..9cc5ef5 100644
--- a/lib/libutil/Makefile
+++ b/lib/libutil/Makefile
@@ -10,6 +10,10 @@ SRCS= login.c login_tty.c logout.c logwtmp.c pty.c setproctitle.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
INCS= libutil.h login_cap.h
+
+LDADD+= -lcrypt
+DPADD+= ${LIBCRYPT}
+
MAN3+= login.3 login_auth.3 login_tty.3 logout.3 logwtmp.3 pty.3 \
setproctitle.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 +29,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 44ccd64..4bdf54f 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
@@ -396,8 +399,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.c b/lib/libutil/login_cap.c
index b7528b9..7410380 100644
--- a/lib/libutil/login_cap.c
+++ b/lib/libutil/login_cap.c
@@ -798,3 +798,16 @@ login_getstyle(login_cap_t *lc, char *style, const char *auth)
return lc->lc_style;
}
+
+const char *
+login_setcryptfmt(login_cap_t *lc, const char *def, const char *error)
+{
+ const char *cipher;
+
+ cipher = login_getcapstr(lc, "passwd_format", def, NULL);
+ if (cipher == NULL)
+ return (error);
+ if (!crypt_set_format(cipher))
+ return (error);
+ return (cipher);
+}
diff --git a/lib/libutil/login_cap.h b/lib/libutil/login_cap.h
index f4b3825..1320278 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/secure/lib/libcrypt/Makefile b/secure/lib/libcrypt/Makefile
index 0721f55..b46df11 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 6508529..e239683 100644
--- a/usr.bin/passwd/local_passwd.c
+++ b/usr.bin/passwd/local_passwd.c
@@ -172,20 +172,13 @@ 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';
- }
+ if (login_setcryptfmt(lc, "md5", NULL) == NULL)
+ pw_error("cannot set password cipher", 1, 1);
+ /* 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 bee05cc..bb82d3a 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 2c491fd..c4e66b4 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;
}
OpenPOWER on IntegriCloud