From cbbe71752d7f9c6204ab0f16600fe7f10490f203 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sat, 24 Apr 2004 22:38:50 +0000 Subject: Completed implementation of ldap/ntlm/simple handlers --- daemon/basic.c | 242 ++++++--------------------------------------------------- 1 file changed, 22 insertions(+), 220 deletions(-) (limited to 'daemon/basic.c') diff --git a/daemon/basic.c b/daemon/basic.c index a8325af..da73682 100644 --- a/daemon/basic.c +++ b/daemon/basic.c @@ -1,243 +1,45 @@ -/* On some linux this is required to get crypt to show itself */ -#define _XOPEN_SOURCE - #include "usuals.h" #include "httpauthd.h" -#include "defaults.h" - -#include -#include -#include - -#define BASIC_MAXLINE 128 - -/* This needs to be the same as an MD5 hash length */ -#define BASIC_HASH_KEY_LEN 16 -#define BASIC_ESTABLISHED (void*)1 - -/* ------------------------------------------------------------------------------- - * Structures - */ - -typedef struct basic_context -{ - const char* filename; /* The file name with the user names */ - const char* realm; /* The realm for basic authentication */ - - /* Context ----------------------------------------------------------- */ - hash_t* established; /* Established connections */ -} -basic_context_t; - -/* ------------------------------------------------------------------------------- - * Handler Functions - */ - -int basic_config(ha_context_t* context, const char* name, const char* value) -{ - basic_context_t* ctx = (basic_context_t*)(context.data); - - if(strcmp(name, "basicfile") == 0) - { - ctx->filename = value; - return HA_OK; - } - - else if(strcmp(name, "realm") == 0) - { - ctx->realm = value; - return HA_OK; - } - - return HA_FALSE; -} - -int basic_init(ha_context_t* context) -{ - /* Don't do global init */ - if(!context) - return HA_OK; - - basic_context_t* ctx = (basic_context_t*)(context.data); - int fd; - - /* Make sure there are some types of authentication we can do */ - if(!(context->types & HA_TYPE_BASIC)) - { - ha_messagex(LOG_ERR, "Basic module configured, but does not implement any " - "configured authentication type."); - return HA_ERROR; - } - - /* Check to make sure the file exists */ - if(!ctx->filename) - { - ha_messagex(LOG_ERR, "Basic configuration incomplete. " - "Must have a BasicFile configured."); - return HA_ERROR; - } - - fd = open(ctx->filename, O_RDONLY); - if(fd == -1) - { - ha_message(LOG_ERR, "can't open file for basic authentication: %s", ctx->filename); - return HA_ERROR; - } - - close(fd); +#include "basic.h" - /* Initialize our cache table */ - if(!(ctx->established = hash_create(BASIC_HASH_KEY_LEN))) - { - ha_messagex(LOG_CRIT, "out of memory"); - return HA_ERROR; - } - - return HA_OK; -} - -int basic_process(ha_context_t* context, ha_request_t* req, - ha_response_t* resp, ha_buffer_t* buf) +int basic_parse(const char* header, ha_buffer_t* buf, basic_header_t* rec) { - basic_context_t* ctx = (basic_context_t*)(context.data); - const char* header; char* t; - int found = 0; - ha_basic_header_t basic; - - memset(&basic, 0, sizeof(basic)); - - ha_lock(NULL); - /* Purge the cache */ - hash_purge(ctx->established, time(NULL) - context->timeout); - - ha_unlock(NULL); + memset(rec, 0, sizeof(*rec)); + /* Trim the white space */ + while(*header && isspace(*header)) + header++; /* - * Init checked and made sure basic auth is enabled, so we - * can take that for granted here. + * Authorization header is in this format: + * + * "Basic " B64(user ":" password) */ + ha_bufdec64(buf, header, 0); + header = ha_bufdata(buf); - header = ha_getheader(req, "Authorization", BASIC_PREFIX); - if(header) - { - if(ha_parsebasic(header, buf, &basic) == HA_ERROR) - return HA_ERROR; - - /* Check and see if this connection is in the cache */ - ha_lock(NULL); - - if(hash_get(ctx->established, basic.key) == BASIC_ESTABLISHED) - { - hash_touch(ctx->established, basic.key); - found = 1; - } - - ha_unlock(NULL); - } - - - /* If we have a user name and password that wasn't in the cache */ - if(!found && basic.user && basic.user[0] && - basic.password && basic.password[0]) - { - FILE* f; - char line[BASIC_MAXLINE]; - - f = fopen(ctx->filename, "r"); - if(!f) - { - ha_message(LOG_ERR, "can't open file for basic auth: %s", ctx->filename); - resp->code = HA_SERVER_ERROR; - return HA_FALSE; - } - - /* - * 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, BASIC_MAXLINE, f); - - if(ferror(f)) - ha_message(LOG_ERR, "error reading basic password file"); - - t = strchr(line, ':'); - if(t) - { - /* Split the line */ - *t = 0; - t++; - - /* Check the user */ - if(strcmp(line, basic.user) == 0) - { - /* Not sure if crypt is thread safe so we lock */ - ha_lock(); - - /* Check the password */ - if(strcmp(crypt(basic.password, t), t) == 0) - found = 1; - - ha_unlock(); - - if(found) - break; - } - } - } + if(!header) + return HA_ERROR; - fclose(f); - } - /* If we found a user then tell them what it was */ - if(found) - { - resp->code = HA_SERVER_ACCEPT; - resp->detail = basic.user; + /* We have a cache key at this point so hash it */ + md5_string(rec->key, header); - /* We put this connection into the successful connections */ - if(!hash_set(ctx->established, basic.key, BASIC_ESTABLISHED)) - { - ha_messagex(LOG_CRIT, "out of memory"); - return HA_ERROR; - } - } - /* Otherwise make the browser authenticate */ - else + /* Parse the user. We need it in any case */ + t = strchr(header, ':'); + if(t != NULL) { - resp->code = HA_SERVER_DECLINE; - - ha_bufnext(buf); - ha_bufcat(buf, "BASIC realm=\"", ctx->realm ? ctx->realm : "", - "\"", NULL); + /* Break the string in half */ + *t = 0; - ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf)); + rec->user = header; + rec->password = t + 1; } return HA_OK; } - -/* ------------------------------------------------------------------------------- - * Handler Definition - */ - -ha_handler_t basic_handler = -{ - "Basic", /* The type */ - basic_init, /* Initialization function */ - basic_destroy, /* Uninitialization routine */ - basic_config, /* Config routine */ - basic_process, /* Processing routine */ - NULL, /* A default context */ - sizeof(basic_context_t) /* Size of the context */ -}; - -- cgit v1.2.3