Commit | Line | Data |
---|---|---|
d9898ee8 | 1 | /* |
ac40fd9e | 2 | ** Copyright 2001-2008 Double Precision, Inc. See COPYING for |
d9898ee8 | 3 | ** distribution information. |
4 | */ | |
5 | ||
6 | #if HAVE_CONFIG_H | |
7 | #include "courier_auth_config.h" | |
8 | #endif | |
9 | #include <string.h> | |
10 | #if HAVE_UNISTD_H | |
11 | #include <unistd.h> | |
12 | #endif | |
13 | #include <stdlib.h> | |
14 | #if HAVE_CRYPT_H | |
15 | #include <crypt.h> | |
16 | #endif | |
8d138742 CE |
17 | #if HAVE_SYS_TIME_H |
18 | #include <sys/time.h> | |
19 | #endif | |
d9898ee8 | 20 | #include "auth.h" |
ac40fd9e | 21 | #include "md5/md5.h" |
22 | #include "sha1/sha1.h" | |
8d138742 | 23 | #include "random128/random128.h" |
d9898ee8 | 24 | |
8d138742 | 25 | static const char rcsid[]="$Id: cryptpassword.c,v 1.13 2008/12/25 14:52:38 mrsam Exp $"; |
d9898ee8 | 26 | |
27 | #if HAVE_CRYPT | |
28 | #if NEED_CRYPT_PROTOTYPE | |
29 | extern char *crypt(const char *, const char *); | |
30 | #endif | |
31 | #endif | |
32 | ||
d9898ee8 | 33 | static const char crypt_salt[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./"; |
34 | ||
35 | static const char *crypt_hash(const char *pw) | |
36 | { | |
8d138742 | 37 | random128binbuf randbuf; |
d9898ee8 | 38 | char salt[3]; |
39 | ||
8d138742 | 40 | random128_binary(&randbuf); |
d9898ee8 | 41 | |
8d138742 CE |
42 | salt[0]=crypt_salt[ randbuf[0] % 64 ]; |
43 | salt[1]=crypt_salt[ randbuf[1] % 64 ]; | |
44 | salt[2]=0; | |
d9898ee8 | 45 | |
8d138742 CE |
46 | return (crypt(pw, salt)); |
47 | } | |
d9898ee8 | 48 | |
8d138742 CE |
49 | static const char *ssha_hash_int(const char *pw) |
50 | { | |
51 | random128binbuf randbuf; | |
d9898ee8 | 52 | |
8d138742 | 53 | random128_binary(&randbuf); |
d9898ee8 | 54 | |
8d138742 | 55 | return ssha_hash(pw, randbuf); |
d9898ee8 | 56 | } |
57 | ||
d9898ee8 | 58 | static const char *crypt_md5_wrapper(const char *pw) |
59 | { | |
60 | struct timeval tv; | |
61 | char salt[10]; | |
62 | int i; | |
63 | ||
64 | gettimeofday(&tv, NULL); | |
65 | ||
66 | tv.tv_sec |= tv.tv_usec; | |
67 | tv.tv_sec ^= getpid(); | |
68 | ||
69 | strcpy(salt, "$1$"); | |
70 | ||
71 | for (i=3; i<8; i++) | |
72 | { | |
73 | salt[i]=crypt_salt[ tv.tv_sec % 64 ]; | |
74 | tv.tv_sec /= 64; | |
75 | } | |
76 | ||
77 | strcpy(salt+i, "$"); | |
78 | ||
79 | return (md5_crypt(pw, salt)); | |
80 | } | |
d9898ee8 | 81 | |
82 | char *authcryptpasswd(const char *password, const char *encryption_hint) | |
83 | { | |
84 | const char *(*hash_func)(const char *)=0; | |
85 | const char *pfix=0; | |
86 | const char *p; | |
87 | char *pp; | |
88 | ||
d9898ee8 | 89 | if (!encryption_hint || strncmp(encryption_hint, "$1$", 3) == 0) |
90 | { | |
91 | pfix=""; | |
92 | hash_func=crypt_md5_wrapper; | |
93 | } | |
94 | ||
95 | if (!encryption_hint || strncasecmp(encryption_hint, "{MD5}", 5) == 0) | |
96 | { | |
97 | hash_func= &md5_hash_courier; | |
98 | pfix="{MD5}"; | |
99 | } | |
dd184caf | 100 | |
101 | if (!encryption_hint || strncasecmp(encryption_hint, "{MD5RAW}", 5) | |
102 | == 0) | |
103 | { | |
104 | hash_func= &md5_hash_raw; | |
105 | pfix="{MD5RAW}"; | |
106 | } | |
d9898ee8 | 107 | |
d9898ee8 | 108 | if (!encryption_hint || strncasecmp(encryption_hint, "{SHA}", 5) == 0) |
109 | { | |
110 | hash_func= &sha1_hash; | |
111 | pfix="{SHA}"; | |
112 | } | |
113 | ||
8d138742 CE |
114 | if (!encryption_hint || strncasecmp(encryption_hint, "{SSHA}", 6) == 0) |
115 | { | |
116 | hash_func= &ssha_hash_int; | |
117 | pfix="{SSHA}"; | |
118 | } | |
119 | ||
d9898ee8 | 120 | if (!encryption_hint || |
121 | strncasecmp(encryption_hint, "{SHA256}", 8) == 0) | |
122 | { | |
123 | hash_func= &sha256_hash; | |
124 | pfix="{SHA256}"; | |
125 | } | |
d9898ee8 | 126 | |
8d138742 CE |
127 | if (!encryption_hint || |
128 | strncasecmp(encryption_hint, "{SHA512}", 8) == 0) | |
129 | { | |
130 | hash_func= &sha512_hash; | |
131 | pfix="{SHA512}"; | |
132 | } | |
133 | ||
d9898ee8 | 134 | if (!hash_func) |
135 | { | |
136 | hash_func= &crypt_hash; | |
137 | pfix="{CRYPT}"; | |
138 | } | |
139 | ||
140 | p= (*hash_func)(password); | |
141 | if (!p || (pp=malloc(strlen(pfix)+strlen(p)+1)) == 0) | |
142 | return (0); | |
143 | ||
144 | return (strcat(strcpy(pp, pfix), p)); | |
145 | } |