XRootD
Loading...
Searching...
No Matches
XrdVomsFun Class Reference

#include <XrdVomsFun.hh>

Collaboration diagram for XrdVomsFun:

Public Types

enum  CertFormat {
  gCertRaw = 0 ,
  gCertPEM = 1 ,
  gCertX509 = 2
}

Public Member Functions

 XrdVomsFun (XrdSysError &erp)
 ~XrdVomsFun ()
void SetCertFmt (CertFormat n)
int VOMSFun (XrdSecEntity &ent)
int VOMSInit (const char *cfg)

Detailed Description

Definition at line 43 of file XrdVomsFun.hh.

Member Enumeration Documentation

◆ CertFormat

Enumerator
gCertRaw 
gCertPEM 
gCertX509 

Definition at line 49 of file XrdVomsFun.hh.

50 {gCertRaw = 0,
51 gCertPEM = 1,
52 gCertX509 = 2
53 };

Constructor & Destructor Documentation

◆ XrdVomsFun()

XrdVomsFun::XrdVomsFun ( XrdSysError & erp)

Definition at line 100 of file XrdVomsFun.cc.

101 : gGrpWhich(gUseAll), gDebug(0), gDest(erp),
102 gLogger(erp.logger())
103{
104 gCertFmt = gCertRaw; // certfmt:raw|pem|x509 [raw]
105};
XrdSysLogger * logger(XrdSysLogger *lp=0)

References gCertRaw.

◆ ~XrdVomsFun()

XrdVomsFun::~XrdVomsFun ( )
inline

Definition at line 63 of file XrdVomsFun.hh.

63{} // Once constructed never deleted (except for Http).

Member Function Documentation

◆ SetCertFmt()

void XrdVomsFun::SetCertFmt ( CertFormat n)
inline

Definition at line 55 of file XrdVomsFun.hh.

55{gCertFmt = n;}

Referenced by XrdHttpGetSecXtractor().

Here is the caller graph for this function:

◆ VOMSFun()

int XrdVomsFun::VOMSFun ( XrdSecEntity & ent)

Definition at line 185 of file XrdVomsFun.cc.

