comparison src/http/modules/ngx_http_secure_link_module.c @ 635:e67b227c8dbb default tip

Merge with current.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Apr 2011 04:07:55 +0400
parents be70f83b184f
children
comparison
equal deleted inserted replaced
578:f3a9e57d2e17 635:e67b227c8dbb
9 #include <ngx_http.h> 9 #include <ngx_http.h>
10 #include <ngx_md5.h> 10 #include <ngx_md5.h>
11 11
12 12
13 typedef struct { 13 typedef struct {
14 ngx_str_t secret; 14 ngx_http_complex_value_t *variable;
15 ngx_http_complex_value_t *md5;
16 ngx_str_t secret;
15 } ngx_http_secure_link_conf_t; 17 } ngx_http_secure_link_conf_t;
16 18
17 19
20 typedef struct {
21 ngx_str_t expires;
22 } ngx_http_secure_link_ctx_t;
23
24
25 static ngx_int_t ngx_http_secure_link_old_variable(ngx_http_request_t *r,
26 ngx_http_secure_link_conf_t *conf, ngx_http_variable_value_t *v,
27 uintptr_t data);
28 static ngx_int_t ngx_http_secure_link_expires_variable(ngx_http_request_t *r,
29 ngx_http_variable_value_t *v, uintptr_t data);
18 static void *ngx_http_secure_link_create_conf(ngx_conf_t *cf); 30 static void *ngx_http_secure_link_create_conf(ngx_conf_t *cf);
19 static char *ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent, 31 static char *ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent,
20 void *child); 32 void *child);
21 static ngx_int_t ngx_http_secure_link_add_variables(ngx_conf_t *cf); 33 static ngx_int_t ngx_http_secure_link_add_variables(ngx_conf_t *cf);
22 34
23 35
24 static ngx_command_t ngx_http_secure_link_commands[] = { 36 static ngx_command_t ngx_http_secure_link_commands[] = {
37
38 { ngx_string("secure_link"),
39 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
40 ngx_http_set_complex_value_slot,
41 NGX_HTTP_LOC_CONF_OFFSET,
42 offsetof(ngx_http_secure_link_conf_t, variable),
43 NULL },
44
45 { ngx_string("secure_link_md5"),
46 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
47 ngx_http_set_complex_value_slot,
48 NGX_HTTP_LOC_CONF_OFFSET,
49 offsetof(ngx_http_secure_link_conf_t, md5),
50 NULL },
25 51
26 { ngx_string("secure_link_secret"), 52 { ngx_string("secure_link_secret"),
27 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 53 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
28 ngx_conf_set_str_slot, 54 ngx_conf_set_str_slot,
29 NGX_HTTP_LOC_CONF_OFFSET, 55 NGX_HTTP_LOC_CONF_OFFSET,
63 NULL, /* exit master */ 89 NULL, /* exit master */
64 NGX_MODULE_V1_PADDING 90 NGX_MODULE_V1_PADDING
65 }; 91 };
66 92
67 93
68 static ngx_str_t ngx_http_secure_link = ngx_string("secure_link"); 94 static ngx_str_t ngx_http_secure_link_name = ngx_string("secure_link");
95 static ngx_str_t ngx_http_secure_link_expires_name =
96 ngx_string("secure_link_expires");
69 97
70 98
71 static ngx_int_t 99 static ngx_int_t
72 ngx_http_secure_link_variable(ngx_http_request_t *r, 100 ngx_http_secure_link_variable(ngx_http_request_t *r,
73 ngx_http_variable_value_t *v, uintptr_t data) 101 ngx_http_variable_value_t *v, uintptr_t data)
74 { 102 {
75 u_char *p, *start, *end, *last; 103 u_char *p, *last;
76 size_t len; 104 ngx_str_t val, hash;
77 ngx_int_t n; 105 time_t expires;
78 ngx_uint_t i; 106 ngx_md5_t md5;
79 ngx_md5_t md5; 107 ngx_http_secure_link_ctx_t *ctx;
80 ngx_http_secure_link_conf_t *conf; 108 ngx_http_secure_link_conf_t *conf;
81 u_char hash[16]; 109 u_char hash_buf[16], md5_buf[16];
82 110
83 conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module); 111 conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module);
84 112
85 if (conf->secret.len == 0) { 113 if (conf->secret.len) {
86 goto not_found; 114 return ngx_http_secure_link_old_variable(r, conf, v, data);
87 } 115 }
116
117 if (conf->variable == NULL || conf->md5 == NULL) {
118 goto not_found;
119 }
120
121 if (ngx_http_complex_value(r, conf->variable, &val) != NGX_OK) {
122 return NGX_ERROR;
123 }
124
125 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
126 "secure link: \"%V\"", &val);
127
128 last = val.data + val.len;
129
130 p = ngx_strlchr(val.data, last, ',');
131 expires = 0;
132
133 if (p) {
134 val.len = p++ - val.data;
135
136 expires = ngx_atotm(p, last - p);
137 if (expires <= 0) {
138 goto not_found;
139 }
140
141 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_secure_link_ctx_t));
142 if (ctx == NULL) {
143 return NGX_ERROR;
144 }
145
146 ngx_http_set_ctx(r, ctx, ngx_http_secure_link_module);
147
148 ctx->expires.len = last - p;
149 ctx->expires.data = p;
150 }
151
152 if (val.len > 24) {
153 goto not_found;
154 }
155
156 hash.len = 16;
157 hash.data = hash_buf;
158
159 if (ngx_decode_base64url(&hash, &val) != NGX_OK) {
160 goto not_found;
161 }
162
163 if (hash.len != 16) {
164 goto not_found;
165 }
166
167 if (ngx_http_complex_value(r, conf->md5, &val) != NGX_OK) {
168 return NGX_ERROR;
169 }
170
171 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
172 "secure link md5: \"%V\"", &val);
173
174 ngx_md5_init(&md5);
175 ngx_md5_update(&md5, val.data, val.len);
176 ngx_md5_final(md5_buf, &md5);
177
178 if (ngx_memcmp(hash_buf, md5_buf, 16) != 0) {
179 goto not_found;
180 }
181
182 v->data = (u_char *) ((expires && expires < ngx_time()) ? "0" : "1");
183 v->len = 1;
184 v->valid = 1;
185 v->no_cacheable = 0;
186 v->not_found = 0;
187
188 return NGX_OK;
189
190 not_found:
191
192 v->not_found = 1;
193
194 return NGX_OK;
195 }
196
197
198 static ngx_int_t
199 ngx_http_secure_link_old_variable(ngx_http_request_t *r,
200 ngx_http_secure_link_conf_t *conf, ngx_http_variable_value_t *v,
201 uintptr_t data)
202 {
203 u_char *p, *start, *end, *last;
204 size_t len;
205 ngx_int_t n;
206 ngx_uint_t i;
207 ngx_md5_t md5;
208 u_char hash[16];
88 209
89 p = &r->unparsed_uri.data[1]; 210 p = &r->unparsed_uri.data[1];
90 last = r->unparsed_uri.data + r->unparsed_uri.len; 211 last = r->unparsed_uri.data + r->unparsed_uri.len;
91 212
92 while (p < last) { 213 while (p < last) {
143 264
144 return NGX_OK; 265 return NGX_OK;
145 } 266 }
146 267
147 268
269 static ngx_int_t
270 ngx_http_secure_link_expires_variable(ngx_http_request_t *r,
271 ngx_http_variable_value_t *v, uintptr_t data)
272 {
273 ngx_http_secure_link_ctx_t *ctx;
274
275 ctx = ngx_http_get_module_ctx(r, ngx_http_secure_link_module);
276
277 if (ctx) {
278 v->len = ctx->expires.len;
279 v->valid = 1;
280 v->no_cacheable = 0;
281 v->not_found = 0;
282 v->data = ctx->expires.data;
283
284 } else {
285 v->not_found = 1;
286 }
287
288 return NGX_OK;
289 }
290
291
148 static void * 292 static void *
149 ngx_http_secure_link_create_conf(ngx_conf_t *cf) 293 ngx_http_secure_link_create_conf(ngx_conf_t *cf)
150 { 294 {
151 ngx_http_secure_link_conf_t *conf; 295 ngx_http_secure_link_conf_t *conf;
152 296
156 } 300 }
157 301
158 /* 302 /*
159 * set by ngx_pcalloc(): 303 * set by ngx_pcalloc():
160 * 304 *
161 * conf->secret = { 0, NULL } 305 * conf->variable = NULL;
306 * conf->md5 = NULL;
307 * conf->secret = { 0, NULL };
162 */ 308 */
163 309
164 return conf; 310 return conf;
165 } 311 }
166 312
171 ngx_http_secure_link_conf_t *prev = parent; 317 ngx_http_secure_link_conf_t *prev = parent;
172 ngx_http_secure_link_conf_t *conf = child; 318 ngx_http_secure_link_conf_t *conf = child;
173 319
174 ngx_conf_merge_str_value(conf->secret, prev->secret, ""); 320 ngx_conf_merge_str_value(conf->secret, prev->secret, "");
175 321
322 if (conf->variable == NULL) {
323 conf->variable = prev->variable;
324 }
325
326 if (conf->md5 == NULL) {
327 conf->md5 = prev->md5;
328 }
329
176 return NGX_CONF_OK; 330 return NGX_CONF_OK;
177 } 331 }
178 332
179 333
180 static ngx_int_t 334 static ngx_int_t
181 ngx_http_secure_link_add_variables(ngx_conf_t *cf) 335 ngx_http_secure_link_add_variables(ngx_conf_t *cf)
182 { 336 {
183 ngx_http_variable_t *var; 337 ngx_http_variable_t *var;
184 338
185 var = ngx_http_add_variable(cf, &ngx_http_secure_link, NGX_HTTP_VAR_NOHASH); 339 var = ngx_http_add_variable(cf, &ngx_http_secure_link_name, 0);
186 if (var == NULL) { 340 if (var == NULL) {
187 return NGX_ERROR; 341 return NGX_ERROR;
188 } 342 }
189 343
190 var->get_handler = ngx_http_secure_link_variable; 344 var->get_handler = ngx_http_secure_link_variable;
191 345
192 return NGX_OK; 346 var = ngx_http_add_variable(cf, &ngx_http_secure_link_expires_name, 0);
193 } 347 if (var == NULL) {
348 return NGX_ERROR;
349 }
350
351 var->get_handler = ngx_http_secure_link_expires_variable;
352
353 return NGX_OK;
354 }