2011-03-06 06:58:58 -05:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <openssl/hmac.h>
|
|
|
|
#include <openssl/evp.h>
|
|
|
|
|
2012-02-19 06:36:44 -05:00
|
|
|
#include "imapfilter.h"
|
|
|
|
|
2011-03-06 06:58:58 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Authenticate to the server with the Challenge-Response Authentication
|
|
|
|
* Mechanism (CRAM). The authentication type associated with CRAM is
|
|
|
|
* "CRAM-MD5".
|
|
|
|
*/
|
2012-02-12 15:57:18 -05:00
|
|
|
unsigned char *
|
|
|
|
auth_cram_md5(const char *user, const char *pass, unsigned char *chal)
|
2011-03-06 06:58:58 -05:00
|
|
|
{
|
|
|
|
size_t n;
|
|
|
|
unsigned int i;
|
2012-02-12 15:57:18 -05:00
|
|
|
unsigned char *resp, *buf, *out;
|
2011-03-06 06:58:58 -05:00
|
|
|
unsigned char md[EVP_MAX_MD_SIZE], mdhex[EVP_MAX_MD_SIZE * 2 + 1];
|
|
|
|
unsigned int mdlen;
|
|
|
|
HMAC_CTX hmac;
|
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
n = strlen((char *)(chal)) * 3 / 4 + 1;
|
|
|
|
resp = (unsigned char *)xmalloc(n * sizeof(char));
|
|
|
|
memset(resp, 0, n);
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
EVP_DecodeBlock(resp, chal, strlen((char *)(chal)));
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-16 12:49:57 -05:00
|
|
|
HMAC_Init(&hmac, (const unsigned char *)pass, strlen(pass), EVP_md5());
|
2012-02-12 15:57:18 -05:00
|
|
|
HMAC_Update(&hmac, resp, strlen((char *)(resp)));
|
|
|
|
HMAC_Final(&hmac, md, &mdlen);
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
xfree(chal);
|
|
|
|
xfree(resp);
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
for (i = 0; i < mdlen; i++)
|
|
|
|
snprintf((char *)(mdhex) + i * 2, mdlen * 2 - i * 2 + 1,
|
|
|
|
"%02x", md[i]);
|
|
|
|
mdhex[mdlen * 2] = '\0';
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
n = strlen(user) + 1 + strlen((char *)(mdhex)) + 1;
|
|
|
|
buf = (unsigned char *)xmalloc(n * sizeof(unsigned char));
|
|
|
|
memset(buf, 0, n);
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
snprintf((char *)(buf), n, "%s %s", user, mdhex);
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
n = (strlen((char *)(buf)) + 3) * 4 / 3 + 1;
|
|
|
|
out = (unsigned char *)xmalloc(n * sizeof(unsigned char));
|
|
|
|
memset(out, 0, n);
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
EVP_EncodeBlock(out, buf, strlen((char *)(buf)));
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
xfree(buf);
|
2011-03-06 06:58:58 -05:00
|
|
|
|
2012-02-12 15:57:18 -05:00
|
|
|
return out;
|
2011-03-06 06:58:58 -05:00
|
|
|
}
|