Build courier-authlib 0.60.2-0hcoop1.
[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
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
49extern char *crypt(const char *, const char *);
50#endif
51#endif
52
53extern char userdb_hex64[];
54
55#ifdef RANDOM
56extern void userdb_get_random(char *buf, unsigned n);
57#endif
58
59#if HAVE_MD5
60
61char *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
72static struct termios tios;
73static int have_tios;
74
75static 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
87static void read_pw(char *buf)
88{
89int 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
99int main(int argc, char **argv)
100{
101int n=1;
102int md5=0;
103char buf[BUFSIZ];
104char salt[9];
105#if HAVE_HMAC
106struct 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}