summaryrefslogtreecommitdiffstats
path: root/modules/aaa/mod_auth_digest.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/aaa/mod_auth_digest.c')
-rw-r--r--modules/aaa/mod_auth_digest.c91
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);