Re: HTRequest only holds a single auth scheme
Steinar Bang <[email protected]> Fri, 04 Jun 2004 10:00:16 +0200
| Newsgroups | gmane.comp.lib.libwww |
|---|---|
| Organization | Probably a good idea |
| Message-ID | <[email protected]> |
>>>>> Steinar Bang <[email protected]>: >>>>> Steinar Bang <[email protected]>: >> The apache mod_auth_kerberos module by default has two >> WWW-Authenticate headers, one for "Negotiate", and one for "Basic". >> I believe this is the default behaviour for IIS as well. >> However the HTRequest structure only has room for a single >> authentication scheme, so the last WWW-Authentication header >> ("Basic" in this case) overwrites any previous values set. >> This means that my functions set with a call to HTAA_newModule(), are >> only called when I switch off password authentication. > Attached is my attempt at a patch for multiple auth schemes (diff done > against libwww CVS HEAD). The idea is to iterate through the list in > the order the WWW-Authenticate headers occur in the HTTP response, and > if the implementation for a scheme returns HT_ERROR, skip to the next > one. The previous patch didn't build with MSVC7.1. I had to declare local variables in a single block at the start of the functions. New patch attached.
multiple_authschemes.diff
(text/x-patch, 9.2 KB)
Index: Library/src/HTAAUtil.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTAAUtil.c,v
retrieving revision 2.35
diff -c -c -r2.35 HTAAUtil.c
*** a/Library/src/HTAAUtil.c 22 Feb 1999 22:10:10 -0000 2.35
--- b/Library/src/HTAAUtil.c 4 Jun 2004 07:57:00 -0000
***************
*** 414,419 ****
--- 414,439 ----
return HT_OK;
}
+ /*
+ ** Single point of change structuring function.
+ ** Call the after function of the authentication module identified by
+ ** the scheme argument
+ */
+ PRIVATE int run_after_filter (HTRequest * request,
+ HTResponse * response,
+ const char * scheme,
+ int status)
+ {
+ HTAAModule * module = NULL;
+ if ((module = HTAA_findModule(scheme)) != NULL) {
+ HTTRACE(AUTH_TRACE, "Auth Engine. Found AFTER filter %p\n" _ module->after);
+ HTRequest_deleteCredentialsAll(request);
+ HTRequest_addAARetry (request);
+ return (*module->after)(request, response, NULL, status);
+ }
+ return HT_ERROR;
+ }
+
/* HTAA_afterFilter
** -----------------
** Call the AFTER filter that knows how to handle this scheme.
***************
*** 422,443 ****
PUBLIC int HTAA_afterFilter (HTRequest * request, HTResponse * response,
void * param, int status)
{
! const char * scheme = HTResponse_scheme(response);
! HTAAModule * module = NULL;
HTTRACE(AUTH_TRACE, "Auth Engine. After filter status %d\n" _ status);
! /*
! ** If we don't have a scheme then the server has made an error. We
! ** try to make up for it by creating our own "noop" realm and use basic.
! */
! if (!scheme) {
HTResponse_addChallenge(response, "basic", "realm LIBWWW-UNKNOWN");
scheme = "basic";
}
if ((module = HTAA_findModule(scheme)) != NULL) {
! HTTRACE(AUTH_TRACE, "Auth Engine. Found AFTER filter %p\n" _ module->after);
HTRequest_deleteCredentialsAll(request);
! HTRequest_addAARetry (request);
! return (*module->after)(request, response, NULL, status);
}
return HT_ERROR;
}
--- 442,490 ----
PUBLIC int HTAA_afterFilter (HTRequest * request, HTResponse * response,
void * param, int status)
{
! const char* scheme = 0;
! HTList * schemes = 0;
HTTRACE(AUTH_TRACE, "Auth Engine. After filter status %d\n" _ status);
! schemes = HTResponse_schemes(response);
! if (schemes != 0) {
! while ((scheme = (char *) HTList_nextObject(schemes))) {
! int retval = run_after_filter(request,response,scheme,status);
! if (retval != HT_ERROR) {
! return retval;
! }
! }
! return HT_ERROR;
! } else {
! /*
! ** If we don't have a scheme then the server has made an
! ** error. We try to make up for it by creating our own "noop"
! ** realm and use basic.
! */
HTResponse_addChallenge(response, "basic", "realm LIBWWW-UNKNOWN");
scheme = "basic";
+ return run_after_filter(request, response, scheme, status);
}
+ }
+ /*
+ ** Single point of change structuring function.
+ ** Call the after function of the authentication module identified by
+ ** the scheme argument
+ */
+ PRIVATE int run_update_filter (HTRequest * request,
+ HTResponse * response,
+ const char * scheme,
+ int status)
+ {
+ HTAAModule * module = NULL;
if ((module = HTAA_findModule(scheme)) != NULL) {
! /* we don't call this module systematically, as it could hamper
! the execution of Basic authentication requests for nothing */
! if (module->update) {
! HTTRACE(AUTH_TRACE, "Auth Engine. Found Update filter %p\n" _ module->update);
HTRequest_deleteCredentialsAll(request);
! return (*module->update)(request, response, NULL, status);
! }
! return HT_OK;
}
return HT_ERROR;
}
***************
*** 450,477 ****
PUBLIC int HTAA_updateFilter (HTRequest * request, HTResponse * response,
void * param, int status)
{
! const char * scheme = HTResponse_scheme(response);
! HTAAModule * module = NULL;
HTTRACE(AUTH_TRACE, "Auth Engine. Update filter status %d\n" _ status);
! /*
! ** If we don't have a scheme then the server has made an error. We
! ** try to make up for it by creating our own "noop" realm and use basic.
! */
! if (!scheme) {
HTResponse_addChallenge(response, "basic", "realm LIBWWW-UNKNOWN");
scheme = "basic";
}
- if ((module = HTAA_findModule(scheme)) != NULL) {
- /* we don't call this module systematically, as it could hamper
- the execution of Basic authentication requests for nothing */
- if (module->update) {
- HTTRACE(AUTH_TRACE, "Auth Engine. Found Update filter %p\n" _ module->update);
- HTRequest_deleteCredentialsAll(request);
- return (*module->update)(request, response, NULL, status);
- }
- return HT_OK;
- }
- return HT_ERROR;
}
--- 497,524 ----
PUBLIC int HTAA_updateFilter (HTRequest * request, HTResponse * response,
void * param, int status)
{
! const char * scheme = 0;
! HTList * schemes = 0;
HTTRACE(AUTH_TRACE, "Auth Engine. Update filter status %d\n" _ status);
! schemes = HTResponse_schemes(response);
! if (schemes != 0) {
! while ((scheme = (char *) HTList_nextObject(schemes))) {
! int retval = run_update_filter(request,response,scheme,status);
! if (retval != HT_ERROR) {
! return retval;
! }
! }
! return HT_ERROR;
! } else {
! /*
! ** If we don't have a scheme then the server has made an
! ** error. We try to make up for it by creating our own "noop"
! ** realm and use basic.
! */
HTResponse_addChallenge(response, "basic", "realm LIBWWW-UNKNOWN");
scheme = "basic";
+ return run_update_filter(request, response, scheme, status);
}
}
Index: Library/src/HTResMan.html
===================================================================
RCS file: /sources/public/libwww/Library/src/HTResMan.html,v
retrieving revision 2.7
diff -c -c -r2.7 HTResMan.html
*** a/Library/src/HTResMan.html 30 Oct 2000 10:04:23 -0000 2.7
--- b/Library/src/HTResMan.html 4 Jun 2004 07:57:00 -0000
***************
*** 73,79 ****
by the authentication parsers and generators respectively.
<PRE>
char * realm; /* Current realm */
! char * scheme; /* Current scheme */
HTAssocList * challenge; /* Challenge received in response */
</PRE>
--- 73,79 ----
by the authentication parsers and generators respectively.
<PRE>
char * realm; /* Current realm */
! HTList * schemes; /* Current schemes */
HTAssocList * challenge; /* Challenge received in response */
</PRE>
Index: Library/src/HTResponse.c
===================================================================
RCS file: /sources/public/libwww/Library/src/HTResponse.c,v
retrieving revision 2.12
diff -c -c -r2.12 HTResponse.c
*** a/Library/src/HTResponse.c 30 Oct 2000 10:04:23 -0000 2.12
--- b/Library/src/HTResponse.c 4 Jun 2004 07:57:00 -0000
***************
*** 43,54 ****
PUBLIC BOOL HTResponse_delete (HTResponse * me)
{
if (me) {
HTTRACE(CORE_TRACE, "Response.... Delete %p\n" _ me);
/* Access Authentication */
HT_FREE(me->realm);
! HT_FREE(me->scheme);
if (me->challenge) HTAssocList_delete(me->challenge);
/* Connection headers */
--- 43,59 ----
PUBLIC BOOL HTResponse_delete (HTResponse * me)
{
+ char * scheme;
+ HTList * cursor = 0;
if (me) {
HTTRACE(CORE_TRACE, "Response.... Delete %p\n" _ me);
/* Access Authentication */
HT_FREE(me->realm);
! cursor = me->schemes;
! while ((scheme = (char *) HTList_nextObject(cursor)))
! HT_FREE(scheme);
! HTList_delete(me->schemes);
if (me->challenge) HTAssocList_delete(me->challenge);
/* Connection headers */
***************
*** 189,204 ****
*/
PUBLIC BOOL HTResponse_setScheme (HTResponse * me, char * scheme)
{
if (me && scheme) {
! StrAllocCopy(me->scheme, scheme);
return YES;
}
return NO;
}
! PUBLIC const char * HTResponse_scheme (HTResponse * me)
{
! return (me ? me->scheme : NULL);
}
/*
--- 194,214 ----
*/
PUBLIC BOOL HTResponse_setScheme (HTResponse * me, char * scheme)
{
+ char* responseScheme = 0;
if (me && scheme) {
! if (me->schemes == 0) {
! me->schemes = HTList_new();
! }
! StrAllocCopy(responseScheme, scheme);
! HTList_appendObject(me->schemes, responseScheme);
return YES;
}
return NO;
}
! PUBLIC HTList * HTResponse_schemes (HTResponse * me)
{
! return me->schemes;
}
/*
Index: Library/src/HTResponse.html
===================================================================
RCS file: /sources/public/libwww/Library/src/HTResponse.html,v
retrieving revision 2.14
diff -c -c -r2.14 HTResponse.html
*** a/Library/src/HTResponse.html 19 Dec 2000 11:21:29 -0000 2.14
--- b/Library/src/HTResponse.html 4 Jun 2004 07:57:00 -0000
***************
*** 127,133 ****
</H3>
<PRE>
extern BOOL HTResponse_setScheme (HTResponse * response, char * scheme);
! extern const char * HTResponse_scheme (HTResponse * response);
</PRE>
<H2>
HTTP Connection Control Directives
--- 127,133 ----
</H3>
<PRE>
extern BOOL HTResponse_setScheme (HTResponse * response, char * scheme);
! extern HTList * HTResponse_schemes (HTResponse * response);
</PRE>
<H2>
HTTP Connection Control Directives