186{
187 // Implementation of XrdSecgsiAuthzFun extracting the information from the
188 // proxy chain in entity.creds
189 EPNAME("Fun");
190
191 vomsdata v;
192 X509 *pxy = 0;
193 STACK_OF(X509) *stk = 0;
194 int freestk = 1;
195
196// Set extractor name in the XrdSecEntity object
197//
198 strcpy(ent.prox, "xrdvoms");
199
200 if (gCertFmt == gCertRaw) {
201 //
202 // RAW format
203 //
204 XrdCryptoX509Chain *c = (XrdCryptoX509Chain *) ent.creds;
205 if (!c) {
206 PRINT("ERROR: no proxy chain found!");
207 return -1;
208 }
209
210 XrdCryptoX509 *xp = c->End();
211 if (!xp) {
212 PRINT("ERROR: no proxy certificate in chain!");
213 return -1;
214 }
215 pxy = (X509 *) xp->Opaque();
216 VOMSDBGSUBJ("proxy: ", pxy)
217 freestk = 2;
218
219 stk =sk_X509_new_null();
220 XrdCryptoX509 *xxp = c->Begin();
221 while (xxp) {
222 if (xxp == c->End()) break;
223 if (xxp->type != XrdCryptoX509::kCA) {
224 VOMSDBGSUBJ("adding cert: ", (X509 *) xxp->Opaque())
225 sk_X509_push(stk, (X509 *) xxp->Opaque());
226 }
227 xxp = c->Next();
228 }
229 } else if (gCertFmt == gCertPEM) {
230 //
231 // PEM format
232 //
233 // Create a bio_mem to store the certificates
234 BIO *bmem = BIO_new(BIO_s_mem());
235 if (!bmem) {
236 PRINT("unable to create BIO for memory operations");
237 return -1;
238 }
239
240 // Write data to BIO
241 int nw = BIO_write(bmem, (const void *)(ent.creds), ent.credslen);
242 if (nw != ent.credslen) {
243 PRINT("problems writing data to memory BIO (nw: "<<nw<<")");
244 BIO_free(bmem);
245 return -1;
246 }
247
248 // Get certificate from BIO
249 if (!(pxy = PEM_read_bio_X509(bmem,0,0,0))) {
250 PRINT("unable to read certificate to memory BIO");
251 BIO_free(bmem);
252 return -1;
253 }
254 VOMSDBGSUBJ("proxy: ", pxy)
255 //
256 // The chain now
257 X509 *xc = 0;
258 stk =sk_X509_new_null();
259 while ((xc = PEM_read_bio_X509(bmem,0,0,0))) {
260 VOMSDBGSUBJ("adding cert: ", xc)
261 sk_X509_push(stk, xc);
262 }
263 //
264 // Free BIO
265 BIO_free(bmem);
266
267 } else {
268 //
269 // STACK_OF(X509) format
270 //
271 Voms_x509_in_t *voms_in = (Voms_x509_in_t *) ent.creds;
272 pxy = voms_in->cert;
273 stk = voms_in->chain;
274 freestk = 0;
275 }
276
277 bool extfound = 0;
278 XrdOucString endor, grps, role, vo, xendor, xgrps, xrole, xvo;
279 if (v.Retrieve(pxy, stk, RECURSE_CHAIN)) {
280 VOMSDBG("retrieval successful");
281 extfound = 1;
282 std::vector<voms>::iterator i = v.data.begin();
283 for ( ; i != v.data.end(); i++) {
284 VOMSDBG("found VO: " << (*i).voname);
285 xvo = (*i).voname.c_str(); VOMSSPTTAB(xvo);
286 // Filter the VO? (*i) is voms
287 if (gVOs.Num() > 0 && !gVOs.Find((*i).voname.c_str())) continue;
288 // Save VO name (in tuple mode this is done later, in the loop over groups)
289 if (gGrpWhich < gUseAll) vo = xvo;
290 std::vector<data> dat = (*i).std;
291 std::vector<data>::iterator idat = dat.begin();
292 // Same size as std::vector<data> by construction (same information in compact form)
293 std::vector<std::string> fqa = (*i).fqan;
294 std::vector<std::string>::iterator ifqa = fqa.begin();
295 for (; idat != dat.end(); idat++, ifqa++) {
296 VOMSDBG(" ---> group: '"<<(*idat).group<<"', role: '"<<(*idat).role<<"', cap: '" <<(*idat).cap<<"'");
297 VOMSDBG(" ---> fqan: '"<<(*ifqa)<<"'");
298 xgrps = (*idat).group.c_str(); VOMSSPTTAB(xgrps);
299 xrole = (*idat).role.c_str(); VOMSSPTTAB(xrole);
300 xendor = (*ifqa).c_str(); VOMSSPTTAB(xendor);
301 bool fillgrp = true;
302 if (gGrps.Num() && !gGrps.Find((*idat).group.c_str()))
303 fillgrp = false;
304 if (fillgrp) {
305 if (gGrpWhich == gUseAll) {
306 if (vo.length() > 0) vo += " ";
307 vo += (*i).voname.c_str();
308 if (grps.length() > 0) grps += " ";
309 grps += (*idat).group.c_str();
310 if (role.length() > 0) role += " ";
311 role += (*idat).role.c_str();
312 if (endor.length() > 0) endor += ",";
313 endor += (*ifqa).c_str();
314 } else {
315 grps = (*idat).group.c_str();
316 role = (*idat).role.c_str();
317 endor = (*ifqa).c_str();
318 }
319 }
320 // If we are asked to take the first we break
321 if (gGrpWhich == gUseFirst && grps.length() > 0) break;
322 }
323 if (grps.length() <= 0) {
324 // Reset all the fields
325 role = "";
326 vo = "";
327 endor = "";
328 }
329 }
330 // Save the information found
331 SafeFree(ent.vorg);
332 SafeFree(ent.grps);
333 SafeFree(ent.role);
335 if (vo.length() > 0) {
336 ent.vorg = strdup(vo.c_str());
337 // Save the groups
338 if (grps.length() > 0) ent.grps = strdup(grps.c_str());
339 if (role.length() > 0) ent.role = strdup(role.c_str());
340 // Save the whole string in endorsements
341 if (endor.length() > 0) ent.endorsements = strdup(endor.c_str());
342 } else if (extfound) {
343 VOMSDBG("VOMS extensions do not match required criteria ("<<gRequire<<")");
344 }
345 } else {
346 PRINT("retrieval FAILED: "<< v.ErrorMessage());
347 }
348
349 // Fix spaces in XrdSecEntity::name
350// char *sp = 0;
351// while ((sp = strchr(ent.name, ' '))) { *sp = '\t'; }
352
353 // Adjust the output format, if required
354 FmtReplace(ent);
355
356 // Free memory taken by the chain, if required
357 if (stk && freestk > 0) {
358 if (freestk == 1) {
359 sk_X509_pop_free(stk, X509_free);
360 X509_free(pxy);
361 } else if (freestk == 2) {
362 while (sk_X509_pop(stk)) { }
363 sk_X509_free(stk);
364 }
365 }
366
367 // Success or failure?
368 int rc = !ent.vorg ? -1 : 0;
369 if (rc == 0 && gGrps.Num() && !ent.grps) rc = -1;
370
371 // If we have a mapfile object, apply the mapping now.
372 if (m_mapfile) {
373 auto mapfile_rc = m_mapfile->Apply(ent);
374 rc = rc ? rc : mapfile_rc;
375 }
376
377 // Done
378 return rc;
379}
#define EPNAME(x)
#define PRINT(y)
#define SafeFree(x)
if(ec< 0) ec
#define VOMSSPTTAB(a)
Definition XrdVomsFun.cc:79
#define VOMSDBG(m)
Definition XrdVomsFun.cc:59
#define VOMSDBGSUBJ(m, c)
Definition XrdVomsFun.cc:64
virtual XrdCryptoX509data Opaque()
int length() const
const char * c_str() const
char * vorg
Entity's virtual organization(s).
int credslen
Length of the 'creds' data.
char prox[XrdSecPROTOIDSIZE]
Auth extractor used (e.g. xrdvoms).
char * creds
Raw entity credentials or cert.
char * grps
Entity's group name(s).
char * role
Entity's role(s).
char * endorsements
Protocol specific endorsements.

