diff options
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/basic.c | 2 | ||||
-rw-r--r-- | daemon/digest.c | 44 | ||||
-rw-r--r-- | daemon/httpauthd.c | 167 | ||||
-rw-r--r-- | daemon/httpauthd.h | 28 | ||||
-rw-r--r-- | daemon/ldap.c | 169 | ||||
-rw-r--r-- | daemon/misc.c | 14 | ||||
-rw-r--r-- | daemon/ntlm.c | 137 | ||||
-rw-r--r-- | daemon/simple.c | 102 |
8 files changed, 388 insertions, 275 deletions
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; } } |