summaryrefslogtreecommitdiff
path: root/daemon/basic.c
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2004-04-24 22:38:50 +0000
committerStef Walter <stef@memberwebs.com>2004-04-24 22:38:50 +0000
commitcbbe71752d7f9c6204ab0f16600fe7f10490f203 (patch)
tree365e6e472d239d117b5f849c45f3c08fc6617c0a /daemon/basic.c
parentff76efc3e5e1b0e4ca3b10b7402406f619509bba (diff)
Completed implementation of ldap/ntlm/simple handlers
Diffstat (limited to 'daemon/basic.c')
-rw-r--r--daemon/basic.c242
1 files changed, 22 insertions, 220 deletions
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 <syslog.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#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 */
-};
-