XRootD
Macaroons::Authz Class Referencefinal

#include <XrdMacaroonsAuthz.hh>

+ Inheritance diagram for Macaroons::Authz:
+ Collaboration diagram for Macaroons::Authz:

Public Member Functions

 Authz (XrdSysLogger *lp, const char *parms, XrdAccAuthorize *chain)
 
virtual ~Authz ()
 
virtual XrdAccPrivs Access (const XrdSecEntity *Entity, const char *path, const Access_Operation oper, XrdOucEnv *env) override
 
virtual int Audit (const int accok, const XrdSecEntity *Entity, const char *path, const Access_Operation oper, XrdOucEnv *Env) override
 
virtual Issuers IssuerList () override
 
virtual int Test (const XrdAccPrivs priv, const Access_Operation oper) override
 
virtual bool Validate (const char *token, std::string &emsg, long long *expT, XrdSecEntity *entP) override
 
- Public Member Functions inherited from XrdAccAuthorize
 XrdAccAuthorize ()
 Constructor. More...
 
virtual ~XrdAccAuthorize ()
 Destructor. More...
 
virtual XrdAccPrivs Access (const XrdSecEntity *Entity, const char *path, const Access_Operation oper, std::string &eInfo, XrdOucEnv *Env=0)
 
- Public Member Functions inherited from XrdSciTokensHelper
 XrdSciTokensHelper ()
 Constructor and Destructor. More...
 
virtual ~XrdSciTokensHelper ()
 

Additional Inherited Members

- Public Types inherited from XrdSciTokensHelper
typedef std::vector< ValidIssuerIssuers
 

Detailed Description

Definition at line 7 of file XrdMacaroonsAuthz.hh.

Constructor & Destructor Documentation

◆ Authz()

Authz::Authz ( XrdSysLogger lp,
const char *  parms,
XrdAccAuthorize chain 
)

Definition at line 132 of file XrdMacaroonsAuthz.cc.

133  : m_max_duration(86400),
134  m_chain(chain),
135  m_log(log, "macarons_"),
136  m_authz_behavior(static_cast<int>(Handler::AuthzBehavior::PASSTHROUGH))
137 {
138  Handler::AuthzBehavior behavior(Handler::AuthzBehavior::PASSTHROUGH);
139  XrdOucEnv env;
140  if (!Handler::Config(config, &env, &m_log, m_location, m_secret, m_max_duration, behavior))
141  {
142  throw std::runtime_error("Macaroon authorization config failed.");
143  }
144  m_authz_behavior = static_cast<int>(behavior);
145 }
static bool Config(const char *config, XrdOucEnv *env, XrdSysError *log, std::string &location, std::string &secret, ssize_t &max_duration, AuthzBehavior &behavior)

References Macaroons::Handler::Config().

+ Here is the call graph for this function:

◆ ~Authz()

virtual Macaroons::Authz::~Authz ( )
inlinevirtual

Definition at line 12 of file XrdMacaroonsAuthz.hh.

12 {}

Member Function Documentation

◆ Access()

XrdAccPrivs Authz::Access ( const XrdSecEntity Entity,
const char *  path,
const Access_Operation  oper,
XrdOucEnv Env 
)
overridevirtual

Check whether or not the client is permitted specified access to a path.

Parameters
Entity-> Authentication information
path-> The logical path which is the target of oper
oper-> The operation being attempted (see the enum above). If the oper is AOP_Any, then the actual privileges are returned and the caller may make subsequent tests using Test().
Env-> Environmental information at the time of the operation as supplied by the path CGI string. This is optional and the pointer may be zero.
Returns
Permit: a non-zero value (access is permitted) Deny: zero (access is denied)

Implements XrdAccAuthorize.

Definition at line 164 of file XrdMacaroonsAuthz.cc.

