summaryrefslogtreecommitdiff
path: root/daemon/httpauthd.c
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2004-08-09 18:35:56 +0000
committerStef Walter <stef@memberwebs.com>2004-08-09 18:35:56 +0000
commit670eba73c474230e31d688e9568fcd540b4e3b39 (patch)
tree624502f0713a9c6f3b0520416134b405f150f356 /daemon/httpauthd.c
parentb0e50bbeb12e6247dd52dfd9e44c62f558c8a3a0 (diff)
- added request parameter to ha_message...
- combined ha_request and ha_response
Diffstat (limited to 'daemon/httpauthd.c')
-rw-r--r--daemon/httpauthd.c2021
1 files changed, 1007 insertions, 1014 deletions
diff --git a/daemon/httpauthd.c b/daemon/httpauthd.c
index c238a1a..17ed15c 100644
--- a/daemon/httpauthd.c
+++ b/daemon/httpauthd.c
@@ -36,15 +36,15 @@ extern ha_handler_t ntlm_handler;
/* This is the list of all available handlers */
ha_handler_t* g_handlerlist[] =
{
- &simple_handler,
- &ldap_handler,
- &ntlm_handler
+ &simple_handler,
+ &ldap_handler,
+ &ntlm_handler
};
typedef struct httpauth_loaded
{
- ha_context_t ctx;
- struct httpauth_loaded* next;
+ ha_context_t ctx;
+ struct httpauth_loaded* next;
}
httpauth_loaded_t;
@@ -58,34 +58,34 @@ httpauth_loaded_t* g_handlers = NULL;
/* A command definition. Used in parsing */
typedef struct httpauth_command
{
- const char* name;
- int code;
- int word_args; /* Arguments to be parsed as words */
- int rest_arg; /* Parse remainder as one arg? */
- const char** headers; /* Headers needed/allowed */
+ const char* name;
+ int code;
+ int word_args; /* Arguments to be parsed as words */
+ int rest_arg; /* Parse remainder as one arg? */
+ const char** headers; /* Headers needed/allowed */
}
httpauth_command_t;
/* The various valid headers for the auth command */
const char* kAuthHeaders[] =
{
- "Authorization",
- NULL
+ "Authorization",
+ NULL
};
/* The command definitions */
const httpauth_command_t kCommands[] =
{
- { "auth", REQTYPE_AUTH, 3, 0, kAuthHeaders },
- { "set", REQTYPE_SET, 1, 1, NULL },
- { "quit", REQTYPE_QUIT, 0, 0, NULL },
- { NULL, -1, 0, 0, NULL }
+ { "auth", REQTYPE_AUTH, 3, 0, kAuthHeaders },
+ { "set", REQTYPE_SET, 1, 1, NULL },
+ { "quit", REQTYPE_QUIT, 0, 0, NULL },
+ { NULL, -1, 0, 0, NULL }
};
typedef struct httpauth_thread
{
- pthread_t tid;
- int fd;
+ pthread_t tid;
+ int fd;
}
httpauth_thread_t;
@@ -126,9 +126,8 @@ static int usage();
static void writepid(const char* pid);
static void* httpauth_thread(void* arg);
static int httpauth_processor(int ifd, int ofd);
-static int httpauth_respond(int ofd, int scode, int ccode, const char* msg);
-static int process_auth(ha_request_t* req, ha_response_t* resp,
- ha_buffer_t* outb);
+static int httpauth_respond(ha_request_t* rq, int ofd, int scode, int ccode, const char* msg);
+static int process_auth(ha_request_t* rq);
static int config_parse(const char* file, ha_buffer_t* buf);
static void on_quit(int signal);
@@ -138,990 +137,984 @@ static void on_quit(int signal);
int main(int argc, char* argv[])
{
- const char* conf = DEFAULT_CONFIG;
- const char* pidfile = NULL;
- httpauth_thread_t* threads = NULL;
- httpauth_loaded_t* h;
- char peername[MAXPATHLEN];
- struct sockaddr_any sany;
- int daemonize = 1;
- ha_buffer_t cbuf;
- int r, i, sock;
- int ch = 0;
-
- /* Keep note of the main thread */
- g_mainthread = pthread_self();
-
- /* Create the main mutex */
- if(pthread_mutexattr_init(&g_mutexattr) != 0 ||
- pthread_mutexattr_settype(&g_mutexattr, HA_MUTEX_TYPE) ||
- pthread_mutex_init(&g_mutex, &g_mutexattr) != 0)
- errx(1, "threading problem. can't create mutex");
-
- /* Parse the arguments nicely */
+ const char* conf = DEFAULT_CONFIG;
+ const char* pidfile = NULL;
+ httpauth_thread_t* threads = NULL;
+ httpauth_loaded_t* h;
+ char peername[MAXPATHLEN];
+ struct sockaddr_any sany;
+ int daemonize = 1;
+ ha_buffer_t cbuf;
+ int r, i, sock;
+ int ch = 0;
+
+ /* Keep note of the main thread */
+ g_mainthread = pthread_self();
+
+ /* Create the main mutex */
+ if(pthread_mutexattr_init(&g_mutexattr) != 0 ||
+ pthread_mutexattr_settype(&g_mutexattr, HA_MUTEX_TYPE) ||
+ pthread_mutex_init(&g_mutex, &g_mutexattr) != 0)
+ errx(1, "threading problem. can't create mutex");
+
+ /* Parse the arguments nicely */
while((ch = getopt(argc, argv, "d:f:p:X")) != -1)
{
switch(ch)
{
/* Don't daemonize */
- case 'd':
- {
- char* t;
-
- daemonize = 0;
- g_debuglevel = strtol(optarg, &t, 10);
- if(*t || g_debuglevel > 4)
- errx(1, "invalid debug log level");
- g_debuglevel += LOG_ERR;
- }
- break;
-
- /* The configuration file */
- case 'f':
- conf = optarg;
- break;
-
- /* Write out a pid file */
- case 'p':
- pidfile = optarg;
- break;
-
- /* Process console input instead */
+ case 'd':
+ {
+ char* t;
+ daemonize = 0;
+ g_debuglevel = strtol(optarg, &t, 10);
+ if(*t || g_debuglevel > 4)
+ errx(1, "invalid debug log level");
+ g_debuglevel += LOG_ERR;
+ }
+ break;
+
+ /* The configuration file */
+ case 'f':
+ conf = optarg;
+ break;
+
+ /* Write out a pid file */
+ case 'p':
+ pidfile = optarg;
+ break;
+
+ /* Process console input instead */
case 'X':
- g_console = 1;
- daemonize = 0;
- break;
+ g_console = 1;
+ daemonize = 0;
+ break;
- /* Usage information */
- case '?':
- default:
- return usage();
- break;
- }
- }
+ /* Usage information */
+ case '?':
+ default:
+ return usage();
+ break;
+ }
+ }
- argc -= optind;
- argv += optind;
+ argc -= optind;
+ argv += optind;
- if(argc != 0)
- return usage();
+ if(argc != 0)
+ return usage();
- ha_messagex(LOG_DEBUG, "starting up...");
+ ha_messagex(NULL, LOG_DEBUG, "starting up...");
- /* From here on out we need to quit in an orderly fashion */
+ /* From here on out we need to quit in an orderly fashion */
- /* Run global initialization on all handlers */
- for(i = 0; i < countof(g_handlerlist); i++)
- {
- if(g_handlerlist[i]->f_init)
+ /* Run global initialization on all handlers */
+ for(i = 0; i < countof(g_handlerlist); i++)
{
- if((r = (g_handlerlist[i]->f_init)(NULL)) == -1)
- goto finally;
+ if(g_handlerlist[i]->f_init)
+ {
+ if((r = (g_handlerlist[i]->f_init)(NULL)) == -1)
+ goto finally;
+ }
}
- }
- /* Initialize our configuration buffer */
- ha_bufinit(&cbuf);
+ /* Initialize our configuration buffer */
+ ha_bufinit(&cbuf);
- /* Parse the configuration */
- config_parse(conf, &cbuf);
+ /* Parse the configuration */
+ config_parse(conf, &cbuf);
- if(!g_console)
- {
- /* Create the thread buffers */
- threads = (httpauth_thread_t*)calloc(g_maxthreads, sizeof(httpauth_thread_t));
- if(!threads)
- errx(1, "out of memory");
+ if(!g_console)
+ {
+ /* Create the thread buffers */
+ threads = (httpauth_thread_t*)calloc(g_maxthreads, sizeof(httpauth_thread_t));
+ if(!threads)
+ errx(1, "out of memory");
- /* Get the socket type */
- if(sock_any_pton(g_socket, &sany, DEFAULT_PORT) == -1)
- errx(1, "invalid socket name or ip: %s", g_socket);
+ /* TODO: Import the new sock_any from clamsmtp */
+ /* Get the socket type */
+ if(sock_any_pton(g_socket, &sany, DEFAULT_PORT) == -1)
+ errx(1, "invalid socket name or ip: %s", g_socket);
- /* Create the socket */
- sock = socket(SANY_TYPE(sany), SOCK_STREAM, 0);
- if(sock < 0)
- err(1, "couldn't open socket");
+ /* Create the socket */
+ sock = socket(SANY_TYPE(sany), SOCK_STREAM, 0);
+ if(sock < 0)
+ err(1, "couldn't open socket");
- /* Unlink the socket file if it exists */
- /* TODO: Is this safe? */
- unlink(g_socket);
+ /* Unlink the socket file if it exists */
+ /* TODO: Is this safe? */
+ unlink(g_socket);
- if(bind(sock, &SANY_ADDR(sany), SANY_LEN(sany)) != 0)
- err(1, "couldn't bind to address: %s", g_socket);
+ if(bind(sock, &SANY_ADDR(sany), SANY_LEN(sany)) != 0)
+ err(1, "couldn't bind to address: %s", g_socket);
- /* Let 5 connections queue up */
- if(listen(sock, 5) != 0)
- err(1, "couldn't listen on socket");
+ /* Let 5 connections queue up */
+ if(listen(sock, 5) != 0)
+ err(1, "couldn't listen on socket");
- ha_messagex(LOG_DEBUG, "created socket: %s", g_socket);
- }
+ ha_messagex(NULL, LOG_DEBUG, "created socket: %s", g_socket);
+ }
- /* Initialize all the handlers */
- for(h = g_handlers; h; h = h->next)
- {
- if(h->ctx.handler->f_init)
+ /* Initialize all the handlers */
+ for(h = g_handlers; h; h = h->next)
{
- if((r = (h->ctx.handler->f_init)(&(h->ctx))) == -1)
- goto finally;
+ if(h->ctx.handler->f_init)
+ {
+ if((r = (h->ctx.handler->f_init)(&(h->ctx))) == -1)
+ goto finally;
+ }
}
- }
-
-
- /* This is for debugging the internal processes */
- if(g_console)
- {
- ha_messagex(LOG_DEBUG, "processing from console");
- r = httpauth_processor(0, 1);
- goto finally;
- }
- /* This is the daemon section of the code */
- else
- {
- if(daemonize)
+ /* This is for debugging the internal processes */
+ if(g_console)
{
- /* Fork a daemon nicely here */
- if(daemon(0, 0) == -1)
- {
- ha_message(LOG_ERR, "couldn't run httpauth as daemon");
- exit(1);
- }
-
- ha_messagex(LOG_DEBUG, "running as a daemon");
- g_daemonized = 1;
+ ha_messagex(NULL, LOG_DEBUG, "processing from console");
+ r = httpauth_processor(0, 1);
+ goto finally;
}
- writepid(pidfile);
- /* Handle some signals */
- signal(SIGPIPE, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
- signal(SIGINT, on_quit);
- signal(SIGTERM, on_quit);
+ /* This is the daemon section of the code */
+ else
+ {
+ if(daemonize)
+ {
+ /* Fork a daemon nicely here */
+ if(daemon(0, 0) == -1)
+ {
+ ha_message(NULL, LOG_ERR, "couldn't run httpauth as daemon");
+ exit(1);
+ }
- siginterrupt(SIGINT, 1);
- siginterrupt(SIGTERM, 1);
+ ha_messagex(NULL, LOG_DEBUG, "running as a daemon");
+ g_daemonized = 1;
+ }
- /* Open the system log */
- openlog("httpauthd", 0, LOG_AUTHPRIV);
+ writepid(pidfile);
- ha_messagex(LOG_DEBUG, "accepting connections");
+ /* Handle some signals */
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGINT, on_quit);
+ signal(SIGTERM, on_quit);
- /* Now loop and accept the connections */
- while(!g_quit)
- {
- int fd;
+ siginterrupt(SIGINT, 1);
+ siginterrupt(SIGTERM, 1);
- fd = accept(sock, NULL, NULL);
- if(fd == -1)
- {
- switch(errno)
- {
- case EINTR:
- case EAGAIN:
- break;
+ /* Open the system log */
+ openlog("httpauthd", 0, LOG_AUTHPRIV);
- case ECONNABORTED:
- ha_message(LOG_ERR, "couldn't accept a connection");
- break;
+ ha_messagex(NULL, LOG_DEBUG, "accepting connections");
- default:
- ha_message(LOG_ERR, "couldn't accept a connection");
- g_quit = 1;
- break;
- };
+ /* Now loop and accept the connections */
+ while(!g_quit)
+ {
+ int fd;
- if(g_quit)
- break;
+ fd = accept(sock, NULL, NULL);
+ if(fd == -1)
+ {
+ switch(errno)
+ {
+ case EINTR:
+ case EAGAIN:
+ break;
+
+ case ECONNABORTED:
+ ha_message(NULL, LOG_ERR, "couldn't accept a connection");
+ break;
+
+ default:
+ ha_message(NULL, LOG_ERR, "couldn't accept a connection");
+ g_quit = 1;
+ break;
+ };
+
+ if(g_quit)
+ break;
+
+ continue;
+ }
- continue;
- }
+ memset(&sany, 0, sizeof(sany));
+ SANY_LEN(sany) = sizeof(sany);
- memset(&sany, 0, sizeof(sany));
- SANY_LEN(sany) = sizeof(sany);
+ /* TODO: Move this code into the thread */
+ /* Get the peer name */
+ if(getpeername(fd, &SANY_ADDR(sany), &SANY_LEN(sany)) == -1 ||
+ sock_any_ntop(&sany, peername, MAXPATHLEN, SANY_OPT_NOPORT) == -1)
+ ha_messagex(NULL, LOG_WARNING, "%d: couldn't get peer address", fd);
+ else
+ ha_messagex(NULL, LOG_INFO, "%d: accepted connection from: %s", fd, peername);
- /* Get the peer name */
- if(getpeername(fd, &SANY_ADDR(sany), &SANY_LEN(sany)) == -1 ||
- sock_any_ntop(&sany, peername, MAXPATHLEN, SANY_OPT_NOPORT) == -1)
- ha_messagex(LOG_WARNING, "%d: couldn't get peer address", fd);
- else
- ha_messagex(LOG_INFO, "%d: accepted connection from: %s", fd, peername);
+ /* Look for thread and also clean up others */
+ for(i = 0; i < g_maxthreads; i++)
+ {
+ /* Clean up quit threads */
+ if(threads[i].tid != 0)
+ {
+ if(threads[i].fd == -1)
+ {
+ ha_messagex(NULL, LOG_DEBUG, "cleaning up completed thread");
+ pthread_join(threads[i].tid, NULL);
+ threads[i].tid = 0;
+ }
+ }
+
+ /* Start a new thread if neccessary */
+ if(fd != -1 && threads[i].tid == 0)
+ {
+ threads[i].fd = fd;
+ r = pthread_create(&(threads[i].tid), NULL, httpauth_thread,
+ (void*)(threads + i));
+ if(r != 0)
+ {
+ errno = r;
+ ha_message(NULL, LOG_ERR, "couldn't create thread");
+ g_quit = 1;
+ break;
+ }
+
+ ha_messagex(NULL, LOG_DEBUG, "%d: created thread for connection", fd);
+ fd = -1;
+ break;
+ }
+ }
- /* Look for thread and also clean up others */
- for(i = 0; i < g_maxthreads; i++)
- {
- /* Clean up quit threads */
- if(threads[i].tid != 0)
- {
- if(threads[i].fd == -1)
- {
- ha_messagex(LOG_DEBUG, "cleaning up completed thread");
- pthread_join(threads[i].tid, NULL);
- threads[i].tid = 0;
- }
+ /* Check to make sure we have a thread */
+ if(fd != -1)
+ {
+ ha_messagex(NULL, LOG_ERR, "too many connections open (max %d)", g_maxthreads);
+ httpauth_respond(NULL, fd, HA_SERVER_ERROR, 0, "too many connections");
+ shutdown(fd, SHUT_RDWR);
+ }
}
- /* Start a new thread if neccessary */
- if(fd != -1 && threads[i].tid == 0)
+ ha_messagex(NULL, LOG_INFO, "waiting for threads to quit");
+
+ /* Quit all threads here */
+ for(i = 0; i < g_maxthreads; i++)
{
- threads[i].fd = fd;
- r = pthread_create(&(threads[i].tid), NULL, httpauth_thread,
- (void*)(threads + i));
- if(r != 0)
- {
- errno = r;
- ha_message(LOG_ERR, "couldn't create thread");
- g_quit = 1;
- break;
- }
+ /* Clean up quit threads */
+ if(threads[i].tid != 0)
+ {
+ if(threads[i].fd != -1)
+ shutdown(threads[i].fd, SHUT_RDWR);
- ha_messagex(LOG_DEBUG, "%d: created thread for connection", fd);
- fd = -1;
- break;
+ pthread_join(threads[i].tid, NULL);
+ }
}
- }
-
- /* Check to make sure we have a thread */
- if(fd != -1)
- {
- ha_messagex(LOG_ERR, "too many connections open (max %d)", g_maxthreads);
- httpauth_respond(fd, HA_SERVER_ERROR, 0, "too many connections");
- shutdown(fd, SHUT_RDWR);
- }
- }
-
- ha_messagex(LOG_INFO, "waiting for threads to quit");
- /* Quit all threads here */
- for(i = 0; i < g_maxthreads; i++)
- {
- /* Clean up quit threads */
- if(threads[i].tid != 0)
- {
- if(threads[i].fd != -1)
- shutdown(threads[i].fd, SHUT_RDWR);
-
- pthread_join(threads[i].tid, NULL);
- }
+ r = 0;
}
- r = 0;
- }
-
finally:
- ha_messagex(LOG_DEBUG, "performing cleanup...");
+ ha_messagex(NULL, LOG_DEBUG, "performing cleanup...");
- /* Uninitialize all the handlers */
- for(h = g_handlers; h; h = h->next)
- {
- if(h->ctx.handler->f_destroy)
- (h->ctx.handler->f_destroy)(&(h->ctx));
- }
-
- /* Run global destroy for all handlers */
- for(i = 0; i < countof(g_handlerlist); i++)
- {
- if(g_handlerlist[i]->f_destroy)
- (g_handlerlist[i]->f_destroy)(NULL);
- }
+ /* Uninitialize all the handlers */
+ for(h = g_handlers; h; h = h->next)
+ {
+ if(h->ctx.handler->f_destroy)
+ (h->ctx.handler->f_destroy)(&(h->ctx));
+ }
- /* Clean up memory and stuff */
- ha_buffree(&cbuf);
+ /* Run global destroy for all handlers */
+ for(i = 0; i < countof(g_handlerlist); i++)
+ {
+ if(g_handlerlist[i]->f_destroy)
+ (g_handlerlist[i]->f_destroy)(NULL);
+ }
- /* Close the mutex */
- pthread_mutex_destroy(&g_mutex);
- pthread_mutexattr_destroy(&g_mutexattr);
+ /* Clean up memory and stuff */
+ ha_buffree(&cbuf);
- ha_messagex(LOG_DEBUG, "stopped");
+ /* Close the mutex */
+ pthread_mutex_destroy(&g_mutex);
+ pthread_mutexattr_destroy(&g_mutexattr);
- return r == -1 ? 1 : 0;
+ ha_messagex(NULL, LOG_DEBUG, "stopped");
+ return r == -1 ? 1 : 0;
}
static void on_quit(int signal)
{
- g_quit = 1;
- fprintf(stderr, "httpauthd: got signal to quit\n");
+ g_quit = 1;
+ fprintf(stderr, "httpauthd: got signal to quit\n");
}
static int usage()
{
- fprintf(stderr, "usage: httpauthd [-d level] [-X] [-p pidfile] [-f conffile]\n");
- return 2;
+ fprintf(stderr, "usage: httpauthd [-d level] [-X] [-p pidfile] [-f conffile]\n");
+ return 2;
}
static void writepid(const char* pidfile)
{
- FILE* f = fopen(pidfile, "w");
- if(f == NULL)
- {
- warnx("couldn't open pid file: %s", pidfile);
- }
- else
- {
- fprintf(f, "%d\n", (int)getpid());
-
- if(ferror(f))
- warnx("couldn't write to pid file: %s", pidfile);
-
- fclose(f);
- }
+ FILE* f = fopen(pidfile, "w");
+ if(f == NULL)
+ {
+ warnx("couldn't open pid file: %s", pidfile);
+ }
+ else
+ {
+ fprintf(f, "%d\n", (int)getpid());
+
+ if(ferror(f))
+ warnx("couldn't write to pid file: %s", pidfile);
+
+ fclose(f);
+ }
}
static void* httpauth_thread(void* arg)
{
- httpauth_thread_t* thread = (httpauth_thread_t*)arg;
- int r;
+ httpauth_thread_t* thread = (httpauth_thread_t*)arg;
+ int r;
- siginterrupt(SIGINT, 1);
- siginterrupt(SIGTERM, 1);
-
- ASSERT(thread);
- ASSERT(thread->fd != -1);
+ siginterrupt(SIGINT, 1);
+ siginterrupt(SIGTERM, 1);
- /* call the processor */
- r = httpauth_processor(thread->fd, thread->fd);
+ ASSERT(thread);
+ ASSERT(thread->fd != -1);
- ha_messagex(LOG_INFO, "%d: closed connection", thread->fd);
+ /* call the processor */
+ r = httpauth_processor(thread->fd, thread->fd);
- /* mark this as done */
- thread->fd = -1;
+ /* TODO: Move this to more appropriate place (where we have a req) */
+ ha_messagex(NULL, LOG_INFO, "%d: closed connection", thread->fd);
- return (void*)r;
+ /* mark this as done */
+ thread->fd = -1;
+ return (void*)r;
}
/* -----------------------------------------------------------------------
* Logging
*/
-void log_request(ha_request_t* req, ha_buffer_t* buf, int fd)
+void log_request(ha_request_t* rq)
{
- const httpauth_command_t* cmd;
- const char* t;
- const char* t2;
- int i;
+ const httpauth_command_t* cmd;
+ const char* t;
+ const char* t2;
+ int i;
- if(g_debuglevel < LOG_DEBUG)
- return;
+ if(g_debuglevel < LOG_DEBUG)
+ return;
- if(req->type == REQTYPE_IGNORE || req->type == -1)
- return;
+ if(rq->req_type == REQTYPE_IGNORE || rq->req_type == -1)
+ return;
- ha_bufcpy(buf, "");
+ ha_bufcpy(rq->buf, "");
- for(i = 0; i < HA_MAX_ARGS; i++)
- {
- if(req->args[i])
+ for(i = 0; i < HA_MAX_ARGS; i++)
{
- ha_bufjoin(buf);
- ha_bufmcat(buf, ha_buflen(buf) > 0 ? ", " : "", req->args[i], NULL);
+ if(rq->req_args[i])
+ {
+ ha_bufjoin(rq->buf);
+ ha_bufmcat(rq->buf, ha_buflen(rq->buf) > 0 ? ", " : "", rq->req_args[i], NULL);
+ }
}
- }
- t = ha_bufdata(buf);
+ t = ha_bufdata(rq->buf);
+ t2 = NULL;
- t2 = NULL;
-
- /* Figure out which command it is */
- for(cmd = kCommands; cmd->name; cmd++)
- {
- if(cmd->code == req->type)
+ /* Figure out which command it is */
+ for(cmd = kCommands; cmd->name; cmd++)
{
- t2 = cmd->name;
- break;
+ if(cmd->code == rq->req_type)
+ {
+ t2 = cmd->name;
+ break;
+ }
}
- }
- ASSERT(t2);
+ ASSERT(t2);
- ha_messagex(LOG_DEBUG, "%d: received request: "
- "[ type: %s / args: %s ]", fd, t2, t);
+ ha_messagex(rq, LOG_DEBUG, "received request: [ type: %s / args: %s ]", t2, t);
- for(i = 0; i < HA_MAX_HEADERS; i++)
- {
- if(req->headers[i].name)
+ for(i = 0; i < HA_MAX_HEADERS; i++)
{
- ASSERT(req->headers[i].data);
- ha_messagex(LOG_DEBUG, "%d: received header: [ %s: %s ]", fd,
- req->headers[i].name, req->headers[i].data);
+ if(rq->req_headers[i].name)
+ {
+ ASSERT(rq->req_headers[i].data);
+ ha_messagex(rq, LOG_DEBUG, "received header: [ %s: %s ]",
+ rq->req_headers[i].name, rq->req_headers[i].data);
+ }
}
- }
}
-void log_response(ha_response_t* resp, int fd)
+void log_response(ha_request_t* rq)
{
- int i;
+ int i;
- if(g_debuglevel < LOG_DEBUG)
- return;
+ if(g_debuglevel < LOG_DEBUG)
+ return;
- ha_messagex(LOG_DEBUG, "%d: sending response: "
- "[ code: 200 / ccode: %d / detail: %s ]", fd,
- resp->code, resp->detail ? resp->detail : "");
+ ha_messagex(rq, LOG_DEBUG, "sending response: [ code: 200 / ccode: %d / detail: %s ]",
+ rq->resp_code, rq->resp_detail ? rq->resp_detail : "");
- for(i = 0; i < HA_MAX_HEADERS; i++)
- {
- if(resp->headers[i].name)
+ for(i = 0; i < HA_MAX_HEADERS; i++)
{
- ASSERT(resp->headers[i].data);
- ha_messagex(LOG_DEBUG, "%d: sending header: [ %s: %s ]", fd,
- resp->headers[i].name, resp->headers[i].data);
+ if(rq->resp_headers[i].name)
+ {
+ ASSERT(rq->resp_headers[i].data);
+ ha_messagex(rq, LOG_DEBUG, "sending header: [ %s: %s ]",
+ rq->resp_headers[i].name, rq->resp_headers[i].data);
+ }
}
- }
}
-void log_respcode(int code, const char* msg, int fd)
+void log_respcode(ha_request_t* rq, int code, const char* msg)
{
- if(g_debuglevel < LOG_DEBUG)
- return;
+ if(g_debuglevel < LOG_DEBUG)
+ return;
- ha_messagex(LOG_DEBUG, "%d: sending response: "
- "[ code: %d / detail: %s ]", fd, code, msg ? msg : "");
+ ha_messagex(rq, LOG_DEBUG, "sending response: [ code: %d / detail: %s ]",
+ code, msg ? msg : "");
}
/* -----------------------------------------------------------------------
* Command Parsing and Handling
*/
-static int httpauth_read(int ifd, ha_request_t* req,
- ha_buffer_t* buf)
+static int httpauth_read(ha_request_t* rq, int ifd)
{
- const httpauth_command_t* cmd;
- char* t;
- int i, r;
- int more = 1;
+ const httpauth_command_t* cmd;
+ char* t;
+ int i, r;
+ int more = 1;
- ASSERT(req && buf);
- ASSERT(ifd != -1);
+ ASSERT(r);
+ ASSERT(ifd != -1);
- /* Clean up the request header */
- req->type = -1;
- memset(req->args, 0, sizeof(req->args));
- memset(req->headers, 0, sizeof(req->headers));
+ /* Clean up the request header */
+ rq->req_type = -1;
+ memset(rq->req_args, 0, sizeof(rq->req_args));
+ memset(rq->req_headers, 0, sizeof(rq->req_headers));
- /* This guarantees a bit of memory allocated, and resets buffer */
- ha_bufreset(buf);
+ /* This guarantees a bit of memory allocated, and resets buffer */
+ ha_bufreset(rq->buf);
- r = ha_bufreadline(ifd, buf);
- if(r == -1)
- return -1;
+ r = ha_bufreadline(ifd, rq->buf);
+ if(r == -1)
+ return -1;
- /* Check if this is the last line */
- if(r == 0)
- more = 0;
+ /* Check if this is the last line */
+ if(r == 0)
+ more = 0;
- /* Check to see if we got anything */
- if(ha_buflen(buf) == 0)
- {
- req->type = REQTYPE_IGNORE;
- return more;
- }
+ /* Check to see if we got anything */
+ if(ha_buflen(rq->buf) == 0)
+ {
+ rq->req_type = REQTYPE_IGNORE;
+ return more;
+ }
- /* Find the first space in the line */
- t = ha_bufparseword(buf, " \t");
+ /* Find the first space in the line */
+ t = ha_bufparseword(rq->buf, " \t");
- if(t)
- {
- /* Figure out which command it is */
- for(cmd = kCommands; cmd->name; cmd++)
+ if(t)
{
- if(strcasecmp(t, cmd->name) == 0)
- {
- req->type = cmd->code;
- break;
- }
+ /* Figure out which command it is */
+ for(cmd = kCommands; cmd->name; cmd++)
+ {
+ if(strcasecmp(t, cmd->name) == 0)
+ {
+ rq->req_type = cmd->code;
+ break;
+ }
+ }
}
- }
-
- else
- {
- req->type = REQTYPE_IGNORE;
- return more;
- }
- /* Check for invalid command */
- if(req->type == -1)
- return more;
+ else
+ {
+ rq->req_type = REQTYPE_IGNORE;
+ return more;
+ }
- /* Now parse the arguments if any */
- for(i = 0; i < cmd->word_args; i++)
- req->args[i] = ha_bufparseword(buf, " \t");
+ /* Check for invalid command */
+ if(rq->req_type == -1)
+ return more;
- /* Does it want the rest as one argument? */
- if(cmd->rest_arg)
- req->args[i] = ha_bufparseline(buf, 1);
+ /* Now parse the arguments if any */
+ for(i = 0; i < cmd->word_args; i++)
+ rq->req_args[i] = ha_bufparseword(rq->buf, " \t");
+ /* Does it want the rest as one argument? */
+ if(cmd->rest_arg)
+ rq->req_args[i] = ha_bufparseline(rq->buf, 1);
- /* Now skip anything else we have in the buffer */
- ha_bufskip(buf);
+ /* Now skip anything else we have in the buffer */
+ ha_bufskip(rq->buf);
- /* If we need headers, then read them now */
- if(cmd->headers)
- {
- const char** head; /* For iterating through valid headers */
- int valid = 0; /* The last header was valid */
- i = 0; /* The header we're working with */
- for(;;)
+ /* If we need headers, then read them now */
+ if(cmd->headers)
{
- /* Make sure we have more data */
- if(!more)
- break;
-
- r = ha_bufreadline(ifd, buf);
- if(r == -1)
- return -1;
-
- /* Check if this is the last line */
- if(r == 0)
- more = 0;
-
- /* An empty line is the end of the headers */
- if(ha_buflen(buf) == 0)
- break;
+ const char** head; /* For iterating through valid headers */
+ int valid = 0; /* The last header was valid */
+ i = 0; /* The header we're working with */
- /* Check if the header starts with a space */
- if(isspace(ha_bufchar(buf)))
- {
- /* Skip all the spaces */
- while(ha_buflen(buf) > 0 && isspace(ha_bufchar(buf)))
- ha_bufeat(buf);
+ for(;;)
+ {
+ /* Make sure we have more data */
+ if(!more)
+ break;
- /* An empty line is the end of the headers
- even if that line has spaces on it */
- if(ha_buflen(buf) == 0)
- break;
+ r = ha_bufreadline(ifd, rq->buf);
+ if(r == -1)
+ return -1;
- /* A header that has data on it but started
- with a space continues the previous header */
- if(valid && i > 0)
- {
- t = ha_bufparseline(buf, 0);
- if(t)
- {
- char* t2 = (char*)req->headers[i - 1].data + strlen(req->headers[i - 1].data);
-
- /* Fill the area between the end of the last
- valid header and this with spaces */
- memset(t2, ' ', t - t2);
- }
- }
- }
- else
- {
- if(i < HA_MAX_HEADERS)
- {
- t = ha_bufparseword(buf, ":");
+ /* Check if this is the last line */
+ if(r == 0)
+ more = 0;
- if(t)
- {
- for(head = cmd->headers; ; head++)
- {
- if(!(*head))
- {
- t = NULL;
+ /* An empty line is the end of the headers */
+ if(ha_buflen(rq->buf) == 0)
break;
- }
- if(strcasecmp(t, *head) == 0)
- break;
+ /* Check if the header starts with a space */
+ if(isspace(ha_bufchar(rq->buf)))
+ {
+ /* Skip all the spaces */
+ while(ha_buflen(rq->buf) > 0 && isspace(ha_bufchar(rq->buf)))
+ ha_bufeat(rq->buf);
+
+ /* An empty line is the end of the headers
+ even if that line has spaces on it */
+ if(ha_buflen(rq->buf) == 0)
+ break;
+
+ /* A header that has data on it but started
+ with a space continues the previous header */
+ if(valid && i > 0)
+ {
+ t = ha_bufparseline(rq->buf, 0);
+ if(t)
+ {
+ char* t2 = (char*)rq->req_headers[i - 1].data + strlen(rq->req_headers[i - 1].data);
+
+ /* Fill the area between the end of the last
+ valid header and this with spaces */
+ memset(t2, ' ', t - t2);
+ }
+ }
+ }
+ else
+ {
+ if(i < HA_MAX_HEADERS)
+ {
+ t = ha_bufparseword(rq->buf, ":");
+
+ if(t)
+ {
+ for(head = cmd->headers; ; head++)
+ {
+ if(!(*head))
+ {
+ t = NULL;
+ break;
+ }
+
+ if(strcasecmp(t, *head) == 0)
+ break;
+ }
+ }
+
+ if(t)
+ {
+ rq->req_headers[i].name = t;
+ rq->req_headers[i].data = ha_bufparseline(rq->buf, 1);
+ i++;
+ }
+
+ valid = (t != NULL) ? 1 : 0;
+ }
}
- }
-
- if(t)
- {
- req->headers[i].name = t;
- req->headers[i].data = ha_bufparseline(buf, 1);
- i++;
- }
- valid = (t != NULL) ? 1 : 0;
+ ha_bufskip(rq->buf);
}
- }
-
- ha_bufskip(buf);
}
- }
- return more;
+ return more;
}
-static int write_data(int ofd, const char* data)
+static int write_data(ha_request_t* rq, int ofd, const char* data)
{
- int r;
+ int r;
- ASSERT(data);
- ASSERT(ofd != -1);
+ ASSERT(data);
+ ASSERT(ofd != -1);
- while(*data != 0)
- {
- r = write(ofd, data, strlen(data));
+ while(*data != 0)
+ {
+ r = write(ofd, data, strlen(data));
- if(r > 0)
- data += r;
+ if(r > 0)
+ data += r;
- else if(r == -1)
- {
- if(errno == EAGAIN)
- continue;
+ else if(r == -1)
+ {
+ if(errno == EAGAIN)
+ continue;
- /* The other end closed. no message */
- if(errno != EPIPE)
- ha_message(LOG_ERR, "couldn't write data");
+ /* The other end closed. no message */
+ if(errno != EPIPE)
+ ha_message(rq, LOG_ERR, "couldn't write data");
- return HA_CRITERROR;
+ return HA_CRITERROR;
+ }
}
- }
- return 0;
+ return 0;
}
-static int httpauth_respond(int ofd, int scode, int ccode, const char* msg)
+static int httpauth_respond(ha_request_t* rq, int ofd, int scode, int ccode, const char* msg)
{
- char num[16];
+ char num[16];
- ASSERT(ofd != -1);
- ASSERT(scode > 99 && scode < 1000);
- ASSERT(ccode == 0 || (ccode > 99 && ccode < 1000));
+ ASSERT(ofd != -1);
+ ASSERT(scode > 99 && scode < 1000);
+ ASSERT(ccode == 0 || (ccode > 99 && ccode < 1000));
- /* Can only have a client code when server code is 200 */
- ASSERT(ccode == 0 || scode == HA_SERVER_OK);
+ /* Can only have a client code when server code is 200 */
+ ASSERT(ccode == 0 || scode == HA_SERVER_OK);
- sprintf(num, "%d ", scode);
+ sprintf(num, "%d ", scode);
- if(write_data(ofd, num) < 0)
- return HA_CRITERROR;
+ if(write_data(rq, ofd, num) < 0)
+ return HA_CRITERROR;
- if(ccode != 0)
- {
- sprintf(num, "%d ", ccode);
+ if(ccode != 0)
+ {
+ sprintf(num, "%d ", ccode);
- if(write_data(ofd, num) < 0)
- return HA_CRITERROR;
- }
+ if(write_data(rq, ofd, num) < 0)
+ return HA_CRITERROR;
+ }
- if(!msg)
- {
- switch(scode)
+ if(!msg)
{
- case HA_SERVER_ACCEPTED:
- msg = "Accepted";
- break;
- case HA_SERVER_ERROR:
- msg = "Internal Error ";
- break;
- case HA_SERVER_BADREQ:
- msg = "Bad Request ";
- break;
- case HA_SERVER_DECLINE:
- msg = "Unauthorized ";
- break;
- default:
- msg = NULL;
- break;
- };
- }
+ switch(scode)
+ {
+ case HA_SERVER_ACCEPTED:
+ msg = "Accepted";
+ break;
+ case HA_SERVER_ERROR:
+ msg = "Internal Error ";
+ break;
+ case HA_SERVER_BADREQ:
+ msg = "Bad Request ";
+ break;
+ case HA_SERVER_DECLINE:
+ msg = "Unauthorized ";
+ break;
+ default:
+ msg = NULL;
+ break;
+ };
+ }
- if(msg && write_data(ofd, msg) < 0)
- return HA_CRITERROR;
+ if(msg && write_data(rq, ofd, msg) < 0)
+ return HA_CRITERROR;
- /* When the client code is 0, then caller should log */
- if(ccode == 0)
- log_respcode(scode, msg, ofd);
+ /* When the client code is 0, then caller should log */
+ if(ccode == 0)
+ log_respcode(rq, scode, msg);
- return write_data(ofd, "\n");
+ return write_data(rq, ofd, "\n");
}
const char kHeaderDelimiter[] = ": ";
-static int httpauth_write(int ofd, ha_response_t* resp)
+static int httpauth_write(ha_request_t* rq, int ofd)
{
- int i;
- int wrote = 0;
+ int i;
+ int wrote = 0;
- ASSERT(ofd != -1);
- ASSERT(resp);
+ ASSERT(ofd != -1);
+ ASSERT(rq);
- if(httpauth_respond(ofd, HA_SERVER_OK, resp->code, resp->detail) < 0)
- return HA_CRITERROR;
+ if(httpauth_respond(rq, ofd, HA_SERVER_OK, rq->resp_code, rq->resp_detail) < 0)
+ return HA_CRITERROR;
- for(i = 0; i < HA_MAX_HEADERS; i++)
- {
- if(resp->headers[i].name)
+ for(i = 0; i < HA_MAX_HEADERS; i++)
{
- if(write_data(ofd, resp->headers[i].name) == -1 ||
- write_data(ofd, kHeaderDelimiter) == -1 ||
- write_data(ofd, resp->headers[i].data) == -1 ||
- write_data(ofd, "\n") == -1)
- return -1;
+ if(rq->resp_headers[i].name)
+ {
+ if(write_data(rq, ofd, rq->resp_headers[i].name) == -1 ||
+ write_data(rq, ofd, kHeaderDelimiter) == -1 ||
+ write_data(rq, ofd, rq->resp_headers[i].data) == -1 ||
+ write_data(rq, ofd, "\n") == -1)
+ return -1;
- wrote = 1;
+ wrote = 1;
+ }
}
- }
- if(write_data(ofd, "\n") == -1)
- return -1;
+ if(write_data(rq, ofd, "\n") == -1)
+ return -1;
- log_response(resp, ofd);
+ log_response(rq);
- return 0;
+ return 0;
}
-static int httpauth_error(int ofd, int r)
+static int httpauth_error(ha_request_t* rq, int ofd, int r)
{
- int scode = 0;
- const char* msg = NULL;
+ int scode = 0;
+ const char* msg = NULL;
- ASSERT(r < 0);
+ ASSERT(r < 0);
- switch(r)
- {
- case HA_BADREQ:
- scode = HA_SERVER_BADREQ;
- break;
+ switch(r)
+ {
+ case HA_BADREQ:
+ scode = HA_SERVER_BADREQ;
+ break;
- case HA_CRITERROR:
- msg = "Critical Error";
- /* fall through */
+ case HA_CRITERROR:
+ msg = "Critical Error";
+ /* fall through */
- case HA_FAILED:
- scode = HA_SERVER_ERROR;
- break;
+ case HA_FAILED:
+ scode = HA_SERVER_ERROR;
+ break;
- default:
- ASSERT(0 && "invalid error code");
- break;
- }
+ default:
+ ASSERT(0 && "invalid error code");
+ break;
+ };
- return httpauth_respond(ofd, scode, 0, msg);
+ return httpauth_respond(rq, ofd, scode, 0, msg);
}
-static int httpauth_ready(int ofd, ha_buffer_t* buf)
+static int httpauth_ready(ha_request_t* rq, int ofd)
{
- const char* t;
- httpauth_loaded_t* h;
+ const char* t;
+ httpauth_loaded_t* h;
- ASSERT(ofd != -1);
- ASSERT(buf);
+ ASSERT(ofd != -1);
+ ASSERT(rq);
- /* We send a ready banner to our client */
+ /* We send a ready banner to our client */
- if(ha_buferr(buf))
- return httpauth_error(ofd, HA_CRITERROR);
-
- else
- return httpauth_respond(ofd, HA_SERVER_READY, 0, "HTTPAUTH/1.0");
+ if(ha_buferr(rq->buf))
+ return httpauth_error(rq, ofd, HA_CRITERROR);
+ else
+ return httpauth_respond(rq, ofd, HA_SERVER_READY, 0, "HTTPAUTH/1.0");
}
-static int httpauth_auth(int ofd, ha_request_t* req, ha_response_t* resp)
+static int httpauth_auth(ha_request_t* rq, int ofd)
{
- int r;
-
- ASSERT(req && resp);
-
- if(!req->context)
- {
- ha_messagex(LOG_ERR, "no auth handler set");
- return httpauth_respond(ofd, HA_SERVER_BADREQ, 0, "No Auth Handler Set");
- }
-
- /* Clear out our response */
- resp->code = -1;
- resp->detail = NULL;
- memset(resp->headers, 0, sizeof(resp->headers));
- ASSERT(resp->buf != NULL);
-
- /* Check our connection argument */
- if(!req->args[AUTH_ARG_CONN] || !(req->args[AUTH_ARG_CONN][0]))
- {
- ha_messagex(LOG_ERR, "missing connection ID in request");
- return httpauth_respond(ofd, HA_SERVER_BADREQ, 0, "Missing Connection ID");
- }
-
- /* Check our uri argument */
- if(!req->args[AUTH_ARG_URI] || !(req->args[AUTH_ARG_URI][0]))
- {
- ha_messagex(LOG_ERR, "missing URI in request");
- return httpauth_respond(ofd, HA_SERVER_BADREQ, 0, "Missing URI");
- }
-
- /* Check our connection arguments */
- if(!req->args[AUTH_ARG_METHOD] || !(req->args[AUTH_ARG_METHOD][0]))
- {
- ha_messagex(LOG_ERR, "missing HTTP method in request");
- return httpauth_respond(ofd, HA_SERVER_BADREQ, 0, "Missing HTTP Method");
- }
-
- ASSERT(req->context->handler && req->context->handler->f_process);
- r = (req->context->handler->f_process)(req, resp);
- if(r < 0)
- return r;
-
- if(httpauth_write(ofd, resp) < 0)
- return HA_CRITERROR;
-
- return HA_OK;
+ int r;
+
+ ASSERT(rq);
+
+ if(!rq->context)
+ {
+ ha_messagex(rq, LOG_ERR, "no auth handler set");
+ return httpauth_respond(rq, ofd, HA_SERVER_BADREQ, 0, "No Auth Handler Set");
+ }
+
+ /* Clear out our response */
+ rq->resp_code = -1;
+ rq->resp_detail = NULL;
+ memset(rq->resp_headers, 0, sizeof(rq->resp_headers));
+
+ /* Check our connection argument */
+ if(!rq->req_args[AUTH_ARG_CONN] || !(rq->req_args[AUTH_ARG_CONN][0]))
+ {
+ ha_messagex(rq, LOG_ERR, "missing connection ID in request");
+ return httpauth_respond(rq, ofd, HA_SERVER_BADREQ, 0, "Missing Connection ID");
+ }
+
+ /* Check our uri argument */
+ if(!rq->req_args[AUTH_ARG_URI] || !(rq->req_args[AUTH_ARG_URI][0]))
+ {
+ ha_messagex(rq, LOG_ERR, "missing URI in request");
+ return httpauth_respond(rq, ofd, HA_SERVER_BADREQ, 0, "Missing URI");
+ }
+
+ /* Check our connection arguments */
+ if(!rq->req_args[AUTH_ARG_METHOD] || !(rq->req_args[AUTH_ARG_METHOD][0]))
+ {
+ ha_messagex(rq, LOG_ERR, "missing HTTP method in request");
+ return httpauth_respond(rq, ofd, HA_SERVER_BADREQ, 0, "Missing HTTP Method");
+ }
+
+ ASSERT(rq->context->handler && rq->context->handler->f_process);
+ r = (rq->context->handler->f_process)(rq);
+ if(r < 0)
+ return r;
+
+ if(httpauth_write(rq, ofd) < 0)
+ return HA_CRITERROR;
+
+ return HA_OK;
}
-static int httpauth_set(int ofd, ha_request_t* req)
+static int httpauth_set(ha_request_t* rq, int ofd)
{
- httpauth_loaded_t* h;
- const char* name = req->args[0];
- const char* value = req->args[1];
-
- ASSERT(req);
-
- /* Check our name argument */
- if(!name || !*name)
- {
- ha_messagex(LOG_ERR, "missing name in SET request");
- return HA_BADREQ;
- }
-
- if(strcasecmp(name, "Domain") == 0)
- {
- req->digest_domain = value ? value : "";
- }
-
- else if(strcasecmp(name, "Handler") == 0)
- {
- if(!value || !*value)
+ httpauth_loaded_t* h;
+ const char* name = rq->req_args[0];
+ const char* value = rq->req_args[1];
+
+ /* Check our name argument */
+ if(!name || !*name)
{
- ha_messagex(LOG_ERR, "no auth handler specified in SET request.");
- return HA_BADREQ;
+ ha_messagex(rq, LOG_ERR, "missing name in SET request");
+ return HA_BADREQ;
}
- /* Find a handler for this type */
- for(h = g_handlers; h; h = h->next)
+ if(strcasecmp(name, "Domain") == 0)
{
- if(strcasecmp(h->ctx.name, value) == 0)
- {
- req->context = &(h->ctx);
- value = NULL;
- break;
- }
+ rq->digest_domain = value ? value : "";
}
- if(value != NULL)
+ else if(strcasecmp(name, "Handler") == 0)
{
- ha_messagex(LOG_ERR, "unknown authentication type: %s", req->args[0]);
- return httpauth_respond(ofd, HA_SERVER_BADREQ, 0, "Unknown Auth Handler");
+ if(!value || !*value)
+ {
+ ha_messagex(rq, LOG_ERR, "no auth handler specified in SET request.");
+ return HA_BADREQ;
+ }
+
+ /* Find a handler for this type */
+ for(h = g_handlers; h; h = h->next)
+ {
+ if(strcasecmp(h->ctx.name, value) == 0)
+ {
+ rq->context = &(h->ctx);
+ value = NULL;
+ break;
+ }
+ }
+
+ if(value != NULL)
+ {
+ ha_messagex(rq, LOG_ERR, "unknown authentication type: %s", rq->req_args[0]);
+ return httpauth_respond(rq, ofd, HA_SERVER_BADREQ, 0, "Unknown Auth Handler");
+ }
}
- }
- else
- {
- ha_messagex(LOG_ERR, "bad option in SET request");
- return HA_BADREQ;
- }
+ else
+ {
+ ha_messagex(rq, LOG_ERR, "bad option in SET request");
+ return HA_BADREQ;
+ }
- return httpauth_respond(ofd, HA_SERVER_ACCEPTED, 0, NULL);
+ return httpauth_respond(rq, ofd, HA_SERVER_ACCEPTED, 0, NULL);
}
static int httpauth_processor(int ifd, int ofd)
{
- ha_buffer_t buf;
- ha_request_t req;
- ha_response_t resp;
- int result = -1;
- int r;
+ ha_buffer_t buf;
+ ha_request_t rq;
+ int result = -1;
+ int r;
- ASSERT(ifd != -1);
- ASSERT(ofd != -1);
+ ASSERT(ifd != -1);
+ ASSERT(ofd != -1);
- /* Initialize the memory buffers */
- ha_bufinit(&buf);
+ /* Initialize the memory buffers */
+ ha_bufinit(&buf);
- memset(&req, 0, sizeof(req));
- memset(&resp, 0, sizeof(resp));
+ memset(&rq, 0, sizeof(rq));
- /* Set up some context stuff */
- req.digest_domain = "";
- req.buf = &buf;
- resp.buf = &buf;
+ /* Set up some context stuff */
+ rq.digest_domain = "";
+ rq.buf = &buf;
- if(httpauth_ready(ofd, &buf) == -1)
- {
- result = 1;
- goto finally;
- }
+ if(httpauth_ready(&rq, ofd) == -1)
+ {
+ result = 1;
+ goto finally;
+ }
- /* Now loop and handle the commands */
- while(result == -1)
- {
- ha_bufreset(&buf);
+ /* Now loop and handle the commands */
+ while(result == -1)
+ {
+ ha_bufreset(&buf);
- r = httpauth_read(ifd, &req, &buf);
+ r = httpauth_read(&rq, ifd);
- if(ha_buferr(&buf))
- r = HA_CRITERROR;
+ if(ha_buferr(&buf))
+ r = HA_CRITERROR;
- if(r < 0)
- {
- httpauth_error(ofd, r);
- result = 1;
- break;
- }
+ if(r < 0)
+ {
+ httpauth_error(&rq, ofd, r);
+ result = 1;
+ break;
+ }
- log_request(&req, &buf, ifd);
+ log_request(&rq);
- if(r == 0)
- result = 0;
+ if(r == 0)
+ result = 0;
- switch(req.type)
- {
- case REQTYPE_AUTH:
- r = httpauth_auth(ofd, &req, &resp);
- break;
+ switch(rq.req_type)
+ {
+ case REQTYPE_AUTH:
+ r = httpauth_auth(&rq, ofd);
+ break;
- case REQTYPE_SET:
- r = httpauth_set(ofd, &req);
- break;
+ case REQTYPE_SET:
+ r = httpauth_set(&rq, ofd);
+ break;
- case REQTYPE_QUIT:
- r = HA_OK;
- result = 0;
- break;
+ case REQTYPE_QUIT:
+ r = HA_OK;
+ result = 0;
+ break;
- case REQTYPE_IGNORE:
- r = HA_FALSE;
- break;
+ case REQTYPE_IGNORE:
+ r = HA_FALSE;
+ break;
- default:
- ha_messagex(LOG_WARNING, "%d: received unknown command from client", ifd);
- r = httpauth_respond(ofd, HA_SERVER_BADREQ, 0, "Unknown command");
- break;
- };
+ default:
+ ha_messagex(&rq, LOG_WARNING, "received unknown command from client");
+ r = httpauth_respond(&rq, ofd, HA_SERVER_BADREQ, 0, "Unknown command");
+ break;
+ };
- if(ha_buferr(&buf))
- r = HA_CRITERROR;
+ if(ha_buferr(&buf))
+ r = HA_CRITERROR;
- if(r < 0)
- {
- httpauth_error(ofd, r);
+ if(r < 0)
+ {
+ httpauth_error(&rq, ofd, r);
- if(r == HA_CRITERROR)
- result = 1;
+ if(r == HA_CRITERROR)
+ result = 1;
+ }
}
- }
- if(ifd == ofd)
- shutdown(ofd, SHUT_RDWR);
- else
- close(ofd);
+ if(ifd == ofd)
+ {
+ shutdown(ofd, SHUT_RDWR);
+ close(ofd);
+ }
+ else
+ {
+ close(ifd);
+ close(ofd);
+ }
finally:
- ha_buffree(&buf);
-
- return result;
+ ha_buffree(&buf);
+ return result;
}
/* -----------------------------------------------------------------------
@@ -1129,335 +1122,335 @@ finally:
*/
static ha_context_t* config_addhandler(ha_buffer_t* buf, const char* alias,
- ha_handler_t* handler, const ha_context_t* defaults)
+ ha_handler_t* handler, const ha_context_t* defaults)
{
- httpauth_loaded_t* loaded;
- int len;
+ httpauth_loaded_t* loaded;
+ int len;
- ASSERT(buf && alias && handler && defaults);
+ ASSERT(buf && alias && handler && defaults);
- len = sizeof(httpauth_loaded_t) + handler->context_size;
+ len = sizeof(httpauth_loaded_t) + handler->context_size;
- loaded = (httpauth_loaded_t*)ha_bufmalloc(buf, len);
- if(!loaded)
- errx(1, "out of memory");
+ loaded = (httpauth_loaded_t*)ha_bufmalloc(buf, len);
+ if(!loaded)
+ errx(1, "out of memory");
- memset(loaded, 0, len);
+ memset(loaded, 0, len);
- /* Setup the options from the defaults */
- memcpy(&(loaded->ctx), defaults, sizeof(ha_context_t));
+ /* Setup the options from the defaults */
+ memcpy(&(loaded->ctx), defaults, sizeof(ha_context_t));
- if(handler->context_size)
- {
- void* mem = ((unsigned char*)(loaded)) + sizeof(httpauth_loaded_t);
-
- /* Initialize the defaults properly */
- if(handler->context_default)
- memcpy(mem, handler->context_default, handler->context_size);
+ if(handler->context_size)
+ {
+ void* mem = ((unsigned char*)(loaded)) + sizeof(httpauth_loaded_t);
- loaded->ctx.ctx_data = mem;
- }
+ /* Initialize the defaults properly */
+ if(handler->context_default)
+ memcpy(mem, handler->context_default, handler->context_size);
- else
- {
- loaded->ctx.ctx_data = NULL;
- }
+ loaded->ctx.ctx_data = mem;
+ }
- loaded->ctx.name = (char*)alias;
- loaded->ctx.handler = handler;
+ else
+ {
+ loaded->ctx.ctx_data = NULL;
+ }
- if(!g_handlers)
- {
- g_handlers = loaded;
- }
- else
- {
- httpauth_loaded_t* l = g_handlers;
+ loaded->ctx.name = (char*)alias;
+ loaded->ctx.handler = handler;
- for(;;)
+ if(!g_handlers)
+ {
+ g_handlers = loaded;
+ }
+ else
{
- if(strcasecmp(alias, l->ctx.name) == 0)
- errx(1, "duplicate handler section for '%s'", alias);
+ httpauth_loaded_t* l = g_handlers;
- if(!(l->next))
- break;
+ for(;;)
+ {
+ if(strcasecmp(alias, l->ctx.name) == 0)
+ errx(1, "duplicate handler section for '%s'", alias);
- l = l->next;
- }
+ if(!(l->next))
+ break;
- l->next = loaded;
- }
+ l = l->next;
+ }
- ha_messagex(LOG_DEBUG, "configuration: handler: %s (%s)", alias, handler->type);
- return &(loaded->ctx);
+ l->next = loaded;
+ }
+
+ ha_messagex(NULL, LOG_DEBUG, "configuration: handler: %s (%s)", alias, handler->type);
+ return &(loaded->ctx);
}
#define VALID_ALIAS_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ_-."
static int config_parse(const char* file, ha_buffer_t* buf)
{
- ha_context_t defaults;
- ha_context_t* ctx = NULL;
- int line = 0;
- int fd;
- char* t;
- char* name;
- char* value;
- int more = 1;
- int recog;
- int r, i;
-
- ASSERT(file && buf);
-
- /* Open the configuration file */
- fd = open(file, O_RDONLY);
- if(fd == -1)
- err(1, "couldn't open configuration file: %s", file);
-
- /* These are the default options for the contexts */
- memset(&defaults, 0, sizeof(defaults));
- defaults.allowed_types = 0xFFFFFFFF; /* All types by default */
- defaults.cache_timeout = DEFAULT_TIMEOUT; /* Timeout for cache */
- defaults.cache_max = DEFAULT_CACHEMAX;
- defaults.realm = "";
-
- /* Read each line and process */
- while(more)
- {
- ha_bufskip(buf);
-
- if((more = ha_bufreadline(fd, buf)) == -1)
- return -1;
-
- line++;
-
- /* Eat all white space at beginning of line */
- while(ha_buflen(buf) && isspace(ha_bufchar(buf)))
- ha_bufeat(buf);
-
- /* Skip blank lines */
- if(ha_buflen(buf) == 0)
- continue;
-
- /* Skip comment lines */
- if(ha_bufchar(buf) == '#')
- continue;
-
- /* Check for a handler */
- if(ha_bufchar(buf) == '[')
+ ha_context_t defaults;
+ ha_context_t* ctx = NULL;
+ int line = 0;
+ int fd;
+ char* t;
+ char* name;
+ char* value;
+ int more = 1;
+ int recog;
+ int r, i;
+
+ ASSERT(file && buf);
+
+ /* Open the configuration file */
+ fd = open(file, O_RDONLY);
+ if(fd == -1)
+ err(1, "couldn't open configuration file: %s", file);
+
+ /* These are the default options for the contexts */
+ memset(&defaults, 0, sizeof(defaults));
+ defaults.allowed_types = 0xFFFFFFFF; /* All types by default */
+ defaults.cache_timeout = DEFAULT_TIMEOUT; /* Timeout for cache */
+ defaults.cache_max = DEFAULT_CACHEMAX;
+ defaults.realm = "";
+
+ /* Read each line and process */
+ while(more)
{
- ha_handler_t* handler = NULL;
- const char* x;
+ ha_bufskip(buf);
- ha_bufeat(buf);
- name = ha_bufparseline(buf, 1);
+ if((more = ha_bufreadline(fd, buf)) == -1)
+ return -1;
- if(!name || name[strlen(name) - 1] != ']')
- errx(1, "handler section invalid (line %d)", line);
+ line++;
+ /* Eat all white space at beginning of line */
+ while(ha_buflen(buf) && isspace(ha_bufchar(buf)))
+ ha_bufeat(buf);
- /* remove the bracket */
- name[strlen(name) - 1] = 0;
+ /* Skip blank lines */
+ if(ha_buflen(buf) == 0)
+ continue;
- /*
- * Take out any colon found, past which would
- * be an aliased name
- */
- t = strchr(name, ':');
- if(t != NULL)
- {
- *t = 0;
- t++;
+ /* Skip comment lines */
+ if(ha_bufchar(buf) == '#')
+ continue;
- /* Rid of whitespace on ends */
- t = trim_space(t);
+ /* Check for a handler */
+ if(ha_bufchar(buf) == '[')
+ {
+ ha_handler_t* handler = NULL;
+ const char* x;
- /* Validate the alias name */
- if(!*t || strspn(t, VALID_ALIAS_CHARS) != strlen(t))
- errx(1, "invalid name for handler: %s", t);
- }
+ ha_bufeat(buf);
+ name = ha_bufparseline(buf, 1);
- /* Rid of whitespace */
- name = trim_space(name);
+ if(!name || name[strlen(name) - 1] != ']')
+ errx(1, "handler section invalid (line %d)", line);
- /* Look for a handler with this type */
- for(i = 0; i < countof(g_handlerlist); i++)
- {
- if(g_handlerlist[i] && g_handlerlist[i]->type &&
- strcasecmp(name, g_handlerlist[i]->type) == 0)
- {
- handler = g_handlerlist[i];
- break;
- }
- }
- if(handler == NULL)
- errx(1, "unknown handler type '%s' (line %d)", name, line);
+ /* remove the bracket */
+ name[strlen(name) - 1] = 0;
- /* If we had a last handler then add it to handlers */
- ctx = config_addhandler(buf, t ? t : name, handler, &defaults);
+ /*
+ * Take out any colon found, past which would
+ * be an aliased name
+ */
+ t = strchr(name, ':');
+ if(t != NULL)
+ {
+ *t = 0;
+ t++;
- /* Rest doesn't apply to handler headers */
- continue;
- }
+ /* Rid of whitespace on ends */
+ t = trim_space(t);
+ /* Validate the alias name */
+ if(!*t || strspn(t, VALID_ALIAS_CHARS) != strlen(t))
+ errx(1, "invalid name for handler: %s", t);
+ }
- /* Parse out the name */
- name = ha_bufparseword(buf, ":");
- if(!name || !name[0])
- errx(1, "configuration file invalid (line %d)", line);
+ /* Rid of whitespace */
+ name = trim_space(name);
- strlwr(name);
+ /* Look for a handler with this type */
+ for(i = 0; i < countof(g_handlerlist); i++)
+ {
+ if(g_handlerlist[i] && g_handlerlist[i]->type &&
+ strcasecmp(name, g_handlerlist[i]->type) == 0)
+ {
+ handler = g_handlerlist[i];
+ break;
+ }
+ }
- /* And get the rest of the line */
- value = ha_bufparseline(buf, 1);
- if(value == NULL)
- errx(1, "configuration missing value at (line %d)", line);
+ if(handler == NULL)
+ errx(1, "unknown handler type '%s' (line %d)", name, line);
+ /* If we had a last handler then add it to handlers */
+ ctx = config_addhandler(buf, t ? t : name, handler, &defaults);
- recog = 0;
+ /* Rest doesn't apply to handler headers */
+ continue;
+ }
- /* Is this the global section? */
- if(!ctx)
- {
- /* Look and see if that's a name we want */
- if(strcmp("socket", name) == 0)
- {
- g_socket = value;
- recog = 1;
- }
-
- else if(strcmp("maxthreads", name) == 0)
- {
- if(ha_confint(name, value, 1, 256, &g_maxthreads) == -1)
- exit(1);
- recog = 1;
- }
- }
- /* Otherwise we're in a handler */
- else
- {
- if(ctx->handler->f_config)
- {
- r = (ctx->handler->f_config)(ctx, name, value);
- if(r < 0)
- return r;
+ /* Parse out the name */
+ name = ha_bufparseword(buf, ":");
+ if(!name || !name[0])
+ errx(1, "configuration file invalid (line %d)", line);
- if(!recog && r == HA_OK)
- recog = 1;
- }
- }
+ strlwr(name);
- /* Options that are legal in both global and internal sections */
- if(!recog)
- {
- ha_context_t* opts = ctx ? ctx : &defaults;
- ASSERT(opts);
-
- if(strcmp(name, "cachetimeout") == 0)
- {
- int v;
- if(ha_confint(name, value, 0, 86400, &v) < 0)
- exit(1); /* Message already printed */
-
- opts->cache_timeout = v;
- recog = 1;
- }
-
- else if(strcmp(name, "cachemax") == 0)
- {
- int v;
- if(ha_confint(name, value, 0, 0x7FFFFFFF, &v) < 0)
- exit(1); /* Message already printed */
-
- opts->cache_max = v;
- recog = 1;
- }
-
- else if(strcmp(name, "authtypes") == 0)
- {
- int types = 0;
- char* t;
-
- strlwr(value);
-
- /* Split the line into tokens at the spaces */
- while(*value)
- {
- value = trim_space(value);
- t = value;
+ /* And get the rest of the line */
+ value = ha_bufparseline(buf, 1);
+ if(value == NULL)
+ errx(1, "configuration missing value at (line %d)", line);
- while(*t && !isspace(*t))
- t++;
- if(strncmp(value, "basic", 5) == 0)
- types |= HA_TYPE_BASIC;
+ recog = 0;
- else if(strncmp(value, "digest", 6) == 0)
- types |= HA_TYPE_DIGEST;
+ /* Is this the global section? */
+ if(!ctx)
+ {
+ /* Look and see if that's a name we want */
+ if(strcmp("socket", name) == 0)
+ {
+ g_socket = value;
+ recog = 1;
+ }
- else if(strncmp(value, "ntlm", 4) == 0)
- types |= HA_TYPE_NTLM;
+ else if(strcmp("maxthreads", name) == 0)
+ {
+ if(ha_confint(name, value, 1, 256, &g_maxthreads) == -1)
+ exit(1);
+ recog = 1;
+ }
+ }
- else
- errx(1, "invalid type for '%s': %s (line %d)", name, value, line);
+ /* Otherwise we're in a handler */
+ else
+ {
+ if(ctx->handler->f_config)
+ {
+ r = (ctx->handler->f_config)(ctx, name, value);
+ if(r < 0)
+ return r;
- value = t;
+ if(!recog && r == HA_OK)
+ recog = 1;
+ }
}
- if(types == 0)
- errx(1, "no authentication types for '%s' (line %d)", name, line);
+ /* Options that are legal in both global and internal sections */
+ if(!recog)
+ {
+ ha_context_t* opts = ctx ? ctx : &defaults;
+ ASSERT(opts);
- opts->allowed_types = types;
- recog = 1;
- }
+ if(strcmp(name, "cachetimeout") == 0)
+ {
+ int v;
+ if(ha_confint(name, value, 0, 86400, &v) < 0)
+ exit(1); /* Message already printed */
- else if(strcmp(name, "realm") == 0)
- {
- opts->realm = value;
- recog = 1;
- }
+ opts->cache_timeout = v;
+ recog = 1;
+ }
- else if(strcmp(name, "digestignoreuri") == 0)
- {
- int v;
- if(ha_confbool(name, value, &v) < 0)
- exit(1); /* Message already printed */
+ else if(strcmp(name, "cachemax") == 0)
+ {
+ int v;
+ if(ha_confint(name, value, 0, 0x7FFFFFFF, &v) < 0)
+ exit(1); /* Message already printed */
- opts->digest_ignoreuri = v;
- recog = 1;
- }
+ opts->cache_max = v;
+ recog = 1;
+ }
- else if(strcmp(name, "digestignorenc") == 0)
- {
- int v;
- if(ha_confbool(name, value, &v) < 0)
- exit(1); /* Message already printed */
+ else if(strcmp(name, "authtypes") == 0)
+ {
+ int types = 0;
+ char* t;
- opts->digest_ignorenc = v;
- recog = 1;
- }
+ strlwr(value);
+
+ /* Split the line into tokens at the spaces */
+ while(*value)
+ {
+ value = trim_space(value);
+ t = value;
+
+ while(*t && !isspace(*t))
+ t++;
+
+ if(strncmp(value, "basic", 5) == 0)
+ types |= HA_TYPE_BASIC;
+
+ else if(strncmp(value, "digest", 6) == 0)
+ types |= HA_TYPE_DIGEST;
+
+ else if(strncmp(value, "ntlm", 4) == 0)
+ types |= HA_TYPE_NTLM;
+
+ else
+ errx(1, "invalid type for '%s': %s (line %d)", name, value, line);
+
+ value = t;
+ }
+
+ if(types == 0)
+ errx(1, "no authentication types for '%s' (line %d)", name, line);
+
+ opts->allowed_types = types;
+ recog = 1;
+ }
+
+ else if(strcmp(name, "realm") == 0)
+ {
+ opts->realm = value;
+ recog = 1;
+ }
+
+ else if(strcmp(name, "digestignoreuri") == 0)
+ {
+ int v;
+ if(ha_confbool(name, value, &v) < 0)
+ exit(1); /* Message already printed */
+
+ opts->digest_ignoreuri = v;
+ recog = 1;
+ }
+
+ else if(strcmp(name, "digestignorenc") == 0)
+ {
+ int v;
+ if(ha_confbool(name, value, &v) < 0)
+ exit(1); /* Message already printed */
+
+ opts->digest_ignorenc = v;
+ recog = 1;
+ }
#ifdef _DEBUG
- else if(strcmp(name, "digestdebugnonce") == 0)
- {
- opts->digest_debugnonce = value;
- recog = 1;
- }
+ else if(strcmp(name, "digestdebugnonce") == 0)
+ {
+ opts->digest_debugnonce = value;
+ recog = 1;
+ }
#endif
- }
+ }
- if(!recog)
- errx(1, "unrecognized configuration setting '%s' (line %d)", name, line);
- else
- ha_messagex(LOG_DEBUG, "configuration: setting: [ %s: %s ]", name, value);
- }
+ if(!recog)
+ errx(1, "unrecognized configuration setting '%s' (line %d)", name, line);
+ else
+ ha_messagex(NULL, LOG_DEBUG, "configuration: setting: [ %s: %s ]", name, value);
+ }
- if(!g_handlers)
- ha_messagex(LOG_WARNING, "configuration: no handlers found in configuration file");
+ if(!g_handlers)
+ ha_messagex(NULL, LOG_WARNING, "configuration: no handlers found in configuration file");
- return 0;
+ return 0;
}