ref: fc0eee2980f993d1474669e04859e80ef7e231db
parent: 8166868375e2994265e4e2dfd788dae2c4b6754f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Apr 2 16:29:20 EDT 2022
webfs: do not reuse digest Authorization headers We must use the digest authorization header only once for a single request.
--- a/sys/src/cmd/webfs/http.c
+++ b/sys/src/cmd/webfs/http.c
@@ -505,27 +505,33 @@
}
void
+freeauth(Hauth **a)
+{
+ Hauth *x = *a;
+
+ if(x == nil)
+ return;
+ *a = x->next;
+ if(debug)
+ fprint(2, "freeauth for %U\n", x->url);
+ freeurl(x->url);
+ memset(x->auth, 0, strlen(x->auth));
+ free(x->auth);
+ free(x);
+}
+
+void
flushauth(Url *u, char *t)
{
- Hauth *a, *p;
+ Hauth **a;
- qlock(&authlk);
-Again:
- for(p = nil, a = hauth; a; p = a, a = a->next)
- if(matchurl(u, a->url) && (t == nil || !strcmp(t, a->auth))){
- if(p)
- p->next = a->next;
- else
- hauth = a->next;
- if(debug)
- fprint(2, "flushauth for %U\n", a->url);
- freeurl(a->url);
- memset(a->auth, 0, strlen(a->auth));
- free(a->auth);
- free(a);
- goto Again;
+ for(a = &hauth; *a != nil; ){
+ if(matchurl(u, (*a)->url) && (t == nil || !strcmp(t, (*a)->auth))){
+ freeauth(a);
+ continue;
}
- qunlock(&authlk);
+ a = &(*a)->next;
+ }
}
static void
@@ -548,7 +554,7 @@
Url ru, tu, *nu;
Key *k, *rhdr;
Hconn *h;
- Hauth *a;
+ Hauth **a;
incref(qbody);
if(qpost) incref(qpost);
@@ -598,15 +604,17 @@
/* preemptive authentication from hauth cache */
qlock(&authlk);
if(proxy && !lookkey(shdr, "Proxy-Authorization"))
- for(a = hauth; a; a = a->next)
- if(matchurl(a->url, proxy)){
- shdr = addkey(shdr, "Proxy-Authorization", a->auth);
+ for(a = &hauth; *a != nil; a = &(*a)->next)
+ if(matchurl((*a)->url, proxy)){
+ shdr = addkey(shdr, "Proxy-Authorization", (*a)->auth);
+ if(strncmp((*a)->auth, "Digest ", 7) == 0) freeauth(a);
break;
}
if(!lookkey(shdr, "Authorization"))
- for(a = hauth; a; a = a->next)
- if(matchurl(a->url, u)){
- shdr = addkey(shdr, "Authorization", a->auth);
+ for(a = &hauth; *a != nil; a = &(*a)->next)
+ if(matchurl((*a)->url, u)){
+ shdr = addkey(shdr, "Authorization", (*a)->auth);
+ if(strncmp((*a)->auth, "Digest ", 7) == 0) freeauth(a);
break;
}
qunlock(&authlk);
@@ -900,7 +908,9 @@
if(0){
case 401: /* Unauthorized */
if(x = lookkey(shdr, "Authorization")){
+ qlock(&authlk);
flushauth(nil, x);
+ qunlock(&authlk);
if(badauth++)
goto Error;
}
@@ -918,7 +928,9 @@
if(proxy == nil)
goto Error;
if(x = lookkey(shdr, "Proxy-Authorization")){
+ qlock(&authlk);
flushauth(proxy, x);
+ qunlock(&authlk);
if(badauth++)
goto Error;
}