From 80b0e2c0fdad108454ae87130496f595f0b81b81 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Fri, 7 May 2004 22:02:29 +0000 Subject: - Reworked the internal API - Added common functions for trimming - Debugging - Reworked the module to the new protocol --- apache1x/mod_httpauth.c | 215 +++++++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 105 deletions(-) (limited to 'apache1x/mod_httpauth.c') diff --git a/apache1x/mod_httpauth.c b/apache1x/mod_httpauth.c index fae668e..39cdd8d 100644 --- a/apache1x/mod_httpauth.c +++ b/apache1x/mod_httpauth.c @@ -8,6 +8,7 @@ #include #include "sock_any.h" +#include "stringx.h" #define DEFAULT_PORT 8020 @@ -17,9 +18,9 @@ typedef struct httpauth_context { const char* socketname; int socket; - const char* method; int types; - char* authtypes; + const char* method; + const char* domain; pool* child_pool; } httpauth_context_t; @@ -68,7 +69,7 @@ static const char* set_socket(cmd_parms* cmd, void* config, const char* val) static const char* set_method(cmd_parms* cmd, void* config, const char* val) { httpauth_context_t* conf = (httpauth_context_t*)config; - conf->method = ap_pstrdup(cmd->pool, val); + conf->method = val; return NULL; } @@ -96,6 +97,13 @@ static const char* set_types(cmd_parms* cmd, void* config, const char* val) return NULL; } +static const char* set_domain(cmd_parms* cmd, void* config, const char* val) +{ + httpauth_context_t* conf = (httpauth_context_t*)config; + conf->domain = trim_space(ap_pstrdup(cmd->pool, val)); + return NULL; +} + static const command_rec httpauth_cmds[] = { { "HttpAuthSocket", set_socket, NULL, OR_AUTHCFG, TAKE1, @@ -104,6 +112,8 @@ static const command_rec httpauth_cmds[] = "The method that httpauthd should use to authenticate" }, { "HttpAuthTypes", set_types, NULL, OR_AUTHCFG, ITERATE, "The types of authentiction allowed (Basic, Digest, NTLM ...)" }, + { "HttpAuthDigestDomain", set_domain, NULL, OR_AUTHCFG, RAW_ARGS, + "The domain for which digest authentication is relevant" }, { NULL, NULL, NULL, 0, 0, NULL } }; @@ -111,32 +121,6 @@ static const command_rec httpauth_cmds[] = * Socket handling code */ -const char* trim_start(const char* data) -{ - while(*data && ap_isspace(*data)) - ++data; - return data; -} - -char* trim_end(char* data) -{ - char* t = data + strlen(data); - - while(t > data && ap_isspace(*(t - 1))) - { - t--; - *t = 0; - } - - return data; -} - -char* trim_space(char* data) -{ - data = (char*)trim_start(data); - return trim_end(data); -} - void read_junk(httpauth_context_t* ctx, request_rec* r) { char buf[16]; @@ -280,6 +264,13 @@ int read_response(httpauth_context_t* ctx, request_rec* r, if(code) *code = c; + if(c >= 400) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: received error from httpauthd: %d %s", c, line); + return -1; + } + /* Get the second response code if we're a 200 */ if(c == 200) { @@ -296,7 +287,9 @@ int read_response(httpauth_context_t* ctx, request_rec* r, *ccode = c; } - *details = trim_space(line); + if(details) + *details = trim_space(line); + return 0; } @@ -416,6 +409,46 @@ void disconnect_socket(httpauth_context_t* ctx, server_rec* s) } } +int write_data(httpauth_context_t* ctx, server_rec* s, const char* data) +{ + int r; + + if(ctx->socket == -1) + { + ap_log_error(APLOG_MARK, APLOG_ERR, s, + "httpauth: Socket to httpauthd daemon closed. Can't write data."); + return -1; + } + + while(*data != 0) + { + r = write(ctx->socket, data, strlen(data)); + + if(r > 0) + data += r; + + else if(r == -1) + { + if(errno == EAGAIN) + continue; + + /* The other end closed. no message */ + if(errno == EPIPE) + disconnect_socket(ctx, s); + + else + ap_log_error(APLOG_MARK, APLOG_ERR, s, + "httpauth: Couldn't write data to daemon"); + + errno = 0; + return -1; + } + } + + errno = 0; + return 0; +} + int connect_socket(httpauth_context_t* ctx, request_rec* r) { struct sockaddr_any sany; @@ -468,97 +501,76 @@ int connect_httpauth(httpauth_context_t* ctx, request_rec* r) if(read_response(ctx, r, &code, NULL, &details) == -1) goto finally; - if(code >= 400) + if(code != 100) { ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: received error from httpauthd: %d", code); + "httpauth: protocol error (Expected 100, got %d)", code); goto finally; } - if(code != 100) + /* Check theversion number */ + details = trim_space(details); + + if(strcmp(details, "HTTPAUTH/1.0") != 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: protocol error (Expected 100, got %d)", code); + "httpauth: Daemon speaking incompatible protocol version: %s", details); goto finally; } - /* - * Not pretty code :) In order to keep from parsing up - * the whole available types string that we get from the - * client, and keeping an array etc... we just make sure - * that the auth type requested is in the string, and - * it's on word boundaries. - */ - - t = ap_strcasestr(details, ctx->method); - if(t) + /* Send our method */ + if(ctx->method) { - /* Make sure we're at a parse mark */ - if(t == details || ap_isspace(*(t - 1))) - { - /* Make sure end is at a parse mark */ - t += strlen(ctx->method); - if(!*t || ap_isspace(*t)) - { - ap_log_rerror(APLOG_MARK, APLOG_INFO, r, - "httpauth: connected to daemon (methods: %s)", details); + t = ap_pstrcat(r->pool, "SET Method ", ctx->method, "\n", NULL); - /* We're cool! */ - ret = 0; - goto finally; - } - } - } + if(write_data(ctx, r->server, t) == -1) + goto finally; - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: The configured method '%s' is not provided by httpauthd: %s", - ctx->method, details); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "httpauth: sent method to daemon: %s", t); -finally: - if(ret == -1) - disconnect_socket(ctx, r->server); + if(read_response(ctx, r, &code, NULL, NULL) == -1) + goto finally; - return ret; -} - -int write_data(httpauth_context_t* ctx, server_rec* s, const char* data) -{ - int r; - - if(ctx->socket == -1) - { - ap_log_error(APLOG_MARK, APLOG_ERR, s, - "httpauth: Socket to httpauthd daemon closed. Can't write data."); - return -1; + if(code != 202) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol error (Expected 202, got %d)", code); + goto finally; + } } - while(*data != 0) + /* Send any setup info we have */ + if(ctx->domain) { - r = write(ctx->socket, data, strlen(data)); - - if(r > 0) - data += r; + t = ap_pstrcat(r->pool, "SET Domain ", ctx->domain, "\n", NULL); - else if(r == -1) - { - if(errno == EAGAIN) - continue; + if(write_data(ctx, r->server, t) == -1) + goto finally; - /* The other end closed. no message */ - if(errno == EPIPE) - disconnect_socket(ctx, s); + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r, + "httpauth: sent domains to daemon: %s", t); - else - ap_log_error(APLOG_MARK, APLOG_ERR, s, - "httpauth: Couldn't write data to daemon"); + if(read_response(ctx, r, &code, NULL, NULL) == -1) + goto finally; - errno = 0; - return -1; + if(code != 202) + { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "httpauth: protocol error (Expected 202, got %d)", code); + goto finally; } } - errno = 0; - return 0; + /* We're cool! */ + ret = 0; + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, "httpauth: connected to daemon"); + +finally: + if(ret == -1) + disconnect_socket(ctx, r->server); + + return ret; } int write_request(httpauth_context_t* ctx, request_rec* r) @@ -574,7 +586,7 @@ int write_request(httpauth_context_t* ctx, request_rec* r) */ /* Send the request header to httpauthd */ - t = ap_pstrcat(r->pool, "AUTH ", ctx->method, " XXX ", r->method, + t = ap_pstrcat(r->pool, "AUTH XXX ", r->method, " ", r->unparsed_uri, "\n", NULL); if(write_data(ctx, r->server, t) == -1) @@ -679,14 +691,6 @@ static int httpauth_authenticate(request_rec* r) if(read_response(ctx, r, &code, &ccode, &details) == -1) return SERVER_ERROR; - if(code >= 400 && code < 600) - { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "httpauth: received server error from httpauthd: %d%s%s%s", - code, details ? " (" : "", details ? details : "", details ? ")" : ""); - return SERVER_ERROR; - } - if(code != 200) { ap_log_rerror(APLOG_MARK, APLOG_ERR, r, @@ -756,3 +760,4 @@ module MODULE_VAR_EXPORT httpauth_module = * so we include this here */ #include "../common/sock_any.c" +#include "../common/stringx.c" -- cgit v1.2.3