5 #define __STDC_FORMAT_MACROS
39 const string &progname,
40 const string &search_path,
44 , search_path_(search_path)
72 int retval = pthread_mutex_destroy(&
lock_);
78 Send(
string(
"{\"cvmfs_authz_v1\":{") +
101 retval = waitpid(
pid_, &statloc, WNOHANG);
104 "authz helper %s unresponsive, killing",
progname_.c_str());
105 retval = kill(
pid_, SIGKILL);
108 (void) waitpid(
pid_, &statloc, 0);
111 (void) waitpid(
pid_, &statloc, WNOHANG);
115 }
while (retval == 0);
123 "authz helper %s enters fail state, no more authorization",
147 char *argv[] = {argv0, NULL};
149 const bool strip_prefix =
true;
150 vector<string> authz_env =
153 for (
unsigned i = 0; i < authz_env.size(); ++i)
154 envp.push_back(
strdupa(authz_env[i].c_str()));
155 envp.push_back(
strdupa(
"CVMFS_AUTHZ_HELPER=yes"));
156 envp.push_back(NULL);
159 int max_fd = sysconf(_SC_OPEN_MAX);
162 std::vector<int> open_fds;
163 DIR *dirp = opendir(
"/proc/self/fd");
167 const std::string name(dirent->d_name);
168 uint64_t name_uint64;
174 open_fds.push_back(static_cast<int>(name_uint64));
184 int retval = dup2(pipe_send[0], 0);
186 retval = dup2(pipe_recv[1], 1);
189 for (
int fd = 2; fd < max_fd; fd++)
192 for (
unsigned i = 0; i < open_fds.size(); ++i)
198 struct sigaction signal_handler;
199 signal_handler.sa_handler = SIG_DFL;
203 execve(argv0, argv, &envp[0]);
204 syslog(LOG_USER | LOG_ERR,
"failed to start authz helper %s (%d)",
213 signal(SIGPIPE, SIG_IGN);
250 string pure_membership;
252 string json_msg = string(
"{\"cvmfs_authz_v1\":{") +
258 "\"membership\":\"" +
Base64(pure_membership) +
260 retval =
Send(json_msg) &&
Recv(&json_msg);
281 string pure_membership;
284 if (!sanitizer.
IsValid(authz_schema)) {
286 authz_schema.c_str());
290 string exe_path =
search_path_ +
"/cvmfs_" + authz_schema +
"_helper";
304 string json_debug_log;
306 json_debug_log =
",\"debug_log\":\"" + debug_log +
"\"";
307 string json_msg = string(
"{") +
308 "\"cvmfs_authz_v1\":{" +
311 "\"fqrn\":\"" +
fqrn_ +
"\"," +
316 bool retval =
Send(json_msg);
320 retval =
Recv(&json_msg);
333 int retval = pthread_mutex_init(&
lock_, NULL);
345 header.length = msg.length();
346 unsigned raw_length =
sizeof(header) + msg.length();
347 unsigned char *raw_msg =
reinterpret_cast<unsigned char *
>(
349 memcpy(raw_msg, &header,
sizeof(header));
350 memcpy(raw_msg +
sizeof(header), msg.data(), header.length);
373 const std::string &json_msg,
377 assert(binary_msg != NULL);
380 if (!json_document.
IsValid()) {
382 "invalid json from authz helper %s: %s",
389 json_document->
root(),
"cvmfs_authz_v1", JSON_OBJECT);
390 if (json_authz == NULL) {
392 "\"cvmfs_authz_v1\" not found in json from authz helper %s: %s",
399 (binary_msg->
msgid != expected_msgid))
423 json_authz,
"msgid", JSON_INT);
424 if (json_msgid == NULL) {
426 "\"msgid\" not found in json from authz helper %s",
432 if ((json_msgid->int_value < 0) ||
436 "invalid \"msgid\" in json from authz helper %s: %d",
437 progname_.c_str(), json_msgid->int_value);
457 if (json_status == NULL) {
459 "\"status\" not found in json from authz helper %s",
464 if ((json_status->int_value < 0) || (json_status->int_value >
kAuthzUnknown))
469 json_status->int_value);
473 if (json_ttl == NULL) {
482 if (json_token != NULL) {
485 bool valid_base64 =
Debase64(json_token->string_value, &token_binary);
488 "invalid Base64 in 'x509_proxy' from authz helper %s",
493 unsigned size = token_binary.size();
505 if (json_token != NULL) {
507 unsigned size = strlen(json_token->string_value);
516 "Got a bearer_token from authz_helper. "
517 "Setting token type to kTokenBearer");
521 "bearer_token was in returned JSON from Authz helper,"
522 " but of size 0 from authz helper %s",
531 "No auth token found in returned JSON from Authz helper %s",
544 json_authz,
"revision", JSON_INT);
545 if (json_revision == NULL) {
547 "\"revision\" not found in json from authz helper %s",
553 if (json_revision->int_value < 0) {
555 "invalid \"revision\" in json from authz helper %s: %d",
556 progname_.c_str(), json_revision->int_value);
569 if (retval != static_cast<int>(
sizeof(version))) {
575 "authz helper uses unknown protocol version %u", version);
582 if (retval != static_cast<int>(
sizeof(length))) {
590 while (nbytes < length) {
591 const unsigned remaining = length - nbytes;
595 "read failure from authz helper %s",
progname_.c_str());
600 msg->append(buf, retval);
608 const string &membership,
609 string *authz_schema,
610 string *pure_membership)
612 vector<string> components =
SplitString(membership,
'%');
613 *authz_schema = components[0];
614 if (components.size() < 2) {
617 *pure_membership =
"";
621 components.erase(components.begin());
AuthzExternalMsgIds msgid
AuthzExternalFetcher(const std::string &fqrn, const std::string &progname, const std::string &search_path, OptionsManager *options_manager)
static JSON * SearchInObject(const JSON *json_object, const std::string &name, const json_type type)
static const unsigned kChildTimeout
string JoinStrings(const vector< string > &strings, const string &joint)
Helper: "I verified, cvmfs, here's the result".
void StripAuthzSchema(const std::string &membership, std::string *authz_schema, std::string *pure_membership)
std::vector< std::string > GetEnvironmentSubset(const std::string &key_prefix, bool strip_prefix)
bool SafeWrite(int fd, const void *buf, size_t nbyte)
assert((mem||(size==0))&&"Out Of Memory")
bool Debase64(const string &data, string *decoded)
void MakePipe(int pipe_fd[2])
bool ParseMsgId(JSON *json_authz, AuthzExternalMsg *binary_msg)
static const uint32_t kProtocolVersion
Helper: "Yes, cvmfs, I'm here".
bool String2Uint64Parse(const std::string &value, uint64_t *result)
OptionsManager * options_manager_
bool ParsePermit(JSON *json_authz, AuthzExternalMsg *binary_msg)
bool FileExists(const std::string &path)
bool Recv(std::string *msg)
#define GetLogDebugFile()
ssize_t SafeRead(int fd, void *buf, size_t nbyte)
static JsonDocument * Create(const std::string &text)
vector< string > SplitString(const string &str, char delim)
static int g_suppressed_signals[13]
std::string FindHelper(const std::string &membership)
Cvmfs: "Please verify, helper".
string StringifyInt(const int64_t value)
struct AuthzExternalMsg::@0 permit
bool ParseRevision(JSON *json_authz, AuthzExternalMsg *binary_msg)
virtual ~AuthzExternalFetcher()
virtual AuthzStatus Fetch(const QueryInfo &query_info, AuthzToken *authz_token, unsigned *ttl)
bool ParseMsg(const std::string &json_msg, const AuthzExternalMsgIds expected_msgid, AuthzExternalMsg *binary_msg)
bool Send(const std::string &msg)
string Base64(const string &data)
BashOptionsManager options_manager_
Cvmfs: "Please shutdown, helper".
static const unsigned kDefaultTtl
First invalid message id.
const JSON * root() const
int GetLogSyslogFacility()
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)