hcoop release
[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
d9898ee8 25
26#if HAVE_CRYPT
27#if NEED_CRYPT_PROTOTYPE
28extern char *crypt(const char *, const char *);
29#endif
30#endif
31
d9898ee8 32static const char crypt_salt[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./";
33
8d138742
CE
34static const char *ssha_hash_int(const char *pw)
35{
36 random128binbuf randbuf;
d9898ee8 37
8d138742 38 random128_binary(&randbuf);
d9898ee8 39
8d138742 40 return ssha_hash(pw, randbuf);
d9898ee8 41}
42
d9898ee8 43static const char *crypt_md5_wrapper(const char *pw)
44{
45 struct timeval tv;
46 char salt[10];
47 int i;
48
49 gettimeofday(&tv, NULL);
50
51 tv.tv_sec |= tv.tv_usec;
52 tv.tv_sec ^= getpid();
53
54 strcpy(salt, "$1$");
55
56 for (i=3; i<8; i++)
57 {
58 salt[i]=crypt_salt[ tv.tv_sec % 64 ];
59 tv.tv_sec /= 64;
60 }
61
62 strcpy(salt+i, "$");
63
64 return (md5_crypt(pw, salt));
65}
d9898ee8 66
67char *authcryptpasswd(const char *password, const char *encryption_hint)
68{
69 const char *(*hash_func)(const char *)=0;
70 const char *pfix=0;
71 const char *p;
72 char *pp;
73
d9898ee8 74 if (!encryption_hint || strncmp(encryption_hint, "$1$", 3) == 0)
75 {
76 pfix="";
77 hash_func=crypt_md5_wrapper;
78 }
79
80 if (!encryption_hint || strncasecmp(encryption_hint, "{MD5}", 5) == 0)
81 {
82 hash_func= &md5_hash_courier;
83 pfix="{MD5}";
84 }
dd184caf 85
86 if (!encryption_hint || strncasecmp(encryption_hint, "{MD5RAW}", 5)
87 == 0)
88 {
89 hash_func= &md5_hash_raw;
90 pfix="{MD5RAW}";
91 }
d9898ee8 92
d9898ee8 93 if (!encryption_hint || strncasecmp(encryption_hint, "{SHA}", 5) == 0)
94 {
95 hash_func= &sha1_hash;
96 pfix="{SHA}";
97 }
98
8d138742
CE
99 if (!encryption_hint || strncasecmp(encryption_hint, "{SSHA}", 6) == 0)
100 {
101 hash_func= &ssha_hash_int;
102 pfix="{SSHA}";
103 }
104
d9898ee8 105 if (!encryption_hint ||
106 strncasecmp(encryption_hint, "{SHA256}", 8) == 0)
107 {
108 hash_func= &sha256_hash;
109 pfix="{SHA256}";
110 }
d9898ee8 111
8d138742
CE
112 if (!encryption_hint ||
113 strncasecmp(encryption_hint, "{SHA512}", 8) == 0)
114 {
115 hash_func= &sha512_hash;
116 pfix="{SHA512}";
117 }
118
d9898ee8 119 if (!hash_func)
120 {
0e333c05
CE
121 hash_func= &ssha_hash_int;
122 pfix="{SSHA}";
d9898ee8 123 }
124
125 p= (*hash_func)(password);
126 if (!p || (pp=malloc(strlen(pfix)+strlen(p)+1)) == 0)
127 return (0);
128
129 return (strcat(strcpy(pp, pfix), p));
130}