summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2004-04-26 20:39:55 +0000
committerStef Walter <stef@memberwebs.com>2004-04-26 20:39:55 +0000
commit8368de7830f336533f9fe6369641070239bf739c (patch)
tree5ad9641a6254c1c3a9e33750fdfb37ac7fbb7583
parent627c573af25b602ac64c36b01c8163c592cbb494 (diff)
More debugging fixes.
-rw-r--r--common/buffer.c8
-rw-r--r--daemon/basic.c2
-rw-r--r--daemon/digest.c44
-rw-r--r--daemon/httpauthd.c167
-rw-r--r--daemon/httpauthd.h28
-rw-r--r--daemon/ldap.c169
-rw-r--r--daemon/misc.c14
-rw-r--r--daemon/ntlm.c137
-rw-r--r--daemon/simple.c102
-rw-r--r--sample/httpauthd.conf19
10 files changed, 403 insertions, 287 deletions
diff --git a/common/buffer.c b/common/buffer.c
index 0cb045c..57d20e2 100644
--- a/common/buffer.c
+++ b/common/buffer.c
@@ -561,7 +561,7 @@ void* ha_bufdec64(ha_buffer_t* buf, const char* src, size_t* bytes)
buffer_bump(buf, 4);
if(ha_buferr(buf))
- return;
+ return NULL;
switch(state)
{
@@ -691,13 +691,13 @@ void* ha_bufdechex(ha_buffer_t* buf, const char* src, size_t* bytes)
src++;
}
+ /* We always null terminate anyway */
+ *(buf->_rp++) = 0;
+
/* All bytes have to come in pairs */
if(state != 0)
return NULL;
- /* We always null terminate anyway */
- *(buf->_rp++) = 0;
-
if(bytes)
*bytes = done;
diff --git a/daemon/basic.c b/daemon/basic.c
index 45e49cb..1d476ca 100644
--- a/daemon/basic.c
+++ b/daemon/basic.c
@@ -22,7 +22,7 @@ int basic_parse(const char* header, ha_buffer_t* buf, basic_header_t* rec)
header = (const char*)ha_bufdec64(buf, header, NULL);
if(!header)
- return HA_ERROR;
+ return ha_buferr(buf) ? HA_CRITERROR : HA_FALSE;
/* We have a cache key at this point so hash it */
diff --git a/daemon/digest.c b/daemon/digest.c
index d1cfe20..0bd6398 100644
--- a/daemon/digest.c
+++ b/daemon/digest.c
@@ -138,7 +138,7 @@ int digest_parse(char* header, ha_buffer_t* buf, digest_header_t* rec,
header = ha_bufcpy(buf, header);
if(!header)
- return HA_ERROR;
+ return HA_CRITERROR;
memset(rec, 0, sizeof(*rec));
@@ -253,7 +253,7 @@ int digest_parse(char* header, ha_buffer_t* buf, digest_header_t* rec,
}
int digest_check(const char* realm, const char* method, const char* uri,
- ha_buffer_t* buf, digest_header_t* dg, digest_record_t* rec)
+ ha_buffer_t* buf, digest_header_t* dg, digest_record_t* rec)
{
unsigned char hash[MD5_LEN];
md5_ctx_t md5;
@@ -268,7 +268,7 @@ int digest_check(const char* realm, const char* method, const char* uri,
if(!dg->digest || !dg->digest[0])
{
ha_messagex(LOG_WARNING, "digest response missing digest");
- return HA_FALSE;
+ return HA_BADREQ;
}
/* Username */
@@ -276,7 +276,7 @@ int digest_check(const char* realm, const char* method, const char* uri,
md5_strcmp(rec->userhash, dg->username) != 0)
{
ha_messagex(LOG_WARNING, "digest response missing username");
- return HA_FALSE;
+ return HA_BADREQ;
}
/* The realm */
@@ -284,7 +284,7 @@ int digest_check(const char* realm, const char* method, const char* uri,
{
ha_messagex(LOG_WARNING, "digest response contains invalid realm: '%s'",
dg->realm ? dg->realm : "");
- return HA_FALSE;
+ return HA_BADREQ;
}
/* Components in the new RFC */
@@ -298,21 +298,21 @@ int digest_check(const char* realm, const char* method, const char* uri,
{
ha_messagex(LOG_WARNING, "digest response contains unknown or unsupported qop: '%s'",
dg->qop ? dg->qop : "");
- return HA_FALSE;
+ return HA_BADREQ;
}
/* The cnonce */
if(!dg->cnonce || !dg->cnonce[0])
{
ha_messagex(LOG_WARNING, "digest response is missing cnonce value");
- return HA_FALSE;
+ return HA_BADREQ;
}
/* The nonce count */
if(!dg->nc || !dg->nc[0])
{
ha_messagex(LOG_WARNING, "digest response is missing nc value");
- return HA_FALSE;
+ return HA_BADREQ;
}
/* Validate the nc */
@@ -325,7 +325,7 @@ int digest_check(const char* realm, const char* method, const char* uri,
{
ha_messagex(LOG_WARNING, "digest response has invalid nc value: %s",
dg->nc);
- return HA_FALSE;
+ return HA_BADREQ;
}
}
}
@@ -335,14 +335,14 @@ int digest_check(const char* realm, const char* method, const char* uri,
{
ha_messagex(LOG_WARNING, "digest response contains unknown or unsupported algorithm: '%s'",
dg->algorithm ? dg->algorithm : "");
- return HA_FALSE;
+ return HA_BADREQ;
}
/* Request URI */
if(!dg->uri)
{
ha_messagex(LOG_WARNING, "digest response is missing uri");
- return HA_FALSE;
+ return HA_BADREQ;
}
if(strcmp(dg->uri, uri) != 0)
@@ -350,23 +350,29 @@ int digest_check(const char* realm, const char* method, const char* uri,
ha_uri_t d_uri;
ha_uri_t s_uri;
- if(ha_uriparse(buf, dg->uri, &d_uri) == HA_ERROR)
+ if(ha_uriparse(buf, dg->uri, &d_uri) < 0)
{
+ if(ha_buferr(buf))
+ return HA_CRITERROR;
+
ha_messagex(LOG_WARNING, "digest response constains invalid uri: %s", dg->uri);
- return HA_FALSE;
+ return HA_BADREQ;
}
- if(ha_uriparse(buf, uri, &s_uri) == HA_ERROR)
+ if(ha_uriparse(buf, uri, &s_uri) < 0)
{
+ if(ha_buferr(buf))
+ return HA_CRITERROR;
+
ha_messagex(LOG_ERR, "server sent us an invalid uri");
- return HA_ERROR;
+ return HA_BADREQ;
}
if(ha_uricmp(&d_uri, &s_uri) != 0)
{
ha_messagex(LOG_WARNING, "digest response contains wrong uri: %s "
"(should be %s)", dg->uri, uri);
- return HA_ERROR;
+ return HA_BADREQ;
}
}
@@ -386,7 +392,7 @@ int digest_check(const char* realm, const char* method, const char* uri,
t = ha_bufenchex(buf, rec->ha1, MD5_LEN);
if(t == NULL)
- return HA_ERROR;
+ return HA_CRITERROR;
/* Encode ha2 */
md5_init(&md5);
@@ -398,7 +404,7 @@ int digest_check(const char* realm, const char* method, const char* uri,
ha_bufenchex(buf, hash, MD5_LEN);
if(!ha_bufdata(buf))
- return HA_ERROR;
+ return HA_CRITERROR;
/* Old style digest (RFC 2069) */
@@ -435,7 +441,7 @@ int digest_check(const char* realm, const char* method, const char* uri,
digest = ha_bufenchex(buf, hash, MD5_LEN);
if(digest == NULL)
- return HA_ERROR;
+ return HA_CRITERROR;
if(strcasecmp(dg->digest, digest) != 0)
{
diff --git a/daemon/httpauthd.c b/daemon/httpauthd.c
index 465ac68..2dba6c2 100644
--- a/daemon/httpauthd.c
+++ b/daemon/httpauthd.c
@@ -17,6 +17,12 @@
#include "httpauthd.h"
#include "defaults.h"
+/*
+ * This shouldn't be used by handlers,
+ * they should return HA_FAILED instead.
+ */
+#define HA_SERVER_ERROR 500
+
/* -----------------------------------------------------------------------
* Handlers Registered Here
*/
@@ -329,7 +335,7 @@ int main(int argc, char* argv[])
if(fd != 0)
{
ha_messagex(LOG_ERR, "too many connections open (max %d)", g_maxthreads);
- httpauth_respond(fd, HA_SERVER_ERROR, "too many connections");
+ httpauth_respond(fd, HA_SERVER_ERROR, 0, "too many connections");
shutdown(fd, SHUT_RDWR);
}
}
@@ -567,54 +573,59 @@ int write_data(int ofd, const char* data)
if(errno != EPIPE)
ha_message(LOG_ERR, "couldn't write data");
- return -1;
+ return HA_CRITERROR;
}
}
return 0;
}
-int httpauth_respond(int ofd, int code, const char* msg)
+int httpauth_respond(int ofd, int scode, int ccode, const char* msg)
{
- const char* t;
char num[16];
ASSERT(ofd != -1);
- ASSERT(code > 99 && code < 1000);
+ ASSERT(scode > 99 && scode < 1000);
+ ASSERT(ccode == 0 || (ccode > 99 && ccode < 1000));
- sprintf(num, "%d", code);
+ /* Can only have a client code when server code is 200 */
+ ASSERT(ccode == 0 || scode == HA_SERVER_ACCEPT);
- if(write_data(ofd, num) == -1 ||
- write_data(ofd, " ") == -1)
- return -1;
+ sprintf(num, "%d ", scode);
+
+ if(write_data(ofd, num) < 0)
+ return HA_CRITERROR;
- switch(code)
+ if(ccode != 0)
{
- case HA_SERVER_ERROR:
- t = "Internal Error ";
- break;
- case HA_SERVER_BADREQ:
- t = "Bad Request ";
- break;
- case HA_SERVER_DECLINE:
- t = "Unauthorized ";
- break;
- default:
- t = NULL;
- break;
- };
+ sprintf(num, "%d ", ccode);
- if(t && write_data(ofd, t) == -1)
- return -1;
+ if(write_data(ofd, num) < 0)
+ return HA_CRITERROR;
+ }
- if(msg)
+ if(!msg)
{
- if(write_data(ofd, "[") == -1 ||
- write_data(ofd, msg) == -1 ||
- write_data(ofd, "]") == -1)
- return -1;
+ switch(scode)
+ {
+ 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;
+
return write_data(ofd, "\n");
}
@@ -628,8 +639,8 @@ int httpauth_write(int ofd, ha_response_t* resp)
ASSERT(ofd != -1);
ASSERT(resp);
- if(httpauth_respond(ofd, resp->code, resp->detail) == -1)
- return -1;
+ if(httpauth_respond(ofd, HA_SERVER_ACCEPT, resp->code, resp->detail) < 0)
+ return HA_CRITERROR;
for(i = 0; i < MAX_HEADERS; i++)
{
@@ -645,12 +656,41 @@ int httpauth_write(int ofd, ha_response_t* resp)
}
}
- if(wrote && write_data(ofd, "\n") == -1)
+ if(write_data(ofd, "\n") == -1)
return -1;
return 0;
}
+int httpauth_error(int ofd, int r)
+{
+ int scode = 0;
+ const char* msg = NULL;
+
+ ASSERT(r < 0);
+
+ switch(r)
+ {
+ case HA_BADREQ:
+ scode = HA_SERVER_BADREQ;
+ break;
+
+ case HA_CRITERROR:
+ msg = "Critical Error";
+ /* fall through */
+
+ case HA_FAILED:
+ scode = HA_SERVER_ERROR;
+ break;
+
+ default:
+ ASSERT(0 && "invalid error code");
+ break;
+ }
+
+ return httpauth_respond(ofd, scode, 0, msg);
+}
+
int httpauth_ready(int ofd, ha_buffer_t* buf)
{
const char* t;
@@ -671,9 +711,13 @@ int httpauth_ready(int ofd, ha_buffer_t* buf)
}
if(ha_buferr(buf))
- return httpauth_respond(ofd, HA_SERVER_ERROR, NULL);
+ {
+ return httpauth_error(ofd, HA_CRITERROR);
+ }
else
- return httpauth_respond(ofd, HA_SERVER_READY, ha_bufdata(buf));
+ {
+ return httpauth_respond(ofd, HA_SERVER_READY, 0, ha_bufdata(buf));
+ }
}
int httpauth_processor(int ifd, int ofd)
@@ -705,9 +749,13 @@ int httpauth_processor(int ifd, int ofd)
ha_bufreset(&inb);
r = httpauth_read(ifd, &req, &inb);
- if(r == -1 || ha_buferr(&inb))
+
+ if(ha_buferr(&inb))
+ r = HA_CRITERROR;
+
+ if(r < 0)
{
- httpauth_respond(ofd, HA_SERVER_ERROR, NULL);
+ httpauth_error(ofd, r);
result = 1;
continue;
}
@@ -720,15 +768,20 @@ int httpauth_processor(int ifd, int ofd)
case REQTYPE_AUTH:
r = process_auth(&req, &resp, &outb);
- if(r == -1 || ha_buferr(&outb))
+
+ if(ha_buferr(&outb))
+ r = HA_CRITERROR;
+
+ if(r < 0)
{
- httpauth_respond(ofd, HA_SERVER_ERROR, NULL);
+ httpauth_error(ofd, r);
result = 1;
continue;
}
- if(httpauth_write(ofd, &resp) == -1)
+ if(httpauth_write(ofd, &resp) < 0)
{
+ /* If writing failed then we don't bother notifying the client */
result = 1;
continue;
}
@@ -744,7 +797,7 @@ int httpauth_processor(int ifd, int ofd)
break;
default:
- if(httpauth_respond(ofd, HA_SERVER_BADREQ, "Unknown command") == -1)
+ if(httpauth_respond(ofd, HA_SERVER_BADREQ, 0, "Unknown command") == -1)
{
result = -1;
continue;
@@ -780,27 +833,21 @@ int process_auth(ha_request_t* req, ha_response_t* resp,
if(!req->args[AUTH_ARG_CONN] || !(req->args[AUTH_ARG_CONN][0]))
{
ha_messagex(LOG_ERR, "Missing connection ID in request");
- resp->detail = "Missing connection ID";
- resp->code = HA_SERVER_BADREQ;
- return 0;
+ return HA_BADREQ;
}
/* Check our uri argument */
if(!req->args[AUTH_ARG_URI] || !(req->args[AUTH_ARG_URI][0]))
{
ha_messagex(LOG_ERR, "Missing URI in request");
- resp->detail = "Missing URI";
- resp->code = HA_SERVER_BADREQ;
- return 0;
+ return HA_BADREQ;
}
/* Check our connection arguments */
if(!req->args[AUTH_ARG_METHOD] || !(req->args[AUTH_ARG_METHOD][0]))
{
ha_messagex(LOG_ERR, "Missing method in request");
- resp->detail = "Missing method";
- resp->code = HA_SERVER_BADREQ;
- return 0;
+ return HA_BADREQ;
}
@@ -810,17 +857,13 @@ int process_auth(ha_request_t* req, ha_response_t* resp,
if(strcasecmp(h->ctx.name, req->args[0]) == 0)
{
/* Now let the handler handle it */
- if(h->ctx.handler->f_process)
- return (h->ctx.handler->f_process)(&(h->ctx), req, resp, outb);
-
- return 0;
+ ASSERT(h->ctx.handler->f_process);
+ return (h->ctx.handler->f_process)(&(h->ctx), req, resp, outb);
}
}
ha_messagex(LOG_ERR, "Unknown authentication type: %s", req->args[0]);
- resp->detail = "Unknown authentication type";
- resp->code = HA_SERVER_BADREQ;
- return -1;
+ return HA_BADREQ;
}
/* -----------------------------------------------------------------------
@@ -1024,10 +1067,10 @@ int config_parse(const char* file, ha_buffer_t* buf)
if(ctx->handler->f_config)
{
r = (ctx->handler->f_config)(ctx, name, value);
- if(r == -1)
- return -1;
+ if(r < 0)
+ return r;
- if(!recog && r)
+ if(!recog && r == HA_OK)
recog = 1;
}
}
@@ -1038,7 +1081,7 @@ int config_parse(const char* file, ha_buffer_t* buf)
if(strcmp(name, "cachetimeout") == 0)
{
int v;
- if(ha_confint(name, value, 0, 86400, &v) == HA_ERROR)
+ if(ha_confint(name, value, 0, 86400, &v) < 0)
exit(1); /* Message already printed */
(ctx ? ctx : &defaults)->cache_timeout = v;
@@ -1048,7 +1091,7 @@ int config_parse(const char* file, ha_buffer_t* buf)
else if(strcmp(name, "cachemax") == 0)
{
int v;
- if(ha_confint(name, value, 0, 0x7FFFFFFF, &v) == HA_ERROR)
+ if(ha_confint(name, value, 0, 0x7FFFFFFF, &v) < 0)
exit(1); /* Message already printed */
(ctx ? ctx : &defaults)->cache_max = v;
diff --git a/daemon/httpauthd.h b/daemon/httpauthd.h
index 8693310..95187be 100644
--- a/daemon/httpauthd.h
+++ b/daemon/httpauthd.h
@@ -148,24 +148,33 @@ typedef struct ha_handler
ha_handler_t;
/*
- * OK signifies that things went according to plan. Return
- * this even if authentication fails (send auth to user)
- * unless something unexpected happens.
+ * OK signifies that things went according to plan.
*/
-#define HA_OK 1
+#define HA_OK 0
/*
- * FALSE signifies that we couldn't process but it wasn't
- * an error.
+ * FALSE: the process failed but it wasn't an error.
*/
-#define HA_FALSE 0
+#define HA_FALSE 1
/*
* ERROR means a bad error happened which will kill the
* current processing thread. Examples are out of memory
* errors or the like.
*/
-#define HA_ERROR -1
+#define HA_CRITERROR -1
+
+/*
+ * FAILED: something internal to the server failed.
+ */
+#define HA_FAILED -2
+
+/*
+ * BADREQ means that we got a bad request or call.
+ */
+#define HA_BADREQ -3
+
+
struct ha_options;
@@ -237,12 +246,11 @@ typedef struct ha_request
}
ha_request_t;
-/* The various response codes */
+/* The various response codes for the client */
#define HA_SERVER_READY 100
#define HA_SERVER_ACCEPT 200
#define HA_SERVER_DECLINE 401
#define HA_SERVER_BADREQ 402
-#define HA_SERVER_ERROR 500
#define HA_SERVER_BUSY 500
/* A response to the client */
diff --git a/daemon/ldap.c b/daemon/ldap.c
index b6da6d4..9a79d43 100644
--- a/daemon/ldap.c
+++ b/daemon/ldap.c
@@ -96,14 +96,14 @@ static const ldap_context_t ldap_defaults =
{
NULL, /* servers */
NULL, /* filter */
- "", /* base */
+ NULL, /* base */
"userPassword", /* pw_attr */
NULL, /* ha1_attr */
NULL, /* user */
NULL, /* password */
NULL, /* dnmap */
389, /* port */
- LDAP_SCOPE_DEFAULT, /* scope */
+ LDAP_SCOPE_SUBTREE, /* scope */
"", /* realm */
NULL, /* domains */
1, /* dobind */
@@ -130,7 +130,7 @@ static void free_hash_object(void* arg, void* val)
free(val);
}
-static int report_ldap(const char* msg, int code, ha_response_t* resp)
+static int report_ldap(const char* msg, int code)
{
ASSERT(code != LDAP_SUCCESS);
@@ -142,13 +142,10 @@ static int report_ldap(const char* msg, int code, ha_response_t* resp)
switch(code)
{
case LDAP_NO_MEMORY:
- return HA_ERROR;
+ return HA_CRITERROR;
default:
- if(resp)
- resp->code = HA_SERVER_ERROR;
-
- return HA_FALSE;
+ return HA_FAILED;
};
}
@@ -197,7 +194,10 @@ static int save_cached_digest(ldap_context_t* ctx, digest_record_t* rec)
ASSERT(ctx && rec);
if(ctx->cache_max == 0)
+ {
+ free_hash_object(NULL, rec);
return HA_FALSE;
+ }
ha_lock(NULL);
@@ -211,7 +211,7 @@ static int save_cached_digest(ldap_context_t* ctx, digest_record_t* rec)
if(!r)
{
ha_messagex(LOG_CRIT, "out of memory");
- return HA_ERROR;
+ return HA_CRITERROR;
}
return HA_OK;
@@ -238,7 +238,7 @@ static int add_cached_basic(ldap_context_t* ctx, unsigned char* key)
if(!r)
{
ha_messagex(LOG_CRIT, "out of memory");
- return HA_ERROR;
+ return HA_CRITERROR;
}
return HA_OK;
@@ -282,6 +282,12 @@ static const char* substitute_params(ldap_context_t* ctx, ha_buffer_t* buf,
ha_bufcpy(buf, ctx->realm);
t++;
break;
+
+ case '%':
+ ha_bufjoin(buf);
+ ha_bufcpy(buf, "%");
+ t++;
+ break;
};
str = t;
@@ -351,7 +357,7 @@ static int parse_ldap_password(const char** password)
/* find a scheme in our map */
for(i = 0; i < countof(kLDAPPWTypes); i++)
{
- if(strncasecmp(kLDAPPWTypes[i].name, scheme, pw - scheme))
+ if(strncasecmp(kLDAPPWTypes[i].name, scheme, pw - scheme) == 0)
return kLDAPPWTypes[i].type;
}
@@ -412,13 +418,14 @@ static int parse_ldap_ha1(ha_buffer_t* buf, struct berval* bv, unsigned char* ha
}
}
- return ha_buferr(buf) ? HA_ERROR : HA_FALSE;
+ return ha_buferr(buf) ? HA_CRITERROR : HA_FALSE;
}
static int validate_ldap_password(ldap_context_t* ctx, LDAP* ld, LDAPMessage* entry,
ha_buffer_t* buf, const char* user, const char* clearpw)
{
char** pws;
+ char** t;
const char* pw;
const char* p;
int type;
@@ -432,9 +439,9 @@ static int validate_ldap_password(ldap_context_t* ctx, LDAP* ld, LDAPMessage* en
if(pws)
{
- for( ; *pws; pws++)
+ for(t = pws ; *t; t++)
{
- pw = *pws;
+ pw = *t;
type = parse_ldap_password(&pw);
switch(type)
@@ -470,7 +477,7 @@ static int validate_ldap_password(ldap_context_t* ctx, LDAP* ld, LDAPMessage* en
if(!p)
{
- res = HA_ERROR;
+ res = HA_CRITERROR;
break;
}
@@ -494,6 +501,7 @@ static int validate_ldap_ha1(ldap_context_t* ctx, LDAP* ld, LDAPMessage* entry,
ha_buffer_t* buf, const char* user, const char* clearpw)
{
struct berval** ha1s;
+ struct berval** b;
unsigned char key[MD5_LEN];
unsigned char k[MD5_LEN];
int r, first = 1;
@@ -510,10 +518,10 @@ static int validate_ldap_ha1(ldap_context_t* ctx, LDAP* ld, LDAPMessage* entry,
{
digest_makeha1(key, user, ctx->realm, clearpw);
- for( ; *ha1s; ha1s++)
+ for(b = ha1s ; *b; b++)
{
- r = parse_ldap_ha1(buf, *ha1s, k);
- if(r == HA_ERROR)
+ r = parse_ldap_ha1(buf, *b, k);
+ if(r < 0)
{
res = r;
break;
@@ -578,7 +586,7 @@ static LDAP* get_ldap_connection(ldap_context_t* ctx)
ctx->password ? ctx->password : "");
if(r != LDAP_SUCCESS)
{
- report_ldap("couldn't bind to LDAP server", r, NULL);
+ report_ldap("couldn't bind to LDAP server", r);
ldap_unbind_s(ld);
return NULL;
}
@@ -645,7 +653,7 @@ static int retrieve_user_entry(ldap_context_t* ctx, ha_buffer_t* buf, LDAP* ld,
/* Filters can also have %u and %r */
filter = substitute_params(ctx, buf, user, ctx->filter);
if(!filter)
- return HA_ERROR;
+ return HA_CRITERROR;
}
else
{
@@ -664,7 +672,15 @@ static int retrieve_user_entry(ldap_context_t* ctx, ha_buffer_t* buf, LDAP* ld,
filter, (char**)attrs, 0, &tv, result);
if(r != LDAP_SUCCESS)
- return report_ldap("couldn't search LDAP server", r, NULL);
+ {
+ if(r == LDAP_NO_SUCH_OBJECT)
+ {
+ ha_messagex(LOG_WARNING, "user not found in LDAP: %s", user);
+ return HA_FALSE;
+ }
+
+ return report_ldap("couldn't search LDAP server", r);
+ }
/* Only one result should exist */
@@ -685,28 +701,27 @@ static int retrieve_user_entry(ldap_context_t* ctx, ha_buffer_t* buf, LDAP* ld,
break;
};
- ldap_msgfree(*result);
return HA_FALSE;
}
static int complete_digest_ha1(ldap_context_t* ctx, digest_record_t* rec,
- ha_buffer_t* buf, const char* user, int* code)
+ ha_buffer_t* buf, const char* user)
{
LDAP* ld = NULL; /* freed in finally */
LDAPMessage* results = NULL; /* freed in finally */
LDAPMessage* entry = NULL; /* no need to free */
- struct berval** ha1s; /* freed manually */
+ struct berval** ha1s = NULL; /* freed manually */
char** pws;
int ret = HA_FALSE;
- const char* dn;
+ const char* dn = NULL;
int r;
- ASSERT(ctx && rec && buf && user && code);
+ ASSERT(ctx && rec && buf && user);
ld = get_ldap_connection(ctx);
if(!ld)
{
- *code = HA_SERVER_ERROR;
+ ret = HA_FAILED;
goto finally;
}
@@ -721,7 +736,7 @@ static int complete_digest_ha1(ldap_context_t* ctx, digest_record_t* rec,
dn = substitute_params(ctx, buf, user, ctx->dnmap);
if(!dn)
{
- ret = HA_ERROR;
+ ret = HA_CRITERROR;
goto finally;
}
}
@@ -742,12 +757,10 @@ static int complete_digest_ha1(ldap_context_t* ctx, digest_record_t* rec,
{
if(*ha1s)
{
- r = parse_ldap_ha1(buf, *ha1s, rec->ha1);
- if(r != HA_OK)
+ ret = parse_ldap_ha1(buf, *ha1s, rec->ha1);
+ if(ret != HA_OK)
{
- ret = r;
-
- if(ret != HA_FALSE)
+ if(ret == HA_FALSE)
ha_messagex(LOG_ERR, "LDAP contains invalid HA1 digest hash for user: %s", user);
}
}
@@ -764,14 +777,16 @@ static int complete_digest_ha1(ldap_context_t* ctx, digest_record_t* rec,
/* Find a cleartext password */
const char* t = find_cleartext_password(buf, (const char**)pws);
- ldap_value_free(pws);
-
if(t)
{
digest_makeha1(rec->ha1, user, ctx->realm, t);
ret = HA_OK;
- goto finally;
}
+
+ ldap_value_free(pws);
+
+ if(ret == HA_OK)
+ goto finally;
}
ha_messagex(LOG_ERR, "LDAP contains no cleartext password for user: %s", user);
@@ -794,15 +809,15 @@ static int basic_ldap_response(ldap_context_t* ctx, const char* header,
LDAP* ld = NULL;
LDAPMessage* entry = NULL;
LDAPMessage* results = NULL;
- const char* dn;
+ const char* dn = NULL;
int ret = HA_FALSE;
int found = 0;
int r;
ASSERT(buf && header && resp && buf);
- if(basic_parse(header, buf, &basic) == HA_ERROR)
- return HA_ERROR;
+ if((r = basic_parse(header, buf, &basic)) < 0)
+ return r;
/* Past this point we don't return directly */
@@ -823,7 +838,7 @@ static int basic_ldap_response(ldap_context_t* ctx, const char* header,
ld = get_ldap_connection(ctx);
if(!ld)
{
- resp->code = HA_SERVER_ERROR;
+ ret = HA_FAILED;
goto finally;
}
@@ -839,7 +854,7 @@ static int basic_ldap_response(ldap_context_t* ctx, const char* header,
dn = substitute_params(ctx, buf, basic.user, ctx->dnmap);
if(!dn)
{
- ret = HA_ERROR;
+ ret = HA_CRITERROR;
goto finally;
}
}
@@ -882,7 +897,7 @@ static int basic_ldap_response(ldap_context_t* ctx, const char* header,
if(r == LDAP_INVALID_CREDENTIALS)
ha_messagex(LOG_WARNING, "invalid login for: %s", basic.user);
else
- report_ldap("couldn't bind to LDAP server", r, resp);
+ report_ldap("couldn't bind to LDAP server", r);
goto finally;
}
@@ -903,7 +918,7 @@ static int basic_ldap_response(ldap_context_t* ctx, const char* header,
found = 1;
else
- ha_messagex(LOG_WARNING, "invalid or unrecognized password for user: %s", basic.user);
+ ha_messagex(LOG_WARNING, "invalid, unreadable or unrecognized password for user: %s", basic.user);
}
@@ -915,7 +930,7 @@ finally:
if(results)
ldap_msgfree(results);
- if(found && ret != HA_ERROR)
+ if(found && ret >= 0)
{
resp->code = HA_SERVER_ACCEPT;
resp->detail = basic.user;
@@ -950,14 +965,14 @@ static int digest_ldap_challenge(ldap_context_t* ctx, ha_response_t* resp,
nonce_str = ha_bufenchex(buf, nonce, DIGEST_NONCE_LEN);
if(!nonce_str)
- return HA_ERROR;
+ return HA_CRITERROR;
}
/* Now generate a message to send */
header = digest_challenge(buf, nonce_str, ctx->realm, ctx->domains, stale);
if(!header)
- return HA_ERROR;
+ return HA_CRITERROR;
/* And append it nicely */
resp->code = HA_SERVER_DECLINE;
@@ -984,8 +999,8 @@ static int digest_ldap_response(ldap_context_t* ctx, const char* header,
/* We use this below to send a default response */
resp->code = -1;
- if(digest_parse(header, buf, &dg, nonce) == HA_ERROR)
- return HA_ERROR;
+ if((r = digest_parse(header, buf, &dg, nonce)) < 0)
+ return r;
#ifdef _DEBUG
if(ctx->debug_nonce)
@@ -993,6 +1008,7 @@ static int digest_ldap_response(ldap_context_t* ctx, const char* header,
if(dg.nonce && strcmp(dg.nonce, ctx->debug_nonce) != 0)
{
ret = HA_FALSE;
+ resp->code = HA_SERVER_BADREQ;
ha_messagex(LOG_WARNING, "digest response contains invalid nonce");
goto finally;
}
@@ -1010,9 +1026,11 @@ static int digest_ldap_response(ldap_context_t* ctx, const char* header,
if(r != HA_OK)
{
if(r == HA_FALSE)
+ {
+ resp->code = HA_SERVER_BADREQ;
ha_messagex(LOG_WARNING, "digest response contains invalid nonce");
+ }
- ret = r;
goto finally;
}
}
@@ -1037,11 +1055,11 @@ static int digest_ldap_response(ldap_context_t* ctx, const char* header,
rec = digest_makerec(nonce, dg.username);
if(!rec)
{
- ret = HA_ERROR;
+ ret = HA_CRITERROR;
goto finally;
}
- r = complete_digest_ha1(ctx, rec, buf, dg.username, &(resp->code));
+ r = complete_digest_ha1(ctx, rec, buf, dg.username);
if(r != HA_OK)
{
ret = r;
@@ -1054,7 +1072,13 @@ static int digest_ldap_response(ldap_context_t* ctx, const char* header,
ret = digest_check(ctx->realm, method, uri, buf, &dg, rec);
- if(ret == HA_OK)
+ if(ret == HA_BADREQ)
+ {
+ ret = HA_FALSE;
+ resp->code = HA_SERVER_BADREQ;
+ }
+
+ else if(ret == HA_OK)
{
resp->code = HA_SERVER_ACCEPT;
resp->detail = dg.username;
@@ -1069,7 +1093,7 @@ static int digest_ldap_response(ldap_context_t* ctx, const char* header,
t = digest_respond(buf, &dg, rec, stale ? nonce : NULL);
if(!t)
{
- ret = HA_ERROR;
+ ret = HA_CRITERROR;
goto finally;
}
@@ -1077,10 +1101,10 @@ static int digest_ldap_response(ldap_context_t* ctx, const char* header,
ha_addheader(resp, "Authentication-Info", t);
/* Put the connection into the cache */
- if(save_cached_digest(ctx, rec) == HA_ERROR)
- ret = HA_ERROR;
- else
- rec = NULL;
+ if((r = save_cached_digest(ctx, rec)) < 0)
+ ret = r;
+
+ rec = NULL;
}
finally:
@@ -1179,7 +1203,7 @@ int ldap_config(ha_context_t* context, const char* name, const char* value)
else
{
ha_messagex(LOG_ERR, "invalid value for '%s' (must be 'sub', 'base' or 'one')", name);
- return HA_ERROR;
+ return HA_FAILED;
}
return HA_OK;
@@ -1232,24 +1256,29 @@ int ldap_inithand(ha_context_t* context)
{
ha_messagex(LOG_ERR, "LDAP module configured, but does not implement any "
"configured authentication type.");
- return HA_ERROR;
+ return HA_FAILED;
}
/* Check for mandatory configuration */
- if(!ctx->servers || !(ctx->dnmap || ctx->filter))
+ if(!ctx->servers)
{
- ha_messagex(LOG_ERR, "Digest LDAP configuration incomplete. "
- "Must have LDAPServers and either LDAPFilter or LDAPDNMap.");
- return HA_ERROR;
+ ha_messagex(LOG_ERR, "LDAP configuration incomplete. "
+ "Must have LDAPServers.");
+ return HA_FAILED;
}
- ASSERT(!ctx->cache);
+ if(!ctx->dnmap && (!ctx->filter || !ctx->base))
+ {
+ ha_messagex(LOG_ERR, "LDAP configuration incomplete. "
+ "When not using LDAPDNMap must specify LDAPBase and LDAPFilter.");
+ return HA_FAILED;
+ }
/* The cache for digest records and basic */
if(!(ctx->cache = hash_create(MD5_LEN, free_hash_object, NULL)))
{
ha_messagex(LOG_CRIT, "out of memory");
- return HA_ERROR;
+ return HA_CRITERROR;
}
ASSERT(!ctx->pool);
@@ -1264,7 +1293,7 @@ int ldap_inithand(ha_context_t* context)
if(!ctx->pool)
{
ha_messagex(LOG_CRIT, "out of memory");
- return HA_ERROR;
+ return HA_CRITERROR;
}
memset(ctx->pool, 0, sizeof(LDAP*) * ctx->ldap_max);
@@ -1338,7 +1367,7 @@ int ldap_process(ha_context_t* context, ha_request_t* req,
{
ret = digest_ldap_response(ctx, header, req->args[AUTH_ARG_METHOD],
req->args[AUTH_ARG_URI], resp, buf);
- if(ret == HA_ERROR)
+ if(ret < 0)
return ret;
}
}
@@ -1350,7 +1379,7 @@ int ldap_process(ha_context_t* context, ha_request_t* req,
if(header)
{
ret = basic_ldap_response(ctx, header, resp, buf);
- if(ret == HA_ERROR)
+ if(ret < 0)
return ret;
}
}
@@ -1364,7 +1393,7 @@ int ldap_process(ha_context_t* context, ha_request_t* req,
if(context->types & HA_TYPE_DIGEST)
{
ret = digest_ldap_challenge(ctx, resp, buf, 0);
- if(ret == HA_ERROR)
+ if(ret < 0)
return ret;
}
@@ -1373,7 +1402,7 @@ int ldap_process(ha_context_t* context, ha_request_t* req,
ha_bufmcat(buf, "BASIC realm=\"", ctx->realm , "\"", NULL);
if(ha_buferr(buf))
- return HA_ERROR;
+ return HA_CRITERROR;
ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf));
}
diff --git a/daemon/misc.c b/daemon/misc.c
index 15344ce..cda6dc2 100644
--- a/daemon/misc.c
+++ b/daemon/misc.c
@@ -195,7 +195,7 @@ int ha_confbool(const char* name, const char* conf, int* value)
}
ha_messagex(LOG_ERR, "invalid configuration value '%s': must be 'on' or 'off'.", name);
- return HA_ERROR;
+ return HA_FAILED;
}
int ha_confint(const char* name, const char* conf, int min, int max, int* value)
@@ -211,7 +211,7 @@ int ha_confint(const char* name, const char* conf, int min, int max, int* value)
if(*p || errno == ERANGE || (*value < min) || (*value > max))
{
ha_messagex(LOG_ERR, "invalid configuration value '%s': must be a number between %d and %d", name, min, max);
- return HA_ERROR;
+ return HA_FAILED;
}
return HA_OK;
@@ -289,11 +289,13 @@ int ha_uriparse(ha_buffer_t* buf, const char* suri, ha_uri_t* uri)
ASSERT(buf && suri && uri);
+ /* TODO: We need to http decode the uri */
+
/* Copy the memory */
str = ha_bufcpy(buf, suri);
if(!str)
- return HA_ERROR;
+ return HA_CRITERROR;
/* Initialize the structure */
memset(uri, 0, sizeof(*uri));
@@ -445,7 +447,7 @@ deal_with_host:
port = strtol(s, &endstr, 10);
uri->port = port;
if(*endstr != '\0')
- return HA_FALSE;
+ return HA_FAILED;
}
goto deal_with_path;
@@ -548,7 +550,7 @@ int ha_genrandom(unsigned char* data, size_t len)
if(dd == -1)
{
ha_message(LOG_ERR, "couldn't open /dev/urandom");
- return HA_ERROR;
+ return HA_FAILED;
}
for(;;)
@@ -582,5 +584,5 @@ int ha_genrandom(unsigned char* data, size_t len)
}
close(dd);
- return r == -1 ? HA_ERROR : HA_OK;
+ return r == -1 ? HA_FAILED : HA_OK;
}
diff --git a/daemon/ntlm.c b/daemon/ntlm.c
index 736ac28..ef889f1 100644
--- a/daemon/ntlm.c
+++ b/daemon/ntlm.c
@@ -70,44 +70,6 @@ static pthread_mutexattr_t g_smblib_mutexattr;
* Internal Functions
*/
-static ntlm_connection_t* getpending(ntlm_context_t* ctx, const void* key)
-{
- ntlm_connection_t* ret;
-
- ASSERT(ctx && key);
-
- ha_lock(NULL);
-
- ret = (ntlm_connection_t*)hash_rem(ctx->pending, key);
-
- ha_unlock(NULL);
-
- return ret;
-}
-
-static int putpending(ntlm_context_t* ctx, const void* key, ntlm_connection_t* conn)
-{
- int r = 0;
-
- ASSERT(ctx && key && conn);
- ASSERT(conn->handle);
-
- if(!hash_get(ctx->pending, key))
- {
- ha_lock(NULL);
-
- if(!hash_set(ctx->pending, key, (void*)conn))
- {
- ha_messagex(LOG_ERR, "out of memory");
- r = -1;
- }
-
- ha_unlock(NULL);
- }
-
- return r;
-}
-
static ntlm_connection_t* makeconnection(ntlm_context_t* ctx)
{
ntlm_connection_t* conn;
@@ -163,6 +125,45 @@ static void free_hash_object(void* arg, void* val)
}
}
+static ntlm_connection_t* getpending(ntlm_context_t* ctx, const void* key)
+{
+ ntlm_connection_t* ret;
+
+ ASSERT(ctx && key);
+
+ ha_lock(NULL);
+
+ ret = (ntlm_connection_t*)hash_rem(ctx->pending, key);
+
+ ha_unlock(NULL);
+
+ return ret;
+}
+
+static int putpending(ntlm_context_t* ctx, const void* key, ntlm_connection_t* conn)
+{
+ int r = 0;
+
+ ASSERT(ctx && key && conn);
+ ASSERT(conn->handle);
+
+ if(!hash_get(ctx->pending, key))
+ {
+ ha_lock(NULL);
+
+ if(!hash_set(ctx->pending, key, (void*)conn))
+ {
+ free_hash_object(NULL, conn);
+ ha_messagex(LOG_ERR, "out of memory");
+ r = -1;
+ }
+
+ ha_unlock(NULL);
+ }
+
+ return r;
+}
+
int ntlm_auth_basic(ntlm_context_t* ctx, char* key, const char* header,
ha_response_t* resp, ha_buffer_t* buf)
{
@@ -171,6 +172,7 @@ int ntlm_auth_basic(ntlm_context_t* ctx, char* key, const char* header,
basic_header_t basic;
const char* domain = NULL;
int found = 0;
+ int r;
ASSERT(ctx && key && header && resp && buf);
@@ -183,8 +185,8 @@ int ntlm_auth_basic(ntlm_context_t* ctx, char* key, const char* header,
if(conn)
freeconnection(conn);
- if(basic_parse(header, buf, &basic) == HA_ERROR)
- return HA_ERROR;
+ if((r = basic_parse(header, buf, &basic)) < 0)
+ return r;
/* Check and see if this connection is in the cache */
ha_lock(NULL);
@@ -249,7 +251,7 @@ int ntlm_auth_basic(ntlm_context_t* ctx, char* key, const char* header,
if(!r)
{
ha_messagex(LOG_CRIT, "out of memory");
- return HA_ERROR;
+ return HA_CRITERROR;
}
return HA_OK;
@@ -329,11 +331,19 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
* pending stack so that the correct request will complete
* properly when it comes through.
*/
- if(putpending(ctx, key, conn) != -1)
- conn = NULL;
+ r = putpending(ctx, key, conn);
+ conn = NULL;
+
+ if(r < 0)
+ {
+ ret = HA_CRITERROR;
+ }
+ else
+ {
+ ha_messagex(LOG_ERR, "received out of order NTLM request from client");
+ resp->code = HA_SERVER_BADREQ;
+ }
- ha_messagex(LOG_ERR, "received out of order NTLM request from client");
- resp->code = HA_SERVER_BADREQ;
goto finally;
}
@@ -362,7 +372,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
if(!conn)
{
- resp->code = HA_SERVER_ERROR;
+ ret = HA_FAILED;
goto finally;
}
@@ -396,11 +406,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
*/
/* Cache this connection in our pending set ... */
- if(putpending(ctx, key, conn) == -1)
- {
- resp->code = HA_SERVER_ERROR;
- goto finally;
- }
+ r = putpending(ctx, key, conn);
/*
* By marking this as null, the cleanup code
@@ -409,8 +415,15 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
*/
conn = NULL;
- ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf));
- resp->code = HA_SERVER_DECLINE;
+ if(r < 0)
+ {
+ ret = HA_CRITERROR;
+ }
+ else
+ {
+ ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf));
+ resp->code = HA_SERVER_DECLINE;
+ }
goto finally;
}
@@ -475,7 +488,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
if(!r)
{
ha_messagex(LOG_CRIT, "out of memory");
- ret = HA_ERROR;
+ ret = HA_CRITERROR;
}
else
{
@@ -495,7 +508,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
finally:
if(ha_buferr(buf))
- ret = HA_ERROR;
+ ret = HA_CRITERROR;
if(conn)
freeconnection(conn);
@@ -565,7 +578,7 @@ int ntlm_init(ha_context_t* context)
{
ha_messagex(LOG_ERR, "NTLM module configured, but does not implement any "
"configured authentication type.");
- return HA_ERROR;
+ return HA_FAILED;
}
/* Check for mandatory configuration */
@@ -573,7 +586,7 @@ int ntlm_init(ha_context_t* context)
{
ha_messagex(LOG_ERR, "NTLM configuration incomplete. "
"Must have NTLMServer and NTLMDomain configured.");
- return HA_ERROR;
+ return HA_FAILED;
}
ASSERT(!ctx->pending);
@@ -584,7 +597,7 @@ int ntlm_init(ha_context_t* context)
!(ctx->established = hash_create(NTLM_HASH_KEY_LEN, NULL, NULL)))
{
ha_messagex(LOG_CRIT, "out of memory");
- return HA_ERROR;
+ return HA_CRITERROR;
}
}
@@ -597,7 +610,7 @@ int ntlm_init(ha_context_t* context)
pthread_mutex_init(&g_smblib_mutex, &g_smblib_mutexattr) != 0)
{
ha_messagex(LOG_CRIT, "threading problem. can't create mutex");
- return HA_ERROR;
+ return HA_CRITERROR;
}
}
@@ -671,7 +684,7 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
header++;
ret = ntlm_auth_ntlm(ctx, key, header, resp, buf);
- if(ret == HA_ERROR)
+ if(ret < 0)
return ret;
}
}
@@ -688,7 +701,7 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
header++;
ret = ntlm_auth_basic(ctx, key, header, resp, buf);
- if(ret == HA_ERROR)
+ if(ret < 0)
return ret;
}
}
@@ -730,7 +743,7 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
ctx->basic_realm ? ctx->basic_realm : "", "\"", NULL);
if(ha_buferr(buf))
- return HA_ERROR;
+ return HA_CRITERROR;
ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf));
}
diff --git a/daemon/simple.c b/daemon/simple.c
index d2f8063..4c7fb28 100644
--- a/daemon/simple.c
+++ b/daemon/simple.c
@@ -96,7 +96,10 @@ static int save_cached_digest(simple_context_t* ctx, digest_record_t* rec)
ASSERT(ctx && rec);
if(ctx->cache_max == 0)
+ {
+ free_hash_object(NULL, rec);
return HA_FALSE;
+ }
ha_lock(NULL);
@@ -109,8 +112,9 @@ static int save_cached_digest(simple_context_t* ctx, digest_record_t* rec)
if(!r)
{
+ free_hash_object(NULL, rec);
ha_messagex(LOG_CRIT, "out of memory");
- return HA_ERROR;
+ return HA_CRITERROR;
}
return HA_OK;
@@ -137,30 +141,29 @@ static int add_cached_basic(simple_context_t* ctx, unsigned char* key)
if(!r)
{
ha_messagex(LOG_CRIT, "out of memory");
- return HA_ERROR;
+ return HA_CRITERROR;
}
return HA_OK;
}
static int complete_digest_ha1(simple_context_t* ctx, digest_record_t* rec,
- ha_buffer_t* buf, const char* user, int* code)
+ ha_buffer_t* buf, const char* user)
{
FILE* f;
- int found = 0;
char* t;
char* t2;
size_t len;
char line[SIMPLE_MAXLINE];
+ int ret = HA_FALSE;
- ASSERT(ctx && rec && buf && user && user[0] && code);
+ ASSERT(ctx && rec && buf && user && user[0]);
f = fopen(ctx->filename, "r");
if(!f)
{
ha_message(LOG_ERR, "can't open file for basic auth: %s", ctx->filename);
- *code = HA_SERVER_ERROR;
- return HA_FALSE;
+ return HA_FAILED;
}
/*
@@ -176,7 +179,7 @@ static int complete_digest_ha1(simple_context_t* ctx, digest_record_t* rec,
if(ferror(f))
{
ha_message(LOG_ERR, "error reading basic password file");
- *code = HA_SERVER_ERROR;
+ ret = HA_FAILED;
break;
}
@@ -207,13 +210,13 @@ static int complete_digest_ha1(simple_context_t* ctx, digest_record_t* rec,
if(t && len == MD5_LEN)
{
memcpy(rec->ha1, t, MD5_LEN);
- found = 1;
+ ret = HA_OK;
break;
}
}
}
- if(!t2 || !found)
+ if(!t2 || ret != HA_OK)
ha_messagex(LOG_WARNING, "user '%s' found in file, but password not in digest format", user);
}
}
@@ -222,31 +225,30 @@ static int complete_digest_ha1(simple_context_t* ctx, digest_record_t* rec,
fclose(f);
if(ha_buferr(buf))
- return HA_ERROR;
+ return HA_CRITERROR;
- return found ? HA_OK : HA_FALSE;
+ return ret;
}
static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
- const char* user, const char* clearpw, int* code)
+ const char* user, const char* clearpw)
{
FILE* f;
- int found = 0;
char line[SIMPLE_MAXLINE];
unsigned char ha1[MD5_LEN];
char* t;
char* t2;
size_t len;
+ int ret = HA_FALSE;
- ASSERT(ctx && buf && code);
+ ASSERT(ctx && buf);
ASSERT(user && user[0] && clearpw);
f = fopen(ctx->filename, "r");
if(!f)
{
ha_message(LOG_ERR, "can't open file for basic auth: %s", ctx->filename);
- *code = HA_SERVER_ERROR;
- return HA_FALSE;
+ return HA_FAILED;
}
digest_makeha1(ha1, user, ctx->realm, clearpw);
@@ -264,7 +266,7 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
if(ferror(f))
{
ha_message(LOG_ERR, "error reading basic password file");
- *code = HA_SERVER_ERROR;
+ ret = HA_FAILED;
break;
}
@@ -296,7 +298,7 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
if(strcmp(crypt(clearpw, t), t) == 0)
{
- found = 1;
+ ret = HA_OK;
break;
}
@@ -316,7 +318,7 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
t = ha_bufdechex(buf, t2, &len);
if(t && len == MD5_LEN && memcmp(ha1, t, MD5_LEN) == 0)
{
- found = 1;
+ ret = HA_OK;
break;
}
}
@@ -331,9 +333,9 @@ static int validate_user_password(simple_context_t* ctx, ha_buffer_t* buf,
fclose(f);
if(ha_buferr(buf))
- return HA_ERROR;
+ return HA_CRITERROR;
- return found ? HA_FALSE : HA_OK;
+ return ret;
}
static int simple_basic_response(simple_context_t* ctx, const char* header,
@@ -346,8 +348,8 @@ static int simple_basic_response(simple_context_t* ctx, const char* header,
ASSERT(buf && header && resp && buf);
- if(basic_parse(header, buf, &basic) == HA_ERROR)
- return HA_ERROR;
+ if((r = basic_parse(header, buf, &basic)) < 0)
+ return r;
/* Past this point we don't return directly */
@@ -365,7 +367,7 @@ static int simple_basic_response(simple_context_t* ctx, const char* header,
goto finally;
- ret = validate_user_password(ctx, buf, basic.user, basic.password, &(resp->code));
+ ret = validate_user_password(ctx, buf, basic.user, basic.password);
finally:
@@ -405,7 +407,7 @@ static int simple_digest_challenge(simple_context_t* ctx, ha_response_t* resp,
nonce_str = ha_bufenchex(buf, nonce, DIGEST_NONCE_LEN);
if(!nonce_str)
- return HA_ERROR;
+ return HA_CRITERROR;
}
@@ -413,7 +415,7 @@ static int simple_digest_challenge(simple_context_t* ctx, ha_response_t* resp,
header = digest_challenge(buf, nonce_str, ctx->realm, ctx->domains, stale);
if(!header)
- return HA_ERROR;
+ return HA_CRITERROR;
/* And append it nicely */
resp->code = HA_SERVER_DECLINE;
@@ -440,14 +442,15 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
/* We use this below to send a default response */
resp->code = -1;
- if(digest_parse(header, buf, &dg, nonce) == HA_ERROR)
- return HA_ERROR;
+ if((r = digest_parse(header, buf, &dg, nonce)) < 0)
+ return r;
#ifdef _DEBUG
if(ctx->debug_nonce)
{
if(dg.nonce && strcmp(dg.nonce, ctx->debug_nonce) != 0)
{
+ resp->code = HA_SERVER_BADREQ;
ret = HA_FALSE;
ha_messagex(LOG_WARNING, "digest response contains invalid nonce");
goto finally;
@@ -466,7 +469,10 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
if(r != HA_OK)
{
if(r == HA_FALSE)
+ {
+ resp->code = HA_SERVER_BADREQ;
ha_messagex(LOG_WARNING, "digest response contains invalid nonce");
+ }
ret = r;
goto finally;
@@ -492,11 +498,11 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
rec = digest_makerec(nonce, dg.username);
if(!rec)
{
- ret = HA_ERROR;
+ ret = HA_CRITERROR;
goto finally;
}
- r = complete_digest_ha1(ctx, rec, buf, dg.username, &(resp->code));
+ r = complete_digest_ha1(ctx, rec, buf, dg.username);
if(r != HA_OK)
{
ret = r;
@@ -509,7 +515,13 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
ret = digest_check(ctx->realm, method, uri, buf, &dg, rec);
- if(ret == HA_OK)
+ if(ret == HA_BADREQ)
+ {
+ ret = HA_FALSE;
+ resp->code = HA_SERVER_BADREQ;
+ }
+
+ else if(ret == HA_OK)
{
resp->code = HA_SERVER_ACCEPT;
resp->detail = dg.username;
@@ -524,7 +536,7 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
t = digest_respond(buf, &dg, rec, stale ? nonce : NULL);
if(!t)
{
- ret = HA_ERROR;
+ ret = HA_CRITERROR;
goto finally;
}
@@ -532,10 +544,10 @@ static int simple_digest_response(simple_context_t* ctx, const char* header,
ha_addheader(resp, "Authentication-Info", t);
/* Put the connection into the cache */
- if(save_cached_digest(ctx, rec) == HA_ERROR)
- ret = HA_ERROR;
- else
- rec = NULL;
+ if((r = save_cached_digest(ctx, rec)) < 0)
+ ret = r;
+
+ rec = NULL;
}
finally:
@@ -612,7 +624,7 @@ int simple_init(ha_context_t* context)
{
ha_messagex(LOG_ERR, "Simple module configured, but does not implement any "
"configured authentication type.");
- return HA_ERROR;
+ return HA_FAILED;
}
@@ -621,14 +633,14 @@ int simple_init(ha_context_t* context)
{
ha_messagex(LOG_ERR, "Basic configuration incomplete. "
"Must have a PasswordFile configured.");
- return HA_ERROR;
+ return HA_FAILED;
}
fd = open(ctx->filename, O_RDONLY);
if(fd == -1)
{
ha_message(LOG_ERR, "can't open file for simple authentication: %s", ctx->filename);
- return HA_ERROR;
+ return HA_FAILED;
}
close(fd);
@@ -639,7 +651,7 @@ int simple_init(ha_context_t* context)
if(!(ctx->cache = hash_create(MD5_LEN, free_hash_object, NULL)))
{
ha_messagex(LOG_CRIT, "out of memory");
- return HA_ERROR;
+ return HA_CRITERROR;
}
/* Copy some settings over for easy access */
@@ -697,7 +709,7 @@ int simple_process(ha_context_t* context, ha_request_t* req,
{
ret = simple_digest_response(ctx, header, req->args[AUTH_ARG_METHOD],
req->args[AUTH_ARG_URI], resp, buf);
- if(ret == HA_ERROR)
+ if(ret < 0)
return ret;
}
}
@@ -709,7 +721,7 @@ int simple_process(ha_context_t* context, ha_request_t* req,
if(header)
{
ret = simple_basic_response(ctx, header, resp, buf);
- if(ret == HA_ERROR)
+ if(ret < 0)
return ret;
}
}
@@ -725,7 +737,7 @@ int simple_process(ha_context_t* context, ha_request_t* req,
ha_bufmcat(buf, "BASIC realm=\"", ctx->realm , "\"", NULL);
if(ha_buferr(buf))
- return HA_ERROR;
+ return HA_CRITERROR;
ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf));
}
@@ -733,7 +745,7 @@ int simple_process(ha_context_t* context, ha_request_t* req,
if(context->types & HA_TYPE_DIGEST)
{
ret = simple_digest_challenge(ctx, resp, buf, 0);
- if(ret == HA_ERROR)
+ if(ret < 0)
return ret;
}
}
diff --git a/sample/httpauthd.conf b/sample/httpauthd.conf
index f08ebad..ba8af0a 100644
--- a/sample/httpauthd.conf
+++ b/sample/httpauthd.conf
@@ -14,16 +14,19 @@ DigestDebugNonce: AkCLQA==560f26e24db2d4cecbe5d6e24d958377ab73def9
[LDAP]
Realm: blah
LDAPServers: authdev.ws.local
-LDAPDoBind: True
+LDAPDoBind: False
LDAPDNMap: cn=%u,ou=test,dc=fam
DigestDomains: http://test.ws.local/
+LDAPUser: cn=root,dc=fam
+LDAPPassword: ldaptest@@password
+LDAPHA1Attr: login
+# LDAPPWAttr: clearPassword
+
+LDAPFilter: (&(comment=%r)(&(cn=%u)(objectClass=contactInfo)))
+LDAPBase: ou=test,dc=fam
+LDAPScope: one
+
+DigestDebugNonce: AkCLQA==560f26e24db2d4cecbe5d6e24d958377ab73def9
-# LDAPFilter:
-# LDAPBase:
-# LDAPPWAttr:
-# LDAPHA1Attr:
-# LDAPUser:
-# LDAPPassword:
-# LDAPScope:
# LDAPMax:
# LDAPTimeout: