summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--apache1x/mod_httpauth.c1102
-rw-r--r--configure.in41
-rw-r--r--sample/httpauthd.conf31
4 files changed, 616 insertions, 563 deletions
diff --git a/ChangeLog b/ChangeLog
index 2152415..f61e967 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
0.5
- - Postgresql support
+ - PostgreSQL support
+ - MYSQL support
+ - Fixed Base64 decoding problems
+ - Lots of bug fixes and testing
0.4.2
- Separated base handler functionality, reorganized files, code
diff --git a/apache1x/mod_httpauth.c b/apache1x/mod_httpauth.c
index 4b1abe6..9f0d491 100644
--- a/apache1x/mod_httpauth.c
+++ b/apache1x/mod_httpauth.c
@@ -16,12 +16,12 @@ module MODULE_VAR_EXPORT httpauth_module;
typedef struct httpauth_context
{
- const char* socketname;
- int socket;
- int types;
- const char* handler;
- const char* domain;
- pool* child_pool;
+ const char* socketname;
+ int socket;
+ int types;
+ const char* handler;
+ const char* domain;
+ pool* child_pool;
}
httpauth_context_t;
@@ -44,77 +44,77 @@ httpauth_context_t;
static void* httpauth_dir_config(pool* p, char* dir)
{
- httpauth_context_t* ctx;
+ httpauth_context_t* ctx;
- ctx = (httpauth_context_t*)ap_pcalloc(p, sizeof(*ctx));
- memset(ctx, 0, sizeof(*ctx));
+ ctx = (httpauth_context_t*)ap_pcalloc(p, sizeof(*ctx));
+ memset(ctx, 0, sizeof(*ctx));
- ctx->socket = -1;
- ctx->types = 0xFFFFFFFF;
- ctx->child_pool = p;
- return ctx;
+ ctx->socket = -1;
+ ctx->types = 0xFFFFFFFF;
+ ctx->child_pool = p;
+ return ctx;
}
static const char* set_socket(cmd_parms* cmd, void* config, const char* val)
{
- struct sockaddr_any sany;
+ struct sockaddr_any sany;
- if(sock_any_pton(val, &sany, DEFAULT_PORT) == -1)
- return "Invalid socket name or ip in HttpAuthSocket";
+ if(sock_any_pton(val, &sany, DEFAULT_PORT) == -1)
+ return "Invalid socket name or ip in HttpAuthSocket";
- ((httpauth_context_t*)config)->socketname = val;
- return NULL;
+ ((httpauth_context_t*)config)->socketname = val;
+ return NULL;
}
static const char* set_handler(cmd_parms* cmd, void* config, const char* val)
{
- httpauth_context_t* conf = (httpauth_context_t*)config;
- conf->handler = val;
- return NULL;
+ httpauth_context_t* conf = (httpauth_context_t*)config;
+ conf->handler = val;
+ return NULL;
}
static const char* set_types(cmd_parms* cmd, void* config, const char* val)
{
- httpauth_context_t* conf = (httpauth_context_t*)config;
- int type = 0;
-
- if(strcasecmp(val, AUTH_PREFIX_BASIC) == 0)
- type = AUTH_TYPE_BASIC;
- else if(strcasecmp(val, AUTH_PREFIX_DIGEST) == 0)
- type = AUTH_TYPE_DIGEST;
- else if(strcasecmp(val, AUTH_PREFIX_NTLM) == 0)
- type = AUTH_TYPE_NTLM;
- else if(strcasecmp(val, "any"))
- type = AUTH_TYPE_ANY;
- else
- return "Invalid type in HttpAuthTypes";
-
- if(conf->types == 0xFFFFFFFF)
- conf->types = type;
- else
- conf->types |= type;
-
- return NULL;
+ httpauth_context_t* conf = (httpauth_context_t*)config;
+ int type = 0;
+
+ if(strcasecmp(val, AUTH_PREFIX_BASIC) == 0)
+ type = AUTH_TYPE_BASIC;
+ else if(strcasecmp(val, AUTH_PREFIX_DIGEST) == 0)
+ type = AUTH_TYPE_DIGEST;
+ else if(strcasecmp(val, AUTH_PREFIX_NTLM) == 0)
+ type = AUTH_TYPE_NTLM;
+ else if(strcasecmp(val, "any"))
+ type = AUTH_TYPE_ANY;
+ else
+ return "Invalid type in HttpAuthTypes";
+
+ if(conf->types == 0xFFFFFFFF)
+ conf->types = type;
+ else
+ conf->types |= type;
+
+ 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;
+ 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,
- "The socket that httpauthd is listening on" },
- { "HttpAuthHandler", set_handler, NULL, OR_AUTHCFG, TAKE1,
- "The handler 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 }
+ { "HttpAuthSocket", set_socket, NULL, OR_AUTHCFG, TAKE1,
+ "The socket that httpauthd is listening on" },
+ { "HttpAuthHandler", set_handler, NULL, OR_AUTHCFG, TAKE1,
+ "The handler 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 }
};
/* -------------------------------------------------------------------------------
@@ -123,653 +123,653 @@ static const command_rec httpauth_cmds[] =
void read_junk(httpauth_context_t* ctx, request_rec* r)
{
- char buf[16];
- const char* t;
- int said = 0;
- int l;
-
- if(ctx->socket == -1)
- return;
+ char buf[16];
+ const char* t;
+ int said = 0;
+ int l;
- /* Make it non blocking */
- fcntl(ctx->socket, F_SETFL, fcntl(ctx->socket, F_GETFL, 0) | O_NONBLOCK);
+ if(ctx->socket == -1)
+ return;
- for(;;)
- {
- l = read(ctx->socket, buf, sizeof(buf) - 1);
- if(l <= 0)
- break;
+ /* Make it non blocking */
+ fcntl(ctx->socket, F_SETFL, fcntl(ctx->socket, F_GETFL, 0) | O_NONBLOCK);
- buf[l] = 0;
- t = trim_start(buf);
-
- if(!said && *t)
+ for(;;)
{
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
- "httpauth: received junk data from daemon");
- said = 1;
+ l = read(ctx->socket, buf, sizeof(buf) - 1);
+ if(l <= 0)
+ break;
+
+ buf[l] = 0;
+ t = trim_start(buf);
+
+ if(!said && *t)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
+ "httpauth: received junk data from daemon");
+ said = 1;
+ }
}
- }
- fcntl(ctx->socket, F_SETFL, fcntl(ctx->socket, F_GETFL, 0) & ~O_NONBLOCK);
- errno = 0;
+ fcntl(ctx->socket, F_SETFL, fcntl(ctx->socket, F_GETFL, 0) & ~O_NONBLOCK);
+ errno = 0;
}
int read_line(httpauth_context_t* ctx, request_rec* r, char** line)
{
- int l;
- int al = 128;
- char* t;
- const char* e;
+ int l;
+ int al = 128;
+ char* t;
+ const char* e;
- e = t = NULL;
- *line = NULL;
+ e = t = NULL;
+ *line = NULL;
- for(;;)
- {
- if(!*line || t + 2 == e)
+ for(;;)
{
- char* n;
- int d;
-
- n = (char*)ap_palloc(r->pool, al * 2);
-
- if(*line)
- memcpy(n, *line, al);
+ if(!*line || t + 2 == e)
+ {
+ char* n;
+ int d;
+
+ n = (char*)ap_palloc(r->pool, al * 2);
+
+ if(*line)
+ memcpy(n, *line, al);
+
+ al *= 2;
+
+ /* The difference */
+ d = t - *line;
+
+ *line = n;
+ t = n + d;
+ e = n + al;
+ }
+
+ l = read(ctx->socket, (void*)t, sizeof(char));
+
+ /* We got a character */
+ if(l == 1)
+ {
+ /* Skip junky CRLFs */
+ if(*t == '\r')
+ {
+ *t = ' ';
+ continue;
+ }
+
+ /* End of line */
+ else if(*t == '\n')
+ {
+ t++;
+ break;
+ }
+
+ t++;
+ }
+
+ /* If it's the end of file then return that */
+ else if(l == 0)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: unexpected end of data from daemon");
+ return -1;
+ }
+
+ /* Transient errors */
+ else if(l == -1 && errno == EAGAIN)
+ continue;
+
+ /* Fatal errors */
+ else if(l == -1)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: couldn't read data from daemon");
+ return -1;
+ }
+ }
- al *= 2;
+ *t = 0;
+ errno = 0;
+ return 0;
+}
- /* The difference */
- d = t - *line;
+int read_response(httpauth_context_t* ctx, request_rec* r,
+ int* code, int* ccode, char** details)
+{
+ int c;
+ char* line;
+ char* t;
+ char* t2;
- *line = n;
- t = n + d;
- e = n + al;
- }
+ if(read_line(ctx, r, &line) == -1)
+ return -1;
- l = read(ctx->socket, (void*)t, sizeof(char));
+ line = trim_space(line);
- /* We got a character */
- if(l == 1)
- {
- /* Skip junky CRLFs */
- if(*t == '\r')
- {
- *t = ' ';
- continue;
- }
-
- /* End of line */
- else if(*t == '\n')
- {
- t++;
- break;
- }
-
- t++;
- }
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "httpauth: received response line from daemon: %s", line);
- /* If it's the end of file then return that */
- else if(l == 0)
+ /* Get response code */
+ t = ap_getword_nc(r->pool, &line, ' ');
+ c = strtol(t, &t2, 10);
+ if(*t2 || c < 100 || c > 999)
{
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: unexpected end of data from daemon");
- return -1;
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: protocol error: invalid code: %s", t);
+ return -1;
}
- /* Transient errors */
- else if(l == -1 && errno == EAGAIN)
- continue;
+ if(code)
+ *code = c;
- /* Fatal errors */
- else if(l == -1)
+ if(c >= 400)
{
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: couldn't read data from daemon");
- return -1;
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: received error from httpauthd: %d %s", c, line);
+ return -1;
}
- }
- *t = 0;
- errno = 0;
- return 0;
-}
-
-int read_response(httpauth_context_t* ctx, request_rec* r,
- int* code, int* ccode, char** details)
-{
- int c;
- char* line;
- char* t;
- char* t2;
-
- if(read_line(ctx, r, &line) == -1)
- return -1;
-
- line = trim_space(line);
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
- "httpauth: received response line from daemon: %s", line);
-
- /* Get response code */
- t = ap_getword_nc(r->pool, &line, ' ');
- c = strtol(t, &t2, 10);
- if(*t2 || c < 100 || c > 999)
- {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: protocol error: invalid code: %s", t);
- return -1;
- }
-
- 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)
- {
- t = ap_getword_nc(r->pool, &line, ' ');
- c = strtol(t, &t2, 10);
- if(*t2 || c < 100 || c > 999)
+ /* Get the second response code if we're a 200 */
+ if(c == 200)
{
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: protocol error: invalid code: %s", t);
- return -1;
+ t = ap_getword_nc(r->pool, &line, ' ');
+ c = strtol(t, &t2, 10);
+ if(*t2 || c < 100 || c > 999)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: protocol error: invalid code: %s", t);
+ return -1;
+ }
+
+ if(ccode)
+ *ccode = c;
}
- if(ccode)
- *ccode = c;
- }
+ if(details)
+ *details = trim_space(line);
- if(details)
- *details = trim_space(line);
-
- return 0;
+ return 0;
}
int read_copy_headers(httpauth_context_t* ctx, int ccode, request_rec* r)
{
- char* line;
- const char* name;
- table* headers;
- int c = 0;
-
- if(ccode > 299)
- headers = r->err_headers_out;
- else
- headers = r->headers_out;
-
- for(;;)
- {
- if(read_line(ctx, r, &line) == -1)
- return -1;
+ char* line;
+ const char* name;
+ table* headers;
+ int c = 0;
- /* If that's it then break */
- if(!*line)
- break;
+ if(ccode > 299)
+ headers = r->err_headers_out;
+ else
+ headers = r->headers_out;
- if(ap_isspace(*line))
+ for(;;)
{
- line = (char*)trim_start(line);
+ if(read_line(ctx, r, &line) == -1)
+ return -1;
+
+ /* If that's it then break */
+ if(!*line)
+ break;
+
+ if(ap_isspace(*line))
+ {
+ line = (char*)trim_start(line);
+
+ /* End of headers */
+ if(!*line)
+ break;
+
+ if(c > 0)
+ {
+ /*
+ * TODO: We really should be supporting headers split
+ * across lines. But httpauthd doesn't currently produce
+ * headers like that, so we don't need to care about it.
+ */
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
+ "httpauth: protocol error: server sent us an split header, which we don't support.");
+ }
+ else
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: protocol error: invalid headers.");
+ }
+ }
+
+ name = ap_getword_nc(r->pool, &line, ':');
+ if(!name || !*name)
+ break;
- /* End of headers */
- if(!*line)
- break;
-
- if(c > 0)
- {
/*
- * TODO: We really should be supporting headers split
- * across lines. But httpauthd doesn't currently produce
- * headers like that, so we don't need to care about it.
+ * If that was the end of the line, then it's an
+ * invalid header :(
*/
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
- "httpauth: protocol error: server sent us an split header, which we don't support.");
- }
- else
- {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: protocol error: invalid headers.");
- }
+ if(!*line)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: protocol header: invalid headers");
+ return -1;
+ }
+
+ line = trim_space(line);
+
+ if(strcasecmp(name, "WWW-Authenticate") == 0)
+ {
+ if(strncasecmp(line, AUTH_PREFIX_BASIC, strlen(AUTH_PREFIX_BASIC)) == 0 &&
+ !(ctx->types & AUTH_TYPE_BASIC))
+ continue;
+
+ else if(strncasecmp(line, AUTH_PREFIX_DIGEST, strlen(AUTH_PREFIX_DIGEST)) == 0 &&
+ !(ctx->types & AUTH_TYPE_DIGEST))
+ continue;
+
+ else if(strncasecmp(line, AUTH_PREFIX_NTLM, strlen(AUTH_PREFIX_NTLM)) == 0 &&
+ !(ctx->types & AUTH_TYPE_NTLM))
+ continue;
+
+ /* Only allow unknown if we don't have it */
+ else if(!(ctx->types & AUTH_TYPE_ANY))
+ continue;
+
+ /* Fix up when we're a proxy */
+ if(r->proxyreq == STD_PROXY)
+ name = "Proxy-Authenticate";
+ }
+
+ else if(strcasecmp(name, "Authentication-Info") == 0)
+ {
+ if(r->proxyreq == STD_PROXY)
+ name = "Proxy-Authentication-Info";
+ }
+
+ c++;
+ ap_table_addn(headers, name, line);
}
- name = ap_getword_nc(r->pool, &line, ':');
- if(!name || !*name)
- break;
-
- /*
- * If that was the end of the line, then it's an
- * invalid header :(
- */
- if(!*line)
- {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: protocol header: invalid headers");
- return -1;
- }
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "httpauth: received %d headers from daemon", c);
- line = trim_space(line);
+ return 0;
+}
- if(strcasecmp(name, "WWW-Authenticate") == 0)
+void disconnect_socket(httpauth_context_t* ctx, server_rec* s)
+{
+ if(ctx->socket != -1)
{
- if(strncasecmp(line, AUTH_PREFIX_BASIC, strlen(AUTH_PREFIX_BASIC)) == 0 &&
- !(ctx->types & AUTH_TYPE_BASIC))
- continue;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, s,
+ "httpauth: disconnecting from daemon");
- else if(strncasecmp(line, AUTH_PREFIX_DIGEST, strlen(AUTH_PREFIX_DIGEST)) == 0 &&
- !(ctx->types & AUTH_TYPE_DIGEST))
- continue;
-
- else if(strncasecmp(line, AUTH_PREFIX_NTLM, strlen(AUTH_PREFIX_NTLM)) == 0 &&
- !(ctx->types & AUTH_TYPE_NTLM))
- continue;
+ /* TODO: Should we be closing this nicely somewhere? */
+ ap_pclosesocket(ctx->child_pool, ctx->socket);
+ ctx->socket = -1;
+ errno = 0;
+ }
+}
- /* Only allow unknown if we don't have it */
- else if(!(ctx->types & AUTH_TYPE_ANY))
- continue;
+int write_data(httpauth_context_t* ctx, server_rec* s, const char* data)
+{
+ int r;
- /* Fix up when we're a proxy */
- if(r->proxyreq == STD_PROXY)
- name = "Proxy-Authenticate";
+ if(ctx->socket == -1)
+ {
+ ap_log_error(APLOG_MARK, APLOG_ERR, s,
+ "httpauth: Socket to httpauthd daemon closed. Can't write data.");
+ return -1;
}
- else if(strcasecmp(name, "Authentication-Info") == 0)
+ while(*data != 0)
{
- if(r->proxyreq == STD_PROXY)
- name = "Proxy-Authentication-Info";
- }
+ r = write(ctx->socket, data, strlen(data));
- c++;
- ap_table_addn(headers, name, line);
- }
+ if(r > 0)
+ data += r;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
- "httpauth: received %d headers from daemon", c);
+ else if(r == -1)
+ {
+ if(errno == EAGAIN)
+ continue;
- return 0;
-}
+ /* The other end closed. no message */
+ if(errno == EPIPE)
+ disconnect_socket(ctx, s);
-void disconnect_socket(httpauth_context_t* ctx, server_rec* s)
-{
- if(ctx->socket != -1)
- {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, s,
- "httpauth: disconnecting from daemon");
+ else
+ ap_log_error(APLOG_MARK, APLOG_ERR, s,
+ "httpauth: Couldn't write data to daemon");
+
+ errno = 0;
+ return -1;
+ }
+ }
- /* TODO: Should we be closing this nicely somewhere? */
- ap_pclosesocket(ctx->child_pool, ctx->socket);
- ctx->socket = -1;
errno = 0;
- }
+ return 0;
}
-int write_data(httpauth_context_t* ctx, server_rec* s, const char* data)
+int connect_socket(httpauth_context_t* ctx, request_rec* r)
{
- 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;
- }
+ struct sockaddr_any sany;
+ int ret = -1;
- while(*data != 0)
- {
- r = write(ctx->socket, data, strlen(data));
-
- if(r > 0)
- data += r;
+ disconnect_socket(ctx, r->server);
- else if(r == -1)
+ if(sock_any_pton(ctx->socketname, &sany, DEFAULT_PORT) == -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");
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, r,
+ "httpauth: Invalid socket name or ip.");
+ goto finally;
+ }
- errno = 0;
- return -1;
+ ctx->socket = ap_psocket(ctx->child_pool, SANY_TYPE(sany), SOCK_STREAM, 0);
+ if(ctx->socket == -1)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, r,
+ "httpauth: Can't create socket: %s", ctx->socketname);
+ goto finally;
}
- }
- errno = 0;
- return 0;
-}
+ if(connect(ctx->socket, &SANY_ADDR(sany), SANY_LEN(sany)) != 0)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, r,
+ "httpauth: Can't connect to httpauthd");
+ goto finally;
+ }
-int connect_socket(httpauth_context_t* ctx, request_rec* r)
-{
- struct sockaddr_any sany;
- int ret = -1;
-
- disconnect_socket(ctx, r->server);
-
- if(sock_any_pton(ctx->socketname, &sany, DEFAULT_PORT) == -1)
- {
- ap_log_rerror(APLOG_MARK, APLOG_CRIT, r,
- "httpauth: Invalid socket name or ip.");
- goto finally;
- }
-
- ctx->socket = ap_psocket(ctx->child_pool, SANY_TYPE(sany), SOCK_STREAM, 0);
- if(ctx->socket == -1)
- {
- ap_log_rerror(APLOG_MARK, APLOG_CRIT, r,
- "httpauth: Can't create socket: %s", ctx->socketname);
- goto finally;
- }
-
- if(connect(ctx->socket, &SANY_ADDR(sany), SANY_LEN(sany)) != 0)
- {
- ap_log_rerror(APLOG_MARK, APLOG_CRIT, r,
- "httpauth: Can't connect to httpauthd");
- goto finally;
- }
-
- ret = 0;
+ ret = 0;
finally:
- if(ret == -1)
- disconnect_socket(ctx, r->server);
+ if(ret == -1)
+ disconnect_socket(ctx, r->server);
- errno = 0;
- return ret;
+ errno = 0;
+ return ret;
}
int connect_httpauth(httpauth_context_t* ctx, request_rec* r)
{
- int ret = -1;
- int code;
- char* details;
- const char* t;
-
- if(connect_socket(ctx, r) == -1)
- goto finally;
-
- if(read_response(ctx, r, &code, NULL, &details) == -1)
- goto finally;
-
- if(code != 100)
- {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: protocol error (Expected 100, got %d)", code);
- goto finally;
- }
-
- /* Check theversion number */
- details = trim_space(details);
-
- if(strcmp(details, "HTTPAUTH/1.0") != 0)
- {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: Daemon speaking incompatible protocol version: %s", details);
- goto finally;
- }
-
- /* Send our handler */
- if(ctx->handler)
- {
- t = ap_pstrcat(r->pool, "SET Handler ", ctx->handler, "\n", NULL);
+ int ret = -1;
+ int code;
+ char* details;
+ const char* t;
- if(write_data(ctx, r->server, t) == -1)
- goto finally;
+ if(connect_socket(ctx, r) == -1)
+ goto finally;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
- "httpauth: sent handler to daemon: %s", t);
+ if(read_response(ctx, r, &code, NULL, &details) == -1)
+ goto finally;
- if(read_response(ctx, r, &code, NULL, NULL) == -1)
- goto finally;
+ if(code != 100)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: protocol error (Expected 100, got %d)", code);
+ goto finally;
+ }
+
+ /* Check theversion number */
+ details = trim_space(details);
- if(code != 202)
+ if(strcmp(details, "HTTPAUTH/1.0") != 0)
{
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: protocol error (Expected 202, got %d)", code);
- goto finally;
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: Daemon speaking incompatible protocol version: %s", details);
+ goto finally;
}
- }
- /* Send any setup info we have */
- if(ctx->domain)
- {
- t = ap_pstrcat(r->pool, "SET Domain ", ctx->domain, "\n", NULL);
+ /* Send our handler */
+ if(ctx->handler)
+ {
+ t = ap_pstrcat(r->pool, "SET Handler ", ctx->handler, "\n", NULL);
- if(write_data(ctx, r->server, t) == -1)
- goto finally;
+ if(write_data(ctx, r->server, t) == -1)
+ goto finally;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
- "httpauth: sent domains to daemon: %s", t);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "httpauth: sent handler to daemon: %s", t);
- if(read_response(ctx, r, &code, NULL, NULL) == -1)
- goto finally;
+ if(read_response(ctx, r, &code, NULL, NULL) == -1)
+ goto finally;
- if(code != 202)
+ if(code != 202)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: protocol error (Expected 202, got %d)", code);
+ goto finally;
+ }
+ }
+
+ /* Send any setup info we have */
+ if(ctx->domain)
{
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: protocol error (Expected 202, got %d)", code);
- goto finally;
+ t = ap_pstrcat(r->pool, "SET Domain ", ctx->domain, "\n", NULL);
+
+ if(write_data(ctx, r->server, t) == -1)
+ goto finally;
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "httpauth: sent domains to daemon: %s", t);
+
+ if(read_response(ctx, r, &code, NULL, NULL) == -1)
+ goto finally;
+
+ if(code != 202)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: protocol error (Expected 202, got %d)", code);
+ goto finally;
+ }
}
- }
- /* We're cool! */
- ret = 0;
- ap_log_rerror(APLOG_MARK, APLOG_INFO, r, "httpauth: connected to daemon");
+ /* 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);
+ if(ret == -1)
+ disconnect_socket(ctx, r->server);
- return ret;
+ return ret;
}
int write_request(httpauth_context_t* ctx, request_rec* r)
{
- int i, c = 0;
- const char* t;
- const array_header* hdrs_arr;
- const table_entry* elts;
+ int i, c = 0;
+ const char* t;
+ const array_header* hdrs_arr;
+ const table_entry* elts;
- /*
- * TODO: We need to use a valid connection id for
- * NTLM connections to work properly.
- */
-
- /* Send the request header to httpauthd */
- t = ap_pstrcat(r->pool, "AUTH XXX ", r->method,
- " ", r->unparsed_uri, "\n", NULL);
+ /*
+ * TODO: We need to use a valid connection id for
+ * NTLM connections to work properly.
+ */
- if(write_data(ctx, r->server, t) == -1)
- return -1;
+ /* Send the request header to httpauthd */
+ t = ap_pstrcat(r->pool, "AUTH XXX ", r->method,
+ " ", r->unparsed_uri, "\n", NULL);
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
- "httpauth: sent auth request to daemon: %s", t);
+ if(write_data(ctx, r->server, t) == -1)
+ return -1;
- /* Now send the headers to httpauthd */
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "httpauth: sent auth request to daemon: %s", t);
- hdrs_arr = ap_table_elts(r->headers_in);
- elts = (const table_entry*)hdrs_arr->elts;
+ /* Now send the headers to httpauthd */
- for(i = 0; i < hdrs_arr->nelts; i++)
- {
- if(!elts[i].val)
- continue;
+ hdrs_arr = ap_table_elts(r->headers_in);
+ elts = (const table_entry*)hdrs_arr->elts;
- /* Filter out headers we don't want */
- if(strcasecmp(elts[i].key, r->proxyreq == STD_PROXY ?
- "Proxy-Authorization" : "Authorization") == 0)
+ for(i = 0; i < hdrs_arr->nelts; i++)
{
- t = trim_start(elts[i].val);
+ if(!elts[i].val)
+ continue;
- if(strncasecmp(t, AUTH_PREFIX_BASIC, strlen(AUTH_PREFIX_BASIC)) == 0 &&
- !(ctx->types & AUTH_TYPE_BASIC))
- continue;
+ /* Filter out headers we don't want */
+ if(strcasecmp(elts[i].key, r->proxyreq == STD_PROXY ?
+ "Proxy-Authorization" : "Authorization") == 0)
+ {
+ t = trim_start(elts[i].val);
- else if(strncasecmp(t, AUTH_PREFIX_DIGEST, strlen(AUTH_PREFIX_DIGEST)) == 0 &&
- !(ctx->types & AUTH_TYPE_DIGEST))
- continue;
+ if(strncasecmp(t, AUTH_PREFIX_BASIC, strlen(AUTH_PREFIX_BASIC)) == 0 &&
+ !(ctx->types & AUTH_TYPE_BASIC))
+ continue;
- else if(strncasecmp(t, AUTH_PREFIX_NTLM, strlen(AUTH_PREFIX_NTLM)) == 0 &&
- !(ctx->types & AUTH_TYPE_NTLM))
- continue;
+ else if(strncasecmp(t, AUTH_PREFIX_DIGEST, strlen(AUTH_PREFIX_DIGEST)) == 0 &&
+ !(ctx->types & AUTH_TYPE_DIGEST))
+ continue;
- /* Only allow unknown if we don't have it */
- else if(!(ctx->types & AUTH_TYPE_ANY))
- continue;
+ else if(strncasecmp(t, AUTH_PREFIX_NTLM, strlen(AUTH_PREFIX_NTLM)) == 0 &&
+ !(ctx->types & AUTH_TYPE_NTLM))
+ continue;
- /* Extra blank line when at end */
- t = ap_pstrcat(r->pool, "Authorization: ", elts[i].val, "\n", NULL);
+ /* Only allow unknown if we don't have it */
+ else if(!(ctx->types & AUTH_TYPE_ANY))
+ continue;
- if(write_data(ctx, r->server, t) == -1)
- return SERVER_ERROR;
+ /* Extra blank line when at end */
+ t = ap_pstrcat(r->pool, "Authorization: ", elts[i].val, "\n", NULL);
- c++;
+ if(write_data(ctx, r->server, t) == -1)
+ return SERVER_ERROR;
+
+ c++;
+ }
}
- }
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
- "httpauth: sent %d headers to daemon", c);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, r,
+ "httpauth: sent %d headers to daemon", c);
- return write_data(ctx, r->server, "\n");
+ return write_data(ctx, r->server, "\n");
}
static int httpauth_authenticate(request_rec* r)
{
- httpauth_context_t* ctx;
- const char* authtype;
- int code = 0;
- int ccode = 0;
- char* details = NULL;
- request_rec* mainreq;
- int retried = 0;
-
- /* Make sure it's for us */
- if(!(authtype = ap_auth_type(r)) || strcasecmp(HTTPAUTH_AUTHTYPE, authtype) != 0)
- return DECLINED;
-
- ctx = (httpauth_context_t*)ap_get_module_config(r->per_dir_config,
+ httpauth_context_t* ctx;
+ const char* authtype;
+ int code = 0;
+ int ccode = 0;
+ char* details = NULL;
+ request_rec* mainreq;
+ int retried = 0;
+
+ /* Make sure it's for us */
+ if(!(authtype = ap_auth_type(r)) || strcasecmp(HTTPAUTH_AUTHTYPE, authtype) != 0)
+ return DECLINED;
+
+ ctx = (httpauth_context_t*)ap_get_module_config(r->per_dir_config,
&httpauth_module);
- if(!ctx->socketname || !ctx->handler)
- return DECLINED;
+ if(!ctx->socketname || !ctx->handler)
+ return DECLINED;
- mainreq = r;
+ mainreq = r;
- while(mainreq->main != NULL)
- mainreq = mainreq->main;
+ while(mainreq->main != NULL)
+ mainreq = mainreq->main;
- while(mainreq->prev != NULL)
- mainreq = mainreq->prev;
+ while(mainreq->prev != NULL)
+ mainreq = mainreq->prev;
- /* Check if we've already authenticated this request */
- if(ap_get_module_config(mainreq->request_config, &httpauth_module))
- return OK;
+ /* Check if we've already authenticated this request */
+ if(ap_get_module_config(mainreq->request_config, &httpauth_module))
+ return OK;
/* For jumping to when a connection has been closed */
retry:
- if(ctx->socket == -1)
- {
- if(connect_httpauth(ctx, r) == -1)
- return SERVER_ERROR;
- }
+ if(ctx->socket == -1)
+ {
+ if(connect_httpauth(ctx, r) == -1)
+ return SERVER_ERROR;
+ }
- /* Make sure we're starting on a clean slate */
- read_junk(ctx, r);
+ /* Make sure we're starting on a clean slate */
+ read_junk(ctx, r);
- /* Send off a request */
- if(write_request(ctx, r) == -1)
- {
- /*
- * If our connection was closed by httpauthd then this
- * is where we get the error. Just do one retry to
- * try and reconnect. This happens often when restarting
- * httpauthd.
- */
-
- if(ctx->socket == -1 && !retried)
+ /* Send off a request */
+ if(write_request(ctx, r) == -1)
{
- retried = 1;
- goto retry;
- }
+ /*
+ * If our connection was closed by httpauthd then this
+ * is where we get the error. Just do one retry to
+ * try and reconnect. This happens often when restarting
+ * httpauthd.
+ */
- return SERVER_ERROR;
- }
+ if(ctx->socket == -1 && !retried)
+ {
+ retried = 1;
+ goto retry;
+ }
- /* Read a response line */
- if(read_response(ctx, r, &code, &ccode, &details) == -1)
- return SERVER_ERROR;
+ return SERVER_ERROR;
+ }
- if(code != 200)
- {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "httpauth: protocol error: unexpected code: %d", code);
- return SERVER_ERROR;
- }
+ /* Read a response line */
+ if(read_response(ctx, r, &code, &ccode, &details) == -1)
+ return SERVER_ERROR;
- /* Copy over other headers */
- if(read_copy_headers(ctx, ccode, r) == -1)
- return SERVER_ERROR;
+ if(code != 200)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "httpauth: protocol error: unexpected code: %d", code);
+ return SERVER_ERROR;
+ }
- if(ccode == 200)
- {
- ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
- "httpauth: successful authentication for user: %s", details);
+ /* Copy over other headers */
+ if(read_copy_headers(ctx, ccode, r) == -1)
+ return SERVER_ERROR;
- (char*)(r->connection->user) = ap_pstrdup(r->connection->pool, details);
- r->connection->ap_auth_type = HTTPAUTH_AUTHTYPE;
+ if(ccode == 200)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
+ "httpauth: successful authentication for user: %s", details);
- /* Mark request as successfully authenticated */
- ap_set_module_config(r->request_config, &httpauth_module, details);
- return OK;
- }
+ (char*)(r->connection->user) = ap_pstrdup(r->connection->pool, details);
+ r->connection->ap_auth_type = HTTPAUTH_AUTHTYPE;
- return ccode;
+ /* Mark request as successfully authenticated */
+ ap_set_module_config(r->request_config, &httpauth_module, details);
+ return OK;
+ }
+
+ return ccode;
}
static int httpauth_access(request_rec *r)
{
- /* TODO: We need to support require directives */
- return OK;
+ /* TODO: We need to support require directives */
+ return OK;
}
/* Dispatch list for API hooks */
module MODULE_VAR_EXPORT httpauth_module =
{
STANDARD_MODULE_STUFF,
- NULL, /* module initializer */
- httpauth_dir_config, /* create per-dir config structures */
- NULL, /* merge per-dir config structures */
- NULL, /* create per-server config structures */
- NULL, /* merge per-server config structures */
- httpauth_cmds, /* table of config file commands */
- NULL, /* [#8] MIME-typed-dispatched handlers */
- NULL, /* [#1] URI to filename translation */
- httpauth_authenticate, /* [#4] validate user id from request */
- httpauth_access, /* [#5] check if the user is ok _here_ */
- NULL, /* [#3] check access by host address */
- NULL, /* [#6] determine MIME type */
- NULL, /* [#7] pre-run fixups */
- NULL, /* [#9] log a transaction */
- NULL, /* [#2] header parser */
- NULL, /* child_init */
- NULL, /* child_exit */
- NULL /* [#0] post read-request */
+ NULL, /* module initializer */
+ httpauth_dir_config, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ NULL, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ httpauth_cmds, /* table of config file commands */
+ NULL, /* [#8] MIME-typed-dispatched handlers */
+ NULL, /* [#1] URI to filename translation */
+ httpauth_authenticate, /* [#4] validate user id from request */
+ httpauth_access, /* [#5] check if the user is ok _here_ */
+ NULL, /* [#3] check access by host address */
+ NULL, /* [#6] determine MIME type */
+ NULL, /* [#7] pre-run fixups */
+ NULL, /* [#9] log a transaction */
+ NULL, /* [#2] header parser */
+ NULL, /* child_init */
+ NULL, /* child_exit */
+ NULL /* [#0] post read-request */
#ifdef EAPI
- ,NULL, /* EAPI: add_module */
- NULL, /* EAPI: remove_module */
- NULL, /* EAPI: rewrite_command */
- NULL /* EAPI: new_connection */
+ ,NULL, /* EAPI: add_module */
+ NULL, /* EAPI: remove_module */
+ NULL, /* EAPI: rewrite_command */
+ NULL /* EAPI: new_connection */
#endif
};
diff --git a/configure.in b/configure.in
index 6fc6add..ebe14cd 100644
--- a/configure.in
+++ b/configure.in
@@ -36,8 +36,8 @@ dnl Nate Nielsen <nielsen@memberwebs.com>
dnl
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(httpauth, 0.4.2, nielsen@memberwebs.com)
-AM_INIT_AUTOMAKE(httpauth, 0.4.2)
+AC_INIT(httpauth, 0.5, nielsen@memberwebs.com)
+AM_INIT_AUTOMAKE(httpauth, 0.5)
LDFLAGS="$LDFLAGS -L/usr/local/lib"
CFLAGS="$CFLAGS -I/usr/local/include -g -O0"
@@ -64,6 +64,8 @@ fi
# Check for the various options
AC_ARG_WITH(ldap, [ --with-ldap with LDAP support])
+AC_ARG_WITH(pgsql, [ --with-pgsql with Postgres support])
+AC_ARG_WITH(ldap, [ --with-mysql with MYSQL support])
AC_ARG_ENABLE(ntlm, [ --enable-ntlm enable NTLM support])
# TODO: Figure out why we need this wierd hack
@@ -95,7 +97,7 @@ AC_CHECK_DECL(PTHREAD_MUTEX_ERRORCHECK_NP, [AC_DEFINE(HAVE_ERR_MUTEX, 1, "Error
AC_CHECK_FUNCS([memset strerror malloc realloc getopt strchr tolower getaddrinfo], ,
[echo "ERROR: Required function missing"; exit 1])
AC_CHECK_FUNCS([strlwr])
-
+
# LDAP support
AM_CONDITIONAL(WITH_LDAP, test -n "$with_ldap")
if test -n "$with_ldap"; then
@@ -104,7 +106,7 @@ if test -n "$with_ldap"; then
if test "$with_ldap" != "yes"; then
LDFLAGS="$LDFLAGS -L$with_ldap/lib"
- CFLAGS="$CFLAGS -L$with_ldap/include"
+ CFLAGS="$CFLAGS -I$with_ldap/include"
fi
AC_CHECK_LIB([ldap], [ldap_init], ,
@@ -122,7 +124,7 @@ if test -n "$with_pgsql"; then
if test "$with_pgsql" != "yes"; then
LDFLAGS="$LDFLAGS -L$with_pgsql/lib"
- CFLAGS="$CFLAGS -L$with_pgsql/include"
+ CFLAGS="$CFLAGS -I$with_pgsql/include"
fi
AC_CHECK_LIB([pq], [PQexec], ,
@@ -132,6 +134,35 @@ if test -n "$with_pgsql"; then
AC_DEFINE_UNQUOTED(WITH_PGSQL, 1, [With PGSQL Support] )
fi
+# MYSQL support
+
+AM_CONDITIONAL(WITH_MYSQL, test -n "$with_mysql")
+if test -n "$with_mysql"; then
+
+ echo "enabling MYSQL support"
+
+ if test "$with_mysql" != "yes"; then
+
+ MYSQL_LIBS="-L$with_mysql/lib -L$with_mysql/lib/mysql -lz"
+ MYSQL_CFLAGS="-I$with_mysql/include -I$with_mysql/include/mysql"
+
+ else
+
+ AC_CHECK_MYSQL
+
+ fi
+
+ # MYSQL really sucks when it comes to all of this
+ LDFLAGS="$LDFLAGS `echo $MYSQL_LIBS | sed -e "s/'//g"`"
+ CFLAGS="$CFLAGS `echo $MYSQL_CFLAGS | sed -e "s/'//g"`"
+
+ AC_CHECK_LIB([mysqlclient], [mysql_init], ,
+ [ echo "ERROR: MYSQL mysqlclient library required."; exit 1] )
+
+ AC_CHECK_HEADERS(mysql.h)
+ AC_DEFINE_UNQUOTED(WITH_MYSQL, 1, [With MYSQL Support] )
+fi
+
# NTLM Support
AM_CONDITIONAL(WITH_NTLM, test -n "$enable_ntlm")
if test -n "$enable_ntlm"; then
diff --git a/sample/httpauthd.conf b/sample/httpauthd.conf
index f9481d2..19b168b 100644
--- a/sample/httpauthd.conf
+++ b/sample/httpauthd.conf
@@ -5,27 +5,46 @@ MaxThreads: 18
CacheTimeout: 300
# AuthTypes: Digest
AuthTypes: Basic Digest
+# AuthTypes: Basic
Socket: 0.0.0.0
# DigestIgnoreNC: True
-[Simple:UDB]
+[Simple:UDBsim]
Realm: blah
PasswordFile: /data/projects/httpauth/sample/passwd.file
-[LDAP]
+[LDAP:UDBldap]
Realm: blah
LDAPServers: authdev.ws.local
LDAPDoBind: False
LDAPDNMap: cn=%u,ou=test,dc=fam
-# DigestDomains: http://test.ws.local/
LDAPUser: cn=root,dc=fam
LDAPPassword: ldaptest@@password
-# LDAPHA1Attr: login
+LDAPHA1Attr: clearPassword
LDAPPWAttr: clearPassword
-DigestDebugNonce: AkCLQA==560f26e24db2d4cecbe5d6e24d958377ab73def9
-
+# DigestDebugNonce: AkCLQA==560f26e24db2d4cecbe5d6e24d958377ab73def9
LDAPFilter: (cn=%u)
LDAPBase: dc=fam
LDAPScope: sub
+[PGSQL:UDBpg]
+Realm: blah
+DBServer: sean-2
+DBUser: testuser
+DBPassword: testuser
+DBDatabase: test
+DBQuery: SELECT * from testauth WHERE username = '%u';
+# DBPWType: md5
+DBHA1Column: pw
+
+[MYSQL:UDB]
+Realm: blah
+DBServer: var/lib/mysql/mysql.sock
+DBUser: testuser
+DBPassword: testuser
+DBDatabase: test
+DBQuery: UPDATE testauth SET name = 'testo';
+# DBQuery: SELECT pw from testauth WHERE name = '%u';
+# DBPWType: crypt
+# DBHA1Column: pw