static int ngx_http_lua_ngx_decode_base64url(lua_State *L) { ngx_str_t p, src; if (lua_gettop(L) != 1) { return luaL_error(L, "expecting one argument"); } if (lua_type(L, 1) != LUA_TSTRING) { return luaL_error(L, "string argument only"); } src.data = (u_char *) luaL_checklstring(L, 1, &src.len); p.len = ngx_base64_decoded_length(src.len); p.data = lua_newuserdata(L, p.len); if (ngx_decode_base64url(&p, &src) == NGX_OK) { lua_pushlstring(L, (char *) p.data, p.len); } else { lua_pushnil(L); } return 1; }
ngx_int_t ngx_http_set_misc_set_decode_base64url(ngx_http_request_t *r, ngx_str_t *res, ngx_http_variable_value_t *v) { ngx_str_t src; src.len = v->len; src.data = v->data; res->len = ngx_base64url_decoded_length(v->len); res->data = ngx_palloc(r->pool, res->len); if (res->data == NULL) { return NGX_ERROR; } #if defined(nginx_version) && nginx_version >= 1005010 if (ngx_decode_base64url(res, &src) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "set_decode_base64url: invalid value"); return NGX_ERROR; } #else u_int i; for (i=0;i<src.len;i++) { switch (src.data[i]) { case '-': src.data[i]='+'; break; case '_': src.data[i]='/'; break; } } if (ngx_decode_base64(res, &src) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "set_decode_base64url: invalid value"); return NGX_ERROR; } #endif return NGX_OK; }
//获取secure_link配置的值,同时与secure_link_md5运算的值进行比较,相同则置$secure_link变量为1,不同则置0 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, *last; ngx_str_t val, hash; time_t expires; ngx_md5_t md5; ngx_http_secure_link_ctx_t *ctx; ngx_http_secure_link_conf_t *conf; u_char hash_buf[16], md5_buf[16]; conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module); if (conf->secret.data) { return ngx_http_secure_link_old_variable(r, conf, v, data); } if (conf->variable == NULL || conf->md5 == NULL) { goto not_found; } if (ngx_http_complex_value(r, conf->variable, &val) != NGX_OK) { return NGX_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "secure link: \"%V\"", &val); last = val.data + val.len; p = ngx_strlchr(val.data, last, ','); ////secure_link md5_str, 120配置, expires = 0; if (p) { val.len = p++ - val.data; //这时候,val.len=md5_str的字符串长度了,不包括后面的,120字符串 expires = ngx_atotm(p, last - p); //获取//secure_link md5_str, 120配置中的120 if (expires <= 0) { goto not_found; } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_secure_link_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_secure_link_module); ctx->expires.len = last - p; ctx->expires.data = p; } //这时候,val.len=md5_str的字符串长度了,不包括后面的,120字符串 if (val.len > 24) {//secure_link配置解析出的字符串不能超过24个字符 ?????? 为什么呢 goto not_found; } hash.len = 16; hash.data = hash_buf; //把secure_link md5_str, 120配置中的md5_str字符串进行base64解密decode运算后的值存到这里面 if (ngx_decode_base64url(&hash, &val) != NGX_OK) { goto not_found; } if (hash.len != 16) { goto not_found; } //解析secure_link_md5 $the_uri_you_want_to_hashed_by_md5配置的字符串 if (ngx_http_complex_value(r, conf->md5, &val) != NGX_OK) { return NGX_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "secure link md5: \"%V\"", &val); //echo -n 'ttlsa.com/download/nginx-1.9.2.rar1452130593' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d = ngx_md5_init(&md5); ngx_md5_update(&md5, val.data, val.len); ngx_md5_final(md5_buf, &md5); if (ngx_memcmp(hash_buf, md5_buf, 16) != 0) { //比较判断是否一致 goto not_found; } //设置v变量对应的值为0或者1 v->data = (u_char *) ((expires && expires < ngx_time()) ? "0" : "1"); v->len = 1; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; return NGX_OK; not_found: v->not_found = 1; return NGX_OK; }
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, *last; ngx_str_t val, hash; time_t expires; ngx_md5_t md5; ngx_http_secure_link_ctx_t *ctx; ngx_http_secure_link_conf_t *conf; u_char hash_buf[16], md5_buf[16]; conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module); if (conf->secret.len) { return ngx_http_secure_link_old_variable(r, conf, v, data); } if (conf->variable == NULL || conf->md5 == NULL) { goto not_found; } if (ngx_http_complex_value(r, conf->variable, &val) != NGX_OK) { return NGX_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "secure link: \"%V\"", &val); last = val.data + val.len; p = ngx_strlchr(val.data, last, ','); expires = 0; if (p) { val.len = p++ - val.data; expires = ngx_atotm(p, last - p); if (expires <= 0) { goto not_found; } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_secure_link_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_secure_link_module); ctx->expires.len = last - p; ctx->expires.data = p; } if (val.len > 24) { goto not_found; } hash.len = 16; hash.data = hash_buf; if (ngx_decode_base64url(&hash, &val) != NGX_OK) { goto not_found; } if (hash.len != 16) { goto not_found; } if (ngx_http_complex_value(r, conf->md5, &val) != NGX_OK) { return NGX_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "secure link md5: \"%V\"", &val); ngx_md5_init(&md5); ngx_md5_update(&md5, val.data, val.len); ngx_md5_final(md5_buf, &md5); if (ngx_memcmp(hash_buf, md5_buf, 16) != 0) { goto not_found; } v->data = (u_char *) ((expires && expires < ngx_time()) ? "0" : "1"); v->len = 1; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; return NGX_OK; not_found: v->not_found = 1; return NGX_OK; }