Build courier-authlib 0.60.2-0hcoop5.
[hcoop/debian/courier-authlib.git] / cryptpassword.c
1 /*
2 ** Copyright 2001-2002 Double Precision, Inc. See COPYING for
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
17 #include "auth.h"
18 #include <sys/time.h>
19
20 static const char rcsid[]="$Id: cryptpassword.c,v 1.9 2007/10/07 18:33:22 mrsam Exp $";
21
22 #if HAVE_CRYPT
23 #if NEED_CRYPT_PROTOTYPE
24 extern char *crypt(const char *, const char *);
25 #endif
26 #endif
27
28 #if HAVE_MD5LIB
29 #include "md5/md5.h"
30 #endif
31
32 #if HAVE_SHA1LIB
33 #include "sha1/sha1.h"
34 #endif
35
36 static const char crypt_salt[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./";
37
38 static const char *crypt_hash(const char *pw)
39 {
40 struct timeval tv;
41 char salt[3];
42
43 gettimeofday(&tv, NULL);
44
45 tv.tv_sec |= tv.tv_usec;
46 tv.tv_sec ^= getpid();
47
48 salt[0]=crypt_salt[ tv.tv_sec % 64 ];
49
50 tv.tv_sec /= 64;
51
52 salt[1]=crypt_salt[ tv.tv_sec % 64 ];
53 salt[2]=0;
54
55 return (crypt(pw, salt));
56 }
57
58 #if HAVE_MD5LIB
59 static const char *crypt_md5_wrapper(const char *pw)
60 {
61 struct timeval tv;
62 char salt[10];
63 int i;
64
65 gettimeofday(&tv, NULL);
66
67 tv.tv_sec |= tv.tv_usec;
68 tv.tv_sec ^= getpid();
69
70 strcpy(salt, "$1$");
71
72 for (i=3; i<8; i++)
73 {
74 salt[i]=crypt_salt[ tv.tv_sec % 64 ];
75 tv.tv_sec /= 64;
76 }
77
78 strcpy(salt+i, "$");
79
80 return (md5_crypt(pw, salt));
81 }
82 #endif
83
84 char *authcryptpasswd(const char *password, const char *encryption_hint)
85 {
86 const char *(*hash_func)(const char *)=0;
87 const char *pfix=0;
88 const char *p;
89 char *pp;
90
91 #if HAVE_MD5LIB
92
93 if (!encryption_hint || strncmp(encryption_hint, "$1$", 3) == 0)
94 {
95 pfix="";
96 hash_func=crypt_md5_wrapper;
97 }
98
99 if (!encryption_hint || strncasecmp(encryption_hint, "{MD5}", 5) == 0)
100 {
101 hash_func= &md5_hash_courier;
102 pfix="{MD5}";
103 }
104
105 if (!encryption_hint || strncasecmp(encryption_hint, "{MD5RAW}", 5)
106 == 0)
107 {
108 hash_func= &md5_hash_raw;
109 pfix="{MD5RAW}";
110 }
111 #endif
112
113 #if HAVE_SHA1LIB
114 if (!encryption_hint || strncasecmp(encryption_hint, "{SHA}", 5) == 0)
115 {
116 hash_func= &sha1_hash;
117 pfix="{SHA}";
118 }
119
120 if (!encryption_hint ||
121 strncasecmp(encryption_hint, "{SHA256}", 8) == 0)
122 {
123 hash_func= &sha256_hash;
124 pfix="{SHA256}";
125 }
126 #endif
127
128 if (!hash_func)
129 {
130 hash_func= &crypt_hash;
131 pfix="{CRYPT}";
132 }
133
134 p= (*hash_func)(password);
135 if (!p || (pp=malloc(strlen(pfix)+strlen(p)+1)) == 0)
136 return (0);
137
138 return (strcat(strcpy(pp, pfix), p));
139 }