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, XrdOucEnv *Env=0)=0
 
virtual int Audit (const int accok, const XrdSecEntity *Entity, const char *path, const Access_Operation oper, XrdOucEnv *Env=0)=0
 
virtual int Test (const XrdAccPrivs priv, const Access_Operation oper)=0
 
- Public Member Functions inherited from XrdSciTokensHelper
 XrdSciTokensHelper ()
 Constructor and Destructor.
 
virtual ~XrdSciTokensHelper ()
 
virtual Issuers IssuerList ()=0
 
virtual bool Validate (const char *token, std::string &emsg, long long *expT=0, XrdSecEntity *entP=0)=0
 

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

132 : m_max_duration(86400),
133 m_chain(chain),
134 m_log(log, "macarons_"),
135 m_authz_behavior(static_cast<int>(Handler::AuthzBehavior::PASSTHROUGH))
136{
138 XrdOucEnv env;
139 if (!Handler::Config(config, &env, &m_log, m_location, m_secret, m_max_duration, behavior))
140 {
141 throw std::runtime_error("Macaroon authorization config failed.");
142 }
143 m_authz_behavior = static_cast<int>(behavior);
144}
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(), 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 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
180 // If there's no request-specific token, check for a ZTN session token
181 if (!authz && Entity && !strcmp("ztn", Entity->prot) && Entity->creds &&
182 Entity->credslen && Entity->creds[Entity->credslen] == '\0')
183 {
184 authz = Entity->creds;
185 }
186
187 if (!authz) {
188 return OnMissing(Entity, path, oper, env);
189 }
190
191 macaroon_returncode mac_err = MACAROON_SUCCESS;
192 struct macaroon* macaroon = macaroon_deserialize(
193 authz,
194 &mac_err);
195 if (!macaroon)
196 {
197 // Do not log - might be other token type!
198 //m_log.Emsg("Access", "Failed to parse the macaroon");
199 return OnMissing(Entity, path, oper, env);
200 }
201
202 struct macaroon_verifier *verifier = macaroon_verifier_create();
203 if (!verifier)
204 {
205 m_log.Emsg("Access", "Failed to create a new macaroon verifier");
206 return XrdAccPriv_None;
207 }
208 if (!path)
209 {
210 m_log.Emsg("Access", "Request with no provided path.");
211 macaroon_verifier_destroy(verifier);
212 return XrdAccPriv_None;
213 }
214
215 AuthzCheck check_helper(path, oper, m_max_duration, m_log);
216
217 if (macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_before_s, &check_helper, &mac_err) ||
218 macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_activity_s, &check_helper, &mac_err) ||
219 macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_name_s, &check_helper, &mac_err) ||
220 macaroon_verifier_satisfy_general(verifier, AuthzCheck::verify_path_s, &check_helper, &mac_err))
221 {
222 m_log.Emsg("Access", "Failed to configure caveat verifier:");
223 macaroon_verifier_destroy(verifier);
224 return XrdAccPriv_None;
225 }
226
227 const unsigned char *macaroon_loc;
228 size_t location_sz;
229 macaroon_location(macaroon, &macaroon_loc, &location_sz);
230 if (strncmp(reinterpret_cast<const char *>(macaroon_loc), m_location.c_str(), location_sz))
231 {
232 std::string location_str(reinterpret_cast<const char *>(macaroon_loc), location_sz);
233 m_log.Emsg("Access", "Macaroon is for incorrect location", location_str.c_str());
234 macaroon_verifier_destroy(verifier);
235 macaroon_destroy(macaroon);
236 return m_chain ? m_chain->Access(Entity, path, oper, env) : XrdAccPriv_None;
237 }
238
239 if (macaroon_verify(verifier, macaroon,
240 reinterpret_cast<const unsigned char *>(m_secret.c_str()),
241 m_secret.size(),
242 NULL, 0, // discharge macaroons
243 &mac_err))
244 {
245 m_log.Log(LogMask::Debug, "Access", "Macaroon verification failed");
246 macaroon_verifier_destroy(verifier);
247 macaroon_destroy(macaroon);
248 return m_chain ? m_chain->Access(Entity, path, oper, env) : XrdAccPriv_None;
249 }
250 macaroon_verifier_destroy(verifier);
251
252 const unsigned char *macaroon_id;
253 size_t id_sz;
254 macaroon_identifier(macaroon, &macaroon_id, &id_sz);
255
256 std::string macaroon_id_str(reinterpret_cast<const char *>(macaroon_id), id_sz);
257 m_log.Log(LogMask::Info, "Access", "Macaroon verification successful; ID", macaroon_id_str.c_str());
258 macaroon_destroy(macaroon);
259
260 // Copy the name, if present into the macaroon, into the credential object.
261 if (Entity && check_helper.GetSecName().size()) {
262 const std::string &username = check_helper.GetSecName();
263 m_log.Log(LogMask::Debug, "Access", "Setting the request name to", username.c_str());
264 Entity->eaAPI->Add("request.name", username,true);
265 }
266
267 // We passed verification - give the correct privilege.
268 return AddPriv(oper, XrdAccPriv_None);
269}
@ AOP_Any
Special for getting privs.
@ XrdAccPriv_None
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.
XrdSecEntityAttr * eaAPI
non-const API to attributes
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
char * creds
Raw entity credentials or cert.
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
void Log(int mask, const char *esfx, const char *text1, const char *text2=0, const char *text3=0)

References XrdAccAuthorize::Access(), XrdSecEntityAttr::Add(), AOP_Any, XrdSecEntity::creds, XrdSecEntity::credslen, Macaroons::Debug, XrdSecEntity::eaAPI, XrdSysError::Emsg(), XrdOucEnv::Get(), Macaroons::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 271 of file XrdMacaroonsAuthz.cc.

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

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

+ Here is the call graph for this function:

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