166 {
167  // We don't allow any testing to occur in this authz module, preventing
168  // a macaroon to be used to receive further macaroons.
169  if (oper == AOP_Any)
170  {
171  return m_chain ? m_chain->Access(Entity, path, oper, env) : XrdAccPriv_None;
172  }
173 
174  const char *authz = env ? env->Get("authz") : nullptr;
175  if (authz && !strncmp(authz, "Bearer%20", 9))
176  {
177  authz += 9;
178  }
179  else if (!authz && (authz = env ? env->Get("access_token") : nullptr) && !strncmp(authz, "Bearer%20", 9))
180  {
181  authz += 9;
182  }
183 
184  // If there's no request-specific token, check for a ZTN session token
185  if (!authz && Entity && !strcmp("ztn", Entity->prot) && Entity->creds &&
186  Entity->credslen && Entity->creds[Entity->credslen] == '\0')
187  {
188  authz = Entity->creds;
189  }
190 
191  if (!authz) {
192  return OnMissing(Entity, path, oper, env);
193  }
194 
195  macaroon_returncode mac_err = MACAROON_SUCCESS;
196  struct macaroon* macaroon = macaroon_deserialize(
197  authz,
198  &mac_err);
199  if (!macaroon)
200  {
201  // Do not log - might be other token type!
202  //m_log.Emsg("Access", "Failed to parse the macaroon");
203  return OnMissing(Entity, path, oper, env);
204  }
205 
206  struct macaroon_verifier *verifier = macaroon_verifier_create();
207  if (!verifier)
208  {
209  m_log.Emsg("Access", "Failed to create a new macaroon verifier");
210  return XrdAccPriv_None;
211  }
212  if (!path)
213  {
214  m_log.Emsg("Access", "Request with no provided path.");
215  macaroon_verifier_destroy(verifier);
216  return XrdAccPriv_None;
217  }
218 
219  AuthzCheck check_helper(path, oper, m_max_duration, m_log);
220 
221  if (macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_before_s, &check_helper, &mac_err) ||
222  macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_activity_s, &check_helper, &mac_err) ||
223  macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_name_s, &check_helper, &mac_err) ||
224  macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_path_s, &check_helper, &mac_err))
225  {
226  m_log.Emsg("Access", "Failed to configure caveat verifier:");
227  macaroon_verifier_destroy(verifier);
228  return XrdAccPriv_None;
229  }
230 
231  const unsigned char *macaroon_loc;
232  size_t location_sz;
233  macaroon_location(macaroon, &macaroon_loc, &location_sz);
234  if (strncmp(reinterpret_cast<const char *>(macaroon_loc), m_location.c_str(), location_sz))
235  {
236  std::string location_str(reinterpret_cast<const char *>(macaroon_loc), location_sz);
237  m_log.Emsg("Access", "Macaroon is for incorrect location", location_str.c_str());
238  macaroon_verifier_destroy(verifier);
239  macaroon_destroy(macaroon);
240  return m_chain ? m_chain->Access(Entity, path, oper, env) : XrdAccPriv_None;
241  }
242 
243  if (macaroon_verify(verifier, macaroon,
244  reinterpret_cast<const unsigned char *>(m_secret.c_str()),
245  m_secret.size(),
246  nullptr, 0, // discharge macaroons
247  &mac_err))
248  {
249  m_log.Log(LogMask::Debug, "Access", "Macaroon verification failed");
250  macaroon_verifier_destroy(verifier);
251  macaroon_destroy(macaroon);
252  // This token is from our server (location matched) but caveats or HMAC
253  // failed. Falling through to the chain would let a path-restricted
254  // macaroon bypass its own restrictions. Deny unconditionally.
255  return XrdAccPriv_None;
256  }
257  macaroon_verifier_destroy(verifier);
258 
259  const unsigned char *macaroon_id;
260  size_t id_sz;
261  macaroon_identifier(macaroon, &macaroon_id, &id_sz);
262 
263  std::string macaroon_id_str(reinterpret_cast<const char *>(macaroon_id), id_sz);
264  m_log.Log(LogMask::Info, "Access", "Macaroon verification successful; ID", macaroon_id_str.c_str());
265  macaroon_destroy(macaroon);
266 
267  // Copy the name, if present into the macaroon, into the credential object.
268  if (Entity && check_helper.GetSecName().size()) {
269  const std::string &username = check_helper.GetSecName();
270  m_log.Log(LogMask::Debug, "Access", "Setting the request name to", username.c_str());
271  Entity->eaAPI->Add("request.name", username,true);
272  }
273 
274  // We passed verification - give the correct privilege.
275  return AddPriv(oper, XrdAccPriv_None);
276 }
@ AOP_Any
Special for getting privs.
@ XrdAccPriv_None
Definition: XrdAccPrivs.hh:55
bool Debug
virtual XrdAccPrivs Access(const XrdSecEntity *Entity, const char *path, const Access_Operation oper, XrdOucEnv *Env=0)=0
bool Add(XrdSecAttr &attr)
int credslen
Length of the 'creds' data.
Definition: XrdSecEntity.hh:78
XrdSecEntityAttr * eaAPI
non-const API to attributes
Definition: XrdSecEntity.hh:92
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
Definition: XrdSecEntity.hh:67
char * creds
Raw entity credentials or cert.
Definition: XrdSecEntity.hh:77
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:116
void Log(int mask, const char *esfx, const char *text1, const char *text2=0, const char *text3=0)
Definition: XrdSysError.hh:167

