webfs: implement RFC2617 qop extension for http digest authentication
This commit is contained in:
parent
945fef7ff2
commit
8166868375
2 changed files with 26 additions and 4 deletions
|
@ -81,7 +81,7 @@ static char *service;
|
||||||
static long time0;
|
static long time0;
|
||||||
static char *user;
|
static char *user;
|
||||||
static char *agent;
|
static char *agent;
|
||||||
static Client client[64];
|
static Client client[256];
|
||||||
static int nclient;
|
static int nclient;
|
||||||
|
|
||||||
#define CLIENTID(c) ((int)(((Client*)(c)) - client))
|
#define CLIENTID(c) ((int)(((Client*)(c)) - client))
|
||||||
|
|
|
@ -362,7 +362,7 @@ hauthgetkey(char *params)
|
||||||
int
|
int
|
||||||
authenticate(Url *u, Url *ru, char *method, char *s)
|
authenticate(Url *u, Url *ru, char *method, char *s)
|
||||||
{
|
{
|
||||||
char oerr[ERRMAX], *user, *pass, *realm, *nonce, *opaque, *x;
|
char oerr[ERRMAX], *user, *pass, *realm, *nonce, *qop, *opaque, *x;
|
||||||
Hauth *a;
|
Hauth *a;
|
||||||
Fmt fmt;
|
Fmt fmt;
|
||||||
int n;
|
int n;
|
||||||
|
@ -415,6 +415,8 @@ authenticate(Url *u, Url *ru, char *method, char *s)
|
||||||
}else
|
}else
|
||||||
if(!cistrncmp(s, "Digest ", 7)){
|
if(!cistrncmp(s, "Digest ", 7)){
|
||||||
char chal[1024], ouser[128], resp[2*MD5LEN+1];
|
char chal[1024], ouser[128], resp[2*MD5LEN+1];
|
||||||
|
uchar cnonce[16];
|
||||||
|
uint nc;
|
||||||
int nchal;
|
int nchal;
|
||||||
|
|
||||||
s += 7;
|
s += 7;
|
||||||
|
@ -422,6 +424,10 @@ authenticate(Url *u, Url *ru, char *method, char *s)
|
||||||
realm = unquote(x+6, &s);
|
realm = unquote(x+6, &s);
|
||||||
if(x = cistrstr(s, "nonce="))
|
if(x = cistrstr(s, "nonce="))
|
||||||
nonce = unquote(x+6, &s);
|
nonce = unquote(x+6, &s);
|
||||||
|
if(x = cistrstr(s, "qop="))
|
||||||
|
qop = unquote(x+4, &s);
|
||||||
|
else
|
||||||
|
qop = "";
|
||||||
if(x = cistrstr(s, "opaque="))
|
if(x = cistrstr(s, "opaque="))
|
||||||
opaque = unquote(x+7, &s);
|
opaque = unquote(x+7, &s);
|
||||||
if(realm == nil || nonce == nil)
|
if(realm == nil || nonce == nil)
|
||||||
|
@ -432,7 +438,19 @@ authenticate(Url *u, Url *ru, char *method, char *s)
|
||||||
fmtprint(&fmt, " user=%q", user);
|
fmtprint(&fmt, " user=%q", user);
|
||||||
if((s = fmtstrflush(&fmt)) == nil)
|
if((s = fmtstrflush(&fmt)) == nil)
|
||||||
return -1;
|
return -1;
|
||||||
nchal = snprint(chal, sizeof(chal), "%s %s %U", nonce, method, ru);
|
|
||||||
|
/* RFC2617 "quality of protection" (qop) extension */
|
||||||
|
if(cistrcmp(qop, "auth") == 0){
|
||||||
|
static uint counter = 0;
|
||||||
|
|
||||||
|
nc = ++counter;
|
||||||
|
genrandom(cnonce, sizeof(cnonce));
|
||||||
|
nchal = snprint(chal, sizeof(chal), "%s:%8.8ud:%.*H:%s %s %U",
|
||||||
|
nonce, nc, sizeof(cnonce), cnonce, qop, method, ru);
|
||||||
|
} else {
|
||||||
|
nc = 0;
|
||||||
|
nchal = snprint(chal, sizeof(chal), "%s %s %U", nonce, method, ru);
|
||||||
|
}
|
||||||
n = auth_respond(chal, nchal, ouser, sizeof ouser, resp, sizeof resp, hauthgetkey,
|
n = auth_respond(chal, nchal, ouser, sizeof ouser, resp, sizeof resp, hauthgetkey,
|
||||||
"proto=httpdigest role=client server=%q%s", u->host, s);
|
"proto=httpdigest role=client server=%q%s", u->host, s);
|
||||||
memset(chal, 0, sizeof(chal));
|
memset(chal, 0, sizeof(chal));
|
||||||
|
@ -446,7 +464,11 @@ authenticate(Url *u, Url *ru, char *method, char *s)
|
||||||
fmtprint(&fmt, "host=\"%N\", ", u->host);
|
fmtprint(&fmt, "host=\"%N\", ", u->host);
|
||||||
fmtprint(&fmt, "uri=\"%U\", ", ru);
|
fmtprint(&fmt, "uri=\"%U\", ", ru);
|
||||||
fmtprint(&fmt, "nonce=\"%s\", ", nonce);
|
fmtprint(&fmt, "nonce=\"%s\", ", nonce);
|
||||||
fmtprint(&fmt, "response=\"%s\"", resp);
|
if(cistrcmp(qop, "auth") == 0){
|
||||||
|
fmtprint(&fmt, "qop=%s, nc=%8.8ud, cnonce=\"%.*H\", ", qop, nc, sizeof(cnonce), cnonce);
|
||||||
|
memset(cnonce, 0, sizeof(cnonce));
|
||||||
|
}
|
||||||
|
fmtprint(&fmt, "response=\"%.*s\"", n, resp);
|
||||||
if(opaque)
|
if(opaque)
|
||||||
fmtprint(&fmt, ", opaque=\"%s\"", opaque);
|
fmtprint(&fmt, ", opaque=\"%s\"", opaque);
|
||||||
u = saneurl(url("/", u)); /* BUG: should be the ones in domain= only */
|
u = saneurl(url("/", u)); /* BUG: should be the ones in domain= only */
|
||||||
|
|
Loading…
Reference in a new issue