include blowfish cipher - free config of which cipher to use
authorprovos <provos@openbsd.org>
Fri, 14 Feb 1997 23:27:25 +0000 (23:27 +0000)
committerprovos <provos@openbsd.org>
Fri, 14 Feb 1997 23:27:25 +0000 (23:27 +0000)
usr.bin/passwd/Makefile
usr.bin/passwd/local_passwd.c
usr.bin/passwd/pwd_gensalt.c [new file with mode: 0644]
usr.bin/passwd/yp_passwd.c

index 96bf8b3..06f02b8 100644 (file)
@@ -1,13 +1,13 @@
-#      $OpenBSD: Makefile,v 1.11 1997/01/02 16:34:51 etheisen Exp $
+#      $OpenBSD: Makefile,v 1.12 1997/02/14 23:27:25 provos Exp $
 
 .include <bsd.own.mk>
 
 PROG=  passwd
-SRCS=  local_passwd.c yp_passwd.c passwd.c getpwent.c
+SRCS=  local_passwd.c yp_passwd.c passwd.c getpwent.c pwd_gensalt.c
 .PATH:  ${.CURDIR}/../../lib/libc/gen
 DPADD+= ${LIBRPCSVC} ${LIBCRYPT} ${LIBUTIL}
 LDADD+= -lrpcsvc -lutil
-CFLAGS+=-I${.CURDIR}
+CFLAGS+= -I${.CURDIR}
 
 .if defined(YP)
 CFLAGS+=-DYP -I${.CURDIR}/../../lib/libc/yp
index f48411e..c367545 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: local_passwd.c,v 1.4 1996/09/30 01:54:48 millert Exp $        */
+/*     $OpenBSD: local_passwd.c,v 1.5 1997/02/14 23:27:28 provos Exp $ */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -35,7 +35,7 @@
 
 #ifndef lint
 /*static char sccsid[] = "from: @(#)local_passwd.c     5.5 (Berkeley) 5/6/91";*/
-static char rcsid[] = "$OpenBSD: local_passwd.c,v 1.4 1996/09/30 01:54:48 millert Exp $";
+static char rcsid[] = "$OpenBSD: local_passwd.c,v 1.5 1997/02/14 23:27:28 provos Exp $";
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -107,7 +107,8 @@ getnewpasswd(pw)
 {
        register char *p, *t;
        int tries;
-       char buf[_PASSWORD_LEN+1], salt[9], *crypt(), *getpass();
+       char buf[_PASSWORD_LEN+1], salt[_PASSWORD_LEN], *crypt(), *getpass();
+       void pwd_gensalt __P(( char *, int, struct passwd *, char));
 
        (void)printf("Changing local password for %s.\n", pw->pw_name);
 
@@ -138,15 +139,7 @@ getnewpasswd(pw)
                        break;
                (void)printf("Mismatch; try again, EOF to quit.\n");
        }
-       /* grab a random printable character that isn't a colon */
-       (void)srandom((int)time((time_t *)NULL));
-#ifdef NEWSALT
-       salt[0] = _PASSWORD_EFMT1;
-       to64(&salt[1], (long)(29 * 25), 4);
-       to64(&salt[5], random(), 4);
-#else
-       to64(&salt[0], random(), 2);
-#endif
+       pwd_gensalt( salt, _PASSWORD_LEN, pw, 'l' );
        return(crypt(buf, salt));
 }
 
