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

127  : m_max_duration(86400),
128  m_chain(chain),
129  m_log(log, "macarons_"),
130  m_authz_behavior(static_cast<int>(Handler::AuthzBehavior::PASSTHROUGH))
131 {
132  Handler::AuthzBehavior behavior(Handler::AuthzBehavior::PASSTHROUGH);
133  XrdOucEnv env;
134  if (!Handler::Config(config, &env, &m_log, m_location, m_secret, m_max_duration, behavior))
135  {
136  throw std::runtime_error("Macaroon authorization config failed.");
137  }
138  m_authz_behavior = static_cast<int>(behavior);
139 }
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 158 of file XrdMacaroonsAuthz.cc.

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

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

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