From 7a8682334f95647fefd9df0829f18b6ba5fdff82 Mon Sep 17 00:00:00 2001 From: Sorin Manolache Date: Thu, 28 Mar 2024 15:48:09 +0100 Subject: [PATCH 1/8] .gitignoring autom4te.cache --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b1fa6a7..e36019b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ /config.guess~ /config.sub~ /configure~ +/autom4te.cache From ee5ffc3d1b647272a4b7511ae80241b0cd7b3ed0 Mon Sep 17 00:00:00 2001 From: Sorin Manolache Date: Thu, 28 Mar 2024 15:49:42 +0100 Subject: [PATCH 2/8] Makefile.am: Installation in $(libdir)/nginx/modules. make install-exec works now. No custom install and uninstall targets needed any more. --- Makefile.am | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Makefile.am b/Makefile.am index 92ad68d..649fa07 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,7 +9,8 @@ AM_LDFLAGS = --coverage LDADD = $(CODE_COVERAGE_LIBS) -lib_LTLIBRARIES = @PACKAGE_NAME@.la +pkglib_LTLIBRARIES = @PACKAGE_NAME@.la +pkglibdir = $(libdir)/nginx/modules @PACKAGE_NAME@_la_CFLAGS = @OAUTH2_CFLAGS@ @OAUTH2_NGINX_CFLAGS@ @NGINX_CFLAGS@ @PACKAGE_NAME@_la_LIBADD = @OAUTH2_LIBS@ @OAUTH2_NGINX_LIBS@ @NGINX_LIBS@ @@ -22,10 +23,3 @@ lib_LTLIBRARIES = @PACKAGE_NAME@.la clang-format: clang-format -style=file -i `find . -name *.[ch]` - -install: - ${INSTALL} -d $(DESTDIR)/usr/local/nginx/modules/ - ${INSTALL} -p -m 755 .libs/@PACKAGE_NAME@.so $(DESTDIR)/usr/local/nginx/modules/@PACKAGE_NAME@.so - -uninstall: - rm -f $(DESTDIR)/usr/local/nginx/modules/@PACKAGE_NAME@.so From ee5ea7f3b17fec254ab5a0f2942e43f74effeeb6 Mon Sep 17 00:00:00 2001 From: Sorin Manolache Date: Thu, 28 Mar 2024 15:51:27 +0100 Subject: [PATCH 3/8] * The values of the variables were stored in the local config. A request with a valid token set them. A second request passing no token at all would retrieve the values of the previous token because the local config object would be shared among the requests. The variables are now stored in an ngx_hash in a request context. It is destroyed after each request. * If the request passes no token the previous code still returned NGX_OK. Now we check if there was a OAuth2TokenVerify configuration directive for the location. If yes then we return NGX_HTTP_UNAUTHORIZED. An NGX_OK is returned only if there was no OAuth2TokenVerify configuration directive, meaning that the request is not 'for us'. * Added the optional configuration directive OAuth2Require. It takes between zero and seven arguments. Every argument is a variable name. The authorization callback returns NGX_OK only if every variable is defined and its value is the string '1'. We can combine the Nginx 'map' configuration directive and the variables that hold token values in order to synthesize the variables used by OAuth2Require. In this way we may check that the token holds desired values, for example that 'iss' matches a given regular expression or that the 'scope' is belongs to a required set. This new configuration directive is optional. If absent then the module behaves like before, i.e. it returns NGX_OK if the token can be decrypted, parsed, and it is not expired. --- src/ngx_oauth2_module.c | 348 ++++++++++++++++++++++++++++++---------- 1 file changed, 267 insertions(+), 81 deletions(-) diff --git a/src/ngx_oauth2_module.c b/src/ngx_oauth2_module.c index 8267956..7d18a78 100644 --- a/src/ngx_oauth2_module.c +++ b/src/ngx_oauth2_module.c @@ -19,7 +19,6 @@ * **************************************************************************/ -#include #include #include @@ -27,27 +26,58 @@ #include #include +#include + #include #include #include #include #include -typedef struct ngx_oauth_claim_t { - char *name; - char *value; - struct ngx_oauth_claim_t *next; -} ngx_oauth_claim_t; +extern ngx_module_t ngx_oauth2_module; + +typedef struct ngx_oauth2_claims_hash_s { + ngx_hash_keys_arrays_t keys; + ngx_hash_t h; +} ngx_oauth2_claims_hash_t; typedef struct ngx_oauth2_cfg_t { ngx_http_complex_value_t source_token; oauth2_cfg_token_verify_t *verify; ngx_conf_t *cf; - ngx_oauth_claim_t *claims; + ngx_array_t *requirements; // TODO: oauth2_log_t *log; } ngx_oauth2_cfg_t; +static ngx_int_t ngx_oauth2_init_hash(ngx_pool_t *pool, + ngx_oauth2_claims_hash_t *claims); +static ngx_int_t ngx_oauth2_init_keys(ngx_pool_t *pool, + ngx_oauth2_claims_hash_t *claims); + +static inline ngx_str_t chr_to_ngx_str(ngx_pool_t *p, const char *k) +{ + ngx_str_t in = {strlen(k), (u_char *)k}; + ngx_str_t out = {in.len, ngx_pstrdup(p, &in)}; + return out; +} + +static inline char *ngx_str_to_chr(ngx_pool_t *p, const ngx_str_t *str) +{ + char *s = ngx_pnalloc(p, str->len + 1); + if (s) { + memcpy(s, str->data, str->len); + s[str->len] = '\0'; + } + return s; +} + +static inline char *chr_to_chr(ngx_pool_t *p, const char *str) +{ + ngx_str_t s = {strlen(str), (u_char *)str}; + return ngx_str_to_chr(p, &s); +} + static void ngx_oauth2_cleanup(void *data) { ngx_oauth2_cfg_t *cfg = (ngx_oauth2_cfg_t *)data; @@ -63,7 +93,7 @@ static void *ngx_oauth2_create_loc_conf(ngx_conf_t *cf) cfg = ngx_pcalloc(cf->pool, sizeof(ngx_oauth2_cfg_t)); cfg->log = NULL; cfg->cf = cf; - cfg->claims = NULL; + cfg->requirements = NULL; cfg->verify = NULL; cfg->source_token.flushes = NULL; cfg->source_token.lengths = NULL; @@ -97,32 +127,46 @@ static char *ngx_oauth2_merge_loc_conf(ngx_conf_t *cf, void *parent, ? oauth2_cfg_token_verify_clone(NULL, cfg->verify) : oauth2_cfg_token_verify_clone(NULL, prev->verify); + if (!cfg->requirements) { + // No requirements were set in the child. Copy those of the + // parent. If the child has its own requirements then do not + // override them with the parent's. + cfg->requirements = prev->requirements; + } + return NGX_CONF_OK; } static ngx_int_t ngx_oauth2_claim_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, - uintptr_t data) + uintptr_t s) { - ngx_oauth_claim_t *claim = (ngx_oauth_claim_t *)data; + ngx_oauth2_claims_hash_t *claims; + const char *value; - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "ngx_oauth2_claim_variable: %s=%s", - claim && claim->name ? claim->name : "(null)", - claim && claim->value ? claim->value : "(null)"); + ngx_str_t key = {strlen((const char *)s), (u_char *)s}; - if (claim && claim->value) { - v->len = strlen(claim->value); - v->data = ngx_palloc(r->pool, v->len); - ngx_memcpy(v->data, claim->value, v->len); + claims = (ngx_oauth2_claims_hash_t *) + ngx_http_get_module_ctx(r, ngx_oauth2_module); + if (!claims) { + v->not_found = 1; + return NGX_OK; } - if (v->len) { - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; + value = (const char *)ngx_hash_find(&claims->h, + ngx_hash_key(key.data, key.len), + key.data, key.len); + if (value) { + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ngx_oauth2_claim_variable: %V=%s", &key, value); + v->data = (u_char *)value; + v->len = strlen(value); + v->no_cacheable = 1; + v->not_found = 0; } else { - v->not_found = 1; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ngx_oauth2_claim_variable: %V=(null)", &key); + v->not_found = 1; } return NGX_OK; @@ -133,18 +177,12 @@ static char *ngx_oauth2_set_claim(ngx_conf_t *cf, ngx_command_t *cmd, { char *rv = NGX_CONF_ERROR; // ngx_http_core_loc_conf_t *clcf = NULL; - ngx_oauth2_cfg_t *cfg = (ngx_oauth2_cfg_t *)conf; // ngx_http_compile_complex_value_t ccv; - ngx_str_t *value = NULL; + ngx_str_t *value; ngx_http_variable_t *v; - ngx_oauth_claim_t *claim = NULL, *ptr = NULL; value = cf->args->elts; - claim = ngx_pcalloc(cf->pool, sizeof(ngx_oauth_claim_t)); - claim->name = oauth2_strndup((const char *)value[1].data, value[1].len); - claim->value = NULL; - if (value[2].data[0] != '$') { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid variable name \"%V\"", &value[2]); @@ -156,21 +194,23 @@ static char *ngx_oauth2_set_claim(ngx_conf_t *cf, ngx_command_t *cmd, v = ngx_http_add_variable(cf, &value[2], 0); if (v == NULL) { - rv = "ngx_http_add_variable failed"; + // avoid rv = "...", as it would be an implicit cast + // from const char * to char * + ngx_str_t msg = ngx_string("ngx_http_add_variable failed"); + rv = ngx_str_to_chr(cf->pool, &msg); goto end; } v->get_handler = ngx_oauth2_claim_variable; - v->data = (uintptr_t)claim; - - claim->next = NULL; - if (cfg->claims == NULL) { - cfg->claims = claim; - } else { - for (ptr = cfg->claims; ptr->next; ptr = ptr->next) - ; - ptr->next = claim; + char *claim = ngx_str_to_chr(cf->pool, &value[1]); + if (!claim) { + // avoid rv = "...", as it would be an implicit cast + // from const char * to char * + ngx_str_t msg = ngx_string("Out of memory"); + rv = ngx_str_to_chr(cf->pool, &msg); + goto end; } + v->data = (uintptr_t)claim; rv = NGX_CONF_OK; @@ -212,11 +252,61 @@ OAUTH2_NGINX_CFG_FUNC_ARGS1(oauth2, ngx_oauth2_cfg_t, passphrase, OAUTH2_NGINX_CFG_FUNC_ARGS2(oauth2, ngx_oauth2_cfg_t, cache, oauth2_cfg_set_cache, NULL) +static char *ngx_oauth2_set_require(ngx_conf_t *cf, ngx_command_t *cmd, + void *cnf) +{ + if (!cnf) { + ngx_str_t msg = ngx_string("Out of memory"); + return ngx_str_to_chr(cf->pool, &msg); + } + ngx_oauth2_cfg_t *cfg = (ngx_oauth2_cfg_t *)cnf; + if (!cf->args) { + ngx_str_t msg = ngx_string("Out of memory"); + return ngx_str_to_chr(cf->pool, &msg); + } + + if (!cfg->requirements) { + cfg->requirements = ngx_array_create(cf->pool, cf->args->nelts, + sizeof(ngx_int_t)); + if (!cfg->requirements) { + ngx_str_t msg = ngx_string("Out of memory"); + return ngx_str_to_chr(cf->pool, &msg); + } + } + for (unsigned int i = 1; i < cf->args->nelts; ++i) { + ngx_str_t var = *((ngx_str_t *)(cf->args->elts) + i); + if (var.len > 0 && '$' == *var.data) { + ++var.data; + --var.len; + } + ngx_int_t index = ngx_http_get_variable_index(cf, &var); + if (NGX_ERROR == index) { + static const size_t MAX_SIZE = 128; + char buf[MAX_SIZE]; + int n = snprintf(buf, MAX_SIZE, "Unknown variable %.*s", + (int)var.len, var.data); + if (n >= (int)MAX_SIZE) + n = MAX_SIZE - 1; + ngx_str_t msg = {n, (u_char *)&buf[0]}; + return ngx_str_to_chr(cf->pool, &msg); + } + // no allocation here because we've already dimensioned the + // array upon its creation + ngx_int_t *n = + (ngx_int_t *)ngx_array_push(cfg->requirements); + *n = index; + } + + return NGX_CONF_OK; +} + static ngx_command_t ngx_oauth2_commands[] = { OAUTH2_NGINX_CMD(1, oauth2, "OAuth2CryptoPassphrase", passphrase), OAUTH2_NGINX_CMD(12, oauth2, "OAuth2Cache", cache), OAUTH2_NGINX_CMD(3 | NGX_CONF_TAKE4, oauth2, "OAuth2TokenVerify", token_verify), + OAUTH2_NGINX_CMD(1234 | NGX_CONF_TAKE5 | NGX_CONF_TAKE6 | NGX_CONF_TAKE7, + oauth2, "OAuth2Require", require), OAUTH2_NGINX_CMD(2, oauth2, "OAuth2Claim", claim), ngx_null_command}; static ngx_int_t ngx_oauth2_post_config(ngx_conf_t *cf); @@ -287,49 +377,111 @@ static ngx_int_t ngx_oauth2_post_config(ngx_conf_t *cf) return rv; } -static void ngx_set_target_variable(ngx_oauth2_cfg_t *cfg, - oauth2_nginx_request_context_t *ctx, - const char *key, const char *val) +static ngx_int_t ngx_set_target_variable(ngx_oauth2_claims_hash_t *claims, + oauth2_nginx_request_context_t *ctx, + const char *k, const char *v) { - ngx_oauth_claim_t *ptr = NULL; - ptr = cfg->claims; - while (ptr) { - if (strcmp(ptr->name, key) == 0) - break; - ptr = ptr->next; + ngx_str_t key = chr_to_ngx_str(claims->keys.pool, k); + if (!key.data) { + return NGX_ERROR; } - if (ptr) { - ptr->value = oauth2_strdup(val); + + const char *value = chr_to_chr(claims->keys.pool, v); + if (!value) { + return NGX_ERROR; } + + return ngx_hash_add_key(&claims->keys, &key, (char *)value, + NGX_HASH_READONLY_KEY); } // TODO: generalize/callback part of this (at least the looping and encoding is // generic) -static void ngx_set_target_variables(ngx_oauth2_cfg_t *cfg, - oauth2_nginx_request_context_t *ctx, - json_t *json_token) +static ngx_int_t ngx_set_target_variables(ngx_http_request_t *r, + oauth2_nginx_request_context_t *ctx, + json_t *json_token) { - void *iter = NULL; - const char *key = NULL; - json_t *value = NULL; - char *val = NULL; + void *iter; + const char *key; + json_t *value; + ngx_oauth2_claims_hash_t *claims; + + claims = (ngx_oauth2_claims_hash_t *) + ngx_http_get_module_ctx(r, ngx_oauth2_module); + if (!claims) { + int rc; + + claims = ngx_palloc(r->pool, sizeof(*claims)); + if (!claims) { + return NGX_ERROR; + } + + rc = ngx_oauth2_init_keys(r->pool, claims); + if (NGX_OK != rc) { + return rc; + } + + ngx_http_set_ctx(r, claims, ngx_oauth2_module); + } + iter = json_object_iter(json_token); while (iter) { + int rc; + key = json_object_iter_key(iter); value = json_object_iter_value(iter); if (json_is_string(value)) { - val = oauth2_strdup(json_string_value(value)); + rc = ngx_set_target_variable(claims, ctx, key, + json_string_value(value)); } else { - val = oauth2_json_encode(ctx->log, value, - JSON_ENCODE_ANY); + const char *val = oauth2_json_encode(ctx->log, value, + JSON_ENCODE_ANY); + rc = ngx_set_target_variable(claims, ctx, key, val); + oauth2_mem_free((char *)val); } - ngx_set_target_variable(cfg, ctx, key, val); + if (NGX_OK != rc) { + return rc; + } - if (val) - oauth2_mem_free(val); iter = json_object_iter_next(json_token, iter); } + + return ngx_oauth2_init_hash(r->pool, claims); +} + +static ngx_int_t +ngx_oauth2_check_requirement(ngx_http_request_t *r, + oauth2_nginx_request_context_t *ctx, + ngx_int_t var) { + ngx_http_variable_value_t *v = ngx_http_get_flushed_variable(r, var); + + if (!v || v->not_found) { + oauth2_error(ctx->log, "Variable not found"); + return NGX_ERROR; + } + + return 1 == v->len && '1' == *v->data ? NGX_OK : NGX_HTTP_UNAUTHORIZED; +} + +static ngx_int_t +ngx_oauth2_check_requirements(ngx_http_request_t *r, + oauth2_nginx_request_context_t *ctx, + ngx_oauth2_cfg_t *cfg) { + if (!cfg->requirements) { + return NGX_OK; + } + + for (unsigned int i = 0; i < cfg->requirements->nelts; ++i) { + ngx_int_t var = + *(ngx_int_t *)cfg->requirements->elts + i; + int rc = ngx_oauth2_check_requirement(r, ctx, var); + if (NGX_OK != rc) { + return rc; + } + } + + return NGX_OK; } static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r) @@ -337,22 +489,30 @@ static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r) ngx_int_t rv = NGX_DECLINED; // bool rc = false; oauth2_nginx_request_context_t *ctx = NULL; - ngx_oauth2_cfg_t *cfg = NULL; + ngx_oauth2_cfg_t *cfg; ngx_str_t ngx_source_token; char *source_token = NULL; json_t *json_payload = NULL; - ngx_source_token.data = NULL; - ngx_source_token.len = 0; - - if (r != r->main) - goto end; + if (r != r->main) { + // Do not goto end because ctx is not yet built and ctx->log + // would segfault + return NGX_DECLINED; + } cfg = (ngx_oauth2_cfg_t *)ngx_http_get_module_loc_conf( r, ngx_oauth2_module); if (cfg == NULL) { - rv = NGX_ERROR; - goto end; + // Do not goto end because ctx is not yet built and ctx->log + // would segfault + return NGX_ERROR; + } + + if (!cfg->verify) { + // This is an unhandled path. There was no OAuth2TokenVerify + // conf directive in this location. + // Do not goto end because the ctx is not yet built + return NGX_DECLINED; } ctx = oauth2_nginx_request_context_init(r); @@ -361,8 +521,7 @@ static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r) goto end; } - // TODO: if we have a verify post config, call it here - // ... + ngx_str_null(&ngx_source_token); if (ngx_http_complex_value(r, &cfg->source_token, &ngx_source_token) != NGX_OK) { @@ -376,8 +535,7 @@ static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r) if (ngx_source_token.len == 0) { oauth2_debug(ctx->log, "ngx_http_complex_value ngx_source_token.len=0"); - // needed for non-handled paths - // TODO: return an error if there was any config for this path? + rv = NGX_HTTP_UNAUTHORIZED; goto end; } @@ -390,17 +548,19 @@ static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r) if (oauth2_token_verify(ctx->log, ctx->request, cfg->verify, source_token, &json_payload) == false) { oauth2_warn(ctx->log, "Token could not be verified."); - // TODO: return HTTP 401 unauthorized - rv = NGX_ERROR; + rv = NGX_HTTP_UNAUTHORIZED; goto end; } oauth2_debug(ctx->log, "json_payload=%p", json_payload); - ngx_set_target_variables(cfg, ctx, json_payload); + rv = ngx_set_target_variables(r, ctx, json_payload); + if (NGX_OK != rv) { + oauth2_error(ctx->log, "Error setting variables."); + goto end; + } - // TODO: set response, right...? - rv = NGX_OK; + rv = ngx_oauth2_check_requirements(r, ctx, cfg); end: @@ -417,3 +577,29 @@ static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r) return rv; } + +static ngx_int_t ngx_oauth2_init_keys(ngx_pool_t *pool, + ngx_oauth2_claims_hash_t *claims) +{ + claims->keys.pool = pool; + claims->keys.temp_pool = pool; + + return ngx_hash_keys_array_init(&claims->keys, NGX_HASH_SMALL); +} + +static ngx_int_t ngx_oauth2_init_hash(ngx_pool_t *pool, + ngx_oauth2_claims_hash_t *claims) +{ + ngx_hash_init_t init; + + init.hash = &claims->h; + init.key = ngx_hash_key; + init.max_size = 64; + init.bucket_size = ngx_align(64, ngx_cacheline_size); + init.name = "claims"; + init.pool = pool; + init.temp_pool = pool; + + return ngx_hash_init(&init, claims->keys.keys.elts, + claims->keys.keys.nelts); +} From f50889442af5b6215c75bd5f2a9ca573cb977578 Mon Sep 17 00:00:00 2001 From: Sorin Manolache Date: Thu, 28 Mar 2024 17:30:12 +0100 Subject: [PATCH 4/8] bug fix in handling ngx_arrays --- src/ngx_oauth2_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ngx_oauth2_module.c b/src/ngx_oauth2_module.c index 7d18a78..8446bcb 100644 --- a/src/ngx_oauth2_module.c +++ b/src/ngx_oauth2_module.c @@ -474,7 +474,7 @@ ngx_oauth2_check_requirements(ngx_http_request_t *r, for (unsigned int i = 0; i < cfg->requirements->nelts; ++i) { ngx_int_t var = - *(ngx_int_t *)cfg->requirements->elts + i; + *((ngx_int_t *)cfg->requirements->elts + i); int rc = ngx_oauth2_check_requirement(r, ctx, var); if (NGX_OK != rc) { return rc; From 30e423a00eeb0f21b867eab2595f486820356c2a Mon Sep 17 00:00:00 2001 From: Sorin Manolache Date: Mon, 22 Apr 2024 18:58:52 +0200 Subject: [PATCH 5/8] OAuth2Require directive may be placed inside ifs --- src/ngx_oauth2_module.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ngx_oauth2_module.c b/src/ngx_oauth2_module.c index 8446bcb..2d7e147 100644 --- a/src/ngx_oauth2_module.c +++ b/src/ngx_oauth2_module.c @@ -305,8 +305,13 @@ static ngx_command_t ngx_oauth2_commands[] = { OAUTH2_NGINX_CMD(12, oauth2, "OAuth2Cache", cache), OAUTH2_NGINX_CMD(3 | NGX_CONF_TAKE4, oauth2, "OAuth2TokenVerify", token_verify), - OAUTH2_NGINX_CMD(1234 | NGX_CONF_TAKE5 | NGX_CONF_TAKE6 | NGX_CONF_TAKE7, - oauth2, "OAuth2Require", require), + { + ngx_string("OAuth2Require"), + NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | + NGX_CONF_TAKE1 | NGX_CONF_TAKE2 | NGX_CONF_TAKE3 | NGX_CONF_TAKE4 | + NGX_CONF_TAKE5 | NGX_CONF_TAKE6 | NGX_CONF_TAKE7, + ngx_oauth2_set_require, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL + }, OAUTH2_NGINX_CMD(2, oauth2, "OAuth2Claim", claim), ngx_null_command}; static ngx_int_t ngx_oauth2_post_config(ngx_conf_t *cf); From c71817010bcd2fda94eedc8196de52f089f6e261 Mon Sep 17 00:00:00 2001 From: Sorin Manolache Date: Mon, 22 Apr 2024 22:16:31 +0200 Subject: [PATCH 6/8] All OAuth2 directives may be placed inside ifs --- src/ngx_oauth2_module.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/ngx_oauth2_module.c b/src/ngx_oauth2_module.c index 2d7e147..13b6a7b 100644 --- a/src/ngx_oauth2_module.c +++ b/src/ngx_oauth2_module.c @@ -301,10 +301,24 @@ static char *ngx_oauth2_set_require(ngx_conf_t *cf, ngx_command_t *cmd, } static ngx_command_t ngx_oauth2_commands[] = { - OAUTH2_NGINX_CMD(1, oauth2, "OAuth2CryptoPassphrase", passphrase), - OAUTH2_NGINX_CMD(12, oauth2, "OAuth2Cache", cache), - OAUTH2_NGINX_CMD(3 | NGX_CONF_TAKE4, oauth2, "OAuth2TokenVerify", - token_verify), + { + ngx_string("OAuth2CryptoPassphrase"), + NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | + NGX_CONF_TAKE1, + ngx_oauth2_set_passphrase, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL + }, + { + ngx_string("OAuth2Cache"), + NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | + NGX_CONF_TAKE12, + ngx_oauth2_set_cache, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL + }, + { + ngx_string("OAuth2TokenVerify"), + NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | + NGX_CONF_TAKE3 | NGX_CONF_TAKE4, + ngx_oauth2_set_token_verify, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL + }, { ngx_string("OAuth2Require"), NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | @@ -312,7 +326,14 @@ static ngx_command_t ngx_oauth2_commands[] = { NGX_CONF_TAKE5 | NGX_CONF_TAKE6 | NGX_CONF_TAKE7, ngx_oauth2_set_require, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, - OAUTH2_NGINX_CMD(2, oauth2, "OAuth2Claim", claim), ngx_null_command}; + { + ngx_string("OAuth2Claim"), + NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | + NGX_CONF_TAKE2, + ngx_oauth2_set_claim, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL + }, + ngx_null_command +}; static ngx_int_t ngx_oauth2_post_config(ngx_conf_t *cf); From c2787cb653c97e70ff0e859ecc24a1aa5c9f3649 Mon Sep 17 00:00:00 2001 From: Sorin Manolache Date: Mon, 22 Apr 2024 23:23:04 +0200 Subject: [PATCH 7/8] OAuth2Claim: avoid defining the same variable multiple times --- src/ngx_oauth2_module.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ngx_oauth2_module.c b/src/ngx_oauth2_module.c index 13b6a7b..f7b1d46 100644 --- a/src/ngx_oauth2_module.c +++ b/src/ngx_oauth2_module.c @@ -192,7 +192,7 @@ static char *ngx_oauth2_set_claim(ngx_conf_t *cf, ngx_command_t *cmd, value[2].len--; value[2].data++; - v = ngx_http_add_variable(cf, &value[2], 0); + v = ngx_http_add_variable(cf, &value[2], NGX_HTTP_VAR_CHANGEABLE); if (v == NULL) { // avoid rv = "...", as it would be an implicit cast // from const char * to char * @@ -215,7 +215,6 @@ static char *ngx_oauth2_set_claim(ngx_conf_t *cf, ngx_command_t *cmd, rv = NGX_CONF_OK; end: - return rv; } From 9568c8c78d7e0cd32d019a511271d1a378516ed2 Mon Sep 17 00:00:00 2001 From: Sorin Manolache Date: Tue, 23 Apr 2024 12:05:46 +0200 Subject: [PATCH 8/8] logging; claims are not variable indexes any more but compiled values --- src/ngx_oauth2_module.c | 378 +++++++++++++++++++++++++++------------- 1 file changed, 260 insertions(+), 118 deletions(-) diff --git a/src/ngx_oauth2_module.c b/src/ngx_oauth2_module.c index f7b1d46..210b881 100644 --- a/src/ngx_oauth2_module.c +++ b/src/ngx_oauth2_module.c @@ -46,7 +46,6 @@ typedef struct ngx_oauth2_cfg_t { oauth2_cfg_token_verify_t *verify; ngx_conf_t *cf; ngx_array_t *requirements; - // TODO: oauth2_log_t *log; } ngx_oauth2_cfg_t; @@ -83,14 +82,24 @@ static void ngx_oauth2_cleanup(void *data) ngx_oauth2_cfg_t *cfg = (ngx_oauth2_cfg_t *)data; if (cfg->verify) oauth2_cfg_token_verify_free(NULL, cfg->verify); + if (cfg->log) { + oauth2_log_free(cfg->log); + } } static void *ngx_oauth2_create_loc_conf(ngx_conf_t *cf) { ngx_oauth2_cfg_t *cfg = NULL; ngx_pool_cleanup_t *cln = NULL; + oauth2_log_sink_t *sink; cfg = ngx_pcalloc(cf->pool, sizeof(ngx_oauth2_cfg_t)); + if (!cfg) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_ENOMEM, + "ngx_oauth2_create_loc_conf: out of memory " + "allocating location configuration"); + return NULL; + } cfg->log = NULL; cfg->cf = cf; cfg->requirements = NULL; @@ -101,17 +110,33 @@ static void *ngx_oauth2_create_loc_conf(ngx_conf_t *cf) cfg->source_token.value.len = 0; cfg->source_token.values = NULL; - // TODO: correct level - // oauth2_log_t *log = oauth2_log_init(OAUTH2_LOG_TRACE1, NULL); - cln = ngx_pool_cleanup_add(cf->pool, 0); - if (cln == NULL) - goto end; + if (!cln) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, NGX_ENOMEM, + "ngx_oauth2_create_loc_conf: out of memory " + "allocating cleanup handler"); + return NULL; + } cln->handler = ngx_oauth2_cleanup; cln->data = cfg; -end: + sink = oauth2_log_sink_create(OAUTH2_LOG_INFO, oauth2_nginx_log, + cf->log); + if (!sink) { + ngx_conf_log_error(NGX_LOG_WARN, cf, NGX_ENOMEM, + "ngx_oauth2_create_loc_conf: out of memory " + "allocating log sink"); + return cfg; + } + cfg->log = oauth2_log_init(OAUTH2_LOG_INFO, sink); + if (!cfg->log) { + ngx_conf_log_error(NGX_LOG_WARN, cf, NGX_ENOMEM, + "ngx_oauth2_create_loc_conf: out of memory " + "allocating logger"); + oauth2_mem_free(sink); + return cfg; + } return cfg; } @@ -175,7 +200,6 @@ static ngx_int_t ngx_oauth2_claim_variable(ngx_http_request_t *r, static char *ngx_oauth2_set_claim(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - char *rv = NGX_CONF_ERROR; // ngx_http_core_loc_conf_t *clcf = NULL; // ngx_http_compile_complex_value_t ccv; ngx_str_t *value; @@ -183,22 +207,26 @@ static char *ngx_oauth2_set_claim(ngx_conf_t *cf, ngx_command_t *cmd, value = cf->args->elts; - if (value[2].data[0] != '$') { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid variable name \"%V\"", &value[2]); - goto end; + if (value[2].len <= 1 || value[2].data[0] != '$') { + static const size_t MAX_BUF = 128; + char buf[MAX_BUF]; + int n = snprintf(buf, sizeof(buf), "Invalid variable name %.*s", + (int)value[2].len, value[2].data); + ngx_str_t msg = {n, (u_char *)&buf[0]}; + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; } value[2].len--; value[2].data++; v = ngx_http_add_variable(cf, &value[2], NGX_HTTP_VAR_CHANGEABLE); - if (v == NULL) { + if (!v) { // avoid rv = "...", as it would be an implicit cast // from const char * to char * ngx_str_t msg = ngx_string("ngx_http_add_variable failed"); - rv = ngx_str_to_chr(cf->pool, &msg); - goto end; + char *rv = ngx_str_to_chr(cf->pool, &msg); + return rv ? rv : NGX_CONF_ERROR; } v->get_handler = ngx_oauth2_claim_variable; @@ -207,93 +235,184 @@ static char *ngx_oauth2_set_claim(ngx_conf_t *cf, ngx_command_t *cmd, // avoid rv = "...", as it would be an implicit cast // from const char * to char * ngx_str_t msg = ngx_string("Out of memory"); - rv = ngx_str_to_chr(cf->pool, &msg); - goto end; + char *rv = ngx_str_to_chr(cf->pool, &msg); + return rv ? rv : NGX_CONF_ERROR; } v->data = (uintptr_t)claim; - rv = NGX_CONF_OK; + return NGX_CONF_OK; +} + +static char * +ngx_oauth2_set_token_verify(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + char *rv; + ngx_oauth2_cfg_t *cfg = (ngx_oauth2_cfg_t *)conf; + ngx_str_t *value = cf->args->elts; + ngx_http_compile_complex_value_t ccv; + int rc; + char *v1 = NULL, *v2 = NULL, *v3 = NULL; + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &cfg->source_token; + + rc = ngx_http_compile_complex_value(&ccv); + if (NGX_OK != rc) { + static const size_t MAX_BUF = 128; + char buf[MAX_BUF]; + int n = snprintf(buf, sizeof(buf), "Error %d compiling " + "expression %.*s", rc, (int)value[1].len, + value[1].data); + ngx_str_t msg = {n, (u_char *)&buf[0]}; + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; + } + + if (cf->args->nelts > 2) { + v1 = oauth2_strndup((const char *)value[2].data, + (size_t)value[2].len); + if (!v1) { + ngx_str_t msg = ngx_string("Out of memory"); + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; + } + } + if (cf->args->nelts > 3) { + v2 = oauth2_strndup((const char *)value[3].data, + (size_t)value[3].len); + if (!v1) { + ngx_str_t msg = ngx_string("Out of memory"); + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; + } + } + if (cf->args->nelts > 4) { + v3 = oauth2_strndup((const char *)value[4].data, + (size_t)value[4].len); + if (!v1) { + ngx_str_t msg = ngx_string("Out of memory"); + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; + } + } + + rv = oauth2_cfg_token_verify_add_options(NULL, &cfg->verify, v1, v2, v3); + + oauth2_mem_free(v3); + oauth2_mem_free(v2); + oauth2_mem_free(v1); -end: return rv; } -// ngx_oauth2_cfg_set_token_verify -OAUTH2_NGINX_CFG_FUNC_START(oauth2, ngx_oauth2_cfg_t, token_verify) -ngx_http_compile_complex_value_t ccv; - -ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); -ccv.cf = cf; -ccv.value = &value[1]; -ccv.complex_value = &cfg->source_token; -// TODO: check return value -ngx_http_compile_complex_value(&ccv); - -char *v1 = cf->args->nelts > 2 ? oauth2_strndup((const char *)value[2].data, - (size_t)value[2].len) - : NULL; -char *v2 = cf->args->nelts > 3 ? oauth2_strndup((const char *)value[3].data, - (size_t)value[3].len) - : NULL; -char *v3 = cf->args->nelts > 4 ? oauth2_strndup((const char *)value[4].data, - (size_t)value[4].len) - : NULL; - -rv = oauth2_cfg_token_verify_add_options(NULL, &cfg->verify, v1, v2, v3); - -oauth2_mem_free(v3); -oauth2_mem_free(v2); -oauth2_mem_free(v1); -OAUTH2_NGINX_CFG_FUNC_END(cf, rv) - -OAUTH2_NGINX_CFG_FUNC_ARGS1(oauth2, ngx_oauth2_cfg_t, passphrase, - oauth2_crypto_passphrase_set, NULL) -OAUTH2_NGINX_CFG_FUNC_ARGS2(oauth2, ngx_oauth2_cfg_t, cache, - oauth2_cfg_set_cache, NULL) - -static char *ngx_oauth2_set_require(ngx_conf_t *cf, ngx_command_t *cmd, - void *cnf) -{ +static char * +ngx_oauth2_set_passphrase(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + const char *rv; + ngx_oauth2_cfg_t *cfg = (ngx_oauth2_cfg_t *)cf; + ngx_str_t *value = cf->args->elts; + char *v1 = NULL; + + if (cf->args->nelts > 1) { + v1 = oauth2_strndup((const char *)value[1].data, + (size_t)value[1].len); + if (!v1) { + ngx_str_t msg = ngx_string("Out of memory"); + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; + } + } + rv = oauth2_crypto_passphrase_set(cfg->log, NULL, v1); + oauth2_mem_free(v1); + if (rv) { + char *s = chr_to_chr(cf->pool, rv); + return s ? s : NGX_CONF_ERROR; + } + return NGX_CONF_OK; +} + +static char * +ngx_oauth2_set_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + char *rv; + ngx_oauth2_cfg_t *cfg = (ngx_oauth2_cfg_t *)cf; + ngx_str_t *value = cf->args->elts; + char *v1 = NULL, *v2 = NULL; + + if (cf->args->nelts > 1) { + v1 = oauth2_strndup((const char *)value[1].data, + (size_t)value[1].len); + if (!v1) { + ngx_str_t msg = ngx_string("Out of memory"); + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; + } + } + if (cf->args->nelts > 2) { + v2 = oauth2_strndup((const char *)value[2].data, + (size_t)value[2].len); + if (!v2) { + ngx_str_t msg = ngx_string("Out of memory"); + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; + } + } + rv = oauth2_cfg_set_cache(cfg->log, NULL, v1, v2); + oauth2_mem_free(v1); + return rv; +} + +static char * +ngx_oauth2_set_require(ngx_conf_t *cf, ngx_command_t *cmd, void *cnf) { if (!cnf) { ngx_str_t msg = ngx_string("Out of memory"); - return ngx_str_to_chr(cf->pool, &msg); + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; } ngx_oauth2_cfg_t *cfg = (ngx_oauth2_cfg_t *)cnf; if (!cf->args) { ngx_str_t msg = ngx_string("Out of memory"); - return ngx_str_to_chr(cf->pool, &msg); + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; } if (!cfg->requirements) { - cfg->requirements = ngx_array_create(cf->pool, cf->args->nelts, - sizeof(ngx_int_t)); + cfg->requirements = + ngx_array_create(cf->pool, cf->args->nelts, + sizeof(ngx_http_complex_value_t)); if (!cfg->requirements) { ngx_str_t msg = ngx_string("Out of memory"); - return ngx_str_to_chr(cf->pool, &msg); + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; } } for (unsigned int i = 1; i < cf->args->nelts; ++i) { - ngx_str_t var = *((ngx_str_t *)(cf->args->elts) + i); - if (var.len > 0 && '$' == *var.data) { - ++var.data; - --var.len; - } - ngx_int_t index = ngx_http_get_variable_index(cf, &var); - if (NGX_ERROR == index) { - static const size_t MAX_SIZE = 128; - char buf[MAX_SIZE]; - int n = snprintf(buf, MAX_SIZE, "Unknown variable %.*s", - (int)var.len, var.data); - if (n >= (int)MAX_SIZE) - n = MAX_SIZE - 1; - ngx_str_t msg = {n, (u_char *)&buf[0]}; - return ngx_str_to_chr(cf->pool, &msg); - } + ngx_http_complex_value_t *val; + ngx_http_compile_complex_value_t ccv; + ngx_str_t *var; + int rc; + + var = (ngx_str_t *)cf->args->elts + i; // no allocation here because we've already dimensioned the // array upon its creation - ngx_int_t *n = - (ngx_int_t *)ngx_array_push(cfg->requirements); - *n = index; + val = (ngx_http_complex_value_t *) + ngx_array_push(cfg->requirements); + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + ccv.cf = cf; + ccv.value = var; + ccv.complex_value = val; + + rc = ngx_http_compile_complex_value(&ccv); + if (NGX_OK != rc) { + static const size_t MAX_BUF = 128; + char buf[MAX_BUF]; + int n = snprintf(buf, sizeof(buf), "Error %d compiling " + "expression %.*s", rc, (int)var->len, + var->data); + ngx_str_t msg = {n, (u_char *)&buf[0]}; + char *s = ngx_str_to_chr(cf->pool, &msg); + return s ? s : NGX_CONF_ERROR; + } } return NGX_CONF_OK; @@ -430,19 +549,24 @@ static ngx_int_t ngx_set_target_variables(ngx_http_request_t *r, const char *key; json_t *value; ngx_oauth2_claims_hash_t *claims; + int rc; claims = (ngx_oauth2_claims_hash_t *) ngx_http_get_module_ctx(r, ngx_oauth2_module); if (!claims) { - int rc; - claims = ngx_palloc(r->pool, sizeof(*claims)); if (!claims) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, + NGX_ENOMEM, "ngx_set_target_variables: " + "error allocating claims hash"); return NGX_ERROR; } rc = ngx_oauth2_init_keys(r->pool, claims); if (NGX_OK != rc) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "ngx_set_target_variables: error %d " + "initializing hash keys", rc); return rc; } @@ -451,8 +575,6 @@ static ngx_int_t ngx_set_target_variables(ngx_http_request_t *r, iter = json_object_iter(json_token); while (iter) { - int rc; - key = json_object_iter_key(iter); value = json_object_iter_value(iter); if (json_is_string(value)) { @@ -466,27 +588,40 @@ static ngx_int_t ngx_set_target_variables(ngx_http_request_t *r, } if (NGX_OK != rc) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "ngx_set_target_variables: error %d " + "setting value of key %s in claims hash", + rc, key); return rc; } iter = json_object_iter_next(json_token, iter); } - return ngx_oauth2_init_hash(r->pool, claims); + rc = ngx_oauth2_init_hash(r->pool, claims); + if (NGX_OK != rc) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "ngx_set_target_variables: error %d initializing " + "claims hash", rc); + return rc; + } + return NGX_OK; } static ngx_int_t ngx_oauth2_check_requirement(ngx_http_request_t *r, oauth2_nginx_request_context_t *ctx, - ngx_int_t var) { - ngx_http_variable_value_t *v = ngx_http_get_flushed_variable(r, var); - - if (!v || v->not_found) { - oauth2_error(ctx->log, "Variable not found"); + ngx_http_complex_value_t *cv) { + ngx_str_t v; + ngx_int_t rc = ngx_http_complex_value(r, cv, &v); + if (NGX_OK != rc) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Error %d " + "evaluating expression %*.s", rc, + (int)cv->value.len, cv->value.data); return NGX_ERROR; } - return 1 == v->len && '1' == *v->data ? NGX_OK : NGX_HTTP_UNAUTHORIZED; + return 1 == v.len && '1' == *v.data ? NGX_OK : NGX_HTTP_UNAUTHORIZED; } static ngx_int_t @@ -498,9 +633,9 @@ ngx_oauth2_check_requirements(ngx_http_request_t *r, } for (unsigned int i = 0; i < cfg->requirements->nelts; ++i) { - ngx_int_t var = - *((ngx_int_t *)cfg->requirements->elts + i); - int rc = ngx_oauth2_check_requirement(r, ctx, var); + ngx_http_complex_value_t *cv = + (ngx_http_complex_value_t *)cfg->requirements->elts + i; + int rc = ngx_oauth2_check_requirement(r, ctx, cv); if (NGX_OK != rc) { return rc; } @@ -525,41 +660,45 @@ static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r) return NGX_DECLINED; } - cfg = (ngx_oauth2_cfg_t *)ngx_http_get_module_loc_conf( - r, ngx_oauth2_module); - if (cfg == NULL) { - // Do not goto end because ctx is not yet built and ctx->log - // would segfault + cfg = (ngx_oauth2_cfg_t *) + ngx_http_get_module_loc_conf(r, ngx_oauth2_module); + if (!cfg) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ENOMEM, + "ngx_oauth2_handler: error allocating request " + "context"); return NGX_ERROR; } if (!cfg->verify) { // This is an unhandled path. There was no OAuth2TokenVerify // conf directive in this location. - // Do not goto end because the ctx is not yet built return NGX_DECLINED; } ctx = oauth2_nginx_request_context_init(r); - if (ctx == NULL) { - rv = NGX_ERROR; - goto end; + if (!ctx) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "ngx_oauth2_handler: error initializing request " + "context"); + return NGX_ERROR; } ngx_str_null(&ngx_source_token); - if (ngx_http_complex_value(r, &cfg->source_token, &ngx_source_token) != - NGX_OK) { - oauth2_warn( - ctx->log, - "ngx_http_complex_value failed to obtain source_token"); + rv = ngx_http_complex_value(r, &cfg->source_token, &ngx_source_token); + if (NGX_OK != rv) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "ngx_oauth2_handler: error %d evaluating " + "expression %*.s", rv, + (int)cfg->source_token.value.len, + cfg->source_token.value.data); rv = NGX_ERROR; goto end; } if (ngx_source_token.len == 0) { - oauth2_debug(ctx->log, - "ngx_http_complex_value ngx_source_token.len=0"); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ngx_oauth2_handler: empty token"); rv = NGX_HTTP_UNAUTHORIZED; goto end; } @@ -567,35 +706,38 @@ static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r) source_token = oauth2_strndup((const char *)ngx_source_token.data, ngx_source_token.len); - oauth2_debug(ctx->log, "enter: source_token=%s, initial_request=%d", - source_token, (r != r->main)); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ngx_oauth2_handler: enter: source_token=%s, " + "initial_request=%d", source_token, (r != r->main)); - if (oauth2_token_verify(ctx->log, ctx->request, cfg->verify, - source_token, &json_payload) == false) { - oauth2_warn(ctx->log, "Token could not be verified."); + if (!oauth2_token_verify(ctx->log, ctx->request, cfg->verify, + source_token, &json_payload)) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "ngx_oauth2_handler: token %s could not be " + "verified", source_token); rv = NGX_HTTP_UNAUTHORIZED; goto end; } - oauth2_debug(ctx->log, "json_payload=%p", json_payload); + ngx_log_debug1(NGX_LOG_DEBUG, r->connection->log, 0, + "ngx_oauth2_handler: json_payload=%p", json_payload); rv = ngx_set_target_variables(r, ctx, json_payload); if (NGX_OK != rv) { - oauth2_error(ctx->log, "Error setting variables."); goto end; } rv = ngx_oauth2_check_requirements(r, ctx, cfg); end: - if (source_token) oauth2_mem_free(source_token); if (json_payload) json_decref(json_payload); // hereafter we destroy the log object... - oauth2_debug(ctx->log, "leave: %d", rv); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "Leave: %d", rv); if (ctx) oauth2_nginx_request_context_free(ctx);