XRootD
Loading...
Searching...
No Matches
XrdSecProtocolgsi Class Reference

#include <XrdSecProtocolgsi.hh>

+ Inheritance diagram for XrdSecProtocolgsi:
+ Collaboration diagram for XrdSecProtocolgsi:

Public Member Functions

 XrdSecProtocolgsi (int opts, const char *hname, XrdNetAddrInfo &endPoint, const char *parms=0)
 
virtual ~XrdSecProtocolgsi ()
 
int Authenticate (XrdSecCredentials *cred, XrdSecParameters **parms, XrdOucErrInfo *einfo=0)
 
int Decrypt (const char *inbuf, int inlen, XrdSecBuffer **outbuf)
 
void Delete ()
 Delete the protocol object. DO NOT use C++ delete() on this object.
 
int Encrypt (const char *inbuf, int inlen, XrdSecBuffer **outbuf)
 
XrdSecCredentialsgetCredentials (XrdSecParameters *parm=0, XrdOucErrInfo *einfo=0)
 
int getKey (char *kbuf=0, int klen=0)
 
int setKey (char *kbuf, int klen)
 
int Sign (const char *inbuf, int inlen, XrdSecBuffer **outbuf)
 
int Verify (const char *inbuf, int inlen, const char *sigbuf, int siglen)
 
- Public Member Functions inherited from XrdSecProtocol
 XrdSecProtocol (const char *pName)
 Constructor.
 
virtual bool needTLS ()
 Check if this protocol requires TLS to properly function.
 

Static Public Member Functions

static XrdOucTraceEnableTracing ()
 
static char * Init (gsiOptions o, XrdOucErrInfo *erp)
 

Friends

class gsiHSVars
 
class gsiOptions
 

Additional Inherited Members

- Public Attributes inherited from XrdSecProtocol
XrdSecEntity Entity
 
- Protected Member Functions inherited from XrdSecProtocol
virtual ~XrdSecProtocol ()
 Destructor (prevents use of direct delete).
 

Detailed Description

Definition at line 280 of file XrdSecProtocolgsi.hh.

Constructor & Destructor Documentation

◆ XrdSecProtocolgsi()

XrdSecProtocolgsi::XrdSecProtocolgsi ( int opts,
const char * hname,
XrdNetAddrInfo & endPoint,
const char * parms = 0 )

Definition at line 293 of file XrdSecProtocolgsi.cc.

295 : XrdSecProtocol("gsi")
296{
297 // Default constructor
298 EPNAME("XrdSecProtocolgsi");
299
300 if (QTRACE(Authen)) { PRINT("constructing: "<<this); }
301
302 // Create instance of the handshake vars
303 if ((hs = new gsiHSVars())) {
304 // Update time stamp
305 hs->TimeStamp = time(0);
306 // Local handshake variables
307 hs->Tty = (isatty(0) == 0 || isatty(1) == 0) ? 0 : 1;
308 } else {
309 PRINT("could not create handshake vars object");
310 }
311
312 // Set host name and address
313 // The hostname is critical for the GSI protocol; it must match the potential
314 // names on the remote EEC. We default to the hostname requested by the user to
315 // the client (or proxy). However, as we may have been redirected to an IP
316 // address instead of an actual hostname, we must fallback to a reverse DNS lookup.
317 // As of time of testing (June 2018), EOS will redirect to an IP address to handle
318 // metadata commands and rely on the reverse DNS lookup for GSI security to function.
319 // Hence, this fallback likely needs to be kept for some time.
320 //
321 // We provide servers a switch and clients an environment variable to override all
322 // usage of DNS (processed on XrdSecProtocolgsiInit).
323 // Default is to fallback to DNS lookups in limited
324 // cases for backward compatibility.
325 expectedHost = NULL;
326 if (TrustDNS) {
327 if (!hname || !XrdNetAddrInfo::isHostName(hname)) {
328 Entity.host = strdup(endPoint.Name(""));
329 } else {
330 // At this point, hname still may possibly be a non-qualified domain name.
331 // If there is a '.' character, then we assume it is a qualified domain name --
332 // otherwise, we use DNS.
333 //
334 // NOTE: We can definitively test whether this is a qualified domain name by
335 // simply appending a '.' to `hname` and performing a lookup. However, this
336 // causes DNS to be used by every lookup - meaning we rely on the security
337 // of DNS for all cases; we want to avoid this.
338 if (strchr(hname, '.')) {
339 // We have a valid hostname; proceed.
340 Entity.host = strdup(hname);
341 } else {
342 XrdNetAddr xrd_addr;
343 char canonname[256];
344 if (!xrd_addr.Set(hname) || (xrd_addr.Format(canonname, 256, XrdNetAddrInfo::fmtName, XrdNetAddrInfo::noPort) <= 0)) {
345 Entity.host = strdup(hname);
346 } else {
347 Entity.host = strdup(canonname);
348 }
349 }
350 }
351 } else {
352 // We have been told via environment variable to not trust DNS; use the exact
353 // hostname provided by the user.
354// char dnBuff[256];
355// getdomainname(dnBuff, sizeof(dnBuff));
356 Entity.host = strdup(hname);
357 expectedHost = strdup(hname);
358 }
359 epAddr = endPoint;
360 Entity.addrInfo = &epAddr;
361
362 // Init session variables
363 sessionCF = 0;
364 sessionKey = 0;
365 bucketKey = 0;
366 sessionMD = 0;
367 sessionKsig = 0;
368 sessionKver = 0;
369 sessionKver = 0;
370 proxyChain = 0;
371 useIV = false;
372
373 //
374 // Notify, if required
375 DEBUG("constructing: host: "<< Entity.host);
376 DEBUG("p: "<<XrdSecPROTOIDENT<<", plen: "<<XrdSecPROTOIDLEN);
377 //
378 // basic settings
379 options = opts;
380 srvMode = 0;
381
382 //
383 // Mode specific initializations
384 if (Server) {
385 srvMode = 1;
386 DEBUG("mode: server");
387 } else {
388 DEBUG("mode: client");
389 //
390 // Decode received buffer
391 if (parms) {
392 XrdOucString p("&P=gsi,");
393 p += parms;
394 hs->Parms = new XrdSutBuffer(p.c_str(), p.length());
395 }
396 }
397
398 // We are done
399 String vers = Version;
400 vers.insert('.',vers.length()-2);
401 vers.insert('.',vers.length()-5);
402 DEBUG("object created: v"<<vers.c_str());
403}
#define DEBUG(x)
#define EPNAME(x)
#define QTRACE(act)
#define PRINT(y)
static const kXR_int32 Version
#define XrdSecPROTOIDLEN
#define XrdSecPROTOIDENT
struct myOpts opts
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)
void insert(const int i, int start=-1)
int length() const
const char * c_str() const
XrdNetAddrInfo * addrInfo
Entity's connection details.
char * host
Entity's host name dnr dependent.
XrdSecEntity Entity
XrdSecProtocol(const char *pName)
Constructor.
XrdSutBuffer * Parms

References XrdSecEntity::addrInfo, XrdOucString::c_str(), DEBUG, XrdSecProtocol::Entity, EPNAME, XrdNetAddrInfo::fmtName, XrdNetAddrInfo::Format(), gsiHSVars, XrdSecEntity::host, XrdOucString::insert(), XrdNetAddrInfo::isHostName(), XrdOucString::length(), XrdNetAddrInfo::Name(), XrdNetAddrInfo::noPort, opts, gsiHSVars::Parms, PRINT, QTRACE, XrdNetAddr::Set(), gsiHSVars::TimeStamp, gsiHSVars::Tty, Version, XrdSecPROTOIDENT, and XrdSecPROTOIDLEN.

+ Here is the call graph for this function:

◆ ~XrdSecProtocolgsi()

virtual XrdSecProtocolgsi::~XrdSecProtocolgsi ( )
inlinevirtual

Definition at line 294 of file XrdSecProtocolgsi.hh.

294{} // Delete() does it all

Member Function Documentation

◆ Authenticate()

int XrdSecProtocolgsi::Authenticate ( XrdSecCredentials * cred,
XrdSecParameters ** parms,
XrdOucErrInfo * einfo = 0 )
virtual

Authenticate a client.

Parameters
credCredentials supplied by the client.
parmsPlace where the address of additional authentication data is to be placed for another autrhentication handshake.
einfoThe error information object where error messages should be placed. The messages are returned to the client. Should einfo be null, messages should be written to stderr.
Returns
> 0 -> parms present (more authentication needed) = 0 -> Entity present (authentication suceeded) < 0 -> einfo present (error has occurred)

Implements XrdSecProtocol.

Definition at line 1748 of file XrdSecProtocolgsi.cc.

