Permalink
Browse files

moved cleanup_list init out of conf-file parsing routines

previously the array would not be allocated if the auth_digest_shm_size
directive was not used in nginx.conf leading to a deadlock
  • Loading branch information...
1 parent 909be1e commit 2199fdc449460a85cbb322f4b31a9e7f7831367b @samizdatco committed Dec 17, 2011
Showing with 32 additions and 30 deletions.
  1. +22 −13 ngx_http_auth_digest_module.c
  2. +10 −17 ngx_http_auth_digest_module.h
@@ -96,6 +96,15 @@ ngx_http_auth_digest_worker_init(ngx_cycle_t *cycle){
return NGX_OK;
}
+ // create a cleanup queue big enough for the max number of tree nodes in the shm
+ ngx_http_auth_digest_cleanup_list = ngx_array_create(cycle->pool,
+ NGX_HTTP_AUTH_DIGEST_CLEANUP_BATCH_SIZE,
+ sizeof(ngx_rbtree_node_t *));
+ if (ngx_http_auth_digest_cleanup_list==NULL){
+ ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "Could not allocate shared memory for auth_digest");
+ return NGX_ERROR;
+ }
+
ngx_connection_t *dummy;
dummy = ngx_pcalloc(cycle->pool, sizeof(ngx_connection_t));
if (dummy == NULL) return NGX_ERROR;
@@ -136,7 +145,10 @@ ngx_http_auth_digest_handler(ngx_http_request_t *r)
ngx_http_auth_digest_loc_conf_t *alcf;
ngx_http_auth_digest_cred_t *auth_fields;
u_char buf[NGX_HTTP_AUTH_DIGEST_BUF_SIZE];
-
+
+
+
+ // if digest auth is disabled for this location, bail out immediately
alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_digest_module);
if (alcf->realm.len == 0 || alcf->user_file.value.len == 0) {
return NGX_DECLINED;
@@ -441,7 +453,7 @@ ngx_http_auth_digest_verify_hash(ngx_http_request_t *r, ngx_http_auth_digest_cre
int nc = ngx_atoi(fields->nc.data, fields->nc.len-1);
if (nc<0 || nc>=alcf->replays){
- fields->stale = 1;
+ fields->stale = 1;
return NGX_DECLINED;
}
@@ -458,6 +470,14 @@ ngx_http_auth_digest_verify_hash(ngx_http_request_t *r, ngx_http_auth_digest_cre
// mark this nc as ‘used’ to prevent replays
ngx_bitvector_set(found->nc, nc);
+
+
+ // todo: if the bitvector is now ‘full’, could preemptively expire the node from the rbtree
+ // ngx_rbtree_delete(ngx_http_auth_digest_rbtree, found);
+ // ngx_slab_free_locked(shpool, found);
+
+
+
ngx_shmtx_unlock(&shpool->mutex);
// recalculate the digest with a modified HA2 value (for rspauth) and emit the
@@ -614,19 +634,8 @@ ngx_http_auth_digest_set_shm_size(ngx_conf_t *cf, ngx_command_t *cmd, void *conf
ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "Cannot change memory area size without restart, ignoring change");
} else {
ngx_http_auth_digest_shm_size = new_shm_size;
-
- // create a cleanup queue big enough for the max number of tree nodes in the shm
- ngx_uint_t count = NGX_HTTP_AUTH_DIGEST_CLEANUP_BATCH_SIZE;
- ngx_http_auth_digest_cleanup_list = ngx_array_create(cf->pool, count, sizeof(ngx_rbtree_node_t *));
-
- if (ngx_http_auth_digest_cleanup_list==NULL){
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "Could not allocate shared memory for auth_digest");
- return NGX_CONF_ERROR;
- }
-
}
ngx_conf_log_error(NGX_LOG_DEBUG, cf, 0, "Using %udKiB of shared memory for auth_digest", new_shm_size >> 10);
-
return NGX_CONF_OK;
}
@@ -91,11 +91,16 @@ static void ngx_rbtree_generic_insert(ngx_rbtree_node_t *temp,
static int ngx_http_auth_digest_rbtree_cmp(const ngx_rbtree_node_t *v_left,
const ngx_rbtree_node_t *v_right);
-
-// nc-counting
-static ngx_uint_t ngx_bitvector_size(ngx_uint_t nbits);
-static ngx_uint_t ngx_bitvector_test(char *bv, ngx_uint_t bit);
-static void ngx_bitvector_set(char *bv, ngx_uint_t bit);
+// quick & dirty bitvectors (for marking used nc values)
+static ngx_inline ngx_uint_t ngx_bitvector_size(ngx_uint_t nbits){
+ return ((nbits + CHAR_BIT - 1) / CHAR_BIT);
+}
+static ngx_inline ngx_uint_t ngx_bitvector_test(char *bv, ngx_uint_t bit){
+ return ((bv)[((bit) / CHAR_BIT)] & (1 << ((bit) % CHAR_BIT)));
+}
+static ngx_inline void ngx_bitvector_set(char *bv, ngx_uint_t bit){
+ ((bv)[((bit) / CHAR_BIT)] &= ~(1 << ((bit) % CHAR_BIT)));
+}
// module plumbing
static void *ngx_http_auth_digest_create_loc_conf(ngx_conf_t *cf);
@@ -104,7 +109,6 @@ static ngx_int_t ngx_http_auth_digest_init(ngx_conf_t *cf);
static ngx_int_t ngx_http_auth_digest_worker_init(ngx_cycle_t *cycle);
static char *ngx_http_auth_digest(ngx_conf_t *cf, void *post, void *data);
-
// module datastructures
static ngx_conf_post_handler_pt ngx_http_auth_digest_p = ngx_http_auth_digest;
static ngx_command_t ngx_http_auth_digest_commands[] = {
@@ -181,15 +185,4 @@ ngx_module_t ngx_http_auth_digest_module = {
NGX_MODULE_V1_PADDING
};
-// quick & dirty bitvectors for holding the nc usage record
-#define BITMASK(b) (1 << ((b) % CHAR_BIT))
-#define BITSLOT(b) ((b) / CHAR_BIT)
-#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
-#define BITCLEAR(a, b) ((a)[BITSLOT(b)] &= ~BITMASK(b))
-#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))
-#define BITNSLOTS(nb) ((nb + CHAR_BIT - 1) / CHAR_BIT)
-static ngx_inline ngx_uint_t ngx_bitvector_size(ngx_uint_t nbits){ return BITNSLOTS(nbits); }
-static ngx_inline ngx_uint_t ngx_bitvector_test(char *bv, ngx_uint_t bit){ return BITTEST(bv, bit); }
-static ngx_inline void ngx_bitvector_set(char *bv, ngx_uint_t bit){ BITCLEAR(bv, bit); }
-
#endif

0 comments on commit 2199fdc

Please sign in to comment.