diff options
Diffstat (limited to 'modules/aaa/mod_auth_digest.c')
-rw-r--r-- | modules/aaa/mod_auth_digest.c | 91 |
1 files changed, 49 insertions, 42 deletions
diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c index a67f069..791cec2 100644 --- a/modules/aaa/mod_auth_digest.c +++ b/modules/aaa/mod_auth_digest.c @@ -92,7 +92,6 @@ typedef struct digest_config_struct { int check_nc; const char *algorithm; char *uri_list; - const char *ha1; } digest_config_rec; @@ -153,6 +152,7 @@ typedef struct digest_header_struct { apr_time_t nonce_time; enum hdr_sts auth_hdr_sts; int needed_auth; + const char *ha1; client_entry *client; } digest_header_rec; @@ -262,6 +262,12 @@ static int initialize_tables(server_rec *s, apr_pool_t *ctx) /* Create the shared memory segment */ + client_shm = NULL; + client_rmm = NULL; + client_lock = NULL; + opaque_lock = NULL; + client_list = NULL; + /* * Create a unique filename using our pid. This information is * stashed in the global variable so the children inherit it. @@ -408,8 +414,6 @@ static int initialize_module(apr_pool_t *p, apr_pool_t *plog, if (initialize_tables(s, p) != OK) { return !OK; } - /* Call cleanup_tables on exit or restart */ - apr_pool_cleanup_register(p, NULL, cleanup_tables, apr_pool_cleanup_null); #endif /* APR_HAS_SHARED_MEMORY */ return OK; } @@ -553,16 +557,16 @@ static const char *set_qop(cmd_parms *cmd, void *config, const char *op) { digest_config_rec *conf = (digest_config_rec *) config; - if (!strcasecmp(op, "none")) { + if (!ap_cstr_casecmp(op, "none")) { apr_array_clear(conf->qop_list); *(const char **)apr_array_push(conf->qop_list) = "none"; return NULL; } - if (!strcasecmp(op, "auth-int")) { + if (!ap_cstr_casecmp(op, "auth-int")) { return "AuthDigestQop auth-int is not implemented"; } - else if (strcasecmp(op, "auth")) { + else if (ap_cstr_casecmp(op, "auth")) { return apr_pstrcat(cmd->pool, "Unrecognized qop: ", op, NULL); } @@ -610,11 +614,11 @@ static const char *set_nc_check(cmd_parms *cmd, void *config, int flag) static const char *set_algorithm(cmd_parms *cmd, void *config, const char *alg) { - if (!strcasecmp(alg, "MD5-sess")) { + if (!ap_cstr_casecmp(alg, "MD5-sess")) { return "AuthDigestAlgorithm: ERROR: algorithm `MD5-sess' " "is not implemented"; } - else if (strcasecmp(alg, "MD5")) { + else if (ap_cstr_casecmp(alg, "MD5")) { return apr_pstrcat(cmd->pool, "Invalid algorithm in AuthDigestAlgorithm: ", alg, NULL); } @@ -927,7 +931,7 @@ static int get_digest_rec(request_rec *r, digest_header_rec *resp) } resp->scheme = ap_getword_white(r->pool, &auth_line); - if (strcasecmp(resp->scheme, "Digest")) { + if (ap_cstr_casecmp(resp->scheme, "Digest")) { resp->auth_hdr_sts = NOT_DIGEST; return !OK; } @@ -991,25 +995,25 @@ static int get_digest_rec(request_rec *r, digest_header_rec *resp) auth_line++; } - if (!strcasecmp(key, "username")) + if (!ap_cstr_casecmp(key, "username")) resp->username = apr_pstrdup(r->pool, value); - else if (!strcasecmp(key, "realm")) + else if (!ap_cstr_casecmp(key, "realm")) resp->realm = apr_pstrdup(r->pool, value); - else if (!strcasecmp(key, "nonce")) + else if (!ap_cstr_casecmp(key, "nonce")) resp->nonce = apr_pstrdup(r->pool, value); - else if (!strcasecmp(key, "uri")) + else if (!ap_cstr_casecmp(key, "uri")) resp->uri = apr_pstrdup(r->pool, value); - else if (!strcasecmp(key, "response")) + else if (!ap_cstr_casecmp(key, "response")) resp->digest = apr_pstrdup(r->pool, value); - else if (!strcasecmp(key, "algorithm")) + else if (!ap_cstr_casecmp(key, "algorithm")) resp->algorithm = apr_pstrdup(r->pool, value); - else if (!strcasecmp(key, "cnonce")) + else if (!ap_cstr_casecmp(key, "cnonce")) resp->cnonce = apr_pstrdup(r->pool, value); - else if (!strcasecmp(key, "opaque")) + else if (!ap_cstr_casecmp(key, "opaque")) resp->opaque = apr_pstrdup(r->pool, value); - else if (!strcasecmp(key, "qop")) + else if (!ap_cstr_casecmp(key, "qop")) resp->message_qop = apr_pstrdup(r->pool, value); - else if (!strcasecmp(key, "nc")) + else if (!ap_cstr_casecmp(key, "nc")) resp->nonce_count = apr_pstrdup(r->pool, value); } @@ -1182,7 +1186,7 @@ static void note_digest_auth_failure(request_rec *r, if (apr_is_empty_array(conf->qop_list)) { qop = ", qop=\"auth\""; } - else if (!strcasecmp(*(const char **)(conf->qop_list->elts), "none")) { + else if (!ap_cstr_casecmp(*(const char **)(conf->qop_list->elts), "none")) { qop = ""; } else { @@ -1271,7 +1275,7 @@ static int hook_note_digest_auth_failure(request_rec *r, const char *auth_type) digest_header_rec *resp; digest_config_rec *conf; - if (strcasecmp(auth_type, "Digest")) + if (ap_cstr_casecmp(auth_type, "Digest")) return DECLINED; /* get the client response and mark */ @@ -1304,7 +1308,7 @@ static int hook_note_digest_auth_failure(request_rec *r, const char *auth_type) */ static authn_status get_hash(request_rec *r, const char *user, - digest_config_rec *conf) + digest_config_rec *conf, const char **rethash) { authn_status auth_result; char *password; @@ -1356,7 +1360,7 @@ static authn_status get_hash(request_rec *r, const char *user, } while (current_provider); if (auth_result == AUTH_USER_FOUND) { - conf->ha1 = password; + *rethash = password; } return auth_result; @@ -1381,7 +1385,7 @@ static int check_nc(const request_rec *r, const digest_header_rec *resp, } if (!apr_is_empty_array(conf->qop_list) && - !strcasecmp(*(const char **)(conf->qop_list->elts), "none")) { + !ap_cstr_casecmp(*(const char **)(conf->qop_list->elts), "none")) { /* qop is none, client must not send a nonce count */ if (snc != NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01772) @@ -1422,9 +1426,14 @@ static int check_nonce(request_rec *r, digest_header_rec *resp, time_rec nonce_time; char tmp, hash[NONCE_HASH_LEN+1]; - if (strlen(resp->nonce) != NONCE_LEN) { + /* Since the time part of the nonce is a base64 encoding of an + * apr_time_t (8 bytes), it should end with a '=', fail early otherwise. + */ + if (strlen(resp->nonce) != NONCE_LEN + || resp->nonce[NONCE_TIME_LEN - 1] != '=') { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01775) - "invalid nonce %s received - length is not %d", + "invalid nonce '%s' received - length is not %d " + "or time encoding is incorrect", resp->nonce, NONCE_LEN); note_digest_auth_failure(r, conf, resp, 1); return HTTP_UNAUTHORIZED; @@ -1483,25 +1492,24 @@ static int check_nonce(request_rec *r, digest_header_rec *resp, /* RFC-2069 */ static const char *old_digest(const request_rec *r, - const digest_header_rec *resp, const char *ha1) + const digest_header_rec *resp) { const char *ha2; ha2 = ap_md5(r->pool, (unsigned char *)apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL)); return ap_md5(r->pool, - (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce, - ":", ha2, NULL)); + (unsigned char *)apr_pstrcat(r->pool, resp->ha1, ":", + resp->nonce, ":", ha2, NULL)); } /* RFC-2617 */ static const char *new_digest(const request_rec *r, - digest_header_rec *resp, - const digest_config_rec *conf) + digest_header_rec *resp) { const char *ha1, *ha2, *a2; - ha1 = conf->ha1; + ha1 = resp->ha1; a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL); ha2 = ap_md5(r->pool, (const unsigned char *)a2); @@ -1514,7 +1522,6 @@ static const char *new_digest(const request_rec *r, NULL)); } - static void copy_uri_components(apr_uri_t *dst, apr_uri_t *src, request_rec *r) { if (src->scheme && src->scheme[0] != '\0') { @@ -1583,7 +1590,7 @@ static int authenticate_digest_user(request_rec *r) /* do we require Digest auth for this URI? */ - if (!(t = ap_auth_type(r)) || strcasecmp(t, "Digest")) { + if (!(t = ap_auth_type(r)) || ap_cstr_casecmp(t, "Digest")) { return DECLINED; } @@ -1751,7 +1758,7 @@ static int authenticate_digest_user(request_rec *r) } if (resp->algorithm != NULL - && strcasecmp(resp->algorithm, "MD5")) { + && ap_cstr_casecmp(resp->algorithm, "MD5")) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01789) "unknown algorithm `%s' received: %s", resp->algorithm, r->uri); @@ -1759,7 +1766,7 @@ static int authenticate_digest_user(request_rec *r) return HTTP_UNAUTHORIZED; } - return_code = get_hash(r, r->user, conf); + return_code = get_hash(r, r->user, conf, &resp->ha1); if (return_code == AUTH_USER_NOT_FOUND) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01790) @@ -1789,7 +1796,7 @@ static int authenticate_digest_user(request_rec *r) if (resp->message_qop == NULL) { /* old (rfc-2069) style digest */ - if (strcmp(resp->digest, old_digest(r, resp, conf->ha1))) { + if (strcmp(resp->digest, old_digest(r, resp))) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01792) "user %s: password mismatch: %s", r->user, r->uri); @@ -1802,7 +1809,7 @@ static int authenticate_digest_user(request_rec *r) int match = 0, idx; const char **tmp = (const char **)(conf->qop_list->elts); for (idx = 0; idx < conf->qop_list->nelts; idx++) { - if (!strcasecmp(*tmp, resp->message_qop)) { + if (!ap_cstr_casecmp(*tmp, resp->message_qop)) { match = 1; break; } @@ -1811,7 +1818,7 @@ static int authenticate_digest_user(request_rec *r) if (!match && !(apr_is_empty_array(conf->qop_list) - && !strcasecmp(resp->message_qop, "auth"))) { + && !ap_cstr_casecmp(resp->message_qop, "auth"))) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01793) "invalid qop `%s' received: %s", resp->message_qop, r->uri); @@ -1819,7 +1826,7 @@ static int authenticate_digest_user(request_rec *r) return HTTP_UNAUTHORIZED; } - exp_digest = new_digest(r, resp, conf); + exp_digest = new_digest(r, resp); if (!exp_digest) { /* we failed to allocate a client struct */ return HTTP_INTERNAL_SERVER_ERROR; @@ -1893,7 +1900,7 @@ static int add_auth_info(request_rec *r) /* do rfc-2069 digest */ if (!apr_is_empty_array(conf->qop_list) && - !strcasecmp(*(const char **)(conf->qop_list->elts), "none") + !ap_cstr_casecmp(*(const char **)(conf->qop_list->elts), "none") && resp->message_qop == NULL) { /* use only RFC-2069 format */ ai = nextnonce; @@ -1903,7 +1910,7 @@ static int add_auth_info(request_rec *r) /* calculate rspauth attribute */ - ha1 = conf->ha1; + ha1 = resp->ha1; a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL); ha2 = ap_md5(r->pool, (const unsigned char *)a2); |