43#include "XrdVersion.hh"
68#define POPTS(t,y) {if (t) {std::cerr <<"Secgsi" <<y <<'\n' << std::flush;}}
103 "ErrDuplicateBucket",
141String XrdSecProtocolgsi::CAdir =
"/etc/grid-security/certificates/";
142String XrdSecProtocolgsi::CRLdir =
"/etc/grid-security/certificates/";
143String XrdSecProtocolgsi::DefCRLext=
".r0";
144String XrdSecProtocolgsi::GMAPFile =
"/etc/grid-security/grid-mapfile";
145String XrdSecProtocolgsi::SrvCert =
"/etc/grid-security/xrd/xrdcert.pem";
146String XrdSecProtocolgsi::SrvKey =
"/etc/grid-security/xrd/xrdkey.pem";
147String XrdSecProtocolgsi::UsrProxy;
148String XrdSecProtocolgsi::UsrCert =
"/.globus/usercert.pem";
149String XrdSecProtocolgsi::UsrKey =
"/.globus/userkey.pem";
150String XrdSecProtocolgsi::PxyValid =
"12:00";
151int XrdSecProtocolgsi::DepLength= 0;
153int XrdSecProtocolgsi::CACheck = caVerifyss;
154int XrdSecProtocolgsi::CRLCheck = crlTry;
155int XrdSecProtocolgsi::CRLDownload = 0;
156int XrdSecProtocolgsi::CRLRefresh = 86400;
157int XrdSecProtocolgsi::GMAPOpt = 1;
158bool XrdSecProtocolgsi::GMAPuseDNname = 0;
159String XrdSecProtocolgsi::DefCrypto=
"ssl";
160String XrdSecProtocolgsi::DefCipher=
"aes-128-cbc:bf-cbc:des-ede3-cbc";
161String XrdSecProtocolgsi::DefMD =
"sha256";
162String XrdSecProtocolgsi::DefError =
"invalid credentials ";
163int XrdSecProtocolgsi::PxyReqOpts = 0;
164int XrdSecProtocolgsi::AuthzPxyWhat = -1;
165int XrdSecProtocolgsi::AuthzPxyWhere = -1;
166int XrdSecProtocolgsi::AuthzAlways = 1;
170int XrdSecProtocolgsi::AuthzCertFmt = -1;
171int XrdSecProtocolgsi::GMAPCacheTimeOut = -1;
172int XrdSecProtocolgsi::AuthzCacheTimeOut = 43200;
173String XrdSecProtocolgsi::SrvAllowedNames;
174int XrdSecProtocolgsi::VOMSAttrOpt = vatIgnore;
176int XrdSecProtocolgsi::VOMSCertFmt = -1;
177int XrdSecProtocolgsi::MonInfoOpt = 0;
178bool XrdSecProtocolgsi::HashCompatibility = 1;
179bool XrdSecProtocolgsi::TrustDNS =
false;
180bool XrdSecProtocolgsi::ShowDN =
false;
183int XrdSecProtocolgsi::ncrypt = 0;
204time_t XrdSecProtocolgsi::lastGMAPCheck = -1;
208int XrdSecProtocolgsi::Debug = 0;
209bool XrdSecProtocolgsi::Server = 1;
210int XrdSecProtocolgsi::TimeSkew = 300;
226 static const char *ukn =
"Unknown";
228 kclt = (kclt < 0) ? 0 : kclt;
242 static const char *ukn =
"Unknown";
244 ksrv = (ksrv < 0) ? 0 : ksrv;
265 PRINT(
"----------------------------------------------------------------");
266 PRINT(
"protocol instance: "<<p);
267 PRINT(
"this: "<<
this);
284 PRINT(
"----------------------------------------------------------------");
298 EPNAME(
"XrdSecProtocolgsi");
300 if (
QTRACE(Authen)) {
PRINT(
"constructing: "<<
this); }
305 hs->TimeStamp = time(0);
307 hs->Tty = (isatty(0) == 0 || isatty(1) == 0) ? 0 : 1;
309 PRINT(
"could not create handshake vars object");
338 if (strchr(hname,
'.')) {
340 Entity.host = strdup(hname);
345 Entity.host = strdup(hname);
347 Entity.host = strdup(canonname);
356 Entity.host = strdup(hname);
357 expectedHost = strdup(hname);
360 Entity.addrInfo = &epAddr;
386 DEBUG(
"mode: server");
388 DEBUG(
"mode: client");
411 char *Failure = 0, *Parms = 0;
420 ErrF(erp,
kGSErrInit,
"tracing object (gsiTrace) not initialized! cannot continue");
424 int trace = 0, traceSut = 0, traceCrypto = 0;
430 }
else if (Debug >= 2) {
436 }
else if (Debug >= 1) {
448 if (opt.
hashcomp == 0) HashCompatibility = 0;
452 Server = (opt.
mode ==
's');
461 if (opt.
ca >= caNoVerify && opt.
ca <= caVerify)
463 DEBUG(
"option CACheck: "<<getOptName(caVerOpts,CACheck));
474 while ((from = tmp.
tokenize(dp, from,
',')) != -1) {
478 if (errno == ENOENT) {
487 if (!(CAtmp.
endswith(
','))) CAtmp +=
',';
491 PRINT(
"Warning: could not expand: "<<dp);
498 DEBUG(
"using CA dir(s): "<<CAdir);
510 const char *cocrl[] = {
"do-not-care",
"use-if-available",
"require",
"require-not-expired" };
511 const char *codwld[] = {
"no",
"yes"};
512 if (opt.
crl >= crlUpdate) {
516 if (opt.
crl >= crlIgnore && opt.
crl <= crlRequire)
518 DEBUG(
"option CRLCheck: "<<CRLCheck<<
" ('"<<cocrl[CRLCheck]<<
"'; download? "<<
519 codwld[CRLDownload]<<
")");
530 while ((from = tmp.
tokenize(dp, from,
',')) != -1) {
534 if (errno == ENOENT) {
543 if (!(CRLtmp.
endswith(
','))) CRLtmp +=
',';
547 PRINT(
"Warning: could not expand: "<<dp);
559 DEBUG(
"using CRL dir(s): "<<CRLdir);
570 DEBUG(
"CRL information refreshed every "<<CRLRefresh<<
" secs");
575 DEBUG(
"trust DNS option: "<<TrustDNS);
580 DEBUG(
"show DN option: "<<ShowDN);
588 DefCrypto = opt.
clist;
592 String crypts(DefCrypto,0,-1,64);
600 while ((from = crypts.
tokenize(ncpt, from,
'|')) != -1) {
601 if (ncpt.
length() > 0 && ncpt[0] !=
'-') {
606 cryptID[ncrypt] = cf->
ID();
607 cryptName[ncrypt].insert(cf->
Name(),0,strlen(cf->
Name())+1);
611 if (!(refcip[ncrypt] = cf->
Cipher(0,0,0))) {
612 PRINT(
"ref cipher for module "<<ncpt<<
613 " cannot be instantiated : disable");
618 PRINT(
"max number of crypto modules ("
622 if (cryptlist.
length()) cryptlist +=
":";
627 PRINT(
"cannot instantiate crypto factory "<<ncpt<<
637 ErrF(erp,
kGSErrInit,
"could not find any valid crypto module");
648 while ((from = DefCipher.tokenize(cip, from,
':')) != -1) {
651 for (; i < ncrypt; i++) {
652 if (!(cryptF[i]->SupportedCipher(cip.
c_str()))) {
654 DEBUG(
"cipher type not supported ("<<cip<<
") - disabling");
656 DefCipher.erase(cip);
669 while ((from = DefMD.tokenize(md, from,
':')) != -1) {
672 for (; i < ncrypt; i++) {
673 if (!(cryptF[i]->SupportedMsgDigest(md.
c_str()))) {
675 PRINT(
"MD type not supported ("<<md<<
") - disabling");
690 PRINT(
"Could not expand: "<<opt.
cert<<
": use default");
698 PRINT(
"Could not expand: "<<opt.
key<<
": use default");
703 if (
access(SrvKey.c_str(), R_OK)) {
704 PRINT(
"WARNING: process has no permission to read the certificate key file: "<<SrvKey);
709 for (; i<ncrypt; i++) {
710 if (!GetSrvCertEnt(ceref, cryptF[i], time(0), certcalist)) {
711 PRINT(
"problems loading srv cert");
720 if (cacheCert.Num() <= 0) {
721 ErrF(erp,
kGSErrError,
"no valid server certificate found");
726 DEBUG(
"CA list: "<<certcalist);
736 const char *cogmap[] = {
"do-not-use",
"use-if-available",
"require" };
737 const char *codnnm[] = {
"DN hash",
"DN name"};
738 if (opt.
ogmap >= 10) {
744 DEBUG(
"user mapping file option: "<<cogmap[GMAPOpt]);
746 DEBUG(
"default option for entity name if no mapping available: "<<codnnm[(
int)GMAPuseDNname]);
755 PRINT(
"Could not expand: "<<opt.
gridmap<<
": use default");
763 if (Debug) pars +=
"dbg|";
764 if (opt.
gmapto > 0) { pars +=
"to="; pars += (int)opt.
gmapto; }
767 ErrF(erp,
kGSErrError,
"error loading grid map file",GMAPFile.c_str());
771 NOTIFY(
"Grid map file: "<<GMAPFile<<
" cannot be 'access'ed: do not use");
774 DEBUG(
"using grid map file: "<<GMAPFile);
781 if (opt.
gmapfun && GMAPOpt > 0) {
782 if (!(GMAPFun = LoadGMAPFun((
const char *) opt.
gmapfun,
793 if (!hasgmap && !hasgmapfun) {
795 ErrF(erp,
kGSErrError,
"User mapping required, but neither a grid mapfile"
796 " nor a mapping function are available");
804 bool hasauthzfun = 0;
807 if (!(AuthzFun = LoadAuthzFun((
const char *) opt.
authzfun,
815 if (AuthzCertFmt >= 0 && AuthzCertFmt <= 1) {
816 const char *ccfmt[] = {
"raw",
"PEM base64" };
817 DEBUG(
"authzfun: proxy certificate format: "<<ccfmt[AuthzCertFmt]);
819 NOTIFY(
"authzfun: proxy certificate format: unknown (code: "<<AuthzCertFmt<<
")");
823 AuthzCacheTimeOut = opt.
authzto;
824 DEBUG(
"grid-map cache entries expire after "<<AuthzCacheTimeOut<<
" secs");
830 if (GMAPOpt > 0 && !hasauthzfun && opt.
gmapto > 0) {
831 GMAPCacheTimeOut = opt.
gmapto;
832 DEBUG(
"grid-map cache entries expire after "<<GMAPCacheTimeOut<<
" secs");
846 const char *capxy_what = (AuthzPxyWhat == 1) ?
"'last proxy only'"
847 :
"'full proxy chain'";
848 const char *capxy_where = (AuthzPxyWhere == 1) ?
"XrdSecEntity.creds"
849 :
"XrdSecEntity.endorsements";
850 DEBUG(
"Export proxy for authorization in '"<<capxy_where<<
"': "<<capxy_what);
853 PRINT(
"WARNING: proxy export for authz enabled: be aware that any setting of '"<<capxy_what<<
854 "' done by '"<<opt.
authzfun<<
"' will get overwritten with "<<capxy_what);
862 DEBUG(
"Will not accept delegated proxies");
865 if (opt.
dlgpxy == dlgReqSign)
870 if (!strcmp(opt.
exppxy,
"=creds")) {
873 DEBUG(
"Delegated proxy saved in Entity.creds ");
876 if (strcmp(opt.
exppxy,
"=default"))
882 UsrProxy +=
"u<uid>";
885 DEBUG(
"File template for delegated proxy: "<<UsrProxy);
888 DEBUG(
"Delegated proxies options: "<<PxyReqOpts);
896 VOMSAttrOpt = (opt.
vomsat <= vatRequire && opt.
vomsat >= vatIgnore)
897 ? opt.
vomsat : VOMSAttrOpt;
902 if (!(VOMSFun = LoadVOMSFun((
const char *) opt.
vomsfun,
909 if (VOMSCertFmt >= 0 && VOMSCertFmt <= 1) {
910 const char *ccfmt[] = {
"raw",
"PEM base64" };
911 DEBUG(
"vomsfun: proxy certificate format: "<<ccfmt[VOMSCertFmt]);
914 snprintf(fbuff,
sizeof(fbuff),
"%d", VOMSCertFmt);
915 ErrF(erp,
kGSErrError,
"VOMS plug-in returned invalid cert "
922 DEBUG(
"VOMS attributes options: "<<getOptName(vomsatOpts, VOMSAttrOpt));
929 const char *cmoninfo = (MonInfoOpt == 1) ?
"DN" :
"none";
930 DEBUG(
"Monitor information options: "<<cmoninfo);
935 if (certcalist.
length() == 0)
936 {ErrF(erp,
kGSErrInit,
"unable to generate ca cert hash list!");
944 Parms =
new char[cryptlist.
length()+3+12+certcalist.
length()+5];
946 sprintf(Parms,
"v:%d,c:%s,ca:%s",
949 ErrF(erp,
kGSErrInit,
"no system resources for 'Parms'");
955 DEBUG(
"available crypto modules: "<<cryptlist);
956 DEBUG(
"issuer CAs of server certs (hashes): "<<certcalist);
963 struct passwd *pw = getpwuid(getuid());
965 NOTIFY(
"WARNING: cannot get user information (uid:"<<getuid()<<
")");
975 PRINT(
"Could not expand: "<<opt.
proxy<<
": use default");
979 UsrProxy += (int)(pw->pw_uid);
987 PRINT(
"Could not expand: "<<opt.
cert<<
": use default");
999 PRINT(
"Could not expand: "<<opt.
key<<
": use default");
1007 PxyValid = opt.
valid;
1009 if (opt.
deplen != DepLength)
1012 if (opt.
bits > DefBits)
1016 if (opt.
dlgpxy > dlgIgnore) {
1018 if (opt.
dlgpxy == dlgSendpxy) {
1036 TRACE(Authen,
"using certificate file: "<<UsrCert);
1037 TRACE(Authen,
"using private key file: "<<UsrKey);
1038 TRACE(Authen,
"proxy: file: "<<UsrProxy);
1039 TRACE(Authen,
"proxy: validity: "<<PxyValid);
1040 TRACE(Authen,
"proxy: depth of signature path: "<<DepLength);
1041 TRACE(Authen,
"proxy: bits in key: "<<DefBits);
1042 TRACE(Authen,
"server cert: allowed names: "<<SrvAllowedNames);
1044 TRACE(Authen,
"allowing for pure cert/key authentication (no proxy) ");
1083 if (proxyChain) proxyChain->Cleanup();
1116 if (!inbuf || inlen <= 0 || !outbuf)
1123 iv = sessionKey->RefreshIV(liv);
1128 char *buf = (
char *)malloc(sessionKey->EncOutLength(inlen) + liv);
1133 memcpy(buf, iv, liv);
1136 int len = sessionKey->Encrypt(inbuf, inlen, buf + liv) + liv;
1147 DEBUG(
"encrypted buffer has "<<len<<
" bytes");
1167 if (!inbuf || inlen <= 0 || !outbuf)
1171 int liv = (useIV) ? sessionKey->MaxIVLength() : 0;
1172 int sz = inlen - liv;
1174 char *buf = (
char *)malloc(sessionKey->DecOutLength(sz) + liv);
1180 char *iv =
new char[liv];
1181 memcpy(iv, inbuf, liv);
1182 sessionKey->SetIV(liv, iv);
1187 int len = sessionKey->Decrypt(inbuf + liv, sz, buf);
1197 DEBUG(
"decrypted buffer has "<<len<<
" bytes");
1215 if (!sessionKsig || !sessionMD)
1219 if (!inbuf || inlen <= 0 || !outbuf)
1223 sessionMD->Reset(0);
1226 sessionMD->Update(inbuf, inlen);
1230 int lmax = sessionKsig->GetOutlen(sessionMD->Length());
1231 char *buf = (
char *)malloc(lmax);
1236 int len = sessionKsig->EncryptPrivate(sessionMD->Buffer(),
1237 sessionMD->Length(),
1248 DEBUG(
"signature has "<<len<<
" bytes");
1267 if (!sessionKver || !sessionMD)
1271 if (!inbuf || inlen <= 0 || !sigbuf || siglen <= 0)
1275 sessionMD->Reset(0);
1278 sessionMD->Update(inbuf, inlen);
1282 int lmax = sessionKver->GetOutlen(siglen);
1283 char *buf =
new char[lmax];
1288 int len = sessionKver->DecryptPublic(sigbuf, siglen, buf, lmax);
1296 if (len == sessionMD->Length()) {
1297 if (!strncmp(buf, sessionMD->Buffer(), len)) {
1300 DEBUG(
"signature successfully verified");
1305 if (buf)
delete[] buf;
1308 return ((bad) ? 1 : 0);
1331 bucketKey = sessionKey->AsBucket();
1338 return bucketKey->size;
1341 if (klen < bucketKey->size)
1346 memcpy(kbuf, bucketKey->buffer, bucketKey->size);
1349 DEBUG(
"session key exported");
1350 return bucketKey->size;
1368 if (!kbuf || klen <= 0)
1395 sessionKey = newKey;
1401 DEBUG(
"session key update");
1417 EPNAME(
"getCredentials");
1431 char *nbuf = (
char *) malloc(bck->
size);
1447 "handshake var container missing",
"getCredentials");
1450 if ((!parm && !hs->Parms) || (parm && (!(parm->
buffer) || parm->
size <= 0))) {
1452 return ErrC(ei,0,0,0,
kGSErrNoBuffer,
"missing parameters",
"getCredentials");
1458 char *upp = (ei && ei->
getEnv()) ? ei->
getEnv()->
Get(
"xrd.gsiusrpxy") : 0;
1459 if (upp) urlUsrProxy = upp;
1461 if (upp) urlUsrCert = upp;
1463 if (upp) urlUsrKey = upp;
1469 hs->TimeStamp = time(0);
1474 const char *stepstr = 0;
1501 if (!(step = bpar->
GetStep())) {
1510 bmsg.
form(
"IN: bpar: %s", stepstr);
1515 if (ParseClientInput(bpar, &bmai, Emsg) == -1) {
1516 DEBUG(Emsg<<
" CF: "<<sessionCF);
1522 bmsg.
form(
"IN: bmai: %s", stepstr);
1528 DEBUG(
"version run by server: "<< hs->RemVers);
1531 if (!CheckRtag(bmai, Emsg))
1536 if (user.
length() <= 0) user = getenv(
"XrdSecUSER");
1552 return ErrC(ei,bpar,bmai,0,
1561 c = hs->PxyChain->Begin();
1565 issuerHash +=
"|"; issuerHash += c->
SubjectHash(1); }
1570 issuerHash +=
"|"; issuerHash += c->
IssuerHash(1); }
1572 while ((c = hs->PxyChain->Next()) != 0) {
1578 issuerHash +=
"|"; issuerHash += c->
SubjectHash(1); }
1581 DEBUG(
"Client issuer hash: " << issuerHash);
1587 if (hs->RemVers >= 10100) {
1601 return ErrC(ei,bpar,bmai,0,
1606 if (!(bpub = sessionKey->Public(lpub)))
1607 return ErrC(ei,bpar,bmai,0,
1616 if (sessionKsig->EncryptPrivate(*bck) <= 0)
1618 "encrypting client DH public parameters",stepstr);
1621 "client signing key undefined!",stepstr);
1630 if (sessionKsig->ExportPublic(cpub) < 0)
1632 "exporting client public key",stepstr);
1686 if (AddSerialized(
'c', nextstep, hs->ID,
1687 bpar, bmai,
kXRS_main, sessionKey) != 0) {
1688 return ErrC(ei,bpar,bmai,0,
1708 DEBUG(
"returned " << nser <<
" bytes of credentials");
1711 NOTIFY(
"problems with final serialization");
1728 if (e && (e->
status == st_ref)) {
1731 if (to_ref > 0 && (ts_ref - e->
mtime) > to_ref) expired = 1;
1732 int notafter = *((
int *) e->
buf2.
buf);
1733 if (to_ref > notafter) expired = 1;
1768 "handshake var container missing",
1769 "protocol initialization problems");
1772 hs->TimeStamp = time(0);
1776 if (hs->ID.length() <= 0)
1778 DEBUG(
"handshaking ID: " << hs->ID);
1786 bool vomsFailed =
false;
1787 const char *stepstr = 0;
1819 bmsg.
form(
"IN: bpar: %s", stepstr);
1824 if (ParseServerInput(bpar, &bmai, ClntMsg) == -1) {
1830 DEBUG(
"version run by client: "<< hs->RemVers);
1831 DEBUG(
"options req by client: "<< hs->Options);
1836 bmsg.
form(
"IN: bmai: %s", stepstr);
1842 if (!CheckRtag(bmai, ClntMsg))
1847 if (!X509ExportChain) {
1850 "crypto factory function for chain export not found");
1862 if (!(bpub = hs->Rcip->Public(lpub)))
1872 if (sessionKsig->EncryptPrivate(*bck) <= 0)
1874 "encrypting server DH public parameters",stepstr);
1877 "server signing key undefined!",stepstr);
1893 return ErrS(hs->ID,ei,bpar,bmai,0,
1898 return ErrS(hs->ID,ei,bpar,bmai,0,
1918 QueryGMAP(hs->Chain, hs->TimeStamp, name);
1919 DEBUG(
"username(s) associated with this DN: "<<name);
1920 if (name.
length() <= 0) {
1925 PRINT(
"ERROR: user mapping required, but lookup failed - failure");
1928 NOTIFY(
"WARNING: user mapping lookup failed - use DN or DN-hash as name");
1939 DEBUG(
"target user: "<<user);
1945 while ((from = name.
tokenize(u, from,
',')) != -1) {
1946 if (user == u) { ok = 1;
break; }
1950 DEBUG(
"DN mapping: requested user is authorized: name is '"<<name<<
"'");
1955 PRINT(
"WARNING: user mapping lookup ok, but the requested user is not"
1956 " authorized ("<<user<<
"). Instead, mapped as " << name <<
".");
1961 DEBUG(
"user mapping lookup successful: name is '"<<name<<
"'");
1964 Entity.eaAPI->Add(
"gridmap.name",
"1",
true);
1970 if (!GMAPuseDNname && hs->Chain->EEChash()) {
1971 Entity.name = strdup(hs->Chain->EEChash());
1972 }
else if (GMAPuseDNname && hs->Chain->EECname()) {
1973 Entity.name = strdup(hs->Chain->EECname());
1975 PRINT(
"WARNING: DN missing: corruption? ");
1980 if (MonInfoOpt > 0 || ShowDN) {
1981 const char *theDN = hs->Chain->EECname();
1983 if (ShowDN && !GMAPuseDNname) {
1986 if (MonInfoOpt > 0)
Entity.moninfo = strdup(theDN);
1990 if (VOMSAttrOpt > vatIgnore && VOMSFun) {
1992 if (VOMSCertFmt == 1) {
1994 bpxy = (*X509ExportChain)(hs->Chain,
true);
2001 Entity.creds = (
char *) hs->Chain;
2004 if ((*VOMSFun)(
Entity) != 0) {
2006 if (VOMSAttrOpt == vatRequire) {
2009 PRINT(
"ERROR: the VOMS extraction plug-in reported "
2010 "authentication failure");
2017 NOTIFY(
"VOMS: Entity.endorsements: "<< (
Entity.endorsements ?
Entity.endorsements :
"<none>"));
2023 if (AuthzFun && AuthzKey && (AuthzAlways || vomsFailed)) {
2025 if (AuthzCertFmt == 1) {
2029 bpxy = (*X509ExportChain)(hs->Chain,
true);
2042 Entity.creds = (
char *) hs->Chain;
2049 if ((lkey = (*AuthzKey)(
Entity, &key)) < 0) {
2052 PRINT(
"ERROR: unable to get the key associated to this user");
2055 const char *dn = (
const char *)key;
2056 time_t now = hs->TimeStamp;
2059 bool rdlock =
false;
2065 PRINT(
"ERROR: unable to get cache entry for dn: "<<dn);
2077 if ((authzrc = (*AuthzFun)(
Entity)) != 0) {
2080 PRINT(
"ERROR: the authz plug-in reported failure");
2089 CopyEntity(&
Entity, se, &slen);
2095 int notafter = hs->Chain->End() ? hs->Chain->End()->NotAfter() : -1;
2096 cent->
buf2.
buf = (
char *)
new int(notafter);
2102 DEBUG(
"Saved Entity to cacheAuthzFun ("<<slen<<
" bytes)");
2110 DEBUG(
"Got Entity from cacheAuthzFun ("<<slen<<
" bytes)");
2119 if (AuthzPxyWhat >= azFull) {
2120 if (bpxy && AuthzPxyWhat == azLast) {
2126 if (AuthzPxyWhat == 1 && hs->Chain->End()) {
2127 bpxy = hs->Chain->End()->Export();
2129 bpxy = (*X509ExportChain)(hs->Chain,
true);
2133 if (AuthzPxyWhere == azCred) {
2141 NOTIFY(
"Entity.endorsements: "<<(
void *)
Entity.endorsements);
2150 if (hs->RemVers >= 10100) {
2167 if (ClntMsg.
length() > 0) {
2173 return ErrS(hs->ID,ei,bpar,bmai,0,
kGSErrBadOpt, stepstr);
2179 if (ClntMsg.
length() > 0)
2181 NOTIFY(
"problems adding bucket with message for client");
2185 if (AddSerialized(
's', nextstep, hs->ID,
2186 bpar, bmai,
kXRS_main, sessionKey) != 0) {
2188 "main / session cipher",stepstr);
2227 if (!in || !out)
return;
2241 slen += strlen(in->
moninfo); }
2244 if (lout) *lout = slen;
2281 eDest.logger(&Logger);
2297 if ((
mode ==
'c') &&
debug <= 0)
return;
2299 POPTS(t,
" -------------------------------------------------------------------");
2300 POPTS(t,
" Mode: "<< ((
mode ==
'c') ?
"client" :
"server"));
2303 POPTS(t,
" CA verification level: "<< getOptName(caVerOpts,
ca));
2305 POPTS(t,
" CRL extension: " << (
crlext ?
crlext : XrdSecProtocolgsi::DefCRLext));
2306 POPTS(t,
" CRL check level: "<< getOptName(crlOpts,
crl));
2309 POPTS(t,
" Certificate: " << (
cert ?
cert : XrdSecProtocolgsi::UsrCert));
2310 POPTS(t,
" Key: " << (
key ?
key : XrdSecProtocolgsi::UsrKey));
2311 POPTS(t,
" Proxy file: " << XrdSecProtocolgsi::UsrProxy);
2312 POPTS(t,
" Proxy validity: " << (
valid ?
valid : XrdSecProtocolgsi::PxyValid));
2317 if (
createpxy)
POPTS(t,
" Pure Cert/Key authentication allowed");
2320 POPTS(t,
" Certificate: " << (
cert ?
cert : XrdSecProtocolgsi::SrvCert));
2321 POPTS(t,
" Key: " << (
key ?
key : XrdSecProtocolgsi::SrvKey));
2322 POPTS(t,
" Proxy delegation option: "<< getOptName(sDlgOpts,
dlgpxy));
2326 POPTS(t,
" GRIDmap option: "<< getOptName(gmoOpts,
ogmap));
2327 POPTS(t,
" GRIDmap cache entries expiration (secs): "<<
gmapto);
2332 if (
gmapfunparms)
POPTS(t,
" DN mapping function parms: ignored (no mapping function defined)");
2338 POPTS(t,
" Authz cache entries expiration (secs): " <<
authzto);
2340 if (
authzfunparms)
POPTS(t,
" Authz function parms: ignored (no authz function defined)");
2343 POPTS(t,
" Client proxy availability in XrdSecEntity.endorsement: "<< getOptName(azPxyOpts,
authzpxy));
2344 POPTS(t,
" VOMS option: "<< getOptName(vomsatOpts,
vomsat));
2349 if (
vomsfunparms)
POPTS(t,
" VOMS extraction function parms: ignored (no VOMS extraction function defined)");
2353 POPTS(t,
" Name hashing algorithm compatibility OFF");
2357 POPTS(t,
" Crypto modules: "<< (
clist ?
clist : XrdSecProtocolgsi::DefCrypto));
2359 POPTS(t,
" MDigests: "<< (
md ?
md : XrdSecProtocolgsi::DefMD));
2361 POPTS(t,
" Trusting DNS for hostname checking");
2363 POPTS(t,
" Untrusting DNS for hostname checking");
2365 POPTS(t,
" -------------------------------------------------------------------");
2382 EPNAME(
"ProtocolgsiInit");
2385 char *rc = (
char *)
"";
2446 cenv = getenv(
"XrdSecDEBUG");
2448 {
if (cenv[0] >= 49 && cenv[0] <= 51)
opts.debug = atoi(cenv);
2449 else {
PRINT(
"unsupported debug value from env XrdSecDEBUG: "<<cenv<<
" - setting to 1");
2455 cenv = (getenv(
"XrdSecGSICADIR") ? getenv(
"XrdSecGSICADIR")
2456 : getenv(
"X509_CERT_DIR"));
2458 opts.certdir = strdup(cenv);
2461 cenv = (getenv(
"XrdSecGSICRLDIR") ? getenv(
"XrdSecGSICRLDIR")
2462 : getenv(
"X509_CERT_DIR"));
2464 opts.crldir = strdup(cenv);
2467 cenv = getenv(
"XrdSecGSICRLEXT");
2469 opts.crlext = strdup(cenv);
2472 cenv = getenv(
"XrdSecGSICRLRefresh");
2474 opts.crlrefresh = atoi(cenv);
2477 cenv = (getenv(
"XrdSecGSIUSERCERT") ? getenv(
"XrdSecGSIUSERCERT")
2478 : getenv(
"X509_USER_CERT"));
2480 opts.cert = strdup(cenv);
2483 cenv = (getenv(
"XrdSecGSIUSERKEY") ? getenv(
"XrdSecGSIUSERKEY")
2484 : getenv(
"X509_USER_KEY"));
2486 opts.key = strdup(cenv);
2489 cenv = (getenv(
"XrdSecGSIUSERPROXY") ? getenv(
"XrdSecGSIUSERPROXY")
2490 : getenv(
"X509_USER_PROXY"));
2492 opts.proxy = strdup(cenv);
2495 cenv = getenv(
"XrdSecGSIPROXYVALID");
2497 opts.valid = strdup(cenv);
2500 cenv = getenv(
"XrdSecGSIPROXYDEPLEN");
2502 opts.deplen = atoi(cenv);
2505 cenv = getenv(
"XrdSecGSIPROXYKEYBITS");
2507 opts.bits = atoi(cenv);
2510 cenv = getenv(
"XrdSecGSICACHECK");
2512 opts.ca = atoi(cenv);
2515 cenv = getenv(
"XrdSecGSICRLCHECK");
2517 opts.crl = atoi(cenv);
2520 cenv = getenv(
"XrdSecGSIDELEGPROXY");
2522 opts.dlgpxy = atoi(cenv);
2525 cenv = getenv(
"XrdSecGSICREATEPROXY");
2527 opts.createpxy = atoi(cenv);
2530 cenv = getenv(
"XrdSecGSISRVNAMES");
2532 opts.srvnames = strdup(cenv);
2535 cenv = getenv(
"XrdSecGSIUSEDEFAULTHASH");
2540 if ((cenv = getenv(
"XrdSecGSITRUSTDNS")))
2541 opts.trustdns = (!strcmp(cenv,
"0")) ?
false :
true;
2548 if (!rc)
opts.debug = 1;
2566 cenv = getenv(
"XRDDEBUG");
2567 if (cenv && !strcmp(cenv,
"1"))
opts.debug = 1;
2574 char parmbuff[1024];
2575 strlcpy(parmbuff, parms,
sizeof(parmbuff));
2623 String gmapfunparms =
"";
2625 String authzfunparms =
"";
2627 String vomsfunparms =
"";
2631 int crlrefresh = 86400;
2636 int dlgpxy = dlgIgnore;
2638 int vomsat = vatIgnore;
2641 int trustdns =
false;
2645 while ((op = inParms.
GetToken())) {
2646 if (!strncmp(op,
"-d:",3)) {
2648 }
else if (!strncmp(op,
"-c:",3)) {
2649 clist = (
const char *)(op+3);
2650 }
else if (!strncmp(op,
"-certdir:",9)) {
2651 certdir = (
const char *)(op+9);
2652 }
else if (!strncmp(op,
"-crldir:",8)) {
2653 crldir = (
const char *)(op+8);
2654 }
else if (!strncmp(op,
"-crlext:",8)) {
2655 crlext = (
const char *)(op+8);
2656 }
else if (!strncmp(op,
"-cert:",6)) {
2657 cert = (
const char *)(op+6);
2658 }
else if (!strncmp(op,
"-key:",5)) {
2659 key = (
const char *)(op+5);
2660 }
else if (!strncmp(op,
"-cipher:",8)) {
2661 cipher = (
const char *)(op+8);
2662 }
else if (!strncmp(op,
"-md:",4)) {
2663 md = (
const char *)(op+4);
2664 }
else if (!strncmp(op,
"-ca:",4)) {
2665 ca = getOptVal(caVerOpts, op+4);
2667 }
else if (!strncmp(op,
"-crl:",5)) {
2668 crl = getOptVal(crlOpts, op+5);
2669 }
else if (!strncmp(op,
"-crlrefresh:",12)) {
2670 crlrefresh = atoi(op+12);
2671 }
else if (!strncmp(op,
"-gmapopt:",9)) {
2672 ogmap = getOptVal(gmoOpts, op+9);
2673 }
else if (!strncmp(op,
"-gridmap:",9)) {
2674 gridmap = (
const char *)(op+9);
2675 }
else if (!strncmp(op,
"-gmapfun:",9)) {
2676 gmapfun = (
const char *)(op+9);
2677 }
else if (!strncmp(op,
"-gmapfunparms:",14)) {
2678 gmapfunparms = (
const char *)(op+14);
2679 }
else if (!strncmp(op,
"-authzcall:",11)) {
2680 authzcall = getOptVal(azCallOpts, op+11);
2681 }
else if (!strncmp(op,
"-authzfun:",10)) {
2682 authzfun = (
const char *)(op+10);
2683 }
else if (!strncmp(op,
"-authzfunparms:",15)) {
2684 authzfunparms = (
const char *)(op+15);
2685 }
else if (!strncmp(op,
"-authzto:",9)) {
2686 authzto = atoi(op+9);
2687 }
else if (!strncmp(op,
"-gmapto:",8)) {
2688 gmapto = atoi(op+8);
2689 }
else if (!strncmp(op,
"-dlgpxy:",8)) {
2690 opts.dlgpxy = getOptVal(sDlgOpts, op+8);
2691 }
else if (!strncmp(op,
"-exppxy:",8)) {
2692 exppxy = (
const char *)(op+8);
2693 }
else if (!strncmp(op,
"-authzpxy:",10)) {
2694 opts.authzpxy = getOptVal(azPxyOpts, op+10);
2695 }
else if (!strncmp(op,
"-authzpxy",9)) {
2697 }
else if (!strncmp(op,
"-vomsat:",8)) {
2698 vomsat = getOptVal(vomsatOpts, op+8);
2699 if (vomsat != vatIgnore && vomsfun.
length() == 0)
2700 vomsfun =
"default";
2701 }
else if (!strncmp(op,
"-vomsfun:",9)) {
2702 vomsfun = (
const char *)(op+9);
2703 }
else if (!strncmp(op,
"-vomsfunparms:",14)) {
2704 vomsfunparms = (
const char *)(op+14);
2705 }
else if (!strcmp(op,
"-moninfo")) {
2707 }
else if (!strncmp(op,
"-moninfo:",9)) {
2708 moninfo = atoi(op+9);
2709 }
else if (!strcmp(op,
"-defaulthash")) {
2711 }
else if (!strncmp(op,
"-trustdns:",10)) {
2712 trustdns = getOptVal(tdnsOpts, op+10);
2713 }
else if (!strncmp(op,
"-showdn:",8)) {
2714 showDN = getOptVal(tdnsOpts, op+8);
2716 PRINT(
"ignoring unknown switch: "<<op);
2726 if (vomsfun.
length() > 0)
2727 {
if (vomsat == vatIgnore) vomsat = vatExtract;
2729 }
else authzcall = azAlways;
2733 opts.debug = (debug > -1) ? debug :
opts.debug;
2737 opts.crlrefresh = crlrefresh;
2739 opts.gmapto = gmapto;
2740 opts.authzcall = authzcall;
2741 opts.authzto = authzto;
2742 opts.dlgpxy = (dlgpxy >= dlgIgnore && dlgpxy <= dlgReqSign) ? dlgpxy : 0;
2743 opts.authzpxy = authzpxy;
2744 opts.vomsat = vomsat;
2745 opts.moninfo = moninfo;
2746 opts.hashcomp = hashcomp;
2747 opts.trustdns = (trustdns <= 0) ?
false :
true;
2748 opts.showDN = (showDN > 0) ?
true :
false;
2751 if (certdir.
length() > 0)
2765 if (gridmap.
length() > 0)
2767 if (gmapfun.
length() > 0)
2769 if (gmapfunparms.
length() > 0)
2770 opts.gmapfunparms = (
char *)gmapfunparms.
c_str();
2771 if (authzfun.
length() > 0)
2772 opts.authzfun = (
char *)authzfun.
c_str();
2773 if (authzfunparms.
length() > 0)
2774 opts.authzfunparms = (
char *)authzfunparms.
c_str();
2777 if (vomsfun.
length() > 0)
2779 if (vomsfunparms.
length() > 0)
2780 opts.vomsfunparms = (
char *)vomsfunparms.
c_str();
2810 const char *hostname,
2821 const char *msg =
"Secgsi: Insufficient memory for protocol.";
2825 std::cerr <<msg <<std::endl;
2831 std::cerr <<
"protocol object instantiated" << std::endl;
2851 if (!bls || !buf || (opt != 0 && opt !=
'c' && opt !=
's')) {
2852 PRINT(
"invalid inputs ("
2853 <<bls<<
","<<buf<<
","<<opt<<
")"
2863 hs->LastStep = step;
2870 if (brt && sessionKsig) {
2873 if (sessionKsig->EncryptPrivate(*brt) <= 0) {
2874 PRINT(
"error encrypting random tag");
2892 if (!(brt =
new XrdSutBucket(RndmTag,
kXRS_rtag))) {
2893 PRINT(
"error creating random tag bucket");
2901 PRINT(
"cache entry not found: protocol error");
2907 hs->Cref->mtime = (
kXR_int32)hs->TimeStamp;
2914 XrdSutBucket *bck = 0;;
2917 if (!(bck =
new XrdSutBucket(bser,nser,type))) {
2918 PRINT(
"error creating bucket "
2931 if (cip->
Encrypt(*bck, useIV) == 0) {
2932 PRINT(
"error encrypting bucket - cipher "
2947 EPNAME(
"ParseClientInput");
2951 PRINT(
"invalid inputs ("<<br<<
","<<bm<<
")");
2952 cmsg =
"invalid inputs";
2964 if (ClientDoInit(br, bm, cmsg) != 0)
2969 if (ClientDoCert(br, bm, cmsg) != 0)
2974 if (ClientDoPxyreq(br, bm, cmsg) != 0)
2978 cmsg =
"protocol error: unknown action: "; cmsg += step;
2999 emsg =
"error instantiating main buffer";
3005 int ii =
opts.find(
"v:");
3008 sver.erase(sver.find(
','));
3009 hs->RemVers = atoi(sver.c_str());
3012 emsg =
"server version information not found in options:"
3013 " assume same as local";
3023 if (!(hs->Cref =
new XrdSutPFEntry(
"c"))) {
3024 emsg =
"error creating cache";
3029 hs->Cref->status = hs->RemVers;
3032 hs->Options = PxyReqOpts;
3036 ii =
opts.find(
"c:");
3041 NOTIFY(
"Crypto list missing: protocol error? (use defaults)");
3046 emsg =
"cannot find / load crypto requested modules :";
3053 ii =
opts.find(
"ca:");
3059 if (ParseCAlist(srvca) != 0) {
3060 emsg =
"unknown CA: cannot verify server certificate";
3074 String clientcert = UsrCert, clientkey = UsrKey, clientproxy = UsrProxy;
3075 if (urlUsrCert.length()>0) clientcert = urlUsrCert;
3076 if (urlUsrKey.length()>0) clientkey = urlUsrKey;
3077 if (urlUsrProxy.length()>0) clientproxy = urlUsrProxy;
3082 PRINT(
"Problems resolving templates in "<<clientcert);
3086 PRINT(
"Problems resolving templates in "<<clientkey);
3093 PRINT(
"Problems resolving templates in "<<clientproxy);
3098 ProxyIn_t pi = {clientcert.
c_str(), clientkey.c_str(), CAdir.c_str(),
3099 clientproxy.c_str(), PxyValid.c_str(),
3100 DepLength, DefBits, createpxy};
3101 ProxyOut_t po = {hs->PxyChain, sessionKsig, hs->Cbck };
3102 if (QueryProxy(1, &cachePxy, clientproxy.c_str(),
3103 sessionCF, hs->TimeStamp, &pi, &po) != 0) {
3104 emsg =
"error getting user proxies";
3110 emsg =
"failed to initialize user proxies";
3116 hs->PxyChain = po.
chain;
3117 hs->Cbck =
new XrdSutBucket(*((XrdSutBucket *)(po.
cbck)));
3118 if (!po.
ksig || !(sessionKsig = sessionCF->RSA(*(po.
ksig)))) {
3119 emsg =
"could not get a copy of the signing key:";
3136 XrdSutBucket *bck = 0;
3141 emsg =
"cache entry not found";
3147 int reftime = hs->TimeStamp - TimeSkew;
3148 if (hs->Cref->mtime < reftime) {
3149 emsg =
"cache entry expired";
3157 hs->RemVers = hs->Cref->status;
3167 while ((from = ciplist.
tokenize(cip, from,
':')) != -1) {
3169 if (sessionCF->SupportedCipher(cip.
c_str()))
3175 emsg =
"no common cipher algorithm";
3180 NOTIFY(
"WARNING: list of ciphers supported by server missing"
3181 " - using default");
3187 emsg =
"server certificate missing";
3196 emsg =
"cannot duplicate reference chain";
3205 emsg =
"cannot attach to ParseBucket function!";
3209 int nci = (*ParseBucket)(bck, hs->Chain);
3212 emsg +=
" vs 1 expected)";
3217 x509ChainVerifyOpt_t vopt = {0,
static_cast<int>(hs->TimeStamp),-1,hs->Crl};
3219 if (!(hs->Chain->Verify(ecode, &vopt))) {
3220 emsg =
"certificate chain verification failed: ";
3221 emsg += hs->Chain->LastError();
3232 DEBUG(
"Checking cert is for host " <<
Entity.host);
3234 bool hasSAN, usedDNS =
false;
3235 const char *wantHost = (
Entity.host ?
Entity.host :
"");
3237 if (!hs->Chain->End()->MatchesSAN(
Entity.host, hasSAN))
3238 {
if (hasSAN && !TrustDNS)
3239 {
emsg =
"Unable to verify server hostname '";
emsg += wantHost;
3240 emsg+=
"' using SAN extension; common name fallback disallowed.";
3244 if (!ServerCertNameOK(hs->Chain->End()->Subject(),
Entity.host,
emsg))
3245 {
if (!TrustDNS ||
Entity.addrInfo == 0 || expectedHost)
3246 {
emsg =
"Unable to verify server hostname '";
emsg += wantHost;
3247 emsg+=
"' using common name; DNS fallback prohibited.";
3251 const char *name =
Entity.addrInfo->Name();
3253 {
emsg =
"Unable to verify server hostname '";
emsg += wantHost;
3254 emsg+=
"'; DNS fallback translation failed.";
3257 DEBUG(
"TrustDNS: checking if cert is for host " <<name);
3259 bool hostOK = ServerCertNameOK(hs->Chain->End()->Subject(),name,
emsg)
3260 || (hasSAN && hs->Chain->End()->MatchesSAN(name,hasSAN));
3261 if (!hostOK)
return -1;
3272 (SrvAllowedNames.length() > 0 &&
3273 !ServerCertNameOK(hs->Chain->End()->Subject(), NULL,
emsg)))
3276 std::cerr <<
"secgsi: proxy delegation forbidden when trusting DNS "
3277 "to resolve '" <<wantHost <<
"'!\n" <<std::flush;
3283 sessionKver = sessionCF->RSA(*(hs->Chain->End()->PKI()));
3284 if (!sessionKver || !sessionKver->IsValid()) {
3285 emsg =
"server certificate contains an invalid key";
3297 emsg =
"server public part for session cipher missing";
3303 if (sessionKver->DecryptPublic(*bck) <= 0) {
3304 emsg =
"decrypting server DH public parameters";
3311 emsg =
"server public part for session cipher missing";
3319 PRINT(
"no signed DH parameters from " <<
Entity.host
3320 <<
". Will not delegate x509 proxy to it");
3328 sessionCF->Cipher(hs->HasPad, 0,bck->buffer,bck->size,cip.
c_str())) || !(sessionKey->IsValid())) {
3329 PRINT(
"could not instantiate session cipher "
3330 "using cipher public info from server");
3331 emsg =
"could not instantiate session cipher ";
3359 bck->ToString(mdlist);
3362 while ((from = mdlist.
tokenize(md, from,
':')) != -1) {
3364 if (sessionCF->SupportedMsgDigest(md.
c_str()))
3369 NOTIFY(
"WARNING: list of digests supported by server missing"
3370 " - using default");
3373 if (!(sessionMD = sessionCF->MsgDigest(md.
c_str()))) {
3374 emsg =
"could not instantiate digest object";
3383 XrdSutBucket *bckm = 0;
3385 emsg =
"main buffer missing";
3391 if (!((*bm) =
new XrdSutBuffer(bckm->
buffer,bckm->
size))) {
3392 emsg =
"error deserializing main buffer";
3408 XrdSutBucket *bck = 0;
3413 XrdSutBucket *bckm = 0;
3415 emsg =
"main buffer missing";
3421 if (!(sessionKey->Decrypt(*bckm, useIV))) {
3422 emsg =
"error with session cipher";
3429 if (!((*bm) =
new XrdSutBuffer(bckm->
buffer,bckm->
size))) {
3430 emsg =
"error deserializing main buffer";
3438 XrdCryptoX509 *pxy = 0;
3439 XrdCryptoRSA *kpxy = 0;
3440 if (!(hs->PxyChain) ||
3441 !(pxy = hs->PxyChain->End()) || !(kpxy = pxy->
PKI())) {
3442 emsg =
"local proxy info missing or corrupted";
3448 emsg =
"problems exporting private key";
3452 if ((*bm)->AddBucket(pri,
kXRS_x509) != 0) {
3453 emsg =
"problem adding bucket with private key to main buffer";
3459 emsg =
"Not allowed to sign proxy requests";
3464 emsg =
"bucket with proxy request missing";
3467 XrdCryptoX509Req *req = sessionCF->X509Req(bck);
3469 emsg =
"could not resolve proxy request";
3474 XrdCryptoX509 *pxy = 0;
3475 XrdCryptoRSA *kpxy = 0;
3476 if (!(hs->PxyChain) ||
3477 !(pxy = hs->PxyChain->End()) || !(kpxy = pxy->
PKI())) {
3478 emsg =
"local proxy info missing or corrupted";
3483 if (!X509SignProxyReq) {
3484 emsg =
"problems getting method to sign request";
3487 XrdCryptoX509 *npxy = 0;
3488 if ((*X509SignProxyReq)(pxy, kpxy, req, &npxy) != 0) {
3489 emsg =
"problems signing the request";
3496 if ((bck = npxy->
Export())) {
3498 if ((*bm)->AddBucket(bck) != 0) {
3499 emsg =
"problem adding signed request to main buffer";
3520 EPNAME(
"ParseServerInput");
3524 PRINT(
"invalid inputs ("<<br<<
","<<bm<<
")");
3525 cmsg =
"invalid inputs";
3537 if (ServerDoCertreq(br, bm, cmsg) != 0)
3542 if (ServerDoCert(br, bm, cmsg) != 0)
3547 if (ServerDoSigpxy(br, bm, cmsg) != 0)
3551 cmsg =
"protocol error: unknown action: "; cmsg += step;
3569 XrdSutBucket *bck = 0;
3570 XrdSutBucket *bckm = 0;
3576 cmsg =
"client version information not found in options:"
3577 " assume same as local";
3587 cmsg =
"main buffer missing";
3593 cmsg =
"crypto module specification missing";
3600 cmsg =
"cannot find / load crypto requested module :";
3607 cmsg =
"client issuer hash missing";
3614 if (ParseCAlist(cahash) != 0) {
3615 cmsg =
"unknown CA: cannot verify client credentials";
3620 XrdSutCacheEntry *cent = GetSrvCertEnt(ceref, sessionCF, hs->TimeStamp, cadum);
3622 cmsg =
"cannot find certificate: corruption?";
3627 sessionKsig = sessionCF->RSA(*((XrdCryptoRSA *)(cent->
buf2.
buf)));
3628 hs->Cbck =
new XrdSutBucket(*((XrdSutBucket *)(cent->
buf3.
buf)));
3632 if (!(hs->Cref =
new XrdSutPFEntry(hs->ID.c_str()))) {
3633 cmsg =
"cannot create cache entry";
3638 if (!((*bm) =
new XrdSutBuffer(bckm->
buffer,bckm->
size))) {
3639 cmsg =
"error deserializing main buffer";
3664 XrdSutBucket *bck = 0;
3665 XrdSutBucket *bckm = 0;
3670 cmsg =
"main buffer missing";
3680 int piv = cip.
find(
'#');
3683 if (siv.isdigit()) lenIV = siv.atoi();
3687 if (DefCipher.find(cip) == -1) {
3688 cmsg =
"unsupported cipher chosen by the client";
3695 NOTIFY(
"WARNING: client choice for cipher missing"
3696 " - using default");
3705 cmsg =
"bucket with client public key missing";
3709 sessionKver = sessionCF->RSA(cpub.
c_str(), cpub.
length());
3710 if (!sessionKver || !sessionKver->IsValid()) {
3711 cmsg =
"bucket with client public key contains an invalid key";
3717 cmsg =
"bucket with client DH parameters missing";
3722 if (sessionKver->DecryptPublic(*bck) <= 0) {
3723 cmsg =
"decrypting client DH public parameters";
3731 cmsg =
"bucket with client DH parameters missing";
3738 PRINT(
"no signed DH parameters from client:" <<
Entity.tident <<
3739 " : will not delegate x509 proxy to it");
3740 if ((PxyReqOpts &
kOptsSrvReq)) PxyReqOpts &= ~kOptsSrvReq;
3753 cmsg =
"reference cipher missing";
3757 sessionKey = hs->Rcip;
3760 if (!(sessionKey->Finalize(hs->HasPad,bck->
buffer,bck->
size,cip.
c_str()))) {
3761 cmsg =
"cannot finalize session cipher";
3767 if (lenIV > 0) sessionKey->SetIV(lenIV, (
const char *)0);
3770 cmsg =
"bucket with DH parameters not found or invalid: cannot finalize session cipher";
3781 if (!(sessionKey->Decrypt(*bckm, useIV))) {
3782 cmsg =
"error decrypting main buffer with session cipher";
3789 if (!((*bm) =
new XrdSutBuffer(bckm->
buffer,bckm->
size))) {
3790 cmsg =
"error deserializing main buffer";
3796 if (hs->RemVers == -1) {
3797 if ((*bm)->UnmarshalBucket(
kXRS_version,hs->RemVers) != 0) {
3799 cmsg =
"client version information not found in options:"
3800 " assume same as local";
3809 cmsg =
"session cache has gone";
3815 int reftime = hs->TimeStamp - TimeSkew;
3816 if (hs->Cref->mtime < reftime) {
3817 cmsg =
"cache entry expired";
3825 if (!(bck = (*bm)->GetBucket(
kXRS_x509))) {
3826 cmsg =
"client certificate missing";
3836 cmsg =
"cannot duplicate reference chain";
3845 cmsg =
"cannot attach to ParseBucket function!";
3850 int nci = (*ParseBucket)(bck, hs->Chain);
3852 cmsg =
"wrong number of certificates in received bucket (received: ";
3854 cmsg +=
", expected: >= ";
3861 x509ChainVerifyOpt_t vopt = {0,
static_cast<int>(hs->TimeStamp),-1,hs->Crl};
3863 if (!(hs->Chain->Verify(ecode, &vopt))) {
3864 cmsg =
"certificate chain verification failed: ";
3865 cmsg += hs->Chain->LastError();
3871 XrdCryptoRSA *ckey = sessionCF->RSA(*(hs->Chain->End()->PKI()));
3872 if (!ckey || !ckey->
IsValid()) {
3873 cmsg =
"client certificate contains an invalid key";
3878 XrdOucString cpubcert;
3880 cmsg =
"exporting client public key";
3883 if (cpubcert != cpub) {
3884 cmsg =
"client public key does not match the one from the bucket!";
3903 if (!X509CreateProxyReq) {
3904 cmsg =
"cannot attach to X509CreateProxyReq function!";
3917 if ((*ParseBucket)(bck, hs->PxyChain) > 1) {
3919 hs->PxyChain->Reorder();
3922 XrdCryptoX509Req *rPXp = (XrdCryptoX509Req *) &(hs->RemVers);
3923 XrdCryptoRSA *krPXp = 0;
3924 if ((*X509CreateProxyReq)(hs->PxyChain->End(), &rPXp, &krPXp) == 0) {
3926 hs->Cref->buf4.len = krPXp->
GetPrilen() + 1;
3927 hs->Cref->buf4.buf =
new char[hs->Cref->buf4.len];
3928 if (krPXp->
ExportPrivate(hs->Cref->buf4.buf, hs->Cref->buf4.len) != 0) {
3931 if (hs->PxyChain) hs->PxyChain->Cleanup();
3933 cmsg =
"cannot export private key of the proxy request!";
3937 XrdSutBucket *bckr = rPXp->
Export();
3939 if ((*bm)->AddBucket(bckr) != 0) {
3940 if (hs->PxyChain) hs->PxyChain->Cleanup();
3942 NOTIFY(
"WARNING: proxy req: problem adding bucket to main buffer");
3947 if (hs->PxyChain) hs->PxyChain->Cleanup();
3949 NOTIFY(
"WARNING: proxy req: problem creating request");
3953 if (hs->PxyChain) hs->PxyChain->Cleanup();
3955 NOTIFY(
"WARNING: proxy req: wrong number of certificates");
3966 if (DefMD.find(md) == -1) {
3967 cmsg =
"unsupported MD chosen by the client";
3973 NOTIFY(
"WARNING: client choice for digests missing"
3974 " - using default");
3977 if (!(sessionMD = sessionCF->MsgDigest(md.
c_str()))) {
3978 cmsg =
"could not instantiate digest object";
3993 EPNAME(
"ServerDoSigpxy");
3995 XrdSutBucket *bck = 0;
3996 XrdSutBucket *bckm = 0;
4001 cmsg =
"main buffer missing";
4007 if (!(sessionKey->Decrypt(*bckm, useIV))) {
4008 cmsg =
"error decrypting main buffer with session cipher";
4014 if (!((*bm) =
new XrdSutBuffer(bckm->
buffer,bckm->
size))) {
4015 cmsg =
"error deserializing main buffer";
4020 if (!(bck = (*bm)->GetBucket(
kXRS_x509))) {
4021 cmsg =
"buffer with requested info missing";
4027 DEBUG(
"msg from client: "<<m);
4029 cmsg +=
" :"; cmsg += m;
4037 cmsg =
"the proxy chain is gone";
4045 XrdCryptoRSA *kpx = pxyc->
End()->
PKI();
4047 cmsg =
"problems importing private key";
4054 cmsg =
"session cache has gone";
4058 XrdCryptoX509 *npx = sessionCF->X509(bck);
4060 cmsg =
"could not resolve signed request";
4064 XrdCryptoRSA *
const knpx = npx->
PKI();
4065 if (!knpx || knpx->
ImportPrivate(hs->Cref->buf4.buf, hs->Cref->buf4.len) != 0) {
4067 cmsg =
"could not import private key into signed request";
4077 if (
QTRACE(Authen)) { proxyChain->Dump(); }
4083 (sessionCF) ? sessionCF->X509ExportChain() : 0;
4085 cmsg =
"chain exporter not found; proxy chain not exported";
4089 XrdSutBucket *bpxy = (*c2mem)(proxyChain,
true);
4094 DEBUG(
"proxy chain exported in Entity.creds (" <<
Entity.credslen <<
" bytes)");
4103 if ((bck = (*bm)->GetBucket(
kXRS_user))) {
4112 String pxfile = UsrProxy, name;
4113 struct passwd *pw = getpwnam(user.
c_str());
4118 XrdCryptoX509 *c = proxyChain->SearchBySubject(proxyChain->EECname());
4122 cmsg =
"proxy chain not dumped to file: could not find subject hash";
4128 PRINT(
"Problems resolving templates in "<<pxfile);
4133 String suid; suid += (int) pw->pw_uid;
4134 pxfile.
replace(
"<uid>", suid.c_str());
4139 if ((*ctofile)(proxyChain,pxfile.
c_str()) != 0) {
4140 cmsg =
"problems dumping proxy chain to file ";
4144 PRINT(
"proxy chain dumped to "<< pxfile);
4146 cmsg =
"proxy chain not dumped to file: entity name undefined";
4157 const char *msg1,
const char *msg2,
4164 int k, i = 0, sz = strlen(
"Secgsi");
4170 const char *cmsg = (cm > -1) ?
gGSErrStr[cm] : 0;
4174 msgv[i++] = (
char *)
"Secgsi";
4175 if (cmsg) {msgv[i++] = (
char *)
": ";
4176 msgv[i++] = (
char *)cmsg;
4177 sz += strlen(msgv[i-1]) + 2;
4179 if (msg1) {msgv[i++] = (
char *)
": ";
4180 msgv[i++] = (
char *)msg1;
4181 sz += strlen(msgv[i-1]) + 2;
4183 if (msg2) {msgv[i++] = (
char *)
": ";
4184 msgv[i++] = (
char *)msg2;
4185 sz += strlen(msgv[i-1]) + 2;
4187 if (msg3) {msgv[i++] = (
char *)
": ";
4188 msgv[i++] = (
char *)msg3;
4189 sz += strlen(msgv[i-1]) + 2;
4194 einfo->
setErrInfo(ecode, (
const char **)msgv, i);
4197 char *bout =
new char[sz+10];
4200 for (k = 0; k < i; k++)
4201 strcat(bout, msgv[k]);
4204 for (k = 0; k < i; k++)
4223 ErrF(einfo, ecode, msg1, msg2, msg3);
4236 const char *msg1,
const char *msg2,
4242 ErrF(einfo, ecode, msg1, msg2, msg3);
4259 emsg =
"Buffer not defined";
4264 if (hs->Cref && hs->Cref->buf1.len > 0) {
4265 XrdSutBucket *brt = 0;
4268 if (!(sessionKver)) {
4269 emsg =
"Session cipher undefined";
4273 if (sessionKver->DecryptPublic(*brt) <= 0) {
4274 emsg =
"error decrypting random tag with public key";
4278 emsg =
"random tag missing - protocol error";
4283 if (memcmp(brt->
buffer,hs->Cref->buf1.buf,hs->Cref->buf1.len)) {
4284 emsg =
"random tag content mismatch";
4291 memset(hs->Cref->buf1.buf,0,hs->Cref->buf1.len);
4292 hs->Cref->buf1.SetBuf();
4297 DEBUG(
"Random tag successfully checked");
4299 DEBUG(
"Nothing to check");
4317 XrdCryptoX509Crl *crl = 0;
4322 PRINT(
"Invalid inputs");
4330 if (strcmp(subjhash, xca->
SubjectHash())) hashalg = 1;
4332 String caroot(cahash, 0, cahash.
find(
".0")-1);
4335 String crlext = XrdSecProtocolgsi::DefCRLext;
4339 while ((from = CRLdir.tokenize(crldir, from,
',')) != -1) {
4340 if (crldir.
length() <= 0)
continue;
4342 String crlfile = crldir + caroot;
4344 DEBUG(
"target file: "<<crlfile);
4347 if ((errcrl = VerifyCRL(crl, xca, crldir,
CF, hashalg)) == 0)
return crl;
4353 if (CRLCheck < 2 || (dwld == 0)) {
4366 if ((errcrl = VerifyCRL(crl, xca, crldir,
CF, hashalg)) == 0)
return crl;
4372 while ((from = CRLdir.tokenize(crldir, from,
',')) != -1) {
4373 if (crldir.
length() <= 0)
continue;
4375 String crlurl = crldir + caroot;
4376 crlurl +=
".crl_url";
4377 DEBUG(
"target file: "<<crlurl);
4380 PRINT(
"could not open file: "<<crlurl);
4384 while ((fgets(line,
sizeof(line), furl))) {
4385 if (line[strlen(line) - 1] ==
'\n') line[strlen(line) - 1] = 0;
4387 if ((errcrl = VerifyCRL(crl, xca, crldir,
CF, hashalg)) == 0)
return crl;
4395 while ((from = CRLdir.tokenize(crldir, from,
',')) != -1) {
4396 if (crldir.
length() <= 0)
continue;
4401 PRINT(
"could not open directory: "<<crldir<<
" (errno: "<<errno<<
")");
4405 struct dirent *dent = 0;
4406 while ((dent =
readdir(dd))) {
4408 if (!strcmp(cahash.
c_str(),dent->d_name))
continue;
4410 if (!strstr(dent->d_name,caroot.c_str()))
continue;
4412 String crlfile = crldir + dent->d_name;
4413 DEBUG(
"analysing entry "<<crlfile);
4416 if ((errcrl = VerifyCRL(crl, xca, crldir,
CF, hashalg)) == 0)
break;
4440 DEBUG(
"CA signing certificate file = "<<casigfile);
4442 XrdCryptoX509 *xcasig = 0;
4444 if (CRLCheck >= 2) {
4445 PRINT(
"CA certificate to verify the signature ("<<crl->
IssuerHash(hashalg)<<
4446 ") could not be loaded - exit");
4448 DEBUG(
"CA certificate to verify the signature could not be loaded - verification skipped");
4453 if (crl->
Verify(xcasig)) {
4455 if (CRLCheck >= 3 && crl && crl->
IsExpired()) {
4457 NOTIFY(
"CRL is expired (CRLCheck: "<<CRLCheck<<
")");
4461 PRINT(
"CA signature or CRL verification failed!");
4467 PRINT(
"Loaded CRL does not match CA (subject CA "<<xca->
SubjectHash(hashalg)<<
4468 " does not match CRL issuer "<<crl->
IssuerHash(hashalg)<<
"! ");
4474String XrdSecProtocolgsi::GetCApath(
const char *cahash)
4482 while ((from = CAdir.tokenize(ent, from,
',')) != -1) {
4514 PRINT(
"Invalid input ");
4521 PRINT(
"Cannot attach to the ParseFile function");
4526 XrdCryptoX509 *xc = cca->
Begin();
4528 PRINT(
"Cannot attach to first certificate in chain");
4544 XrdCryptoX509 *xd = xc;
4548 for (
int ha = 0; ha < 2; ha++) {
4550 if (inam.
length() <= 0)
continue;
4552 ncis = (*ParseFile)(inam.
c_str(), ch, 0);
4553 if (ncis >= 1)
break;
4556 if (ncis < 1)
break;
4557 XrdCryptoX509 *xi = ch->
Begin();
4584 if (!(verified = cca->
Verify(e, &vopt)))
4587 PRINT(
"CA certificate not self-signed: cannot verify integrity ("<<xc->
SubjectHash()<<
")");
4596 NOTIFY(
"Warning: CA certificate not self-signed and"
4597 " integrity not checked: assuming OK ("<<xc->
SubjectHash()<<
")");
4601 if (CACheck > caNoVerify) {
4603 bool checkselfsigned = (CACheck > caVerifyss) ?
true : false;
4604 if (!(verified = cca->
CheckCA(checkselfsigned)))
4605 PRINT(
"CA certificate self-signed: integrity check failed ("<<xc->
SubjectHash()<<
")");
4610 NOTIFY(
"Warning: CA certificate self-signed but"
4611 " integrity not checked: assuming OK ("<<xc->
SubjectHash()<<
")");
4632 if (!e)
return false;
4643 PRINT(
"CA entry for '"<<e->
name<<
"' needs refreshing: clean the related entry cache first");
4650 if ((crl_check == 2 && !crl) || (crl_check == 3 && crl->
IsExpired())) goodcrl = 0;
4651 if (crl_refresh > 0 && ((ts_ref - e->
mtime) > crl_refresh)) goodcrl = 0;
4655 PRINT(
"CRL entry for '"<<e->
name<<
"' needs refreshing: clean the related entry cache first ("<<e<<
")");
4662int XrdSecProtocolgsi::GetCA(
const char *cahash,
4674 if (!cahash || !cf) {
4675 PRINT(
"Invalid input ");
4680 time_t timestamp = (hs) ? hs->TimeStamp : time(0);
4686 DEBUG(
"Querying cache for tag: "<<tag<<
" (timestamp:"<<timestamp<<
4687 ", refresh fq:"<< CRLRefresh <<
")");
4689 bool rdlock =
false;
4690 XrdSutCacheArg_t arg = {CRLCheck, CRLRefresh, timestamp, -1};
4691 XrdSutCacheEntry *cent = cacheCA.Get(tag.c_str(), rdlock,
GetCACheck, (
void *) &arg);
4693 PRINT(
"unable to get a valid entry from cache for " << tag);
4700 XrdCryptoX509Crl *crl = (XrdCryptoX509Crl *)(cent->
buf2.
buf);
4705 if (chain) stackCA.Del(chain);
4706 if (crl) stackCRL->Del(crl);
4707 PRINT(
"unable to get a valid entry from cache for " << tag);
4714 if (hs) hs->Chain = chain;
4718 if (hs) hs->Crl = crl;
4726 if (chain) stackCA.Del(chain);
4727 if (crl) stackCRL->Del(crl);
4735 String fnam = GetCApath(cahash);
4736 DEBUG(
"trying to load CA certificate from "<<fnam);
4739 bool createchain = (hs && hs->Chain) ? 0 : 1;
4740 chain = (createchain) ?
new X509Chain() : hs->Chain;
4742 PRINT(
"could not attach-to or create new GSI chain");
4749 int nci = (createchain) ? (*
ParseFile)(fnam.
c_str(), chain, 0) : 1;
4750 bool ok = 0, verified = 0;
4753 verified = VerifyCA(CACheck, chain, cf);
4754 XrdCryptoX509Crl *crl = 0;
4760 if ((crl = LoadCRL(chain->
EffCA(), cahash, cf, CRLDownload, errcrl))) {
4762 DEBUG(
"CRL successfully loaded");
4764 String em =
"missing or expired: ignoring";
4765 if ((CRLCheck == 1 && errcrl != 0 && errcrl != -5) || (CRLCheck >= 2 && errcrl != 0)) {
4767 em =
"invalid: failing";
4768 }
else if (CRLCheck >= 2) {
4770 em =
"missing or expired: failing";
4772 NOTIFY(
"CRL is "<<em<<
" (CRLCheck: "<<CRLCheck<<
")");
4779 cent->
buf1.
buf = (
char *)(chain);
4783 cent->
buf2.
buf = (
char *)(crl);
4787 cent->
mtime = timestamp;
4803 NOTIFY(
"certificate not found or invalid (nci: "<<nci<<
", CA: "<<
4804 (
int)(verified)<<
")");
4813 return (rc != 0) ? rc : 0;
4827 if (isatty(0) == 0 || isatty(1) == 0) {
4828 NOTIFY(
"Not a tty: cannot prompt for proxies - do nothing ");
4837 PRINT(
"chain or key container undefined");
4842 if (
stat(pi->
key, &st) != 0) {
4843 DEBUG(
"cannot access private key file: "<<pi->
key);
4846 if (!S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) ||
4847 (st.st_mode & (S_IWGRP | S_IWOTH)) != 0 ||
4848 (st.st_mode & (S_IRGRP | S_IROTH)) != 0) {
4849 DEBUG(
"wrong permissions for file: "<<pi->
key<<
" (should be 0600)");
4857 XrdProxyOpt_t pxopt = {pi->
bits,
4863 if (!X509CreateProxy) {
4864 PRINT(
"cannot attach to X509CreateProxy function!");
4867 rc = (*X509CreateProxy)(pi->
cert, pi->
key, &pxopt, ch, kp, pi->
out);
4874int XrdSecProtocolgsi::ParseCAlist(
String calist)
4882 if (calist.
length() <= 0) {
4883 PRINT(
"nothing to parse");
4886 DEBUG(
"parsing list: "<<calist);
4894 while ((from = calist.
tokenize(cahash, from,
'|')) != -1) {
4899 if (!cahash.
endswith(
".0")) cahash +=
".0";
4901 if (GetCA(cahash.
c_str(), sessionCF, hs) == 0)
4912int XrdSecProtocolgsi::ParseCrypto(
String clist)
4923 if (clist.
length() <= 0) {
4924 NOTIFY(
"empty list: nothing to parse");
4927 DEBUG(
"parsing list: "<<clist);
4934 while ((from = clist.
tokenize(hs->CryptoMod, from,
'|')) != -1) {
4936 if (hs->CryptoMod.length() > 0) {
4937 DEBUG(
"found module: "<<hs->CryptoMod);
4939 bool otherHasPad =
true;
4941 if (hs->CryptoMod.endswith(
gNoPadTag)) {
4942 otherHasPad =
false;
4946 otherHasPad =
false;
4951 sessionCF->SetTrace(GSITrace->What);
4952 if (
QTRACE(Debug)) sessionCF->Notify();
4953 if (otherHasPad && sessionCF->HasPaddingSupport()) hs->HasPad = 1;
4954 int fid = sessionCF->ID();
4957 while (i < ncrypt) {
4958 if (cryptID[i] == fid)
break;
4963 DEBUG(
"max number of crypto slots reached - do nothing");
4967 cryptF[i] = sessionCF;
4973 hs->Rcip = sessionCF->Cipher(hs->HasPad, 0,0,0);
4998int XrdSecProtocolgsi::QueryProxy(
bool checkcache,
XrdSutCache *cache,
5008 bool rdlock =
false;
5009 XrdSutCacheArg_t arg = {timestamp, -1, -1, -1};
5012 PRINT(
"cannot get cache entry for: "<<tag);
5017 if (checkcache && rdlock) {
5040 delete (XrdSutBucket *)(cent->
buf3.
buf);
5051 PRINT(
"cannot create new chain!");
5056 bool exportbucket = 0;
5059 while (!hasproxy && ntry > 0) {
5067 if (InitProxy(pi, cf, po->
chain, &(po->
ksig)) != 0) {
5068 NOTIFY(
"problems initializing proxy via external shell");
5077 timestamp = time(0);
5085 char *cbuf = getenv(
"XrdSecCREDS");
5090 xbck.SetBuf(cbuf, strlen(cbuf));
5093 PRINT(
"cannot attach to ParseBucket function!");
5096 int nci = (*ParseBucket)(&xbck, po->
chain);
5098 NOTIFY(
"proxy bucket must have at least two certificates"
5099 " (found: "<<nci<<
")");
5111 PRINT(
"cannot attach to ParseFile function!");
5117 int nci = (*ParseFile)(pi->
out, po->
chain, 0);
5119 DEBUG(
"proxy files must have at least 2 certificates"
5120 " (found: "<<nci<<
")");
5125 DEBUG(
"cert files must have at least 1 certificates"
5126 " (found: "<<nci<<
")");
5135 bool checkselfsigned = (CACheck > caVerifyss) ?
true : false;
5143 NOTIFY(
"proxy files contains expired certificates");
5149 NOTIFY(
"proxy files contains inconsistent certificates");
5156 NOTIFY(
"proxy files contain invalid key pair");
5162 PRINT(
"cannot attach to ExportChain function!");
5168 po->
cbck = (*ExportChain)(po->
chain, 0);
5170 PRINT(
"could not create bucket for export");
5214 if ((e->
status != st_ref) ||
5215 ((e->
status == st_ref) &&
5217 ((ts_ref - e->
mtime) > to_ref))) {
5243 PRINT(
"input chain undefined!");
5249 const char *dn = chain->
EECname();
5252 bool rdlock =
false;
5253 XrdSutCacheArg_t arg = {
kCE_ok, now, GMAPCacheTimeOut, -1};
5254 XrdSutCacheEntry *cent = cacheGMAPFun.Get(dn, rdlock,
QueryGMAPCheck, (
void *) &arg);
5256 PRINT(
"unable to get a valid entry from cache for dn: " << dn);
5264 char *name = (*GMAPFun)(dn, now);
5270 cent->
buf1.
len = strlen(name);
5286 if (servGMap->dn2user(dn, u,
sizeof(u), now) == 0) {
5287 if (usrs.
length() > 0) usrs +=
",";
5288 usrs += (
const char *)u;
5305 if (!plugin || strlen(plugin) <= 0) {
5306 PRINT(
"plug-in file undefined");
5311 XrdOucPinLoader gmapLib(errBuff,
sizeof(errBuff),gsiVersion,
"gmaplib",plugin);
5314 bool useglobals = 0;
5315 XrdOucString params, ps(parms), p;
5317 while ((from = ps.tokenize(p, from,
'|')) != -1) {
5318 if (p ==
"useglobals") {
5321 if (params.
length() > 0) params +=
" ";
5325 DEBUG(
"params: '"<< params<<
"'; useglobals: "<<useglobals);
5329 if (useglobals) gmapLib.Global(
true);
5334 PRINT(
"could not find 'XrdSecgsiGMAPFun()' in "<<plugin);
5339 if ((*ep)(params.
c_str(), 0) == (
char *)-1) {
5340 PRINT(
"could not initialize 'XrdSecgsiGMAPFun()'");
5345 PRINT(
"using 'XrdSecgsiGMAPFun()' from "<<plugin);
5353 const char *parms,
int &certfmt)
5398 if (!plugin || strlen(plugin) <= 0) {
5399 PRINT(
"plug-in file undefined");
5404 XrdOucPinLoader authzLib(errBuff,
sizeof(errBuff),gsiVersion,
"authzlib",plugin);
5407 bool useglobals = 0;
5408 XrdOucString params, ps(parms), p;
5410 while ((from = ps.tokenize(p, from,
'|')) != -1) {
5411 if (p ==
"useglobals") {
5414 if (params.
length() > 0) params +=
" ";
5418 DEBUG(
"params: '"<< params<<
"'; useglobals: "<<useglobals);
5422 if (useglobals) authzLib.Global(
true);
5426 PRINT(
"could not find 'XrdSecgsiAuthzFun()' in "<<plugin);
5434 PRINT(
"could not find 'XrdSecgsiAuthzKey()' in "<<plugin);
5442 PRINT(
"could not find 'XrdSecgsiAuthzInit()' in "<<plugin);
5447 if ((certfmt = (*epinit)(params.
c_str())) == -1) {
5448 PRINT(
"problems executing 'XrdSecgsiAuthzInit()' (rc: "<<certfmt<<
")");
5453 PRINT(
"using 'XrdSecgsiAuthzFun()' from "<<plugin);
5461 const char *parms,
int &certfmt)
5495 if (!plugin || strlen(plugin) <= 0) {
5496 PRINT(
"plug-in file undefined");
5501 XrdOucPinLoader vomsLib(errBuff,
sizeof(errBuff),gsiVersion,
"vomslib",plugin);
5504 bool useglobals = 0;
5505 XrdOucString params, ps(parms), p;
5507 while ((from = ps.tokenize(p, from,
'|')) != -1) {
5508 if (p ==
"useglobals") {
5511 if (params.
length() > 0) params +=
" ";
5515 DEBUG(
"params: '"<< params<<
"'; useglobals: "<<useglobals);
5519 if (useglobals) vomsLib.Global(
true);
5523 PRINT(
"could not find 'XrdSecgsiVOMSFun()' in "<<plugin);
5532 PRINT(
"could not find 'XrdSecgsiVOMSInit()' in "<<plugin);
5537 if ((certfmt = (*epinit)(params.
c_str())) == -1) {
5538 PRINT(
"problems executing 'XrdSecgsiVOMSInit()' (rc: "<<certfmt<<
")");
5543 PRINT(
"using 'XrdSecgsiVOMSFun()' from "<<plugin);
5551bool XrdSecProtocolgsi::ServerCertNameOK(
const char *subject,
const char *hname,
XrdOucString &
emsg)
5557 if (!subject || strlen(subject) <= 0)
return 0;
5565 int cnidx = srvsubj.
find(
"CN=");
5570 size_t ih = srvcn.
find(
"/");
5571 if (ih != std::string::npos) {
5578 if (
emsg.length() <= 0) {
5579 emsg =
"server certificate CN '";
emsg += srvcn;
5580 emsg +=
"' does not match the expected format(s):";
5582 String defcn(
"[*/]"); defcn += hname; defcn +=
"[/*]";
5588 if (SrvAllowedNames.length() > 0) {
5594 String allowedfmts(SrvAllowedNames);
5595 allowedfmts.replace(
"<host>", hname);
5596 allowedfmts.replace(
"<fqdn>", hname);
5599 while ((from = allowedfmts.tokenize(fmt, from,
'|')) != -1) {
5606 if (srvcn.
matches(fmt.
c_str()) > 0) allowed = (deny) ? 0 : 1;
5610 if (
emsg.length() <= 0) {
5611 emsg =
"server certificate CN '";
emsg += srvcn;
5612 emsg +=
"' does not match the expected format:";
5614 emsg +=
" '";
emsg += SrvAllowedNames;
emsg +=
"' (exceptions)";
5621 emsg +=
"; exceptions are controlled by the env XrdSecGSISRVNAMES";
5632 if (e->
status > st_ref) {
5633 if (e->
mtime >= ts_ref)
5643 time_t timestamp,
String &certcalist)
5651 PRINT(
"Invalid inputs");
5652 return (XrdSutCacheEntry *)0;
5655 bool rdlock =
false;
5656 XrdSutCacheArg_t arg = {
kCE_allowed, timestamp, -1, -1};
5659 PRINT(
"unable to get a valid entry from cache for " << cf->
Name());
5660 return (XrdSutCacheEntry *)0;
5665 if (rdlock)
return cent;
5666 if (cent->
buf1.
buf)
PRINT(
"entry has expired: trying to renew ...");
5671 ProxyIn_t pi = {SrvCert.c_str(), SrvKey.c_str(), CAdir.c_str(),
5672 UsrProxy.c_str(), PxyValid.c_str(), 0, 512,
false};
5674 XrdCryptoRSA *k = 0;
5675 XrdSutBucket *b = 0;
5676 ProxyOut_t po = {ch, k, b };
5679 if (QueryProxy(0, &cacheCert, cf->
Name(), cf, timestamp, &pi, &po) != 0) {
5680 PRINT(
"proxy expired and cannot be renewed");
5681 return (XrdSutCacheEntry *)0;
5689 XrdCryptoX509 *buf1 = (XrdCryptoX509*) cent->
buf1.
buf;
5690 XrdSutBucket *buf3 = (XrdSutBucket*) cent->
buf3.
buf;
5704 uid_t gsi_uid = geteuid();
5705 gid_t gsi_gid = getegid();
5707 if (!
stat(SrvKey.c_str(), &st)) {
5708 if (st.st_uid != gsi_uid || st.st_gid != gsi_gid) {
5709 gsi_uid = st.st_uid;
5710 gsi_gid = st.st_gid;
5715 XrdCryptoX509 *xsrv = cf->
X509(SrvCert.c_str(), SrvKey.c_str());
5719 PRINT(
"problems loading srv cert: not EEC but: "<<xsrv->
Type());
5722 return (XrdSutCacheEntry *)0;
5726 PRINT(
"problems loading srv cert: invalid");
5729 return (XrdSutCacheEntry *)0;
5733 PRINT(
"problems loading srv cert: invalid PKI");
5736 return (XrdSutCacheEntry *)0;
5739 XrdSutBucket *xbck = xsrv->
Export();
5741 PRINT(
"problems loading srv cert: cannot export into bucket");
5744 return (XrdSutCacheEntry *)0;
5748 if ((rcgetca = GetCA(xsrv->
IssuerHash(), cf)) != 0) {
5752 if ((rcgetca = GetCA(xsrv->
IssuerHash(1), cf)) != 0) {
5759 if (rcgetca == -1) {
5760 PRINT(
"do not have certificate for the issuing CA '"<<
emsg<<
"'");
5762 PRINT(
"failed to load certificate for the issuing CA '"<<
emsg<<
"'");
5767 return (XrdSutCacheEntry *)0;
5778 delete (XrdCryptoX509 *) cent->
buf1.
buf;
5779 cent->
buf1.
buf = (
char *)xsrv;
5788 delete (XrdSutBucket *) cent->
buf3.
buf;
5789 cent->
buf3.
buf = (
char *)(xbck);
5794 if (certcalist.
length() > 0) certcalist +=
"|";
5798 if (HashCompatibility && xsrv->
IssuerHash(1) &&
5801 if (certcalist.
length() > 0) certcalist +=
"|";
5806 PRINT(
"failed to load certificate from files ("<< SrvCert <<
","<<SrvKey<<
")");
void XrdCryptoSetTrace(kXR_int32 trace)
#define cryptoTRACE_Notify
#define cryptoTRACE_Debug
#define XrdCryptoDefRSABits
int(* XrdCryptoX509ChainToFile_t)(XrdCryptoX509Chain *, const char *)
int(* XrdCryptoX509CreateProxy_t)(const char *, const char *, XrdProxyOpt_t *, XrdCryptogsiX509Chain *, XrdCryptoRSA **, const char *)
int(* XrdCryptoX509SignProxyReq_t)(XrdCryptoX509 *, XrdCryptoRSA *, XrdCryptoX509Req *, XrdCryptoX509 **)
XrdSutBucket *(* XrdCryptoX509ExportChain_t)(XrdCryptoX509Chain *, bool)
int(* XrdCryptoX509ParseBucket_t)(XrdSutBucket *, XrdCryptoX509Chain *)
int(* XrdCryptoX509ParseFile_t)(const char *fname, XrdCryptoX509Chain *, const char *)
int(* XrdCryptoX509CreateProxyReq_t)(XrdCryptoX509 *, XrdCryptoX509Req **, XrdCryptoRSA **)
const int kOptsCheckSubCA
XrdOucGMap * XrdOucgetGMap(XrdOucGMapArgs)
XrdSecBuffer XrdSecParameters
XrdSecBuffer XrdSecCredentials
static bool GetCACheck(XrdSutCacheEntry *e, void *a)
static const char * gGSErrStr[]
static const char * gsiServerSteps[]
static bool QueryProxyCheck(XrdSutCacheEntry *e, void *a)
static const char * gNoPadTag
static const char * ClientStepStr(int kclt)
static const char * gUsrPxyDef
static const kXR_int32 Version
static const char * ServerStepStr(int ksrv)
static bool GetSrvCertEntCheck(XrdSutCacheEntry *e, void *a)
static bool QueryGMAPCheck(XrdSutCacheEntry *e, void *a)
XrdVERSIONINFO(XrdSecProtocolgsiObject, secgsi)
static const char * gsiClientSteps[]
XrdSecProtocol * XrdSecProtocolgsiObject(const char mode, const char *hostname, XrdNetAddrInfo &endPoint, const char *parms, XrdOucErrInfo *erp)
static bool AuthzFunCheck(XrdSutCacheEntry *e, void *a)
char * XrdSecProtocolgsiInit(const char mode, const char *parms, XrdOucErrInfo *erp)
int(* XrdSecgsiAuthz_t)(XrdSecEntity &)
XrdCryptogsiX509Chain X509Chain
XrdSecgsiAuthz_t XrdSecgsiVOMS_t
int(* XrdSecgsiAuthzKey_t)(XrdSecEntity &, char **)
#define XrdSecgsiVersCertKey
#define XrdSecgsiVersDHsigned
int(* XrdSecgsiAuthzInit_t)(const char *)
XrdSecgsiAuthzInit_t XrdSecgsiVOMSInit_t
char *(* XrdSecgsiGMAP_t)(const char *, int)
XrdCryptoX509ParseFile_t ParseFile
int emsg(int rc, char *msg)
int XrdSutParseTime(const char *tstr, int opt)
int XrdSutExpand(XrdOucString &path)
int XrdSutResolve(XrdOucString &path, const char *ho, const char *vo, const char *gr, const char *us)
const char * XrdSutHome()
const char * XrdSutBuckStr(int kbck)
void XrdSutSetTrace(kXR_int32 trace)
virtual int Encrypt(const char *in, int lin, char *out)
virtual bool HasPaddingSupport()
virtual XrdCryptoX509ParseBucket_t X509ParseBucket()
virtual XrdCryptoX509 * X509(const char *cf, const char *kf=0)
virtual void SetTrace(kXR_int32 trace)
virtual XrdCryptoX509ParseFile_t X509ParseFile()
virtual XrdCryptoX509CreateProxy_t X509CreateProxy()
virtual XrdCryptoCipher * Cipher(const char *t, int l=0)
virtual XrdCryptoX509Crl * X509Crl(const char *crlfile, int opt=0)
static XrdCryptoFactory * GetCryptoFactory(const char *factoryname)
virtual XrdCryptoX509ExportChain_t X509ExportChain()
virtual int ExportPrivate(char *out, int lout)
virtual int ImportPrivate(const char *in, int lin)
virtual int ExportPublic(char *out, int lout)
bool CheckCA(bool checkselfsigned=1)
virtual int CheckValidity(bool outatfirst=1, int when=0)
XrdCryptoX509 * EffCA() const
void Cleanup(bool keepCA=0)
void Remove(XrdCryptoX509 *c)
void SetStatusCA(ECAStatus st)
void PushBack(XrdCryptoX509 *c)
const char * X509ChainError(EX509ChainErr e)
XrdCryptoX509 * End() const
void PutInFront(XrdCryptoX509 *c)
virtual const char * IssuerHash(int)
virtual bool IsExpired(int when=0)
virtual bool Verify(XrdCryptoX509 *ref)
virtual XrdSutBucket * Export()
const char * Type(EX509Type t=kUnknown) const
virtual XrdCryptoRSA * PKI()
virtual const char * SubjectHash(int)
virtual time_t NotBefore()
virtual const char * IssuerHash(int)
virtual XrdSutBucket * Export()
static bool MatchHostnames(const char *match_pattern, const char *fqdn)
virtual bool IsValid(int when=0)
virtual time_t NotAfter()
bool Verify(EX509ChainErr &e, x509ChainVerifyOpt_t *vopt=0)
static const int noPort
Do not add port number.
static bool isHostName(const char *name)
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
@ fmtName
Hostname if it is resolvable o/w use fmtAddr.
const char * Name(const char *eName=0, const char **eText=0)
const char * Set(const char *hSpec, int pNum=PortInSpec)
char * Get(const char *varname)
const char * getErrText()
int setErrInfo(int code, const char *emsg)
void insert(const int i, int start=-1)
void assign(const char *s, int j, int k=-1)
int erasefromstart(int sz=0)
int erase(int start=0, int size=0)
int matches(const char *s, char wch=' *')
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)
int form(const char *fmt,...)
int tokenize(XrdOucString &tok, int from, char del=':')
const char * c_str() const
char * GetToken(char **rest=0, int lowcase=0)
char * vorg
Entity's virtual organization(s)
int credslen
Length of the 'creds' data.
char * creds
Raw entity credentials or cert.
char * grps
Entity's group name(s)
char * name
Entity's name.
char * role
Entity's role(s)
char * endorsements
Protocol specific endorsements.
char * moninfo
Information for monitoring.
char * host
Entity's host name dnr dependent.
XrdSecProtocol(const char *pName)
Constructor.
static XrdOucTrace * EnableTracing()
int Authenticate(XrdSecCredentials *cred, XrdSecParameters **parms, XrdOucErrInfo *einfo=0)
int Verify(const char *inbuf, int inlen, const char *sigbuf, int siglen)
XrdSecProtocolgsi(int opts, const char *hname, XrdNetAddrInfo &endPoint, const char *parms=0)
int Decrypt(const char *inbuf, int inlen, XrdSecBuffer **outbuf)
int Encrypt(const char *inbuf, int inlen, XrdSecBuffer **outbuf)
void Delete()
Delete the protocol object. DO NOT use C++ delete() on this object.
static char * Init(gsiOptions o, XrdOucErrInfo *erp)
XrdSecCredentials * getCredentials(XrdSecParameters *parm=0, XrdOucErrInfo *einfo=0)
int getKey(char *kbuf=0, int klen=0)
int Sign(const char *inbuf, int inlen, XrdSecBuffer **outbuf)
int setKey(char *kbuf, int klen)
int SetBuf(const char *nb=0, int ns=0)
void ToString(XrdOucString &s)
void Update(char *nb=0, int ns=0, int ty=0)
int AddBucket(char *bp=0, int sz=0, int ty=0)
int UpdateBucket(const char *bp, int sz, int ty)
int Serialized(char **buffer, char opt='n')
const char * GetProtocol() const
void Dump(const char *stepstr=0, bool all=false)
const char * GetOptions() const
XrdSutBucket * GetBucket(kXR_int32 type, const char *tag=0)
kXR_int32 MarshalBucket(kXR_int32 type, kXR_int32 code)
void Deactivate(kXR_int32 type)
kXR_int32 UnmarshalBucket(kXR_int32 type, kXR_int32 &code)
void UnLock(bool reset=true)
void ReadLock(XrdSysRWLock *lock=0)
void Set(XrdSysRWLock *lock)
XrdSutCacheEntry * Get(const char *tag)
static int GetRndmTag(XrdOucString &rtag)
void Dump(XrdSecProtocolgsi *p=0)
void Print(XrdOucTrace *t)
Generic structure to pass security information back and forth.
char * buffer
Pointer to the buffer.
int size
Size of the buffer or length of data in the buffer.