Commit | Line | Data |
---|---|---|
d9898ee8 | 1 | /* |
2 | ** Copyright 1998 - 2006 Double Precision, Inc. | |
3 | ** See COPYING for distribution information. | |
4 | */ | |
5 | ||
6 | #if HAVE_CONFIG_H | |
7 | #include "config.h" | |
8 | #endif | |
9 | #include <sys/types.h> | |
10 | #if HAVE_SYS_STAT_H | |
11 | #include <sys/stat.h> | |
12 | #endif | |
13 | #if HAVE_FCNTL_H | |
14 | #include <fcntl.h> | |
15 | #endif | |
16 | #if HAVE_UNISTD_H | |
17 | #include <unistd.h> | |
18 | #endif | |
19 | #if TIME_WITH_SYS_TIME | |
20 | #include <sys/time.h> | |
21 | #include <time.h> | |
22 | #else | |
23 | #if HAVE_SYS_TIME_H | |
24 | #include <sys/time.h> | |
25 | #else | |
26 | #include <time.h> | |
27 | #endif | |
28 | #endif | |
29 | #if HAVE_MD5 | |
30 | #include "md5/md5.h" | |
31 | #endif | |
32 | #if HAVE_HMAC | |
33 | #include "libhmac/hmac.h" | |
34 | #endif | |
35 | ||
0e333c05 CE |
36 | #if HAVE_BCRYPT |
37 | #include <pwd.h> | |
38 | #endif | |
d9898ee8 | 39 | #include <string.h> |
40 | #include <stdio.h> | |
41 | #include <signal.h> | |
42 | #include <stdlib.h> | |
43 | #if HAVE_TERMIOS_H | |
44 | #include <termios.h> | |
45 | #endif | |
46 | #if HAVE_CRYPT_H | |
47 | #include <crypt.h> | |
48 | #endif | |
49 | ||
50 | #if HAVE_CRYPT | |
51 | #if NEED_CRYPT_PROTOTYPE | |
52 | extern char *crypt(const char *, const char *); | |
53 | #endif | |
54 | #endif | |
55 | ||
56 | extern char userdb_hex64[]; | |
57 | ||
58 | #ifdef RANDOM | |
59 | extern void userdb_get_random(char *buf, unsigned n); | |
60 | #endif | |
61 | ||
62 | #if HAVE_MD5 | |
63 | ||
64 | char *userdb_mkmd5pw(const char *); | |
65 | ||
66 | #endif | |
67 | ||
68 | /* | |
69 | ** Where possible, we turn off echo when entering the password. | |
70 | ** We set up a signal handler to catch signals and restore the echo | |
71 | ** prior to exiting. | |
72 | */ | |
73 | ||
74 | #if HAVE_TERMIOS_H | |
75 | static struct termios tios; | |
76 | static int have_tios; | |
77 | ||
78 | static RETSIGTYPE sighandler(int signum) | |
79 | { | |
80 | if (write(1, "\n", 1) < 0) | |
81 | ; /* ignore gcc warning */ | |
82 | tcsetattr(0, TCSANOW, &tios); | |
83 | _exit(0); | |
84 | #if RETSIGTYPE != void | |
85 | return (0); | |
86 | #endif | |
87 | } | |
88 | #endif | |
89 | ||
90 | static void read_pw(char *buf) | |
91 | { | |
92 | int n, c; | |
93 | ||
94 | n=0; | |
95 | while ((c=getchar()) != EOF && c != '\n') | |
96 | if (n < BUFSIZ-1) | |
97 | buf[n++]=c; | |
98 | if (c == EOF && n == 0) exit(1); | |
99 | buf[n]=0; | |
100 | } | |
101 | ||
102 | int main(int argc, char **argv) | |
103 | { | |
104 | int n=1; | |
105 | int md5=0; | |
106 | char buf[BUFSIZ]; | |
107 | char salt[9]; | |
0e333c05 CE |
108 | #if HAVE_BCRYPT |
109 | char *cryptsalt; | |
110 | #endif | |
d9898ee8 | 111 | #if HAVE_HMAC |
112 | struct hmac_hashinfo *hmac=0; | |
113 | #endif | |
114 | ||
115 | while (n < argc) | |
116 | { | |
117 | if (strcmp(argv[n], "-md5") == 0) | |
118 | { | |
119 | md5=1; | |
120 | ++n; | |
121 | continue; | |
122 | } | |
123 | #if HAVE_HMAC | |
124 | if (strncmp(argv[n], "-hmac-", 6) == 0) | |
125 | { | |
126 | int i; | |
127 | ||
128 | for (i=0; hmac_list[i] && | |
129 | strcmp(hmac_list[i]->hh_name, argv[n]+6); i++) | |
130 | ; | |
131 | if (hmac_list[i]) | |
132 | { | |
133 | hmac=hmac_list[i]; | |
134 | ++n; | |
135 | continue; | |
136 | } | |
137 | } | |
138 | #endif | |
139 | fprintf(stderr, "%s: invalid argument.\n", argv[0]); | |
140 | exit(1); | |
141 | } | |
142 | ||
143 | /* Read the password */ | |
144 | #if HAVE_TERMIOS_H | |
145 | ||
146 | have_tios=0; | |
147 | if (tcgetattr(0, &tios) == 0) | |
148 | { | |
149 | struct termios tios2; | |
150 | char buf2[BUFSIZ]; | |
151 | ||
152 | have_tios=1; | |
153 | signal(SIGINT, sighandler); | |
154 | signal(SIGHUP, sighandler); | |
155 | tios2=tios; | |
156 | tios2.c_lflag &= ~ECHO; | |
157 | tcsetattr(0, TCSANOW, &tios2); | |
158 | ||
159 | for (;;) | |
160 | { | |
161 | if (write(2, "Password: ", 10) < 0) | |
162 | ; /* ignore gcc warning */ | |
163 | read_pw(buf); | |
164 | if (write(2, "\nReenter password: ", 19) < 0) | |
165 | ; /* ignore gcc warning */ | |
166 | read_pw(buf2); | |
167 | if (strcmp(buf, buf2) == 0) break; | |
168 | if (write(2, "\nPasswords don't match.\n\n", 25) < 0) | |
169 | ; /* ignore gcc warning */ | |
170 | } | |
171 | ||
172 | } | |
173 | else | |
174 | #endif | |
175 | read_pw(buf); | |
176 | ||
177 | #if HAVE_TERMIOS_H | |
178 | if (have_tios) | |
179 | { | |
180 | if (write(2, "\n", 1) < 0) | |
181 | ; /* ignore gcc warning */ | |
182 | ||
183 | tcsetattr(0, TCSANOW, &tios); | |
184 | signal(SIGINT, SIG_DFL); | |
185 | signal(SIGHUP, SIG_DFL); | |
186 | } | |
187 | #endif | |
188 | ||
189 | /* Set the password */ | |
190 | ||
191 | #if HAVE_HMAC | |
192 | if (hmac) | |
193 | { | |
194 | unsigned char *p=malloc(hmac->hh_L*2); | |
195 | unsigned i; | |
196 | ||
197 | if (!p) | |
198 | { | |
199 | perror("malloc"); | |
200 | exit(1); | |
201 | } | |
202 | ||
203 | hmac_hashkey(hmac, buf, strlen(buf), p, p+hmac->hh_L); | |
204 | for (i=0; i<hmac->hh_L*2; i++) | |
205 | printf("%02x", (int)p[i]); | |
206 | printf("\n"); | |
207 | exit(0); | |
208 | } | |
209 | #endif | |
210 | ||
211 | #if HAVE_CRYPT | |
212 | ||
213 | #else | |
214 | md5=1; | |
215 | #endif | |
216 | ||
217 | #if HAVE_MD5 | |
218 | if (md5) | |
219 | { | |
220 | ||
221 | printf("%s\n", userdb_mkmd5pw(buf)); | |
222 | exit(0); | |
223 | } | |
224 | #endif | |
225 | #ifdef RANDOM | |
226 | userdb_get_random(salt, 2); | |
227 | salt[0]=userdb_hex64[salt[0] & 63]; | |
228 | salt[1]=userdb_hex64[salt[0] & 63]; | |
229 | #else | |
230 | { | |
231 | time_t t; | |
232 | int i; | |
233 | ||
234 | time(&t); | |
235 | t ^= getpid(); | |
236 | salt[0]=0; | |
237 | salt[1]=0; | |
238 | for (i=0; i<6; i++) | |
239 | { | |
240 | salt[0] <<= 1; | |
241 | salt[1] <<= 1; | |
242 | salt[0] |= (t & 1); | |
243 | t >>= 1; | |
244 | salt[1] |= (t & 1); | |
245 | t >>= 1; | |
246 | } | |
247 | salt[0]=userdb_hex64[(unsigned)salt[0]]; | |
248 | salt[1]=userdb_hex64[(unsigned)salt[1]]; | |
249 | } | |
250 | #endif | |
251 | ||
0e333c05 CE |
252 | #if HAVE_BCRYPT |
253 | cryptsalt=bcrypt_gensalt(8); | |
254 | printf("%s\n", crypt(buf, cryptsalt)); | |
255 | fflush(stdout); | |
256 | #elif HAVE_CRYPT | |
d9898ee8 | 257 | printf("%s\n", crypt(buf, salt)); |
258 | fflush(stdout); | |
259 | #endif | |
260 | return (0); | |
261 | } |