From 2c1dec428c6e1d1bb6675847a5046a4fabdfe4c4 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Thu, 29 Apr 2004 03:55:57 +0000 Subject: - Added documentation - Fixed bugs - Added support for dns to sock_any --- daemon/defaults.h | 2 +- daemon/digest.c | 87 ++++++++++++++++++++++++++++++++++-------------------- daemon/digest.h | 4 +-- daemon/httpauthd.c | 10 +++++++ daemon/httpauthd.h | 3 +- daemon/ldap.c | 20 ++++++------- daemon/simple.c | 14 ++++----- 7 files changed, 85 insertions(+), 55 deletions(-) (limited to 'daemon') diff --git a/daemon/defaults.h b/daemon/defaults.h index 828bec1..b3c6fcf 100644 --- a/daemon/defaults.h +++ b/daemon/defaults.h @@ -3,7 +3,7 @@ #define __DEFAULTS_H__ #define DEFAULT_PENDING_MAX 16 -#define DEFAULT_PENDING_TIMEOUT 60 +#define DEFAULT_PENDING_TIMEOUT 20 #define DEFAULT_TIMEOUT 900 #define DEFAULT_CACHEMAX 1024 #define DEFAULT_PORT 8020 diff --git a/daemon/digest.c b/daemon/digest.c index 0bd6398..5c53191 100644 --- a/daemon/digest.c +++ b/daemon/digest.c @@ -242,7 +242,7 @@ int digest_parse(char* header, ha_buffer_t* buf, digest_header_t* rec, if(rec->nonce) { size_t len = DIGEST_NONCE_LEN; - void* d = ha_bufdec64(buf, rec->nonce, &len); + void* d = ha_bufdechex(buf, rec->nonce, &len); if(d && len == DIGEST_NONCE_LEN) memcpy(nonce, d, DIGEST_NONCE_LEN); @@ -252,15 +252,15 @@ int digest_parse(char* header, ha_buffer_t* buf, digest_header_t* rec, return HA_OK; } -int digest_check(const char* realm, const char* method, const char* uri, - ha_buffer_t* buf, digest_header_t* dg, digest_record_t* rec) +int digest_check(digest_header_t* dg, digest_record_t* rec, ha_options_t* opts, + ha_buffer_t* buf, const char* method, const char* uri) { unsigned char hash[MD5_LEN]; md5_ctx_t md5; const char* digest; const char* t; - ASSERT(realm && method && uri && buf && dg && rec); + ASSERT(opts && method && buf && dg && rec); /* TODO: Many of these should somehow communicate BAD REQ back to the client */ @@ -272,21 +272,31 @@ int digest_check(const char* realm, const char* method, const char* uri, } /* Username */ - if(!dg->username || !dg->username[0] || - md5_strcmp(rec->userhash, dg->username) != 0) + if(!dg->username || !dg->username[0]) { ha_messagex(LOG_WARNING, "digest response missing username"); return HA_BADREQ; } + if(md5_strcmp(rec->userhash, dg->username) != 0) + { + ha_messagex(LOG_ERR, "digest response contains invalid username"); + return HA_FALSE; + } + /* The realm */ - if(!dg->realm || strcmp(dg->realm, realm) != 0) + if(!dg->realm) { - ha_messagex(LOG_WARNING, "digest response contains invalid realm: '%s'", - dg->realm ? dg->realm : ""); + ha_messagex(LOG_WARNING, "digest response contains missing realm"); return HA_BADREQ; } + if(strcmp(dg->realm, opts->realm) != 0) + { + ha_messagex(LOG_ERR, "digest response contains invalid realm: %s", dg->realm); + return HA_FALSE; + } + /* Components in the new RFC */ if(dg->qop) { @@ -308,25 +318,38 @@ int digest_check(const char* realm, const char* method, const char* uri, return HA_BADREQ; } - /* The nonce count */ - if(!dg->nc || !dg->nc[0]) + if(!opts->digest_ignorenc) { - ha_messagex(LOG_WARNING, "digest response is missing nc value"); - return HA_BADREQ; - } - - /* Validate the nc */ - else - { - char* e; - long nc = strtol(dg->nc, &e, 10); - - if(*e || nc != rec->nc) + /* The nonce count */ + if(!dg->nc || !dg->nc[0]) { - ha_messagex(LOG_WARNING, "digest response has invalid nc value: %s", - dg->nc); + ha_messagex(LOG_WARNING, "digest response is missing nc value"); return HA_BADREQ; } + + /* Validate the nc */ + else + { + char* e; + long nc = strtol(dg->nc, &e, 16); + + if(*e) + { + ha_messagex(LOG_ERR, "digest response has invalid nc value: %s", dg->nc); + return HA_BADREQ; + } + + /* If we didn't a nc then save it away */ + if(!*e && rec->nc == 0) + rec->nc = nc; + + if(*e || nc != rec->nc) + { + ha_messagex(LOG_WARNING, "digest response has wrong nc value. " + "possible replay attack: %s", dg->nc); + return HA_FALSE; + } + } } } @@ -345,7 +368,7 @@ int digest_check(const char* realm, const char* method, const char* uri, return HA_BADREQ; } - if(strcmp(dg->uri, uri) != 0) + if(!opts->digest_ignoreuri && strcmp(dg->uri, uri) != 0) { ha_uri_t d_uri; ha_uri_t s_uri; @@ -370,9 +393,9 @@ int digest_check(const char* realm, const char* method, const char* uri, 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_BADREQ; + ha_messagex(LOG_ERR, "digest response contains wrong uri: %s " + "(should be %s)", dg->uri, uri); + return HA_FALSE; } } @@ -523,14 +546,14 @@ const char* digest_respond(ha_buffer_t* buf, digest_header_t* dg, return NULL; ha_bufmcat(buf, "rspauth=\"", t, "\"", - " qop=", dg->qop, - " nc=", dg->nc, - " cnonce=\"", dg->cnonce, "\"", NULL); + ", qop=", dg->qop, + ", nc=", dg->nc, + ", cnonce=\"", dg->cnonce, "\"", NULL); if(nextnonce) { ha_bufjoin(buf); - ha_bufmcat(buf, " nextnonce=\"", nextnonce, "\"", NULL); + ha_bufmcat(buf, ", nextnonce=\"", nextnonce, "\"", NULL); } return ha_bufdata(buf); diff --git a/daemon/digest.h b/daemon/digest.h index 0f5e6b2..8eec901 100644 --- a/daemon/digest.h +++ b/daemon/digest.h @@ -42,8 +42,8 @@ int ha_digestparse(char* header, ha_buffer_t* buf, digest_header_t* rec, int ha_digestnonce(time_t* tm, unsigned char* nonce); -int ha_digestcheck(const char* realm, const char* method, const char* uri, - ha_buffer_t* buf, digest_header_t* header, digest_record_t* rec); +int digest_check(digest_header_t* dg, digest_record_t* rec, ha_options_t* opts, + ha_buffer_t* buf, const char* method, const char* uri); const char* digest_respond(ha_buffer_t* buf, digest_header_t* dg, digest_record_t* rec, unsigned char* next); diff --git a/daemon/httpauthd.c b/daemon/httpauthd.c index 7c74754..55092db 100644 --- a/daemon/httpauthd.c +++ b/daemon/httpauthd.c @@ -1314,6 +1314,16 @@ static int config_parse(const char* file, ha_buffer_t* buf) recog = 1; } + else if(strcmp(name, "digestignorenc") == 0) + { + int v; + if(ha_confbool(name, value, &v) < 0) + exit(1); /* Message already printed */ + + opts->digest_ignorenc = v; + recog = 1; + } + else if(strcmp(name, "digestdomains") == 0) { opts->digest_domains = value; diff --git a/daemon/httpauthd.h b/daemon/httpauthd.h index cd1d39e..d225e4b 100644 --- a/daemon/httpauthd.h +++ b/daemon/httpauthd.h @@ -188,7 +188,8 @@ typedef struct ha_options const char* realm; /* For digest auth: */ - int digest_ignoreuri; + unsigned int digest_ignoreuri : 1; + unsigned int digest_ignorenc : 1; const char* digest_domains; const char* digest_debugnonce; } diff --git a/daemon/ldap.c b/daemon/ldap.c index 78e048f..1e03c32 100644 --- a/daemon/ldap.c +++ b/daemon/ldap.c @@ -981,7 +981,7 @@ static int digest_ldap_challenge(ldap_context_t* ctx, ha_response_t* resp, if(ctx->opts->digest_debugnonce) { nonce_str = ctx->opts->digest_debugnonce; - ha_messagex(LOG_WARNING, "simple: using debug nonce. security non-existant."); + ha_messagex(LOG_WARNING, "ldap: using debug nonce. security non-existant."); } else #endif @@ -1036,7 +1036,6 @@ static int digest_ldap_response(ldap_context_t* ctx, const char* header, if(dg.nonce && strcmp(dg.nonce, ctx->opts->digest_debugnonce) != 0) { ret = HA_FALSE; - resp->code = HA_SERVER_BADREQ; ha_messagex(LOG_WARNING, "ldap: digest response contains invalid nonce"); goto finally; } @@ -1054,10 +1053,7 @@ 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, "ldap: digest response contains invalid nonce"); - } goto finally; } @@ -1099,11 +1095,13 @@ static int digest_ldap_response(ldap_context_t* ctx, const char* header, } } - /* Increment our nonce count */ - rec->nc++; + /* We had a record so ... */ + else + { + rec->nc++; + } - ret = digest_check(ctx->opts->realm, method, - ctx->opts->digest_ignoreuri ? NULL : uri, buf, &dg, rec); + ret = digest_check(&dg, rec, ctx->opts, buf, method, uri); if(ret == HA_BADREQ) { @@ -1391,7 +1389,7 @@ int ldap_process(ha_context_t* context, ha_request_t* req, header = ha_getheader(req, "Authorization", HA_PREFIX_DIGEST); if(header) { - ha_messagex(LOG_DEBUG, "ldap: processing basic auth header"); + ha_messagex(LOG_DEBUG, "ldap: processing digest auth header"); ret = digest_ldap_response(ctx, header, req->args[AUTH_ARG_METHOD], req->args[AUTH_ARG_URI], resp, buf); if(ret < 0) @@ -1405,7 +1403,7 @@ int ldap_process(ha_context_t* context, ha_request_t* req, header = ha_getheader(req, "Authorization", HA_PREFIX_BASIC); if(header) { - ha_messagex(LOG_DEBUG, "ldap: processing digest auth header"); + ha_messagex(LOG_DEBUG, "ldap: processing basic auth header"); ret = basic_ldap_response(ctx, header, resp, buf); if(ret < 0) return ret; diff --git a/daemon/simple.c b/daemon/simple.c index 5b4eb60..d45668f 100644 --- a/daemon/simple.c +++ b/daemon/simple.c @@ -458,7 +458,6 @@ static int simple_digest_response(simple_context_t* ctx, const char* header, { if(dg.nonce && strcmp(dg.nonce, ctx->opts->digest_debugnonce) != 0) { - resp->code = HA_SERVER_BADREQ; ret = HA_FALSE; ha_messagex(LOG_WARNING, "simple: digest response contains invalid nonce"); goto finally; @@ -477,10 +476,7 @@ 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, "simple: digest response contains invalid nonce"); - } ret = r; goto finally; @@ -523,11 +519,13 @@ static int simple_digest_response(simple_context_t* ctx, const char* header, } } - /* Increment our nonce count */ - rec->nc++; + /* We had a record so ... */ + else + { + rec->nc++; + } - ret = digest_check(ctx->opts->realm, method, - ctx->opts->digest_ignoreuri ? NULL : uri, buf, &dg, rec); + ret = digest_check(&dg, rec, ctx->opts, buf, method, uri); if(ret == HA_BADREQ) { -- cgit v1.2.3