Annotation of src/usr.bin/encrypt/encrypt.c, Revision 1.15
1.15 ! millert 1: /* $OpenBSD: encrypt.c,v 1.14 2001/07/31 18:12:02 millert 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.3 downsj 51:
1.15 ! millert 52: void
! 53: usage(void)
1.1 downsj 54: {
1.15 ! millert 55:
! 56: (void)fprintf(stderr,
! 57: "usage: %s [-k] [-b rounds] [-m] [-s salt] [-p | string]\n",
! 58: __progname);
! 59: exit(1);
1.1 downsj 60: }
61:
1.15 ! millert 62: char *
! 63: trim(char *line)
1.2 downsj 64: {
1.15 ! millert 65: char *ptr;
1.2 downsj 66:
1.15 ! millert 67: for (ptr = &line[strlen(line)-1]; ptr > line; ptr--) {
! 68: if (!isspace(*ptr))
! 69: break;
! 70: }
! 71: ptr[1] = '\0';
1.2 downsj 72:
1.15 ! millert 73: for (ptr = line; *ptr && isspace(*ptr); ptr++)
! 74: ;
1.2 downsj 75:
1.15 ! millert 76: return(ptr);
1.2 downsj 77: }
78:
1.15 ! millert 79: void
! 80: print_passwd(char *string, int operation, void *extra)
1.5 provos 81: {
1.15 ! millert 82: char msalt[3], *salt;
! 83: struct passwd pwd;
! 84: login_cap_t *lc;
! 85: int pwd_gensalt __P((char *, int, struct passwd *, login_cap_t *, char));
! 86: void to64 __P((char *, int32_t, int n));
! 87:
! 88: switch(operation) {
! 89: case DO_MAKEKEY:
! 90: /*
! 91: * makekey mode: parse string into separate DES key and salt.
! 92: */
! 93: if (strlen(string) != 10) {
! 94: /* To be compatible... */
! 95: errx(1, "%s", strerror(EFTYPE));
! 96: }
! 97: strcpy(msalt, &string[8]);
! 98: salt = msalt;
! 99: break;
! 100:
! 101: case DO_MD5:
! 102: strcpy(buffer, "$1$");
! 103: to64(&buffer[3], arc4random(), 4);
! 104: to64(&buffer[7], arc4random(), 4);
! 105: strcpy(buffer + 11, "$");
! 106: salt = buffer;
! 107: break;
! 108:
! 109: case DO_BLF:
! 110: strlcpy(buffer, bcrypt_gensalt(*(int *)extra), _PASSWORD_LEN);
! 111: salt = buffer;
! 112: break;
! 113:
! 114: case DO_DES:
! 115: salt = extra;
! 116: break;
! 117:
! 118: default:
! 119: pwd.pw_name = "default";
! 120: if ((lc = login_getclass(NULL)) == NULL)
! 121: errx(1, "unable to get default login class.");
! 122: if (!pwd_gensalt(buffer, _PASSWORD_LEN, &pwd, lc, 'l'))
! 123: errx(1, "can't generate salt");
! 124: salt = buffer;
! 125: break;
! 126: }
! 127:
! 128: (void)fputs(crypt(string, salt), stdout);
1.5 provos 129: }
130:
1.15 ! millert 131: int
! 132: main(int argc, char **argv)
1.1 downsj 133: {
1.15 ! millert 134: int opt;
! 135: int operation = -1;
! 136: int prompt = 0;
! 137: int rounds;
! 138: void *extra; /* Store salt or number of rounds */
! 139:
! 140: if (strcmp(__progname, "makekey") == 0)
! 141: operation = DO_MAKEKEY;
! 142:
! 143: while ((opt = getopt(argc, argv, "kmps:b:")) != -1) {
! 144: switch (opt) {
! 145: case 'k': /* Stdin/Stdout Unix crypt */
! 146: if (operation != -1 || prompt)
! 147: usage();
! 148: operation = DO_MAKEKEY;
! 149: break;
! 150:
! 151: case 'm': /* MD5 password hash */
! 152: if (operation != -1)
! 153: usage();
! 154: operation = DO_MD5;
! 155: break;
! 156:
! 157: case 'p':
! 158: if (operation == DO_MAKEKEY)
! 159: usage();
! 160: prompt = 1;
! 161: break;
! 162:
! 163: case 's': /* Unix crypt (DES) */
! 164: if (operation != -1 || optarg[0] == '$')
! 165: usage();
! 166: operation = DO_DES;
! 167: extra = optarg;
! 168: break;
! 169:
! 170: case 'b': /* Blowfish password hash */
! 171: if (operation != -1)
! 172: usage();
! 173: operation = DO_BLF;
! 174: rounds = atoi(optarg);
! 175: extra = &rounds;
! 176: break;
! 177:
! 178: default:
! 179: usage();
! 180: }
1.1 downsj 181: }
182:
1.15 ! millert 183: if (((argc - optind) < 1) || operation == DO_MAKEKEY) {
! 184: char line[BUFSIZ], *string;
1.1 downsj 185:
1.15 ! millert 186: if (prompt) {
! 187: string = getpass("Enter string: ");
! 188: print_passwd(string, operation, extra);
! 189: (void)fputc('\n', stdout);
! 190: } else {
! 191: /* Encrypt stdin to stdout. */
! 192: while (!feof(stdin) &&
! 193: (fgets(line, sizeof(line), stdin) != NULL)) {
! 194: /* Kill the whitesapce. */
! 195: string = trim(line);
! 196: if (*string == '\0')
! 197: continue;
! 198:
! 199: print_passwd(string, operation, extra);
! 200:
! 201: if (operation == DO_MAKEKEY) {
! 202: fflush(stdout);
! 203: break;
! 204: }
! 205: (void)fputc('\n', stdout);
! 206: }
! 207: }
1.9 alex 208: } else {
1.15 ! millert 209: char *string;
! 210:
! 211: /* can't combine -p with a supplied string */
! 212: if (prompt)
! 213: usage();
! 214:
! 215: /* Perhaps it isn't worth worrying about, but... */
! 216: if ((string = strdup(argv[optind])) == NULL)
! 217: err(1, NULL);
! 218: /* Wipe the argument. */
! 219: memset(argv[optind], 0, strlen(argv[optind]));
! 220:
1.9 alex 221: print_passwd(string, operation, extra);
222:
1.15 ! millert 223: (void)fputc('\n', stdout);
! 224:
! 225: /* Wipe our copy, before we free it. */
! 226: memset(string, 0, strlen(string));
! 227: free(string);
1.1 downsj 228: }
1.15 ! millert 229: exit(0);
1.1 downsj 230: }