56#define SafeFree(x) { if (x) free(x) ; x = 0; }
64#define VOMSDBGSUBJ(m, c) \
66 XrdOucString subject; \
67 NameOneLine(X509_get_subject_name(c), subject); \
68 PRINT(m << subject); \
71#define VOMSREPLACE(a, f, e) \
72 if (a.length() > 0) { \
73 f.replace("<g>", e.grps); \
74 f.replace("<r>", e.role); \
75 f.replace("<vo>", e.vorg); \
76 f.replace("<an>", e.endorsements); \
79#define VOMSSPTTAB(a) \
80 if (a.length() > 0) { \
82 while ((sp = a.find(' ', sp+1)) != STR_NPOS) { a[sp] = '\t'; } \
85#define FATAL(x) {std::cerr <<"VomsFun: "<<x<<std::endl; aOK = false;}
89static const int gSelAll = 0;
90static const int gSelGrps = 1;
91static const short gUseFirst = 0;
92static const short gUseLast = 1;
93static const short gUseAll = 2;
101 : gGrpWhich(gUseAll), gDebug(0), gDest(erp),
102 gLogger(erp.logger())
113void XrdVomsFun::NameOneLine(X509_NAME *nm,
XrdOucString &s)
115 BIO *mbio = BIO_new(BIO_s_mem());
116 X509_NAME_print_ex(mbio, nm, 0, XN_FLAG_COMPAT);
118 long len = BIO_get_mem_data(mbio, &data);
136 XrdOucString gf(gGrpFmt), rf(gRoleFmt), vf(gVoFmt);
142 if (gf.length() > 0) {
144 ent.
grps = strdup(gf.c_str());
146 if (rf.length() > 0) {
148 ent.
role = strdup(rf.c_str());
150 if (vf.length() > 0) {
152 ent.
vorg = strdup(vf.c_str());
166 int igf = in.
find(tag);
168 int from = igf + strlen(tag);
169 if (in[from] ==
'"') {
193 STACK_OF(X509) *stk = 0;
198 strcpy(ent.
prox,
"xrdvoms");
206 PRINT(
"ERROR: no proxy chain found!");
212 PRINT(
"ERROR: no proxy certificate in chain!");
215 pxy = (X509 *) xp->
Opaque();
219 stk =sk_X509_new_null();
222 if (xxp == c->
End())
break;
225 sk_X509_push(stk, (X509 *) xxp->
Opaque());
234 BIO *bmem = BIO_new(BIO_s_mem());
236 PRINT(
"unable to create BIO for memory operations");
241 int nw = BIO_write(bmem, (
const void *)(ent.
creds), ent.
credslen);
243 PRINT(
"problems writing data to memory BIO (nw: "<<nw<<
")");
249 if (!(pxy = PEM_read_bio_X509(bmem,0,0,0))) {
250 PRINT(
"unable to read certificate to memory BIO");
258 stk =sk_X509_new_null();
259 while ((xc = PEM_read_bio_X509(bmem,0,0,0))) {
261 sk_X509_push(stk, xc);
273 stk = voms_in->chain;
278 XrdOucString endor, grps, role, vo, xendor, xgrps, xrole, xvo;
279 if (v.Retrieve(pxy, stk, RECURSE_CHAIN)) {
280 VOMSDBG(
"retrieval successful");
282 std::vector<voms>::iterator i = v.data.begin();
283 for ( ; i != v.data.end(); i++) {
284 VOMSDBG(
"found VO: " << (*i).voname);
287 if (gVOs.Num() > 0 && !gVOs.Find((*i).voname.c_str()))
continue;
289 if (gGrpWhich < gUseAll) vo = xvo;
290 std::vector<data> dat = (*i).std;
291 std::vector<data>::iterator idat = dat.begin();
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)<<
"'");
302 if (gGrps.Num() && !gGrps.Find((*idat).group.c_str()))
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();
315 grps = (*idat).group.
c_str();
316 role = (*idat).role.
c_str();
317 endor = (*ifqa).
c_str();
321 if (gGrpWhich == gUseFirst && grps.
length() > 0)
break;
342 }
else if (extfound) {
343 VOMSDBG(
"VOMS extensions do not match required criteria ("<<gRequire<<
")");
346 PRINT(
"retrieval FAILED: "<< v.ErrorMessage());
357 if (stk && freestk > 0) {
359 sk_X509_pop_free(stk, X509_free);
361 }
else if (freestk == 2) {
362 while (sk_X509_pop(stk)) { }
368 int rc = !ent.
vorg ? -1 : 0;
369 if (rc == 0 && gGrps.Num() && !ent.
grps) rc = -1;
373 auto mapfile_rc = m_mapfile->Apply(ent);
374 rc = rc ? rc : mapfile_rc;
438 XrdOucString fmt, go, grps, voss, gfmt, rfmt, vfmt, sdbg, sdbg2;
447 const char *tag[] = {
"certfmt=",
"grpopt=",
"grps=",
"vos=",
448 "grpfmt=",
"rolefmt=",
"vofmt=",
"dbg",
"dbg2"};
453 for(; i <
NTAG; i++) {
455 int j = oos.
find(tag[i]);
460 for(i = 0; i <
NTAG; i++) {
465 for(j = 0; j <
NTAG; j++) {
467 if (jb[j] > jb[i] && (k < 0 || jb[j] < jb[k])) k = j;
477 ss.
assign(oos, jb[i], je[i]);
478 FmtExtract(*var[i], ss, tag[i]);
482 DEBUG(tag[i] <<
"\"" << *var[i] <<
"\"");
492 }
else if (fmt ==
"pem") {
494 }
else if (fmt ==
"x509") {
497 else FATAL(
"Unsupported cert format - '"<<fmt.
c_str()<<
"'.")
503 int grpopt = go.
atoi();
505 if (n != gSelAll && n != gSelGrps) {
506 FATAL(
"grpopt 'select' must be in [0,1] not '"<<n<<
"'");
508 gGrpWhich = grpopt % 10;
509 if (gGrpWhich != gUseFirst && gGrpWhich != gUseLast
510 && gGrpWhich != gUseAll) {
511 FATAL(
"grpopt 'which' must be in [0,2] not '"<<gGrpWhich<<
"'");
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<<
"'");
519 gRequire =
"grpopt="; gRequire += go;
524 int from = 0, flag = 1;
525 while ((from = grps.
tokenize(gr, from,
',')) != -1) {
528 gGrps.Add(gr.
c_str(), &flag);
530 if (gRequire.length() > 0) gRequire +=
";";
531 gRequire +=
"grps="; gRequire += grps;
536 int from = 0, flag = 1;
537 while ((from = voss.
tokenize(vo, from,
',')) != -1) {
540 gVOs.Add(vo.
c_str(), &flag);
542 if (gRequire.length() > 0) gRequire +=
";";
543 gRequire +=
"vos="; gRequire += voss;
547 FmtExtract(gGrpFmt, gfmt,
"grpfmt=");
549 FmtExtract(gRoleFmt, rfmt,
"rolefmt=");
551 FmtExtract(gVoFmt, vfmt,
"vofmt=");
554 if (sdbg ==
"dbg" && !gDebug) gDebug = 1;
555 if (sdbg2 ==
"dbg2") gDebug = 2;
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]);
567 PRINT(
"+++ group(s): "<< grps);
569 PRINT(
"+++ group(s): <not specified>");
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(
"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
584 PRINT(
"VOMS mapfile requested but initialization failed; failing VOMS plugin config.");
588 return (aOK ? gCertFmt : -1);
#define VOMSREPLACE(a, f, e)
#define VOMSDBGSUBJ(m, c)
XrdCryptoX509 * End() const
virtual XrdCryptoX509data Opaque()
void insert(const int i, int start=-1)
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=':')
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.
XrdVomsFun(XrdSysError &erp)
int VOMSInit(const char *cfg)
int VOMSFun(XrdSecEntity &ent)
static XrdVomsMapfile * Configure(XrdSysError *)