diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-01-17 12:28:19 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-01-17 12:28:19 +0100 |
commit | d5e642d52d5701d00c052de59baeefdf50492dbe (patch) | |
tree | 8d15fc8325949b7f19fb89924d0f483072dfa132 | |
parent | e7399181a9652ac32193318bf7ffd268c96ab117 (diff) | |
download | plan9front-d5e642d52d5701d00c052de59baeefdf50492dbe.tar.xz |
webfs: handle multiple WWW-Authenticate headers, fix fmtstrinit() memory leaks
-rw-r--r-- | sys/src/cmd/webfs/fns.h | 1 | ||||
-rw-r--r-- | sys/src/cmd/webfs/http.c | 26 | ||||
-rw-r--r-- | sys/src/cmd/webfs/sub.c | 14 |
3 files changed, 29 insertions, 12 deletions
diff --git a/sys/src/cmd/webfs/fns.h b/sys/src/cmd/webfs/fns.h index 5646bd36b..655a9fe49 100644 --- a/sys/src/cmd/webfs/fns.h +++ b/sys/src/cmd/webfs/fns.h @@ -6,6 +6,7 @@ void nstrcpy(char *to, char *from, int n); 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); diff --git a/sys/src/cmd/webfs/http.c b/sys/src/cmd/webfs/http.c index f9cb50a21..ecc2dde83 100644 --- a/sys/src/cmd/webfs/http.c +++ b/sys/src/cmd/webfs/http.c @@ -322,7 +322,6 @@ authenticate(Url *u, Url *ru, char *method, char *s) 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 @@ authenticate(Url *u, Url *ru, char *method, char *s) 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 @@ authenticate(Url *u, Url *ru, char *method, char *s) 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 @@ authenticate(Url *u, Url *ru, char *method, char *s) 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 @@ authenticate(Url *u, Url *ru, char *method, char *s) 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,9 +799,7 @@ http(char *m, Url *u, Key *shdr, Buq *qbody, Buq *qpost) case 401: /* Unauthorized */ if(x = lookkey(shdr, "Authorization")) flushauth(nil, x); - if((x = lookkey(rhdr, "WWW-Authenticate")) == nil) - goto Error; - if(authenticate(u, &ru, method, x) < 0) + if(hauthenticate(u, &ru, method, "WWW-Authenticate", rhdr) < 0) goto Error; } if(0){ @@ -798,9 +808,7 @@ http(char *m, Url *u, Key *shdr, Buq *qbody, Buq *qpost) 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 */ diff --git a/sys/src/cmd/webfs/sub.c b/sys/src/cmd/webfs/sub.c index 476e5fd26..633f0edbf 100644 --- a/sys/src/cmd/webfs/sub.c +++ b/sys/src/cmd/webfs/sub.c @@ -71,14 +71,22 @@ delkey(Key *h, char *key) 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; } |