diff options
Diffstat (limited to 'daemon')
-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 |
7 files changed, 48 insertions, 8 deletions
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) |