diff options
Diffstat (limited to 'daemon/simple.c')
-rw-r--r-- | daemon/simple.c | 200 |
1 files changed, 112 insertions, 88 deletions
diff --git a/daemon/simple.c b/daemon/simple.c index bda60c3..8e4f8df 100644 --- a/daemon/simple.c +++ b/daemon/simple.c @@ -29,13 +29,13 @@ typedef struct simple_context simple_context_t; /* Forward declarations for callbacks */ -static int complete_digest(ha_request_t* rq, const char* user, unsigned char* ha1); +static int validate_digest(ha_request_t* rq, const char* user, digest_context_t* dg); static int validate_basic(ha_request_t* rq, const char* user, const char* password); /* The defaults for the context */ static const simple_context_t simple_defaults = { - BD_CALLBACKS(complete_digest, validate_basic), + BD_CALLBACKS(validate_digest, validate_basic, NULL), NULL /* filename */ }; @@ -43,7 +43,7 @@ static const simple_context_t simple_defaults = * Internal Functions */ -static int complete_digest(ha_request_t* rq, const char* user, unsigned char* ha1) +static int validate_digest(ha_request_t* rq, const char* user, digest_context_t* dg) { simple_context_t* ctx = (simple_context_t*)rq->context->ctx_data; FILE* f; @@ -52,6 +52,8 @@ static int complete_digest(ha_request_t* rq, const char* user, unsigned char* ha size_t len; char line[SIMPLE_MAXLINE]; int ret = HA_FALSE; + int foundinvalid = 0; + int foundgood = 0; ASSERT(ctx && rq && user && user[0]); ha_messagex(rq, LOG_DEBUG, "searching password file for user's ha1: %s", user); @@ -59,7 +61,7 @@ static int complete_digest(ha_request_t* rq, const char* user, unsigned char* ha f = fopen(ctx->filename, "r"); if(!f) { - ha_message(rq, LOG_ERR, "can't open file for basic auth: %s", ctx->filename); + ha_message(rq, LOG_ERR, "can't open file for digest auth: %s", ctx->filename); return HA_FAILED; } @@ -81,45 +83,63 @@ static int complete_digest(ha_request_t* rq, const char* user, unsigned char* ha } t = strchr(line, ':'); - if(t) + if(!t) + continue; + + /* Split the line */ + *t = 0; + t++; + + /* Check the user */ + if(strcmp(line, user) != 0) + continue; + + t2 = strchr(t, ':'); + if(!t2) { - /* Split the line */ - *t = 0; - t++; - - /* Check the user */ - if(strcmp(line, user) == 0) - { - /* Otherwise it might be a digest type ha1. */ - t2 = strchr(t, ':'); - if(t2) - { - *t2 = 0; - t2++; - - /* Check the realm */ - if(strcmp(t, rq->context->realm) == 0) - { - len = MD5_LEN; - - /* Now try and decode the ha1 */ - t = ha_bufdechex(rq->buf, t2, &len); - if(t && len == MD5_LEN) - { - ha_messagex(rq, LOG_DEBUG, "found ha1 for user: %s", user); - memcpy(ha1, t, MD5_LEN); - ret = HA_OK; - break; - } - } - } - - if(!t2 || ret != HA_OK) - ha_messagex(rq, LOG_WARNING, "user '%s' found in file, but password not in digest format", user); - } + /* An invalid line without a realm */ + foundinvalid = 1; + continue; } + + /* Split the line */ + *t2 = 0; + t2++; + + /* Check the realm */ + if(strcmp(t, rq->context->realm) != 0) + continue; + + /* Now try and decode the ha1 */ + len = MD5_LEN; + t = ha_bufdechex(rq->buf, t2, &len); + + if(!t || len != MD5_LEN) + { + /* An invalid ha1 */ + foundinvalid = 1; + continue; + } + + ha_messagex(rq, LOG_DEBUG, "found ha1 for user: %s", user); + memcpy(dg->ha1, t, MD5_LEN); + foundgood = 1; + + /* Try to do the validation */ + ret = digest_complete_check(dg, rq->buf); + + /* If invalid then continue search */ + if(ret == HA_FALSE) + continue; + + /* Success or an error ends here */ + break; } + + if(foundinvalid && !foundgood) + ha_messagex(rq, LOG_WARNING, "user '%s' found in file, but password not in digest format", user); + fclose(f); if(ha_buferr(rq->buf)) @@ -173,57 +193,61 @@ static int validate_basic(ha_request_t* rq, const char* user, const char* passwo trim_end(line); t = strchr(line, ':'); - if(t) + if(!t) + continue; + + /* Split the line */ + *t = 0; + t++; + + /* Check the user */ + if(strcmp(line, user) != 0) + continue; + + /* Not sure if crypt is thread safe so we lock */ + ha_lock(NULL); + + /* Check the password */ + t2 = crypt(password, t); + + ha_unlock(NULL); + + if(strcmp(t2, t) == 0) { - /* Split the line */ - *t = 0; - t++; - - /* Check the user */ - if(strcmp(line, user) == 0) - { - /* Not sure if crypt is thread safe so we lock */ - ha_lock(NULL); - - /* Check the password */ - t2 = crypt(password, t); - - ha_unlock(NULL); - - if(strcmp(t2, t) == 0) - { - ha_messagex(rq, LOG_DEBUG, "found valid crypt password for user: %s", user); - ret = HA_OK; - break; - } - - /* Otherwise it might be a digest type ha1. */ - t2 = strchr(t, ':'); - if(t2) - { - *t2 = 0; - t2++; - - /* Check the realm */ - if(strcmp(t, rq->context->realm) == 0) - { - len = MD5_LEN; - - /* Now try antd decode the ha1 */ - t = ha_bufdechex(rq->buf, t2, &len); - if(t && len == MD5_LEN && memcmp(ha1, t, MD5_LEN) == 0) - { - ha_messagex(rq, LOG_DEBUG, "found valid ha1 for user: %s", user); - ret = HA_OK; - break; - } - } - } - - if(ha_buferr(rq->buf)) - break; - } + ha_messagex(rq, LOG_DEBUG, "found valid crypt password for user: %s", user); + ret = HA_OK; + break; } + + /* Otherwise it might be a digest type ha1. */ + t2 = strchr(t, ':'); + if(!t2) + continue; + + /* Split the line */ + *t2 = 0; + t2++; + + /* Check the realm */ + if(strcmp(t, rq->context->realm) != 0) + continue; + + /* Now try antd decode the ha1 */ + len = MD5_LEN; + + t = ha_bufdechex(rq->buf, t2, &len); + if(!t || len != MD5_LEN) + continue; + + if(memcmp(ha1, t, MD5_LEN) == 0) + { + ha_messagex(rq, LOG_DEBUG, "found valid ha1 for user: %s", user); + ret = HA_OK; + break; + } + + if(ha_buferr(rq->buf)) + break; } fclose(f); |