shithub: riscv

Download patch

ref: d5e642d52d5701d00c052de59baeefdf50492dbe
parent: e7399181a9652ac32193318bf7ffd268c96ab117
author: cinap_lenrek <[email protected]>
date: Thu Jan 17 07:28:19 EST 2013

webfs: handle multiple WWW-Authenticate headers, fix fmtstrinit() memory leaks

--- a/sys/src/cmd/webfs/fns.h
+++ b/sys/src/cmd/webfs/fns.h
@@ -6,6 +6,7 @@
 
 Key*	addkey(Key *h, char *key, char *val);
 Key*	delkey(Key *h, char *key);
+Key*	getkey(Key *h, char *key);
 char*	lookkey(Key *k, char *key);
 Key*	parsehdr(char *s);
 char*	unquote(char *s, char **ps);
--- a/sys/src/cmd/webfs/http.c
+++ b/sys/src/cmd/webfs/http.c
@@ -322,7 +322,6 @@
 	user = u->user;
 	pass = u->pass;
 	realm = nonce = opaque = nil;
-	fmtstrinit(&fmt);
 	if(!cistrncmp(s, "Basic ", 6)){
 		char cred[128], plain[128];
 		UserPasswd *up;
@@ -334,6 +333,7 @@
 			return -1;
 		up = nil;
 		if(user == nil || pass == nil){
+			fmtstrinit(&fmt);
 			fmtprint(&fmt, " realm=%q", realm);
 			if(user)
 				fmtprint(&fmt, " user=%q", user);
@@ -374,6 +374,7 @@
 			opaque = unquote(x+7, &s);
 		if(realm == nil || nonce == nil)
 			return -1;
+		fmtstrinit(&fmt);
 		fmtprint(&fmt, " realm=%q", realm);
 		if(user)
 			fmtprint(&fmt, " user=%q", user);
@@ -399,12 +400,14 @@
 		u = saneurl(url("/", u));	/* BUG: should be the ones in domain= only */
 	} else
 		return -1;
-	if(u == nil)
-		return -1;
 	if((s = fmtstrflush(&fmt)) == nil){
 		freeurl(u);
 		return -1;
 	}
+	if(u == nil){
+		free(s);
+		return -1;
+	}
 	a = emalloc(sizeof(*a));
 	a->url = u;
 	a->auth = s;
@@ -416,6 +419,15 @@
 	return 0;
 }
 
+int
+hauthenticate(Url *u, Url *ru, char *method, char *key, Key *hdr)
+{
+	for(hdr = getkey(hdr, key); hdr != nil; hdr = getkey(hdr->next, key))
+		if(authenticate(u, ru, method, hdr->val) == 0)
+			return 0;
+	return -1;
+}
+
 void
 flushauth(Url *u, char *t)
 {
@@ -787,10 +799,8 @@
 		case 401:	/* Unauthorized */
 			if(x = lookkey(shdr, "Authorization"))
 				flushauth(nil, x);
-			if((x = lookkey(rhdr, "WWW-Authenticate")) == nil)
+			if(hauthenticate(u, &ru, method, "WWW-Authenticate", rhdr) < 0)
 				goto Error;
-			if(authenticate(u, &ru, method, x) < 0)
-				goto Error;
 			}
 			if(0){
 		case 407:	/* Proxy Auth */
@@ -798,9 +808,7 @@
 				goto Error;
 			if(x = lookkey(shdr, "Proxy-Authorization"))
 				flushauth(proxy, x);
-			if((x = lookkey(rhdr, "Proxy-Authenticate")) == nil)
-				goto Error;
-			if(authenticate(proxy, proxy, method, x) < 0)
+			if(hauthenticate(u, &ru, method, "Proxy-Authenticate", rhdr) < 0)
 				goto Error;
 			}
 		case 0:		/* No status */
--- a/sys/src/cmd/webfs/sub.c
+++ b/sys/src/cmd/webfs/sub.c
@@ -71,14 +71,22 @@
 	return h;
 }
 
-char*
-lookkey(Key *k, char *key)
+Key*
+getkey(Key *k, char *key)
 {
 	while(k){
 		if(!cistrcmp(k->key, key))
-			return k->val;
+			break;
 		k = k->next;
 	}
+	return k;
+}
+
+char*
+lookkey(Key *k, char *key)
+{
+	if(k = getkey(k, key))
+		return k->val;
 	return nil;
 }