XRootD
Loading...
Searching...
No Matches
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.
 
virtual ~XrdAccAuthorize ()
 Destructor.
 
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.
 
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{
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 XrdAccAuthorize::XrdAccAuthorize(), Macaroons::Handler::Config(), and Macaroons::Handler::PASSTHROUGH.

+ 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
bool Add(XrdSecAttr &attr)
int credslen
Length of the 'creds' data.
XrdSecEntityAttr * eaAPI
non-const API to attributes
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
char * creds
Raw entity credentials or cert.

References XrdSecEntityAttr::Add(), AOP_Any, XrdSecEntity::creds, XrdSecEntity::credslen, Macaroons::Debug, XrdSecEntity::eaAPI, XrdOucEnv::Get(), Macaroons::Info, 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)

References AOP_Read, Macaroons::Debug, emsg(), Macaroons::Error, Macaroons::Info, and Macaroons::Warning.

+ Here is the call graph for this function:

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