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