summaryrefslogtreecommitdiff
path: root/daemon/simple.c
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2004-05-07 22:02:29 +0000
committerStef Walter <stef@memberwebs.com>2004-05-07 22:02:29 +0000
commit80b0e2c0fdad108454ae87130496f595f0b81b81 (patch)
tree696ce7e9010f412ce4e988e4d88553b19e2e42a8 /daemon/simple.c
parent0bc8575dbfb281f5f5e9fb530247d29ba1f296fc (diff)
- Reworked the internal API
- Added common functions for trimming - Debugging - Reworked the module to the new protocol
Diffstat (limited to 'daemon/simple.c')
-rw-r--r--daemon/simple.c151
1 files changed, 72 insertions, 79 deletions
diff --git a/daemon/simple.c b/daemon/simple.c
index 7165c9c..8059051 100644
--- a/daemon/simple.c
+++ b/daemon/simple.c
@@ -27,7 +27,6 @@ typedef struct simple_context
{
/* Settings ----------------------------------------------------------- */
const char* filename; /* The file name with the user names */
- const ha_context_opts_t* opts; /* Options from httpauthd.c */
/* Context ----------------------------------------------------------- */
hash_t* cache; /* Some cached records or basic */
@@ -45,13 +44,14 @@ static void free_hash_object(void* arg, void* val)
free(val);
}
-static digest_record_t* get_cached_digest(simple_context_t* ctx, unsigned char* nonce)
+static digest_record_t* get_cached_digest(simple_context_t* ctx, ha_context_t* c,
+ unsigned char* nonce)
{
digest_record_t* rec;
- ASSERT(ctx && nonce);
+ ASSERT(ctx && c && nonce);
- if(ctx->opts->cache_max == 0)
+ if(c->cache_max == 0)
return NULL;
ha_lock(NULL);
@@ -83,13 +83,14 @@ static int have_cached_basic(simple_context_t* ctx, unsigned char* key)
return ret;
}
-static int save_cached_digest(simple_context_t* ctx, digest_record_t* rec)
+static int save_cached_digest(simple_context_t* ctx, ha_context_t* c,
+ digest_record_t* rec)
{
int r;
- ASSERT(ctx && rec);
+ ASSERT(ctx && c && rec);
- if(ctx->opts->cache_max == 0)
+ if(c->cache_max == 0)
{
free_hash_object(NULL, rec);
return HA_FALSE;
@@ -97,7 +98,7 @@ static int save_cached_digest(simple_context_t* ctx, digest_record_t* rec)
ha_lock(NULL);
- while(hash_count(ctx->cache) >= ctx->opts->cache_max)
+ while(hash_count(ctx->cache) >= c->cache_max)
hash_bump(ctx->cache);
r = hash_set(ctx->cache, rec->nonce, rec);
@@ -114,18 +115,19 @@ static int save_cached_digest(simple_context_t* ctx, digest_record_t* rec)
return HA_OK;
}
-static int add_cached_basic(simple_context_t* ctx, unsigned char* key)
+static int add_cached_basic(simple_context_t* ctx, ha_context_t* c,
+ unsigned char* key)
{
int r;
- ASSERT(ctx && key);
+ ASSERT(ctx && c && key);
- if(ctx->opts->cache_max == 0)
+ if(c->cache_max == 0)
return HA_FALSE;
ha_lock(NULL);
- while(hash_count(ctx->cache) >= ctx->opts->cache_max)
+ while(hash_count(ctx->cache) >= c->cache_max)
hash_bump(ctx->cache);
r = hash_set(ctx->cache, key, BASIC_ESTABLISHED);
@@ -142,7 +144,7 @@ static int add_cached_basic(simple_context_t* ctx, unsigned char* key)
}
static int complete_digest_ha1(simple_context_t* ctx, digest_record_t* rec,
- ha_buffer_t* buf, const char* user)
+ const ha_request_t* req, const char* user)
{
FILE* f;
char* t;
@@ -151,7 +153,7 @@ static int complete_digest_ha1(simple_context_t* ctx, digest_record_t* rec,
char line[SIMPLE_MAXLINE];
int ret = HA_FALSE;
- ASSERT(ctx && rec && buf && user && user[0]);
+ ASSERT(ctx && rec && req && user && user[0]);
ha_messagex(LOG_DEBUG, "searching password file for user's ha1: %s", user);
f = fopen(ctx->filename, "r");
@@ -196,12 +198,12 @@ static int complete_digest_ha1(simple_context_t* ctx, digest_record_t* rec,
t2++;
/* Check the realm */
- if(strcmp(t, ctx->opts->realm) == 0)
+ if(strcmp(t, req->context->realm) == 0)
{
len = MD5_LEN;
/* Now try antd decode the ha1 */
- t = ha_bufdechex(buf, t2, &len);
+ t = ha_bufdechex(req->buf, t2, &len);
if(t && len == MD5_LEN)
{
ha_messagex(LOG_DEBUG, "simple: found ha1 for user: %s", user);
@@ -220,13 +222,13 @@ static int complete_digest_ha1(simple_context_t* ctx, digest_record_t* rec,
fclose(f);
- if(ha_buferr(buf))
+ if(ha_buferr(req->buf))
return HA_CRITERROR;
return ret;
}
-static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
+static int validate_user_password(simple_context_t* ctx, const ha_request_t* req,
const char* user, const char* clearpw)
{
FILE* f;
@@ -237,7 +239,7 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
size_t len;
int ret = HA_FALSE;
- ASSERT(ctx && buf);
+ ASSERT(ctx && req);
ASSERT(user && user[0] && clearpw);
ha_messagex(LOG_DEBUG, "simple: validating user against password file: %s", user);
@@ -248,7 +250,7 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
return HA_FAILED;
}
- digest_makeha1(ha1, user, ctx->opts->realm, clearpw);
+ digest_makeha1(ha1, user, req->context->realm, clearpw);
/*
* Note: There should be no returns or jumps between
@@ -268,12 +270,7 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
}
/* Take white space off end of line */
- t = line + strlen(line);
- while(t != line && isspace(*(t - 1)))
- {
- *(t - 1) = 0;
- t--;
- }
+ trim_end(line);
t = strchr(line, ':');
if(t)
@@ -308,12 +305,12 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
t2++;
/* Check the realm */
- if(strcmp(t, ctx->opts->realm) == 0)
+ if(strcmp(t, req->context->realm) == 0)
{
len = MD5_LEN;
/* Now try antd decode the ha1 */
- t = ha_bufdechex(buf, t2, &len);
+ t = ha_bufdechex(req->buf, t2, &len);
if(t && len == MD5_LEN && memcmp(ha1, t, MD5_LEN) == 0)
{
ha_messagex(LOG_DEBUG, "simple: found valid ha1 for user: %s", user);
@@ -323,7 +320,7 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
}
}
- if(ha_buferr(buf))
+ if(ha_buferr(req->buf))
break;
}
}
@@ -331,23 +328,23 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
fclose(f);
- if(ha_buferr(buf))
+ if(ha_buferr(req->buf))
return HA_CRITERROR;
return ret;
}
static int simple_basic_response(simple_context_t* ctx, const char* header,
- ha_response_t* resp, ha_buffer_t* buf)
+ const ha_request_t* req, ha_response_t* resp)
{
basic_header_t basic;
int ret = HA_FALSE;
int found = 0;
int r;
- ASSERT(buf && header && resp && buf);
+ ASSERT(header && req && resp);
- if((r = basic_parse(header, buf, &basic)) < 0)
+ if((r = basic_parse(header, req->buf, &basic)) < 0)
return r;
/* Past this point we don't return directly */
@@ -367,7 +364,7 @@ static int simple_basic_response(simple_context_t* ctx, const char* header,
goto finally;
- ret = validate_user_password(ctx, buf, basic.user, basic.password);
+ ret = validate_user_password(ctx, req, basic.user, basic.password);
if(ret == HA_OK)
ha_messagex(LOG_NOTICE, "simple: validated basic user against file: %s", basic.user);
@@ -383,26 +380,26 @@ finally:
resp->detail = basic.user;
/* We put this connection into the successful connections */
- ret = add_cached_basic(ctx, basic.key);
+ ret = add_cached_basic(ctx, req->context, basic.key);
}
return ret;
}
static int simple_digest_challenge(simple_context_t* ctx, const ha_request_t* req,
- ha_response_t* resp, ha_buffer_t* buf, int stale)
+ ha_response_t* resp, int stale)
{
const char* nonce_str;
const char* header;
- ASSERT(ctx && resp && buf);
+ ASSERT(ctx && req && resp);
/* Generate an nonce */
#ifdef _DEBUG
- if(ctx->opts->digest_debugnonce)
+ if(req->context->digest_debugnonce)
{
- nonce_str = ctx->opts->digest_debugnonce;
+ nonce_str = req->context->digest_debugnonce;
ha_messagex(LOG_WARNING, "simple: using debug nonce. security non-existant.");
}
else
@@ -411,15 +408,15 @@ static int simple_digest_challenge(simple_context_t* ctx, const ha_request_t* re
unsigned char nonce[DIGEST_NONCE_LEN];
digest_makenonce(nonce, g_simple_secret, NULL);
- nonce_str = ha_bufenchex(buf, nonce, DIGEST_NONCE_LEN);
+ nonce_str = ha_bufenchex(req->buf, nonce, DIGEST_NONCE_LEN);
if(!nonce_str)
return HA_CRITERROR;
}
/* Now generate a message to send */
- header = digest_challenge(buf, nonce_str, ctx->opts->realm,
- req->opts->digest_domains, stale);
+ header = digest_challenge(req->buf, nonce_str, req->context->realm,
+ req->digest_domain, stale);
if(!header)
return HA_CRITERROR;
@@ -433,7 +430,7 @@ static int simple_digest_challenge(simple_context_t* ctx, const ha_request_t* re
}
static int simple_digest_response(simple_context_t* ctx, const char* header,
- const ha_request_t* req, ha_response_t* resp, ha_buffer_t* buf)
+ const ha_request_t* req, ha_response_t* resp)
{
unsigned char nonce[DIGEST_NONCE_LEN];
digest_header_t dg;
@@ -444,18 +441,18 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
int stale = 0;
int r;
- ASSERT(ctx && header && req && resp && buf);
+ ASSERT(ctx && header && req && resp);
/* We use this below to send a default response */
resp->code = -1;
- if((r = digest_parse(header, buf, &dg, nonce)) < 0)
+ if((r = digest_parse(header, req->buf, &dg, nonce)) < 0)
return r;
#ifdef _DEBUG
- if(ctx->opts->digest_debugnonce)
+ if(req->context->digest_debugnonce)
{
- if(dg.nonce && strcmp(dg.nonce, ctx->opts->digest_debugnonce) != 0)
+ if(dg.nonce && strcmp(dg.nonce, req->context->digest_debugnonce) != 0)
{
ret = HA_FALSE;
ha_messagex(LOG_WARNING, "simple: digest response contains invalid nonce");
@@ -463,7 +460,7 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
}
/* Do a rough hash into the real nonce, for use as a key */
- md5_string(nonce, ctx->opts->digest_debugnonce);
+ md5_string(nonce, req->context->digest_debugnonce);
/* Debug nonce's never expire */
expiry = time(NULL);
@@ -482,10 +479,10 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
}
}
- rec = get_cached_digest(ctx, nonce);
+ rec = get_cached_digest(ctx, req->context, nonce);
/* Check to see if we're stale */
- if((expiry + ctx->opts->cache_timeout) <= time(NULL))
+ if((expiry + req->context->cache_timeout) <= time(NULL))
{
ha_messagex(LOG_INFO, "simple: nonce expired, sending stale challenge: %s",
dg.username);
@@ -510,7 +507,7 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
goto finally;
}
- r = complete_digest_ha1(ctx, rec, buf, dg.username);
+ r = complete_digest_ha1(ctx, rec, req, dg.username);
if(r != HA_OK)
{
ret = r;
@@ -524,7 +521,7 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
rec->nc++;
}
- ret = digest_check(&dg, rec, ctx->opts, buf,
+ ret = digest_check(&dg, rec, req->context, req->buf,
req->args[AUTH_ARG_METHOD], req->args[AUTH_ARG_URI]);
if(ret == HA_BADREQ)
@@ -539,8 +536,8 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
resp->detail = dg.username;
/* Figure out if we need a new nonce */
- if((expiry + (ctx->opts->cache_timeout -
- (ctx->opts->cache_timeout / 8))) < time(NULL))
+ if((expiry + (req->context->cache_timeout -
+ (req->context->cache_timeout / 8))) < time(NULL))
{
ha_messagex(LOG_INFO, "simple: nonce almost expired, creating new one: %s",
dg.username);
@@ -549,7 +546,7 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
stale = 1;
}
- t = digest_respond(buf, &dg, rec, stale ? nonce : NULL);
+ t = digest_respond(req->buf, &dg, rec, stale ? nonce : NULL);
if(!t)
{
ret = HA_CRITERROR;
@@ -562,7 +559,7 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
ha_messagex(LOG_NOTICE, "simple: validated digest user: %s", dg.username);
/* Put the connection into the cache */
- if((r = save_cached_digest(ctx, rec)) < 0)
+ if((r = save_cached_digest(ctx, req->context, rec)) < 0)
ret = r;
rec = NULL;
@@ -576,7 +573,7 @@ finally:
/* If nobody above responded then challenge the client again */
if(resp->code == -1)
- return simple_digest_challenge(ctx, req, resp, buf, stale);
+ return simple_digest_challenge(ctx, req, resp, stale);
return ret;
}
@@ -588,7 +585,7 @@ finally:
int simple_config(ha_context_t* context, const char* name, const char* value)
{
- simple_context_t* ctx = (simple_context_t*)(context->data);
+ simple_context_t* ctx = (simple_context_t*)(context->ctx_data);
ASSERT(name && name[0] && value && value[0]);
@@ -613,13 +610,13 @@ int simple_init(ha_context_t* context)
/* Context specific initialization */
else
{
- simple_context_t* ctx = (simple_context_t*)(context->data);
+ simple_context_t* ctx = (simple_context_t*)(context->ctx_data);
int fd;
ASSERT(ctx);
/* Make sure there are some types of authentication we can do */
- if(!(context->opts->types & (HA_TYPE_BASIC | HA_TYPE_DIGEST)))
+ if(!(context->allowed_types & (HA_TYPE_BASIC | HA_TYPE_DIGEST)))
{
ha_messagex(LOG_ERR, "simple: module configured, but does not implement any "
"configured authentication type.");
@@ -653,9 +650,6 @@ int simple_init(ha_context_t* context)
return HA_CRITERROR;
}
- /* Copy some settings over for easy access */
- ctx->opts = context->opts;
-
ha_messagex(LOG_INFO, "simple: initialized handler");
}
@@ -668,7 +662,7 @@ void simple_destroy(ha_context_t* context)
if(context)
{
/* Note: We don't need to be thread safe here anymore */
- simple_context_t* ctx = (simple_context_t*)(context->data);
+ simple_context_t* ctx = (simple_context_t*)(context->ctx_data);
if(ctx->cache)
hash_free(ctx->cache);
@@ -677,24 +671,23 @@ void simple_destroy(ha_context_t* context)
}
}
-int simple_process(ha_context_t* context, const ha_request_t* req,
- ha_response_t* resp, ha_buffer_t* buf)
+int simple_process(const ha_request_t* req, ha_response_t* resp)
{
- simple_context_t* ctx = (simple_context_t*)(context->data);
+ simple_context_t* ctx = (simple_context_t*)(req->context->ctx_data);
const char* header = NULL;
int ret = HA_FALSE;
int found = 0;
basic_header_t basic;
int r;
- ASSERT(context && req && resp && buf);
+ ASSERT(req && resp);
ASSERT(req->args[AUTH_ARG_METHOD]);
ASSERT(req->args[AUTH_ARG_URI]);
ha_lock(NULL);
/* Purge the cache */
- r = hash_purge(ctx->cache, time(NULL) - ctx->opts->cache_timeout);
+ r = hash_purge(ctx->cache, time(NULL) - req->context->cache_timeout);
ha_unlock(NULL);
@@ -706,26 +699,26 @@ int simple_process(ha_context_t* context, const ha_request_t* req,
/* Check the headers and see if we got a response thingy */
- if(context->opts->types & HA_TYPE_DIGEST)
+ if(req->context->allowed_types & HA_TYPE_DIGEST)
{
header = ha_getheader(req, "Authorization", HA_PREFIX_DIGEST);
if(header)
{
ha_messagex(LOG_DEBUG, "simple: processing digest auth header");
- ret = simple_digest_response(ctx, header, req, resp, buf);
+ ret = simple_digest_response(ctx, header, req, resp);
if(ret < 0)
return ret;
}
}
/* Or a basic authentication */
- if(!header && context->opts->types & HA_TYPE_BASIC)
+ if(!header && req->context->allowed_types & HA_TYPE_BASIC)
{
ha_messagex(LOG_DEBUG, "simple: processing basic auth header");
header = ha_getheader(req, "Authorization", HA_PREFIX_BASIC);
if(header)
{
- ret = simple_basic_response(ctx, header, resp, buf);
+ ret = simple_basic_response(ctx, header, req, resp);
if(ret < 0)
return ret;
}
@@ -737,20 +730,20 @@ int simple_process(ha_context_t* context, const ha_request_t* req,
{
resp->code = HA_SERVER_DECLINE;
- if(context->opts->types & HA_TYPE_BASIC)
+ if(req->context->allowed_types & HA_TYPE_BASIC)
{
- ha_bufmcat(buf, "BASIC realm=\"", ctx->opts->realm , "\"", NULL);
+ ha_bufmcat(req->buf, "BASIC realm=\"", req->context->realm , "\"", NULL);
- if(ha_buferr(buf))
+ if(ha_buferr(req->buf))
return HA_CRITERROR;
- ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf));
+ ha_addheader(resp, "WWW-Authenticate", ha_bufdata(req->buf));
ha_messagex(LOG_DEBUG, "simple: sent basic auth request");
}
- if(context->opts->types & HA_TYPE_DIGEST)
+ if(req->context->allowed_types & HA_TYPE_DIGEST)
{
- ret = simple_digest_challenge(ctx, req, resp, buf, 0);
+ ret = simple_digest_challenge(ctx, req, resp, 0);
if(ret < 0)
return ret;
}