diff -Naur nginx-0.8.4.orig/src/http/modules/ngx_http_secure_link_module.c nginx-0.8.4/src/http/modules/ngx_http_secure_link_module.c --- nginx-0.8.4.orig/src/http/modules/ngx_http_secure_link_module.c 2009-05-13 14:44:15.000000000 +0200 +++ nginx-0.8.4/src/http/modules/ngx_http_secure_link_module.c 2009-05-13 15:00:49.000000000 +0200 @@ -12,6 +12,7 @@ typedef struct { ngx_str_t secret; + time_t timeout; } ngx_http_secure_link_conf_t; @@ -30,6 +31,12 @@ offsetof(ngx_http_secure_link_conf_t, secret), NULL }, + { ngx_string("secure_link_timeout"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_sec_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_secure_link_conf_t, timeout), + NULL }, ngx_null_command }; @@ -67,22 +74,36 @@ static ngx_str_t ngx_http_secure_link = ngx_string("secure_link"); +static u_char +ngx_hex2int(u_char hex) +{ + hex = hex - '0'; + if (hex > 9) { + hex = (hex + '0' - 1) | 0x20; + hex = hex - 'a' + 11; + } + if (hex > 15) + hex = 0xFF; + + return hex; +} static ngx_int_t ngx_http_secure_link_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - u_char *p, *start, *end, *last; - size_t len; + u_char *p, *start, *end, *last, *tss, *tse; + size_t len, tslen; ngx_int_t n; ngx_uint_t i; ngx_md5_t md5; + time_t ts; ngx_http_secure_link_conf_t *conf; u_char hash[16]; conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module); - if (conf->secret.len == 0) { + if (conf->secret.len == 0 || conf->timeout == 0) { goto not_found; } @@ -103,22 +124,46 @@ while (p < last) { if (*p++ == '/') { end = p - 1; - goto url_start; + goto tstamp_start; } } goto not_found; + tstamp_start: + + tss = p; + + while (p < last) { + if (*p++ == '/') { + tse = p - 1; + goto url_start; + } + } + + goto not_found; + url_start: + tslen = tse - tss; len = last - p; - if (end - start != 32 || len == 0) { + if (end - start != 32 || len == 0 || tslen != 8) { goto not_found; } + ts = 0; + for (i = 0; i < 8; i++) { + ts = (ts << 4) + ngx_hex2int(tss[i]); + } + + if (ts < r->start_sec - conf->timeout) { + goto not_found; + } + ngx_md5_init(&md5); ngx_md5_update(&md5, p, len); + ngx_md5_update(&md5, tss, tslen); ngx_md5_update(&md5, conf->secret.data, conf->secret.len); ngx_md5_final(hash, &md5); @@ -160,7 +205,8 @@ * * conf->secret = { 0, NULL } */ - + + conf->timeout = NGX_CONF_UNSET; return conf; } @@ -172,6 +218,7 @@ ngx_http_secure_link_conf_t *conf = child; ngx_conf_merge_str_value(conf->secret, prev->secret, ""); + ngx_conf_merge_sec_value(conf->timeout, prev->timeout, 3600); return NGX_CONF_OK; }