summaryrefslogtreecommitdiff
path: root/daemon/simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/simple.c')
-rw-r--r--daemon/simple.c865
1 files changed, 199 insertions, 666 deletions
diff --git a/daemon/simple.c b/daemon/simple.c
index ee4fafa..d570a25 100644
--- a/daemon/simple.c
+++ b/daemon/simple.c
@@ -5,19 +5,14 @@
#include "usuals.h"
#include "httpauthd.h"
#include "defaults.h"
-#include "basic.h"
-#include "digest.h"
#include "hash.h"
+#include "bd.h"
#include "md5.h"
-#include <syslog.h>
+#include <stdio.h>
#include <fcntl.h>
-#include <unistd.h>
-
-unsigned char g_simple_secret[DIGEST_SECRET_LEN];
#define SIMPLE_MAXLINE 256
-#define BASIC_ESTABLISHED (void*)1
/* -------------------------------------------------------------------------------
* Structures
@@ -25,736 +20,274 @@ unsigned char g_simple_secret[DIGEST_SECRET_LEN];
typedef struct simple_context
{
- /* Settings ----------------------------------------------------------- */
- const char* filename; /* The file name with the user names */
+ /* Base Handler ------------------------------------------------------ */
+ bd_context_t bd;
- /* Context ----------------------------------------------------------- */
- hsh_t* cache; /* Some cached records or basic */
+ /* Settings ---------------------------------------------------------- */
+ const char* filename; /* The file name with the user names */
}
simple_context_t;
+/* Forward declarations for callbacks */
+static int complete_digest(const ha_request_t* req, const char* user, unsigned char* ha1);
+static int validate_basic(const ha_request_t* req, const char* user, const char* password);
+
+/* The defaults for the context */
+static const simple_context_t simple_defaults =
+{
+ BD_CALLBACKS(complete_digest, validate_basic),
+ NULL /* filename */
+};
/* -------------------------------------------------------------------------------
* Internal Functions
*/
-static void free_hash_object(void* arg, void* val)
-{
- if(val && val != BASIC_ESTABLISHED)
- free(val);
-}
-
-static digest_record_t* get_cached_digest(simple_context_t* ctx, ha_context_t* c,
- unsigned char* nonce)
-{
- digest_record_t* rec;
-
- ASSERT(ctx && c && nonce);
-
- if(c->cache_max == 0)
- return NULL;
-
- ha_lock(NULL);
-
- rec = (digest_record_t*)hsh_get(ctx->cache, nonce);
-
- /* Just in case it's a basic :) */
- if(rec && rec != BASIC_ESTABLISHED)
- hsh_rem(ctx->cache, nonce);
-
- ha_unlock(NULL);
-
- ASSERT(!rec || memcmp(nonce, rec->nonce, DIGEST_NONCE_LEN) == 0);
- return rec;
-}
-
-static int have_cached_basic(simple_context_t* ctx, unsigned char* key)
-{
- int ret = 0;
-
- ASSERT(ctx && key);
-
- ha_lock(NULL);
-
- ret = (hsh_get(ctx->cache, key) == BASIC_ESTABLISHED);
-
- ha_unlock(NULL);
-
- return ret;
-}
-
-static int save_cached_digest(simple_context_t* ctx, ha_context_t* c,
- digest_record_t* rec)
+static int complete_digest(const ha_request_t* req, const char* user, unsigned char* ha1)
{
- int r;
-
- ASSERT(ctx && c && rec);
-
- if(c->cache_max == 0)
- {
- free_hash_object(NULL, rec);
- return HA_FALSE;
- }
-
- ha_lock(NULL);
-
- while(hsh_count(ctx->cache) >= c->cache_max)
- hsh_bump(ctx->cache);
-
- r = hsh_set(ctx->cache, rec->nonce, rec);
-
- ha_unlock(NULL);
-
- if(!r)
- {
- free_hash_object(NULL, rec);
- ha_messagex(LOG_CRIT, "out of memory");
- return HA_CRITERROR;
- }
-
- return HA_OK;
-}
-
-static int add_cached_basic(simple_context_t* ctx, ha_context_t* c,
- unsigned char* key)
-{
- int r;
-
- ASSERT(ctx && c && key);
-
- if(c->cache_max == 0)
- return HA_FALSE;
-
- ha_lock(NULL);
-
- while(hsh_count(ctx->cache) >= c->cache_max)
- hsh_bump(ctx->cache);
-
- r = hsh_set(ctx->cache, key, BASIC_ESTABLISHED);
-
- ha_unlock(NULL);
-
- if(!r)
- {
- ha_messagex(LOG_CRIT, "out of memory");
- return HA_CRITERROR;
- }
-
- return HA_OK;
-}
-
-static int complete_digest_ha1(simple_context_t* ctx, digest_record_t* rec,
- const ha_request_t* req, const char* user)
-{
- FILE* f;
- char* t;
- char* t2;
- size_t len;
- char line[SIMPLE_MAXLINE];
- int ret = HA_FALSE;
-
- 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");
- if(!f)
- {
- ha_message(LOG_ERR, "simple: can't open file for basic auth: %s", ctx->filename);
- return HA_FAILED;
- }
-
- /*
- * Note: There should be no returns or jumps between
- * this point and the closing of the file below.
- */
-
- /* Now look through the whole file */
- while(!feof(f))
- {
- fgets(line, SIMPLE_MAXLINE, f);
-
- if(ferror(f))
- {
- ha_message(LOG_ERR, "simple: error reading basic password file");
- ret = HA_FAILED;
- break;
- }
-
- t = strchr(line, ':');
- if(t)
- {
- /* 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, req->context->realm) == 0)
- {
- len = MD5_LEN;
-
- /* Now try antd decode the ha1 */
- t = ha_bufdechex(req->buf, t2, &len);
- if(t && len == MD5_LEN)
- {
- ha_messagex(LOG_DEBUG, "simple: found ha1 for user: %s", user);
- memcpy(rec->ha1, t, MD5_LEN);
- ret = HA_OK;
- break;
- }
- }
- }
-
- if(!t2 || ret != HA_OK)
- ha_messagex(LOG_WARNING, "simple: user '%s' found in file, but password not in digest format", user);
- }
- }
- }
-
- fclose(f);
-
- if(ha_buferr(req->buf))
- return HA_CRITERROR;
-
- return ret;
-}
-
-static int validate_user_password(simple_context_t* ctx, const ha_request_t* req,
- const char* user, const char* clearpw)
-{
- FILE* f;
- char line[SIMPLE_MAXLINE];
- unsigned char ha1[MD5_LEN];
- char* t;
- char* t2;
- size_t len;
- int ret = HA_FALSE;
-
- ASSERT(ctx && req);
- ASSERT(user && user[0] && clearpw);
- ha_messagex(LOG_DEBUG, "simple: validating user against password file: %s", user);
-
- f = fopen(ctx->filename, "r");
- if(!f)
- {
- ha_message(LOG_ERR, "simple: can't open file for basic auth: %s", ctx->filename);
- return HA_FAILED;
- }
-
- digest_makeha1(ha1, user, req->context->realm, clearpw);
-
- /*
- * Note: There should be no returns or jumps between
- * this point and the closing of the file below.
- */
-
- /* Now look through the whole file */
- while(!feof(f))
- {
- fgets(line, SIMPLE_MAXLINE, f);
-
- if(ferror(f))
+ simple_context_t* ctx = (simple_context_t*)req->context->ctx_data;
+ FILE* f;
+ char* t;
+ char* t2;
+ size_t len;
+ char line[SIMPLE_MAXLINE];
+ int ret = HA_FALSE;
+
+ ASSERT(ctx && req && user && user[0]);
+ ha_messagex(LOG_DEBUG, "searching password file for user's ha1: %s", user);
+
+ f = fopen(ctx->filename, "r");
+ if(!f)
{
- ha_message(LOG_ERR, "simple: error reading basic password file");
- ret = HA_FAILED;
- break;
+ ha_message(LOG_ERR, "simple: can't open file for basic auth: %s", ctx->filename);
+ return HA_FAILED;
}
- /* Take white space off end of line */
- trim_end(line);
+ /*
+ * Note: There should be no returns or jumps between
+ * this point and the closing of the file below.
+ */
- t = strchr(line, ':');
- if(t)
+ /* Now look through the whole file */
+ while(!feof(f))
{
- /* 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);
+ fgets(line, SIMPLE_MAXLINE, f);
- /* Check the password */
- t2 = crypt(clearpw, t);
-
- ha_unlock(NULL);
-
- if(strcmp(crypt(clearpw, t), t) == 0)
+ if(ferror(f))
{
- ha_messagex(LOG_DEBUG, "simple: found valid crypt password for user: %s", user);
- ret = HA_OK;
- break;
+ ha_message(LOG_ERR, "simple: error reading basic password file");
+ ret = HA_FAILED;
+ break;
}
- /* Otherwise it might be a digest type ha1. */
- t2 = strchr(t, ':');
- if(t2)
+ t = strchr(line, ':');
+ if(t)
{
- *t2 = 0;
- t2++;
-
- /* Check the realm */
- if(strcmp(t, req->context->realm) == 0)
- {
- len = MD5_LEN;
+ /* Split the line */
+ *t = 0;
+ t++;
- /* Now try antd decode the ha1 */
- t = ha_bufdechex(req->buf, t2, &len);
- if(t && len == MD5_LEN && memcmp(ha1, t, MD5_LEN) == 0)
+ /* Check the user */
+ if(strcmp(line, user) == 0)
{
- ha_messagex(LOG_DEBUG, "simple: found valid ha1 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, req->context->realm) == 0)
+ {
+ len = MD5_LEN;
+
+ /* Now try and decode the ha1 */
+ t = ha_bufdechex(req->buf, t2, &len);
+ if(t && len == MD5_LEN)
+ {
+ ha_messagex(LOG_DEBUG, "simple: found ha1 for user: %s", user);
+ memcpy(ha1, t, MD5_LEN);
+ ret = HA_OK;
+ break;
+ }
+ }
+ }
+
+ if(!t2 || ret != HA_OK)
+ ha_messagex(LOG_WARNING, "simple: user '%s' found in file, but password not in digest format", user);
}
- }
}
-
- if(ha_buferr(req->buf))
- break;
- }
}
- }
-
- fclose(f);
-
- if(ha_buferr(req->buf))
- return HA_CRITERROR;
-
- return ret;
-}
-
-static int simple_basic_response(simple_context_t* ctx, const char* header,
- const ha_request_t* req, ha_response_t* resp)
-{
- basic_header_t basic;
- int ret = HA_FALSE;
- int found = 0;
- int r;
-
- ASSERT(header && req && resp);
-
- if((r = basic_parse(header, req->buf, &basic)) < 0)
- return r;
-
- /* Past this point we don't return directly */
-
- /* Check and see if this connection is in the cache */
- if(have_cached_basic(ctx, basic.key))
- {
- ha_messagex(LOG_NOTICE, "simple: validated basic user against cache: %s", basic.user);
- found = 1;
- ret = HA_OK;
- goto finally;
- }
-
- /* If we have a user name and password */
- if(!basic.user || !basic.user[0] ||
- !basic.password || !basic.password[0])
- goto finally;
-
-
- 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);
-
- else
- ha_messagex(LOG_WARNING, "simple: basic authentication failed for user: %s", basic.user);
-finally:
+ fclose(f);
- if(ret == HA_OK)
- {
- resp->code = HA_SERVER_OK;
- resp->detail = basic.user;
-
- /* We put this connection into the successful connections */
- 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, int stale)
-{
- const char* nonce_str;
- const char* header;
-
- ASSERT(ctx && req && resp);
-
- /* Generate an nonce */
-
-#ifdef _DEBUG
- if(req->context->digest_debugnonce)
- {
- nonce_str = req->context->digest_debugnonce;
- ha_messagex(LOG_WARNING, "simple: using debug nonce. security non-existant.");
- }
- else
-#endif
- {
- unsigned char nonce[DIGEST_NONCE_LEN];
- digest_makenonce(nonce, g_simple_secret, NULL);
-
- 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(req->buf, nonce_str, req->context->realm,
- req->digest_domain, stale);
-
- if(!header)
- return HA_CRITERROR;
-
- /* And append it nicely */
- resp->code = HA_SERVER_DECLINE;
- ha_addheader(resp, "WWW-Authenticate", header);
+ if(ha_buferr(req->buf))
+ return HA_CRITERROR;
- ha_messagex(LOG_DEBUG, "simple: created digest challenge with nonce: %s", nonce_str);
- return HA_OK;
+ return ret;
}
-static int simple_digest_response(simple_context_t* ctx, const char* header,
- const ha_request_t* req, ha_response_t* resp)
+static int validate_basic(const ha_request_t* req, const char* user, const char* password)
{
- unsigned char nonce[DIGEST_NONCE_LEN];
- digest_header_t dg;
- digest_record_t* rec = NULL;
- const char* t;
- time_t expiry;
- int ret = HA_FALSE;
- int stale = 0;
- int r;
-
- ASSERT(ctx && header && req && resp);
-
- /* We use this below to send a default response */
- resp->code = -1;
-
- if((r = digest_parse(header, req->buf, &dg, nonce)) < 0)
- return r;
-
-#ifdef _DEBUG
- if(req->context->digest_debugnonce)
- {
- if(dg.nonce && strcmp(dg.nonce, req->context->digest_debugnonce) != 0)
- {
- ret = HA_FALSE;
- ha_messagex(LOG_WARNING, "simple: digest response contains invalid nonce");
- goto finally;
- }
-
- /* Do a rough hash into the real nonce, for use as a key */
- md5_string(nonce, req->context->digest_debugnonce);
-
- /* Debug nonce's never expire */
- expiry = time(NULL);
- }
- else
-#endif
- {
- r = digest_checknonce(nonce, g_simple_secret, &expiry);
- if(r != HA_OK)
+ simple_context_t* ctx = (simple_context_t*)req->context->ctx_data;
+ FILE* f;
+ char line[SIMPLE_MAXLINE];
+ unsigned char ha1[MD5_LEN];
+ char* t;
+ char* t2;
+ size_t len;
+ int ret = HA_FALSE;
+
+ ASSERT(ctx && req);
+ ASSERT(user && user[0] && password);
+ ha_messagex(LOG_DEBUG, "simple: validating user against password file: %s", user);
+
+ f = fopen(ctx->filename, "r");
+ if(!f)
{
- if(r == HA_FALSE)
- ha_messagex(LOG_WARNING, "simple: digest response contains invalid nonce");
-
- ret = r;
- goto finally;
+ ha_message(LOG_ERR, "simple: can't open file for basic auth: %s", ctx->filename);
+ return HA_FAILED;
}
- }
- rec = get_cached_digest(ctx, req->context, nonce);
-
- /* Check to see if we're stale */
- if((expiry + req->context->cache_timeout) <= time(NULL))
- {
- ha_messagex(LOG_INFO, "simple: nonce expired, sending stale challenge: %s",
- dg.username);
-
- stale = 1;
- goto finally;
- }
-
- if(!rec)
- {
- ha_messagex(LOG_INFO, "simple: no record in cache, creating one: %s", dg.username);
+ digest_makeha1(ha1, user, req->context->realm, password);
/*
- * If we're valid but don't have a record in the
- * cache then complete the record properly.
+ * Note: There should be no returns or jumps between
+ * this point and the closing of the file below.
*/
- rec = digest_makerec(nonce, dg.username);
- if(!rec)
+ /* Now look through the whole file */
+ while(!feof(f))
{
- ret = HA_CRITERROR;
- goto finally;
- }
+ fgets(line, SIMPLE_MAXLINE, f);
- r = complete_digest_ha1(ctx, rec, req, dg.username);
- if(r != HA_OK)
- {
- ret = r;
- goto finally;
- }
- }
-
- /* We had a record so ... */
- else
- {
- rec->nc++;
- }
-
- ret = digest_check(&dg, rec, req->context, req->buf,
- req->args[AUTH_ARG_METHOD], req->args[AUTH_ARG_URI]);
-
- if(ret == HA_BADREQ)
- {
- ret = HA_FALSE;
- resp->code = HA_SERVER_BADREQ;
- }
-
- else if(ret == HA_OK)
- {
- resp->code = HA_SERVER_OK;
- resp->detail = dg.username;
-
- /* Figure out if we need a new nonce */
- 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);
-
- digest_makenonce(nonce, g_simple_secret, NULL);
- stale = 1;
- }
-
- t = digest_respond(req->buf, &dg, rec, stale ? nonce : NULL);
- if(!t)
- {
- ret = HA_CRITERROR;
- goto finally;
- }
-
- if(t[0])
- ha_addheader(resp, "Authentication-Info", t);
-
- ha_messagex(LOG_NOTICE, "simple: validated digest user: %s", dg.username);
+ if(ferror(f))
+ {
+ ha_message(LOG_ERR, "simple: error reading basic password file");
+ ret = HA_FAILED;
+ break;
+ }
- /* Put the connection into the cache */
- if((r = save_cached_digest(ctx, req->context, rec)) < 0)
- ret = r;
+ /* Take white space off end of line */
+ trim_end(line);
- rec = NULL;
- }
+ t = strchr(line, ':');
+ if(t)
+ {
+ /* Split the line */
+ *t = 0;
+ t++;
-finally:
+ /* 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(LOG_DEBUG, "simple: 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, req->context->realm) == 0)
+ {
+ len = MD5_LEN;
+
+ /* Now try antd decode the ha1 */
+ 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);
+ ret = HA_OK;
+ break;
+ }
+ }
+ }
+
+ if(ha_buferr(req->buf))
+ break;
+ }
+ }
+ }
- /* If the record wasn't stored away then free it */
- if(rec)
- free(rec);
+ fclose(f);
- /* If nobody above responded then challenge the client again */
- if(resp->code == -1)
- return simple_digest_challenge(ctx, req, resp, stale);
+ if(ha_buferr(req->buf))
+ return HA_CRITERROR;
- return ret;
+ return ret;
}
-
/* -------------------------------------------------------------------------------
* Handler Functions
*/
int simple_config(ha_context_t* context, const char* name, const char* value)
{
- simple_context_t* ctx = (simple_context_t*)(context->ctx_data);
-
- ASSERT(name && name[0] && value && value[0]);
-
- if(strcmp(name, "passwordfile") == 0)
- {
- ctx->filename = value;
- return HA_OK;
- }
-
- return HA_FALSE;
-}
-
-int simple_init(ha_context_t* context)
-{
- /* Global initialization */
- if(!context)
- {
- ha_messagex(LOG_DEBUG, "simple: generating secret");
- return ha_genrandom(g_simple_secret, DIGEST_SECRET_LEN);
- }
-
- /* Context specific initialization */
- else
- {
simple_context_t* ctx = (simple_context_t*)(context->ctx_data);
- hsh_table_calls_t htc;
- int fd;
-
- ASSERT(ctx);
-
- /* Make sure there are some types of authentication we can do */
- 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.");
- return HA_FAILED;
- }
-
- /* Check to make sure the file exists */
- if(!ctx->filename)
- {
- ha_messagex(LOG_ERR, "simple: configuration incomplete. "
- "Must have a PasswordFile configured.");
- return HA_FAILED;
- }
+ ASSERT(name && name[0] && value && value[0]);
- fd = open(ctx->filename, O_RDONLY);
- if(fd == -1)
+ if(strcmp(name, "passwordfile") == 0)
{
- ha_message(LOG_ERR, "simple: can't open file for authentication: %s", ctx->filename);
- return HA_FAILED;
+ ctx->filename = value;
+ return HA_OK;
}
- close(fd);
-
- ASSERT(!ctx->cache);
-
- /* The cache for digest records and basic */
- if(!(ctx->cache = hsh_create(MD5_LEN)))
- {
- ha_messagex(LOG_CRIT, "out of memory");
- return HA_CRITERROR;
- }
-
- htc.f_freeval = free_hash_object;
- htc.arg = NULL;
- hsh_set_table_calls(ctx->cache, &htc);
-
- ha_messagex(LOG_INFO, "simple: initialized handler");
- }
-
- return HA_OK;
-}
-
-void simple_destroy(ha_context_t* context)
-{
- /* Per context destroy */
- if(context)
- {
- /* Note: We don't need to be thread safe here anymore */
- simple_context_t* ctx = (simple_context_t*)(context->ctx_data);
-
- if(ctx->cache)
- hsh_free(ctx->cache);
-
- ha_messagex(LOG_INFO, "simple: uninitialized handler");
- }
+ return HA_FALSE;
}
-int simple_process(const ha_request_t* req, ha_response_t* resp)
+int simple_init(ha_context_t* context)
{
- 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(req && resp);
- ASSERT(req->args[AUTH_ARG_METHOD]);
- ASSERT(req->args[AUTH_ARG_URI]);
-
- ha_lock(NULL);
-
- /* Purge the cache */
- r = hsh_purge(ctx->cache, time(NULL) - req->context->cache_timeout);
+ int r;
- ha_unlock(NULL);
+ if((r = bd_init(context)) != HA_OK)
+ return r;
- if(r > 0)
- ha_messagex(LOG_DEBUG, "simple: purged cache records: %d", r);
-
- /* We use this below to detect whether to send a default response */
- resp->code = -1;
-
-
- /* Check the headers and see if we got a response thingy */
- 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);
- if(ret < 0)
- return ret;
- }
- }
-
- /* Or a basic authentication */
- 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)
+ if(context)
{
- ret = simple_basic_response(ctx, header, req, resp);
- if(ret < 0)
- return ret;
- }
- }
-
+ simple_context_t* ctx = (simple_context_t*)(context->ctx_data);
+ int fd;
- /* Send a default response if that's what we need */
- if(resp->code == -1)
- {
- resp->code = HA_SERVER_DECLINE;
+ ASSERT(ctx);
- if(req->context->allowed_types & HA_TYPE_BASIC)
- {
- ha_bufmcat(req->buf, "BASIC realm=\"", req->context->realm , "\"", NULL);
+ /* Check to make sure the file exists */
+ if(!ctx->filename)
+ {
+ ha_messagex(LOG_ERR, "simple: configuration incomplete. "
+ "Must have a PasswordFile configured.");
+ return HA_FAILED;
+ }
- if(ha_buferr(req->buf))
- return HA_CRITERROR;
+ fd = open(ctx->filename, O_RDONLY);
+ if(fd == -1)
+ {
+ ha_message(LOG_ERR, "simple: can't open file for authentication: %s", ctx->filename);
+ return HA_FAILED;
+ }
- ha_addheader(resp, "WWW-Authenticate", ha_bufdata(req->buf));
- ha_messagex(LOG_DEBUG, "simple: sent basic auth request");
- }
+ close(fd);
- if(req->context->allowed_types & HA_TYPE_DIGEST)
- {
- ret = simple_digest_challenge(ctx, req, resp, 0);
- if(ret < 0)
- return ret;
+ ha_messagex(LOG_INFO, "simple: initialized handler");
}
- }
- return ret;
+ return HA_OK;
}
@@ -766,9 +299,9 @@ ha_handler_t simple_handler =
{
"SIMPLE", /* The type */
simple_init, /* Initialization function */
- simple_destroy, /* Uninitialization routine */
+ bd_destroy, /* Uninitialization routine */
simple_config, /* Config routine */
- simple_process, /* Processing routine */
+ bd_process, /* Processing routine */
NULL, /* A default context */
sizeof(simple_context_t) /* Size of the context */
};