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