1 #include <sys/types.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <bglibs/systime.h>
5 #include "v2client.h"
6 #include "sasl.h"
7 #include "sasl_internal.h"
8
9 static const unsigned char hex2bin[256] = {
10 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0-15 */
11 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 16-31 */
12 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 32-47 */
13 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, /* 48-63 */
14 -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 64-79 */
15 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 80-95 */
16 -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 96-111 */
17 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 112-127 */
18 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 128-143 */
19 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 144-159 */
20 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 160-175 */
21 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 176-191 */
22 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 192-207 */
23 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 208-223 */
24 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 224-239 */
25 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 240-255 */
26 };
27
response1(struct sasl_state * ss,const str * response,str * challenge)28 static int response1(struct sasl_state* ss,
29 const str* response, str* challenge)
30 {
31 char binresp[16];
32 const str binrespstr = { binresp, 16, 0 };
33 unsigned i;
34 unsigned j;
35 if (response->len == 0) return SASL_RESP_BAD;
36 if ((i = str_findfirst(response, ' ')) == (unsigned)-1
37 || response->len - i != 33)
38 return SASL_RESP_BAD;
39 response->s[i] = 0;
40 for (j = 0; j < 32; j += 2)
41 binresp[j/2] = hex2bin[(unsigned char)response->s[i+j]] << 4
42 | hex2bin[(unsigned char)response->s[i+j+1]];
43 return sasl_authenticate_cram(ss, response->s, "CRAM-MD5",
44 &ss->init, &binrespstr);
45 (void)challenge;
46 }
47
sasl_cram_md5_start(struct sasl_state * ss,const str * response,str * challenge)48 int sasl_cram_md5_start(struct sasl_state* ss,
49 const str* response, str* challenge)
50 {
51 struct timeval tv;
52 const char* hostname;
53
54 if (response)
55 return SASL_RESP_NOTALLOWED;
56 ss->response = response1;
57 if ((hostname = cvm_client_ucspi_domain()) == 0)
58 hostname = "unknown";
59 if (gettimeofday(&tv, 0) == -1 ||
60 !str_copys(&ss->init, "<") ||
61 !str_cati(&ss->init, getpid()) ||
62 !str_catc(&ss->init, '.') ||
63 !str_catu(&ss->init, tv.tv_sec) ||
64 !str_catc(&ss->init, '.') ||
65 !str_catuw(&ss->init, tv.tv_usec, 6, '0') ||
66 !str_catc(&ss->init, '@') ||
67 !str_cats(&ss->init, hostname) ||
68 !str_catc(&ss->init, '>') ||
69 !str_copy(challenge, &ss->init))
70 return SASL_TEMP_FAIL;
71 return SASL_CHALLENGE;
72 }
73