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< ValidIssuer > Issuers

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

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

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