References XrdCryptoX509Chain::Begin(), XrdOucString::c_str(), Voms_x509_in_t::cert, XrdSecEntity::creds, XrdSecEntity::credslen, XrdCryptoX509Chain::End(), XrdSecEntity::endorsements, EPNAME, gCertPEM, gCertRaw, XrdSecEntity::grps, XrdCryptoX509::kCA, XrdOucString::length(), XrdCryptoX509Chain::Next(), XrdCryptoX509::Opaque(), PRINT, XrdSecEntity::prox, XrdSecEntity::role, SafeFree, XrdCryptoX509::type, VOMSDBG, VOMSDBGSUBJ, VOMSSPTTAB, and XrdSecEntity::vorg.

Here is the call graph for this function:

◆ VOMSInit()

int XrdVomsFun::VOMSInit ( const char * cfg)

Definition at line 387 of file XrdVomsFun.cc.

388{
389 // Initialize the relevant parameters from the 'cfg' string.
390 // Return -1 on failure.
391 // Otherwise, the return code indicates the format required by the main function
392 // defined by 'certfmt' below.
393 //
394 // Supported options:
395 // certfmt=raw|pem|x509 Certificate format: [raw]
396 // raw to be used with XrdCrypto tools
397 // pem PEM base64 format (i.e. cert files)
398 // x509 As a STACK_OF(X509)
399 // grpopt=opt What to do with the group names: [1]
400 // opt = sel * 10 + which
401 // with 'sel'
402 // 0 consider all those present
403 // 1 select among those specified by
404 // 'grps' (see below)
405 // and 'which'
406 // 0 take the first one
407 // 1 take the last
408 // 2 take all
409 //
410 // grpopt=useall|usefirst|uselast
411 // useall: all applicable groups
412 // usefirst: only the first applicable on
413 // uselast: only the last applicable on
414 //
415 // grps=grp1[,grp2,...] Group(s) for which the information is
416 // extracted; if specified the gropt
417 // 'sel' is set to 1 regardless of
418 // the setting.
419 // vos=vo1[,vo2,...] VOs to be considered; the first match is taken
420 // grpfmt=<string> Format to use for XrdSecEntity::grps
421 // rolefmt=<string> Format to use for XrdSecEntity::role
422 // vofmt=<string> Format to use for XrdSecEntity::vorg
423 // Recognized place holders in the above
424 // format strings:
425 // <r> role, from the parsing procedure
426 // <g> group
427 // <vo> VO
428 // <an> Full Qualified Attribute Name
429 // For example, rolefmt=<g>,grpfmt=<r> will
430 // inverse the group and role in XrdSecEntity
431 // dbg To force verbose mode
432 //
433 EPNAME("Init");
434 vomsdata vomsInit; // This forces libssl initialization at load time
435
436 XrdOucString oos(cfg);
437
438 XrdOucString fmt, go, grps, voss, gfmt, rfmt, vfmt, sdbg, sdbg2;
439 XrdOucString gr, vo, ss;
440 bool aOK = true;
441
442 if (oos.length() > 0) {
443
444#define NTAG 9
445 XrdOucString *var[NTAG] = { &fmt, &go, &grps, &voss, &gfmt, &rfmt, &vfmt,
446 &sdbg, &sdbg2};
447 const char *tag[] = {"certfmt=", "grpopt=", "grps=", "vos=",
448 "grpfmt=", "rolefmt=", "vofmt=", "dbg", "dbg2"};
449 int jb[NTAG], je[NTAG];
450
451 // Begin of ranges
452 int i = 0, j = -1;
453 for(; i < NTAG; i++) {
454 jb[i] = -1;
455 int j = oos.find(tag[i]);
456 if (j != STR_NPOS) jb[i] = j;
457// DEBUG("["<<i<<"] "<<tag[i]<<" is "<<(j == STR_NPOS?"no":"")<<"spec");
458 }
459 // End of ranges
460 for(i = 0; i < NTAG; i++) {
461 je[i] = -1;
462// DEBUG("-------------");
463 if (jb[i] > -1) {
464 int k = -1;
465 for(j = 0; j < NTAG; j++) {
466 if (j != i) {
467 if (jb[j] > jb[i] && (k < 0 || jb[j] < jb[k])) k = j;
468// DEBUG("jb[" << j << "] = " << jb[j] <<" jb[ "<< i<<"] = "<<jb[i] << " -> k:" << k);
469 }
470 }
471 if (k >= 0) {
472 je[i] = jb[k] - 2;
473 } else {
474 je[i] = oos.length() - 1;
475 }
476 if (i < NTAG-2) {
477 ss.assign(oos, jb[i], je[i]);
478 FmtExtract(*var[i], ss, tag[i]);
479 } else {
480 *var[i] = tag[i];
481 }
482 DEBUG(tag[i] <<"\"" << *var[i] << "\"");
483 }
484// DEBUG("jb["<<i<<"] = "<<jb[i] <<" ---> "<< "je["<<i<<"] = "<<je[i]);
485 }
486
487
488 // Certificate format
489 if (fmt.length() > 0) {
490 if (fmt == "raw") {
491 gCertFmt = gCertRaw;
492 } else if (fmt == "pem") {
493 gCertFmt = gCertPEM;
494 } else if (fmt == "x509") {
495 gCertFmt = gCertX509;
496 }
497 else FATAL("Unsupported cert format - '"<<fmt.c_str()<<"'.")
498 }
499
500 // Group option
501 if (go.length() > 0) {
502 if (go.isdigit()) {
503 int grpopt = go.atoi();
504 int n = grpopt / 10;
505 if (n != gSelAll && n != gSelGrps) {
506 FATAL("grpopt 'select' must be in [0,1] not '"<<n<<"'");
507 }
508 gGrpWhich = grpopt % 10;
509 if (gGrpWhich != gUseFirst && gGrpWhich != gUseLast
510 && gGrpWhich != gUseAll) {
511 FATAL("grpopt 'which' must be in [0,2] not '"<<gGrpWhich<<"'");
512 }
513 } else {
514 if (go == "useall") gGrpWhich = gUseAll;
515 else if (go == "usefirst") gGrpWhich = gUseFirst;
516 else if (go == "uselast") gGrpWhich = gUseLast;
517 else FATAL("Invalid grpopt '"<<go<<"'");
518 }
519 gRequire = "grpopt="; gRequire += go;
520 }
521
522 // Groups selection
523 if (grps.length() > 0) {
524 int from = 0, flag = 1;
525 while ((from = grps.tokenize(gr, from, ',')) != -1) {
526 // Analyse tok
527 VOMSSPTTAB(gr);
528 gGrps.Add(gr.c_str(), &flag);
529 }
530 if (gRequire.length() > 0) gRequire += ";";
531 gRequire += "grps="; gRequire += grps;
532 }
533
534 // VO selection
535 if (voss.length() > 0) {
536 int from = 0, flag = 1;
537 while ((from = voss.tokenize(vo, from, ',')) != -1) {
538 // Analyse tok
539 VOMSSPTTAB(vo);
540 gVOs.Add(vo.c_str(), &flag);
541 }
542 if (gRequire.length() > 0) gRequire += ";";
543 gRequire += "vos="; gRequire += voss;
544 }
545
546 // Output group format string
547 FmtExtract(gGrpFmt, gfmt, "grpfmt=");
548 // Output role format string
549 FmtExtract(gRoleFmt, rfmt, "rolefmt=");
550 // Output vo format string
551 FmtExtract(gVoFmt, vfmt, "vofmt=");
552
553 // Verbose mode
554 if (sdbg == "dbg" && !gDebug) gDebug = 1;
555 if (sdbg2 == "dbg2") gDebug = 2;
556 }
557
558 // Notify
559 const char *cfmt[3] = { "raw", "pem base64", "STACK_OF(X509)" };
560 const char *cgrs[2] = { "all groups", "specified group(s)"};
561 const char *cgrw[3] = { "first", "last", "all" };
562 int n = (gGrps.Num() ? 1 : 0);
563 PRINT("++++++++++++++++++ VOMS plug-in +++++++++++++++++++++++++++++++");
564 PRINT("+++ proxy fmt: "<< cfmt[gCertFmt]);
565 PRINT("+++ group option: "<<cgrw[gGrpWhich]<<" of "<<cgrs[n]);
566 if (grps.length() > 0) {
567 PRINT("+++ group(s): "<< grps);
568 } else {
569 PRINT("+++ group(s): <not specified>");
570 }
571 if (gGrpFmt.length() > 0)
572 PRINT("+++ grps fmt: "<< gGrpFmt);
573 if (gRoleFmt.length() > 0)
574 PRINT("+++ role fmt: "<< gRoleFmt);
575 if (gVoFmt.length() > 0)
576 PRINT("+++ vorg fmt: "<< gVoFmt);
577 if (gVOs.Num() > 0) {PRINT("+++ VO(s): "<< voss);}
578 else {PRINT("+++ VO(s): all");}
579 PRINT("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
580
581 m_mapfile = XrdVomsMapfile::Configure(&gDest);
582 if (m_mapfile == VOMS_MAP_FAILED) {
583 aOK = false;
584 PRINT("VOMS mapfile requested but initialization failed; failing VOMS plugin config.");
585 }
586
587 // Done
588 return (aOK ? gCertFmt : -1);
589}
#define DEBUG(x)
#define STR_NPOS
#define FATAL(msg)
#define NTAG
#define VOMS_MAP_FAILED
void assign(const char *s, int j, int k=-1)
bool isdigit(int from=0, int to=-1)
long atoi(int from=0, int to=-1)
int tokenize(XrdOucString &tok, int from, char del=':')
static XrdVomsMapfile * Configure(XrdSysError *)

References XrdOucString::assign(), XrdOucString::atoi(), XrdOucString::c_str(), XrdVomsMapfile::Configure(), DEBUG, EPNAME, FATAL, XrdOucString::find(), gCertPEM, gCertRaw, gCertX509, XrdOucString::isdigit(), XrdOucString::length(), NTAG, PRINT, STR_NPOS, XrdOucString::tokenize(), VOMS_MAP_FAILED, and VOMSSPTTAB.

Referenced by XrdHttpGetSecXtractor().

Here is the call graph for this function:
Here is the caller graph for this function:

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