1751{
1752 //
1753 // Check if we have any credentials or if no credentials really needed.
1754 // In either case, use host name as client name
1755 EPNAME("Authenticate");
1756
1757 //
1758 // If cred buffer is two small or empty assume host protocol
1759 if (cred->size <= (int)XrdSecPROTOIDLEN || !cred->buffer) {
1760 strncpy(Entity.prot, "host", sizeof(Entity.prot));
1761 return 0;
1762 }
1763
1764 // Handshake vars conatiner must be initialized at this point
1765 if (!hs)
1766 return ErrS(Entity.tident,ei,0,0,0,kGSErrError,
1767 "handshake var container missing",
1768 "protocol initialization problems");
1769
1770 // Update time stamp
1771 hs->TimeStamp = time(0);
1772
1773 //
1774 // ID of this handshaking
1775 if (hs->ID.length() <= 0)
1776 hs->ID = Entity.tident;
1777 DEBUG("handshaking ID: " << hs->ID);
1778
1779 // Local vars
1780 int kS_rc = kgST_more;
1781 int step = 0;
1782 int nextstep = 0;
1783 char *bpub = 0;
1784 int lpub = 0;
1785 bool vomsFailed = false;
1786 const char *stepstr = 0;
1787 String Message;
1789 String Ciphers;
1790 String Host;
1791 String SrvPuKExp;
1792 String Salt;
1793 String RndmTag;
1794 String ClntMsg(256);
1795 // Buffer related
1796 XrdSutBuffer *bpar = 0; // Global buffer
1797 XrdSutBuffer *bmai = 0; // Main buffer
1798 XrdSutBucket *bck = 0; // Generic bucket
1799 // Proxy export related
1800 XrdOucString spxy;
1801 XrdSutBucket *bpxy = 0;
1802
1803 //
1804 // Decode received buffer
1805 if (!(bpar = new XrdSutBuffer((const char *)cred->buffer,cred->size)))
1806 return ErrS(hs->ID,ei,0,0,0,kGSErrDecodeBuffer,"global",stepstr);
1807 //
1808 // Check protocol ID name
1809 if (strcmp(bpar->GetProtocol(),XrdSecPROTOIDENT))
1810 return ErrS(hs->ID,ei,bpar,bmai,0,kGSErrBadProtocol,stepstr);
1811 //
1812 // The step indicates what we are supposed to do
1813 step = bpar->GetStep();
1814 stepstr = ClientStepStr(step);
1815 // Dump, if requested
1816 XrdOucString bmsg;
1817 if (QTRACE(Dump)) {
1818 bmsg.form("IN: bpar: %s", stepstr);
1819 bpar->Dump(bmsg.c_str());
1820 }
1821 //
1822 // Parse input buffer
1823 if (ParseServerInput(bpar, &bmai, ClntMsg) == -1) {
1824 DEBUG(ClntMsg);
1825 return ErrS(hs->ID,ei,bpar,bmai,0,kGSErrParseBuffer,ClntMsg.c_str(),stepstr);
1826 }
1827 //
1828 // Version
1829 DEBUG("version run by client: "<< hs->RemVers);
1830 DEBUG("options req by client: "<< hs->Options);
1831 //
1832 // Dump, if requested
1833 if (QTRACE(Dump)) {
1834 if (bmai) {
1835 bmsg.form("IN: bmai: %s", stepstr);
1836 bmai->Dump(bmsg.c_str());
1837 }
1838 }
1839 //
1840 // Check random challenge
1841 if (!CheckRtag(bmai, ClntMsg))
1842 return ErrS(hs->ID,ei,bpar,bmai,0,kGSErrBadRndmTag,stepstr,ClntMsg.c_str());
1843
1844 // Extract the VOMS attrbutes, if required
1845 XrdCryptoX509ExportChain_t X509ExportChain = (sessionCF) ? sessionCF->X509ExportChain() : 0;
1846 if (!X509ExportChain) {
1847 // Error
1848 return ErrS(hs->ID,ei,0,0,0,kGSErrError,
1849 "crypto factory function for chain export not found");
1850 }
1851
1852 //
1853 // Now action depens on the step
1854 switch (step) {
1855
1856 case kXGC_certreq:
1857 //
1858 // Client required us to send our certificate and cipher DH public parameters:
1859 // add first this last one.
1860 // Extract buffer with public info for the cipher agreement
1861 if (!(bpub = hs->Rcip->Public(lpub)))
1862 return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrNoPublic,
1863 "session",stepstr);
1864
1865 // If client supports decoding of signed DH, do sign them
1866 if (hs->RemVers >= XrdSecgsiVersDHsigned) {
1867 bck = new XrdSutBucket(bpub,lpub,kXRS_cipher);
1868 if (sessionKsig) {
1869 //
1870 // Encrypt server DH public parameters with server key
1871 if (sessionKsig->EncryptPrivate(*bck) <= 0)
1872 return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrExportPuK,
1873 "encrypting server DH public parameters",stepstr);
1874 } else {
1875 return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrExportPuK,
1876 "server signing key undefined!",stepstr);
1877 }
1878 } else {
1879 // Previous naming
1880 bck = new XrdSutBucket(bpub,lpub,kXRS_puk);
1881 }
1882
1883 //
1884 // Add it to the global list
1885 if (bpar->AddBucket(bck) != 0)
1886 return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrAddBucket,
1887 "main",stepstr);
1888
1889 //
1890 // Add bucket with list of supported ciphers
1891 if (bpar->AddBucket(DefCipher,kXRS_cipher_alg) != 0)
1892 return ErrS(hs->ID,ei,bpar,bmai,0,
1894 //
1895 // Add bucket with list of supported MDs
1896 if (bpar->AddBucket(DefMD,kXRS_md_alg) != 0)
1897 return ErrS(hs->ID,ei,bpar,bmai,0,
1899 //
1900 // Add the server certificate
1901 bpar->AddBucket(hs->Cbck);
1902
1903 // We are done for the moment
1904 nextstep = kXGS_cert;
1905 break;
1906
1907 case kXGC_cert:
1908 //
1909 // Client sent its own credentials: their are checked in
1910 // ParseServerInput, so if we are here they are OK
1911 kS_rc = kgST_ok;
1912 nextstep = kXGS_none;
1913
1914 if (GMAPOpt > 0) {
1915 // Get name from gridmap
1916 String name;
1917 QueryGMAP(hs->Chain, hs->TimeStamp, name);
1918 DEBUG("username(s) associated with this DN: "<<name);
1919 if (name.length() <= 0) {
1920 // Grid map lookup failure
1921 if (GMAPOpt == 2) {
1922 // It was required, so we fail
1923 kS_rc = kgST_error;
1924 PRINT("ERROR: user mapping required, but lookup failed - failure");
1925 break;
1926 } else {
1927 NOTIFY("WARNING: user mapping lookup failed - use DN or DN-hash as name");
1928 }
1929 } else {
1930 //
1931 // Extract user login name, if any
1932 XrdSutBucket *bck = 0;
1933 String user;
1934 if ((bck = bmai->GetBucket(kXRS_user))) {
1935 bck->ToString(user);
1936 bmai->Deactivate(kXRS_user);
1937 }
1938 DEBUG("target user: "<<user);
1939 if (user.length() > 0) {
1940 // Check if the wanted username is authorized
1941 String u;
1942 int from = 0;
1943 bool ok = 0;
1944 while ((from = name.tokenize(u, from, ',')) != -1) {
1945 if (user == u) { ok = 1; break; }
1946 }
1947 if (ok) {
1948 name = u;
1949 DEBUG("DN mapping: requested user is authorized: name is '"<<name<<"'");
1950 } else {
1951 // The requested username is not in the list; we warn and default to the first
1952 // found (to be Globus compliant)
1953 if (name.find(',') != STR_NPOS) name.erase(name.find(','));
1954 PRINT("WARNING: user mapping lookup ok, but the requested user is not"
1955 " authorized ("<<user<<"). Instead, mapped as " << name << ".");
1956 }
1957 } else {
1958 // No username requested: we default to the first found (to be Globus compliant)
1959 if (name.find(',') != STR_NPOS) name.erase(name.find(','));
1960 DEBUG("user mapping lookup successful: name is '"<<name<<"'");
1961 }
1962 Entity.name = strdup(name.c_str());
1963 Entity.eaAPI->Add("gridmap.name", "1", true);
1964 }
1965 }
1966 // If not set, use DN
1967 if (!Entity.name || (strlen(Entity.name) <= 0)) {
1968 // No grid map: set the hash of the client DN as name
1969 if (!GMAPuseDNname && hs->Chain->EEChash()) {
1970 Entity.name = strdup(hs->Chain->EEChash());
1971 } else if (GMAPuseDNname && hs->Chain->EECname()) {
1972 Entity.name = strdup(hs->Chain->EECname());
1973 } else {
1974 PRINT("WARNING: DN missing: corruption? ");
1975 }
1976 }
1977
1978 // Add the DN as default moninfo if requested (the authz plugin may change this)
1979 if (MonInfoOpt > 0 || ShowDN) {
1980 const char *theDN = hs->Chain->EECname();
1981 if (theDN) {
1982 if (ShowDN && !GMAPuseDNname) {
1983 PRINT(Entity.name<<" Subject DN='"<<theDN<<"'");
1984 }
1985 if (MonInfoOpt > 0) Entity.moninfo = strdup(theDN);
1986 }
1987 }
1988
1989 if (VOMSAttrOpt > vatIgnore && VOMSFun) {
1990 // Fill the information needed by the external function
1991 if (VOMSCertFmt == 1) {
1992 // PEM base64
1993 bpxy = (*X509ExportChain)(hs->Chain, true);
1994 bpxy->ToString(spxy);
1995 delete bpxy;
1996 Entity.creds = strdup(spxy.c_str());
1997 Entity.credslen = spxy.length();
1998 } else {
1999 // Raw (opaque) format, to be used with XrdCrypto
2000 Entity.creds = (char *) hs->Chain;
2001 Entity.credslen = 0;
2002 }
2003 if ((*VOMSFun)(Entity) != 0) {
2004 vomsFailed = true;
2005 if (VOMSAttrOpt == vatRequire) {
2006 // Error
2007 kS_rc = kgST_error;
2008 PRINT("ERROR: the VOMS extraction plug-in reported "
2009 "authentication failure");
2010 break;
2011 }
2012 }
2013 NOTIFY("VOMS: Entity.vorg: "<< (Entity.vorg ? Entity.vorg : "<none>"));
2014 NOTIFY("VOMS: Entity.grps: "<< (Entity.grps ? Entity.grps : "<none>"));
2015 NOTIFY("VOMS: Entity.role: "<< (Entity.role ? Entity.role : "<none>"));
2016 NOTIFY("VOMS: Entity.endorsements: "<< (Entity.endorsements ? Entity.endorsements : "<none>"));
2017 }
2018
2019 // Here prepare/extract the information for authorization
2020 spxy = "";
2021 bpxy = 0;
2022 if (AuthzFun && AuthzKey && (AuthzAlways || vomsFailed)) {
2023 // Fill the information needed by the external function
2024 if (AuthzCertFmt == 1) {
2025 // May have been already done
2026 if (!Entity.creds || (Entity.creds && Entity.credslen == 0)) {
2027 // PEM base64
2028 bpxy = (*X509ExportChain)(hs->Chain, true);
2029 bpxy->ToString(spxy);
2030 Entity.creds = strdup(spxy.c_str());
2031 Entity.credslen = spxy.length();
2032 // If not empty Entity.creds is a pointer to hs->Chain and
2033 // we need not to free it
2034 }
2035 } else {
2036 // May have been already done
2037 if (Entity.creds && Entity.credslen > 0) {
2038 // Entity.creds is in PEM form, we need to free it
2039 free(Entity.creds);
2040 // Raw (opaque) format, to be used with XrdCrypto
2041 Entity.creds = (char *) hs->Chain;
2042 Entity.credslen = 0;
2043 }
2044 }
2045 // Get the key
2046 char *key = 0;
2047 int lkey = 0;
2048 if ((lkey = (*AuthzKey)(Entity, &key)) < 0) {
2049 // Fatal error
2050 kS_rc = kgST_error;
2051 PRINT("ERROR: unable to get the key associated to this user");
2052 break;
2053 }
2054 const char *dn = (const char *)key;
2055 time_t now = hs->TimeStamp;
2056 // We may have it in the cache
2057 XrdSutCERef ceref;
2058 bool rdlock = false;
2059 XrdSutCacheArg_t arg = {kCE_ok, now, AuthzCacheTimeOut, kCE_disabled};
2060 XrdSutCacheEntry *cent = cacheAuthzFun.Get(dn, rdlock, AuthzFunCheck, (void *) &arg);
2061 if (!cent) {
2062 // Fatal error
2063 kS_rc = kgST_error;
2064 PRINT("ERROR: unable to get cache entry for dn: "<<dn);
2065 break;
2066 }
2067 ceref.Set(&(cent->rwmtx));
2068 if (!rdlock) {
2069 if (cent->buf1.buf)
2070 FreeEntity((XrdSecEntity *) cent->buf1.buf);
2071 SafeDelete(cent->buf1.buf);
2072 SafeDelete(cent->buf2.buf);
2073 }
2074 if (cent->status != kCE_ok) {
2075 int authzrc = 0;
2076 if ((authzrc = (*AuthzFun)(Entity)) != 0) {
2077 // Error
2078 kS_rc = kgST_error;
2079 PRINT("ERROR: the authz plug-in reported failure");
2080 SafeDelete(key);
2081 ceref.UnLock();
2082 break;
2083 } else {
2084 cent->status = kCE_ok;
2085 // Save a copy of the relevant Entity fields
2086 XrdSecEntity *se = new XrdSecEntity();
2087 int slen = 0;
2088 CopyEntity(&Entity, se, &slen);
2089 FreeEntity((XrdSecEntity *) cent->buf1.buf);
2090 SafeDelete(cent->buf1.buf);
2091 cent->buf1.buf = (char *) se;
2092 cent->buf1.len = slen;
2093 // Proxy expiration time
2094 int notafter = hs->Chain->End() ? hs->Chain->End()->NotAfter() : -1;
2095 cent->buf2.buf = (char *) new int(notafter);
2096 cent->buf2.len = sizeof(int);
2097 // Fill up the rest
2098 cent->cnt = 0;
2099 cent->mtime = now; // creation time
2100 // Notify
2101 DEBUG("Saved Entity to cacheAuthzFun ("<<slen<<" bytes)");
2102 }
2103 } else {
2104 // Fetch a copy of the saved entity
2105 int slen = 0;
2106 FreeEntity(&Entity);
2107 CopyEntity((XrdSecEntity *) cent->buf1.buf, &Entity, &slen);
2108 // Notify
2109 DEBUG("Got Entity from cacheAuthzFun ("<<slen<<" bytes)");
2110 }
2111 // Release lock
2112 ceref.UnLock();
2113 // Cleanup
2114 SafeDelArray(key);
2115 }
2116
2117 // Export proxy for authorization, if required
2118 if (AuthzPxyWhat >= azFull) {
2119 if (bpxy && AuthzPxyWhat == azLast) {
2120 SafeDelete(bpxy); spxy = "";
2122 Entity.credslen = 0;
2123 }
2124 if (!bpxy) {
2125 if (AuthzPxyWhat == 1 && hs->Chain->End()) {
2126 bpxy = hs->Chain->End()->Export();
2127 } else {
2128 bpxy = (*X509ExportChain)(hs->Chain, true);
2129 }
2130 bpxy->ToString(spxy);
2131 }
2132 if (AuthzPxyWhere == azCred) {
2133 Entity.creds = strdup(spxy.c_str());
2134 Entity.credslen = spxy.length();
2135 } else {
2136 // This should be deprecated
2137 Entity.endorsements = strdup(spxy.c_str());
2138 }
2139 delete bpxy;
2140 NOTIFY("Entity.endorsements: "<<(void *)Entity.endorsements);
2141 NOTIFY("Entity.creds: "<<(void *)Entity.creds);
2142 NOTIFY("Entity.credslen: "<<Entity.credslen);
2143
2144 } else if (bpxy) {
2145 // Cleanup
2146 SafeDelete(bpxy); spxy = "";
2147 }
2148
2149 if (hs->RemVers >= 10100) {
2150 if (hs->PxyChain) {
2151 // The client is going to send over info for delegation
2152 kS_rc = kgST_more;
2153 nextstep = kXGS_pxyreq;
2154 }
2155 }
2156
2157 break;
2158
2159 case kXGC_sigpxy:
2160 //
2161 // Nothing to do after this
2162 kS_rc = kgST_ok;
2163 nextstep = kXGS_none;
2164 //
2165 // If something went wrong, print explanation
2166 if (ClntMsg.length() > 0) {
2167 PRINT(ClntMsg);
2168 }
2169 break;
2170
2171 default:
2172 return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrBadOpt, stepstr);
2173 }
2174
2175 if (kS_rc == kgST_more) {
2176 //
2177 // Add message to client
2178 if (ClntMsg.length() > 0)
2179 if (bmai->AddBucket(ClntMsg,kXRS_message) != 0) {
2180 NOTIFY("problems adding bucket with message for client");
2181 }
2182 //
2183 // Serialize, encrypt and add to the global list
2184 if (AddSerialized('s', nextstep, hs->ID,
2185 bpar, bmai, kXRS_main, sessionKey) != 0) {
2186 return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrSerialBuffer,
2187 "main / session cipher",stepstr);
2188 }
2189 //
2190 // Serialize the global buffer
2191 char *bser = 0;
2192 int nser = bpar->Serialized(&bser,'f');
2193 //
2194 // Dump, if requested
2195 if (QTRACE(Authen)) {
2196 bmsg.form("OUT: bpar: %s", ServerStepStr(bpar->GetStep()));
2197 bpar->Dump(bmsg.c_str());
2198 bmsg.form("OUT: bmai: %s", ServerStepStr(bpar->GetStep()));
2199 bmai->Dump(bmsg.c_str());
2200 }
2201 //
2202 // Create buffer for client
2203 *parms = new XrdSecParameters(bser,nser);
2204
2205 } else {
2206 //
2207 // Cleanup handshake vars
2208 SafeDelete(hs);
2209 }
2210 //
2211 // We may release the buffers now
2212 REL2(bpar,bmai);
2213 //
2214 // All done
2215 return kS_rc;
2216}
XrdSutBucket *(* XrdCryptoX509ExportChain_t)(XrdCryptoX509Chain *, bool)
#define STR_NPOS
XrdSecBuffer XrdSecParameters
static const char * ClientStepStr(int kclt)
static const char * ServerStepStr(int ksrv)
static bool AuthzFunCheck(XrdSutCacheEntry *e, void *a)
#define SafeDelete(x)
#define REL2(x, y)
@ kXGS_cert
@ kXGS_none
@ kXGS_pxyreq
#define XrdSecgsiVersDHsigned
@ kgST_ok
@ kgST_error
@ kgST_more
#define SafeFree(x)
#define SafeDelArray(x)
@ kXGC_sigpxy
@ kXGC_cert
@ kXGC_certreq
@ kGSErrExportPuK
@ kGSErrBadRndmTag
@ kGSErrParseBuffer
@ kGSErrBadProtocol
@ kGSErrNoPublic
@ kGSErrSerialBuffer
@ kGSErrDecodeBuffer
@ kGSErrBadOpt
@ kGSErrAddBucket
@ kGSErrError
#define NOTIFY(y)
XrdOucString CryptList
const char * XrdSutBuckStr(int kbck)
Definition XrdSutAux.cc:121
@ kXRS_user
Definition XrdSutAux.hh:65
@ kXRS_cipher_alg
Definition XrdSutAux.hh:82
@ kXRS_message
Definition XrdSutAux.hh:68
@ kXRS_puk
Definition XrdSutAux.hh:61
@ kXRS_cipher
Definition XrdSutAux.hh:62
@ kXRS_main
Definition XrdSutAux.hh:58
@ kXRS_md_alg
Definition XrdSutAux.hh:83
@ kCE_ok
@ kCE_disabled
virtual char * Public(int &lpub)
virtual XrdCryptoX509ExportChain_t X509ExportChain()
virtual int EncryptPrivate(const char *in, int lin, char *out, int lout)
XrdCryptoX509 * End() const
virtual XrdSutBucket * Export()
virtual time_t NotAfter()
int erase(int start=0, int size=0)
int find(const char c, int start=0, bool forward=1)
int form(const char *fmt,...)
int tokenize(XrdOucString &tok, int from, char del=':')
bool Add(XrdSecAttr &attr)
char * vorg
Entity's virtual organization(s)
int credslen
Length of the 'creds' data.
XrdSecEntityAttr * eaAPI
non-const API to attributes
const char * tident
Trace identifier always preset.
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
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.
void ToString(XrdOucString &s)
int AddBucket(char *bp=0, int sz=0, int ty=0)
int Serialized(char **buffer, char opt='n')
const char * GetProtocol() const
void Dump(const char *stepstr=0, bool all=false)
int GetStep() const
XrdSutBucket * GetBucket(kXR_int32 type, const char *tag=0)
void Deactivate(kXR_int32 type)
void UnLock(bool reset=true)
void Set(XrdSysRWLock *lock)
XrdSutCacheEntryBuf buf2
XrdSutCacheEntryBuf buf1
XrdSutCacheEntry * Get(const char *tag)
X509Chain * PxyChain
XrdSutBucket * Cbck
X509Chain * Chain
XrdCryptoCipher * Rcip
char * buffer
Pointer to the buffer.
int size
Size of the buffer or length of data in the buffer.

