Add changelog entry.
[hcoop/debian/courier-authlib.git] / authsaslclientcram.c
CommitLineData
d9898ee8 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
24int authsaslclient_cram(const struct authsaslclientinfo *info,
25 const char *challenge,
26 const struct hmac_hashinfo *hashinfo)
27{
28char *base64buf=malloc(strlen(challenge)+1);
29unsigned char *keybuf;
30char *p;
31const char *userid=info->userid ? info->userid:"";
32const char *password=info->password ? info->password:"";
33int 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
93struct hmac_hashinfo;
94
95int 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