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