References XrdSecEntityAttr::Add(), XrdSutBuffer::AddBucket(), AuthzFunCheck(), XrdSutCacheEntryBuf::buf, XrdSutCacheEntry::buf1, XrdSutCacheEntry::buf2, XrdSecBuffer::buffer, XrdOucString::c_str(), gsiHSVars::Cbck, gsiHSVars::Chain, ClientStepStr(), XrdSutCacheEntry::cnt, XrdSecEntity::creds, XrdSecEntity::credslen, CryptList, XrdSutBuffer::Deactivate(), DEBUG, XrdSutBuffer::Dump(), XrdSecEntity::eaAPI, XrdCryptoX509Chain::EEChash(), XrdCryptoX509Chain::EECname(), XrdCryptoRSA::EncryptPrivate(), XrdCryptoX509Chain::End(), XrdSecEntity::endorsements, XrdSecProtocol::Entity, EPNAME, XrdOucString::erase(), XrdCryptoX509::Export(), XrdOucString::find(), XrdOucString::form(), XrdSutCache::Get(), XrdSutBuffer::GetBucket(), XrdSutBuffer::GetProtocol(), XrdSutBuffer::GetStep(), XrdSecEntity::grps, gsiHSVars::ID, kCE_disabled, kCE_ok, kGSErrAddBucket, kGSErrBadOpt, kGSErrBadProtocol, kGSErrBadRndmTag, kGSErrDecodeBuffer, kGSErrError, kGSErrExportPuK, kGSErrNoPublic, kGSErrParseBuffer, kGSErrSerialBuffer, kgST_error, kgST_more, kgST_ok, kXGC_cert, kXGC_certreq, kXGC_sigpxy, kXGS_cert, kXGS_none, kXGS_pxyreq, kXRS_cipher, kXRS_cipher_alg, kXRS_main, kXRS_md_alg, kXRS_message, kXRS_puk, kXRS_user, XrdSutCacheEntryBuf::len, XrdOucString::length(), XrdSecEntity::moninfo, XrdSutCacheEntry::mtime, XrdSecEntity::name, XrdCryptoX509::NotAfter(), NOTIFY, gsiHSVars::Options, PRINT, XrdSecEntity::prot, XrdCryptoCipher::Public(), gsiHSVars::PxyChain, QTRACE, gsiHSVars::Rcip, REL2, gsiHSVars::RemVers, XrdSecEntity::role, XrdSutCacheEntry::rwmtx, SafeDelArray, SafeDelete, SafeFree, XrdSutBuffer::Serialized(), ServerStepStr(), XrdSutCERef::Set(), XrdSecBuffer::size, XrdSutCacheEntry::status, STR_NPOS, XrdSecEntity::tident, gsiHSVars::TimeStamp, XrdOucString::tokenize(), XrdSutBucket::ToString(), XrdSutCERef::UnLock(), XrdSecEntity::vorg, XrdCryptoFactory::X509ExportChain(), XrdSecgsiVersDHsigned, XrdSecPROTOIDENT, XrdSecPROTOIDLEN, and XrdSutBuckStr().

+ Here is the call graph for this function:

◆ Decrypt()

int XrdSecProtocolgsi::Decrypt ( const char * inbuff,
int inlen,
XrdSecBuffer ** outbuff )
virtual

Decrypt data in inbuff using the session key.

Parameters
inbuffbuffer holding data to be decrypted.
inlenlength of the data.
outbuffplace where a pointer to the decrypted data is placed.
Returns
< 0 Failed,the return value is -errno (see Encrypt). = 0 Success, outbuff contains a pointer to the decrypted data. The caller is responsible for deleting the returned object.

Reimplemented from XrdSecProtocol.

Definition at line 1151 of file XrdSecProtocolgsi.cc.

1154{
1155 // Decrypt data in inbuff and place it in outbuff.
1156 //
1157 // Returns: < 0 Failed,the return value is -errno (see Encrypt).
1158 // = 0 Success, outbuff contains a pointer to the encrypted data.
1159 EPNAME("Decrypt");
1160
1161 // We must have a key
1162 if (!sessionKey)
1163 return -ENOENT;
1164
1165 // And something to decrypt
1166 if (!inbuf || inlen <= 0 || !outbuf)
1167 return -EINVAL;
1168
1169 // Size
1170 int liv = (useIV) ? sessionKey->MaxIVLength() : 0;
1171 int sz = inlen - liv;
1172 // Get output buffer
1173 char *buf = (char *)malloc(sessionKey->DecOutLength(sz) + liv);
1174 if (!buf)
1175 return -ENOMEM;
1176
1177 // Get and set IV
1178 if (useIV) {
1179 char *iv = new char[liv];
1180 memcpy(iv, inbuf, liv);
1181 sessionKey->SetIV(liv, iv);
1182 delete[] iv;
1183 }
1184
1185 // Decrypt
1186 int len = sessionKey->Decrypt(inbuf + liv, sz, buf);
1187 if (len <= 0) {
1188 SafeFree(buf);
1189 return -EINVAL;
1190 }
1191
1192 // Create and fill output buffer
1193 *outbuf = new XrdSecBuffer(buf, len);
1194
1195 // We are done
1196 DEBUG("decrypted buffer has "<<len<<" bytes");
1197 return 0;
1198}
virtual void SetIV(int l, const char *iv)
virtual int Decrypt(const char *in, int lin, char *out)
virtual int DecOutLength(int l)
virtual int MaxIVLength() const
Generic structure to pass security information back and forth.

References DEBUG, XrdCryptoCipher::DecOutLength(), XrdCryptoCipher::Decrypt(), EPNAME, XrdCryptoCipher::MaxIVLength(), SafeFree, and XrdCryptoCipher::SetIV().

