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

enum XrdVomsFun::CertFormat

Enumerator
gCertRaw |
gCertPEM |
gCertX509 |

Definition at line 49 of file XrdVomsFun.hh.

{gCertRaw = 0,
gCertPEM = 1,
gCertX509 = 2
};
XrdVomsFun::gCertX509
@ gCertX509
Definition XrdVomsFun.hh:52
XrdVomsFun::gCertPEM
@ gCertPEM
Definition XrdVomsFun.hh:51
XrdVomsFun::gCertRaw
@ gCertRaw
Definition XrdVomsFun.hh:50

## Constructor & Destructor Documentation

## XrdVomsFun()

XrdVomsFun::XrdVomsFun | ( | XrdSysError & | erp | ) |

Definition at line 102 of file XrdVomsFun.cc.

: gGrpWhich(gUseAll), gDebug(0), gDest(erp),
gLogger(erp.logger())
{
#ifdef HAVE_XRDCRYPTO
gCertFmt = gCertRaw; // certfmt:raw|pem|x509 [raw]
#else
gCertFmt = gCertPEM; // certfmt:pem|x509 [pem]
#endif
};
XrdSysError::logger
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition XrdSysError.hh:141

References gCertPEM, and gCertRaw.

## ~XrdVomsFun()

XrdVomsFun::~XrdVomsFun | ( |  | ) |

inline

Definition at line 63 of file XrdVomsFun.hh.

{} // 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.

{gCertFmt = n;}

Referenced by XrdHttpGetSecXtractor().

Here is the caller graph for this function:

## VOMSFun()

int XrdVomsFun::VOMSFun | ( | XrdSecEntity & | ent | ) |

Definition at line 191 of file XrdVomsFun.cc.

