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 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{
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 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 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
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 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)

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: