31
31
#include <oauth2/oauth2.h>
32
32
#include <oauth2/version.h>
33
33
34
- typedef struct ngx_oauth2_claims_hash_s {
35
- ngx_hash_keys_arrays_t keys ;
36
- ngx_hash_t h ;
37
- } ngx_oauth2_claims_hash_t ;
38
-
39
34
typedef struct ngx_oauth2_cfg_t {
40
35
ngx_http_complex_value_t source_token ;
41
36
oauth2_cfg_token_verify_t * verify ;
42
37
ngx_conf_t * cf ;
38
+ ngx_array_t * requirements ;
43
39
// TODO:
44
40
oauth2_log_t * log ;
45
41
} ngx_oauth2_cfg_t ;
@@ -59,6 +55,7 @@ static void *ngx_oauth2_create_loc_conf(ngx_conf_t *cf)
59
55
cfg = ngx_pcalloc (cf -> pool , sizeof (ngx_oauth2_cfg_t ));
60
56
cfg -> log = NULL ;
61
57
cfg -> cf = cf ;
58
+ cfg -> requirements = NULL ;
62
59
cfg -> verify = NULL ;
63
60
cfg -> source_token .flushes = NULL ;
64
61
cfg -> source_token .lengths = NULL ;
@@ -88,39 +85,18 @@ static char *ngx_oauth2_merge_loc_conf(ngx_conf_t *cf, void *parent,
88
85
ngx_oauth2_cfg_t * cfg = child ;
89
86
90
87
cfg -> cf = cf ;
88
+ if (cfg -> requirements == NULL )
89
+ /* no requirements were set in the child, copy those of the
90
+ * parent; if the child has its own requirements then do not
91
+ * override them with the parent's */
92
+ cfg -> requirements = prev -> requirements ;
91
93
cfg -> verify = cfg -> verify
92
94
? oauth2_cfg_token_verify_clone (NULL , cfg -> verify )
93
95
: oauth2_cfg_token_verify_clone (NULL , prev -> verify );
94
96
95
97
return NGX_CONF_OK ;
96
98
}
97
99
98
- static inline ngx_str_t chr_to_ngx_str (ngx_pool_t * p , const char * k )
99
- {
100
- ngx_str_t in = {strlen (k ), (u_char * )k };
101
- ngx_str_t out = {in .len , ngx_pstrdup (p , & in )};
102
- return out ;
103
- }
104
-
105
- static inline char * ngx_str_to_chr (ngx_pool_t * p , const ngx_str_t * str )
106
- {
107
- char * s = ngx_pnalloc (p , str -> len + 1 );
108
- if (s ) {
109
- memcpy (s , str -> data , str -> len );
110
- s [str -> len ] = '\0' ;
111
- }
112
- return s ;
113
- }
114
-
115
- static inline char * chr_to_chr (ngx_pool_t * p , const char * str )
116
- {
117
- ngx_str_t s = {strlen (str ), (u_char * )str };
118
- return ngx_str_to_chr (p , & s );
119
- }
120
-
121
- static char * ngx_oauth2_set_claim (ngx_conf_t * cf , ngx_command_t * cmd ,
122
- void * conf );
123
-
124
100
// ngx_oauth2_cfg_set_token_verify
125
101
OAUTH2_NGINX_CFG_FUNC_START (oauth2 , ngx_oauth2_cfg_t , token_verify )
126
102
int rc = NGX_OK ;
@@ -140,7 +116,7 @@ if (rc != NGX_OK) {
140
116
"expression %.*s" ,
141
117
rc , (int )value [1 ].len , value [1 ].data );
142
118
ngx_str_t msg = {n , (u_char * )& buf [0 ]};
143
- char * s = ngx_str_to_chr (cf -> pool , & msg );
119
+ char * s = oauth2_nginx_str2chr (cf -> pool , & msg );
144
120
return s ? s : NGX_CONF_ERROR ;
145
121
}
146
122
@@ -161,17 +137,27 @@ oauth2_mem_free(v2);
161
137
oauth2_mem_free (v1 );
162
138
OAUTH2_NGINX_CFG_FUNC_END (cf , rv )
163
139
140
+ OAUTH2_NGINX_CFG_FUNC_RET1 (oauth2 , ngx_oauth2_cfg_t , require ,
141
+ nginx_oauth2_set_require , requirements )
142
+
164
143
OAUTH2_NGINX_CFG_FUNC_ARGS1 (oauth2 , ngx_oauth2_cfg_t , passphrase ,
165
144
oauth2_crypto_passphrase_set , NULL )
166
145
OAUTH2_NGINX_CFG_FUNC_ARGS2 (oauth2 , ngx_oauth2_cfg_t , cache ,
167
146
oauth2_cfg_set_cache , NULL )
168
147
148
+ ngx_module_t ngx_oauth2_module ;
149
+ OAUTH2_NGINX_CMD_SET_IMPL (oauth2 , claim )
150
+
169
151
static ngx_command_t ngx_oauth2_commands [] = {
170
152
OAUTH2_NGINX_CMD (1 , oauth2 , "OAuth2CryptoPassphrase" , passphrase ),
171
153
OAUTH2_NGINX_CMD (12 , oauth2 , "OAuth2Cache" , cache ),
172
154
OAUTH2_NGINX_CMD (3 | NGX_CONF_TAKE4 , oauth2 , "OAuth2TokenVerify" ,
173
155
token_verify ),
174
- OAUTH2_NGINX_CMD (2 , oauth2 , "OAuth2Claim" , claim ), ngx_null_command };
156
+ OAUTH2_NGINX_CMD (123 | NGX_CONF_TAKE4 | NGX_CONF_TAKE5 | NGX_CONF_TAKE6 |
157
+ NGX_CONF_TAKE7 ,
158
+ oauth2 , "OAuth2Require" , require ),
159
+ OAUTH2_NGINX_CMD (2 , oauth2 , "OAuth2Claim" , claim ),
160
+ ngx_null_command };
175
161
176
162
static ngx_int_t ngx_oauth2_post_config (ngx_conf_t * cf );
177
163
@@ -241,199 +227,9 @@ static ngx_int_t ngx_oauth2_post_config(ngx_conf_t *cf)
241
227
return rv ;
242
228
}
243
229
244
- static ngx_int_t ngx_oauth2_claim_variable (ngx_http_request_t * r ,
245
- ngx_http_variable_value_t * v ,
246
- uintptr_t data )
247
- {
248
- ngx_oauth2_claims_hash_t * claims = NULL ;
249
- const char * value = NULL ;
250
-
251
- ngx_str_t key = {strlen ((const char * )data ), (u_char * )data };
252
-
253
- claims = (ngx_oauth2_claims_hash_t * )ngx_http_get_module_ctx (
254
- r , ngx_oauth2_module );
255
- if (!claims ) {
256
- v -> not_found = 1 ;
257
- return NGX_OK ;
258
- }
259
-
260
- value = (const char * )ngx_hash_find (
261
- & claims -> h , ngx_hash_key (key .data , key .len ), key .data , key .len );
262
- if (value ) {
263
- ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
264
- "ngx_oauth2_claim_variable: %V=%s" , & key , value );
265
- v -> data = (u_char * )value ;
266
- v -> len = strlen (value );
267
- v -> no_cacheable = 1 ;
268
- v -> not_found = 0 ;
269
- } else {
270
- ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , r -> connection -> log , 0 ,
271
- "ngx_oauth2_claim_variable: %V=(null)" , & key );
272
- v -> not_found = 1 ;
273
- }
274
-
275
- return NGX_OK ;
276
- }
277
-
278
- static char * ngx_oauth2_set_claim (ngx_conf_t * cf , ngx_command_t * cmd ,
279
- void * conf )
280
- {
281
- ngx_str_t * value ;
282
- ngx_http_variable_t * v ;
283
-
284
- value = cf -> args -> elts ;
285
-
286
- if (value [2 ].len <= 1 || value [2 ].data [0 ] != '$' ) {
287
- static const size_t MAX_BUF = 128 ;
288
- char buf [MAX_BUF ];
289
- int n = snprintf (buf , sizeof (buf ), "Invalid variable name %.*s" ,
290
- (int )value [2 ].len , value [2 ].data );
291
- ngx_str_t msg = {n , (u_char * )& buf [0 ]};
292
- char * s = ngx_str_to_chr (cf -> pool , & msg );
293
- return s ? s : NGX_CONF_ERROR ;
294
- }
295
-
296
- value [2 ].len -- ;
297
- value [2 ].data ++ ;
298
-
299
- v = ngx_http_add_variable (cf , & value [2 ], NGX_HTTP_VAR_CHANGEABLE );
300
- if (!v ) {
301
- ngx_str_t msg = ngx_string ("ngx_http_add_variable failed" );
302
- char * rv = ngx_str_to_chr (cf -> pool , & msg );
303
- return rv ? rv : NGX_CONF_ERROR ;
304
- }
305
-
306
- v -> get_handler = ngx_oauth2_claim_variable ;
307
- char * claim = ngx_str_to_chr (cf -> pool , & value [1 ]);
308
- if (!claim ) {
309
- ngx_str_t msg = ngx_string ("Out of memory" );
310
- char * rv = ngx_str_to_chr (cf -> pool , & msg );
311
- return rv ? rv : NGX_CONF_ERROR ;
312
- }
313
- v -> data = (uintptr_t )claim ;
314
-
315
- return NGX_CONF_OK ;
316
- }
317
-
318
- static ngx_int_t ngx_set_target_variable (ngx_oauth2_claims_hash_t * claims ,
319
- oauth2_nginx_request_context_t * ctx ,
320
- const char * k , const char * v )
321
- {
322
- ngx_str_t key = chr_to_ngx_str (claims -> keys .pool , k );
323
- if (!key .data )
324
- return NGX_ERROR ;
325
-
326
- const char * value = chr_to_chr (claims -> keys .pool , v );
327
- if (!value )
328
- return NGX_ERROR ;
329
-
330
- return ngx_hash_add_key (& claims -> keys , & key , (char * )value ,
331
- NGX_HASH_READONLY_KEY );
332
- }
333
-
334
- static ngx_int_t ngx_oauth2_init_keys (ngx_pool_t * pool ,
335
- ngx_oauth2_claims_hash_t * claims )
336
- {
337
- claims -> keys .pool = pool ;
338
- claims -> keys .temp_pool = pool ;
339
-
340
- return ngx_hash_keys_array_init (& claims -> keys , NGX_HASH_SMALL );
341
- }
342
-
343
- static ngx_int_t ngx_oauth2_init_hash (ngx_pool_t * pool ,
344
- ngx_oauth2_claims_hash_t * claims )
345
- {
346
- ngx_hash_init_t init ;
347
-
348
- init .hash = & claims -> h ;
349
- init .key = ngx_hash_key ;
350
- init .max_size = 64 ;
351
- init .bucket_size = ngx_align (64 , ngx_cacheline_size );
352
- init .name = "claims" ;
353
- init .pool = pool ;
354
- init .temp_pool = pool ;
355
-
356
- return ngx_hash_init (& init , claims -> keys .keys .elts ,
357
- claims -> keys .keys .nelts );
358
- }
359
-
360
- // TODO: generalize/callback part of this (at least the looping and encoding is
361
- // generic)
362
- static ngx_int_t ngx_set_target_variables (ngx_http_request_t * r ,
363
- oauth2_nginx_request_context_t * ctx ,
364
- json_t * json_token )
365
- {
366
- void * iter = NULL ;
367
- const char * key = NULL ;
368
- json_t * value = NULL ;
369
- ngx_oauth2_claims_hash_t * claims = NULL ;
370
- int rc = NGX_OK ;
371
-
372
- claims = (ngx_oauth2_claims_hash_t * )ngx_http_get_module_ctx (
373
- r , ngx_oauth2_module );
374
- if (!claims ) {
375
- claims = ngx_palloc (r -> pool , sizeof (* claims ));
376
- if (!claims ) {
377
- ngx_log_error (NGX_LOG_ERR , r -> connection -> log ,
378
- NGX_ENOMEM ,
379
- "ngx_set_target_variables: "
380
- "error allocating claims hash" );
381
- return NGX_ERROR ;
382
- }
383
-
384
- rc = ngx_oauth2_init_keys (r -> pool , claims );
385
- if (NGX_OK != rc ) {
386
- ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 ,
387
- "ngx_set_target_variables: error %d "
388
- "initializing hash keys" ,
389
- rc );
390
- return rc ;
391
- }
392
-
393
- ngx_http_set_ctx (r , claims , ngx_oauth2_module );
394
- }
395
-
396
- iter = json_object_iter (json_token );
397
- while (iter ) {
398
- key = json_object_iter_key (iter );
399
- value = json_object_iter_value (iter );
400
- if (json_is_string (value )) {
401
- rc = ngx_set_target_variable (claims , ctx , key ,
402
- json_string_value (value ));
403
- } else {
404
- const char * val = oauth2_json_encode (ctx -> log , value ,
405
- JSON_ENCODE_ANY );
406
- rc = ngx_set_target_variable (claims , ctx , key , val );
407
- oauth2_mem_free ((char * )val );
408
- }
409
-
410
- if (NGX_OK != rc ) {
411
- ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 ,
412
- "ngx_set_target_variables: error %d "
413
- "setting value of key %s in claims hash" ,
414
- rc , key );
415
- return rc ;
416
- }
417
-
418
- iter = json_object_iter_next (json_token , iter );
419
- }
420
-
421
- rc = ngx_oauth2_init_hash (r -> pool , claims );
422
- if (NGX_OK != rc ) {
423
- ngx_log_error (NGX_LOG_ERR , r -> connection -> log , 0 ,
424
- "ngx_set_target_variables: error %d initializing "
425
- "claims hash" ,
426
- rc );
427
- return rc ;
428
- }
429
-
430
- return NGX_OK ;
431
- }
432
-
433
230
static ngx_int_t ngx_oauth2_handler (ngx_http_request_t * r )
434
231
{
435
232
ngx_int_t rv = NGX_DECLINED ;
436
- // bool rc = false;
437
233
oauth2_nginx_request_context_t * ctx = NULL ;
438
234
ngx_oauth2_cfg_t * cfg = NULL ;
439
235
ngx_str_t ngx_source_token ;
@@ -466,9 +262,6 @@ static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r)
466
262
return NGX_ERROR ;
467
263
}
468
264
469
- // TODO: if we have a verify post config, call it here
470
- // ...
471
-
472
265
ngx_str_null (& ngx_source_token );
473
266
rv = ngx_http_complex_value (r , & cfg -> source_token , & ngx_source_token );
474
267
if (rv != NGX_OK ) {
@@ -503,7 +296,12 @@ static ngx_int_t ngx_oauth2_handler(ngx_http_request_t *r)
503
296
504
297
oauth2_debug (ctx -> log , "json_payload=%p" , json_payload );
505
298
506
- rv = ngx_set_target_variables (r , ctx , json_payload );
299
+ rv = oauth2_nginx_set_target_variables (ngx_oauth2_module , ctx ,
300
+ json_payload );
301
+ if (rv != NGX_OK )
302
+ goto end ;
303
+
304
+ rv = nginx_oauth2_check_requirements (ctx , cfg -> requirements );
507
305
508
306
end :
509
307
0 commit comments