{
// Implementation of XrdSecgsiAuthzFun extracting the information from the
// proxy chain in entity.creds
EPNAME("Fun");
vomsdata v;
X509 *pxy = 0;
STACK_OF(X509) *stk = 0;
int freestk = 1;
// Set extractor name in the XrdSecEntity object
//
strcpy(ent.prox, "xrdvoms");
if (gCertFmt == gCertRaw) {
#ifdef HAVE_XRDCRYPTO
//
// RAW format
//
XrdCryptoX509Chain *c = (XrdCryptoX509Chain *) ent.creds;
if (!c) {
PRINT("ERROR: no proxy chain found!");
return -1;
}
XrdCryptoX509 *xp = c->End();
if (!xp) {
PRINT("ERROR: no proxy certificate in chain!");
return -1;
}
pxy = (X509 *) xp->Opaque();
VOMSDBGSUBJ("proxy: ", pxy)
freestk = 2;
stk =sk_X509_new_null();
XrdCryptoX509 *xxp = c->Begin();
while (xxp) {
if (xxp == c->End()) break;
if (xxp->type != XrdCryptoX509::kCA) {
VOMSDBGSUBJ("adding cert: ", (X509 *) xxp->Opaque())
sk_X509_push(stk, (X509 *) xxp->Opaque());
}
xxp = c->Next();
}
#else
//
// Do not have support for RAW format
//
PRINT("ERROR: compiled without support for RAW format! Re-run with 'certfmt=pem'");
return -1;
#endif
} else if (gCertFmt == gCertPEM) {
//
// PEM format
//
// Create a bio_mem to store the certificates
BIO *bmem = BIO_new(BIO_s_mem());
if (!bmem) {
PRINT("unable to create BIO for memory operations");
return -1;
}
// Write data to BIO
int nw = BIO_write(bmem, (const void *)(ent.creds), ent.credslen);
if (nw != ent.credslen) {
PRINT("problems writing data to memory BIO (nw: "<<nw<<")");
BIO_free(bmem);
return -1;
}
// Get certificate from BIO
if (!(pxy = PEM_read_bio_X509(bmem,0,0,0))) {
PRINT("unable to read certificate to memory BIO");
BIO_free(bmem);
return -1;
}
VOMSDBGSUBJ("proxy: ", pxy)
//
// The chain now
X509 *xc = 0;
stk =sk_X509_new_null();
while ((xc = PEM_read_bio_X509(bmem,0,0,0))) {
VOMSDBGSUBJ("adding cert: ", xc)
sk_X509_push(stk, xc);
}
//
// Free BIO
BIO_free(bmem);
} else {
//
// STACK_OF(X509) format
//
Voms_x509_in_t *voms_in = (Voms_x509_in_t *) ent.creds;
pxy = voms_in->cert;
stk = voms_in->chain;
freestk = 0;
}
bool extfound = 0;
XrdOucString endor, grps, role, vo, xendor, xgrps, xrole, xvo;
if (v.Retrieve(pxy, stk, RECURSE_CHAIN)) {
VOMSDBG("retrieval successful");
extfound = 1;
std::vector<voms>::iterator i = v.data.begin();
for ( ; i != v.data.end(); i++) {
VOMSDBG("found VO: " << (*i).voname);
xvo = (*i).voname.c_str(); VOMSSPTTAB(xvo);
// Filter the VO? (*i) is voms
if (gVOs.Num() > 0 && !gVOs.Find((*i).voname.c_str())) continue;
// Save VO name (in tuple mode this is done later, in the loop over groups)
if (gGrpWhich < gUseAll) vo = xvo;
std::vector<data> dat = (*i).std;
std::vector<data>::iterator idat = dat.begin();
// Same size as std::vector<data> by construction (same information in compact form)
std::vector<std::string> fqa = (*i).fqan;
std::vector<std::string>::iterator ifqa = fqa.begin();
for (; idat != dat.end(); idat++, ifqa++) {
VOMSDBG(" ---> group: '"<<(*idat).group<<"', role: '"<<(*idat).role<<"', cap: '" <<(*idat).cap<<"'");
VOMSDBG(" ---> fqan: '"<<(*ifqa)<<"'");
xgrps = (*idat).group.c_str(); VOMSSPTTAB(xgrps);
xrole = (*idat).role.c_str(); VOMSSPTTAB(xrole);
xendor = (*ifqa).c_str(); VOMSSPTTAB(xendor);
bool fillgrp = true;
if (gGrps.Num() && !gGrps.Find((*idat).group.c_str()))
fillgrp = false;
if (fillgrp) {
if (gGrpWhich == gUseAll) {
if (vo.length() > 0) vo += " ";
vo += (*i).voname.c_str();
if (grps.length() > 0) grps += " ";
grps += (*idat).group.c_str();
if (role.length() > 0) role += " ";
role += (*idat).role.c_str();
if (endor.length() > 0) endor += ",";
endor += (*ifqa).c_str();
} else {
grps = (*idat).group.c_str();
role = (*idat).role.c_str();
endor = (*ifqa).c_str();
}
}
// If we are asked to take the first we break
if (gGrpWhich == gUseFirst && grps.length() > 0) break;
}
if (grps.length() <= 0) {
// Reset all the fields
role = "";
vo = "";
endor = "";
}
}
// Save the information found
SafeFree(ent.vorg);
SafeFree(ent.grps);
SafeFree(ent.role);
SafeFree(ent.endorsements);
if (vo.length() > 0) {
ent.vorg = strdup(vo.c_str());
// Save the groups
if (grps.length() > 0) ent.grps = strdup(grps.c_str());
if (role.length() > 0) ent.role = strdup(role.c_str());
// Save the whole string in endorsements
if (endor.length() > 0) ent.endorsements = strdup(endor.c_str());
} else if (extfound) {
VOMSDBG("VOMS extensions do not match required criteria ("<<gRequire<<")");
}
} else {
PRINT("retrieval FAILED: "<< v.ErrorMessage());
}
// Fix spaces in XrdSecEntity::name
// char *sp = 0;
// while ((sp = strchr(ent.name, ' '))) { *sp = '\t'; }
// Adjust the output format, if required
FmtReplace(ent);
// Free memory taken by the chain, if required
if (stk && freestk > 0) {
if (freestk == 1) {
sk_X509_pop_free(stk, X509_free);
X509_free(pxy);
} else if (freestk == 2) {
while (sk_X509_pop(stk)) { }
sk_X509_free(stk);
}
}
// Success or failure?
int rc = !ent.vorg ? -1 : 0;
if (rc == 0 && gGrps.Num() && !ent.grps) rc = -1;
// If we have a mapfile object, apply the mapping now.
if (m_mapfile) {
auto mapfile_rc = m_mapfile->Apply(ent);
rc = rc ? rc : mapfile_rc;
}
// Done
return rc;
}
EPNAME
#define EPNAME(x)
Definition XrdBwmTrace.hh:56
PRINT
#define PRINT(y)
Definition XrdCryptosslTrace.hh:39
SafeFree
#define SafeFree(x)
Definition XrdSecProtocolgsi.hh:156
VOMSSPTTAB
#define VOMSSPTTAB(a)
Definition XrdVomsFun.cc:81
VOMSDBG
#define VOMSDBG(m)
Definition XrdVomsFun.cc:61
VOMSDBGSUBJ
#define VOMSDBGSUBJ(m, c)
Definition XrdVomsFun.cc:66
XrdCryptoX509::kCA
@ kCA
Definition XrdCryptoX509.hh:55
XrdCryptoX509::Opaque
virtual XrdCryptoX509data Opaque()
Definition XrdCryptoX509.cc:181
XrdCryptoX509::type
EX509Type type
Definition XrdCryptoX509.hh:56
XrdOucString::length
int length() const
Definition XrdOucString.hh:279
XrdOucString::c_str
const char * c_str() const
Definition XrdOucString.hh:278
XrdSecEntity::vorg
char * vorg
Entity's virtual organization(s).
Definition XrdSecEntity.hh:71
XrdSecEntity::credslen
int credslen
Length of the 'creds' data.
Definition XrdSecEntity.hh:78
XrdSecEntity::prox
char prox[XrdSecPROTOIDSIZE]
Auth extractor used (e.g. xrdvoms).
Definition XrdSecEntity.hh:68
XrdSecEntity::creds
char * creds
Raw entity credentials or cert.
Definition XrdSecEntity.hh:77
XrdSecEntity::grps
char * grps
Entity's group name(s).
Definition XrdSecEntity.hh:73
XrdSecEntity::role
char * role
Entity's role(s).
Definition XrdSecEntity.hh:72
XrdSecEntity::endorsements
char * endorsements
Protocol specific endorsements.
Definition XrdSecEntity.hh:75

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 401 of file XrdVomsFun.cc.