+ Here is the call graph for this function:

◆ Delete()

void XrdSecProtocolgsi::Delete ( )
virtual

Delete the protocol object. DO NOT use C++ delete() on this object.

Implements XrdSecProtocol.

Definition at line 1058 of file XrdSecProtocolgsi.cc.

1059{
1060 // Deletes the protocol
1068 if (Entity.creds && Entity.credslen > 0) {
1070 } else {
1071 Entity.creds = 0;
1072 }
1073 Entity.credslen = 0;
1075 // Cleanup the handshake variables, if still there
1076 SafeDelete(hs);
1077 // Cleanup any other instance specific to this protocol
1078 SafeDelete(sessionKey); // Session Key (result of the handshake)
1079 SafeDelete(bucketKey); // Bucket with the key in export form
1080 SafeDelete(sessionMD); // Message Digest instance
1081 SafeDelete(sessionKsig); // RSA key to sign
1082 SafeDelete(sessionKver); // RSA key to verify
1083 if (proxyChain) proxyChain->Cleanup();
1084 SafeDelete(proxyChain); // Chain with delegated proxies
1085 SafeFree(expectedHost);
1086
1087 delete this;
1088}
void Cleanup(bool keepCA=0)
char * caps
Entity's capabilities.

References XrdSecEntity::caps, XrdCryptoX509Chain::Cleanup(), XrdSecEntity::creds, XrdSecEntity::credslen, XrdSecEntity::endorsements, XrdSecProtocol::Entity, XrdSecEntity::grps, XrdSecEntity::host, XrdSecEntity::moninfo, XrdSecEntity::name, XrdSecEntity::role, SafeDelete, SafeFree, and XrdSecEntity::vorg.

+ Here is the call graph for this function:

◆ EnableTracing()

XrdOucTrace * XrdSecProtocolgsi::EnableTracing ( )
static

Definition at line 2276 of file XrdSecProtocolgsi.cc.

2277{
2278 // Initiate error logging and tracing
2279
2280 eDest.logger(&Logger);
2281 GSITrace = new XrdOucTrace(&eDest);
2282 return GSITrace;
2283}
XrdSysLogger * logger(XrdSysLogger *lp=0)

References eDest, Logger, and XrdSysError::logger().

Referenced by XrdSecProtocolgsiInit().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Encrypt()

int XrdSecProtocolgsi::Encrypt ( const char * inbuff,
int inlen,
XrdSecBuffer ** outbuff )
virtual

Encrypt data in inbuff using the session key.

Parameters
inbuffbuffer holding data to be encrypted.
inlenlength of the data.
outbuffplace where a pointer to the encrypted data is placed.
Returns
< 0 Failed, the return value is -errno of the reason. Typically, -EINVAL - one or more arguments are invalid. -NOTSUP - encryption not supported by the protocol -ENOENT - Context not innitialized = 0 Success, outbuff contains a pointer to the encrypted data. The caller is responsible for deleting the returned object.

Reimplemented from XrdSecProtocol.

Definition at line 1096 of file XrdSecProtocolgsi.cc.

1099{
1100 // Encrypt data in inbuff and place it in outbuff.
1101 //
1102 // Returns: < 0 Failed, the return value is -errno of the reason. Typically,
1103 // -EINVAL - one or more arguments are invalid.
1104 // -ENOTSUP - encryption not supported by the protocol
1105 // -EOVERFLOW - outbuff is too small to hold result
1106 // -ENOENT - Context not initialized
1107 // = 0 Success, outbuff contains a pointer to the encrypted data.
1108 //
1109 EPNAME("Encrypt");
1110
1111 // We must have a key
1112 if (!sessionKey)
1113 return -ENOENT;
1114
1115 // And something to encrypt
1116 if (!inbuf || inlen <= 0 || !outbuf)
1117 return -EINVAL;
1118
1119 // Regenerate IV
1120 int liv = 0;
1121 char *iv = 0;
1122 if (useIV) {
1123 iv = sessionKey->RefreshIV(liv); // no need to call sessionKeySetIV as
1124 // RefreshIV will set the internal value
1125 }
1126
1127 // Get output buffer
1128 char *buf = (char *)malloc(sessionKey->EncOutLength(inlen) + liv);
1129 if (!buf)
1130 return -ENOMEM;
1131 // IV at beginning
1132 memcpy(buf, iv, liv);
1133
1134 // Encrypt
1135 int len = sessionKey->Encrypt(inbuf, inlen, buf + liv) + liv; // the size of initialization vector which is being appended at
1136 // the beginning of the output buffer has to be taken into account
1137 if (len <= 0) {
1138 SafeFree(buf);
1139 return -EINVAL;
1140 }
1141
1142 // Create and fill output buffer
1143 *outbuf = new XrdSecBuffer(buf, len);
1144
1145 // We are done
1146 DEBUG("encrypted buffer has "<<len<<" bytes");
1147 return 0;
1148}
virtual char * RefreshIV(int &l)
virtual int Encrypt(const char *in, int lin, char *out)
virtual int EncOutLength(int l)

References DEBUG, XrdCryptoCipher::EncOutLength(), XrdCryptoCipher::Encrypt(), EPNAME, XrdCryptoCipher::RefreshIV(), and SafeFree.

+ Here is the call graph for this function:

◆ getCredentials()

XrdSecCredentials * XrdSecProtocolgsi::getCredentials ( XrdSecParameters * parm = 0,
XrdOucErrInfo * einfo = 0 )
virtual

Generate client credentials to be used in the authentication process.

Parameters
parmPointer to the information returned by the server either in the initial login response or the authmore response.
einfoThe error information object where error messages should be placed. The messages are returned to the client. Should einfo be null, messages should be written to stderr.
Returns
Success: Pointer to credentials to sent to the server. The caller is responsible for deleting the object. Failure: Null pointer with einfo, if supplied, containing the reason for the failure.

Implements XrdSecProtocol.

Definition at line 1411 of file XrdSecProtocolgsi.cc.

