Skip to content

Commit a4fd41e

Browse files
authored
Merge pull request #6 from marcmengel/master
Updates to apache module
2 parents 6c38174 + 66fc3cd commit a4fd41e

File tree

1 file changed

+176
-67
lines changed

1 file changed

+176
-67
lines changed

src/scitoken.c

Lines changed: 176 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,22 @@
88
#include "apr_strings.h"
99
#include "apr_time.h"
1010

11-
#include <scitokens-cpp/src/scitokens.h>
11+
#include <scitokens/scitokens.h>
1212

1313
#include <unistd.h>
1414

1515
#include "mod_auth.h"
1616

1717
/* ~~~~~~~~~~~~~~~~~~~~~~~~~ CONFIGURATION STRUCTURE ~~~~~~~~~~~~~~~~~~~~~~~~~ */
1818

19+
#define MAX_AUD 20
1920
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];
2327
} authz_scitoken_config_rec;
2428

2529
/* ~~~~~~~~~~~~~~~~~~~~~~~~~ DEFAULT CONFIGURATION ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -28,10 +32,12 @@ static void *create_authz_scitoken_dir_config(apr_pool_t *p, char *d)
2832
{
2933
authz_scitoken_config_rec *conf = apr_palloc(p, sizeof(*conf));
3034

35+
/* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "scitoken: new config allocation"); */
3136
char** issuers = calloc(1, sizeof(char*));
3237
char**resources = calloc(1, sizeof(char*));
3338
*(issuers) = "issuer";
3439
*(resources) = "resources";
40+
conf->audience_buf[0] = 0;
3541
conf->numberofissuer = 1;
3642
conf->issuers = issuers;
3743
conf->resources = resources;
@@ -41,12 +47,16 @@ static void *create_authz_scitoken_dir_config(apr_pool_t *p, char *d)
4147
//The default is to overwrite the old config, NOT merging
4248
static void *merge_auth_scitoken_dir_config(apr_pool_t *p, void *basev, void *new_confv)
4349
{
50+
/* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "scitoken: merging...");*/
4451
authz_scitoken_config_rec *newconf = apr_pcalloc(p, sizeof(*newconf));
4552
authz_scitoken_config_rec *base = basev;
4653
authz_scitoken_config_rec *new_conf = new_confv;
54+
memcpy(newconf, new_conf, sizeof(authz_scitoken_config_rec));
4755
newconf->numberofissuer = new_conf->numberofissuer ? new_conf->numberofissuer : base->numberofissuer;
4856
newconf->issuers = new_conf->issuers ? new_conf->issuers : base->issuers;
4957
newconf->resources = new_conf->resources ? new_conf->resources : base->resources;
58+
newconf->enforcing_flag = new_conf->enforcing_flag;
59+
return newconf;
5060
}
5161

5262
/**
@@ -57,6 +67,7 @@ static void *merge_auth_scitoken_dir_config(apr_pool_t *p, void *basev, void *ne
5767
*/
5868
static const char *set_scitoken_param_iss(cmd_parms *cmd, void *config, const char *issuersstr)
5969
{
70+
/* ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "scitoken: issuer %s" , issuersstr); */
6071
authz_scitoken_config_rec *conf = (authz_scitoken_config_rec *)config;
6172
char *token = strtok((char *)issuersstr, ",");
6273
char *res;
@@ -93,6 +104,47 @@ static const char *set_scitoken_param_iss(cmd_parms *cmd, void *config, const ch
93104
*/
94105
static const char *set_scitoken_param_exp(cmd_parms *cmd, void *config, const char *issuersstr)
95106
{
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+
}
96148
return NULL;
97149
}
98150
/**
@@ -110,6 +162,8 @@ static const command_rec authz_scitoken_cmds[] =
110162
AP_INIT_TAKE1("issuers", set_scitoken_param_iss, NULL, OR_AUTHCFG, "list of issuers"),
111163
AP_INIT_TAKE1("exp", set_scitoken_param_exp, NULL, OR_AUTHCFG, "Enable exp time validation"),
112164
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"),
113167
{NULL}
114168
};
115169

@@ -121,17 +175,22 @@ module AP_MODULE_DECLARE_DATA auth_scitoken_module;
121175
/**
122176
* The main function to verify a Scitoken
123177
*/
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) {
125179
SciToken scitoken;
126180
char *err_msg;
127181
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";
129183
// Read scitoken into memory
184+
185+
/* ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "starting token auth:"); */
186+
130187
auth_line = apr_table_get(r->headers_in,"Authorization");
131188
if(auth_line == NULL){
132189
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Unauthorized.");
133190
return AUTHZ_DENIED;
134191
}
192+
/* ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Found authorization header"); */
193+
135194
auth_scheme = ap_getword(r->pool, &auth_line, ' ');
136195

137196
// Read configuration
@@ -146,10 +205,12 @@ int ScitokenVerify(request_rec *r, const char *require_line, const void *parsed_
146205
}
147206
null_ended_list[numberofissuer] = NULL;
148207

208+
149209
if (strcasecmp(auth_scheme, "Bearer")){
150210
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Wrong scheme");
151211
return AUTHZ_DENIED;
152212
}
213+
/* ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Checked scheme.."); */
153214

154215
while (apr_isspace(*auth_line)) {
155216
auth_line++;
@@ -159,89 +220,137 @@ int ScitokenVerify(request_rec *r, const char *require_line, const void *parsed_
159220
return AUTHZ_DENIED;
160221
}
161222

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)){
163224
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Failed to deserialize scitoken");
164225
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, err_msg, r->uri);
165226
return AUTHZ_DENIED;
166227
}
167228

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+
}
169248
if(scitoken_get_claim_string(scitoken, "iss", &issuer_ptr, &err_msg)) {
170249
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Failed to get issuer from token: %s\n",err_msg);
171250
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, err_msg, r->uri);
172251
return AUTHZ_DENIED;
173252
}
253+
apr_table_set(r->subprocess_env, "SCITOKEN_ISS", issuer_ptr);
174254

175255
//Preparing for enforcer test
176256
Enforcer enf;
177-
257+
178258
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;
188261

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-
}
194262

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+
}
221272
}
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; */
222283
}
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+
*/
228290

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+
*/
235344
}
236-
345+
237346
// +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:");
240349
strcat(str, auth_line);
241350

242351
// 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+
245354
return AUTHZ_GRANTED;
246355

247356
}
@@ -269,8 +378,8 @@ AP_DECLARE_MODULE(auth_scitoken) =
269378
STANDARD20_MODULE_STUFF,
270379
create_authz_scitoken_dir_config, /* dir config creater */
271380
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 */
274383
authz_scitoken_cmds, /* command apr_table_t */
275384
register_hooks /* register hooks */
276385
};

0 commit comments

Comments
 (0)