diff options
author | Stef Walter <stef@memberwebs.com> | 2007-05-31 23:29:35 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2007-05-31 23:29:35 +0000 |
commit | 6d7feb248daf16c260007388692d6de48416d9b7 (patch) | |
tree | 7bb76f937b738c78f8c6dabd66e7b721e1b73b3a | |
parent | 82a32ff78428bec9f9a4f69cc21ccf9d197a38ff (diff) |
Support ignoring the HTTP method.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | daemon/bd.c | 2 | ||||
-rw-r--r-- | daemon/digest.c | 35 | ||||
-rw-r--r-- | daemon/digest.h | 2 | ||||
-rw-r--r-- | daemon/httpauthd.c | 10 | ||||
-rw-r--r-- | daemon/httpauthd.h | 1 | ||||
-rw-r--r-- | daemon/ldap.c | 4 | ||||
-rw-r--r-- | daemon/simple.c | 2 | ||||
-rw-r--r-- | doc/httpauthd.conf.5 | 11 |
10 files changed, 64 insertions, 11 deletions
@@ -1,3 +1,7 @@ +0.8 + - Support ignoring of HTTP method in digest. Useful for pass-through + authentication between SOAP services and websites. + 0.7 [28-05-2007] - Use my real name 'Stef Walter' See: http://memberwebs.com/nielsen/ diff --git a/configure.in b/configure.in index ee8b6db..cc350e7 100644 --- a/configure.in +++ b/configure.in @@ -36,8 +36,8 @@ dnl Stef Walter <stef@memberwebs.com> dnl dnl Process this file with autoconf to produce a configure script. -AC_INIT(httpauth, 0.7, stef@memberwebs.com) -AM_INIT_AUTOMAKE(httpauth, 0.7) +AC_INIT(httpauth, 0.7.90, stef@memberwebs.com) +AM_INIT_AUTOMAKE(httpauth, 0.7.90) LDFLAGS="$LDFLAGS -L/usr/local/lib" CFLAGS="$CFLAGS -I/usr/local/include -g -O0" diff --git a/daemon/bd.c b/daemon/bd.c index 6383801..e11a56b 100644 --- a/daemon/bd.c +++ b/daemon/bd.c @@ -405,7 +405,7 @@ static int do_digest_response(ha_request_t* rq, bd_context_t* ctx, const char* h /* And do the validation ourselves */ memcpy(dg.ha1, rec->ha1, MD5_LEN); - ret = digest_complete_check(&dg, rq->buf); + ret = digest_complete_check(&dg, rq->context, rq->buf); if(ret != HA_OK) { diff --git a/daemon/digest.c b/daemon/digest.c index dc0cfb9..1c68366 100644 --- a/daemon/digest.c +++ b/daemon/digest.c @@ -32,6 +32,11 @@ /* A globally unique counter used to guarantee uniqueness of nonces */ static unsigned int g_digest_unique = 0; +/* All the various HTTP methods to try when ignoring the method */ +static const char* g_http_methods[] = { + "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT", NULL +}; + typedef struct internal_nonce { unsigned char hash[MD5_LEN]; @@ -242,7 +247,7 @@ int digest_check(digest_context_t* dg, const ha_context_t* opts, ha_buffer_t* bu r = digest_pre_check(dg, opts, buf); if(r == HA_OK) - r = digest_complete_check(dg, buf); + r = digest_complete_check(dg, opts, buf); return r; } @@ -396,7 +401,7 @@ int digest_pre_check(digest_context_t* dg, const ha_context_t* opts, ha_buffer_t } -int digest_complete_check(digest_context_t* dg, ha_buffer_t* buf) +static int internal_check(digest_context_t* dg, const char* http_method, ha_buffer_t* buf) { unsigned char hash[MD5_LEN]; md5_ctx_t md5; @@ -419,7 +424,7 @@ int digest_complete_check(digest_context_t* dg, ha_buffer_t* buf) /* Encode ha2 */ md5_init(&md5); - md5_update(&md5, dg->server_method, strlen(dg->server_method)); + md5_update(&md5, http_method, strlen(http_method)); md5_update(&md5, ":", 1); md5_update(&md5, dg->client.uri, strlen(dg->client.uri)); md5_final(hash, &md5); @@ -479,6 +484,30 @@ int digest_complete_check(digest_context_t* dg, ha_buffer_t* buf) return HA_OK; } +int digest_complete_check(digest_context_t* dg, const ha_context_t* opts, ha_buffer_t* buf) +{ + const char** m; + int ret; + + if(opts->digest_ignoremethod) + { + /* Try out each and every method in HTTP */ + for(m = g_http_methods; *m; ++m) + { + ret = internal_check (dg, *m, buf); + if(ret != HA_FALSE) + break; + } + } + else + { + /* Use the method sent to us */ + ret = internal_check (dg, dg->server_method, buf); + } + + return ret; +} + const char* digest_respond(digest_context_t* dg, ha_buffer_t* buf, unsigned char* next) { diff --git a/daemon/digest.h b/daemon/digest.h index 86360c7..af8a1d7 100644 --- a/daemon/digest.h +++ b/daemon/digest.h @@ -73,7 +73,7 @@ int digest_check(digest_context_t* dg, const ha_context_t* opts, ha_buffer_t* bu int digest_pre_check(digest_context_t* dg, const ha_context_t* opts, ha_buffer_t* buf); /* This assumes a digest_context that's been prechecked successfully */ -int digest_complete_check(digest_context_t* dg, ha_buffer_t* buf); +int digest_complete_check(digest_context_t* dg, const ha_context_t* opts, ha_buffer_t* buf); /* This assumes a digest_context that's been checked and validated successfully */ const char* digest_respond(digest_context_t* dg, ha_buffer_t* buf, unsigned char* next); diff --git a/daemon/httpauthd.c b/daemon/httpauthd.c index 68c0e46..b77abcb 100644 --- a/daemon/httpauthd.c +++ b/daemon/httpauthd.c @@ -1514,6 +1514,16 @@ static int config_parse(const char* file, ha_buffer_t* buf) recog = 1; } + else if(strcmp(name, "digestignoremethod") == 0) + { + int v; + if(ha_confbool(name, value, &v) < 0) + exit(1); /* Message already printed */ + + opts->digest_ignoremethod = v; + recog = 1; + } + #ifdef _DEBUG else if(strcmp(name, "digestdebugnonce") == 0) { diff --git a/daemon/httpauthd.h b/daemon/httpauthd.h index 4c7c8d6..36c8449 100644 --- a/daemon/httpauthd.h +++ b/daemon/httpauthd.h @@ -118,6 +118,7 @@ typedef struct ha_context const char* realm; /* For digest auth: */ + unsigned int digest_ignoremethod : 1; unsigned int digest_ignoreuri : 1; unsigned int digest_ignorenc : 1; const char* digest_debugnonce; diff --git a/daemon/ldap.c b/daemon/ldap.c index b3d88fc..59e9912 100644 --- a/daemon/ldap.c +++ b/daemon/ldap.c @@ -695,7 +695,7 @@ static int validate_digest(ha_request_t* rq, const char* user, digest_context_t* foundany = 1; /* Run the actual check */ - ret = digest_complete_check(dg, rq->buf); + ret = digest_complete_check(dg, rq->context, rq->buf); if(ret != HA_FALSE) RETURN(ret); @@ -724,7 +724,7 @@ static int validate_digest(ha_request_t* rq, const char* user, digest_context_t* digest_makeha1(dg->ha1, user, rq->context->realm, *p); /* Run the actual check */ - ret = digest_complete_check(dg, rq->buf); + ret = digest_complete_check(dg, rq->context, rq->buf); if(ret != HA_FALSE) RETURN(ret); diff --git a/daemon/simple.c b/daemon/simple.c index 46b1cf1..1c37c23 100644 --- a/daemon/simple.c +++ b/daemon/simple.c @@ -146,7 +146,7 @@ static int validate_digest(ha_request_t* rq, const char* user, digest_context_t* foundgood = 1; /* Try to do the validation */ - ret = digest_complete_check(dg, rq->buf); + ret = digest_complete_check(dg, rq->context, rq->buf); /* If invalid then continue search */ if(ret == HA_FALSE) diff --git a/doc/httpauthd.conf.5 b/doc/httpauthd.conf.5 index 8d967c3..bae1d2d 100644 --- a/doc/httpauthd.conf.5 +++ b/doc/httpauthd.conf.5 @@ -148,6 +148,14 @@ How this exactly works depends on the method it applies to. [ Default: .Em 900 ] +.It Cd DigestIgnoreMethod +When set to +.Em True +allows the HTTP method value in +.Em Digest +authentication to be mismatched with the actual request. This opens +up a variety of replay attacks, but is useful for pass-through +authentication (eg: a website using a SOAP service). .It Cd DigestIgnoreNC When set to .Em True @@ -164,7 +172,8 @@ When set to allows the URI value in .Em Digest authentication to be mismatched with the URI requested. This opens up -a variety of replay attacks, but may be necessary in some cases. +a variety of replay attacks, but is useful for pass-through +authentication (eg: a website using a SOAP service). .Pp [ Default: .Em False |