{
// Initialize the relevant parameters from the 'cfg' string.
// Return -1 on failure.
// Otherwise, the return code indicates the format required by the main function
// defined by 'certfmt' below.
//
// Supported options:
// certfmt=raw|pem|x509 Certificate format: [raw]
// raw to be used with XrdCrypto tools
// pem PEM base64 format (i.e. cert files)
// x509 As a STACK_OF(X509)
// grpopt=opt What to do with the group names: [1]
// opt = sel * 10 + which
// with 'sel'
// 0 consider all those present
// 1 select among those specified by
// 'grps' (see below)
// and 'which'
// 0 take the first one
// 1 take the last
// 2 take all
//
// grpopt=useall|usefirst|uselast
// useall: all applicable groups
// usefirst: only the first applicable on
// uselast: only the last applicable on
//
// grps=grp1[,grp2,...] Group(s) for which the information is
// extracted; if specified the gropt
// 'sel' is set to 1 regardless of
// the setting.
// vos=vo1[,vo2,...] VOs to be considered; the first match is taken
// grpfmt=<string> Format to use for XrdSecEntity::grps
// rolefmt=<string> Format to use for XrdSecEntity::role
// vofmt=<string> Format to use for XrdSecEntity::vorg
// Recognized place holders in the above
// format strings:
// <r> role, from the parsing procedure
// <g> group
// <vo> VO
// <an> Full Qualified Attribute Name
// For example, rolefmt=<g>,grpfmt=<r> will
// inverse the group and role in XrdSecEntity
// dbg To force verbose mode
//
EPNAME("Init");
vomsdata vomsInit; // This forces libssl initialization at load time
XrdOucString oos(cfg);
XrdOucString fmt, go, grps, voss, gfmt, rfmt, vfmt, sdbg, sdbg2;
XrdOucString gr, vo, ss;
bool aOK = true;
if (oos.length() > 0) {
#define NTAG 9
XrdOucString *var[NTAG] = { &fmt, &go, &grps, &voss, &gfmt, &rfmt, &vfmt,
&sdbg, &sdbg2};
const char *tag[] = {"certfmt=", "grpopt=", "grps=", "vos=",
"grpfmt=", "rolefmt=", "vofmt=", "dbg", "dbg2"};
int jb[NTAG], je[NTAG];
// Begin of ranges
int i = 0, j = -1;
for(; i < NTAG; i++) {
jb[i] = -1;
int j = oos.find(tag[i]);
if (j != STR_NPOS) jb[i] = j;
// DEBUG("["<<i<<"] "<<tag[i]<<" is "<<(j == STR_NPOS?"no":"")<<"spec");
}
// End of ranges
for(i = 0; i < NTAG; i++) {
je[i] = -1;
// DEBUG("-------------");
if (jb[i] > -1) {
int k = -1;
for(j = 0; j < NTAG; j++) {
if (j != i) {
if (jb[j] > jb[i] && (k < 0 || jb[j] < jb[k])) k = j;
// DEBUG("jb[" << j << "] = " << jb[j] <<" jb[ "<< i<<"] = "<<jb[i] << " -> k:" << k);
}
}
if (k >= 0) {
je[i] = jb[k] - 2;
} else {
je[i] = oos.length() - 1;
}
if (i < NTAG-2) {
ss.assign(oos, jb[i], je[i]);
FmtExtract(*var[i], ss, tag[i]);
} else {
*var[i] = tag[i];
}
DEBUG(tag[i] <<"\"" << *var[i] << "\"");
}
// DEBUG("jb["<<i<<"] = "<<jb[i] <<" ---> "<< "je["<<i<<"] = "<<je[i]);
}
// Certificate format
if (fmt.length() > 0) {
if (fmt == "raw") {
#ifdef HAVE_XRDCRYPTO
gCertFmt = gCertRaw;
#else
//
// Do not have support for RAW format
//
PRINT("VomsFun: support for RAW format not available: forcing PEM");
gCertFmt = gCertPEM;
#endif
} else if (fmt == "pem") {
gCertFmt = gCertPEM;
} else if (fmt == "x509") {
gCertFmt = gCertX509;
}
else FATAL("Unsupported cert format - '"<<fmt.c_str()<<"'.")
}
// Group option
if (go.length() > 0) {
if (go.isdigit()) {
int grpopt = go.atoi();
int n = grpopt / 10;
if (n != gSelAll && n != gSelGrps) {
FATAL("grpopt 'select' must be in [0,1] not '"<<n<<"'");
}
gGrpWhich = grpopt % 10;
if (gGrpWhich != gUseFirst && gGrpWhich != gUseLast
&& gGrpWhich != gUseAll) {
FATAL("grpopt 'which' must be in [0,2] not '"<<gGrpWhich<<"'");
}
} else {
if (go == "useall") gGrpWhich = gUseAll;
else if (go == "usefirst") gGrpWhich = gUseFirst;
else if (go == "uselast") gGrpWhich = gUseLast;
else FATAL("Invalid grpopt '"<<go<<"'");
}
gRequire = "grpopt="; gRequire += go;
}
// Groups selection
if (grps.length() > 0) {
int from = 0, flag = 1;
while ((from = grps.tokenize(gr, from, ',')) != -1) {
// Analyse tok
VOMSSPTTAB(gr);
gGrps.Add(gr.c_str(), &flag);
}
if (gRequire.length() > 0) gRequire += ";";
gRequire += "grps="; gRequire += grps;
}
// VO selection
if (voss.length() > 0) {
int from = 0, flag = 1;
while ((from = voss.tokenize(vo, from, ',')) != -1) {
// Analyse tok
VOMSSPTTAB(vo);
gVOs.Add(vo.c_str(), &flag);
}
if (gRequire.length() > 0) gRequire += ";";
gRequire += "vos="; gRequire += voss;
}
// Output group format string
FmtExtract(gGrpFmt, gfmt, "grpfmt=");
// Output role format string
FmtExtract(gRoleFmt, rfmt, "rolefmt=");
// Output vo format string
FmtExtract(gVoFmt, vfmt, "vofmt=");
// Verbose mode
if (sdbg == "dbg" && !gDebug) gDebug = 1;
if (sdbg2 == "dbg2") gDebug = 2;
}
// Notify
const char *cfmt[3] = { "raw", "pem base64", "STACK_OF(X509)" };
const char *cgrs[2] = { "all groups", "specified group(s)"};
const char *cgrw[3] = { "first", "last", "all" };
int n = (gGrps.Num() ? 1 : 0);
PRINT("++++++++++++++++++ VOMS plug-in +++++++++++++++++++++++++++++++");
PRINT("+++ proxy fmt: "<< cfmt[gCertFmt]);
PRINT("+++ group option: "<<cgrw[gGrpWhich]<<" of "<<cgrs[n]);
if (grps.length() > 0) {
PRINT("+++ group(s): "<< grps);
} else {
PRINT("+++ group(s): <not specified>");
}
if (gGrpFmt.length() > 0)
PRINT("+++ grps fmt: "<< gGrpFmt);
if (gRoleFmt.length() > 0)
PRINT("+++ role fmt: "<< gRoleFmt);
if (gVoFmt.length() > 0)
PRINT("+++ vorg fmt: "<< gVoFmt);
if (gVOs.Num() > 0) {PRINT("+++ VO(s): "<< voss);}
else {PRINT("+++ VO(s): all");}
PRINT("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
m_mapfile = XrdVomsMapfile::Configure(&gDest);
if (m_mapfile == VOMS_MAP_FAILED) {
aOK = false;
PRINT("VOMS mapfile requested but initialization failed; failing VOMS plugin config.");
}
// Done
return (aOK ? gCertFmt : -1);
}
DEBUG
#define DEBUG(x)
Definition XrdBwmTrace.hh:54
STR_NPOS
#define STR_NPOS
Definition XrdOucString.hh:250
FATAL
#define FATAL(msg)
Definition XrdTlsContext.cc:576
NTAG
#define NTAG
VOMS_MAP_FAILED
#define VOMS_MAP_FAILED
Definition XrdVomsMapfile.hh:35
XrdOucString::assign
void assign(const char *s, int j, int k=-1)
Definition XrdOucString.cc:511
XrdOucString::isdigit
bool isdigit(int from=0, int to=-1)
Definition XrdOucString.cc:1270
XrdOucString::atoi
long atoi(int from=0, int to=-1)
Definition XrdOucString.cc:1295
XrdOucString::tokenize
int tokenize(XrdOucString &tok, int from, char del=':')
Definition XrdOucString.cc:1220
XrdVomsMapfile::Configure
static XrdVomsMapfile * Configure(XrdSysError *)
Definition XrdVomsMapfile.cc:308

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:

- XrdVomsFun.hh
- XrdVomsFun.cc