xref: /openbsd/usr.bin/encrypt/encrypt.c (revision ea130701)
1 /*	$OpenBSD: encrypt.c,v 1.37 2015/01/05 14:07:12 tedu Exp $	*/
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>
29 #include <ctype.h>
30 #include <err.h>
31 #include <errno.h>
32 #include <pwd.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <login_cap.h>
38 #include <limits.h>
39 
40 /*
41  * Very simple little program, for encrypting passwords from the command
42  * line.  Useful for scripts and such.
43  */
44 
45 extern char *__progname;
46 
47 void	usage(void);
48 
49 #define DO_BLF		0
50 
51 void
52 usage(void)
53 {
54 
55 	(void)fprintf(stderr,
56 	    "usage: %s [-b rounds] [-c class] [-p | string]\n",
57 	    __progname);
58 	exit(1);
59 }
60 
61 static void
62 print_passwd(char *string, int operation, char *extra)
63 {
64 	char buffer[_PASSWORD_LEN];
65 	const char *pref;
66 	char prefbuf[16];
67 
68 	if (operation == DO_BLF) {
69 		snprintf(prefbuf, sizeof(prefbuf), "blowfish,%s", extra);
70 		pref = prefbuf;
71 	} else {
72 		login_cap_t *lc;
73 
74 		if ((lc = login_getclass(extra)) == NULL)
75 			errx(1, "unable to get login class `%s'",
76 			    extra ? (char *)extra : "default");
77 		pref = login_getcapstr(lc, "localcipher", NULL, NULL);
78 	}
79 	if (crypt_newhash(string, pref, buffer, sizeof(buffer)) != 0)
80 		errx(1, "can't generate hash");
81 
82 	fputs(buffer, stdout);
83 }
84 
85 int
86 main(int argc, char **argv)
87 {
88 	int opt;
89 	int operation = -1;
90 	int prompt = 0;
91 	int rounds;
92 	char *extra = NULL;		/* Store salt or number of rounds */
93 	const char *errstr;
94 
95 	while ((opt = getopt(argc, argv, "pb:c:")) != -1) {
96 		switch (opt) {
97 		case 'p':
98 			prompt = 1;
99 			break;
100 		case 'b':                       /* Blowfish password hash */
101 			if (operation != -1)
102 				usage();
103 			operation = DO_BLF;
104 			if (strcmp(optarg, "a") != 0) {
105 				(void)strtonum(optarg, 4, 31, &errstr);
106 				if (errstr != NULL)
107 					errx(1, "rounds is %s: %s", errstr, optarg);
108 			}
109 			extra = optarg;
110 			break;
111 		case 'c':                       /* user login class */
112 			extra = optarg;
113 			operation = -1;
114 			break;
115 		default:
116 			usage();
117 		}
118 	}
119 
120 	if (((argc - optind) < 1)) {
121 		char line[BUFSIZ], *string;
122 
123 		if (prompt) {
124 			if ((string = getpass("Enter string: ")) == NULL)
125 				err(1, "getpass");
126 			print_passwd(string, operation, extra);
127 			(void)fputc('\n', stdout);
128 		} else {
129 			size_t len;
130 			/* Encrypt stdin to stdout. */
131 			while (!feof(stdin) &&
132 			    (fgets(line, sizeof(line), stdin) != NULL)) {
133 			    	len = strlen(line);
134 				if (len == 0 || line[0] == '\n')
135 					continue;
136 				if (line[len - 1] == '\n')
137                      			line[len - 1] = '\0';
138 
139 				print_passwd(line, operation, extra);
140 
141 				(void)fputc('\n', stdout);
142 			}
143 		}
144 	} else {
145 		char *string;
146 
147 		/* can't combine -p with a supplied string */
148 		if (prompt)
149 			usage();
150 
151 		/* Perhaps it isn't worth worrying about, but... */
152 		if ((string = strdup(argv[optind])) == NULL)
153 			err(1, NULL);
154 		/* Wipe the argument. */
155 		memset(argv[optind], 0, strlen(argv[optind]));
156 
157 		print_passwd(string, operation, extra);
158 
159 		(void)fputc('\n', stdout);
160 
161 		/* Wipe our copy, before we free it. */
162 		memset(string, 0, strlen(string));
163 		free(string);
164 	}
165 	exit(0);
166 }
167