Skip to content

Commit e3660c3

Browse files
authored
Add dynamic variable support for access_key and access_secret (#1)
1 parent 7e47ea2 commit e3660c3

File tree

1 file changed

+118
-21
lines changed

1 file changed

+118
-21
lines changed

ngx_http_aws_auth_module.c

Lines changed: 118 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ static void* ngx_http_aws_auth_create_loc_conf(ngx_conf_t *cf);
1616
static char* ngx_http_aws_auth_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);
1717
static ngx_int_t register_variable(ngx_conf_t *cf);
1818
static char *
19+
ngx_http_aws_auth_set_access_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
20+
static char *
21+
ngx_http_aws_auth_set_secret_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
22+
static char *
1923
ngx_http_aws_auth_set_s3_bucket(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
2024
static char *
2125
ngx_http_aws_auth_set_chop_prefix(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -30,6 +34,8 @@ typedef struct {
3034
ngx_str_t secret;
3135
ngx_str_t s3_bucket;
3236
ngx_str_t chop_prefix;
37+
ngx_http_aws_auth_script_t *access_key_script;
38+
ngx_http_aws_auth_script_t *secret_script;
3339
ngx_http_aws_auth_script_t *s3_bucket_script;
3440
ngx_http_aws_auth_script_t *chop_prefix_script;
3541
} ngx_http_aws_auth_conf_t;
@@ -64,14 +70,14 @@ static const char *signed_subresources[] = {
6470
static ngx_command_t ngx_http_aws_auth_commands[] = {
6571
{ ngx_string("aws_access_key"),
6672
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
67-
ngx_conf_set_str_slot,
73+
ngx_http_aws_auth_set_access_key,
6874
NGX_HTTP_LOC_CONF_OFFSET,
6975
offsetof(ngx_http_aws_auth_conf_t, access_key),
7076
NULL },
7177

7278
{ ngx_string("aws_secret_key"),
7379
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
74-
ngx_conf_set_str_slot,
80+
ngx_http_aws_auth_set_secret_key,
7581
NGX_HTTP_LOC_CONF_OFFSET,
7682
offsetof(ngx_http_aws_auth_conf_t, secret),
7783
NULL },
@@ -82,7 +88,7 @@ static ngx_command_t ngx_http_aws_auth_commands[] = {
8288
NGX_HTTP_LOC_CONF_OFFSET,
8389
offsetof(ngx_http_aws_auth_conf_t, s3_bucket),
8490
NULL },
85-
91+
8692
{ ngx_string("chop_prefix"),
8793
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
8894
ngx_http_aws_auth_set_chop_prefix,
@@ -123,6 +129,84 @@ ngx_module_t ngx_http_aws_auth_module = {
123129
NGX_MODULE_V1_PADDING
124130
};
125131

132+
static char *
133+
ngx_http_aws_auth_set_access_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
134+
{
135+
ngx_http_aws_auth_conf_t *aws_conf = conf;
136+
ngx_http_script_compile_t sc;
137+
ngx_str_t *value;
138+
ngx_uint_t n;
139+
value = cf->args->elts;
140+
n = ngx_http_script_variables_count(&value[1]);
141+
142+
if (n == 0) {
143+
// set secret key as string
144+
aws_conf->access_key.data = value[1].data;
145+
aws_conf->access_key.len = value[1].len;
146+
}
147+
else {
148+
//add script to compile
149+
aws_conf->access_key_script = ngx_pcalloc(cf->pool, sizeof(ngx_http_aws_auth_script_t));
150+
if (aws_conf->access_key_script == NULL) {
151+
return NGX_CONF_ERROR;
152+
}
153+
154+
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
155+
156+
sc.cf = cf;
157+
sc.source = &value[1];
158+
sc.lengths = &aws_conf->access_key_script->lengths;
159+
sc.values = &aws_conf->access_key_script->values;
160+
sc.variables = n;
161+
sc.complete_lengths = 1;
162+
sc.complete_values = 1;
163+
164+
if (ngx_http_script_compile(&sc) != NGX_OK) {
165+
return NGX_CONF_ERROR;
166+
}
167+
}
168+
return NGX_CONF_OK;
169+
}
170+
171+
static char *
172+
ngx_http_aws_auth_set_secret_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
173+
{
174+
ngx_http_aws_auth_conf_t *aws_conf = conf;
175+
ngx_http_script_compile_t sc;
176+
ngx_str_t *value;
177+
ngx_uint_t n;
178+
value = cf->args->elts;
179+
n = ngx_http_script_variables_count(&value[1]);
180+
181+
if (n == 0) {
182+
// set secret key as string
183+
aws_conf->secret.data = value[1].data;
184+
aws_conf->secret.len = value[1].len;
185+
}
186+
else {
187+
//add script to compile
188+
aws_conf->secret_script = ngx_pcalloc(cf->pool, sizeof(ngx_http_aws_auth_script_t));
189+
if (aws_conf->secret_script == NULL) {
190+
return NGX_CONF_ERROR;
191+
}
192+
193+
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
194+
195+
sc.cf = cf;
196+
sc.source = &value[1];
197+
sc.lengths = &aws_conf->secret_script->lengths;
198+
sc.values = &aws_conf->secret_script->values;
199+
sc.variables = n;
200+
sc.complete_lengths = 1;
201+
sc.complete_values = 1;
202+
203+
if (ngx_http_script_compile(&sc) != NGX_OK) {
204+
return NGX_CONF_ERROR;
205+
}
206+
}
207+
return NGX_CONF_OK;
208+
}
209+
126210
static char *
127211
ngx_http_aws_auth_set_s3_bucket(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
128212
{
@@ -210,7 +294,7 @@ ngx_http_aws_auth_create_loc_conf(ngx_conf_t *cf)
210294
return NGX_CONF_ERROR;
211295
}
212296

213-
return conf;
297+
return conf;
214298
}
215299

216300
static char *
@@ -383,7 +467,7 @@ ngx_http_aws_auth_get_canon_resource(ngx_http_request_t *r, ngx_str_t *retstr) {
383467
}
384468
}
385469

386-
u_char *c_args = ngx_palloc(r->pool, r->args.len + 1);
470+
u_char *c_args = ngx_palloc(r->pool, r->args.len + 1);
387471
u_char *c_args_cur = c_args;
388472
ngx_str_t arg_val;
389473
ngx_int_t c_args_len = 0;
@@ -408,17 +492,17 @@ ngx_http_aws_auth_get_canon_resource(ngx_http_request_t *r, ngx_str_t *retstr) {
408492
}
409493
c_args_len = c_args_cur - c_args;
410494
*c_args_cur = '\0';
411-
}
495+
}
412496

413497
uri_len = ngx_strlen(uri);
414-
u_char *ret = ngx_palloc(r->pool, uri_len + aws_conf->s3_bucket.len + sizeof("/") + c_args_len + 1);
415-
u_char *cur = ret;
498+
u_char *ret = ngx_palloc(r->pool, uri_len + aws_conf->s3_bucket.len + sizeof("/") + c_args_len + 1);
499+
u_char *cur = ret;
416500
cur = ngx_cpystrn(cur, (u_char *)"/", sizeof("/"));
417501
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "bucket: %V", &aws_conf->s3_bucket);
418502
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "uri: %s", uri);
419503
cur = ngx_cpystrn(cur, aws_conf->s3_bucket.data, aws_conf->s3_bucket.len + 1);
420504
cur = ngx_cpystrn(cur, uri, uri_len + 1);
421-
505+
422506
if ( c_args_len ) {
423507
ngx_memcpy(cur, c_args, c_args_len + 1);
424508
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "args: %s", c_args);
@@ -433,11 +517,25 @@ ngx_http_aws_auth_get_canon_resource(ngx_http_request_t *r, ngx_str_t *retstr) {
433517

434518
static ngx_int_t
435519
ngx_http_aws_auth_get_dynamic_variables(ngx_http_request_t *r){
436-
/*
437-
* Get value for s3_bucket and chop_prefix
520+
/*
521+
* Get value for s3_bucket and chop_prefix
438522
*/
439523
ngx_http_aws_auth_conf_t *aws_conf;
440524
aws_conf = ngx_http_get_module_loc_conf(r, ngx_http_aws_auth_module);
525+
if (aws_conf->access_key_script != NULL){
526+
if (ngx_http_script_run(r, &aws_conf->access_key, aws_conf->access_key_script->lengths->elts, 1,
527+
aws_conf->access_key_script->values->elts) == NULL) {
528+
return NGX_ERROR;
529+
}
530+
aws_conf->access_key.len = aws_conf->access_key.len -1;
531+
}
532+
if (aws_conf->secret_script != NULL){
533+
if (ngx_http_script_run(r, &aws_conf->secret, aws_conf->secret_script->lengths->elts, 1,
534+
aws_conf->secret_script->values->elts) == NULL) {
535+
return NGX_ERROR;
536+
}
537+
aws_conf->secret.len = aws_conf->secret.len -1;
538+
}
441539
if (aws_conf->s3_bucket_script != NULL){
442540
if (ngx_http_script_run(r, &aws_conf->s3_bucket, aws_conf->s3_bucket_script->lengths->elts, 1,
443541
aws_conf->s3_bucket_script->values->elts) == NULL) {
@@ -483,10 +581,10 @@ ngx_http_aws_auth_variable_s3(ngx_http_request_t *r, ngx_http_variable_value_t *
483581
return NGX_ERROR;
484582
}
485583

486-
/*
584+
/*
487585
* This Block of code added to deal with paths that are not on the root -
488-
* that is, via proxy_pass that are being redirected and the base part of
489-
* the proxy url needs to be taken off the beginning of the URI in order
586+
* that is, via proxy_pass that are being redirected and the base part of
587+
* the proxy url needs to be taken off the beginning of the URI in order
490588
* to sign it correctly.
491589
*/
492590

@@ -570,7 +668,7 @@ ngx_http_aws_auth_variable_s3(ngx_http_request_t *r, ngx_http_variable_value_t *
570668
lenall += el_sign->len;
571669
el = to_sign->elts;
572670

573-
lenall += 4; //newlines
671+
lenall += 4; //newlines
574672
u_char * str_to_sign = ngx_palloc(r->pool, lenall + 50);
575673
int offset = 0;
576674
for (i = 0; i < to_sign->nelts ; i++) {
@@ -593,11 +691,11 @@ ngx_http_aws_auth_variable_s3(ngx_http_request_t *r, ngx_http_variable_value_t *
593691
HMAC(evp_md, aws_conf->secret.data, aws_conf->secret.len, str_to_sign, ngx_strlen(str_to_sign), md, &md_len);
594692

595693
BIO* b64 = BIO_new(BIO_f_base64());
596-
BIO* bmem = BIO_new(BIO_s_mem());
694+
BIO* bmem = BIO_new(BIO_s_mem());
597695
b64 = BIO_push(b64, bmem);
598696
BIO_write(b64, md, md_len);
599697
(void)BIO_flush(b64);
600-
BUF_MEM *bptr;
698+
BUF_MEM *bptr;
601699
BIO_get_mem_ptr(b64, &bptr);
602700

603701
ngx_memcpy(str_to_sign, bptr->data, bptr->length-1);
@@ -620,7 +718,7 @@ ngx_http_aws_auth_variable_s3(ngx_http_request_t *r, ngx_http_variable_value_t *
620718
static ngx_int_t
621719
ngx_http_aws_auth_variable_date(ngx_http_request_t *r, ngx_http_variable_value_t *v,
622720
uintptr_t data)
623-
{
721+
{
624722
v->len = ngx_cached_http_time.len;
625723
v->data = ngx_cached_http_time.data;
626724
v->valid = 1;
@@ -654,10 +752,9 @@ register_variable(ngx_conf_t *cf)
654752
var->data = v->data;
655753
}
656754

657-
return NGX_OK;
755+
return NGX_OK;
658756
}
659757

660-
/*
758+
/*
661759
* vim: ts=4 sw=4 et
662760
*/
663-

0 commit comments

Comments
 (0)