1413{
1414 // Query client for the password; remote username and host
1415 // are specified in 'parm'. File '.rootnetrc' is checked.
1416 EPNAME("getCredentials");
1417
1418 // If we are a server the only reason to be here is to get the forwarded
1419 // or saved client credentials
1420 if (srvMode) {
1421 XrdSecCredentials *creds = 0;
1422 if (proxyChain) {
1423 // Export the proxy chain into a bucket
1424 XrdCryptoX509ExportChain_t ExportChain = sessionCF->X509ExportChain();
1425 if (ExportChain) {
1426 XrdSutBucket *bck = (*ExportChain)(proxyChain, 1);
1427 if (bck) {
1428 // We need to duplicate it because XrdSecCredentials uses
1429 // {malloc, free} instead of {new, delete}
1430 char *nbuf = (char *) malloc(bck->size);
1431 if (nbuf) {
1432 memcpy(nbuf, bck->buffer, bck->size);
1433 // Import the buffer in a XrdSecCredentials object
1434 creds = new XrdSecCredentials(nbuf, bck->size);
1435 }
1436 delete bck;
1437 }
1438 }
1439 }
1440 return creds;
1441 }
1442
1443 // Handshake vars container must be initialized at this point
1444 if (!hs)
1445 return ErrC(ei,0,0,0,kGSErrError,
1446 "handshake var container missing","getCredentials");
1447 //
1448 // Nothing to do if buffer is empty
1449 if ((!parm && !hs->Parms) || (parm && (!(parm->buffer) || parm->size <= 0))) {
1450 if (hs->Iter == 0)
1451 return ErrC(ei,0,0,0,kGSErrNoBuffer,"missing parameters","getCredentials");
1452 else
1453 return (XrdSecCredentials *)0;
1454 }
1455
1456 // We support passing the user {proxy, cert, key} paths via Url parameter
1457 char *upp = (ei && ei->getEnv()) ? ei->getEnv()->Get("xrd.gsiusrpxy") : 0;
1458 if (upp) UsrProxy = upp;
1459 upp = (ei && ei->getEnv()) ? ei->getEnv()->Get("xrd.gsiusrcrt") : 0;
1460 if (upp) UsrCert = upp;
1461 upp = (ei && ei->getEnv()) ? ei->getEnv()->Get("xrd.gsiusrkey") : 0;
1462 if (upp) UsrKey = upp;
1463
1464 // Count interations
1465 (hs->Iter)++;
1466
1467 // Update time stamp
1468 hs->TimeStamp = time(0);
1469
1470 // Local vars
1471 int step = 0;
1472 int nextstep = 0;
1473 const char *stepstr = 0;
1474 char *bpub = 0;
1475 int lpub = 0;
1476 String CryptoMod = "";
1477 String Host = "";
1478 String RemID = "";
1479 String Emsg;
1480 String specID = "";
1481 String issuerHash = "";
1482 // Buffer / Bucket related
1483 XrdSutBuffer *bpar = 0; // Global buffer
1484 XrdSutBuffer *bmai = 0; // Main buffer
1485 XrdSutBucket *bck = 0; // Generic bucket
1486
1487 //
1488 // Decode received buffer
1489 bpar = hs->Parms;
1490 if (!bpar && !(bpar = new XrdSutBuffer((const char *)parm->buffer,parm->size)))
1491 return ErrC(ei,0,0,0,kGSErrDecodeBuffer,"global",stepstr);
1492 // Ownership has been transferred
1493 hs->Parms = 0;
1494 //
1495 // Check protocol ID name
1496 if (strcmp(bpar->GetProtocol(),XrdSecPROTOIDENT))
1497 return ErrC(ei,bpar,bmai,0,kGSErrBadProtocol,stepstr);
1498 //
1499 // The step indicates what we are supposed to do
1500 if (!(step = bpar->GetStep())) {
1501 // The first, fake, step
1502 step = kXGS_init;
1503 bpar->SetStep(step);
1504 }
1505 stepstr = ServerStepStr(step);
1506 // Dump, if requested
1507 XrdOucString bmsg;
1508 if (QTRACE(Dump)) {
1509 bmsg.form("IN: bpar: %s", stepstr);
1510 bpar->Dump(bmsg.c_str());
1511 }
1512 //
1513 // Parse input buffer
1514 if (ParseClientInput(bpar, &bmai, Emsg) == -1) {
1515 DEBUG(Emsg<<" CF: "<<sessionCF);
1516 return ErrC(ei,bpar,bmai,0,kGSErrParseBuffer,Emsg.c_str(),stepstr);
1517 }
1518 // Dump, if requested
1519 if (QTRACE(Dump)) {
1520 if (bmai) {
1521 bmsg.form("IN: bmai: %s", stepstr);
1522 bmai->Dump(bmsg.c_str());
1523 }
1524 }
1525 //
1526 // Version
1527 DEBUG("version run by server: "<< hs->RemVers);
1528 //
1529 // Check random challenge
1530 if (!CheckRtag(bmai, Emsg))
1531 return ErrC(ei,bpar,bmai,0,kGSErrBadRndmTag,Emsg.c_str(),stepstr);
1532 //
1533 // Login name if any
1534 String user(Entity.name);
1535 if (user.length() <= 0) user = getenv("XrdSecUSER");
1536 //
1537 // Now action depens on the step
1538 nextstep = kXGC_none;
1539
1540 XrdCryptoX509 *c = 0;
1541
1542 switch (step) {
1543
1544 case kXGS_init:
1545 //
1546 // Add bucket with cryptomod to the global list
1547 // (This must be always visible from now on)
1548 CryptoMod = hs->CryptoMod;
1549 if (hs->RemVers >= XrdSecgsiVersDHsigned && !(hs->HasPad)) CryptoMod += gNoPadTag;
1550 if (bpar->AddBucket(CryptoMod,kXRS_cryptomod) != 0)
1551 return ErrC(ei,bpar,bmai,0,
1553 //
1554 // Add bucket with our version to the main list
1555 if (bpar->MarshalBucket(kXRS_version,(kXR_int32)(Version)) != 0)
1556 return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
1557 XrdSutBuckStr(kXRS_version),"global",stepstr);
1558 //
1559 // Add our issuer hash
1560 c = hs->PxyChain->Begin();
1561 if (c->type == XrdCryptoX509::kCA) {
1562 issuerHash = c->SubjectHash();
1563 if (HashCompatibility && c->SubjectHash(1)) {
1564 issuerHash += "|"; issuerHash += c->SubjectHash(1); }
1565 } else {
1566 issuerHash = c->IssuerHash();
1567 if (HashCompatibility && c->IssuerHash(1)
1568 && strcmp(c->IssuerHash(1),c->IssuerHash())) {
1569 issuerHash += "|"; issuerHash += c->IssuerHash(1); }
1570 }
1571 while ((c = hs->PxyChain->Next()) != 0) {
1572 if (c->type != XrdCryptoX509::kCA)
1573 break;
1574 issuerHash = c->SubjectHash();
1575 if (HashCompatibility && c->SubjectHash(1)
1576 && strcmp(c->IssuerHash(1),c->IssuerHash())) {
1577 issuerHash += "|"; issuerHash += c->SubjectHash(1); }
1578 }
1579
1580 DEBUG("Client issuer hash: " << issuerHash);
1581 if (bpar->AddBucket(issuerHash,kXRS_issuer_hash) != 0)
1582 return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
1584 //
1585 // Add bucket with our delegate proxy options
1586 if (hs->RemVers >= 10100) {
1587 if (bpar->MarshalBucket(kXRS_clnt_opts,(kXR_int32)(hs->Options)) != 0)
1588 return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
1589 XrdSutBuckStr(kXRS_clnt_opts),"global",stepstr);
1590 }
1591
1592 //
1593 nextstep = kXGC_certreq;
1594 break;
1595
1596 case kXGS_cert:
1597 //
1598 // We must have a session cipher at this point
1599 if (!(sessionKey))
1600 return ErrC(ei,bpar,bmai,0,
1601 kGSErrNoCipher,"session cipher",stepstr);
1602
1603 //
1604 // Extract buffer with public info for the cipher agreement
1605 if (!(bpub = sessionKey->Public(lpub)))
1606 return ErrC(ei,bpar,bmai,0,
1607 kGSErrNoPublic,"session",stepstr);
1608
1609 //
1610 // If server supports decoding of signed DH, do sign them
1611 if (hs->RemVers >= XrdSecgsiVersDHsigned) {
1612 bck = new XrdSutBucket(bpub,lpub,kXRS_cipher);
1613 if (sessionKsig) {
1614 // Encrypt client DH public parameters with client private key
1615 if (sessionKsig->EncryptPrivate(*bck) <= 0)
1616 return ErrC(ei,bpar,bmai,0, kGSErrExportPuK,
1617 "encrypting client DH public parameters",stepstr);
1618 } else {
1619 return ErrC(ei,bpar,bmai,0, kGSErrExportPuK,
1620 "client signing key undefined!",stepstr);
1621 }
1622 //
1623 // Add it to the global list
1624 if (bpar->AddBucket(bck) != 0)
1625 return ErrC(ei,bpar,bmai,0, kGSErrAddBucket, "main",stepstr);
1626 //
1627 // Export client public key
1628 XrdOucString cpub;
1629 if (sessionKsig->ExportPublic(cpub) < 0)
1630 return ErrC(ei,bpar,bmai,0, kGSErrExportPuK,
1631 "exporting client public key",stepstr);
1632 // Add it to the global list
1633 if (bpar->UpdateBucket(cpub.c_str(),cpub.length(),kXRS_puk) != 0)
1634 return ErrC(ei,bpar,bmai,0, kGSErrAddBucket,
1635 XrdSutBuckStr(kXRS_puk),"global",stepstr);
1636 } else {
1637 //
1638 // Add it to the global list
1639 if (bpar->UpdateBucket(bpub,lpub,kXRS_puk) != 0)
1640 return ErrC(ei,bpar,bmai,0, kGSErrAddBucket,
1641 XrdSutBuckStr(kXRS_puk),"global",stepstr);
1642 delete[] bpub; // bpub is being duplicated inside of 'UpdateBucket'
1643 }
1644
1645 //
1646 // Add the proxy certificate
1647 bmai->AddBucket(hs->Cbck);
1648 //
1649 // Add login name if any, needed while chosing where to export the proxies
1650 if (user.length() > 0) {
1651 if (bmai->AddBucket(user, kXRS_user) != 0)
1652 return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
1653 XrdSutBuckStr(kXRS_user),stepstr);
1654 }
1655 //
1656 nextstep = kXGC_cert;
1657 break;
1658
1659 case kXGS_pxyreq:
1660 //
1661 // If something went wrong, send explanation
1662 if (Emsg.length() > 0) {
1663 if (bmai->AddBucket(Emsg,kXRS_message) != 0)
1664 return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
1665 XrdSutBuckStr(kXRS_message),stepstr);
1666 }
1667 //
1668 // Add login name if any, needed while chosing where to export the proxies
1669 if (user.length() > 0) {
1670 if (bmai->AddBucket(user, kXRS_user) != 0)
1671 return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
1672 XrdSutBuckStr(kXRS_user),stepstr);
1673 }
1674 //
1675 // The relevant buckets should already be in the buffers
1676 nextstep = kXGC_sigpxy;
1677 break;
1678
1679 default:
1680 return ErrC(ei,bpar,bmai,0, kGSErrBadOpt,stepstr);
1681 }
1682
1683 //
1684 // Serialize and encrypt
1685 if (AddSerialized('c', nextstep, hs->ID,
1686 bpar, bmai, kXRS_main, sessionKey) != 0) {
1687 return ErrC(ei,bpar,bmai,0,
1688 kGSErrSerialBuffer,"main",stepstr);
1689 }
1690 //
1691 // Serialize the global buffer
1692 char *bser = 0;
1693 int nser = bpar->Serialized(&bser,'f');
1694
1695 if (QTRACE(Authen)) {
1696 bmsg.form("OUT: bpar: %s", ClientStepStr(bpar->GetStep()));
1697 bpar->Dump(bmsg.c_str());
1698 bmsg.form("OUT: bmai: %s", ClientStepStr(bpar->GetStep()));
1699 bmai->Dump(bmsg.c_str());
1700 }
1701 //
1702 // We may release the buffers now
1703 REL2(bpar,bmai);
1704 //
1705 // Return serialized buffer
1706 if (nser > 0) {
1707 DEBUG("returned " << nser <<" bytes of credentials");
1708 return new XrdSecCredentials(bser, nser);
1709 } else {
1710 NOTIFY("problems with final serialization");
1711 return (XrdSecCredentials *)0;
1712 }
1713}
int kXR_int32
Definition XPtypes.hh:89
XrdSecBuffer XrdSecCredentials
static const char * gNoPadTag
@ kXGS_init
@ kXGC_none
@ kGSErrNoCipher
@ kGSErrCreateBucket
@ kGSErrNoBuffer
XrdOucString CryptoMod
@ kXRS_issuer_hash
Definition XrdSutAux.hh:80
@ kXRS_version
Definition XrdSutAux.hh:71
@ kXRS_cryptomod
Definition XrdSutAux.hh:57
@ kXRS_clnt_opts
Definition XrdSutAux.hh:76
virtual int ExportPublic(char *out, int lout)
XrdCryptoX509 * Next()
XrdCryptoX509 * Begin()
virtual const char * SubjectHash(int)
virtual const char * IssuerHash(int)
kXR_int32 size
int UpdateBucket(const char *bp, int sz, int ty)
void SetStep(int s)
kXR_int32 MarshalBucket(kXR_int32 type, kXR_int32 code)

References XrdSutBuffer::AddBucket(), XrdCryptoX509Chain::Begin(), XrdSecBuffer::buffer, XrdSutBucket::buffer, XrdOucString::c_str(), gsiHSVars::Cbck, ClientStepStr(), CryptoMod, gsiHSVars::CryptoMod, DEBUG, XrdSutBuffer::Dump(), XrdCryptoRSA::EncryptPrivate(), XrdSecProtocol::Entity, EPNAME, XrdCryptoRSA::ExportPublic(), XrdOucString::form(), XrdOucEnv::Get(), XrdOucErrInfo::getEnv(), XrdSutBuffer::GetProtocol(), XrdSutBuffer::GetStep(), gNoPadTag, gsiHSVars::HasPad, gsiHSVars::ID, XrdCryptoX509::IssuerHash(), gsiHSVars::Iter, XrdCryptoX509::kCA, kGSErrAddBucket, kGSErrBadOpt, kGSErrBadProtocol, kGSErrBadRndmTag, kGSErrCreateBucket, kGSErrDecodeBuffer, kGSErrError, kGSErrExportPuK, kGSErrNoBuffer, kGSErrNoCipher, kGSErrNoPublic, kGSErrParseBuffer, kGSErrSerialBuffer, kXGC_cert, kXGC_certreq, kXGC_none, kXGC_sigpxy, kXGS_cert, kXGS_init, kXGS_pxyreq, kXRS_cipher, kXRS_clnt_opts, kXRS_cryptomod, kXRS_issuer_hash, kXRS_main, kXRS_message, kXRS_puk, kXRS_user, kXRS_version, XrdOucString::length(), XrdSutBuffer::MarshalBucket(), XrdSecEntity::name, XrdCryptoX509Chain::Next(), NOTIFY, gsiHSVars::Options, gsiHSVars::Parms, XrdCryptoCipher::Public(), gsiHSVars::PxyChain, QTRACE, REL2, gsiHSVars::RemVers, XrdSutBuffer::Serialized(), ServerStepStr(), XrdSutBuffer::SetStep(), XrdSecBuffer::size, XrdSutBucket::size, XrdCryptoX509::SubjectHash(), gsiHSVars::TimeStamp, XrdCryptoX509::type, XrdSutBuffer::UpdateBucket(), Version, XrdCryptoFactory::X509ExportChain(), XrdSecgsiVersDHsigned, XrdSecPROTOIDENT, and XrdSutBuckStr().

+ Here is the call graph for this function:

◆ getKey()

int XrdSecProtocolgsi::getKey ( char * buff = 0,
int size = 0 )
virtual

Get the current encryption key (i.e. session key)

Parameters
buffbuffer to hold the key, and may be null.
sizesize of the buffer.
Returns
< 0 Failed, returned value if -errno (see Encrypt) >= 0 The size of the encyption key. The supplied buffer of length size hold the key. If the buffer address is supplied, the key is placed in the buffer.

Reimplemented from XrdSecProtocol.

Definition at line 1311 of file XrdSecProtocolgsi.cc.

1312{
1313 // Get the current encryption key
1314 //
1315 // Returns: < 0 Failed, returned value if -errno (see Encrypt)
1316 // >= 0 The size of the encyption key. The supplied buffer of length
1317 // size hold the key. If the buffer address is 0, only the
1318 // size of the key is returned.
1319 //
1320 EPNAME("getKey");
1321
1322 // Check if we have to serialize the key
1323 if (!bucketKey) {
1324
1325 // We must have a key for that
1326 if (!sessionKey)
1327 // Invalid call
1328 return -ENOENT;
1329 // Create bucket
1330 bucketKey = sessionKey->AsBucket();
1331 }
1332
1333 // Prepare output now, if we have any
1334 if (bucketKey) {
1335 // If are asked only the size, we are done
1336 if (kbuf == 0)
1337 return bucketKey->size;
1338
1339 // Check the size of the buffer
1340 if (klen < bucketKey->size)
1341 // Too small
1342 return -EOVERFLOW;
1343
1344 // Copy the buffer
1345 memcpy(kbuf, bucketKey->buffer, bucketKey->size);
1346
1347 // We are done
1348 DEBUG("session key exported");
1349 return bucketKey->size;
1350 }
1351
1352 // Key exists but we could export it in bucket format
1353 return -ENOMEM;
1354}
virtual XrdSutBucket * AsBucket()

