Import Upstream version 0.69.0
[hcoop/debian/courier-authlib.git] / userdb / userdbpw.c
CommitLineData
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
52extern char *crypt(const char *, const char *);
53#endif
54#endif
55
56extern char userdb_hex64[];
57
58#ifdef RANDOM
59extern void userdb_get_random(char *buf, unsigned n);
60#endif
61
62#if HAVE_MD5
63
64char *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
75static struct termios tios;
76static int have_tios;
77
78static 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
90static void read_pw(char *buf)
91{
92int 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
102int main(int argc, char **argv)
103{
104int n=1;
105int md5=0;
106char buf[BUFSIZ];
107char salt[9];
0e333c05
CE
108#if HAVE_BCRYPT
109char *cryptsalt;
110#endif
d9898ee8 111#if HAVE_HMAC
112struct 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}