References XrdAccAuthorize::Access(), XrdSecEntityAttr::Add(), AOP_Any, XrdSecEntity::creds, XrdSecEntity::credslen, Debug, XrdSecEntity::eaAPI, XrdSysError::Emsg(), XrdOucEnv::Get(), TPC::Info, XrdSysError::Log(), XrdSecEntity::prot, and XrdAccPriv_None.

+ Here is the call graph for this function:

◆ Audit()

virtual int Macaroons::Authz::Audit ( const int  accok,
const XrdSecEntity Entity,
const char *  path,
const Access_Operation  oper,
XrdOucEnv Env 
)
inlineoverridevirtual

Route an audit message to the appropriate audit exit routine. See XrdAccAudit.h for more information on how the default implementation works. Currently, this method is not called by the ofs but should be used by the implementation to record denials or grants, as warranted.

Parameters
accok-> True is access was grated; false otherwise.
Entity-> Authentication information
path-> The logical path which is the target of oper
oper-> The operation being attempted (see above)
Env-> Environmental information at the time of the operation as supplied by the path CGI string. This is optional and the pointer may be zero.
Returns
Success: !0 information recorded. Failure: 0 information could not be recorded.

Implements XrdAccAuthorize.

Definition at line 26 of file XrdMacaroonsAuthz.hh.

29  {
30  return 0;
31  }

◆ IssuerList()

virtual Issuers Macaroons::Authz::IssuerList ( )
inlineoverridevirtual

Implements XrdSciTokensHelper.

Definition at line 41 of file XrdMacaroonsAuthz.hh.

41 {return Issuers();}
std::vector< ValidIssuer > Issuers

◆ Test()

virtual int Macaroons::Authz::Test ( const XrdAccPrivs  priv,
const Access_Operation  oper 
)
inlineoverridevirtual

Check whether the specified operation is permitted.

Parameters
priv-> the privileges as returned by Access().
oper-> The operation being attempted (see above)
Returns
Permit: a non-zero value (access is permitted) Deny: zero (access is denied)

Implements XrdAccAuthorize.

Definition at line 33 of file XrdMacaroonsAuthz.hh.

35  {
36  return 0;
37  }

◆ Validate()

bool Authz::Validate ( const char *  token,
std::string &  emsg,
long long *  expT,
XrdSecEntity entP 
)
overridevirtual

