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

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

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