Build courier-authlib 0.60.2-0hcoop1.
[hcoop/debian/courier-authlib.git] / userdb / userdbpw.c
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 }