9#include <openssl/bio.h>
10#include <openssl/evp.h>
16 char *val = config_obj.
GetWord();
19 log->
Emsg(
"Config",
"macaroons.onmissing requires a value (valid values: passthrough [default], allow, deny)");
22 if (!strcasecmp(val,
"passthrough")) {
24 }
else if (!strcasecmp(val,
"allow")) {
26 }
else if (!strcasecmp(val,
"deny")) {
30 log->
Emsg(
"Config",
"macaroons.onmissing is invalid (valid values: passthrough [default], allow, deny)! Provided value:", val);
37 std::string &location, std::string &secret, ssize_t &max_duration,
40 XrdOucStream config_obj(log, getenv(
"XRDINSTANCE"), env,
"=====> ");
45 if ((cfg_fd =
open(config, O_RDONLY, 0)) < 0) {
46 return log->
Emsg(
"Config", errno,
"open config file", config);
49 static const char *cvec[] = {
"*** macaroons plugin config:", 0 };
56 max_duration = 24*3600;
61 bool success =
true, ismine;
64 if ((ismine = !strncmp(
"all.sitename", var, 12))) var += 4;
65 else if ((ismine = !strncmp(
"macaroons.", var, 10)) && var[10]) var += 10;
69 if (!ismine) {
continue;}
71 if (!strcmp(
"secretkey", var)) {success = xsecretkey(config_obj, log, secret);}
72 else if (!strcmp(
"sitename", var)) {success = xsitename(config_obj, log, location);}
73 else if (!strcmp(
"trace", var)) {success = xtrace(config_obj, log);}
74 else if (!strcmp(
"maxduration", var)) {success = xmaxduration(config_obj, log, max_duration);}
75 else if (!strcmp(
"onmissing", var)) {success =
xonmissing(config_obj, log, behavior);}
77 log->
Say(
"Config warning: ignoring unknown directive '", orig_var,
"'.");
87 if (success && !location.size())
89 log->
Emsg(
"Config",
"all.sitename must be specified to use macaroons.");
98 static struct traceopts {
const char *opname;
enum LogMask opval; } tropts[] = {
106 int i, neg, trval = 0, numopts =
sizeof(tropts)/
sizeof(
struct traceopts);
108 char *val =
Config.GetWord();
111 log->
Emsg(
"Config",
"macaroons.trace requires at least one directive"
112 " [ all | error | warning | info | debug | none | off ]");
116 while (val && *val) {
117 if (strcmp(val,
"off") == 0 || strcmp(val,
"none") == 0) {
120 if ((neg = (val[0] ==
'-' && val[1])))
122 for (i = 0; i < numopts; i++) {
123 if (!strcmp(val, tropts[i].opname)) {
125 trval &= ~tropts[i].opval;
127 trval |= tropts[i].opval;
133 log->
Emsg(
"Config",
"macaroons.trace: ignoring invalid trace option:", val);
143bool Handler::xmaxduration(XrdOucStream &config_obj, XrdSysError *log, ssize_t &max_duration)
145 char *val = config_obj.
GetWord();
148 log->
Emsg(
"Config",
"macaroons.maxduration requires a value");
151 char *endptr =
nullptr;
152 long int max_duration_parsed = strtoll(val, &endptr, 10);
155 log->
Emsg(
"Config",
"Unable to parse macaroons.maxduration as an integer", val);
160 log->
Emsg(
"Config", errno,
"parse macaroons.maxduration as an integer.");
162 max_duration = max_duration_parsed;
167bool Handler::xsitename(XrdOucStream &config_obj, XrdSysError *log, std::string &location)
169 char *val = config_obj.
GetWord();
172 log->
Emsg(
"Config",
"all.sitename requires a name");
180bool Handler::xsecretkey(XrdOucStream &config_obj, XrdSysError *log, std::string &secret)
182 char *val = config_obj.
GetWord();
184 if (!val || !val[0]) {
185 log->
Emsg(
"Config",
"Shared secret key not specified");
189 BIO *bio = BIO_new_file(val,
"rb");
191 log->
Emsg(
"Config",
"Failed to open shared secret key file", val);
195 BIO *b64 = BIO_new(BIO_f_base64());
198 log->
Emsg(
"Config",
"Failed to allocate base64 filter");
202 BIO *bio_out = BIO_new(BIO_s_mem());
206 log->
Emsg(
"Config",
"Failed to allocate BIO output");
215 while ((inlen = BIO_read(b64, inbuf, 512)) > 0) {
217 if (errno == EINTR)
continue;
220 BIO_write(bio_out, inbuf, inlen);
225 BIO_free_all(bio_out);
227 log->
Emsg(
"Config", errno,
"read secret key.");
231 if (!BIO_flush(bio_out)) {
232 BIO_free_all(bio_out);
234 log->
Emsg(
"Config", errno,
"flush secret key.");
239 long data_len = BIO_get_mem_data(bio_out, &decoded);
241 secret = std::string(decoded, data_len);
243 BIO_free_all(bio_out);
246 if (secret.size() < 32) {
247 log->
Emsg(
"Config",
"Secret key is too short; must be 32 bytes long. Try running 'openssl rand -base64 -out", val,
"64' to generate a new key");
static bool Config(const char *config, XrdOucEnv *env, XrdSysError *log, std::string &location, std::string &secret, ssize_t &max_duration, AuthzBehavior &behavior)
char * GetMyFirstWord(int lowcase=0)
char * GetWord(int lowcase=0)
int Attach(int FileDescriptor, int bsz=2047)
static void Capture(const char **cVec=0, bool linefeed=true)
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
void setMsgMask(int mask)