d9898ee8 |
1 | |
2 | /* |
ac40fd9e |
3 | ** Copyright 2000-2008 Double Precision, Inc. See COPYING for |
d9898ee8 |
4 | ** distribution information. |
5 | */ |
6 | |
7 | #include "courier_auth_config.h" |
8 | #include "courierauthsasl.h" |
d9898ee8 |
9 | #include "libhmac/hmac.h" |
d9898ee8 |
10 | #include "authsaslclient.h" |
11 | #include <stdlib.h> |
12 | #include <stdio.h> |
13 | #include <ctype.h> |
14 | #include <string.h> |
15 | #include <errno.h> |
16 | |
d9898ee8 |
17 | int authsaslclient_cram(const struct authsaslclientinfo *info, |
ac40fd9e |
18 | const char *challenge, |
19 | const struct hmac_hashinfo *hashinfo) |
d9898ee8 |
20 | { |
21 | char *base64buf=malloc(strlen(challenge)+1); |
22 | unsigned char *keybuf; |
23 | char *p; |
24 | const char *userid=info->userid ? info->userid:""; |
25 | const char *password=info->password ? info->password:""; |
26 | int i; |
27 | |
28 | if (!base64buf) |
29 | { |
30 | perror("malloc"); |
31 | return (AUTHSASL_ERROR); |
32 | } |
33 | strcpy(base64buf, challenge); |
34 | |
35 | if ( (i=authsasl_frombase64(base64buf))<0 || |
36 | (keybuf=(unsigned char *)malloc(hashinfo->hh_L*3)) == 0) |
37 | { |
38 | free(base64buf); |
39 | perror("malloc"); |
40 | return (AUTHSASL_ERROR); |
41 | } |
42 | |
43 | hmac_hashkey( hashinfo, password, strlen(password), |
44 | keybuf, keybuf+hashinfo->hh_L ); |
45 | |
46 | hmac_hashtext( hashinfo, base64buf, i, |
47 | keybuf, keybuf+hashinfo->hh_L, |
48 | keybuf+hashinfo->hh_L*2); |
49 | |
50 | free(base64buf); |
51 | base64buf=malloc(strlen(userid)+2+hashinfo->hh_L*2); |
52 | if (!base64buf) |
53 | { |
54 | perror("malloc"); |
55 | free(keybuf); |
56 | return (AUTHSASL_ERROR); |
57 | } |
58 | strcat(strcpy(base64buf, userid), " "); |
59 | p=base64buf+strlen(base64buf); |
60 | for (i=0; i<hashinfo->hh_L; i++) |
61 | { |
62 | static const char xdigit[]="0123456789abcdef"; |
63 | int c=keybuf[hashinfo->hh_L*2+i]; |
64 | |
65 | *p++ = xdigit[ (c >> 4) & 0x0F ]; |
66 | *p++ = xdigit[c & 0x0F]; |
67 | } |
68 | *p=0; |
69 | free(keybuf); |
70 | keybuf=(unsigned char *)authsasl_tobase64(base64buf, -1); |
71 | free(base64buf); |
72 | |
73 | if (!keybuf) |
74 | { |
75 | perror("malloc"); |
76 | free(keybuf); |
77 | return (AUTHSASL_ERROR); |
78 | } |
79 | i= (*info->final_conv_func)((char *)keybuf, info->conv_func_arg); |
80 | free(keybuf); |
81 | return (i); |
82 | } |