References XrdCryptoCipher::AsBucket(), XrdSutBucket::buffer, DEBUG, EPNAME, and XrdSutBucket::size.

+ Here is the call graph for this function:

◆ Init()

char * XrdSecProtocolgsi::Init ( gsiOptions o,
XrdOucErrInfo * erp )
static

Definition at line 406 of file XrdSecProtocolgsi.cc.

407{
408 // Static method to the configure the static part of the protocol
409 // Called once by XrdSecProtocolgsiInit
410 EPNAME("Init");
411 char *Failure = 0, *Parms = 0;
412
413 //
414 // Debug an tracing
415 Debug = (opt.debug > -1) ? opt.debug : Debug;
416
417 // We must have the tracing object at this point
418 // (initialized in XrdSecProtocolgsiInit)
419 if (!gsiTrace) {
420 ErrF(erp,kGSErrInit,"tracing object (gsiTrace) not initialized! cannot continue");
421 return Failure;
422 }
423 // Set debug mask ... also for auxilliary libs
424 int trace = 0, traceSut = 0, traceCrypto = 0;
425 if (Debug >= 3) {
426 trace = cryptoTRACE_Dump;
427 traceSut = sutTRACE_Dump;
428 traceCrypto = cryptoTRACE_Dump;
429 GSITrace->What = TRACE_ALL;
430 } else if (Debug >= 2) {
431 trace = cryptoTRACE_Debug;
432 traceSut = sutTRACE_Debug;
433 traceCrypto = cryptoTRACE_Debug;
434 GSITrace->What = TRACE_Debug;
435 GSITrace->What |= TRACE_Authen;
436 } else if (Debug >= 1) {
437 trace = cryptoTRACE_Debug;
438 traceSut = sutTRACE_Notify;
439 traceCrypto = cryptoTRACE_Notify;
440 GSITrace->What = TRACE_Debug;
441 }
442
443 // ... also for auxilliary libs
444 XrdSutSetTrace(traceSut);
445 XrdCryptoSetTrace(traceCrypto);
446
447 // Name hashing algorithm compatibility
448 if (opt.hashcomp == 0) HashCompatibility = 0;
449
450 //
451 // Operation mode
452 Server = (opt.mode == 's');
453
454 //
455 // CA verification level
456 //
457 // 0 do not verify
458 // 1 verify if self-signed; warn if not
459 // 2 verify in all cases; fail if not possible
460 //
461 if (opt.ca >= caNoVerify && opt.ca <= caVerify)
462 CACheck = opt.ca;
463 DEBUG("option CACheck: "<<getOptName(caVerOpts,CACheck));
464
465 //
466 // Check existence of CA directory
467 struct stat st;
468 if (opt.certdir) {
469 DEBUG("testing CA dir(s): "<<opt.certdir);
470 String CAtmp;
471 String tmp = opt.certdir;
472 String dp;
473 int from = 0;
474 while ((from = tmp.tokenize(dp, from, ',')) != -1) {
475 if (dp.length() > 0) {
476 if (XrdSutExpand(dp) == 0) {
477 if (stat(dp.c_str(),&st) == -1) {
478 if (errno == ENOENT) {
479 ErrF(erp,kGSErrError,"CA directory non existing",dp.c_str());
480 PRINT(erp->getErrText());
481 } else {
482 ErrF(erp,kGSErrError,"cannot stat CA directory",dp.c_str());
483 PRINT(erp->getErrText());
484 }
485 } else {
486 if (!(dp.endswith('/'))) dp += '/';
487 if (!(CAtmp.endswith(','))) CAtmp += ',';
488 CAtmp += dp;
489 }
490 } else {
491 PRINT("Warning: could not expand: "<<dp);
492 }
493 }
494 }
495 if (CAtmp.length() > 0)
496 CAdir = CAtmp;
497 }
498 DEBUG("using CA dir(s): "<<CAdir);
499
500 //
501 // CRL check level
502 //
503 // 0 do not care
504 // 1 use if available
505 // 2 require
506 // 3 require not expired
507 // 12 require; try download if missing
508 // 13 require not expired; try download if missing
509 //
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) {
513 CRLDownload = 1;
514 opt.crl %= 10;
515 }
516 if (opt.crl >= crlIgnore && opt.crl <= crlRequire)
517 CRLCheck = opt.crl;
518 DEBUG("option CRLCheck: "<<CRLCheck<<" ('"<<cocrl[CRLCheck]<<"'; download? "<<
519 codwld[CRLDownload]<<")");
520
521 //
522 // Check existence of CRL directory
523 if (opt.crldir) {
524
525 DEBUG("testing CRL dir(s): "<<opt.crldir);
526 String CRLtmp;
527 String tmp = opt.crldir;
528 String dp;
529 int from = 0;
530 while ((from = tmp.tokenize(dp, from, ',')) != -1) {
531 if (dp.length() > 0) {
532 if (XrdSutExpand(dp) == 0) {
533 if (stat(dp.c_str(),&st) == -1) {
534 if (errno == ENOENT) {
535 ErrF(erp,kGSErrError,"CRL directory non existing:",dp.c_str());
536 PRINT(erp->getErrText());
537 } else {
538 ErrF(erp,kGSErrError,"cannot stat CRL directory:",dp.c_str());
539 PRINT(erp->getErrText());
540 }
541 } else {
542 if (!(dp.endswith('/'))) dp += '/';
543 if (!(CRLtmp.endswith(','))) CRLtmp += ',';
544 CRLtmp += dp;
545 }
546 } else {
547 PRINT("Warning: could not expand: "<<dp);
548 }
549 }
550 }
551 if (CRLtmp.length() > 0)
552 CRLdir = CRLtmp;
553
554 } else {
555 // Use CAdir
556 CRLdir = CAdir;
557 }
558 if (CRLCheck > 0)
559 DEBUG("using CRL dir(s): "<<CRLdir);
560
561 //
562 // Default extension for CRL files
563 if (opt.crlext)
564 DefCRLext = opt.crlext;
565
566 //
567 // Refresh or expiration time for CRLs
568 if (opt.crlrefresh)
569 CRLRefresh = opt.crlrefresh;
570 DEBUG("CRL information refreshed every "<<CRLRefresh<<" secs");
571
572 //
573 // Honour trust / unstrust DNS settings (switch or env)
574 TrustDNS = opt.trustdns;
575 DEBUG("trust DNS option: "<<TrustDNS);
576
577 //
578 // Enable/disable displaying the DN
579 ShowDN = opt.showDN;
580 DEBUG("show DN option: "<<ShowDN);
581
582 //
583 // Server specific options
584 if (Server) {
585 //
586 // List of supported / wanted crypto modules
587 if (opt.clist)
588 DefCrypto = opt.clist;
589 //
590 // List of crypto modules
591 String cryptlist;
592 String crypts(DefCrypto,0,-1,64);
593 //
594 // Load crypto modules
595 XrdSutPFEntry ent;
596 XrdCryptoFactory *cf = 0;
597 if (crypts.length()) {
598 String ncpt = "";
599 int from = 0;
600 while ((from = crypts.tokenize(ncpt, from, '|')) != -1) {
601 if (ncpt.length() > 0 && ncpt[0] != '-') {
602 // Try loading
603 if ((cf = XrdCryptoFactory::GetCryptoFactory(ncpt.c_str()))) {
604 // Add it to the list
605 cryptF[ncrypt] = cf;
606 cryptID[ncrypt] = cf->ID();
607 cryptName[ncrypt].insert(cf->Name(),0,strlen(cf->Name())+1);
608 cf->SetTrace(trace);
609 cf->Notify();
610 // Ref cipher
611 if (!(refcip[ncrypt] = cf->Cipher(0,0,0))) {
612 PRINT("ref cipher for module "<<ncpt<<
613 " cannot be instantiated : disable");
614 from -= ncpt.length();
615 } else {
616 ncrypt++;
617 if (ncrypt >= XrdCryptoMax) {
618 PRINT("max number of crypto modules ("
619 << XrdCryptoMax <<") reached ");
620 break;
621 }
622 if (cryptlist.length()) cryptlist += ":";
623 cryptlist += ncpt;
624 if (!cf->HasPaddingSupport()) cryptlist += gNoPadTag;
625 }
626 } else {
627 PRINT("cannot instantiate crypto factory "<<ncpt<<
628 ": disable");
629 from -= ncpt.length();
630 }
631 }
632 }
633 }
634 //
635 // We need at least one valid crypto module
636 if (ncrypt <= 0) {
637 ErrF(erp,kGSErrInit,"could not find any valid crypto module");
638 PRINT(erp->getErrText());
639 return Failure;
640 }
641 //
642 // List of supported / wanted ciphers
643 if (opt.cipher)
644 DefCipher = opt.cipher;
645 // make sure we support all of them
646 String cip = "";
647 int from = 0;
648 while ((from = DefCipher.tokenize(cip, from, ':')) != -1) {
649 if (cip.length() > 0) {
650 int i = 0;
651 for (; i < ncrypt; i++) {
652 if (!(cryptF[i]->SupportedCipher(cip.c_str()))) {
653 // Not supported: drop from the list
654 DEBUG("cipher type not supported ("<<cip<<") - disabling");
655 from -= cip.length();
656 DefCipher.erase(cip);
657 }
658 }
659 }
660 }
661
662 //
663 // List of supported / wanted Message Digest
664 if (opt.md)
665 DefMD = opt.md;
666 // make sure we support all of them
667 String md = "";
668 from = 0;
669 while ((from = DefMD.tokenize(md, from, ':')) != -1) {
670 if (md.length() > 0) {
671 int i = 0;
672 for (; i < ncrypt; i++) {
673 if (!(cryptF[i]->SupportedMsgDigest(md.c_str()))) {
674 // Not supported: drop from the list
675 PRINT("MD type not supported ("<<md<<") - disabling");
676 from -= md.length();
677 DefMD.erase(md);
678 }
679 }
680 }
681 }
682
683 //
684 // Load server certificate and key
685 if (opt.cert) {
686 String TmpCert = opt.cert;
687 if (XrdSutExpand(TmpCert) == 0) {
688 SrvCert = TmpCert;
689 } else {
690 PRINT("Could not expand: "<<opt.cert<<": use default");
691 }
692 }
693 if (opt.key) {
694 String TmpKey = opt.key;
695 if (XrdSutExpand(TmpKey) == 0) {
696 SrvKey = TmpKey;
697 } else {
698 PRINT("Could not expand: "<<opt.key<<": use default");
699 }
700 }
701 //
702 // Check if we can read the certificate key
703 if (access(SrvKey.c_str(), R_OK)) {
704 PRINT("WARNING: process has no permission to read the certificate key file: "<<SrvKey);
705 }
706 int i = 0;
707 String certcalist = ""; // list of CA for server certificates
708 XrdSutCERef ceref;
709 for (; i<ncrypt; i++) {
710 if (!GetSrvCertEnt(ceref, cryptF[i], time(0), certcalist)) {
711 PRINT("problems loading srv cert");
712 ceref.UnLock();
713 continue;
714 }
715 }
716 // Rehash cache
717 ceref.UnLock();
718 //
719 // We must have got at least one valid certificate
720 if (cacheCert.Num() <= 0) {
721 ErrF(erp,kGSErrError,"no valid server certificate found");
722 PRINT(erp->getErrText());
723 return Failure;
724 }
725
726 DEBUG("CA list: "<<certcalist);
727
728 //
729 // GRID map check option
730 //
731 // 0 do not use (DN hash will be used as identifier)
732 // 1 use if available; otherwise as 0
733 // 2 require
734 // 10 do not use (DN name will be used as identifier)
735 // 11 use if available; otherwise as 10
736 const char *cogmap[] = { "do-not-use", "use-if-available", "require" };
737 const char *codnnm[] = { "DN hash", "DN name"};
738 if (opt.ogmap >= 10) {
739 GMAPuseDNname = 1;
740 opt.ogmap %= 10;
741 }
742 if (opt.ogmap >= 0 && opt.ogmap <= 2)
743 GMAPOpt = opt.ogmap;
744 DEBUG("user mapping file option: "<<cogmap[GMAPOpt]);
745 if (GMAPOpt < 2)
746 DEBUG("default option for entity name if no mapping available: "<<codnnm[(int)GMAPuseDNname]);
747
748 //
749 // Check existence of GRID map file
750 if (opt.gridmap) {
751 String GMAPTmp = opt.gridmap;
752 if (XrdSutExpand(GMAPTmp) == 0) {
753 GMAPFile = GMAPTmp;
754 } else {
755 PRINT("Could not expand: "<<opt.gridmap<<": use default");
756 }
757 }
758 bool hasgmap = 0;
759 if (GMAPOpt > 0) {
760 // Initialize the GMap service
761 //
762 String pars;
763 if (Debug) pars += "dbg|";
764 if (opt.gmapto > 0) { pars += "to="; pars += (int)opt.gmapto; }
765 if (!(servGMap = XrdOucgetGMap(&eDest, GMAPFile.c_str(), pars.c_str()))) {
766 if (GMAPOpt > 1) {
767 ErrF(erp,kGSErrError,"error loading grid map file",GMAPFile.c_str());
768 PRINT(erp->getErrText());
769 return Failure;
770 } else {
771 NOTIFY("Grid map file: "<<GMAPFile<<" cannot be 'access'ed: do not use");
772 }
773 } else {
774 DEBUG("using grid map file: "<<GMAPFile);
775 hasgmap = 1;
776 }
777 }
778 //
779 // Load function be used to map DN to usernames, if specified
780 bool hasgmapfun = 0;
781 if (opt.gmapfun && GMAPOpt > 0) {
782 if (!(GMAPFun = LoadGMAPFun((const char *) opt.gmapfun,
783 (const char *) opt.gmapfunparms))) {
784 ErrF(erp, kGSErrError, "GMAP plug-in could not be loaded", opt.gmapfun);
785 PRINT(erp->getErrText());
786 return Failure;
787 } else {
788 hasgmapfun = 1;
789 }
790 }
791 //
792 // Disable GMAP if neither a grid mapfile nor a GMAP function are available
793 if (!hasgmap && !hasgmapfun) {
794 if (GMAPOpt > 1) {
795 ErrF(erp,kGSErrError,"User mapping required, but neither a grid mapfile"
796 " nor a mapping function are available");
797 PRINT(erp->getErrText());
798 return Failure;
799 }
800 GMAPOpt = 0;
801 }
802 //
803 // Authentication function
804 bool hasauthzfun = 0;
805 AuthzAlways = opt.authzcall;
806 if (opt.authzfun) {
807 if (!(AuthzFun = LoadAuthzFun((const char *) opt.authzfun,
808 (const char *) opt.authzfunparms, AuthzCertFmt))) {
809 ErrF(erp, kGSErrError, "Authz plug-in could not be loaded", opt.authzfun);
810 PRINT(erp->getErrText());
811 return Failure;
812 } else {
813 hasauthzfun = 1;
814 // Notify certificate format
815 if (AuthzCertFmt >= 0 && AuthzCertFmt <= 1) {
816 const char *ccfmt[] = { "raw", "PEM base64" };
817 DEBUG("authzfun: proxy certificate format: "<<ccfmt[AuthzCertFmt]);
818 } else {
819 NOTIFY("authzfun: proxy certificate format: unknown (code: "<<AuthzCertFmt<<")");
820 }
821 // Expiration of Authz related cache entries
822 if (opt.authzto > 0) {
823 AuthzCacheTimeOut = opt.authzto;
824 DEBUG("grid-map cache entries expire after "<<AuthzCacheTimeOut<<" secs");
825 }
826 }
827 }
828 //
829 // Expiration of GRIDMAP related cache entries
830 if (GMAPOpt > 0 && !hasauthzfun && opt.gmapto > 0) {
831 GMAPCacheTimeOut = opt.gmapto;
832 DEBUG("grid-map cache entries expire after "<<GMAPCacheTimeOut<<" secs");
833 }
834
835 //
836 // Request for proxy export for authorization
837 // authzpxy = opt_what*10 + opt_where
838 // opt_what = 0 full chain
839 // 1 last proxy only
840 // opt_where = 1 Entity.creds
841 // 2 Entity.endorsements
842 if (opt.authzpxy) {
843 AuthzPxyWhat = opt.authzpxy / 10;
844 AuthzPxyWhere = opt.authzpxy % 10;
845 // Some notification
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);
851 if (hasauthzfun) {
852 // Warn user about possible overwriting of Entity.creds or Entity.endorsements
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);
855 }
856 }
857
858 //
859 // Handle delegated proxies options
860 if (opt.dlgpxy == -1) {
861 // Will not accept any delegated proxies
862 DEBUG("Will not accept delegated proxies");
863 } else {
864 // Ask the client to sign a delegated proxy; client may decide to forward its proxy
865 if (opt.dlgpxy == dlgReqSign)
866 PxyReqOpts |= kOptsSrvReq;
867
868 // Exporting options (default none: delegated proxy kept in memory, in proxyChain)
869 if (opt.exppxy) {
870 if (!strcmp(opt.exppxy, "=creds")) {
871 // register the delegated proxy in Entity.creds (in HEX format)
872 PxyReqOpts |= kOptsPxCred;
873 DEBUG("Delegated proxy saved in Entity.creds ");
874 } else {
875 String TmpProxy = gUsrPxyDef;
876 if (strcmp(opt.exppxy, "=default"))
877 TmpProxy = opt.exppxy;
878 if (XrdSutExpand(TmpProxy) == 0) {
879 UsrProxy = TmpProxy;
880 } else {
881 UsrProxy = gUsrPxyDef;
882 UsrProxy += "u<uid>";
883 }
884 PxyReqOpts |= kOptsPxFile;
885 DEBUG("File template for delegated proxy: "<<UsrProxy);
886 }
887 }
888 DEBUG("Delegated proxies options: "<<PxyReqOpts);
889 }
890
891 //
892 // VOMS attributes switch
893 // vomsat = 0 do not look for
894 // 1 extract if any (fill 'vorg', 'role'; the full string in 'endorsements');
895 // 2 require (fill 'vorg', 'role'; the full string in 'endorsements');
896 VOMSAttrOpt = (opt.vomsat <= vatRequire && opt.vomsat >= vatIgnore)
897 ? opt.vomsat : VOMSAttrOpt;
898
899 //
900 // Alternative VOMS extraction function
901 if (opt.vomsfun) {
902 if (!(VOMSFun = LoadVOMSFun((const char *) opt.vomsfun,
903 (const char *) opt.vomsfunparms, VOMSCertFmt))) {
904 ErrF(erp, kGSErrError, "VOMS plug-in loading failed", opt.vomsfun);
905 PRINT(erp->getErrText());
906 return Failure;
907 } else {
908 // Notify certificate format
909 if (VOMSCertFmt >= 0 && VOMSCertFmt <= 1) {
910 const char *ccfmt[] = { "raw", "PEM base64" };
911 DEBUG("vomsfun: proxy certificate format: "<<ccfmt[VOMSCertFmt]);
912 } else {
913 char fbuff[64];
914 snprintf(fbuff, sizeof(fbuff), "%d", VOMSCertFmt);
915 ErrF(erp, kGSErrError, "VOMS plug-in returned invalid cert "
916 "format", fbuff);
917 PRINT(erp->getErrText());
918 return Failure;
919 }
920 }
921 } else opt.authzcall = AuthzAlways = 1;
922 DEBUG("VOMS attributes options: "<<getOptName(vomsatOpts, VOMSAttrOpt));
923
924 //
925 // Default moninfo option
926 // 0 nothing
927 // 1 DN
928 MonInfoOpt = opt.moninfo;
929 const char *cmoninfo = (MonInfoOpt == 1) ? "DN" : "none";
930 DEBUG("Monitor information options: "<<cmoninfo);
931
932 // Make sure we have a calist as the client can't do anything without it.
933 // If the cryptlist is empty the client will use the default one.
934 //
935 if (certcalist.length() == 0)
936 {ErrF(erp,kGSErrInit,"unable to generate ca cert hash list!");
937 PRINT(erp->getErrText());
938 return Failure;
939 }
940
941 //
942 // Parms in the form:
943 // &P=gsi,v:<version>,c:<cryptomod>,ca:<list_of_srv_cert_ca>
944 Parms = new char[cryptlist.length()+3+12+certcalist.length()+5];
945 if (Parms) {
946 sprintf(Parms,"v:%d,c:%s,ca:%s",
947 Version,cryptlist.c_str(),certcalist.c_str());
948 } else {
949 ErrF(erp,kGSErrInit,"no system resources for 'Parms'");
950 PRINT(erp->getErrText());
951 return Failure;
952 }
953
954 // Some notification
955 DEBUG("available crypto modules: "<<cryptlist);
956 DEBUG("issuer CAs of server certs (hashes): "<<certcalist);
957 }
958
959 //
960 // Client specific options
961 if (!Server) {
962 // use default dir $(HOME)/.<prefix>
963 struct passwd *pw = getpwuid(getuid());
964 if (!pw) {
965 NOTIFY("WARNING: cannot get user information (uid:"<<getuid()<<")");
966 }
967 //
968 // Define user proxy file
969 UsrProxy = gUsrPxyDef;
970 if (opt.proxy) {
971 String TmpProxy = opt.proxy;
972 if (XrdSutExpand(TmpProxy) == 0) {
973 UsrProxy = TmpProxy;
974 } else {
975 PRINT("Could not expand: "<<opt.proxy<<": use default");
976 }
977 } else {
978 if (pw)
979 UsrProxy += (int)(pw->pw_uid);
980 }
981 // Define user certificate file
982 if (opt.cert) {
983 String TmpCert = opt.cert;
984 if (XrdSutExpand(TmpCert) == 0) {
985 UsrCert = TmpCert;
986 } else {
987 PRINT("Could not expand: "<<opt.cert<<": use default");
988 }
989 } else {
990 if (pw)
991 UsrCert.insert(XrdSutHome(),0);
992 }
993 // Define user private key file
994 if (opt.key) {
995 String TmpKey = opt.key;
996 if (XrdSutExpand(TmpKey) == 0) {
997 UsrKey = TmpKey;
998 } else {
999 PRINT("Could not expand: "<<opt.key<<": use default");
1000 }
1001 } else {
1002 if (pw)
1003 UsrKey.insert(XrdSutHome(),0);
1004 }
1005 // Define proxy validity at renewal
1006 if (opt.valid)
1007 PxyValid = opt.valid;
1008 // Set depth of signature path
1009 if (opt.deplen != DepLength)
1010 DepLength = opt.deplen;
1011 // Set number of bits for proxy key
1012 if (opt.bits > DefBits)
1013 DefBits = opt.bits;
1014 //
1015 // Delegate proxy options
1016 if (opt.dlgpxy > dlgIgnore) {
1017 PxyReqOpts |= kOptsSigReq;
1018 if (opt.dlgpxy == dlgSendpxy) {
1019 PxyReqOpts |= kOptsFwdPxy;
1020 } else {
1021 PxyReqOpts |= kOptsDlgPxy;
1022 }
1023 }
1024 //
1025 // No proxy options
1026 if (opt.createpxy) {
1027 PxyReqOpts |= kOptsCreatePxy;
1028 }
1029 //
1030 // Define valid CNs for the server certificates; default is null, which means that
1031 // the server CN must be in the form "*/<hostname>"
1032 if (opt.srvnames)
1033 SrvAllowedNames = opt.srvnames;
1034 //
1035 // Notify
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);
1043 if (!(PxyReqOpts & kOptsCreatePxy)) {
1044 TRACE(Authen, "allowing for pure cert/key authentication (no proxy) ");
1045 }
1046
1047 // We are done
1048 Parms = (char *)"";
1049 }
1050
1051 // We are done
1052 return Parms;
1053}
#define TRACE_Debug
void XrdCryptoSetTrace(kXR_int32 trace)
static XrdSysError eDest(0,"crypto_")
#define cryptoTRACE_Notify
#define cryptoTRACE_Dump
#define cryptoTRACE_Debug
XrdOucGMap * XrdOucgetGMap(XrdOucGMapArgs)
Definition XrdOucGMap.cc:92
#define access(a, b)
Definition XrdPosix.hh:39
#define stat(a, b)
Definition XrdPosix.hh:96
static const char * gUsrPxyDef
@ kOptsSigReq
@ kOptsFwdPxy
@ kOptsPxCred
@ kOptsSrvReq
@ kOptsDlgPxy
@ kOptsCreatePxy
@ kOptsPxFile
#define XrdCryptoMax
@ kGSErrInit
#define TRACE_Authen
XrdOucTrace * gsiTrace
XrdOucString CAdir
XrdOucString CRLdir
bool Debug
int ncrypt
XrdOucString DefCrypto
int XrdSutExpand(XrdOucString &path)
Definition XrdSutAux.cc:366
const char * XrdSutHome()
Definition XrdSutAux.cc:465
void XrdSutSetTrace(kXR_int32 trace)
Definition XrdSutAux.cc:93
#define sutTRACE_Notify
Definition XrdSutAux.hh:100
#define sutTRACE_Debug
Definition XrdSutAux.hh:99
#define sutTRACE_Dump
Definition XrdSutAux.hh:98
#define TRACE(act, x)
Definition XrdTrace.hh:63
#define TRACE_ALL
Definition XrdTrace.hh:35
virtual bool HasPaddingSupport()
virtual void SetTrace(kXR_int32 trace)
char * Name() const
virtual XrdCryptoCipher * Cipher(const char *t, int l=0)
static XrdCryptoFactory * GetCryptoFactory(const char *factoryname)
virtual void Notify()
const char * getErrText()
bool endswith(char c)

