static void ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, ngx_queue_t *q, u_char *name) { u_char *p; size_t len; ngx_path_t *path; ngx_http_file_cache_node_t *fcn; fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); if (fcn->exists) { cache->sh->size -= fcn->fs_size; path = cache->path; p = name + path->name.len + 1 + path->len; p = ngx_hex_dump(p, (u_char *) &fcn->node.key, sizeof(ngx_rbtree_key_t)); len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); p = ngx_hex_dump(p, fcn->key, len); *p = '\0'; fcn->count++; fcn->deleting = 1; ngx_shmtx_unlock(&cache->shpool->mutex); len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; ngx_create_hashed_filename(path, name, len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache expire: \"%s\"", name); if (ngx_delete_file(name) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno, ngx_delete_file_n " \"%s\" failed", name); } ngx_shmtx_lock(&cache->shpool->mutex); fcn->count--; fcn->deleting = 0; } if (fcn->count == 0) { ngx_queue_remove(q); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); } }
static ngx_int_t ngx_extra_var_cache_key(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { u_char *p; ngx_http_cache_t *c; c = r->cache; if (c == NULL) { v->not_found = 1; return NGX_OK; } p = ngx_pnalloc(r->pool, 2 * NGX_HTTP_CACHE_KEY_LEN); if (p == NULL) { return NGX_ERROR; } ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); v->len = 2 * NGX_HTTP_CACHE_KEY_LEN; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; v->data = p; return NGX_OK; }
static u_char * ngx_http_lua_digest_hex(u_char *dest, const u_char *buf, int buf_len) { u_char digest[MD5_DIGEST_LENGTH]; MD5(buf, buf_len, digest); return ngx_hex_dump(dest, digest, sizeof(digest)); }
static int ngx_http_lua_ngx_md5(lua_State *L) { u_char *src; size_t slen; ngx_md5_t md5; u_char md5_buf[MD5_DIGEST_LENGTH]; u_char hex_buf[2 * sizeof(md5_buf)]; if (lua_gettop(L) != 1) { return luaL_error(L, "expecting one argument"); } if (strcmp(luaL_typename(L, 1), (char *) "nil") == 0) { src = (u_char *) ""; slen = 0; } else { src = (u_char *) luaL_checklstring(L, 1, &slen); } ngx_md5_init(&md5); ngx_md5_update(&md5, src, slen); ngx_md5_final(md5_buf, &md5); ngx_hex_dump(hex_buf, md5_buf, sizeof(md5_buf)); lua_pushlstring(L, (char *) hex_buf, sizeof(hex_buf)); return 1; }
static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r, ngx_path_t *path) { u_char *p; ngx_http_cache_t *c; c = r->cache; if (c->file.name.len) { return NGX_OK; } c->file.name.len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1); if (c->file.name.data == NULL) { return NGX_ERROR; } ngx_memcpy(c->file.name.data, path->name.data, path->name.len); p = c->file.name.data + path->name.len + 1 + path->len; p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); *p = '\0'; ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "cache file: \"%s\"", c->file.name.data); return NGX_OK; }
ngx_int_t ngx_http_set_misc_set_encode_hex(ngx_http_request_t *r, ngx_str_t *res, ngx_http_variable_value_t *v) { res->len = (v->len)*2; ndk_palloc_re(res->data, r->pool, res->len); ngx_hex_dump(res->data, v->data, v->len); return NGX_OK; }
u_char * ngx_http_lua_digest_hex(u_char *dest, const u_char *buf, int buf_len) { ngx_md5_t md5; u_char md5_buf[MD5_DIGEST_LENGTH]; ngx_md5_init(&md5); ngx_md5_update(&md5, buf, buf_len); ngx_md5_final(md5_buf, &md5); return ngx_hex_dump(dest, md5_buf, sizeof(md5_buf)); }
void ngx_http_lua_ffi_md5(const u_char *src, size_t len, u_char *dst) { ngx_md5_t md5; u_char md5_buf[MD5_DIGEST_LENGTH]; ngx_md5_init(&md5); ngx_md5_update(&md5, src, len); ngx_md5_final(md5_buf, &md5); ngx_hex_dump(dst, md5_buf, sizeof(md5_buf)); }
static ngx_uint_t ngx_http_auth_mysql_check_md5(ngx_http_request_t *r, ngx_str_t sent_password, ngx_str_t actual_password) { u_char md5_str[2*MD5_DIGEST_LENGTH + 1]; u_char md5_digest[MD5_DIGEST_LENGTH]; ngx_md5_t md5; ngx_md5_init(&md5); ngx_md5_update(&md5, sent_password.data, sent_password.len); ngx_md5_final(md5_digest, &md5); ngx_hex_dump(md5_str, md5_digest, MD5_DIGEST_LENGTH); md5_str[2*MD5_DIGEST_LENGTH] = '\0'; return (ngx_strcmp(actual_password.data, md5_str) == 0)? NGX_OK : NGX_DECLINED; }
ngx_int_t ngx_http_set_misc_set_encode_hex(ngx_http_request_t *r, ngx_str_t *res, ngx_http_variable_value_t *v) { res->len = v->len << 1; res->data = ngx_palloc(r->pool, res->len); if (res->data == NULL) { return NGX_ERROR; } ngx_hex_dump(res->data, v->data, v->len); return NGX_OK; }
/* * Calculate the HMAC-SHA1 digest for a specified message with a defined key. * * @parameters: *pool pool for memory allocation; * *key the hmac key; * *message the message to digest; * * @return NGX_ERROR on error * NGX_OK on success */ static ngx_int_t ngx_apikey_hamac_sha1_digest( ngx_pool_t *pool, ngx_str_t *key, ngx_str_t *message, ngx_str_t *digest ) { ngx_str_t hmac_digest = ngx_null_string; u_char *last = NULL; hmac_digest.len = EVP_MAX_MD_SIZE; hmac_digest.data = ngx_pcalloc( pool, EVP_MAX_MD_SIZE ); if ( hmac_digest.data == NULL ) { ngx_log_error(NGX_LOG_ERR, pool->log, 0, "(%s) failed allocating memory", __func__ ); return NGX_ERROR; } /* HMAC_CTX ctx; HMAC_Init( &ctx, key->data, sizeof(key->data), EVP_sha1() ); HMAC_Update(&ctx, message->data, sizeof(message->data)); HMAC_Final(&ctx, hmac_digest.data, &hmac_digest.len ); HMAC_cleanup(&ctx); */ last = HMAC (EVP_sha1 (), (const void *)key->data, (int)key->len, message->data, (int)message->len, hmac_digest.data, (unsigned int *)&hmac_digest.len ); if ( last == NULL ) { ngx_pfree( pool, hmac_digest.data ); ngx_log_error(NGX_LOG_ERR, pool->log, 0, "(%s) failed calculating HMAC digest", __func__ ); return NGX_ERROR; } digest->len = EVP_MAX_MD_SIZE*2; digest->data = ngx_pcalloc( pool, digest->len + 1 ); if ( digest->data == NULL ) { ngx_pfree( pool, hmac_digest.data ); ngx_log_error(NGX_LOG_ERR, pool->log, 0, "(%s) failed allocating memory", __func__ ); return NGX_ERROR; } ngx_hex_dump(digest->data, hmac_digest.data, hmac_digest.len); ngx_pfree( pool, hmac_digest.data ); return NGX_OK; }
static u_char* ngx_http_memcached_hash_sha256_hash(u_char *result, const u_char *key, size_t key_length) { SHA256_CTX sha256; u_char hash[SHA256_DIGEST_LENGTH]; SHA256_Init(&sha256); SHA256_Update(&sha256, key, key_length); SHA256_Final(hash, &sha256); result = ngx_hex_dump(result, hash, SHA256_DIGEST_LENGTH); return result; }
static void ngx_rtmp_notify_set_name(u_char *dst, size_t dst_len, u_char *src, size_t src_len) { u_char result[16], *p; ngx_md5_t md5; ngx_md5_init(&md5); ngx_md5_update(&md5, src, src_len); ngx_md5_final(result, &md5); p = ngx_hex_dump(dst, result, ngx_min((dst_len - 1) / 2, 16)); *p = '\0'; }
void calc_req_digest( ngx_http_request_t* r, radius_str_t* secret, u_char* digest ) { ngx_md5_t md5; ngx_md5_init( &md5 ); ngx_md5_update( &md5, secret->s, secret->len ); ngx_md5_update( &md5, r->headers_in.user.data, r->headers_in.user.len ); ngx_md5_update( &md5, r->headers_in.passwd.data, r->headers_in.passwd.len ); u_char d[ 16 ]; ngx_md5_final( d, &md5 ); ngx_hex_dump( digest, d, sizeof( d ) ); }
ngx_int_t ngx_http_sticky_misc_hmac_sha1(ngx_pool_t *pool, void *in, size_t len, ngx_str_t *key, ngx_str_t *digest) { u_char hash[SHA_DIGEST_LENGTH]; u_char k[SHA_CBLOCK]; ngx_sha1_t sha1; u_int i; digest->data = ngx_pcalloc(pool, SHA_DIGEST_LENGTH * 2); if (digest->data == NULL) { return NGX_ERROR; } digest->len = SHA_DIGEST_LENGTH * 2; ngx_memzero(k, sizeof(k)); if (key->len > SHA_CBLOCK) { ngx_sha1_init(&sha1); ngx_sha1_update(&sha1, key->data, key->len); ngx_sha1_final(k, &sha1); } else { ngx_memcpy(k, key->data, key->len); } /* XOR ipad */ for (i=0; i < SHA_CBLOCK; i++) { k[i] ^= 0x36; } ngx_sha1_init(&sha1); ngx_sha1_update(&sha1, k, SHA_CBLOCK); ngx_sha1_update(&sha1, in, len); ngx_sha1_final(hash, &sha1); /* Convert k to opad -- 0x6A = 0x36 ^ 0x5C */ for (i=0; i < SHA_CBLOCK; i++) { k[i] ^= 0x6a; } ngx_sha1_init(&sha1); ngx_sha1_update(&sha1, k, SHA_CBLOCK); ngx_sha1_update(&sha1, hash, SHA_DIGEST_LENGTH); ngx_sha1_final(hash, &sha1); ngx_hex_dump(digest->data, hash, SHA_DIGEST_LENGTH); return NGX_OK; }
/* serialize the session id from lua context into buf. * the memory allocation of buf should be handled externally. */ int ngx_http_lua_ffi_ssl_get_session_id(ngx_http_request_t *r, u_char *buf, char **err) { int id_len; u_char *id; ngx_ssl_conn_t *ssl_conn; ngx_connection_t *c; ngx_http_lua_ssl_ctx_t *cctx; c = r->connection; if (c == NULL || c->ssl == NULL) { *err = "bad request"; return NGX_ERROR; } ssl_conn = c->ssl->connection; if (ssl_conn == NULL) { *err = "bad ssl conn"; return NGX_ERROR; } dd("get cctx session"); cctx = ngx_http_lua_ssl_get_ctx(c->ssl->connection); if (cctx == NULL) { *err = "bad lua context"; return NGX_ERROR; } id = cctx->session_id.data; if (id == NULL) { *err = "uninitialized session id in lua context"; return NGX_ERROR; } id_len = cctx->session_id.len; if (id_len == 0) { *err = "uninitialized session id len in lua context"; return NGX_ERROR; } ngx_hex_dump(buf, id, id_len); return NGX_OK; }
ngx_int_t ngx_http_sticky_misc_md5(ngx_pool_t *pool, void *in, size_t len, ngx_str_t *digest) { ngx_md5_t md5; u_char hash[MD5_DIGEST_LENGTH]; digest->data = ngx_pcalloc(pool, MD5_DIGEST_LENGTH * 2); if (digest->data == NULL) { return NGX_ERROR; } digest->len = MD5_DIGEST_LENGTH * 2; ngx_md5_init(&md5); ngx_md5_update(&md5, in, len); ngx_md5_final(hash, &md5); ngx_hex_dump(digest->data, hash, MD5_DIGEST_LENGTH); return NGX_OK; }
ngx_int_t ngx_http_sticky_misc_sha1(ngx_pool_t *pool, void *in, size_t len, ngx_str_t *digest) { ngx_sha1_t sha1; u_char hash[SHA_DIGEST_LENGTH]; digest->data = ngx_pcalloc(pool, SHA_DIGEST_LENGTH * 2); if (digest->data == NULL) { return NGX_ERROR; } digest->len = SHA_DIGEST_LENGTH * 2; ngx_sha1_init(&sha1); ngx_sha1_update(&sha1, in, len); ngx_sha1_final(hash, &sha1); ngx_hex_dump(digest->data, hash, SHA_DIGEST_LENGTH); return NGX_OK; }
static ngx_int_t ngx_http_upstream_session_sticky_set_sid(ngx_conf_t *cf, ngx_http_ss_server_t *s) { u_char buf[16]; ngx_md5_t md5; s->sid.len = 32; s->sid.data = ngx_pnalloc(cf->pool, 32); if (s->sid.data == NULL) { return NGX_ERROR; } ngx_md5_init(&md5); ngx_md5_update(&md5, s->name->data, s->name->len); ngx_md5_final(buf, &md5); ngx_hex_dump(s->sid.data, buf, 16); return NGX_OK; }
static JSBool method_md5(JSContext *cx, JSObject *self, uintN argc, jsval *argv, jsval *rval) { JSString *jsstr; ngx_md5_t md5; u_char *str, hash[16], hex[32]; size_t len; TRACE(); if (argc != 1) { JS_ReportError(cx, "Nginx.md5 takes 1 argument"); return JS_FALSE; } jsstr = JS_ValueToString(cx, argv[0]); if (jsstr == NULL) { return JS_FALSE; } str = (u_char *) JS_GetStringBytes(jsstr); if (str == NULL) { return JS_FALSE; } len = ngx_strlen(str); ngx_md5_init(&md5); ngx_md5_update(&md5, str, len); ngx_md5_final(hash, &md5); ngx_hex_dump(hex, hash, 16); DATA_LEN_to_JS_STRING_to_JSVAL(cx, hex, 32, *rval); return JS_TRUE; }
ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) { ssl_session *session = c->ssl->connection->session; /* * ngx_event_openssl's implementation of this returns a hexdump of * the ASN.1 encoded SSL session object. Our implementation just * returns a hexdump of the session id, because this routine is not * named ngx_ssl_get_entire_session_object. */ s->len = session->length * 2; s->data = ngx_pnalloc(pool, s->len); if (s->data == NULL) { return NGX_ERROR; } ngx_hex_dump(s->data, session->id, session->length); return NGX_OK; }
int main (int argc, char *argv[]) { ngx_int_t i; ngx_md5_t md5; u_char *p, md5_buf[16], md5_dump_buf[32]; ngx_str_t s = ngx_string("bokko"); printf("%s:", s.data); ngx_md5_init(&md5); ngx_md5_update(&md5, s.data, s.len); ngx_md5_final(md5_buf, &md5); p = md5_dump_buf; p = ngx_hex_dump(p, md5_buf, 16); for (i=0;i<32;i++) { printf("%c", md5_dump_buf[i]); } printf("\n"); return 0; }
static int ngx_http_lua_ngx_get_cache_data(lua_State *L) { int n; ngx_http_request_t *r; ngx_http_cache_t *c; ngx_http_file_cache_t *cache, cache_tmp; ngx_http_file_cache_sh_t *sh, sh_tmp; ngx_http_file_cache_node_t *fcn, fcn_tmp; u_char *p; n = lua_gettop(L); if (n != 0) { return luaL_error(L, "expecting no arguments"); } r = ngx_http_lua_get_request(L); if (r == NULL) { return luaL_error(L, "no request object found"); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua cache.metadata"); // TODO setup empty return lua_createtable(L, 0, 2 /* nrec */); /* return table */ c = r->cache; if (!c) { /* empty response */ return 1; } /* make copies of all structs, to avoid locking for too long */ fcn = c->node; cache = c->file_cache; sh = cache ? cache->sh : NULL; memset(&cache_tmp, 0, sizeof(cache_tmp)); memset(&fcn_tmp, 0, sizeof(fcn_tmp)); memset(&sh_tmp, 0, sizeof(sh_tmp)); ngx_shmtx_lock(&c->file_cache->shpool->mutex); if (fcn) { fcn_tmp = *c->node; } if (cache) { cache_tmp = *c->file_cache; if (sh) { sh_tmp = *cache->sh; cache_tmp.sh = &sh_tmp; } } ngx_shmtx_unlock(&c->file_cache->shpool->mutex); p = ngx_pnalloc(r->pool, 2*NGX_HTTP_CACHE_KEY_LEN); if (!p) { return luaL_error(L, "Cannot allocate space for cache key string"); } ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); lua_pushlstring(L, "key", sizeof("key")-1); lua_pushlstring(L, (char*)p, 2*NGX_HTTP_CACHE_KEY_LEN); lua_rawset(L, -3); lua_pushlstring(L, "crc32", sizeof("crc32")-1); lua_pushnumber(L, c->crc32); lua_rawset(L, -3); lua_pushlstring(L, "valid_sec", sizeof("valid_sec")-1); lua_pushnumber(L, c->valid_sec); lua_rawset(L, -3); lua_pushlstring(L, "last_modified", sizeof("last_modified")-1); lua_pushnumber(L, c->last_modified); lua_rawset(L, -3); lua_pushlstring(L, "date", sizeof("date")-1); lua_pushnumber(L, c->date); lua_rawset(L, -3); lua_pushlstring(L, "length", sizeof("length")-1); lua_pushnumber(L, c->length); lua_rawset(L, -3); lua_pushlstring(L, "fs_size", sizeof("fs_size")-1); lua_pushnumber(L, c->fs_size); lua_rawset(L, -3); lua_pushlstring(L, "min_uses", sizeof("min_uses")-1); lua_pushnumber(L, c->min_uses); lua_rawset(L, -3); lua_pushlstring(L, "error", sizeof("error")-1); lua_pushnumber(L, c->error); lua_rawset(L, -3); lua_pushlstring(L, "valid_msec", sizeof("valid_msec")-1); lua_pushnumber(L, c->valid_msec); lua_rawset(L, -3); /* shared memory block */ if (sh) { lua_createtable(L, 0, 2 /* nrec */); /* subtable */ lua_pushlstring(L, "size", sizeof("size")-1); lua_pushnumber(L, sh_tmp.size); lua_rawset(L, -3); lua_setfield(L, -2, "sh"); } /* cache entry */ if (cache) { lua_createtable(L, 0, 8 /* nrec */); /* subtable */ lua_pushlstring(L, "max_size", sizeof("max_size")-1); lua_pushnumber(L, cache_tmp.max_size); lua_rawset(L, -3); lua_pushlstring(L, "bsize", sizeof("bsize")-1); lua_pushnumber(L, cache_tmp.bsize); lua_rawset(L, -3); lua_pushlstring(L, "inactive", sizeof("inactive")-1); lua_pushnumber(L, cache_tmp.inactive); lua_rawset(L, -3); lua_pushlstring(L, "files", sizeof("files")-1); lua_pushnumber(L, cache_tmp.files); lua_rawset(L, -3); lua_pushlstring(L, "loader_files", sizeof("loader_files")-1); lua_pushnumber(L, cache_tmp.loader_files); lua_rawset(L, -3); lua_pushlstring(L, "loader_sleep", sizeof("loader_sleep")-1); lua_pushnumber(L, cache_tmp.loader_sleep); lua_rawset(L, -3); lua_pushlstring(L, "loader_threshold", sizeof("loader_threshold")-1); lua_pushnumber(L, cache_tmp.inactive); lua_rawset(L, -3); lua_setfield(L, -2, "cache"); } /* file_cache_node */ if (fcn) { lua_createtable(L, 0, 11 /* nrec */); /* subtable */ lua_pushlstring(L, "count", sizeof("count")-1); lua_pushnumber(L, fcn_tmp.count); lua_rawset(L, -3); lua_pushlstring(L, "uses", sizeof("uses")-1); lua_pushnumber(L, fcn_tmp.uses); lua_rawset(L, -3); lua_pushlstring(L, "valid_msec", sizeof("valid_msec")-1); lua_pushnumber(L, fcn_tmp.valid_msec); lua_rawset(L, -3); lua_pushlstring(L, "error", sizeof("error")-1); lua_pushnumber(L, fcn_tmp.error); lua_rawset(L, -3); lua_pushlstring(L, "exists", sizeof("exists")-1); lua_pushnumber(L, fcn_tmp.exists); lua_rawset(L, -3); lua_pushlstring(L, "updating", sizeof("updating")-1); lua_pushnumber(L, fcn_tmp.updating); lua_rawset(L, -3); lua_pushlstring(L, "deleting", sizeof("deleting")-1); lua_pushnumber(L, fcn_tmp.deleting); lua_rawset(L, -3); lua_pushlstring(L, "exists", sizeof("exists")-1); lua_pushnumber(L, fcn_tmp.exists); lua_rawset(L, -3); lua_pushlstring(L, "expire", sizeof("expire")-1); lua_pushnumber(L, fcn_tmp.expire); lua_rawset(L, -3); lua_pushlstring(L, "valid_sec", sizeof("valid_sec")-1); lua_pushnumber(L, fcn_tmp.valid_sec); lua_rawset(L, -3); lua_pushlstring(L, "fs_size", sizeof("fs_size")-1); lua_pushnumber(L, fcn_tmp.fs_size); lua_rawset(L, -3); lua_setfield(L, -2, "fcn"); } return 1; }
static ngx_int_t ngx_http_weixin_auth(ngx_http_request_t *r) { u_char *p; ngx_int_t rc; ngx_str_t signature, str, array_str[3], tmp; ngx_sha1_t sha; u_char sha_buf[SHA_DIGEST_LENGTH]; u_char sha_buf_str[SHA_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; ngx_http_weixin_auth_loc_conf_t *auth_conf; auth_conf = ngx_http_get_module_loc_conf(r, ngx_http_weixin_auth_module); if (ngx_http_arg(r, (u_char *) "signature", 9, &signature) != NGX_OK) { return NGX_DECLINED; } if (ngx_http_arg(r, (u_char *) "timestamp", 9, &array_str[0]) != NGX_OK) { return NGX_DECLINED; } if (ngx_http_arg(r, (u_char *) "nonce", 5, &array_str[1]) != NGX_OK) { return NGX_DECLINED; } if (signature.len != SHA_DIGEST_LENGTH * 2) { return NGX_DECLINED; } array_str[2] = auth_conf->token; // token¡¢timestamp¡¢nonce if (ngx_memn2cmp(array_str[0].data, array_str[1].data, array_str[0].len, array_str[1].len) > 0) { tmp = array_str[0]; array_str[0] = array_str[1]; array_str[1] = tmp; } if (ngx_memn2cmp(array_str[1].data, array_str[2].data, array_str[1].len, array_str[2].len) > 0) { tmp = array_str[1]; array_str[1] = array_str[2]; array_str[2] = tmp; } if (ngx_memn2cmp(array_str[0].data, array_str[1].data, array_str[0].len, array_str[1].len) > 0) { tmp = array_str[0]; array_str[0] = array_str[1]; array_str[1] = tmp; } str.len = array_str[0].len + array_str[1].len + array_str[2].len; str.data = ngx_pcalloc(r->pool, str.len + 1); if (str.data == NULL) { return NGX_ERROR; } p = str.data; p = ngx_cpymem(p, array_str[0].data, array_str[0].len); p = ngx_cpymem(p, array_str[1].data, array_str[1].len); p = ngx_cpymem(p, array_str[2].data, array_str[2].len); p = '\0'; ngx_sha1_init(&sha); ngx_sha1_update(&sha, str.data, str.len); ngx_sha1_final(sha_buf, &sha); p = ngx_hex_dump(sha_buf_str, sha_buf, SHA_DIGEST_LENGTH); p = '\0'; rc = ngx_memcmp(sha_buf_str, signature.data, SHA_DIGEST_LENGTH * 2); if (rc != 0) { return NGX_DECLINED; } return NGX_OK; }
/* ngx_http_file_cache_expire,使用了LRU,也就是队列最尾端保存的是最长时间没有被使用的,并且这个函数返回的就是一个wait值 */ static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache) { u_char *name, *p; size_t len; time_t now, wait; ngx_path_t *path; ngx_queue_t *q; ngx_http_file_cache_node_t *fcn; u_char key[2 * NGX_HTTP_CACHE_KEY_LEN]; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache expire"); path = cache->path; len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; // name = ngx_alloc(len + 1, ngx_cycle->log); if (name == NULL) { return 10; } // 拷贝路径名 -- cache存放的目录,不包括子目录 ngx_memcpy(name, path->name.data, path->name.len); now = ngx_time(); ngx_shmtx_lock(&cache->shpool->mutex); // 共享内存区上锁 for ( ;; ) { // 队列空,直接返回 if (ngx_queue_empty(&cache->sh->queue)) { wait = 10; break; } // 在队列的尾部取出一个节点,检查是否已经过期 q = ngx_queue_last(&cache->sh->queue); fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); wait = fcn->expire - now; if (wait > 0) { // wait大于0说明未过期 wait = wait > 10 ? 10 : wait; break; } // 此节点已经过期 ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache expire: #%d %d %02xd%02xd%02xd%02xd", fcn->count, fcn->exists, fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]); if (fcn->count == 0) { ngx_http_file_cache_delete(cache, q, name); continue; } if (fcn->deleting) { wait = 1; break; } // 转换文件名到acsii格式 p = ngx_hex_dump(key, (u_char *) &fcn->node.key, sizeof(ngx_rbtree_key_t)); len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); (void) ngx_hex_dump(p, fcn->key, len); /* * abnormally exited workers may leave locked cache entries, * and although it may be safe to remove them completely, * we prefer to just move them to the top of the inactive queue */ // 将节点放入队列的头部 ngx_queue_remove(q); // 重新计算过期时间 fcn->expire = ngx_time() + cache->inactive; ngx_queue_insert_head(&cache->sh->queue, &fcn->queue); ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "ignore long locked inactive cache entry %*s, count:%d", 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count); } ngx_shmtx_unlock(&cache->shpool->mutex); ngx_free(name); return wait; }
static ngx_int_t ngx_http_auth_digest_verify_hash(ngx_http_request_t *r, ngx_http_auth_digest_cred_t *fields, u_char *hashed_pw) { u_char *p; ngx_str_t http_method; ngx_str_t HA1, HA2, ha2_key; ngx_str_t digest, digest_key; ngx_md5_t md5; u_char hash[16]; // the hashing scheme: // digest: MD5(MD5(username:realm:password):nonce:nc:cnonce:qop:MD5(method:uri)) // ^- HA1 ^- HA2 // verify: fields->response == MD5($hashed_pw:nonce:nc:cnonce:qop:MD5(method:uri)) // ha1 was precalculated and saved to the passwd file: md5(username:realm:password) HA1.len = 33; HA1.data = ngx_pcalloc(r->pool, HA1.len); p = ngx_cpymem(HA1.data, hashed_pw, 32); // calculate ha2: md5(method:uri) http_method.len = r->method_name.len+1; http_method.data = ngx_pcalloc(r->pool, http_method.len); if (http_method.data==NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; p = ngx_cpymem(http_method.data, r->method_name.data, r->method_end - r->method_name.data+1); ha2_key.len = http_method.len + r->uri.len + 1; ha2_key.data = ngx_pcalloc(r->pool, ha2_key.len); if (ha2_key.data==NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; p = ngx_cpymem(ha2_key.data, http_method.data, http_method.len-1); *p++ = ':'; p = ngx_cpymem(p, r->uri.data, r->uri.len); HA2.len = 33; HA2.data = ngx_pcalloc(r->pool, HA2.len); ngx_md5_init(&md5); ngx_md5_update(&md5, ha2_key.data, ha2_key.len-1); ngx_md5_final(hash, &md5); ngx_hex_dump(HA2.data, hash, 16); // calculate digest: md5(ha1:nonce:nc:cnonce:qop:ha2) digest_key.len = HA1.len-1 + fields->nonce.len-1 + fields->nc.len-1 + fields->cnonce.len-1 + fields->qop.len-1 + HA2.len-1 + 5 + 1; digest_key.data = ngx_pcalloc(r->pool, digest_key.len); if (digest_key.data==NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; p = ngx_cpymem(digest_key.data, HA1.data, HA1.len-1); *p++ = ':'; p = ngx_cpymem(p, fields->nonce.data, fields->nonce.len-1); *p++ = ':'; p = ngx_cpymem(p, fields->nc.data, fields->nc.len-1); *p++ = ':'; p = ngx_cpymem(p, fields->cnonce.data, fields->cnonce.len-1); *p++ = ':'; p = ngx_cpymem(p, fields->qop.data, fields->qop.len-1); *p++ = ':'; p = ngx_cpymem(p, HA2.data, HA2.len-1); digest.len = 33; digest.data = ngx_pcalloc(r->pool, 33); if (digest.data==NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; ngx_md5_init(&md5); ngx_md5_update(&md5, digest_key.data, digest_key.len-1); ngx_md5_final(hash, &md5); ngx_hex_dump(digest.data, hash, 16); // compare the hash of the full digest string to the response field of the auth header // and bail out if they don't match if (ngx_strcmp(digest.data, fields->response.data) != 0) return NGX_DECLINED; ngx_http_auth_digest_nonce_t nonce; ngx_uint_t key; ngx_http_auth_digest_node_t *found; ngx_slab_pool_t *shpool; ngx_http_auth_digest_loc_conf_t *alcf; ngx_table_elt_t *info_header; ngx_str_t hkey, hval; shpool = (ngx_slab_pool_t *)ngx_http_auth_digest_shm_zone->shm.addr; alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_digest_module); nonce.rnd = ngx_hextoi(fields->nonce.data, 8); nonce.t = ngx_hextoi(&fields->nonce.data[8], 8); key = ngx_crc32_short((u_char *) &nonce.rnd, sizeof nonce.rnd) ^ ngx_crc32_short((u_char *) &nonce.t, sizeof(nonce.t)); int nc = ngx_atoi(fields->nc.data, fields->nc.len-1); if (nc<0 || nc>=alcf->replays){ fields->stale = 1; return NGX_DECLINED; } // make sure nonce and nc are both valid ngx_shmtx_lock(&shpool->mutex); found = (ngx_http_auth_digest_node_t *)ngx_http_auth_digest_rbtree_find(key, ngx_http_auth_digest_rbtree->root, ngx_http_auth_digest_rbtree->sentinel); if (found!=NULL && ngx_bitvector_test(found->nc, nc)){ if (ngx_bitvector_test(found->nc, 0)){ // if this is the first use of this nonce, switch the expiration time from the timeout // param to now+expires. using the 0th element of the nc vector to flag this... ngx_bitvector_set(found->nc, 0); found->expires = ngx_time() + alcf->expires; } // 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 // Authentication-Info header ngx_memset(ha2_key.data, 0, ha2_key.len); p = ngx_sprintf(ha2_key.data, ":%s", r->uri.data); ngx_memset(HA2.data, 0, HA2.len); ngx_md5_init(&md5); ngx_md5_update(&md5, ha2_key.data, r->uri.len); ngx_md5_final(hash, &md5); ngx_hex_dump(HA2.data, hash, 16); ngx_memset(digest_key.data, 0, digest_key.len); p = ngx_cpymem(digest_key.data, HA1.data, HA1.len-1); *p++ = ':'; p = ngx_cpymem(p, fields->nonce.data, fields->nonce.len-1); *p++ = ':'; p = ngx_cpymem(p, fields->nc.data, fields->nc.len-1); *p++ = ':'; p = ngx_cpymem(p, fields->cnonce.data, fields->cnonce.len-1); *p++ = ':'; p = ngx_cpymem(p, fields->qop.data, fields->qop.len-1); *p++ = ':'; p = ngx_cpymem(p, HA2.data, HA2.len-1); ngx_md5_init(&md5); ngx_md5_update(&md5, digest_key.data, digest_key.len-1); ngx_md5_final(hash, &md5); ngx_hex_dump(digest.data, hash, 16); ngx_str_set(&hkey, "Authentication-Info"); hval.len = sizeof("qop=\"auth\", rspauth=\"\", cnonce=\"\", nc=") + fields->cnonce.len + fields->nc.len + digest.len; hval.data = ngx_pcalloc(r->pool, hval.len); if (hval.data==NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; p = ngx_sprintf(hval.data, "qop=\"auth\", rspauth=\"%s\", cnonce=\"%s\", nc=%s", digest.data, fields->cnonce.data, fields->nc.data); info_header = ngx_list_push(&r->headers_out.headers); if (info_header == NULL) return NGX_HTTP_INTERNAL_SERVER_ERROR; info_header->key = hkey; info_header->value = hval; info_header->hash = 1; return NGX_OK; }else{ // nonce is invalid/expired or client reused an nc value. suspicious... ngx_shmtx_unlock(&shpool->mutex); return NGX_DECLINED; } }
ngx_int_t ngx_http_file_cache_open(ngx_http_request_t *r) { u_char *p; ngx_int_t rc, rv; ngx_uint_t cold, test; ngx_path_t *path; ngx_http_cache_t *c; ngx_pool_cleanup_t *cln; ngx_open_file_info_t of; ngx_http_file_cache_t *cache; ngx_http_core_loc_conf_t *clcf; c = r->cache; if (c->buf) { return ngx_http_file_cache_read(r, c); } cache = c->file_cache; cln = ngx_pool_cleanup_add(r->pool, 0); if (cln == NULL) { return NGX_ERROR; } rc = ngx_http_file_cache_exists(cache, c); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http file cache exists: %i e:%d", rc, c->exists); if (rc == NGX_ERROR) { return rc; } cln->handler = ngx_http_file_cache_cleanup; cln->data = c; if (rc == NGX_AGAIN) { return NGX_HTTP_CACHE_SCARCE; } cold = cache->sh->cold; if (rc == NGX_OK) { if (c->error) { return c->error; } c->temp_file = 1; test = c->exists ? 1 : 0; rv = NGX_DECLINED; } else { /* rc == NGX_DECLINED */ if (c->min_uses > 1) { if (!cold) { return NGX_HTTP_CACHE_SCARCE; } test = 1; rv = NGX_HTTP_CACHE_SCARCE; } else { c->temp_file = 1; test = cold ? 1 : 0; rv = NGX_DECLINED; } } path = cache->path; c->file.name.len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1); if (c->file.name.data == NULL) { return NGX_ERROR; } ngx_memcpy(c->file.name.data, path->name.data, path->name.len); p = c->file.name.data + path->name.len + 1 + path->len; p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); *p = '\0'; ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "cache file: \"%s\"", c->file.name.data); if (!test) { return NGX_DECLINED; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_memzero(&of, sizeof(ngx_open_file_info_t)); of.uniq = c->uniq; of.valid = clcf->open_file_cache_valid; of.min_uses = clcf->open_file_cache_min_uses; of.events = clcf->open_file_cache_events; of.directio = NGX_OPEN_FILE_DIRECTIO_OFF; of.read_ahead = clcf->read_ahead; if (ngx_open_cached_file(clcf->open_file_cache, &c->file.name, &of, r->pool) != NGX_OK) { switch (of.err) { case 0: return NGX_ERROR; case NGX_ENOENT: case NGX_ENOTDIR: return rv; default: ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, ngx_open_file_n " \"%s\" failed", c->file.name.data); return NGX_ERROR; } } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http file cache fd: %d", of.fd); c->file.fd = of.fd; c->file.log = r->connection->log; c->uniq = of.uniq; c->length = of.size; c->buf = ngx_create_temp_buf(r->pool, c->body_start); if (c->buf == NULL) { return NGX_ERROR; } return ngx_http_file_cache_read(r, c); }
static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache) { u_char *name, *p; size_t len; time_t now, wait; ngx_path_t *path; ngx_queue_t *q; ngx_http_file_cache_node_t *fcn; u_char key[2 * NGX_HTTP_CACHE_KEY_LEN]; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache expire"); path = cache->path; len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; name = ngx_alloc(len + 1, ngx_cycle->log); if (name == NULL) { return 10; } ngx_memcpy(name, path->name.data, path->name.len); now = ngx_time(); ngx_shmtx_lock(&cache->shpool->mutex); for ( ;; ) { if (ngx_queue_empty(&cache->sh->queue)) { wait = 10; break; } q = ngx_queue_last(&cache->sh->queue); fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); wait = fcn->expire - now; if (wait > 0) { wait = wait > 10 ? 10 : wait; break; } ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache expire: #%d %d %02xd%02xd%02xd%02xd", fcn->count, fcn->exists, fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]); if (fcn->count) { p = ngx_hex_dump(key, (u_char *) &fcn->node.key, sizeof(ngx_rbtree_key_t)); len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); (void) ngx_hex_dump(p, fcn->key, len); /* * abnormally exited workers may leave locked cache entries, * and although it may be safe to remove them completely, * we prefer to remove them from inactive queue and rbtree * only, and to allow other leaks */ ngx_queue_remove(q); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "ignore long locked inactive cache entry %*s, count:%d", 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count); continue; } if (!fcn->exists) { ngx_queue_remove(q); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); continue; } ngx_http_file_cache_delete(cache, q, name); } ngx_shmtx_unlock(&cache->shpool->mutex); ngx_free(name); return wait; }
static ngx_int_t ngx_http_secure_token_handler(ngx_http_request_t *r) { ngx_http_secure_token_loc_conf_t *stlcf; ngx_http_secure_token_ctx_t *stctx; ngx_http_complex_value_t *cv; ngx_md5_t md5; ngx_str_t val; ngx_int_t rc; ngx_uint_t i; size_t adjust, len; u_char hex[32]; stlcf = ngx_http_get_module_loc_conf(r, ngx_http_secure_token_module); if (!stlcf->enable) { return NGX_DECLINED; } if (stlcf->key.len == 0 || stlcf->md5 == NULL || stlcf->input == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } stctx = ngx_pcalloc(r->pool, sizeof(ngx_http_secure_token_ctx_t)); if (stctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, stctx, ngx_http_secure_token_module); rc = ngx_http_secure_token_parse_input(r); if (rc != NGX_OK) { return rc; } if (stctx->expire_time < ngx_time()) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "secure token: token expired: input: %d now: %d", stctx->expire_time, ngx_time()); return NGX_HTTP_FORBIDDEN; } if (stctx->access.len > 0) { adjust = stctx->access.data[stctx->access.len - 1] == '*' ? 1 : 0; len = r->args.data ? (size_t) (r->args.data - r->unparsed_uri.data) - 1 : r->unparsed_uri.len; if (len < stctx->access.len - adjust || ngx_strncmp(r->unparsed_uri.data, stctx->access.data, stctx->access.len - adjust) != 0) { ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "secure token: access mismatch: input: %V uri: %*s", &stctx->access, len, r->unparsed_uri.data); return NGX_HTTP_FORBIDDEN; } } cv = stlcf->md5->elts; for (i = 0; i < stlcf->md5->nelts; i++) { if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (val.len == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_md5_init(&md5); ngx_md5_update(&md5, val.data, val.len); ngx_md5_final(stctx->md5, &md5); #if (NGX_DEBUG) (void) ngx_hex_dump(hex, stctx->md5, 16); #endif ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "secure token: md5/%d: %*s", i, 32, hex); } #if (!NGX_DEBUG) (void) ngx_hex_dump(hex, stctx->md5, 16); #endif if (ngx_strncasecmp(hex, stctx->token.data, 32)) { ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "secure token: token mismatch: input: %V expected: %*s", &stctx->token, 32, hex); return NGX_HTTP_FORBIDDEN; } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "secure token: OK"); return NGX_OK; }