summaryrefslogtreecommitdiff
path: root/daemon/simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/simple.c')
-rw-r--r--daemon/simple.c200
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);