Validate a scitoken.

Parameters
token- Pointer to the token to validate.
emsg- Reference to a string to hold the reason for rejection
expT- Pointer to where the expiry value is to be placed. If nill, the value is not returned.
entP- Pointer to the SecEntity object and when not nil requests that it be filled with any identifying information in the token. The caller assumes that all supplied fields may be released by calling free().
Returns
Return true if the token is valid; false otherwise with emsg set.

Implements XrdSciTokensHelper.

Definition at line 278 of file XrdMacaroonsAuthz.cc.

282 {
283  macaroon_returncode mac_err = MACAROON_SUCCESS;
284  std::unique_ptr<struct macaroon, decltype(&macaroon_destroy)> macaroon(
285  macaroon_deserialize(token, &mac_err),
286  &macaroon_destroy);
287 
288  if (!macaroon)
289  {
290  emsg = "Failed to deserialize the token as a macaroon";
291  // Purposely log at debug level in case if this validation is ever
292  // chained so we don't have overly-chatty logs.
293  m_log.Log(LogMask::Debug, "Validate", emsg.c_str());
294  return false;
295  }
296 
297  std::unique_ptr<struct macaroon_verifier, decltype(&macaroon_verifier_destroy)> verifier(
298  macaroon_verifier_create(), &macaroon_verifier_destroy);
299  if (!verifier)
300  {
301  emsg = "Internal error: failed to create a verifier.";
302  m_log.Log(LogMask::Error, "Validate", emsg.c_str());
303  return false;
304  }
305 
306  // Note the path and operation here are ignored as we won't use those validators
307  AuthzCheck check_helper("/", AOP_Read, m_max_duration, m_log);
308 
309  if (macaroon_verifier_satisfy_general(verifier.get(), AuthzCheck::verify_before_s, &check_helper, &mac_err) ||
310  macaroon_verifier_satisfy_general(verifier.get(), validate_verify_empty, nullptr, &mac_err))
311  {
312  emsg = "Failed to configure the verifier";
313  m_log.Log(LogMask::Error, "Validate", emsg.c_str());
314  return false;
315  }
316 
317  const unsigned char *macaroon_loc;
318  size_t location_sz;
319  macaroon_location(macaroon.get(), &macaroon_loc, &location_sz);
320  if (strncmp(reinterpret_cast<const char *>(macaroon_loc), m_location.c_str(), location_sz))
321  {
322  emsg = "Macaroon contains incorrect location: " +
323  std::string(reinterpret_cast<const char *>(macaroon_loc), location_sz);
324  m_log.Log(LogMask::Warning, "Validate", emsg.c_str(), ("all.sitename is " + m_location).c_str());
325  return false;
326  }
327 
328  if (macaroon_verify(verifier.get(), macaroon.get(),
329  reinterpret_cast<const unsigned char *>(m_secret.c_str()),
330  m_secret.size(),
331  nullptr, 0,
332  &mac_err))
333  {
334  emsg = "Macaroon verification error" + (check_helper.GetErrorMessage().size() ?
335  (", " + check_helper.GetErrorMessage()) : "");
336  m_log.Log(LogMask::Warning, "Validate", emsg.c_str());
337  return false;
338  }
339 
340  const unsigned char *macaroon_id;
341  size_t id_sz;
342  macaroon_identifier(macaroon.get(), &macaroon_id, &id_sz);
343  m_log.Log(LogMask::Info, "Validate", ("Macaroon verification successful; ID " +
344  std::string(reinterpret_cast<const char *>(macaroon_id), id_sz)).c_str());
345 
346  return true;
347 }
@ AOP_Read
open() r/o, prepare()
int emsg(int rc, char *msg)
@ Error
@ Warning

References AOP_Read, Debug, emsg(), Error, TPC::Info, XrdSysError::Log(), and TPC::Warning.

+ Here is the call graph for this function:

The documentation for this class was generated from the following files: