webfs: implement RFC2617 qop extension for http digest authentication

This commit is contained in:
cinap_lenrek 2022-04-02 19:20:56 +00:00
parent 945fef7ff2
commit 8166868375
2 changed files with 26 additions and 4 deletions

View file

@ -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))

View file

@ -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 */