added basic auth to webfs. Reference: /n/sources/patch/applied/webfs-auth Date: Thu Oct 6 11:03:25 CES 2005 --- /sys/src/cmd/webfs/client.c Thu Oct 6 11:00:14 2005 +++ /sys/src/cmd/webfs/client.c Thu Oct 6 11:00:12 2005 @@ -55,6 +55,8 @@ c->url = nil; free(c->redirect); c->redirect = nil; + free(c->authenticate); + c->authenticate = nil; c->npostbody = 0; c->havepostbody = 0; c->bodyopened = 0; @@ -101,6 +103,8 @@ respond(r, e); return; } + if (c->authenticate) + continue; if(!c->redirect) break; next = c->redirect; --- /sys/src/cmd/webfs/http.c Thu Oct 6 11:00:30 2005 +++ /sys/src/cmd/webfs/http.c Thu Oct 6 11:00:27 2005 @@ -6,6 +6,8 @@ #include #include #include <9p.h> +#include +#include #include "dat.h" #include "fns.h" @@ -20,6 +22,7 @@ char *location; char *setcookie; char *netaddr; + char *credentials; Ibuf b; }; @@ -57,6 +60,46 @@ } } +void +sessionauth(HttpState *hs, char *value) +{ + char *f[4]; + UserPasswd *up; + char *s, cred[64], *usr, *pas; + + *cred = 0; + if(cistrncmp(value, "basic ", 6) != 0) + return; + if(gettokens(value, f, nelem(f), "\"") < 2) + return; + if(hs->c->url->user && hs->c->url->passwd){ + usr = hs->c->url->user; + pas = hs->c->url->passwd; + } + else + if(hs->c->url->user){ + if ((up = auth_getuserpasswd(auth_getkey, "proto=pass service=http user=%q dom=%q relm=%q", + hs->c->url->user, hs->netaddr, f[1])) == nil) + return; + usr = up->user; + pas = up->passwd; + } + else{ + if ((up = auth_getuserpasswd(auth_getkey, "proto=pass service=http dom=%q relm=%q", + hs->netaddr, f[1])) == nil) + return; + usr = up->user; + pas = up->passwd; + } + if ((s = smprint("%s:%s", usr, pas)) == nil) + return; + memset(pas, 0, strlen(pas)); + + enc64(cred, sizeof(cred), (uchar *)s, strlen(s)); + free(s); + hs->credentials = smprint("Basic %s", cred); +} + struct { char *name; /* Case-insensitive */ void (*fn)(HttpState *hs, char *value); @@ -64,6 +107,7 @@ { "location:", location }, { "content-type:", contenttype }, { "set-cookie:", setcookie }, + { "WWW-Authenticate:", sessionauth }, }; static int @@ -158,7 +202,7 @@ int httpopen(Client *c, Url *url) { - int fd, code, redirect; + int fd, code, redirect, authenticate; char *cookies; Ioproc *io; HttpState *hs; @@ -211,6 +255,11 @@ fprint(2, "<- Content-length: %ud\n", c->npostbody); } } + if(c->authenticate){ + ioprint(io, fd, "Authorization: %s\r\n", c->authenticate); + if(httpdebug) + fprint(2, "<- Authorization: %s\n", c->authenticate); + } ioprint(io, fd, "\r\n"); if(c->havepostbody) if(iowrite(io, fd, c->postbody, c->npostbody) != c->npostbody) @@ -218,6 +267,7 @@ c->havepostbody = 0; redirect = 0; + authenticate = 0; initibuf(&hs->b, io, fd); code = httprcode(hs); @@ -258,8 +308,14 @@ goto Error; case 401: /* Unauthorized */ + if (c->authenticate){ + werrstr("Authentication failed (401)"); + goto Error; + } + authenticate = 1; + break; case 402: /* ??? */ - werrstr("Unauthorized (401,402)"); + werrstr("Unauthorized (402)"); goto Error; case 403: /* Forbidden */ @@ -270,6 +326,10 @@ werrstr("Not found on server (404)"); goto Error; + case 407: /* Proxy auth */ + werrstr("Proxy authentication required (407)"); + goto Error; + case 500: /* Internal server error */ werrstr("Server choked (500)"); goto Error; @@ -296,6 +356,14 @@ goto Error; if(c->ctl.acceptcookies && hs->setcookie) httpsetcookie(hs->setcookie, url->host, url->path); + if (authenticate){ + if (!hs->credentials){ + werrstr("Authentication without WWW-Authenticate: header"); + return -1; + } + c->authenticate = hs->credentials; + hs->credentials = nil; + } if(redirect){ if(!hs->location){ werrstr("redirection without Location: header"); @@ -349,6 +417,7 @@ free(hs->location); free(hs->setcookie); free(hs->netaddr); + free(hs->credentials); free(hs); c->aux = nil; } --- /sys/src/cmd/webfs/dat.h Thu Oct 6 11:00:48 2005 +++ /sys/src/cmd/webfs/dat.h Thu Oct 6 11:00:45 2005 @@ -31,6 +31,7 @@ char *contenttype; char *postbody; char *redirect; + char *authenticate; char *ext; int npostbody; int havepostbody; --- /sys/src/cmd/webfs/url.c Thu Oct 6 11:01:09 2005 +++ /sys/src/cmd/webfs/url.c Thu Oct 6 11:01:05 2005 @@ -735,10 +735,6 @@ werrstr("missing authority (hostname, port, etc.)"); return -1; } - if(u->user || u->passwd){ - werrstr("user information not valid with http"); - return -1; - } if(u->host == nil){ werrstr("missing host specification"); return -1;