XRootD
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)
Definition: XrdSysError.hh:175

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  //
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);
334  SafeFree(ent.endorsements);
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)
Definition: XrdBwmTrace.hh:56
#define PRINT(y)
if(Avsz)
#define VOMSSPTTAB(a)
Definition: XrdVomsFun.cc:79
#define SafeFree(x)
Definition: XrdVomsFun.cc:56
#define VOMSDBG(m)
Definition: XrdVomsFun.cc:59
#define VOMSDBGSUBJ(m, c)
Definition: XrdVomsFun.cc:64
XrdCryptoX509 * Begin()
XrdCryptoX509 * End() const
virtual XrdCryptoX509data Opaque()
EX509Type type
T * Find(const char *KeyVal, time_t *KeyTime=0)
Definition: XrdOucHash.icc:160
const char * c_str() const
int length() const
char * vorg
Entity's virtual organization(s)
Definition: XrdSecEntity.hh:71
int credslen
Length of the 'creds' data.
Definition: XrdSecEntity.hh:78
char prox[XrdSecPROTOIDSIZE]
Auth extractor used (e.g. xrdvoms)
Definition: XrdSecEntity.hh:68
char * creds
Raw entity credentials or cert.
Definition: XrdSecEntity.hh:77
char * grps
Entity's group name(s)
Definition: XrdSecEntity.hh:73
char * role
Entity's role(s)
Definition: XrdSecEntity.hh:72
char * endorsements
Protocol specific endorsements.
Definition: XrdSecEntity.hh:75
int Apply(XrdSecEntity &)
X509 * cert
Definition: XrdVoms.hh:40

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

Referenced by XrdVomsHttp::GetSecData().

+ Here is the call graph for this function:
+ Here is the caller 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)
Definition: XrdBwmTrace.hh:54
#define STR_NPOS
#define NTAG
#define FATAL(x)
Definition: XrdVomsFun.cc:85
#define VOMS_MAP_FAILED
T * Add(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
Definition: XrdOucHash.icc:61
void assign(const char *s, int j, int k=-1)
int find(const char c, int start=0, bool forward=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 XrdOucHash< T >::Add(), XrdOucString::assign(), XrdOucString::atoi(), XrdOucString::c_str(), XrdVomsMapfile::Configure(), DEBUG, EPNAME, FATAL, XrdOucString::find(), gCertPEM, gCertRaw, gCertX509, XrdOucString::isdigit(), XrdOucString::length(), NTAG, XrdOucHash< T >::Num(), 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: