1 |
#include <stdio.h> |
2 |
#include <string.h> |
3 |
|
4 |
#include "config.h" |
5 |
#include "imapfilter.h" |
6 |
|
7 |
#ifdef CRAM_MD5 |
8 |
#include <openssl/hmac.h> |
9 |
|
10 |
|
11 |
/* |
12 |
* Authenticate to the server with the Challenge-Response Authentication |
13 |
* Mechanism (CRAM). The authentication type associated with CRAM is |
14 |
* "CRAM-MD5". |
15 |
*/ |
16 |
int |
17 |
imf_cram_md5(int *sock, char *user, char *pass) |
18 |
{ |
19 |
int i, n; |
20 |
unsigned int t; |
21 |
unsigned char *chal, *resp, *out, *buf; |
22 |
unsigned char md[EVP_MAX_MD_SIZE], mdhex[EVP_MAX_MD_SIZE * 2 + 1]; |
23 |
unsigned int mdlen; |
24 |
HMAC_CTX hmac; |
25 |
|
26 |
t = imap_authenticate(sock, "CRAM-MD5", 0); |
27 |
|
28 |
if (authenticate_response(sock, t, &chal) == RESPONSE_NONE) { |
29 |
n = strlen(chal) * 3 / 4 + 1; |
30 |
resp = (char *)xmalloc(n); |
31 |
memset(resp, 0, n); |
32 |
|
33 |
EVP_DecodeBlock(resp, chal, strlen(chal)); |
34 |
|
35 |
HMAC_Init(&hmac, (unsigned char *)pass, strlen(pass), |
36 |
EVP_md5()); |
37 |
HMAC_Update(&hmac, resp, strlen(resp)); |
38 |
HMAC_Final(&hmac, md, &mdlen); |
39 |
|
40 |
xfree(chal); |
41 |
xfree(resp); |
42 |
|
43 |
for (i = 0; i < mdlen; i++) |
44 |
snprintf(mdhex + i * 2, |
45 |
mdlen * 2 - i * 2 + 1, "%02x", md[i]); |
46 |
mdhex[mdlen * 2] = '\0'; |
47 |
|
48 |
n = strlen(user) + 1 + strlen(mdhex) + 1; |
49 |
buf = (unsigned char *)xmalloc(n); |
50 |
memset(buf, 0, n); |
51 |
|
52 |
snprintf(buf, n, "%s %s", user, mdhex); |
53 |
|
54 |
n = (strlen(buf) + 3) * 4 / 3 + 1; |
55 |
out = (unsigned char *)xmalloc(n); |
56 |
memset(out, 0, n); |
57 |
|
58 |
EVP_EncodeBlock(out, buf, strlen(buf)); |
59 |
|
60 |
imap_authenticate(sock, out, 1); |
61 |
|
62 |
xfree(buf); |
63 |
xfree(out); |
64 |
} |
65 |
return authenticate_response(sock, t, NULL); |
66 |
} |
67 |
|
68 |
#endif /* CRAM_MD5 */ |