Skip to content

Commit 444fa9c

Browse files
committed
Add first version of the enforcer.
Can only test for access, not including ACLs.
1 parent 95f8001 commit 444fa9c

File tree

5 files changed

+244
-27
lines changed

5 files changed

+244
-27
lines changed

CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@ target_link_libraries(SciTokens ${LIBCRYPTO_LIBRARIES} ${CURL_LIBRARIES} ${SQLIT
2929
set_target_properties(SciTokens PROPERTIES LINK_FLAGS "-Wl,--version-script=${PROJECT_SOURCE_DIR}/configs/export-symbols")
3030

3131
add_executable(scitokens-test src/test.cpp)
32-
target_link_libraries(scitokens-test SciTokens ${LIBCRYPTO_LIB})
32+
target_link_libraries(scitokens-test SciTokens)
3333

3434
add_executable(scitokens-verify src/verify.cpp)
35-
target_link_libraries(scitokens-verify SciTokens ${LIBCRYPTO_LIB})
35+
target_link_libraries(scitokens-verify SciTokens)
36+
37+
add_executable(scitokens-test-access src/test_access.cpp)
38+
target_link_libraries(scitokens-test-access SciTokens)
3639

3740
if (NOT DEFINED LIB_INSTALL_DIR)
3841
SET(LIB_INSTALL_DIR "lib")

src/scitokens.cpp

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ Validator validator_create() {
135135
return new Validator();
136136
}
137137

138-
int validator_add(Validator validator, const char *claim, ValidatorFunction validator_func, char **err_msg) {
138+
int validator_add(Validator validator, const char *claim, StringValidatorFunction validator_func, char **err_msg) {
139139
if (validator == nullptr) {
140140
if (err_msg) {*err_msg = strdup("Validator may not be a null pointer");}
141141
return -1;
@@ -172,21 +172,82 @@ int validator_add_critical_claims(Validator validator, const char **claims, char
172172
}
173173

174174

175-
int validator_validate(Validator validator, SciToken scitoken, char **err_msg);
175+
int validator_validate(Validator validator, SciToken scitoken, char **err_msg) {
176+
if (validator == nullptr) {
177+
if (err_msg) {*err_msg = strdup("Validator may not be a null pointer");}
178+
return -1;
179+
}
180+
auto real_validator = reinterpret_cast<scitokens::Validator*>(validator);
181+
if (scitoken == nullptr) {
182+
if (err_msg) {*err_msg = strdup("SciToken may not be a null pointer");}
183+
return -1;
184+
}
185+
auto real_scitoken = reinterpret_cast<scitokens::SciToken*>(scitoken);
186+
187+
try {
188+
real_validator->verify(*real_scitoken);
189+
} catch (std::exception exc) {
190+
if (err_msg) {*err_msg = strdup(exc.what());}
191+
return -1;
192+
}
193+
return 0;
194+
}
176195

177196

178-
Enforcer enforcer(const char *issuer, const char **audience) {
179-
return nullptr;
197+
Enforcer enforcer_create(const char *issuer, const char **audience_list, char **err_msg) {
198+
if (issuer == nullptr) {
199+
if (err_msg) {*err_msg = strdup("Issuer may not be a null pointer");}
200+
return nullptr;
201+
}
202+
std::vector<std::string> aud_list;
203+
if (audience_list != nullptr) {
204+
for (int idx=0; audience_list[idx]; idx++) {
205+
aud_list.push_back(audience_list[idx]);
206+
}
207+
}
208+
209+
return new scitokens::Enforcer(issuer, aud_list);
180210
}
181211

212+
213+
void enforcer_destroy(Enforcer enf) {
214+
if (enf == nullptr) {
215+
return;
216+
}
217+
auto real_enf = reinterpret_cast<scitokens::Enforcer*>(enf);
218+
delete real_enf;
219+
}
220+
221+
182222
int enforcer_generate_acls(const Enforcer enf, const SciToken sci, char **Acl, char **err_msg) {
183223
if (err_msg) {
184224
*err_msg = strdup("This function is not implemented");
185225
}
186226
return -1;
187227
}
188228

189-
int enforcer_test(const Enforcer enf, const SciToken sci, const Acl *acl) {
190-
return -1;
191-
}
192229

230+
int enforcer_test(const Enforcer enf, const SciToken scitoken, const Acl *acl, char **err_msg) {
231+
if (enf == nullptr) {
232+
if (err_msg) {*err_msg = strdup("Enforcer may not be a null pointer");}
233+
return -1;
234+
}
235+
auto real_enf = reinterpret_cast<scitokens::Enforcer*>(enf);
236+
if (scitoken == nullptr) {
237+
if (err_msg) {*err_msg = strdup("SciToken may not be a null pointer");}
238+
return -1;
239+
}
240+
auto real_scitoken = reinterpret_cast<scitokens::SciToken*>(scitoken);
241+
if (acl == nullptr) {
242+
if (err_msg) {*err_msg = strdup("ACL may not be a null pointer");}
243+
return -1;
244+
}
245+
246+
try {
247+
return real_enf->test(*real_scitoken, acl->authz, acl->resource) == true ? 0 : -1;
248+
} catch (std::exception exc) {
249+
if (err_msg) {*err_msg = strdup(exc.what());}
250+
return -1;
251+
}
252+
return 0;
253+
}

src/scitokens.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ typedef void * SciToken;
1313
typedef void * Validator;
1414
typedef void * Enforcer;
1515

16-
typedef int (*ValidatorFunction)(const char *value, char **err_msg);
16+
typedef int (*StringValidatorFunction)(const char *value, char **err_msg);
1717
typedef struct Acl_s {
18-
char *authz;
19-
char *resource;
18+
const char *authz;
19+
const char *resource;
2020
}
2121
Acl;
2222

@@ -40,17 +40,19 @@ int scitoken_deserialize(const char *value, SciToken *token, char **allowed_issu
4040

4141
Validator validator_create();
4242

43-
int validator_add(Validator validator, const char *claim, ValidatorFunction validator_func, char **err_msg);
43+
int validator_add(Validator validator, const char *claim, StringValidatorFunction validator_func, char **err_msg);
4444

4545
int validator_add_critical_claims(Validator validator, const char **claims, char **err_msg);
4646

4747
int validator_validate(Validator validator, SciToken scitoken, char **err_msg);
4848

49-
Enforcer enforcer(const char *issuer, const char **audience);
49+
Enforcer enforcer_create(const char *issuer, const char **audience, char **err_msg);
50+
51+
void enforcer_destroy(Enforcer);
5052

5153
int enforcer_generate_acls(const Enforcer enf, const SciToken sci, char **Acl, char **err_msg);
5254

53-
int enforcer_test(const Enforcer enf, const SciToken sci, const Acl *acl);
55+
int enforcer_test(const Enforcer enf, const SciToken sci, const Acl *acl, char **err_msg);
5456

5557
#ifdef __cplusplus
5658
}

src/scitokens_internal.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,3 +437,41 @@ Validator::get_public_key_pem(const std::string &issuer, const std::string &kid,
437437
algorithm = alg;
438438
}
439439

440+
441+
bool
442+
scitokens::Enforcer::scope_validator(const jwt::claim &claim, void *myself) {
443+
auto me = reinterpret_cast<scitokens::Enforcer*>(myself);
444+
if (claim.get_type() != jwt::claim::type::string) {
445+
return false;
446+
}
447+
std::string scope = claim.as_string();
448+
std::string requested_path = normalize_absolute_path(me->m_test_path);
449+
auto scope_iter = scope.begin();
450+
//std::cout << "Comparing scope " << scope << " against test accesses " << me->m_test_authz << ":" << requested_path << std::endl;
451+
while (scope_iter != scope.end()) {
452+
while (*scope_iter == ' ') {scope_iter++;}
453+
auto next_scope_iter = std::find(scope_iter, scope.end(), ' ');
454+
std::string full_authz;
455+
full_authz.reserve(std::distance(scope_iter, next_scope_iter));
456+
full_authz.assign(scope_iter, next_scope_iter);
457+
auto sep_iter = full_authz.find(':');
458+
std::string authz = full_authz.substr(0, sep_iter);
459+
std::string path;
460+
if (sep_iter == std::string::npos) {
461+
path = "/";
462+
} else {
463+
path = full_authz.substr((++sep_iter));
464+
}
465+
path = normalize_absolute_path(path);
466+
467+
if (me->m_test_authz.empty()) {
468+
return false; // TODO: implement ACL generation.
469+
} else if ((me->m_test_authz == authz) &&
470+
(requested_path.substr(0, path.size()) == path)) {
471+
return true;
472+
}
473+
474+
scope_iter = next_scope_iter;
475+
}
476+
return false;
477+
}

0 commit comments

Comments
 (0)