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