Annotation of src/usr.bin/encrypt/encrypt.c, Revision 1.23
1.23 ! moritz 1: /* $OpenBSD: encrypt.c,v 1.22 2006/04/02 04:13:07 deraadt Exp $ */
1.1 downsj 2:
3: /*
4: * Copyright (c) 1996, Jason Downs. All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: *
15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
16: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
19: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25: * SUCH DAMAGE.
26: */
27:
28: #include <sys/types.h>
1.15 millert 29: #include <ctype.h>
1.1 downsj 30: #include <err.h>
1.3 downsj 31: #include <errno.h>
1.15 millert 32: #include <pwd.h>
33: #include <stdio.h>
1.7 kstailey 34: #include <stdlib.h>
1.1 downsj 35: #include <string.h>
36: #include <unistd.h>
1.14 millert 37: #include <login_cap.h>
1.1 downsj 38:
39: /*
40: * Very simple little program, for encrypting passwords from the command
41: * line. Useful for scripts and such.
42: */
43:
1.5 provos 44: #define DO_MAKEKEY 0
45: #define DO_DES 1
46: #define DO_MD5 2
47: #define DO_BLF 3
48:
1.15 millert 49: extern char *__progname;
1.5 provos 50: char buffer[_PASSWORD_LEN];
1.19 deraadt 51:
52: void usage(void);
53: char *trim(char *);
54: void print_passwd(char *, int, void *);
1.3 downsj 55:
1.15 millert 56: void
57: usage(void)
1.1 downsj 58: {
1.15 millert 59:
60: (void)fprintf(stderr,
1.18 millert 61: "usage: %s [-k] [-b rounds] [-c class] [-m] [-s salt] [-p | string]\n",
1.15 millert 62: __progname);
63: exit(1);
1.1 downsj 64: }
65:
1.15 millert 66: char *
67: trim(char *line)
1.2 downsj 68: {
1.15 millert 69: char *ptr;
1.2 downsj 70:
1.15 millert 71: for (ptr = &line[strlen(line)-1]; ptr > line; ptr--) {
72: if (!isspace(*ptr))
73: break;
74: }
75: ptr[1] = '\0';
1.2 downsj 76:
1.15 millert 77: for (ptr = line; *ptr && isspace(*ptr); ptr++)
78: ;
1.2 downsj 79:
1.15 millert 80: return(ptr);
1.2 downsj 81: }
82:
1.15 millert 83: void
84: print_passwd(char *string, int operation, void *extra)
1.5 provos 85: {
1.23 ! moritz 86: char msalt[3], *salt, *cryptstr;
1.15 millert 87: login_cap_t *lc;
1.21 millert 88: int pwd_gensalt(char *, int, login_cap_t *, char);
1.22 deraadt 89: void to64(char *, u_int32_t, int n);
1.15 millert 90:
91: switch(operation) {
92: case DO_MAKEKEY:
93: /*
94: * makekey mode: parse string into separate DES key and salt.
95: */
96: if (strlen(string) != 10) {
97: /* To be compatible... */
98: errx(1, "%s", strerror(EFTYPE));
99: }
1.17 deraadt 100: strlcpy(msalt, &string[8], sizeof msalt);
1.15 millert 101: salt = msalt;
102: break;
103:
104: case DO_MD5:
1.17 deraadt 105: strlcpy(buffer, "$1$", sizeof buffer);
1.15 millert 106: to64(&buffer[3], arc4random(), 4);
107: to64(&buffer[7], arc4random(), 4);
1.17 deraadt 108: strlcpy(buffer + 11, "$", sizeof buffer - 11);
1.15 millert 109: salt = buffer;
110: break;
111:
112: case DO_BLF:
113: strlcpy(buffer, bcrypt_gensalt(*(int *)extra), _PASSWORD_LEN);
114: salt = buffer;
115: break;
116:
117: case DO_DES:
118: salt = extra;
119: break;
120:
121: default:
1.18 millert 122: if ((lc = login_getclass(extra)) == NULL)
123: errx(1, "unable to get login class `%s'",
124: extra ? (char *)extra : "default");
1.21 millert 125: if (!pwd_gensalt(buffer, _PASSWORD_LEN, lc, 'l'))
1.15 millert 126: errx(1, "can't generate salt");
127: salt = buffer;
128: break;
129: }
130:
1.23 ! moritz 131: if ((cryptstr = crypt(string, salt)) == NULL)
! 132: errx(1, "crypt failed");
! 133: fputs(cryptstr, stdout);
1.5 provos 134: }
135:
1.15 millert 136: int
137: main(int argc, char **argv)
1.1 downsj 138: {
1.15 millert 139: int opt;
140: int operation = -1;
141: int prompt = 0;
142: int rounds;
1.18 millert 143: void *extra = NULL; /* Store salt or number of rounds */
1.15 millert 144:
145: if (strcmp(__progname, "makekey") == 0)
146: operation = DO_MAKEKEY;
147:
1.18 millert 148: while ((opt = getopt(argc, argv, "kmps:b:c:")) != -1) {
1.15 millert 149: switch (opt) {
150: case 'k': /* Stdin/Stdout Unix crypt */
151: if (operation != -1 || prompt)
152: usage();
153: operation = DO_MAKEKEY;
154: break;
155:
156: case 'm': /* MD5 password hash */
157: if (operation != -1)
158: usage();
159: operation = DO_MD5;
160: break;
161:
162: case 'p':
163: if (operation == DO_MAKEKEY)
164: usage();
165: prompt = 1;
166: break;
167:
168: case 's': /* Unix crypt (DES) */
169: if (operation != -1 || optarg[0] == '$')
170: usage();
171: operation = DO_DES;
172: extra = optarg;
173: break;
174:
175: case 'b': /* Blowfish password hash */
176: if (operation != -1)
177: usage();
178: operation = DO_BLF;
179: rounds = atoi(optarg);
180: extra = &rounds;
1.18 millert 181: break;
182:
183: case 'c': /* user login class */
184: extra = optarg;
185: operation = -1;
1.15 millert 186: break;
187:
188: default:
189: usage();
190: }
1.1 downsj 191: }
192:
1.15 millert 193: if (((argc - optind) < 1) || operation == DO_MAKEKEY) {
194: char line[BUFSIZ], *string;
1.1 downsj 195:
1.15 millert 196: if (prompt) {
1.20 otto 197: if ((string = getpass("Enter string: ")) == NULL)
198: err(1, "getpass");
1.15 millert 199: print_passwd(string, operation, extra);
200: (void)fputc('\n', stdout);
201: } else {
202: /* Encrypt stdin to stdout. */
203: while (!feof(stdin) &&
204: (fgets(line, sizeof(line), stdin) != NULL)) {
205: /* Kill the whitesapce. */
206: string = trim(line);
207: if (*string == '\0')
208: continue;
209:
210: print_passwd(string, operation, extra);
211:
212: if (operation == DO_MAKEKEY) {
213: fflush(stdout);
214: break;
215: }
216: (void)fputc('\n', stdout);
217: }
218: }
1.9 alex 219: } else {
1.15 millert 220: char *string;
221:
222: /* can't combine -p with a supplied string */
223: if (prompt)
224: usage();
225:
226: /* Perhaps it isn't worth worrying about, but... */
227: if ((string = strdup(argv[optind])) == NULL)
228: err(1, NULL);
229: /* Wipe the argument. */
230: memset(argv[optind], 0, strlen(argv[optind]));
231:
1.9 alex 232: print_passwd(string, operation, extra);
233:
1.15 millert 234: (void)fputc('\n', stdout);
235:
236: /* Wipe our copy, before we free it. */
237: memset(string, 0, strlen(string));
238: free(string);
1.1 downsj 239: }
1.15 millert 240: exit(0);
1.1 downsj 241: }