new
This commit is contained in:
parent
45993349d8
commit
1757e76a73
9 changed files with 264 additions and 37 deletions
119
src/cmd/auth/factotum/httpdigest.c
Normal file
119
src/cmd/auth/factotum/httpdigest.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* HTTPDIGEST - MD5 challenge/response authentication (RFC 2617)
|
||||
*
|
||||
* Client protocol:
|
||||
* write challenge: nonce method uri
|
||||
* read response: 2*MD5dlen hex digits
|
||||
*
|
||||
* Server protocol:
|
||||
* unimplemented
|
||||
*/
|
||||
#include "std.h"
|
||||
#include "dat.h"
|
||||
|
||||
static void
|
||||
digest(char *user, char *realm, char *passwd,
|
||||
char *nonce, char *method, char *uri,
|
||||
char *dig);
|
||||
|
||||
static int
|
||||
hdclient(Conv *c)
|
||||
{
|
||||
char *realm, *passwd, *user, *f[4], *s, resp[MD5dlen*2+1];
|
||||
int ret;
|
||||
Key *k;
|
||||
|
||||
ret = -1;
|
||||
s = nil;
|
||||
|
||||
c->state = "keylookup";
|
||||
k = keyfetch(c, "%A", c->attr);
|
||||
if(k == nil)
|
||||
goto out;
|
||||
|
||||
user = strfindattr(k->attr, "user");
|
||||
realm = strfindattr(k->attr, "realm");
|
||||
passwd = strfindattr(k->attr, "!password");
|
||||
|
||||
if(convreadm(c, &s) < 0)
|
||||
goto out;
|
||||
if(tokenize(s, f, 4) != 3){
|
||||
werrstr("bad challenge -- want nonce method uri");
|
||||
goto out;
|
||||
}
|
||||
|
||||
digest(user, realm, passwd, f[0], f[1], f[2], resp);
|
||||
convwrite(c, resp, strlen(resp));
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
free(s);
|
||||
keyclose(k);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
strtolower(char *s)
|
||||
{
|
||||
while(*s){
|
||||
*s = tolower(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
digest(char *user, char *realm, char *passwd,
|
||||
char *nonce, char *method, char *uri,
|
||||
char *dig)
|
||||
{
|
||||
uchar b[MD5dlen];
|
||||
char ha1[MD5dlen*2+1];
|
||||
char ha2[MD5dlen*2+1];
|
||||
DigestState *s;
|
||||
|
||||
/*
|
||||
* H(A1) = MD5(uid + ":" + realm ":" + passwd)
|
||||
*/
|
||||
s = md5((uchar*)user, strlen(user), nil, nil);
|
||||
md5((uchar*)":", 1, nil, s);
|
||||
md5((uchar*)realm, strlen(realm), nil, s);
|
||||
md5((uchar*)":", 1, nil, s);
|
||||
md5((uchar*)passwd, strlen(passwd), b, s);
|
||||
enc16(ha1, sizeof(ha1), b, MD5dlen);
|
||||
strtolower(ha1);
|
||||
|
||||
/*
|
||||
* H(A2) = MD5(method + ":" + uri)
|
||||
*/
|
||||
s = md5((uchar*)method, strlen(method), nil, nil);
|
||||
md5((uchar*)":", 1, nil, s);
|
||||
md5((uchar*)uri, strlen(uri), b, s);
|
||||
enc16(ha2, sizeof(ha2), b, MD5dlen);
|
||||
strtolower(ha2);
|
||||
|
||||
/*
|
||||
* digest = MD5(H(A1) + ":" + nonce + ":" + H(A2))
|
||||
*/
|
||||
s = md5((uchar*)ha1, MD5dlen*2, nil, nil);
|
||||
md5((uchar*)":", 1, nil, s);
|
||||
md5((uchar*)nonce, strlen(nonce), nil, s);
|
||||
md5((uchar*)":", 1, nil, s);
|
||||
md5((uchar*)ha2, MD5dlen*2, b, s);
|
||||
enc16(dig, MD5dlen*2+1, b, MD5dlen);
|
||||
strtolower(dig);
|
||||
}
|
||||
|
||||
static Role hdroles[] =
|
||||
{
|
||||
"client", hdclient,
|
||||
0
|
||||
};
|
||||
|
||||
Proto httpdigest =
|
||||
{
|
||||
"httpdigest",
|
||||
hdroles,
|
||||
"user? realm? !password?",
|
||||
nil,
|
||||
nil
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue