]> git.sur5r.net Git - openldap/blob - libraries/liblutil/passwd.c
Add "lutil*.h" to project.
[openldap] / libraries / liblutil / passwd.c
1 /*
2  * lutil_password(credentials, password)
3  *
4  * Returns true if user supplied credentials matches
5  * the stored password. 
6  *
7  * Due to the use of the crypt(3) function 
8  * this routine is NOT thread-safe.
9  */
10
11 #include "portable.h"
12
13 #include <stdlib.h>
14
15 #include <ac/string.h>
16 #include <ac/unistd.h>
17
18 #include "lutil_md5.h"
19 #include "lutil_sha1.h"
20 #include "lutil.h"
21
22 /*
23  * Return 0 if creds are good.
24  */
25
26 int
27 lutil_passwd(
28         const char *cred,
29         const char *passwd)
30 {
31
32         if (cred == NULL || passwd == NULL) {
33                 return -1;
34         }
35
36         if (strncasecmp(passwd, "{MD5}", sizeof("{MD5}") - 1) == 0 ) {
37                 lutil_MD5_CTX MD5context;
38                 unsigned char MD5digest[16];
39                 char base64digest[25];  /* ceiling(sizeof(input)/3) * 4 + 1 */
40
41                 const char *p = passwd + (sizeof("{MD5}") - 1);
42
43                 lutil_MD5Init(&MD5context);
44                 lutil_MD5Update(&MD5context,
45                                (const unsigned char *)cred, strlen(cred));
46                 lutil_MD5Final(MD5digest, &MD5context);
47
48                 if ( lutil_b64_ntop(MD5digest, sizeof(MD5digest),
49                         base64digest, sizeof(base64digest)) < 0)
50                 {
51                         return ( 1 );
52                 }
53
54                 return( strcmp(p, base64digest) );
55
56         } else if (strncasecmp(passwd, "{SHA}",sizeof("{SHA}") - 1) == 0 ) {
57                 lutil_SHA1_CTX SHA1context;
58                 unsigned char SHA1digest[20];
59                 char base64digest[29];  /* ceiling(sizeof(input)/3) * 4 + 1 */
60                 const char *p = passwd + (sizeof("{SHA}") - 1);
61
62                 lutil_SHA1Init(&SHA1context);
63                 lutil_SHA1Update(&SHA1context,
64                                 (const unsigned char *) cred, strlen(cred));
65                 lutil_SHA1Final(SHA1digest, &SHA1context);
66
67                 if (lutil_b64_ntop(SHA1digest, sizeof(SHA1digest),
68                         base64digest, sizeof(base64digest)) < 0)
69                 {
70                         return ( 1 );
71                 }
72
73                 return( strcmp(p, base64digest) );
74
75         } else if (strncasecmp(passwd, "{SSHA}", sizeof("{SSHA}") - 1) == 0) {
76                 lutil_SHA1_CTX SHA1context;
77                 unsigned char SHA1digest[20];
78                 const char *p = passwd + (sizeof("{SSHA}") - 1);
79                 int pw_len = strlen(p);
80                 int rc;
81                 unsigned char *orig_pass = NULL;
82  
83                 /* base64 un-encode password */
84                 orig_pass = (unsigned char *)malloc((size_t)(pw_len * 0.75 + 1));
85                 if ((rc = lutil_b64_pton(p, orig_pass, pw_len)) < 0)
86                 {
87                         free(orig_pass);
88                         return ( 1 );
89                 }
90  
91                 /* hash credentials with salt */
92                 lutil_SHA1Init(&SHA1context);
93                 lutil_SHA1Update(&SHA1context,
94                                 (const unsigned char *) cred, strlen(cred));
95                 lutil_SHA1Update(&SHA1context,
96                                 (const unsigned char *) orig_pass + sizeof(SHA1digest),
97                                 rc - sizeof(SHA1digest));
98                 lutil_SHA1Final(SHA1digest, &SHA1context);
99  
100                 /* compare */
101                 rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
102                 free(orig_pass);
103                 return(rc);
104
105         } else if (strncasecmp(passwd, "{SMD5}", sizeof("{SMD5}") - 1) == 0) {
106                 lutil_MD5_CTX MD5context;
107                 unsigned char MD5digest[16];
108                 const char *p = passwd + (sizeof("{SMD5}") - 1);
109                 int pw_len = strlen(p);
110                 int rc;
111                 unsigned char *orig_pass = NULL;
112
113                 /* base64 un-encode password */
114                 orig_pass = (unsigned char *)malloc((size_t)(pw_len * 0.75 + 1));
115                 if ((rc = lutil_b64_pton(p, orig_pass, pw_len)) < 0)
116                 {
117                         free(orig_pass);
118                         return ( 1 );
119                 }
120
121                 /* hash credentials with salt */
122                 lutil_MD5Init(&MD5context);
123                 lutil_MD5Update(&MD5context,
124                                 (const unsigned char *) cred, strlen(cred));
125                 lutil_MD5Update(&MD5context,
126                                 (const unsigned char *) orig_pass + sizeof(MD5digest),
127                                 rc - sizeof(MD5digest));
128                 lutil_MD5Final(MD5digest, &MD5context);
129
130                 /* compare */
131                 rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
132                 free(orig_pass);
133                 return ( rc );
134
135 #ifdef SLAPD_CRYPT
136         } else if (strncasecmp(passwd, "{CRYPT}", sizeof("{CRYPT}") - 1) == 0 ) {
137                 const char *p = passwd + (sizeof("{CRYPT}") - 1);
138
139                 return( strcmp(p, crypt(cred, p)) );
140
141 #endif
142         }
143
144 #ifdef SLAPD_CLEARTEXT
145         return( strcmp(passwd, cred) );
146 #else
147         return( 1 );
148 #endif
149
150 }