-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathscitoken_helper_check.cc
144 lines (122 loc) · 3.98 KB
/
scitoken_helper_check.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/**
* This file is part of the CernVM File System.
*/
#include "scitoken_helper_check.h"
#include "x509_helper_log.h"
#include <scitokens/scitokens.h>
#include <sys/types.h>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <vector>
#include <sstream>
#include <string>
#include <map>
#include <memory>
#include <unistd.h>
#include "helper_utils.h"
using namespace std; // NOLINT
__attribute__ ((visibility ("default")))
StatusSciTokenValidation CheckSciToken(const char* membership, FILE *fp_token, FILE *fp_debug) {
SetLogAuthzDebugFile(fp_debug);
SciToken scitoken;
// Read in the entire scitoken into memory
string token;
GetStringFromFile(fp_token, token);
if (token == "") {
return kCheckTokenInvalid;
}
// Loop through the membership, looking for "https://" issuers
map<string, string> issuers;
vector<string> issuers_vec;
std::istringstream iss(membership);
string prefix("https://");
// Look for issuers
for (std::string line; std::getline(iss, line); ) {
if (!line.compare(0, prefix.size(), prefix)) {
// Check for the ";" delimiter
std::size_t found = line.find(";");
string issuer;
string scope("/");
if (found != std::string::npos) {
issuer = line.substr(0, found);
scope = line.substr(found + 1, line.length() + 1);
} else {
issuer = line;
}
issuers[issuer] = scope;
issuers_vec.push_back(issuer);
}
}
// Convert the vector into a null ended list of strings
char** null_ended_list = new char*[issuers_vec.size()+1];
for(std::vector<string>::size_type i = 0; i != issuers_vec.size(); i++) {
char* tmp_char = strdup(issuers_vec[i].c_str());
null_ended_list[i] = tmp_char;
}
null_ended_list[issuers_vec.size()] = NULL;
// Remove the trailing new line from the token, if there is one
if (token[token.size()-1] == '\n') {
token.erase(token.size()-1);
}
char *err_msg = NULL;
if (scitoken_deserialize(token.c_str(), &scitoken, null_ended_list, &err_msg)) {
LogAuthz(kLogAuthzDebug, "Failed to deserialize scitoken: %s", err_msg);
// Loop through and delete the issuers
for (std::vector<string>::size_type i = 0; i < issuers_vec.size(); i++) {
delete null_ended_list[i];
}
delete [] null_ended_list;
return kCheckTokenInvalid;
}
// Get the subject
char* subject_ptr = NULL;
if(scitoken_get_claim_string(scitoken, "sub", &subject_ptr, &err_msg)) {
LogAuthz(kLogAuthzDebug, "Failed to get subject from token: %s\n", err_msg);
scitoken_destroy(scitoken);
return kCheckTokenInvalid;
}
LogAuthz(kLogAuthzDebug, "Checking token sub %s", subject_ptr);
delete subject_ptr;
for (std::vector<string>::size_type i = 0; i < issuers_vec.size(); i++) {
delete null_ended_list[i];
}
delete [] null_ended_list;
// Get the issuer
char* issuer_ptr = NULL;
if(scitoken_get_claim_string(scitoken, "iss", &issuer_ptr, &err_msg)) {
LogAuthz(kLogAuthzDebug, "Failed to get issuer from token: %s\n", err_msg);
scitoken_destroy(scitoken);
return kCheckTokenInvalid;
}
string issuer(issuer_ptr);
delete issuer_ptr;
// Check for the appropriate scope
Enforcer enf;
const char* aud_list[2];
// Get the hostname for the audience
char hostname[1024];
if (gethostname(hostname, 1024) != 0) {
LogAuthz(kLogAuthzDebug, "Failed to get hostname");
}
aud_list[0] = hostname;
aud_list[1] = NULL;
if (!(enf = enforcer_create(issuer.c_str(), aud_list, &err_msg))) {
LogAuthz(kLogAuthzDebug, "Failed to create enforcer");
scitoken_destroy(scitoken);
return kCheckTokenInvalid;
}
Acl acl;
acl.authz = "read";
acl.resource = issuers[issuer].c_str();
// Set the scope appropriately
if (enforcer_test(enf, scitoken, &acl, &err_msg)) {
LogAuthz(kLogAuthzDebug, "Failed enforcer test: %s\n", err_msg);
enforcer_destroy(enf);
scitoken_destroy(scitoken);
return kCheckTokenInvalid;
}
scitoken_destroy(scitoken);
enforcer_destroy(enf);
return kCheckTokenGood;
}