8
8
#include "apr_strings.h"
9
9
#include "apr_time.h"
10
10
11
- #include <scitokens-cpp/src /scitokens.h>
11
+ #include <scitokens/scitokens.h>
12
12
13
13
#include <unistd.h>
14
14
15
15
#include "mod_auth.h"
16
16
17
17
/* ~~~~~~~~~~~~~~~~~~~~~~~~~ CONFIGURATION STRUCTURE ~~~~~~~~~~~~~~~~~~~~~~~~~ */
18
18
19
+ #define MAX_AUD 20
19
20
typedef struct {
20
- char * * issuers ;
21
- char * * resources ;
22
- int numberofissuer ;
21
+ char * * issuers ;
22
+ char * * resources ;
23
+ int numberofissuer ;
24
+ int enforcing_flag ;
25
+ char audience_buf [255 ];
26
+ char * aud_list [MAX_AUD + 1 ];
23
27
} authz_scitoken_config_rec ;
24
28
25
29
/* ~~~~~~~~~~~~~~~~~~~~~~~~~ DEFAULT CONFIGURATION ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -28,10 +32,12 @@ static void *create_authz_scitoken_dir_config(apr_pool_t *p, char *d)
28
32
{
29
33
authz_scitoken_config_rec * conf = apr_palloc (p , sizeof (* conf ));
30
34
35
+ /* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "scitoken: new config allocation"); */
31
36
char * * issuers = calloc (1 , sizeof (char * ));
32
37
char * * resources = calloc (1 , sizeof (char * ));
33
38
* (issuers ) = "issuer" ;
34
39
* (resources ) = "resources" ;
40
+ conf -> audience_buf [0 ] = 0 ;
35
41
conf -> numberofissuer = 1 ;
36
42
conf -> issuers = issuers ;
37
43
conf -> resources = resources ;
@@ -41,12 +47,16 @@ static void *create_authz_scitoken_dir_config(apr_pool_t *p, char *d)
41
47
//The default is to overwrite the old config, NOT merging
42
48
static void * merge_auth_scitoken_dir_config (apr_pool_t * p , void * basev , void * new_confv )
43
49
{
50
+ /* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "scitoken: merging...");*/
44
51
authz_scitoken_config_rec * newconf = apr_pcalloc (p , sizeof (* newconf ));
45
52
authz_scitoken_config_rec * base = basev ;
46
53
authz_scitoken_config_rec * new_conf = new_confv ;
54
+ memcpy (newconf , new_conf , sizeof (authz_scitoken_config_rec ));
47
55
newconf -> numberofissuer = new_conf -> numberofissuer ? new_conf -> numberofissuer : base -> numberofissuer ;
48
56
newconf -> issuers = new_conf -> issuers ? new_conf -> issuers : base -> issuers ;
49
57
newconf -> resources = new_conf -> resources ? new_conf -> resources : base -> resources ;
58
+ newconf -> enforcing_flag = new_conf -> enforcing_flag ;
59
+ return newconf ;
50
60
}
51
61
52
62
/**
@@ -57,6 +67,7 @@ static void *merge_auth_scitoken_dir_config(apr_pool_t *p, void *basev, void *ne
57
67
*/
58
68
static const char * set_scitoken_param_iss (cmd_parms * cmd , void * config , const char * issuersstr )
59
69
{
70
+ /* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "scitoken: issuer %s" , issuersstr); */
60
71
authz_scitoken_config_rec * conf = (authz_scitoken_config_rec * )config ;
61
72
char * token = strtok ((char * )issuersstr , "," );
62
73
char * res ;
@@ -93,6 +104,47 @@ static const char *set_scitoken_param_iss(cmd_parms *cmd, void *config, const ch
93
104
*/
94
105
static const char * set_scitoken_param_exp (cmd_parms * cmd , void * config , const char * issuersstr )
95
106
{
107
+ /* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "scitoken: exp %s" , issuersstr); */
108
+ return NULL ;
109
+ }
110
+
111
+
112
+ static const char * set_scitoken_param_audience (cmd_parms * cmd , void * config , const char * aud )
113
+ {
114
+ authz_scitoken_config_rec * conf = config ;
115
+ int k = 1 ;
116
+ char * pc = conf -> audience_buf + 1 ;
117
+
118
+ /* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "scitoken audience: %s", aud); */
119
+ strncpy (conf -> audience_buf , aud , 255 );
120
+
121
+ conf -> aud_list [0 ] = conf -> audience_buf ;
122
+ conf -> aud_list [1 ] = NULL ;
123
+ while (* pc && k < MAX_AUD ) {
124
+ if (* pc == ',' ) {
125
+ * pc = 0 ;
126
+ conf -> aud_list [k ++ ] = ++ pc ;
127
+ conf -> aud_list [k ] = 0 ;
128
+ } else {
129
+ pc ++ ;
130
+ }
131
+ }
132
+ /* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "Done splitting audience"); */
133
+ return NULL ;
134
+ }
135
+
136
+ static const char * set_scitoken_param_enforcing (cmd_parms * cmd , void * config , const char * flag )
137
+ {
138
+ /* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "scitoken enforcing: %s", flag); */
139
+ authz_scitoken_config_rec * conf = config ;
140
+
141
+ /* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "Setting enforcing: flag: %s", flag); */
142
+
143
+ if (flag [0 ] == 'f' || flag [0 ] == 'F' || flag [0 ] == 'n' || flag [0 ] == 'N' || flag [0 ] == '0' ) {
144
+ conf -> enforcing_flag = 0 ;
145
+ } else {
146
+ conf -> enforcing_flag = 1 ;
147
+ }
96
148
return NULL ;
97
149
}
98
150
/**
@@ -110,6 +162,8 @@ static const command_rec authz_scitoken_cmds[] =
110
162
AP_INIT_TAKE1 ("issuers" , set_scitoken_param_iss , NULL , OR_AUTHCFG , "list of issuers" ),
111
163
AP_INIT_TAKE1 ("exp" , set_scitoken_param_exp , NULL , OR_AUTHCFG , "Enable exp time validation" ),
112
164
AP_INIT_TAKE1 ("alg" , set_scitoken_param_alg , NULL , OR_AUTHCFG , "Enable algorithm validation" ),
165
+ AP_INIT_TAKE1 ("enforcing" , set_scitoken_param_enforcing , NULL , OR_AUTHCFG , "Enable/disable enforcer, default on" ),
166
+ AP_INIT_TAKE1 ("audience" , set_scitoken_param_audience , NULL , OR_AUTHCFG , "set audience" ),
113
167
{NULL }
114
168
};
115
169
@@ -121,17 +175,22 @@ module AP_MODULE_DECLARE_DATA auth_scitoken_module;
121
175
/**
122
176
* The main function to verify a Scitoken
123
177
*/
124
- int ScitokenVerify (request_rec * r , const char * require_line , const void * parsed_require_line ) {
178
+ authz_status ScitokenVerify (request_rec * r , const char * require_line , const void * parsed_require_line ) {
125
179
SciToken scitoken ;
126
180
char * err_msg ;
127
181
const char * auth_line , * auth_scheme ;
128
- const char * listofauthz = "COPY:write DELETE:write GET:read HEAD:read LOCK:write MKCOL:write MOVE:write OPTIONS:read POST:read PROPFIND:write PROPPATCH:write PUT:write TRACE:read UNLOCK:write" ;
182
+ const char * listofauthz = "COPY:write DELETE:write GET:read HEAD:read LOCK:write MKCOL:write MOVE:write OPTIONS:read POST:read PROPFIND:write PROPPATCH:write PUT:write TRACE:read UNLOCK:write" ;
129
183
// Read scitoken into memory
184
+
185
+ /* ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "starting token auth:"); */
186
+
130
187
auth_line = apr_table_get (r -> headers_in ,"Authorization" );
131
188
if (auth_line == NULL ){
132
189
ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Unauthorized." );
133
190
return AUTHZ_DENIED ;
134
191
}
192
+ /* ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Found authorization header"); */
193
+
135
194
auth_scheme = ap_getword (r -> pool , & auth_line , ' ' );
136
195
137
196
// Read configuration
@@ -146,10 +205,12 @@ int ScitokenVerify(request_rec *r, const char *require_line, const void *parsed_
146
205
}
147
206
null_ended_list [numberofissuer ] = NULL ;
148
207
208
+
149
209
if (strcasecmp (auth_scheme , "Bearer" )){
150
210
ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Wrong scheme" );
151
211
return AUTHZ_DENIED ;
152
212
}
213
+ /* ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Checked scheme.."); */
153
214
154
215
while (apr_isspace (* auth_line )) {
155
216
auth_line ++ ;
@@ -159,89 +220,137 @@ int ScitokenVerify(request_rec *r, const char *require_line, const void *parsed_
159
220
return AUTHZ_DENIED ;
160
221
}
161
222
162
- if (scitoken_deserialize (auth_line , & scitoken , null_ended_list , & err_msg )){
223
+ if (scitoken_deserialize (auth_line , & scitoken , ( char const * const * ) null_ended_list , & err_msg )){
163
224
ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Failed to deserialize scitoken" );
164
225
ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , err_msg , r -> uri );
165
226
return AUTHZ_DENIED ;
166
227
}
167
228
168
- char * issuer_ptr = NULL ;
229
+ int i ;
230
+ /* int k; */
231
+ char * issuer_ptr = NULL ;
232
+ char * sub_ptr = NULL ;
233
+ char * aud_ptr = NULL ;
234
+ char * scope_ptr = NULL ;
235
+ char * wlcg_groups_ptr = NULL ;
236
+ if (!scitoken_get_claim_string (scitoken , "sub" , & sub_ptr , & err_msg )) {
237
+ apr_table_set (r -> subprocess_env , "SCITOKEN_SUB" , sub_ptr );
238
+ }
239
+ if (!scitoken_get_claim_string (scitoken , "aud" , & aud_ptr , & err_msg )) {
240
+ apr_table_set (r -> subprocess_env , "SCITOKEN_AUD" , aud_ptr );
241
+ }
242
+ if (!scitoken_get_claim_string (scitoken , "scope" , & scope_ptr , & err_msg )) {
243
+ apr_table_set (r -> subprocess_env , "SCITOKEN_SCOPE" , scope_ptr );
244
+ }
245
+ if (!scitoken_get_claim_string (scitoken , "wlcg.groups" , & wlcg_groups_ptr , & err_msg )) {
246
+ apr_table_set (r -> subprocess_env , "SCITOKEN_WLCG_GROUPS" , wlcg_groups_ptr );
247
+ }
169
248
if (scitoken_get_claim_string (scitoken , "iss" , & issuer_ptr , & err_msg )) {
170
249
ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Failed to get issuer from token: %s\n" ,err_msg );
171
250
ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , err_msg , r -> uri );
172
251
return AUTHZ_DENIED ;
173
252
}
253
+ apr_table_set (r -> subprocess_env , "SCITOKEN_ISS" , issuer_ptr );
174
254
175
255
//Preparing for enforcer test
176
256
Enforcer enf ;
177
-
257
+
178
258
char hostname [1024 ];
179
- const char * aud_list [2 ];
180
-
181
- // Get the hostname for the audience. It is using hostname(NOT domain name). Set payload accordingly
182
- if (gethostname (hostname , 1024 ) != 0 ) {
183
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Failed to get hostname" );
184
- return AUTHZ_DENIED ;
185
- }
186
- aud_list [0 ] = hostname ;
187
- aud_list [1 ] = NULL ;
259
+ char * host_aud_list [2 ];
260
+ const char * * aud_list ;
188
261
189
- if (!(enf = enforcer_create (issuer_ptr , aud_list , & err_msg ))) {
190
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Failed to create enforcer" );
191
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" , err_msg );
192
- return AUTHZ_DENIED ;
193
- }
194
262
195
- Acl acl ;
196
- acl .authz = "" ;
197
- acl .resource = "" ;
198
- //retrieve request type => acl.authz = read/write
199
- char * requesttype = r -> method ;
200
- char * authzsubstr = strstr (listofauthz ,requesttype );
201
- if (authzsubstr == NULL ){
202
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Request type not supported(acl.authz)" );
203
- return AUTHZ_DENIED ;
204
- }
205
- //get the requestype:read/write substring
206
- char * substr = (char * )calloc (1 , strchr (authzsubstr ,' ' ) - authzsubstr + 1 );
207
- memcpy (substr ,authzsubstr ,strchr (authzsubstr ,' ' ) - authzsubstr );
208
- strtok (substr ,":" );
209
- acl .authz = strtok (NULL ,":" );
210
- //Resource is found/not found for the audience
211
- int found = 0 ;
212
- for (int i = 0 ; i < conf -> numberofissuer ; i ++ ){
213
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" ,issuer_ptr );
214
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" ,* (conf -> issuers + i ));
215
- if (* (issuer_ptr ) == * * (conf -> issuers + i ))
216
- {
217
- acl .resource = * (conf -> resources + i );
218
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" ,* (conf -> resources + i ));
219
- found = 1 ;
220
- break ;
263
+ /* ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Audience buf: %s" , conf->audience_buf); */
264
+ if ( conf -> audience_buf [0 ] ) {
265
+ /* k = 1; */
266
+ aud_list = (const char * * )conf -> aud_list ;
267
+ for (i = 0 ; i < MAX_AUD ; i ++ ) {
268
+ if (aud_list [i ] == 0 ) {
269
+ /* k = i; */
270
+ break ;
271
+ }
221
272
}
273
+ } else {
274
+ aud_list = (const char * * )host_aud_list ;
275
+ // Get the hostname for the audience. It is using hostname(NOT domain name). Set payload accordingly
276
+ if (gethostname (hostname , 1024 ) != 0 ) {
277
+ ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Failed to get hostname" );
278
+ return AUTHZ_DENIED ;
279
+ }
280
+ aud_list [0 ] = hostname ;
281
+ aud_list [1 ] = NULL ;
282
+ /* k = 1; */
222
283
}
223
- if (!found ){
224
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Resource not found" );
225
- return AUTHZ_DENIED ;
226
- }
227
-
284
+ /*
285
+ * ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Using audience:");
286
+ * for(i = 0; i < k ; i++) {
287
+ * ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "%d: %s" , i, aud_list[i]);
288
+ * }
289
+ */
228
290
229
- if (enforcer_test (enf , scitoken , & acl , & err_msg )) {
230
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Failed enforcer test" );
231
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" , err_msg );
232
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" , hostname );
233
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" , null_ended_list [0 ]);
234
- return AUTHZ_DENIED ;
291
+ if (conf -> enforcing_flag ) {
292
+ /* ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "enforcing_flag on.."); */
293
+
294
+ if (!(enf = enforcer_create (issuer_ptr , aud_list , & err_msg ))) {
295
+ ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Failed to create enforcer: %s" , err_msg );
296
+ return AUTHZ_DENIED ;
297
+ }
298
+
299
+ Acl acl ;
300
+ acl .authz = "" ;
301
+ acl .resource = "" ;
302
+ //retrieve request type => acl.authz = read/write
303
+ const char * requesttype = r -> method ;
304
+ char * authzsubstr = strstr (listofauthz ,requesttype );
305
+ if (authzsubstr == NULL ){
306
+ ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Request type not supported(acl.authz)" );
307
+ return AUTHZ_DENIED ;
308
+ }
309
+ //get the requestype:read/write substring
310
+ char * substr = (char * )calloc (1 , strchr (authzsubstr ,' ' ) - authzsubstr + 1 );
311
+ memcpy (substr ,authzsubstr ,strchr (authzsubstr ,' ' ) - authzsubstr );
312
+ strtok (substr ,":" );
313
+ acl .authz = strtok (NULL ,":" );
314
+ //Resource is found/not found for the audience
315
+ int found = 0 ;
316
+ for (int i = 0 ; i < conf -> numberofissuer ; i ++ ){
317
+ ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" ,issuer_ptr );
318
+ ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" ,* (conf -> issuers + i ));
319
+ if (* (issuer_ptr ) == * * (conf -> issuers + i ))
320
+ {
321
+ acl .resource = * (conf -> resources + i );
322
+ ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "%s" ,* (conf -> resources + i ));
323
+ found = 1 ;
324
+ break ;
325
+ }
326
+ }
327
+ if (!found ){
328
+ ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Resource not found" );
329
+ return AUTHZ_DENIED ;
330
+ }
331
+
332
+ if ( enforcer_test (enf , scitoken , & acl , & err_msg )) {
333
+ ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "Failed enforcer test: %s" , err_msg );
334
+ enforcer_destroy (enf );
335
+ return AUTHZ_DENIED ;
336
+ } else {
337
+ ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , "enforcer_tested.." );
338
+ enforcer_destroy (enf );
339
+ }
340
+
341
+ /* } else {
342
+ * ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "enforcing_flag off..");
343
+ */
235
344
}
236
-
345
+
237
346
// +1 for the null-terminator
238
- char * str = malloc ( strlen ("token" ) + strlen (auth_line ) + 1 );
239
- strcpy (str , "token" );
347
+ char * str = apr_palloc ( r -> pool , strlen ("token: " ) + strlen (auth_line ) + 1 );
348
+ strcpy (str , "token: " );
240
349
strcat (str , auth_line );
241
350
242
351
// log the access
243
- ap_log_rerror (APLOG_MARK , APLOG_INFO , 0 , r , str , r -> uri );
244
- free ( str );
352
+ /* ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, str, r->uri); */
353
+
245
354
return AUTHZ_GRANTED ;
246
355
247
356
}
@@ -269,8 +378,8 @@ AP_DECLARE_MODULE(auth_scitoken) =
269
378
STANDARD20_MODULE_STUFF ,
270
379
create_authz_scitoken_dir_config , /* dir config creater */
271
380
merge_auth_scitoken_dir_config , /* dir merger(overwrite) */
272
- NULL , /* server config */
273
- NULL , /* merge server config */
381
+ create_authz_scitoken_dir_config , /* server config */
382
+ merge_auth_scitoken_dir_config , /* merge server config */
274
383
authz_scitoken_cmds , /* command apr_table_t */
275
384
register_hooks /* register hooks */
276
385
};
0 commit comments