58 #define SafeFree(x) { if (x) free(x) ; x = 0; }
66 #define VOMSDBGSUBJ(m, c) \
68 XrdOucString subject; \
69 NameOneLine(X509_get_subject_name(c), subject); \
70 PRINT(m << subject); \
73 #define VOMSREPLACE(a, f, e) \
74 if (a.length() > 0) { \
75 f.replace("<g>", e.grps); \
76 f.replace("<r>", e.role); \
77 f.replace("<vo>", e.vorg); \
78 f.replace("<an>", e.endorsements); \
81 #define VOMSSPTTAB(a) \
82 if (a.length() > 0) { \
84 while ((sp = a.find(' ', sp+1)) != STR_NPOS) { a[sp] = '\t'; } \
87 #define FATAL(x) {std::cerr <<"VomsFun: "<<x<<std::endl; aOK = false;}
91 static const int gSelAll = 0;
92 static const int gSelGrps = 1;
93 static const short gUseFirst = 0;
94 static const short gUseLast = 1;
95 static const short gUseAll = 2;
103 : gGrpWhich(gUseAll), gDebug(0), gDest(erp),
104 gLogger(erp.logger())
106 #ifdef HAVE_XRDCRYPTO
119 void XrdVomsFun::NameOneLine(X509_NAME *nm,
XrdOucString &s)
121 BIO *mbio = BIO_new(BIO_s_mem());
122 X509_NAME_print_ex(mbio, nm, 0, XN_FLAG_COMPAT);
124 long len = BIO_get_mem_data(mbio, &data);
148 if (gf.length() > 0) {
150 ent.
grps = strdup(gf.c_str());
152 if (rf.length() > 0) {
154 ent.
role = strdup(rf.c_str());
156 if (vf.length() > 0) {
158 ent.
vorg = strdup(vf.c_str());
172 int igf = in.
find(tag);
174 int from = igf + strlen(tag);
175 if (in[from] ==
'"') {
199 STACK_OF(X509) *stk = 0;
204 strcpy(ent.
prox,
"xrdvoms");
207 #ifdef HAVE_XRDCRYPTO
213 PRINT(
"ERROR: no proxy chain found!");
219 PRINT(
"ERROR: no proxy certificate in chain!");
222 pxy = (X509 *) xp->
Opaque();
226 stk =sk_X509_new_null();
229 if (xxp == c->
End())
break;
232 sk_X509_push(stk, (X509 *) xxp->
Opaque());
240 PRINT(
"ERROR: compiled without support for RAW format! Re-run with 'certfmt=pem'");
248 BIO *bmem = BIO_new(BIO_s_mem());
250 PRINT(
"unable to create BIO for memory operations");
255 int nw = BIO_write(bmem, (
const void *)(ent.
creds), ent.
credslen);
257 PRINT(
"problems writing data to memory BIO (nw: "<<nw<<
")");
263 if (!(pxy = PEM_read_bio_X509(bmem,0,0,0))) {
264 PRINT(
"unable to read certificate to memory BIO");
272 stk =sk_X509_new_null();
273 while ((xc = PEM_read_bio_X509(bmem,0,0,0))) {
275 sk_X509_push(stk, xc);
287 stk = voms_in->chain;
292 XrdOucString endor, grps, role, vo, xendor, xgrps, xrole, xvo;
293 if (v.Retrieve(pxy, stk, RECURSE_CHAIN)) {
294 VOMSDBG(
"retrieval successful");
296 std::vector<voms>::iterator i = v.data.begin();
297 for ( ; i != v.data.end(); i++) {
298 VOMSDBG(
"found VO: " << (*i).voname);
301 if (gVOs.
Num() > 0 && !gVOs.
Find((*i).voname.c_str()))
continue;
303 if (gGrpWhich < gUseAll) vo = xvo;
304 std::vector<data> dat = (*i).std;
305 std::vector<data>::iterator idat = dat.begin();
307 std::vector<std::string> fqa = (*i).fqan;
308 std::vector<std::string>::iterator ifqa = fqa.begin();
309 for (; idat != dat.end(); idat++, ifqa++) {
310 VOMSDBG(
" ---> group: '"<<(*idat).group<<
"', role: '"<<(*idat).role<<
"', cap: '" <<(*idat).cap<<
"'");
311 VOMSDBG(
" ---> fqan: '"<<(*ifqa)<<
"'");
316 if (gGrps.
Num() && !gGrps.
Find((*idat).group.c_str()))
319 if (gGrpWhich == gUseAll) {
320 if (vo.
length() > 0) vo +=
" ";
321 vo += (*i).voname.
c_str();
322 if (grps.
length() > 0) grps +=
" ";
323 grps += (*idat).group.
c_str();
324 if (role.
length() > 0) role +=
" ";
325 role += (*idat).role.
c_str();
326 if (endor.
length() > 0) endor +=
",";
327 endor += (*ifqa).
c_str();
329 grps = (*idat).group.
c_str();
330 role = (*idat).role.
c_str();
331 endor = (*ifqa).
c_str();
335 if (gGrpWhich == gUseFirst && grps.
length() > 0)
break;
356 }
else if (extfound) {
357 VOMSDBG(
"VOMS extensions do not match required criteria ("<<gRequire<<
")");
360 PRINT(
"retrieval FAILED: "<< v.ErrorMessage());
371 if (stk && freestk > 0) {
373 sk_X509_pop_free(stk, X509_free);
375 }
else if (freestk == 2) {
376 while (sk_X509_pop(stk)) { }
382 int rc = !ent.
vorg ? -1 : 0;
383 if (rc == 0 && gGrps.
Num() && !ent.
grps) rc = -1;
387 auto mapfile_rc = m_mapfile->
Apply(ent);
388 rc = rc ? rc : mapfile_rc;
452 XrdOucString fmt, go, grps, voss, gfmt, rfmt, vfmt, sdbg, sdbg2;
461 const char *tag[] = {
"certfmt=",
"grpopt=",
"grps=",
"vos=",
462 "grpfmt=",
"rolefmt=",
"vofmt=",
"dbg",
"dbg2"};
467 for(; i <
NTAG; i++) {
469 int j = oos.
find(tag[i]);
474 for(i = 0; i <
NTAG; i++) {
479 for(j = 0; j <
NTAG; j++) {
481 if (jb[j] > jb[i] && (k < 0 || jb[j] < jb[k])) k = j;
491 ss.
assign(oos, jb[i], je[i]);
492 FmtExtract(*var[i], ss, tag[i]);
496 DEBUG(tag[i] <<
"\"" << *var[i] <<
"\"");
505 #ifdef HAVE_XRDCRYPTO
511 PRINT(
"VomsFun: support for RAW format not available: forcing PEM");
514 }
else if (fmt ==
"pem") {
516 }
else if (fmt ==
"x509") {
519 else FATAL(
"Unsupported cert format - '"<<fmt.
c_str()<<
"'.")
525 int grpopt = go.
atoi();
527 if (n != gSelAll && n != gSelGrps) {
528 FATAL(
"grpopt 'select' must be in [0,1] not '"<<n<<
"'");
530 gGrpWhich = grpopt % 10;
531 if (gGrpWhich != gUseFirst && gGrpWhich != gUseLast
532 && gGrpWhich != gUseAll) {
533 FATAL(
"grpopt 'which' must be in [0,2] not '"<<gGrpWhich<<
"'");
536 if (go ==
"useall") gGrpWhich = gUseAll;
537 else if (go ==
"usefirst") gGrpWhich = gUseFirst;
538 else if (go ==
"uselast") gGrpWhich = gUseLast;
539 else FATAL(
"Invalid grpopt '"<<go<<
"'");
541 gRequire =
"grpopt="; gRequire += go;
546 int from = 0, flag = 1;
547 while ((from = grps.
tokenize(gr, from,
',')) != -1) {
552 if (gRequire.
length() > 0) gRequire +=
";";
553 gRequire +=
"grps="; gRequire += grps;
558 int from = 0, flag = 1;
559 while ((from = voss.
tokenize(vo, from,
',')) != -1) {
564 if (gRequire.
length() > 0) gRequire +=
";";
565 gRequire +=
"vos="; gRequire += voss;
569 FmtExtract(gGrpFmt, gfmt,
"grpfmt=");
571 FmtExtract(gRoleFmt, rfmt,
"rolefmt=");
573 FmtExtract(gVoFmt, vfmt,
"vofmt=");
576 if (sdbg ==
"dbg" && !gDebug) gDebug = 1;
577 if (sdbg2 ==
"dbg2") gDebug = 2;
581 const char *cfmt[3] = {
"raw",
"pem base64",
"STACK_OF(X509)" };
582 const char *cgrs[2] = {
"all groups",
"specified group(s)"};
583 const char *cgrw[3] = {
"first",
"last",
"all" };
584 int n = (gGrps.
Num() ? 1 : 0);
585 PRINT(
"++++++++++++++++++ VOMS plug-in +++++++++++++++++++++++++++++++");
586 PRINT(
"+++ proxy fmt: "<< cfmt[gCertFmt]);
587 PRINT(
"+++ group option: "<<cgrw[gGrpWhich]<<
" of "<<cgrs[n]);
589 PRINT(
"+++ group(s): "<< grps);
591 PRINT(
"+++ group(s): <not specified>");
594 PRINT(
"+++ grps fmt: "<< gGrpFmt);
595 if (gRoleFmt.
length() > 0)
596 PRINT(
"+++ role fmt: "<< gRoleFmt);
598 PRINT(
"+++ vorg fmt: "<< gVoFmt);
599 if (gVOs.
Num() > 0) {
PRINT(
"+++ VO(s): "<< voss);}
600 else {
PRINT(
"+++ VO(s): all");}
601 PRINT(
"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
606 PRINT(
"VOMS mapfile requested but initialization failed; failing VOMS plugin config.");
610 return (aOK ? gCertFmt : -1);
#define VOMSREPLACE(a, f, e)
#define VOMSDBGSUBJ(m, c)
XrdCryptoX509 * End() const
virtual XrdCryptoX509data Opaque()
T * Add(const char *KeyVal, T *KeyData, const int LifeTime=0, XrdOucHash_Options opt=Hash_default)
T * Find(const char *KeyVal, time_t *KeyTime=0)
void insert(const int i, int start=-1)
const char * c_str() const
void assign(const char *s, int j, int k=-1)
int erasefromend(int sz=0)
int erase(int start=0, int size=0)
int replace(const char *s1, const char *s2, int from=0, int to=-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=':')
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.
XrdVomsFun(XrdSysError &erp)
int VOMSInit(const char *cfg)
int VOMSFun(XrdSecEntity &ent)
static XrdVomsMapfile * Configure(XrdSysError *)
int Apply(XrdSecEntity &)