Hi Christian, On Thu, Oct 02, 2008 at 09:15:58AM +0200, Christian Kellermann wrote:
* corvid <corvid@lavabit.com> [081002 06:41]:
Christian wrote:
Dear List,
since I have not found any traces of discussion on this list about this topic I dare to ask where to place code handling basic authentication in dillo's source? As I see it the cache module is responsible for handling server responses. So I would at a first try add the code there. How can I connect to a UI dialog from here to get the necessary credentials? Maybe a possible solution looks like this:
- react to 403 header and look for Authorization request - if there is one ask the user for username/pass + resend the request with the Authorisation header added + or display the 403 if the user aborts
What do you think? I will come up with some example code to illustrate the idea in case this is not very clear.
(We'll see what Jorge has to say, but...) cache.c seems like the right place to me, with a dialog called by way of uicmd.cc. The auth data would be stored away somewhere (a new file?), which a_Http_make_query_str() could call like it calls a_Cookies_get_query().
This sounds good.
Yes, following the cookies model, without the dpi part, is a good idea.
What I am thinking about at the moment is how to keep the user/password combination attached to a certain URL for future reference? As I see it the connection structure gets dropped as soon as the transfer of one entity is finished...
A new file (auth.c or basic_auth.c) looks like a good place for the auth-specific functions and data. i.e. you can store a URL to user/password/whatever table there, and query it when the AUTH flag is set.
To be more specific I have been trying something like this:
Index: src/cache.c =================================================================== RCS file: /sfhome/cvs/dillo/dillo2/src/cache.c,v retrieving revision 1.33 diff -b -u -p -r1.33 cache.c --- src/cache.c 14 Sep 2008 20:26:08 -0000 1.33 +++ src/cache.c 2 Oct 2008 07:13:11 -0000 @@ -617,7 +617,7 @@ static Dlist *Cache_parse_multiple_field static void Cache_parse_header(CacheEntry_t *entry) { char *header = entry->Header->str; - char *Length, *Type, *location_str, *encoding, *charset; + char *Length, *Type, *location_str, *encoding, *charset, *auth; #ifndef DISABLE_COOKIES Dlist *Cookies; #endif @@ -657,6 +657,23 @@ static void Cache_parse_header(CacheEntr } dFree(location_str);
+ } else if (strncmp(header + 9, "401", 3) == 0) { + auth = Cache_parse_field(header, "WWW-Authenticate"); + if ( auth ) { + if (strncmp(auth, "Basic", 5) == 0) { + entry->Flags |= CA_AuthNeeded; + entry->Flags |= CA_AuthBasic; + MSG_HTTP("Basic Authentication request\n"); + } else if (strncmp(auth, "Digest", 6) == 0) { + entry->Flags |= CA_AuthNeeded; + entry->Flags |= CA_AuthDigest; + MSG_HTTP("Digest Authentication request\n"); + } else { + MSG_ERR("Unknown authentication method in request " + "'%s'.\n", auth); + } + MSG_HTTP(" for %s!\n", URL_STR(entry->Url)); + } } else if (strncmp(header + 9, "404", 3) == 0) { entry->Flags |= CA_NotFound; } @@ -1037,6 +1054,11 @@ static void Cache_process_queue(CacheEnt entry->ExpectedSize / (1024*1024)); AbortEntry = OfferDownload = TRUE; } + if (entry->Flags & CA_AuthNeeded) { + if (!Client->Callback) { + Client->Callback = Cache_null_client; + } + } } else { /* For non root URLs, ignore redirections and 404 answers */ if (entry->Flags & CA_Redirect || entry->Flags & CA_NotFound) Index: src/cache.h =================================================================== RCS file: /sfhome/cvs/dillo/dillo2/src/cache.h,v retrieving revision 1.5 diff -b -u -p -r1.5 cache.h --- src/cache.h 2 Jun 2008 02:27:43 -0000 1.5 +++ src/cache.h 2 Oct 2008 07:13:11 -0000 @@ -33,6 +33,9 @@ extern "C" { #define CA_InternalUrl 0x800 /* URL content is generated by dillo */ #define CA_HugeFile 0x1000 /* URL content is too big */ #define CA_IsEmpty 0x2000 /* True until a byte of content arrives */ +#define CA_AuthNeeded 0x4000 /* Set if server requests authentication */ +#define CA_AuthBasic 0x8000 /* Set if server requests basic authentication */ +#define CA_AuthDigest 0x10000 /* Set if server requests digest authentication */
/* * Callback type for cache clients
The bit in Cache_process_queue should be the place where the handling is done, at least so I thought. Maybe that is not a good idea... Also I am a but uneasy with introducing new flags but it somehow fits the overall scheme.
Maybe it's possible to make it with just one flag: CA_AuthNeeded. Storing the details in the auth table.
Any suggestions?
Yes, go ahead with the prototype implementation, and if you need more advice, just ask. Currently we're quite busy with the release schedule (a few days to go), so please be patient... -- Cheers Jorge.-