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 12 of file XrdMacaroonsAuthz.hh.

Constructor & Destructor Documentation

◆ Authz()

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

Definition at line 138 of file XrdMacaroonsAuthz.cc.

139  : m_max_duration(86400),
140  m_chain(chain),
141  m_log(log, "macarons_"),
142  m_authz_behavior(static_cast<int>(Handler::AuthzBehavior::PASSTHROUGH))
143 {
144  Handler::AuthzBehavior behavior(Handler::AuthzBehavior::PASSTHROUGH);
145  XrdOucEnv env;
146  if (!Handler::Config(config, &env, &m_log, m_location, m_secret, m_max_duration, behavior))
147  {
148  throw std::runtime_error("Macaroon authorization config failed.");
149  }
150  m_authz_behavior = static_cast<int>(behavior);
151 }
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 17 of file XrdMacaroonsAuthz.hh.

17 {}

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 171 of file XrdMacaroonsAuthz.cc.

173 {
174  // We don't allow any testing to occur in this authz module, preventing
175  // a macaroon to be used to receive further macaroons.
176  if (oper == AOP_Any)
177  {
178  return m_chain ? m_chain->Access(Entity, path, oper, env) : XrdAccPriv_None;
179  }
180 
181  const char *authz = env ? env->Get("authz") : nullptr;
182  if (authz && !strncmp(authz, "Bearer%20", 9))
183  {
184  authz += 9;
185  }
186  else if (!authz && (authz = env ? env->Get("access_token") : nullptr) && !strncmp(authz, "Bearer%20", 9))
187  {
188  authz += 9;
189  }
190 
191  // If there's no request-specific token, check for a ZTN session token
192  if (!authz && Entity && !strcmp("ztn", Entity->prot) && Entity->creds &&
193  Entity->credslen && Entity->creds[Entity->credslen] == '\0')
194  {
195  authz = Entity->creds;
196  }
197 
198  if (!authz) {
199  return OnMissing(Entity, path, oper, env);
200  }
201 
202  macaroon_returncode mac_err = MACAROON_SUCCESS;
203  struct macaroon* macaroon = macaroon_deserialize(
204  authz,
205  &mac_err);
206  if (!macaroon)
207  {
208  // Do not log - might be other token type!
209  //m_log.Emsg("Access", "Failed to parse the macaroon");
210  return OnMissing(Entity, path, oper, env);
211  }
212 
213  struct macaroon_verifier *verifier = macaroon_verifier_create();
214  if (!verifier)
215  {
216  m_log.Emsg("Access", "Failed to create a new macaroon verifier");
217  return XrdAccPriv_None;
218  }
219  if (!path)
220  {
221  m_log.Emsg("Access", "Request with no provided path.");
222  macaroon_verifier_destroy(verifier);
223  return XrdAccPriv_None;
224  }
225 
226  AuthzCheck check_helper(path, oper, m_max_duration, m_log);
227 
228  if (macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_before_s, &check_helper, &mac_err) ||
229  macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_activity_s, &check_helper, &mac_err) ||
230  macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_name_s, &check_helper, &mac_err) ||
231  macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_path_s, &check_helper, &mac_err))
232  {
233  m_log.Emsg("Access", "Failed to configure caveat verifier:");
234  macaroon_verifier_destroy(verifier);
235  return XrdAccPriv_None;
236  }
237 
238  const unsigned char *macaroon_loc;
239  size_t location_sz;
240  macaroon_location(macaroon, &macaroon_loc, &location_sz);
241  if (strncmp(reinterpret_cast<const char *>(macaroon_loc), m_location.c_str(), location_sz))
242  {
243  std::string location_str(reinterpret_cast<const char *>(macaroon_loc), location_sz);
244  m_log.Emsg("Access", "Macaroon is for incorrect location", location_str.c_str());
245  macaroon_verifier_destroy(verifier);
246  macaroon_destroy(macaroon);
247  return m_chain ? m_chain->Access(Entity, path, oper, env) : XrdAccPriv_None;
248  }
249 
250  if (macaroon_verify(verifier, macaroon,
251  reinterpret_cast<const unsigned char *>(m_secret.c_str()),
252  m_secret.size(),
253  NULL, 0, // discharge macaroons
254  &mac_err))
255  {
256  m_log.Log(LogMask::Debug, "Access", "Macaroon verification failed");
257  macaroon_verifier_destroy(verifier);
258  macaroon_destroy(macaroon);
259  return m_chain ? m_chain->Access(Entity, path, oper, env) : XrdAccPriv_None;
260  }
261  macaroon_verifier_destroy(verifier);
262 
263  const unsigned char *macaroon_id;
264  size_t id_sz;
265  macaroon_identifier(macaroon, &macaroon_id, &id_sz);
266 
267  std::string macaroon_id_str(reinterpret_cast<const char *>(macaroon_id), id_sz);
268  m_log.Log(LogMask::Info, "Access", "Macaroon verification successful; ID", macaroon_id_str.c_str());
269  macaroon_destroy(macaroon);
270 
271  // Copy the name, if present into the macaroon, into the credential object.
272  if (Entity && check_helper.GetSecName().size()) {
273  const std::string &username = check_helper.GetSecName();
274  m_log.Log(LogMask::Debug, "Access", "Setting the request name to", username.c_str());
275  Entity->eaAPI->Add("request.name", username,true);
276  }
277 
278  // We passed verification - give the correct privilege.
279  return AddPriv(oper, XrdAccPriv_None);
280 }
@ 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 31 of file XrdMacaroonsAuthz.hh.

34  {
35  return 0;
36  }

◆ IssuerList()

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

Implements XrdSciTokensHelper.

Definition at line 46 of file XrdMacaroonsAuthz.hh.

46 {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 38 of file XrdMacaroonsAuthz.hh.

40  {
41  return 0;
42  }

◆ 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 282 of file XrdMacaroonsAuthz.cc.

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