Annotation of src/usr.bin/encrypt/encrypt.c, Revision 1.5
1.5 ! provos 1: /* $OpenBSD: encrypt.c,v 1.4 1997/03/27 23:43:36 downsj 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 <stdio.h>
29: #include <sys/types.h>
30: #include <err.h>
1.3 downsj 31: #include <errno.h>
1.1 downsj 32: #include <string.h>
33: #include <unistd.h>
1.5 ! provos 34: #include <pwd.h>
1.1 downsj 35:
36: /*
37: * Very simple little program, for encrypting passwords from the command
38: * line. Useful for scripts and such.
39: */
40:
1.5 ! provos 41: #define DO_MAKEKEY 0
! 42: #define DO_DES 1
! 43: #define DO_MD5 2
! 44: #define DO_BLF 3
! 45:
1.1 downsj 46: extern char *optarg;
47: extern int optind;
48:
1.3 downsj 49: char *progname;
1.5 ! provos 50: char buffer[_PASSWORD_LEN];
1.3 downsj 51:
1.1 downsj 52: void usage()
53: {
1.5 ! provos 54: errx(1, "usage: %s [-k] [-b rounds] [-m] [-s salt] [string]", progname);
1.1 downsj 55: }
56:
1.2 downsj 57: char *trim(line)
58: char *line;
59: {
60: char *ptr;
61:
62: for (ptr = &line[strlen(line)-1]; ptr > line; ptr--) {
63: if (!isspace(*ptr))
64: break;
65: }
66: ptr[1] = '\0';
67:
68: for (ptr = line; *ptr && isspace(*ptr); ptr++);
69:
70: return(ptr);
71: }
72:
1.5 ! provos 73: void print_passwd(char *string, int operation, void *extra)
! 74: {
! 75: char msalt[3], *salt;
! 76: struct passwd pwd;
! 77: extern char *bcrypt_gensalt __P((int));
! 78: extern pwd_gensalt __P((char *, int, struct passwd *, char));
! 79:
! 80: switch(operation) {
! 81: case DO_MAKEKEY:
! 82: /*
! 83: * makekey mode: parse string into seperate DES key and salt.
! 84: */
! 85: if (strlen(string) != 10) {
! 86: /* To be compatible... */
! 87: fprintf (stderr, "%s: %s\n", progname, strerror(EFTYPE));
! 88: exit (1);
! 89: }
! 90: strcpy(msalt, &string[8]);
! 91: salt = msalt;
! 92: break;
! 93: case DO_MD5:
! 94: strcpy(buffer, "$1$");
! 95: to64(&buffer[3], arc4random(), 4);
! 96: to64(&buffer[7], arc4random(), 4);
! 97: strcpy(buffer+11, "$");
! 98: salt = buffer;
! 99: break;
! 100: case DO_BLF:
! 101: strncpy(buffer, bcrypt_gensalt(*(int *)extra), _PASSWORD_LEN - 1);
! 102: buffer[_PASSWORD_LEN-1] = 0;
! 103: salt = buffer;
! 104: break;
! 105: case DO_DES:
! 106: salt = extra;
! 107: break;
! 108: default:
! 109: pwd.pw_name = "default";
! 110: if (!pwd_gensalt(buffer, _PASSWORD_LEN, &pwd, 'l')) {
! 111: fprintf (stderr, "%s: Can't generate salt\n", progname);
! 112: exit (1);
! 113: }
! 114: salt = buffer;
! 115: break;
! 116: }
! 117:
! 118: fputs(crypt(string, salt), stdout);
! 119: }
! 120:
1.1 downsj 121: int main(argc, argv)
122: int argc;
123: char *argv[];
124: {
125: int opt;
1.5 ! provos 126: int operation = -1;
! 127: int rounds;
! 128: void *extra; /* Store salt or number of rounds */
1.1 downsj 129:
1.3 downsj 130: if ((progname = strrchr(argv[0], '/')))
131: progname++;
132: else
133: progname = argv[0];
134:
135: if (strcmp(progname, "makekey") == 0)
1.5 ! provos 136: operation = DO_MAKEKEY;
1.3 downsj 137:
1.5 ! provos 138: while ((opt = getopt(argc, argv, "kms:b:")) != -1) {
1.1 downsj 139: switch (opt) {
1.5 ! provos 140: case 'k': /* Stdin/Stdout Unix crypt */
! 141: if (operation != -1)
! 142: usage();
! 143: operation = DO_MAKEKEY;
1.3 downsj 144: break;
1.5 ! provos 145: case 'm': /* MD5 password hash */
! 146: if (operation != -1)
! 147: usage();
! 148: operation = DO_MD5;
1.1 downsj 149: break;
1.5 ! provos 150: case 's': /* Unix crypt (DES) */
! 151: if (operation != -1)
! 152: usage();
! 153: operation = DO_DES;
! 154: if (optarg[0] == '$') /* -s is only for DES. */
1.4 downsj 155: usage();
1.5 ! provos 156: extra = optarg;
1.1 downsj 157: break;
1.5 ! provos 158: case 'b': /* Blowfish password hash */
! 159: if (operation != -1)
! 160: usage();
! 161: operation = DO_BLF;
! 162: rounds = atoi(optarg);
! 163: extra = &rounds;
! 164: break;
1.1 downsj 165: default:
166: usage();
167: }
168: }
169:
1.5 ! provos 170: if (((argc - optind) < 1) || operation == DO_MAKEKEY) {
! 171: char line[BUFSIZ], *string;
1.1 downsj 172:
173: /* Encrypt stdin to stdout. */
174: while (!feof(stdin) && (fgets(line, sizeof(line), stdin) != NULL)) {
1.2 downsj 175: /* Kill the whitesapce. */
176: string = trim(line);
177: if (*string == '\0')
1.1 downsj 178: continue;
1.5 ! provos 179:
! 180: print_passwd(string, operation, extra);
1.1 downsj 181:
1.5 ! provos 182: if (operation == DO_MAKEKEY) {
1.3 downsj 183: fflush(stdout);
184: break;
185: }
1.1 downsj 186: fputc('\n', stdout);
187: }
188: } else {
189: char *string;
190:
191: /* Perhaps it isn't worth worrying about, but... */
192: string = strdup(argv[optind]);
193: if (string == (char *)NULL)
194: err(1, NULL);
195: /* Wipe the argument. */
196: bzero(argv[optind], strlen(argv[optind]));
197:
1.5 ! provos 198: print_passwd(string, operation, extra);
! 199:
1.1 downsj 200: fputc('\n', stdout);
201:
202: /* Wipe our copy, before we free it. */
203: bzero(string, strlen(string));
204: free(string);
205: }
206: exit(0);
207: }