diff --git a/usr.bin/passwd/pwd_gensalt.c b/usr.bin/passwd/pwd_gensalt.c
new file mode 100644 (file)
index 0000000..9f84b47
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Theo de Raadt.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <err.h>
+#include <pwd.h>
+
+
+#define NUM_OPTIONS    2       /* Number of hardcoded defaults */
+#define LINE_MAX       100     /* Max. length of one config file */
+
+static const char options[NUM_OPTIONS][2][80] =
+{
+       {"local_cipher", "blowfish,4"},
+       {"yp_cipher", "old"}
+};
+/* Read lines and removes trailers. */
+
+static int
+read_line(fp, line, max)
+       FILE   *fp;
+       char   *line;
+       int     max;
+{
+       char   *p, *c;
+       /* Read one line of config */
+       if (fgets(line, max, fp) == 0)
+               return 0;
+       if (!(p = strchr(line, '\n'))) {
+               warnx("line too long");
+               return 0;
+       }
+       *p = '\0';
+
+       /* Remove comments */
+       if ((p = strchr(line, '#')))
+               *p = '\0';
+
+       /* Remove trailing spaces */
+       p = line;
+       while (isspace(*p))
+               p++;
+       memcpy(line, p, strlen(p) + 1);
+
+       p = line + strlen(line) - 1;
+       while (isspace(*p))
+               p--;
+       *(p + 1) = '\0';
+       return 1;
+}
+
+
+static const char *
+pwd_default(option)
+       char   *option;
+{
+       int     i;
+       for (i = 0; i < NUM_OPTIONS; i++)
+               if (!strcasecmp(options[i][0], option))
+                       return options[i][1];
+       return NULL;
+}
+
+void
+pwd_gettype(data, max, key, option)
+       char   *data;
+       int     max;
+       char   *key;
+       char   *option;
+{
+       FILE   *fp;
+       char    line[LINE_MAX];
+       static char result[LINE_MAX];
+       int     defaultw;
+       int     keyw;
+       int     got;
+       result[0] = '\0';
+       if ((fp = fopen(_PATH_PASSWDCONF, "r")) == NULL) {
+               strncpy(data, pwd_default(option), max - 1);
+               data[max - 1] = '\0';
+               return;
+       }
+       defaultw = 0;
+       keyw = 0;
+       got = 0;
+       while (!keyw && (got || read_line(fp, line, LINE_MAX))) {
+               got = 0;
+               if (!strcmp("default:", line))
+                       defaultw = 1;
+               if (!strncmp(key, line, strlen(key)) &&
+                   line[strlen(key)] == ':')
+                       keyw = 1;
+
+               /* Now we found default or specified key */
+               if (defaultw || keyw) {
+                       while (read_line(fp, line, LINE_MAX)) {
+                               /* Leaving key field */
+                               if (strchr(line, ':')) {
+                                       got = 1;
+                                       break;
+                               }
+                               if (!strncmp(line, option, strlen(option)) &&
+                                   line[strlen(option)] == '=') {
+                                       char   *p;
+                                       p = line + strlen(option) + 1;
+                                       while (isspace(*p))
+                                               p++;
+                                       strcpy(result, p);
+                                       break;
+                               }
+                       }
+                       if (keyw)
+                               break;
+                       defaultw = 0;
+               }
+       }
+       fclose(fp);
+       if (!strlen(result)) {
+               strncpy(data, pwd_default(option), max - 1);
+               data[max - 1] = '\0';
+               return;
+       }
+       strncpy(data, result, max - 1);
+       data[max - 1] = '\0';
+}
+
+void
+pwd_gensalt(salt, max, pwd, type)
+       char   *salt;
+       int     max;
+       struct passwd *pwd;
+       char    type;
+{
+       char   *bcrypt_gensalt __P((u_int8_t));
+       char    option[LINE_MAX];
+       char   *next, *now;
+       *salt = '\0';
+       if (max < 10)
+               return;
+
+       switch (type) {
+       case 'y':
+               pwd_gettype(option, LINE_MAX, pwd->pw_name, "yp_cipher");
+               break;
+       case 'l':
+       default:
+               pwd_gettype(option, LINE_MAX, pwd->pw_name, "local_cipher");
+               break;
+       }
+
+       next = option;
+       now = strsep(&next, ",");
+       if (!strcmp(now, "old")) {
+               (void) srandom((int) time((time_t *) NULL));
+               to64(&salt[0], random(), 2);
+       } else
+               if (!strcmp(now, "newsalt")) {
+                       (void) srandom((int) time((time_t *) NULL));
+                       salt[0] = _PASSWORD_EFMT1;
+                       to64(&salt[1], (long) (29 * 25), 4);
+                       to64(&salt[5], random(), 4);
+               } else
+                       if (!strcmp(now, "blowfish")) {
+                               int     rounds = atoi(next);
+                               if (rounds < 4)
+                                       rounds = 4;
+                               strncpy(salt, bcrypt_gensalt(rounds), max - 1);
+                               salt[max - 1] = 0;
+                       } else {
+                               strcpy(salt, ":");
+                               warnx("Unkown option %s.", now);
+                       }
+}
index 5c7570c..84e563f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: yp_passwd.c,v 1.4 1996/08/30 13:37:53 deraadt Exp $   */
+/*     $OpenBSD: yp_passwd.c,v 1.5 1997/02/14 23:27:31 provos Exp $    */
 
 /*
  * Copyright (c) 1988 The Regents of the University of California.
@@ -34,7 +34,7 @@
  */
 #ifndef lint
 /*static char sccsid[] = "from: @(#)yp_passwd.c        1.0 2/2/93";*/
-static char rcsid[] = "$OpenBSD: yp_passwd.c,v 1.4 1996/08/30 13:37:53 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: yp_passwd.c,v 1.5 1997/02/14 23:27:31 provos Exp $";
 #endif /* not lint */
 
 #ifdef YP
@@ -191,7 +191,8 @@ getnewpasswd(pw, old_pass)
        static char buf[_PASSWORD_LEN+1];
        register char *p, *t;
        int tries;
-       char salt[9], *crypt(), *getpass();
+       char salt[_PASSWORD_LEN], *crypt(), *getpass();
+       void pwd_gensalt __P(( char *, int, struct passwd *, char));
        
        printf("Changing YP password for %s.\n", pw->pw_name);
 
@@ -230,15 +231,7 @@ getnewpasswd(pw, old_pass)
                        break;
                (void)printf("Mismatch; try again, EOF to quit.\n");
        }
-       /* grab a random printable character that isn't a colon */
-       (void)srandom((int)time((time_t *)NULL));
-#ifdef NEWSALT
-       salt[0] = _PASSWORD_EFMT1;
-       to64(&salt[1], (long)(29 * 25), 4);
-       to64(&salt[5], random(), 4);
-#else
-       to64(&salt[0], random(), 2);
-#endif
+       pwd_gensalt( salt, _PASSWORD_LEN, pw, 'y' );
        return(strdup(crypt(buf, salt)));
 }