Blame


1 1757e76a 2005-02-13 devnull /*
2 1757e76a 2005-02-13 devnull * HTTPDIGEST - MD5 challenge/response authentication (RFC 2617)
3 1757e76a 2005-02-13 devnull *
4 1757e76a 2005-02-13 devnull * Client protocol:
5 fa325e9b 2020-01-10 cross * write challenge: nonce method uri
6 1757e76a 2005-02-13 devnull * read response: 2*MD5dlen hex digits
7 1757e76a 2005-02-13 devnull *
8 1757e76a 2005-02-13 devnull * Server protocol:
9 1757e76a 2005-02-13 devnull * unimplemented
10 1757e76a 2005-02-13 devnull */
11 1757e76a 2005-02-13 devnull #include "std.h"
12 1757e76a 2005-02-13 devnull #include "dat.h"
13 1757e76a 2005-02-13 devnull
14 1757e76a 2005-02-13 devnull static void
15 1757e76a 2005-02-13 devnull digest(char *user, char *realm, char *passwd,
16 1757e76a 2005-02-13 devnull char *nonce, char *method, char *uri,
17 1757e76a 2005-02-13 devnull char *dig);
18 1757e76a 2005-02-13 devnull
19 1757e76a 2005-02-13 devnull static int
20 1757e76a 2005-02-13 devnull hdclient(Conv *c)
21 1757e76a 2005-02-13 devnull {
22 1757e76a 2005-02-13 devnull char *realm, *passwd, *user, *f[4], *s, resp[MD5dlen*2+1];
23 1757e76a 2005-02-13 devnull int ret;
24 1757e76a 2005-02-13 devnull Key *k;
25 fa325e9b 2020-01-10 cross
26 1757e76a 2005-02-13 devnull ret = -1;
27 1757e76a 2005-02-13 devnull s = nil;
28 fa325e9b 2020-01-10 cross
29 1757e76a 2005-02-13 devnull c->state = "keylookup";
30 1757e76a 2005-02-13 devnull k = keyfetch(c, "%A", c->attr);
31 1757e76a 2005-02-13 devnull if(k == nil)
32 1757e76a 2005-02-13 devnull goto out;
33 1757e76a 2005-02-13 devnull
34 1757e76a 2005-02-13 devnull user = strfindattr(k->attr, "user");
35 1757e76a 2005-02-13 devnull realm = strfindattr(k->attr, "realm");
36 1757e76a 2005-02-13 devnull passwd = strfindattr(k->attr, "!password");
37 1757e76a 2005-02-13 devnull
38 1757e76a 2005-02-13 devnull if(convreadm(c, &s) < 0)
39 1757e76a 2005-02-13 devnull goto out;
40 1757e76a 2005-02-13 devnull if(tokenize(s, f, 4) != 3){
41 1757e76a 2005-02-13 devnull werrstr("bad challenge -- want nonce method uri");
42 1757e76a 2005-02-13 devnull goto out;
43 1757e76a 2005-02-13 devnull }
44 1757e76a 2005-02-13 devnull
45 1757e76a 2005-02-13 devnull digest(user, realm, passwd, f[0], f[1], f[2], resp);
46 1757e76a 2005-02-13 devnull convwrite(c, resp, strlen(resp));
47 1757e76a 2005-02-13 devnull ret = 0;
48 fa325e9b 2020-01-10 cross
49 1757e76a 2005-02-13 devnull out:
50 1757e76a 2005-02-13 devnull free(s);
51 1757e76a 2005-02-13 devnull keyclose(k);
52 1757e76a 2005-02-13 devnull return ret;
53 1757e76a 2005-02-13 devnull }
54 1757e76a 2005-02-13 devnull
55 1757e76a 2005-02-13 devnull static void
56 1757e76a 2005-02-13 devnull strtolower(char *s)
57 1757e76a 2005-02-13 devnull {
58 1757e76a 2005-02-13 devnull while(*s){
59 3bd56b04 2005-09-09 devnull *s = tolower((uchar)*s);
60 1757e76a 2005-02-13 devnull s++;
61 1757e76a 2005-02-13 devnull }
62 1757e76a 2005-02-13 devnull }
63 1757e76a 2005-02-13 devnull
64 1757e76a 2005-02-13 devnull static void
65 1757e76a 2005-02-13 devnull digest(char *user, char *realm, char *passwd,
66 1757e76a 2005-02-13 devnull char *nonce, char *method, char *uri,
67 1757e76a 2005-02-13 devnull char *dig)
68 1757e76a 2005-02-13 devnull {
69 1757e76a 2005-02-13 devnull uchar b[MD5dlen];
70 1757e76a 2005-02-13 devnull char ha1[MD5dlen*2+1];
71 1757e76a 2005-02-13 devnull char ha2[MD5dlen*2+1];
72 1757e76a 2005-02-13 devnull DigestState *s;
73 1757e76a 2005-02-13 devnull
74 1757e76a 2005-02-13 devnull /*
75 1757e76a 2005-02-13 devnull * H(A1) = MD5(uid + ":" + realm ":" + passwd)
76 1757e76a 2005-02-13 devnull */
77 1757e76a 2005-02-13 devnull s = md5((uchar*)user, strlen(user), nil, nil);
78 1757e76a 2005-02-13 devnull md5((uchar*)":", 1, nil, s);
79 1757e76a 2005-02-13 devnull md5((uchar*)realm, strlen(realm), nil, s);
80 1757e76a 2005-02-13 devnull md5((uchar*)":", 1, nil, s);
81 1757e76a 2005-02-13 devnull md5((uchar*)passwd, strlen(passwd), b, s);
82 1757e76a 2005-02-13 devnull enc16(ha1, sizeof(ha1), b, MD5dlen);
83 1757e76a 2005-02-13 devnull strtolower(ha1);
84 1757e76a 2005-02-13 devnull
85 1757e76a 2005-02-13 devnull /*
86 1757e76a 2005-02-13 devnull * H(A2) = MD5(method + ":" + uri)
87 1757e76a 2005-02-13 devnull */
88 1757e76a 2005-02-13 devnull s = md5((uchar*)method, strlen(method), nil, nil);
89 1757e76a 2005-02-13 devnull md5((uchar*)":", 1, nil, s);
90 1757e76a 2005-02-13 devnull md5((uchar*)uri, strlen(uri), b, s);
91 1757e76a 2005-02-13 devnull enc16(ha2, sizeof(ha2), b, MD5dlen);
92 1757e76a 2005-02-13 devnull strtolower(ha2);
93 1757e76a 2005-02-13 devnull
94 1757e76a 2005-02-13 devnull /*
95 1757e76a 2005-02-13 devnull * digest = MD5(H(A1) + ":" + nonce + ":" + H(A2))
96 1757e76a 2005-02-13 devnull */
97 1757e76a 2005-02-13 devnull s = md5((uchar*)ha1, MD5dlen*2, nil, nil);
98 1757e76a 2005-02-13 devnull md5((uchar*)":", 1, nil, s);
99 1757e76a 2005-02-13 devnull md5((uchar*)nonce, strlen(nonce), nil, s);
100 1757e76a 2005-02-13 devnull md5((uchar*)":", 1, nil, s);
101 1757e76a 2005-02-13 devnull md5((uchar*)ha2, MD5dlen*2, b, s);
102 1757e76a 2005-02-13 devnull enc16(dig, MD5dlen*2+1, b, MD5dlen);
103 1757e76a 2005-02-13 devnull strtolower(dig);
104 1757e76a 2005-02-13 devnull }
105 1757e76a 2005-02-13 devnull
106 fa325e9b 2020-01-10 cross static Role hdroles[] =
107 1757e76a 2005-02-13 devnull {
108 1757e76a 2005-02-13 devnull "client", hdclient,
109 1757e76a 2005-02-13 devnull 0
110 1757e76a 2005-02-13 devnull };
111 1757e76a 2005-02-13 devnull
112 1757e76a 2005-02-13 devnull Proto httpdigest =
113 1757e76a 2005-02-13 devnull {
114 1757e76a 2005-02-13 devnull "httpdigest",
115 1757e76a 2005-02-13 devnull hdroles,
116 1757e76a 2005-02-13 devnull "user? realm? !password?",
117 1f8a8072 2005-03-15 devnull 0,
118 1f8a8072 2005-03-15 devnull 0
119 1757e76a 2005-02-13 devnull };