3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
15 ngx_http_complex_value_t
*variable
;
16 ngx_http_complex_value_t
*md5
;
18 } ngx_http_secure_link_conf_t
;
23 } ngx_http_secure_link_ctx_t
;
26 static ngx_int_t
ngx_http_secure_link_old_variable(ngx_http_request_t
*r
,
27 ngx_http_secure_link_conf_t
*conf
, ngx_http_variable_value_t
*v
,
29 static ngx_int_t
ngx_http_secure_link_expires_variable(ngx_http_request_t
*r
,
30 ngx_http_variable_value_t
*v
, uintptr_t data
);
31 static void *ngx_http_secure_link_create_conf(ngx_conf_t
*cf
);
32 static char *ngx_http_secure_link_merge_conf(ngx_conf_t
*cf
, void *parent
,
34 static ngx_int_t
ngx_http_secure_link_add_variables(ngx_conf_t
*cf
);
37 static ngx_command_t ngx_http_secure_link_commands
[] = {
39 { ngx_string("secure_link"),
40 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
41 ngx_http_set_complex_value_slot
,
42 NGX_HTTP_LOC_CONF_OFFSET
,
43 offsetof(ngx_http_secure_link_conf_t
, variable
),
46 { ngx_string("secure_link_md5"),
47 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
48 ngx_http_set_complex_value_slot
,
49 NGX_HTTP_LOC_CONF_OFFSET
,
50 offsetof(ngx_http_secure_link_conf_t
, md5
),
53 { ngx_string("secure_link_secret"),
54 NGX_HTTP_MAIN_CONF
|NGX_HTTP_SRV_CONF
|NGX_HTTP_LOC_CONF
|NGX_CONF_TAKE1
,
55 ngx_conf_set_str_slot
,
56 NGX_HTTP_LOC_CONF_OFFSET
,
57 offsetof(ngx_http_secure_link_conf_t
, secret
),
64 static ngx_http_module_t ngx_http_secure_link_module_ctx
= {
65 ngx_http_secure_link_add_variables
, /* preconfiguration */
66 NULL
, /* postconfiguration */
68 NULL
, /* create main configuration */
69 NULL
, /* init main configuration */
71 NULL
, /* create server configuration */
72 NULL
, /* merge server configuration */
74 ngx_http_secure_link_create_conf
, /* create location configuration */
75 ngx_http_secure_link_merge_conf
/* merge location configuration */
79 ngx_module_t ngx_http_secure_link_module
= {
81 &ngx_http_secure_link_module_ctx
, /* module context */
82 ngx_http_secure_link_commands
, /* module directives */
83 NGX_HTTP_MODULE
, /* module type */
84 NULL
, /* init master */
85 NULL
, /* init module */
86 NULL
, /* init process */
87 NULL
, /* init thread */
88 NULL
, /* exit thread */
89 NULL
, /* exit process */
90 NULL
, /* exit master */
95 static ngx_str_t ngx_http_secure_link_name
= ngx_string("secure_link");
96 static ngx_str_t ngx_http_secure_link_expires_name
=
97 ngx_string("secure_link_expires");
101 ngx_http_secure_link_variable(ngx_http_request_t
*r
,
102 ngx_http_variable_value_t
*v
, uintptr_t data
)
108 ngx_http_secure_link_ctx_t
*ctx
;
109 ngx_http_secure_link_conf_t
*conf
;
110 u_char hash_buf
[16], md5_buf
[16];
112 conf
= ngx_http_get_module_loc_conf(r
, ngx_http_secure_link_module
);
114 if (conf
->secret
.data
) {
115 return ngx_http_secure_link_old_variable(r
, conf
, v
, data
);
118 if (conf
->variable
== NULL
|| conf
->md5
== NULL
) {
122 if (ngx_http_complex_value(r
, conf
->variable
, &val
) != NGX_OK
) {
126 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
127 "secure link: \"%V\"", &val
);
129 last
= val
.data
+ val
.len
;
131 p
= ngx_strlchr(val
.data
, last
, ',');
135 val
.len
= p
++ - val
.data
;
137 expires
= ngx_atotm(p
, last
- p
);
142 ctx
= ngx_pcalloc(r
->pool
, sizeof(ngx_http_secure_link_ctx_t
));
147 ngx_http_set_ctx(r
, ctx
, ngx_http_secure_link_module
);
149 ctx
->expires
.len
= last
- p
;
150 ctx
->expires
.data
= p
;
158 hash
.data
= hash_buf
;
160 if (ngx_decode_base64url(&hash
, &val
) != NGX_OK
) {
164 if (hash
.len
!= 16) {
168 if (ngx_http_complex_value(r
, conf
->md5
, &val
) != NGX_OK
) {
172 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, r
->connection
->log
, 0,
173 "secure link md5: \"%V\"", &val
);
176 ngx_md5_update(&md5
, val
.data
, val
.len
);
177 ngx_md5_final(md5_buf
, &md5
);
179 if (ngx_memcmp(hash_buf
, md5_buf
, 16) != 0) {
183 v
->data
= (u_char
*) ((expires
&& expires
< ngx_time()) ? "0" : "1");
200 ngx_http_secure_link_old_variable(ngx_http_request_t
*r
,
201 ngx_http_secure_link_conf_t
*conf
, ngx_http_variable_value_t
*v
,
204 u_char
*p
, *start
, *end
, *last
;
211 p
= &r
->unparsed_uri
.data
[1];
212 last
= r
->unparsed_uri
.data
+ r
->unparsed_uri
.len
;
238 if (end
- start
!= 32 || len
== 0) {
243 ngx_md5_update(&md5
, p
, len
);
244 ngx_md5_update(&md5
, conf
->secret
.data
, conf
->secret
.len
);
245 ngx_md5_final(hash
, &md5
);
247 for (i
= 0; i
< 16; i
++) {
248 n
= ngx_hextoi(&start
[2 * i
], 2);
249 if (n
== NGX_ERROR
|| n
!= hash
[i
]) {
271 ngx_http_secure_link_expires_variable(ngx_http_request_t
*r
,
272 ngx_http_variable_value_t
*v
, uintptr_t data
)
274 ngx_http_secure_link_ctx_t
*ctx
;
276 ctx
= ngx_http_get_module_ctx(r
, ngx_http_secure_link_module
);
279 v
->len
= ctx
->expires
.len
;
283 v
->data
= ctx
->expires
.data
;
294 ngx_http_secure_link_create_conf(ngx_conf_t
*cf
)
296 ngx_http_secure_link_conf_t
*conf
;
298 conf
= ngx_pcalloc(cf
->pool
, sizeof(ngx_http_secure_link_conf_t
));
304 * set by ngx_pcalloc():
306 * conf->variable = NULL;
308 * conf->secret = { 0, NULL };
316 ngx_http_secure_link_merge_conf(ngx_conf_t
*cf
, void *parent
, void *child
)
318 ngx_http_secure_link_conf_t
*prev
= parent
;
319 ngx_http_secure_link_conf_t
*conf
= child
;
321 if (conf
->secret
.data
) {
322 if (conf
->variable
|| conf
->md5
) {
323 ngx_conf_log_error(NGX_LOG_EMERG
, cf
, 0,
324 "\"secure_link_secret\" cannot be mixed with "
325 "\"secure_link\" and \"secure_link_md5\"");
326 return NGX_CONF_ERROR
;
332 if (conf
->variable
== NULL
) {
333 conf
->variable
= prev
->variable
;
336 if (conf
->md5
== NULL
) {
337 conf
->md5
= prev
->md5
;
340 if (conf
->variable
== NULL
&& conf
->md5
== NULL
) {
341 conf
->secret
= prev
->secret
;
349 ngx_http_secure_link_add_variables(ngx_conf_t
*cf
)
351 ngx_http_variable_t
*var
;
353 var
= ngx_http_add_variable(cf
, &ngx_http_secure_link_name
, 0);
358 var
->get_handler
= ngx_http_secure_link_variable
;
360 var
= ngx_http_add_variable(cf
, &ngx_http_secure_link_expires_name
, 0);
365 var
->get_handler
= ngx_http_secure_link_expires_variable
;