References access, gsiOptions::authzcall, gsiOptions::authzfun, gsiOptions::authzfunparms, gsiOptions::authzpxy, gsiOptions::authzto, gsiOptions::bits, XrdOucString::c_str(), gsiOptions::ca, CAdir, gsiOptions::cert, gsiOptions::certdir, XrdCryptoFactory::Cipher(), gsiOptions::cipher, gsiOptions::clist, gsiOptions::createpxy, gsiOptions::crl, CRLdir, gsiOptions::crldir, gsiOptions::crlext, gsiOptions::crlrefresh, cryptoTRACE_Debug, cryptoTRACE_Dump, cryptoTRACE_Notify, DEBUG, Debug, gsiOptions::debug, DefCrypto, gsiOptions::deplen, gsiOptions::dlgpxy, eDest, XrdOucString::endswith(), EPNAME, XrdOucString::erase(), gsiOptions::exppxy, XrdCryptoFactory::GetCryptoFactory(), XrdOucErrInfo::getErrText(), gsiOptions::gmapfun, gsiOptions::gmapfunparms, gsiOptions::gmapto, gNoPadTag, gsiOptions::gridmap, gsiTrace, gUsrPxyDef, gsiOptions::hashcomp, XrdCryptoFactory::HasPaddingSupport(), XrdCryptoFactory::ID(), XrdOucString::insert(), gsiOptions::key, kGSErrError, kGSErrInit, kOptsCreatePxy, kOptsDlgPxy, kOptsFwdPxy, kOptsPxCred, kOptsPxFile, kOptsSigReq, kOptsSrvReq, XrdOucString::length(), gsiOptions::md, gsiOptions::mode, gsiOptions::moninfo, XrdCryptoFactory::Name(), ncrypt, NOTIFY, XrdCryptoFactory::Notify(), XrdSutCache::Num(), gsiOptions::ogmap, PRINT, gsiOptions::proxy, XrdCryptoFactory::SetTrace(), gsiOptions::showDN, gsiOptions::srvnames, stat, sutTRACE_Debug, sutTRACE_Dump, sutTRACE_Notify, XrdOucString::tokenize(), TRACE, TRACE_ALL, TRACE_Authen, TRACE_Debug, gsiOptions::trustdns, XrdSutCERef::UnLock(), gsiOptions::valid, Version, gsiOptions::vomsat, gsiOptions::vomsfun, gsiOptions::vomsfunparms, XrdOucTrace::What, XrdCryptoMax, XrdCryptoSetTrace(), XrdOucgetGMap(), XrdSutExpand(), XrdSutHome(), and XrdSutSetTrace().

