60#define APR_WANT_STRFUNC
98#define DFLT_ALGORITHM "MD5"
100#define DFLT_NONCE_LIFE apr_time_from_sec(300)
101#define NEXTNONCE_DELTA apr_time_from_sec(30)
104#define NONCE_TIME_LEN (((sizeof(apr_time_t)+2)/3)*4)
105#define NONCE_HASH_LEN (2*APR_SHA1_DIGESTSIZE)
106#define NONCE_LEN (int )(NONCE_TIME_LEN + NONCE_HASH_LEN)
109#define RETAINED_DATA_ID "mod_auth_digest"
181#define DEF_SHMEM_SIZE 1000L
182#define DEF_NUM_BUCKETS 15L
189module AP_MODULE_DECLARE_DATA auth_digest_module;
198 "cleaning up shared memory");
228 "%s - all nonce-count checking and one-time nonces "
244 return apr_rmm_addr_get(rmm,
offset);
251 return apr_rmm_free(rmm,
offset);
254#if APR_HAS_SHARED_MEMORY
292 "Failed to create shared memory segment on file %s",
378 "generating secret for digest authentication");
382#error APR random number support is missing
386 "error generating secret");
403#if APR_HAS_SHARED_MEMORY
414 if (initialize_tables(
s,
p) !=
OK) {
469 conf->
qop_list = apr_array_make(
p, 2,
sizeof(
char *));
505 apr_sha1_update_binary(&conf->
nonce_ctx, (
const unsigned char *) realm,
528 return apr_psprintf(
cmd->pool,
529 "Unknown Authn provider: %s",
535 return apr_psprintf(
cmd->pool,
536 "The '%s' Authn provider doesn't support "
562 *(
const char **)apr_array_push(conf->
qop_list) =
"none";
567 return "AuthDigestQop auth-int is not implemented";
570 return apr_pstrcat(
cmd->pool,
"Unrecognized qop: ", op,
NULL);
573 *(
const char **)apr_array_push(conf->
qop_list) = op;
584 lifetime = strtol(
t, &endptr, 10);
586 return apr_pstrcat(
cmd->pool,
587 "Invalid time in AuthDigestNonceLifetime: ",
598 return "AuthDigestNonceFormat is not implemented";
603#if !APR_HAS_SHARED_MEMORY
605 return "AuthDigestNcCheck: ERROR: nonce-count checking "
606 "is not supported on platforms without shared-memory "
618 return "AuthDigestAlgorithm: ERROR: algorithm `MD5-sess' "
619 "is not implemented";
622 return apr_pstrcat(
cmd->pool,
"Invalid algorithm in AuthDigestAlgorithm: ", alg,
NULL);
633 c->uri_list[strlen(
c->uri_list)-1] =
'\0';
634 c->uri_list = apr_pstrcat(
cmd->pool,
c->uri_list,
" ",
uri,
"\"",
NULL);
637 c->uri_list = apr_pstrcat(
cmd->pool,
", domain=\"",
uri,
"\"",
NULL);
643 const char *size_str)
648 size = strtol(size_str, &endptr, 10);
650 if (*endptr ==
'\0' || *endptr ==
'b' || *endptr ==
'B') {
653 else if (*endptr ==
'k' || *endptr ==
'K') {
656 else if (*endptr ==
'm' || *endptr ==
'M') {
660 return apr_pstrcat(
cmd->pool,
"Invalid size in AuthDigestShmemSize: ",
666 return apr_psprintf(
cmd->pool,
"size in AuthDigestShmemSize too small: "
677 "Set shmem-size: %" APR_SIZE_T_FMT
", num-buckets: %ld",
686 "The authentication realm (e.g. \"Members Only\")"),
688 "specify the auth providers for a directory or location"),
690 "A list of quality-of-protection options"),
692 "Maximum lifetime of the server nonce (seconds)"),
694 "The format to use when generating the server nonce"),
696 "Whether or not to check the nonce-count sent by the client"),
698 "The algorithm used for the hash calculation"),
700 "A list of URI's which belong to the same protection space as the current URI"),
702 "The amount of shared memory to allocate for keeping track of clients"),
776 while (entry &&
key != entry->
key) {
791 "get_client(): client %lu found",
key);
795 "get_client(): client %lu not found",
key);
809 unsigned long num_removed = 0, idx;
822 while (entry->
next) {
841 "Failed to free auth_digest client allocation");
878 long num_removed =
gc(
s);
880 "gc'd %ld client entries. Total new clients: "
881 "%ld; Total removed clients: %ld; Total renewed clients: "
888 "unable to allocate new auth_digest client");
906 "allocated new client %lu",
key);
919 const char *auth_line;
926 ?
"Proxy-Authorization"
939 l = strlen(auth_line);
944 while (auth_line[0] !=
'\0') {
952 while (auth_line[0] !=
'=' && auth_line[0] !=
','
953 && auth_line[0] !=
'\0' && !
apr_isspace(auth_line[0])) {
954 key[vk++] = *auth_line++;
964 if (auth_line[0] ==
'=') {
970 if (auth_line[0] ==
'\"') {
972 while (auth_line[0] !=
'\"' && auth_line[0] !=
'\0') {
973 if (auth_line[0] ==
'\\' && auth_line[1] !=
'\0') {
976 value[vv++] = *auth_line++;
978 if (auth_line[0] !=
'\0') {
983 while (auth_line[0] !=
',' && auth_line[0] !=
'\0'
985 value[vv++] = *auth_line++;
991 while (auth_line[0] !=
',' && auth_line[0] !=
'\0') {
994 if (auth_line[0] !=
'\0') {
1094 apr_sha1_update_binary(&
ctx, (
const unsigned char *) timestr, strlen(timestr));
1096 apr_sha1_update_binary(&
ctx, (
const unsigned char *) opaque,
1099 apr_sha1_final(sha1, &
ctx);
1121 t.time = (*otn_counter)++;
1127 apr_base64_encode_binary(nonce,
t.arr,
sizeof(
t.arr));
1152 op = (*opaque_cntr)++;
1157 "failed to allocate client entry - ignoring client");
1172 return apr_psprintf(
p,
"%lx",
num);
1183 const char *qop, *opaque, *opaque_param, *domain, *nonce;
1186 if (apr_is_empty_array(conf->
qop_list)) {
1187 qop =
", qop=\"auth\"";
1193 qop = apr_pstrcat(
r->
pool,
", qop=\"",
1230 opaque_param = apr_pstrcat(
r->
pool,
", opaque=\"", opaque,
"\"",
NULL);
1233 opaque_param =
NULL;
1262 ?
"Proxy-Authenticate" :
"WWW-Authenticate",
1263 apr_psprintf(
r->
pool,
"Digest realm=\"%s\", "
1264 "nonce=\"%s\", algorithm=%s%s%s%s%s",
1266 opaque_param ? opaque_param :
"",
1267 domain ? domain :
"",
1268 stale ?
", stale=true" :
"", qop));
1285 mainreq = mainreq->
main;
1288 mainreq = mainreq->
prev;
1291 &auth_digest_module);
1298 &auth_digest_module);
1324 if (!current_provider) {
1331 "No Authn provider configured");
1338 provider = current_provider->
provider;
1359 current_provider = current_provider->
next;
1360 }
while (current_provider);
1379 "cannot check nonce count without shared memory");
1387 if (!apr_is_empty_array(conf->
qop_list) &&
1392 "invalid nc %s received - no nonce count allowed when qop=none",
1400 nc = strtol(snc, &endptr, 16);
1401 if (endptr < (snc+strlen(snc)) && !
apr_isspace(*endptr)) {
1403 "invalid nc %s received - not a number", snc);
1413 "Warning, possible replay attack: nonce-count "
1414 "check failed: %lu != %lu", nc,
1435 "invalid nonce '%s' received - length is not %d "
1436 "or time encoding is incorrect",
1444 apr_base64_decode_binary(nonce_time.
arr, resp->
nonce);
1451 "invalid nonce %s received - hash is not %s",
1460 "invalid nonce %s received - user attempted "
1461 "time travel", resp->
nonce);
1469 "user %s: nonce expired (%.2f seconds old "
1470 "- max lifetime %.2f) - sending new nonce",
1480 "user %s: one-time-nonce mismatch - sending "
1481 "new nonce",
r->
user);
1502 (
unsigned char *)apr_pstrcat(
r->
pool, resp->
ha1,
":",
1510 const char *ha1, *ha2, *a2;
1518 (
unsigned char *)apr_pstrcat(
r->
pool, ha1,
":", resp->
nonce,
1527 if (
src->scheme &&
src->scheme[0] !=
'\0') {
1531 dst->
scheme = (
char *)
"http";
1534 if (
src->hostname &&
src->hostname[0] !=
'\0') {
1542 if (
src->port_str &&
src->port_str[0] !=
'\0') {
1549 if (
src->path &&
src->path[0] !=
'\0') {
1557 if (
src->query &&
src->query[0] !=
'\0') {
1599 "need AuthName: %s",
r->
uri);
1608 mainreq = mainreq->
main;
1611 mainreq = mainreq->
prev;
1614 &auth_digest_module);
1621 &auth_digest_module);
1629 "client used wrong authentication scheme `%s': %s",
1634 "missing user, realm, nonce, uri, digest, "
1635 "cnonce, or nonce_count in authorization header: %s",
1657 "invalid uri <%s> in Authorization header",
1672 else if (r_uri.
query) {
1689 "AuthDigestEnableQueryStringHack")) {
1692 "applying AuthDigestEnableQueryStringHack "
1702 "uri mismatch - <%s> does not match "
1723 && d_uri.
path[0] ==
'*' && d_uri.
path[1] ==
'\0'))
1730 "uri mismatch - <%s> does not match "
1738 "received invalid opaque - got `%s'",
1746 "realm mismatch - got `%s' but no realm specified",
1754 "realm mismatch - got `%s' but expected `%s'",
1763 "unknown algorithm `%s' received: %s",
1773 "user `%s' in realm `%s' not found: %s",
1784 "user `%s' in realm `%s' denied by provider: %s",
1801 "user %s: password mismatch: %s",
r->
user,
1808 const char *exp_digest;
1810 const char **tmp = (
const char **)(conf->
qop_list->
elts);
1820 && !(apr_is_empty_array(conf->
qop_list)
1823 "invalid qop `%s' received: %s",
1834 if (strcmp(resp->
digest, exp_digest)) {
1836 "user %s: password mismatch: %s",
r->
user,
1865 &auth_digest_module);
1868 &auth_digest_module);
1869 const char *ai =
NULL, *nextnonce =
"";
1883 nextnonce = apr_pstrcat(
r->
pool,
", nextnonce=\"",
1894 nextnonce = apr_pstrcat(
r->
pool,
", nextnonce=\"", nonce,
"\"",
NULL);
1902 if (!apr_is_empty_array(conf->
qop_list) &&
1909 const char *resp_dig, *ha1, *a2, *ha2;
1919 (
unsigned char *)apr_pstrcat(
r->
pool, ha1,
":",
1929 ai = apr_pstrcat(
r->
pool,
1930 "rspauth=\"", resp_dig,
"\"",
1932 resp->
cnonce ?
", cnonce=\"" :
"",
1936 resp->
cnonce ?
"\"" :
"",
1947 ?
"Proxy-Authentication-Info"
1948 :
"Authentication-Info",
1957 static const char *
const cfgPost[]={
"http_core.c",
NULL };
1958 static const char *
const parsePre[]={
"mod_proxy.c",
NULL };
Symbol export macros and hook functions.
int int const char ** match
APR-UTIL Base64 Encoding.
APR Global Locking Routines.
APR general purpose library routines.
APR-UTIL Relocatable Memory Management Routines.
#define APR_SHA1_DIGESTSIZE
APR Shared Memory Routines.
APR Standard Headers Support.
static event_retained_data * retained
static apr_pool_t * pconf
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
char * ap_runtime_dir_relative(apr_pool_t *p, const char *fname)
#define ap_get_module_config(v, m)
void ap_hook_post_config(ap_HOOK_post_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
#define AP_DECLARE_MODULE(foo)
#define AP_INIT_FLAG(directive, func, mconfig, where, help)
#define AP_INIT_ITERATE(directive, func, mconfig, where, help)
#define ap_set_module_config(v, m, val)
void ap_hook_pre_config(ap_HOOK_pre_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
void * ap_retained_data_create(const char *key, apr_size_t size)
void * ap_retained_data_get(const char *key)
void ap_hook_child_init(ap_HOOK_child_init_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
#define ap_default_port(r)
apr_port_t ap_get_server_port(const request_rec *r)
#define AP_SQ_MS_CREATE_PRE_CONFIG
int ap_state_query(int query_code)
const char * ap_get_server_name(request_rec *r)
const char * ap_auth_name(request_rec *r)
const char * ap_auth_type(request_rec *r)
apr_status_t ap_global_mutex_create(apr_global_mutex_t **mutex, const char **name, const char *type, const char *instance_id, server_rec *server, apr_pool_t *pool, apr_int32_t options)
apr_status_t ap_mutex_register(apr_pool_t *pconf, const char *type, const char *default_dir, apr_lockmech_e default_mech, apr_int32_t options)
void ap_hook_note_auth_failure(ap_HOOK_note_auth_failure_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
void ap_hook_post_read_request(ap_HOOK_post_read_request_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
void * ap_lookup_provider(const char *provider_group, const char *provider_name, const char *provider_version)
#define AP_AUTH_INTERNAL_PER_CONF
int ap_is_initial_req(request_rec *r)
void ap_hook_fixups(ap_HOOK_fixups_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
void ap_hook_check_authn(ap_HOOK_check_user_id_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder, int type)
#define APR_STATUS_IS_ENOTIMPL(s)
apr_brigade_flush void * ctx
apr_pool_t apr_dbd_t apr_dbd_results_t ** res
apr_memcache_server_t * server
#define HTTP_INTERNAL_SERVER_ERROR
#define HTTP_UNAUTHORIZED
#define STANDARD20_MODULE_STUFF
char * ap_append_pid(apr_pool_t *p, const char *string, const char *delim)
char * ap_getword_white(apr_pool_t *p, const char **line)
int ap_cstr_casecmp(const char *s1, const char *s2)
void ap_bin2hex(const void *src, apr_size_t srclen, char *dest)
int ap_unescape_url(char *url)
char * ap_escape_quotes(apr_pool_t *p, const char *instring)
const char apr_int32_t flag
apr_seek_where_t apr_off_t * offset
int strcasecmp(const char *a, const char *b)
apr_vformatter_buff_t const char * fmt
apr_vformatter_buff_t * c
apr_interval_time_t apr_int32_t * num
#define apr_pcalloc(p, size)
const char const char * password
apr_int32_t apr_int32_t apr_int32_t err
#define apr_time_sec(time)
#define apr_time_from_sec(sec)
Authentication and Authorization Extension for Apache.
#define AUTHN_PROVIDER_NAME_NOTE
#define AUTHN_PROVIDER_VERSION
#define AUTHN_PROVIDER_GROUP
#define AUTHN_DEFAULT_PROVIDER
static client_entry * get_client(unsigned long key, const request_rec *r)
static int check_nonce(request_rec *r, digest_header_rec *resp, const digest_config_rec *conf)
struct digest_config_struct digest_config_rec
static const char * client_shm_filename
static void log_error_and_cleanup(char *msg, apr_status_t sts, server_rec *s)
static struct hash_table * client_list
static void gen_nonce_hash(char *hash, const char *timestr, const char *opaque, const server_rec *server, const digest_config_rec *conf)
static apr_global_mutex_t * client_lock
static const command_rec digest_cmds[]
static authn_status get_hash(request_rec *r, const char *user, digest_config_rec *conf, const char **rethash)
static const char * set_uri_list(cmd_parms *cmd, void *config, const char *uri)
static const char * old_digest(const request_rec *r, const digest_header_rec *resp)
static apr_time_t * otn_counter
static int initialize_module(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
static void * create_digest_dir_config(apr_pool_t *p, char *dir)
static apr_shm_t * client_shm
static apr_status_t cleanup_tables(void *not_used)
static const char * ltox(apr_pool_t *p, unsigned long num)
static void initialize_child(apr_pool_t *p, server_rec *s)
static const char * add_authn_provider(cmd_parms *cmd, void *config, const char *arg)
static const char * set_shmem_size(cmd_parms *cmd, void *config, const char *size_str)
static long gc(server_rec *s)
static const char * client_mutex_type
static void * rmm_malloc(apr_rmm_t *rmm, apr_size_t size)
static int check_nc(const request_rec *r, const digest_header_rec *resp, const digest_config_rec *conf)
static const char * opaque_mutex_type
static void register_hooks(apr_pool_t *p)
static client_entry * add_client(unsigned long key, client_entry *info, server_rec *s)
static apr_global_mutex_t * opaque_lock
static int add_auth_info(request_rec *r)
static int hook_note_digest_auth_failure(request_rec *r, const char *auth_type)
static int authenticate_digest_user(request_rec *r)
static const char * set_realm(cmd_parms *cmd, void *config, const char *realm)
static unsigned long * opaque_cntr
union time_union time_rec
static void copy_uri_components(apr_uri_t *dst, apr_uri_t *src, request_rec *r)
static const char * set_nonce_format(cmd_parms *cmd, void *config, const char *fmt)
static int get_digest_rec(request_rec *r, digest_header_rec *resp)
struct digest_header_struct digest_header_rec
static const char * new_digest(const request_rec *r, digest_header_rec *resp)
static int pre_init(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
static void note_digest_auth_failure(request_rec *r, const digest_config_rec *conf, digest_header_rec *resp, int stale)
static const char * gen_nonce(apr_pool_t *p, apr_time_t now, const char *opaque, const server_rec *server, const digest_config_rec *conf)
static const char * set_nonce_lifetime(cmd_parms *cmd, void *config, const char *t)
static const char * set_qop(cmd_parms *cmd, void *config, const char *op)
static unsigned long num_buckets
static apr_size_t shmem_size
static int parse_hdr_and_update_nc(request_rec *r)
static const char * set_nc_check(cmd_parms *cmd, void *config, int flag)
struct hash_entry client_entry
static apr_status_t rmm_free(apr_rmm_t *rmm, void *alloc)
static const char * set_algorithm(cmd_parms *cmd, void *config, const char *alg)
static client_entry * gen_client(const request_rec *r)
static unsigned char * secret
static apr_rmm_t * client_rmm
authn_provider_list * next
const authn_provider * provider
const char * provider_name
authn_status(* get_realm_hash)(request_rec *r, const char *user, const char *realm, char **rethash)
apr_time_t nonce_lifetime
authn_provider_list * providers
apr_array_header_t * qop_list
unsigned long nonce_count
char last_nonce[(int)((((sizeof(apr_time_t)+2)/3) *4)+(2 *20))+1]
unsigned long num_entries
unsigned long num_renewed
unsigned long num_removed
unsigned long num_created
A structure that represents the current request.
apr_table_t * err_headers_out
struct ap_conf_vector_t * request_config
apr_table_t * subprocess_env
struct ap_conf_vector_t * per_dir_config
apr_table_t * headers_out
A structure to store information for each virtual server.
unsigned char arr[sizeof(apr_time_t)]
char * ap_md5(apr_pool_t *p, const unsigned char *string)
Apache Mutex support library.