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