Referenced by XrdSecProtocolgsiInit().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setKey()

int XrdSecProtocolgsi::setKey ( char * buff,
int size )
virtual

Set the current encryption key

Parameters
buffbuffer that holds the key.
sizesize of the key.
Returns
: < 0 Failed, returned value if -errno (see Encrypt) = 0 The new key has been set.

Reimplemented from XrdSecProtocol.

Definition at line 1357 of file XrdSecProtocolgsi.cc.

1358{
1359 // Set the current encryption key
1360 //
1361 // Returns: < 0 Failed, returned value if -errno (see Encrypt)
1362 // 0 The new key has been set.
1363 //
1364 EPNAME("setKey");
1365
1366 // Make sur that we can initialize the new key
1367 if (!kbuf || klen <= 0)
1368 // Invalid inputs
1369 return -EINVAL;
1370
1371 if (!sessionCF)
1372 // Invalid context
1373 return -ENOENT;
1374
1375 // Put the buffer key into a bucket
1376 XrdSutBucket *bck = new XrdSutBucket();
1377 if (!bck)
1378 // Cannot get buffer: out-of-resources?
1379 return -ENOMEM;
1380 // Set key buffer
1381 bck->SetBuf(kbuf, klen);
1382
1383 // Init a new cipher from the bucket
1384 XrdCryptoCipher *newKey = sessionCF->Cipher(bck);
1385 if (!newKey) {
1386 SafeDelete(bck);
1387 return -ENOMEM;
1388 }
1389
1390 // Delete current key
1391 SafeDelete(sessionKey);
1392
1393 // Set the new key
1394 sessionKey = newKey;
1395
1396 // Cleanup
1397 SafeDelete(bck);
1398
1399 // Ok
1400 DEBUG("session key update");
1401 return 0;
1402}
int SetBuf(const char *nb=0, int ns=0)

References XrdCryptoFactory::Cipher(), DEBUG, EPNAME, SafeDelete, and XrdSutBucket::SetBuf().

+ Here is the call graph for this function:

◆ Sign()

int XrdSecProtocolgsi::Sign ( const char * inbuff,
int inlen,
XrdSecBuffer ** outbuff )
virtual

Sign data in inbuff using the session key.

Parameters
inbuffbuffer holding data to be signed.
inlenlength of the data.
outbuffplace where a pointer to the signature is placed.
Returns
< 0 Failed,the return value is -errno (see Encrypt). = 0 Success, outbuff contains a pointer to the signature. The caller is responsible for deleting the returned object.

Reimplemented from XrdSecProtocol.

Definition at line 1201 of file XrdSecProtocolgsi.cc.

1204{
1205 // Sign data in inbuff and place the signature in outbuf.
1206 //
1207 // Returns: < 0 Failed, returned value is -errno (see Encrypt).
1208 // = 0 Success, the return value is the length of the signature
1209 // placed in outbuf.
1210 //
1211 EPNAME("Sign");
1212
1213 // We must have a PKI and a digest
1214 if (!sessionKsig || !sessionMD)
1215 return -ENOENT;
1216
1217 // And something to sign
1218 if (!inbuf || inlen <= 0 || !outbuf)
1219 return -EINVAL;
1220
1221 // Reset digest
1222 sessionMD->Reset(0);
1223
1224 // Calculate digest
1225 sessionMD->Update(inbuf, inlen);
1226 sessionMD->Final();
1227
1228 // Output length
1229 int lmax = sessionKsig->GetOutlen(sessionMD->Length());
1230 char *buf = (char *)malloc(lmax);
1231 if (!buf)
1232 return -ENOMEM;
1233
1234 // Sign
1235 int len = sessionKsig->EncryptPrivate(sessionMD->Buffer(),
1236 sessionMD->Length(),
1237 buf, lmax);
1238 if (len <= 0) {
1239 SafeFree(buf);
1240 return -EINVAL;
1241 }
1242
1243 // Create and fill output buffer
1244 *outbuf = new XrdSecBuffer(buf, len);
1245
1246 // We are done
1247 DEBUG("signature has "<<len<<" bytes");
1248 return 0;
1249}
virtual int Length() const
virtual char * Buffer() const
virtual int Update(const char *b, int l)
virtual int Reset(const char *dgst)
virtual int GetOutlen(int lin)

References XrdCryptoBasic::Buffer(), DEBUG, XrdCryptoRSA::EncryptPrivate(), EPNAME, XrdCryptoMsgDigest::Final(), XrdCryptoRSA::GetOutlen(), XrdCryptoBasic::Length(), XrdCryptoMsgDigest::Reset(), SafeFree, and XrdCryptoMsgDigest::Update().

+ Here is the call graph for this function:

◆ Verify()

int XrdSecProtocolgsi::Verify ( const char * inbuff,
int inlen,
const char * sigbuff,
int siglen )
virtual

Verify a signature using the session key.

Parameters
inbuffbuffer holding data to be verified.
inlenlength of the data.
sigbuffpointer to the signature data.
siglenlength of the signature data.
Returns
< 0 Failed,the return value is -errno (see Encrypt). = 0 Success, signature is correct. > 0 Failed to verify, signature does not match inbuff data.

Reimplemented from XrdSecProtocol.

Definition at line 1252 of file XrdSecProtocolgsi.cc.

1256{
1257 // Verify a signature
1258 //
1259 // Returns: < 0 Failed, returned value is -errno (see Encrypt).
1260 // = 0 Signature matches the value in inbuff.
1261 // > 0 Failed to verify, signature does not match inbuff data.
1262 //
1263 EPNAME("Verify");
1264
1265 // We must have a PKI and a digest
1266 if (!sessionKver || !sessionMD)
1267 return -ENOENT;
1268
1269 // And something to verify
1270 if (!inbuf || inlen <= 0 || !sigbuf || siglen <= 0)
1271 return -EINVAL;
1272
1273 // Reset digest
1274 sessionMD->Reset(0);
1275
1276 // Calculate digest
1277 sessionMD->Update(inbuf, inlen);
1278 sessionMD->Final();
1279
1280 // Output length
1281 int lmax = sessionKver->GetOutlen(siglen);
1282 char *buf = new char[lmax];
1283 if (!buf)
1284 return -ENOMEM;
1285
1286 // Decrypt signature
1287 int len = sessionKver->DecryptPublic(sigbuf, siglen, buf, lmax);
1288 if (len <= 0) {
1289 delete[] buf;
1290 return -EINVAL;
1291 }
1292
1293 // Verify signature
1294 bool bad = 1;
1295 if (len == sessionMD->Length()) {
1296 if (!strncmp(buf, sessionMD->Buffer(), len)) {
1297 // Signature matches
1298 bad = 0;
1299 DEBUG("signature successfully verified");
1300 }
1301 }
1302
1303 // Cleanup
1304 if (buf) delete[] buf;
1305
1306 // We are done
1307 return ((bad) ? 1 : 0);
1308}
virtual int DecryptPublic(const char *in, int lin, char *out, int lout)

References XrdCryptoBasic::Buffer(), DEBUG, XrdCryptoRSA::DecryptPublic(), EPNAME, XrdCryptoMsgDigest::Final(), XrdCryptoRSA::GetOutlen(), XrdCryptoBasic::Length(), XrdCryptoMsgDigest::Reset(), and XrdCryptoMsgDigest::Update().

+ Here is the call graph for this function:

Friends And Related Symbol Documentation

◆ gsiHSVars

friend class gsiHSVars
friend

Definition at line 283 of file XrdSecProtocolgsi.hh.

Referenced by XrdSecProtocolgsi().

◆ gsiOptions

friend class gsiOptions
friend

Definition at line 282 of file XrdSecProtocolgsi.hh.


The documentation for this class was generated from the following files: