Annotation of src/usr.bin/passwd/pwd_gensalt.c, Revision 1.6
1.1 provos 1: /*
2: * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
1.2 provos 15: * This product includes software developed by Niels Provos.
1.1 provos 16: * 4. The name of the author may not be used to endorse or promote products
17: * derived from this software without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29: */
30:
1.2 provos 31: #include <sys/syslimits.h>
1.1 provos 32: #include <stdio.h>
1.4 weingart 33: #include <stdlib.h>
1.1 provos 34: #include <string.h>
35: #include <err.h>
36: #include <pwd.h>
1.2 provos 37: #include <util.h>
1.4 weingart 38: #include <time.h>
1.1 provos 39:
1.6 ! deraadt 40: void to64 __P((char *, int32_t, int n));
1.1 provos 41:
1.2 provos 42: int
1.1 provos 43: pwd_gensalt(salt, max, pwd, type)
44: char *salt;
45: int max;
46: struct passwd *pwd;
47: char type;
48: {
49: char *bcrypt_gensalt __P((u_int8_t));
50: char option[LINE_MAX];
51: char *next, *now;
52: *salt = '\0';
53:
54: switch (type) {
55: case 'y':
1.2 provos 56: pw_getconf(option, LINE_MAX, pwd->pw_name, "ypcipher");
1.1 provos 57: break;
58: case 'l':
59: default:
1.2 provos 60: pw_getconf(option, LINE_MAX, pwd->pw_name, "localcipher");
1.1 provos 61: break;
62: }
63:
64: next = option;
65: now = strsep(&next, ",");
66: if (!strcmp(now, "old")) {
1.6 ! deraadt 67: if (max < 3)
1.2 provos 68: return 0;
1.5 provos 69: to64(&salt[0], arc4random(), 2);
1.2 provos 70: salt[2] = '\0';
1.3 provos 71: } else if (!strcmp(now, "newsalt")) {
1.6 ! deraadt 72: if (max < 10)
1.3 provos 73: return 0;
74: salt[0] = _PASSWORD_EFMT1;
1.6 ! deraadt 75: to64(&salt[1], (int32_t) (29 * 25), 4);
1.5 provos 76: to64(&salt[5], arc4random(), 4);
1.3 provos 77: salt[9] = '\0';
78: } else if (!strcmp(now, "md5")) {
1.6 ! deraadt 79: if (max < 13) /* $1$8salt$\0 */
1.3 provos 80: return 0;
81: strcpy(salt, "$1$");
1.5 provos 82: to64(&salt[3], arc4random(), 4);
83: to64(&salt[7], arc4random(), 4);
1.3 provos 84: strcpy(&salt[11], "$");
85: } else if (!strcmp(now, "blowfish")) {
86: int rounds = atoi(next);
87: if (rounds < 4)
88: rounds = 4;
89: strncpy(salt, bcrypt_gensalt(rounds), max - 1);
90: salt[max - 1] = 0;
91: } else {
92: strcpy(salt, ":");
93: warnx("Unkown option %s.", now);
94: }
1.2 provos 95: return 1;
96: }
97:
1.6 ! deraadt 98: static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
! 99: "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1.2 provos 100:
1.6 ! deraadt 101: void
! 102: to64(s, v, n)
! 103: register char *s;
! 104: register int32_t v;
! 105: register int n;
1.2 provos 106: {
1.6 ! deraadt 107: while (--n >= 0) {
! 108: *s++ = itoa64[v&0x3f];
! 109: v >>= 6;
! 110: }
1.1 provos 111: }