Added digest parser for Authorization header Reference: /n/sources/patch/applied/libhttpd-digest-auth Date: Fri Apr 18 16:42:36 CES 2008 Signed-off-by: fst@9netics.com --- /sys/src/libhttpd/parse.c Fri Apr 18 16:40:05 2008 +++ /sys/src/libhttpd/parse.c Fri Apr 18 16:40:02 2008 @@ -567,6 +567,30 @@ } /* + * parse it like cookies + */ +static void +authdigest(Hlex *h, char *) +{ + char *s; + HSPairs *p; + + p = nil; + for(;;){ + while(lex(h) != Word) + if(h->tok != ';' && h->tok != ',') + goto breakout; + s = hstrdup(h->c, h->wordval); + while (lex(h) != Word && h->tok != QString) + if (h->tok != '=') + goto breakout; + p = hmkspairs(h->c, s, hstrdup(h->c, h->wordval), p); + } +breakout: + h->c->head.authinfo = hrevspairs(p); +} + +/* * note: netscape and ie through versions 4.7 and 4 * support only basic authorization, so that is all that is supported here * @@ -575,14 +599,11 @@ * username ":" password */ static void -mimeauthorization(Hlex *h, char *) +authbasic(Hlex *h, char *) { char *up, *p; int n; - if(lex(h) != Word || cistrcmp(h->wordval, "basic") != 0) - return; - n = lexbase64(h); if(!n) return; @@ -608,6 +629,29 @@ *p++ = '\0'; h->c->head.authuser = hstrdup(h->c, up); h->c->head.authpass = hstrdup(h->c, p); + } +} + +/* + * "Authorization" ":" "Basic" | "Digest" ... + */ +static void +mimeauthorization(Hlex *h, char *) +{ + int i; + static MimeHead authparser[] = { + { "basic", authbasic }, + { "digest", authdigest }, + }; + + if(lex(h) != Word) + return; + + for (i = 0; i < nelem(authparser); i++) { + if (cistrcmp(h->wordval, authparser[i].name) == 0) { + (*authparser[i].parse)(h, nil); + break; + } } } --- /sys/include/httpd.h Fri Apr 18 16:40:10 2008 +++ /sys/include/httpd.h Fri Apr 18 16:40:07 2008 @@ -55,8 +55,8 @@ HContent *next; char *generic; char *specific; - float q; /* desirability of this kind of file */ - int mxb; /* max uchars until worthless */ + float q; /* desirability of this kind of file */ + int mxb; /* max uchars until worthless */ }; struct HContents @@ -126,15 +126,15 @@ }; struct Hio { - Hio *hh; /* next lower layer Hio, or nil if reads from fd */ - int fd; /* associated file descriptor */ - ulong seek; /* of start */ - uchar state; /* state of the file */ - uchar xferenc; /* chunked transfer encoding state */ - uchar *pos; /* current position in the buffer */ - uchar *stop; /* last character active in the buffer */ - uchar *start; /* start of data buffer */ - ulong bodylen; /* remaining length of message body */ + Hio *hh; /* next lower layer Hio, or nil if reads from fd */ + int fd; /* associated file descriptor */ + ulong seek; /* of start */ + uchar state; /* state of the file */ + uchar xferenc; /* chunked transfer encoding state */ + uchar *pos; /* current position in the buffer */ + uchar *stop; /* last character active in the buffer */ + uchar *start; /* start of data buffer */ + ulong bodylen; /* remaining length of message body */ uchar buf[Hsize+32]; }; @@ -149,7 +149,7 @@ char *search; int vermaj; int vermin; - HSPairs *searchpairs; + HSPairs *searchpairs; }; /* @@ -157,35 +157,36 @@ */ struct HttpHead { - int closeit; /* http1.1 close connection after this request? */ - uchar persist; /* http/1.1 requests a persistent connection */ + int closeit; /* http1.1 close connection after this request? */ + uchar persist; /* http/1.1 requests a persistent connection */ - uchar expectcont; /* expect a 100-continue */ - uchar expectother; /* expect anything else; should reject with ExpectFail */ - ulong contlen; /* if != ~0UL, length of included message body */ - HFields *transenc; /* if present, encoding of included message body */ - char *client; - char *host; - HContent *okencode; - HContent *oklang; - HContent *oktype; - HContent *okchar; - ulong ifmodsince; - ulong ifunmodsince; - ulong ifrangedate; - HETag *ifmatch; - HETag *ifnomatch; - HETag *ifrangeetag; - HRange *range; - char *authuser; /* authorization info */ - char *authpass; - HSPairs *cookie; /* if present, list of cookies */ + uchar expectcont; /* expect a 100-continue */ + uchar expectother; /* expect anything else; should reject with ExpectFail */ + ulong contlen; /* if != ~0UL, length of included message body */ + HFields *transenc; /* if present, encoding of included message body */ + char *client; + char *host; + HContent *okencode; + HContent *oklang; + HContent *oktype; + HContent *okchar; + ulong ifmodsince; + ulong ifunmodsince; + ulong ifrangedate; + HETag *ifmatch; + HETag *ifnomatch; + HETag *ifrangeetag; + HRange *range; + char *authuser; /* authorization info */ + char *authpass; + HSPairs *cookie; /* if present, list of cookies */ + HSPairs *authinfo; /* digest authorization */ /* * experimental headers */ - int fresh_thresh; - int fresh_have; + int fresh_thresh; + int fresh_have; }; /* @@ -193,21 +194,21 @@ */ struct HConnect { - void *private; /* for the library clients */ - void (*replog)(HConnect*, char*, ...); /* called when reply sent */ + void *private; /* for the library clients */ + void (*replog)(HConnect*, char*, ...); /* called when reply sent */ - HttpReq req; - HttpHead head; + HttpReq req; + HttpHead head; - Bin *bin; + Bin *bin; - ulong reqtime; /* time at start of request */ - char xferbuf[HBufSize]; /* buffer for making up or transferring data */ - uchar header[HBufSize + 2]; /* room for \n\0 */ - uchar *hpos; - uchar *hstop; - Hio hin; - Hio hout; + ulong reqtime; /* time at start of request */ + char xferbuf[HBufSize]; /* buffer for making up or transferring data */ + uchar header[HBufSize + 2]; /* room for \n\0 */ + uchar *hpos; + uchar *hstop; + Hio hin; + Hio hout; }; /*