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