Imported Upstream version 0.63.0
[hcoop/debian/courier-authlib.git] / cryptpassword.c
CommitLineData
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 25static 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
29extern char *crypt(const char *, const char *);
30#endif
31#endif
32
d9898ee8 33static const char crypt_salt[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./";
34
35static 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
49static 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 58static 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
82char *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}