Loading...
Searching...
No Matches
XrdSecProtocolsss.cc
Go to the documentation of this file.
/******************************************************************************/
/* */
/* X r d S e c P r o t o c o l s s s . c c */
/* */
/* (c) 2008 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#if !defined(__FreeBSD__)
#include <alloca.h>
#endif
#include <cctype>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <strings.h>
#include <cstdio>
#include <sys/param.h>
#include <unistd.h>
#include "XrdVersion.hh"
#include "XrdNet/XrdNetUtils.hh"
#include "XrdOuc/XrdOucCRC.hh"
#include "XrdOuc/XrdOucErrInfo.hh"
#include "XrdOuc/XrdOucEnv.hh"
#include "XrdOuc/XrdOucPup.hh"
#include "XrdOuc/XrdOucTokenizer.hh"
#include "XrdOuc/XrdOucUtils.hh"
#include "XrdSec/XrdSecEntityAttr.hh"
#include "XrdSecsss/XrdSecsssEnt.hh"
#include "XrdSecsss/XrdSecProtocolsss.hh"
#include "XrdSys/XrdSysE2T.hh"
#include "XrdSys/XrdSysPlatform.hh"
#include "XrdSys/XrdSysPthread.hh"
/******************************************************************************/
/* D e f i n e s */
/******************************************************************************/
#define XrdsssPROTOIDENT "sss"
#define CLDBG(x) if (sssDEBUG) std::cerr<<"sec_sss: "<<x<<'\n'<<std::flush
/******************************************************************************/
/* L o c a l C l a s s e s */
/******************************************************************************/
namespace
{
class Persona
{
public:
XrdSecsssKT::ktEnt *kTab;
char *xAuth;
char *xUser;
char *xGrup;
char *name;
char *host;
char *vorg;
char *role;
char *grps;
char *caps;
char *endo;
char *creds;
int credslen;
char *pident;
Persona(XrdSecsssKT::ktEnt *kP)
: kTab(kP),
xAuth(nullptr),
xUser(nullptr),
xGrup(nullptr),
name(nullptr),
host(nullptr),
vorg(nullptr),
role(nullptr),
grps(nullptr),
caps(nullptr),
endo(nullptr),
creds(nullptr),
credslen(0),
pident(nullptr)
{}
bool Clonable(const char *aTypes)
{char aKey[XrdSecPROTOIDSIZE+2];
if (!xAuth || !name || !pident
|| !(kTab->Data.Opts & XrdSecsssKT::ktEnt::allUSR)) return false;
int n = strlen(xAuth);
if (n < 2 || n >= XrdSecPROTOIDSIZE) return false;
*aKey = ':';
strcpy(aKey+1, xAuth);
return strstr(aTypes, aKey) != 0;
}
};
// Struct to manage dynamically allocated data buffer
//
struct sssRR_DataHdr
{
XrdSecsssRR_DataHdr *P;
sssRR_DataHdr() : P(0) {}
~sssRR_DataHdr() {if (P) free(P);}
};
}
/******************************************************************************/
/* S t a t i c D a t a */
/******************************************************************************/
XrdCryptoLite *XrdSecProtocolsss::CryptObj = 0;
XrdSecsssKT *XrdSecProtocolsss::ktObject = 0;
XrdSecsssID *XrdSecProtocolsss::idMap = 0;
char *XrdSecProtocolsss::aProts = 0;
XrdSecsssEnt *XrdSecProtocolsss::staticID = 0;
int XrdSecProtocolsss::deltaTime =13;
bool XrdSecProtocolsss::isMutual = false;
bool XrdSecProtocolsss::isMapped = false;
bool XrdSecProtocolsss::ktFixed = false;
struct XrdSecProtocolsss::Crypto XrdSecProtocolsss::CryptoTab[] = {
{"bf32", XrdSecsssRR_Hdr::etBFish32},
{0, '0'}
};
namespace
{
XrdSysMutex initMutex;
bool sssDEBUG = false;
bool sssUseKN = false;
}
/******************************************************************************/
/* A u t h e n t i c a t e */
/******************************************************************************/
int XrdSecProtocolsss::Authenticate(XrdSecCredentials *cred,
XrdSecParameters **parms,
XrdOucErrInfo *einfo)
{
static const int minLen = sizeof(XrdSecsssRR_Hdr) + XrdSecsssRR_Data_HdrLen;
static const int maxLen = XrdSecsssRR_Data::MaxDSz + minLen;
static const int Special= XrdSecsssKT::ktEnt::anyUSR
| XrdSecsssKT::ktEnt::allUSR;
XrdSecsssRR_Hdr *rrHdr = (XrdSecsssRR_Hdr *)(cred->buffer);
XrdSecsssRR_Data *rrData;
XrdSecsssKT::ktEnt decKey;
Persona myID(&decKey);
char *idP = 0, *dP = 0, *eodP = 0, *theIP = 0, *theHost = 0, *atKey = 0, eType = '\0';
int idNum = 0, idTLen, idSz, dLen;
bool badAttr = false;
// Make sure we have atleast the header plus the data header
//
if (cred->size < minLen)
return Fatal(einfo, "Auth", EINVAL, "Credentials too small.");
// Make sure the credentials are not too big (people misuse sss)
//
if (cred->size > maxLen)
return Fatal(einfo, "Auth", EINVAL, "Credentials too big.");
// Allocate the buffer from the stack
//
rrData = (XrdSecsssRR_Data *)alloca(cred->size);
// Decode the credentials
//
if ((dLen = Decode(einfo, decKey, cred->buffer, rrData, cred->size)) <= 0)
return -1;
// Check if we should echo back the LID
//
if (rrData->Options == XrdSecsssRR_DataHdr::SndLID)
{XrdSecsssRR_DataResp rrResp;
char lidBuff[16];
rrResp.Options = 0;
getLID(lidBuff, sizeof(lidBuff));
dP = rrResp.Data;
*dP++ = XrdSecsssRR_Data::theLgid;
XrdOucPup::Pack(&dP, lidBuff);
int n = dP-rrResp.Data + XrdSecsssRR_Data_HdrLen;
*parms = Encode(einfo, decKey, rrHdr, &rrResp, n);
return (*parms ? 1 : -1);
}
// Extract out the entity information
//
dP = rrData->Data; eodP = dP + dLen - XrdSecsssRR_Data_HdrLen;
CLDBG("Processing " <<dLen <<" byes");
while(dP < eodP)
{eType = *dP++;
CLDBG("eType=" <<static_cast<int>(eType)
<<" Used " <<dP-rrData->Data <<" left " <<eodP-dP);
if (!XrdOucPup::Unpack(&dP, eodP, &idP, idSz) || (idP && *idP == '\0'))
{Fatal(einfo, "Authenticate", EINVAL, "Invalid id string.");
return -1;
}
idNum++;
switch(eType)
{case XrdSecsssRR_Data::theName: myID.name = idP; break;
case XrdSecsssRR_Data::theVorg: myID.vorg = idP; break;
case XrdSecsssRR_Data::theRole: myID.role = idP; break;
case XrdSecsssRR_Data::theGrps: myID.grps = idP; break;
case XrdSecsssRR_Data::theEndo: myID.endo = idP; break;
case XrdSecsssRR_Data::theCred: myID.creds = idP;
myID.credslen = idSz;break;
case XrdSecsssRR_Data::theHost:
if (idP && *idP == '[')
myID.host = theIP = idP;
else theHost = idP;
break;
case XrdSecsssRR_Data::theRand: idNum--; break;
case XrdSecsssRR_Data::theAuth: myID.xAuth = idP; break;
case XrdSecsssRR_Data::theTID: myID.pident = idP; break;
case XrdSecsssRR_Data::theAKey: if (atKey) badAttr = true;
atKey = idP; break;
case XrdSecsssRR_Data::theAVal:
if (!atKey) badAttr = true;
else {Entity.eaAPI->Add(std::string(atKey),
std::string(idP), true);
atKey = 0;
}
break;
case XrdSecsssRR_Data::theUser: myID.xUser = idP; break;
case XrdSecsssRR_Data::theGrup: myID.xGrup = idP; break;
case XrdSecsssRR_Data::theCaps: myID.caps = idP; break;
default: break;
}
}
// Verify that we have some kind of identification
//
if (!idNum)
{Fatal(einfo, "Authenticate", ENOENT, "No identification specified.");
return -1;
}
// Make sure we didn't encounter any attribute errors
//
if (badAttr)
{Fatal(einfo, "Authenticate", EINVAL, "Invalid attribute specification.");
return -1;
}
// Verify the source of the information to largely prevent packet stealing. New
// version of the protocol will send an IP address which we prefrentially use.
// Older version used a hostname. This causes problems for multi-homed machines.
//
if (!(decKey.Data.Opts & XrdSecsssKT::ktEnt::noIPCK))
{if (!theHost && !theIP)
{Fatal(einfo,"Authenticate",ENOENT,"No hostname or IP address specified.");
return -1;
}
CLDBG(urName <<' ' <<urIP <<" or " <<urIQ << " must match "
<<(theHost ? theHost : "?") <<' ' <<(theIP ? theIP : "[?]"));
if (theIP)
{if (strcmp(theIP, urIP) && strcmp(theIP, urIQ))
{Fatal(einfo, "Authenticate", EINVAL, "IP address mismatch.");
return -1;
}
} else if (strcmp(theHost, urName))
{Fatal(einfo, "Authenticate", EINVAL, "Hostname mismatch.");
return -1;
}
} else {
CLDBG(urName <<' ' <<urIP <<" or " <<urIQ << " forwarded token from "
<<(theHost ? theHost : "?") <<' ' <<(theIP ? theIP : "[?]"));
}
// At this point we need to check if this identity can be passed as a clone
//
if (aProts && myID.Clonable(aProts))
{strlcpy(Entity.prot, myID.xAuth, sizeof(Entity.prot));
Entity.prot[XrdSecPROTOIDSIZE-1] = 0;
if (myID.xUser) XrdOucUtils::getUID(myID.xUser,Entity.uid,&Entity.gid);
if (myID.xGrup) XrdOucUtils::getGID(myID.xGrup,Entity.gid);
} else {
// Set correct username
//
if (decKey.Data.Opts & Special)
{if (!myID.name) myID.name = (char *)"nobody";}
else myID.name = decKey.Data.User;
// Set correct group
//
if (decKey.Data.Opts & XrdSecsssKT::ktEnt::usrGRP) myID.grps = 0;
else {if (decKey.Data.Opts & XrdSecsssKT::ktEnt::anyGRP)
{if (!myID.grps) myID.grps = (char *)"nogroup";}
else myID.grps = decKey.Data.Grup;
}
// Set corresponding uid and gid
//
if (myID.name) XrdOucUtils::getUID(myID.name, Entity.uid, &Entity.gid);
if (myID.grps) XrdOucUtils::getGID(myID.grps, Entity.gid);
}
// Calculate the amount of space we will need
//
idTLen = strlen(urName)
+ (myID.name ? strlen(myID.name)+1 : 0)
+ (myID.vorg ? strlen(myID.vorg)+1 : 0)
+ (myID.role ? strlen(myID.role)+1 : 0)
+ (myID.grps ? strlen(myID.grps)+1 : 0)
+ (myID.caps ? strlen(myID.caps)+1 : 0)
+ (myID.endo ? strlen(myID.endo)+1 : 0)
+ (myID.creds ? myID.credslen : 0)
+ (myID.pident ? strlen(myID.pident)+1 : 0);
// Complete constructing our identification
//
if (idBuff) free(idBuff);
idBuff = idP = (char *)malloc(idTLen);
Entity.host = urName;
Entity.name = setID(myID.name, &idP);
Entity.vorg = setID(myID.vorg, &idP);
Entity.role = setID(myID.role, &idP);
Entity.grps = setID(myID.grps, &idP);
Entity.caps = setID(myID.caps, &idP);
Entity.endorsements = setID(myID.endo, &idP);
if (myID.pident)
{strcpy(idP, myID.pident);
Entity.pident = idP;
idP += strlen(myID.pident) + 1;
}
if (myID.creds)
{memcpy(idP, myID.creds, myID.credslen);
Entity.creds = idP;
Entity.credslen = myID.credslen;
}
// All done
//
return 0;
}
/******************************************************************************/
/* Private: D e c o d e */
/******************************************************************************/
int XrdSecProtocolsss::Decode(XrdOucErrInfo *error,
XrdSecsssKT::ktEnt &decKey,
char *iBuff,
XrdSecsssRR_DataHdr *rrDHdr,
int iSize)
{
XrdSecsssRR_Hdr *rrHdr = (XrdSecsssRR_Hdr *)iBuff;
char *iData = iBuff+sizeof(XrdSecsssRR_Hdr);
int rc, genTime, dLen = iSize - sizeof(XrdSecsssRR_Hdr);
// Check if this is a recognized protocol
//
if (strcmp(rrHdr->ProtID, XrdsssPROTOIDENT))
{char emsg[256];
snprintf(emsg, sizeof(emsg),
"Authentication protocol id mismatch (%.4s != %.4s).",
XrdsssPROTOIDENT, rrHdr->ProtID);
return Fatal(error, "Decode", EINVAL, emsg);
}
// Verify decryption method
//
if (rrHdr->EncType != Crypto->Type())
return Fatal(error, "Decode", ENOTSUP, "Crypto type not supported.");
// Check if this is a V2 client. V2 client always supply the keyname of the
// key which we may or may not use. If specified, make sure it's correct.
//
if (rrHdr->knSize)
{int knSize = static_cast<int>(rrHdr->knSize);
v2EndPnt = true;
if (knSize > XrdSecsssKT::ktEnt::NameSZ || knSize & 0x07
|| knSize >= dLen || iData[knSize-1])
return Fatal(error, "Decode", EINVAL, "Invalid keyname specified.");
if (sssUseKN) strcpy(decKey.Data.Name, iData);
else decKey.Data.Name[0] = '\0';
CLDBG("V2 client using keyname '" <<iData <<"' dLen=" <<dLen
<<(sssUseKN ? "" : " (ignored)"));
iData += knSize; dLen -= knSize;
} else decKey.Data.Name[0] = '\0';
// Get the key ID
//
decKey.Data.ID = ntohll(rrHdr->KeyID);
if (keyTab->getKey(decKey, *decKey.Data.Name))
return Fatal(error, "Decode", ENOENT, "Decryption key not found.");
// Decrypt
//
CLDBG("Decode keyid: " <<decKey.Data.ID <<" bytes " <<dLen);
if ((rc = Crypto->Decrypt(decKey.Data.Val, decKey.Data.Len, iData, dLen,
(char *)rrDHdr, dLen)) <= 0)
return Fatal(error, "Decode", -rc, "Unable to decrypt credentials.");
// Verify that the packet has not expired (OK to do before CRC check)
//
genTime = ntohl(rrDHdr->GenTime);
if (genTime + deltaTime <= myClock())
return Fatal(error, "Decode", ESTALE,
"Credentials expired (check for clock skew).");
// Return success (size of decrypted info)
//
return rc;
}
/******************************************************************************/
/* D e l e t e */
/******************************************************************************/
void XrdSecProtocolsss::Delete()
{
// Delete things that get re-allocated every time. The staticID is allocated
// only once so it must stick around for every instance of this object.
//
if (urName) free(urName); // Same pointer as Entity.host
if (idBuff) free(idBuff);
if (Crypto && Crypto != CryptObj) delete Crypto;
if (keyTab && keyTab != ktObject) delete keyTab;
delete this;
}
/******************************************************************************/
/* Private: e M s g */
/******************************************************************************/
int XrdSecProtocolsss::eMsg(const char *epname, int rc,
const char *txt1, const char *txt2,
const char *txt3, const char *txt4)
{
std::cerr <<"Secsss (" << epname <<"): ";
std::cerr <<txt1;
if (rc>0) std::cerr <<"; " <<XrdSysE2T(rc);
if (txt2) std::cerr <<txt2;
if (txt3) std::cerr <<txt3;
if (txt4) {std::cerr <<txt4;}
std::cerr <<"\n" <<std::flush;
return (rc ? (rc < 0 ? rc : -rc) : -1);
}
/******************************************************************************/
/* Private: E n c o d e */
/******************************************************************************/
XrdSecCredentials *XrdSecProtocolsss::Encode(XrdOucErrInfo *einfo,
XrdSecsssKT::ktEnt &encKey,
XrdSecsssRR_Hdr *rrHdr,
XrdSecsssRR_DataHdr *rrDHdr,
int dLen)
{
char *credP;
int knum, cLen, hdrSZ = sizeof(XrdSecsssRR_Hdr) + rrHdr->knSize;
// Make sure we don't overrun a 1 server's buffer. V2 servers are forgiving.
//
if (!v2EndPnt && dLen > (int)sizeof(XrdSecsssRR_Data))
{Fatal(einfo,"Encode",ENOBUFS,"Insufficient buffer space for credentials.");
return (XrdSecCredentials *)0;
}
// Complete the packet
//
XrdSecsssKT::genKey(rrDHdr->Rand, sizeof(rrDHdr->Rand));
rrDHdr->GenTime = htonl(myClock());
memset(rrDHdr->Pad, 0, sizeof(rrDHdr->Pad));
// Allocate an output buffer
//
cLen = hdrSZ + dLen + Crypto->Overhead();
if (!(credP = (char *)malloc(cLen)))
{Fatal(einfo, "Encode", ENOMEM, "Insufficient memory for credentials.");
return (XrdSecCredentials *)0;
}
// Copy the header and encrypt the data
//
memcpy(credP, (const void *)rrHdr, hdrSZ);
CLDBG("Encode keyid: " <<encKey.Data.ID <<" bytes " <<cLen-hdrSZ);
if ((dLen = Crypto->Encrypt(encKey.Data.Val, encKey.Data.Len, (char *)rrDHdr,
dLen, credP+hdrSZ, cLen-hdrSZ)) <= 0)
{Fatal(einfo, "Encode", -dLen, "Unable to encrypt credentials.");
return (XrdSecCredentials *)0;
}
// Return new credentials
//
dLen += hdrSZ; knum = encKey.Data.ID&0x7fffffff;
CLDBG("Ret " <<dLen <<" bytes of credentials; k=" <<knum);
return new XrdSecCredentials(credP, dLen);
}
/******************************************************************************/
/* Private: F a t a l */
/******************************************************************************/
int XrdSecProtocolsss::Fatal(XrdOucErrInfo *erP, const char *epn, int rc,
const char *etxt)
{
if (erP) {erP->setErrInfo(rc, etxt);
CLDBG(epn <<": " <<etxt);
}
else eMsg(epn, rc, etxt);
return 0;
}
/******************************************************************************/
/* Private: g e t C r e d */
/******************************************************************************/
int XrdSecProtocolsss::getCred(XrdOucErrInfo *einfo, XrdSecsssRR_DataHdr *&dP,
const char *myUrlID, const char *myIP)
{
int dLen;
// Indicate we have been here
//
Sequence = 1;
// For mutual authentication, the server needs to first send back a handshake.
//
if (isMutual)
{dP = (XrdSecsssRR_DataHdr *)malloc(XrdSecsssRR_Data_HdrLen);
dP->Options = XrdSecsssRR_DataHdr::SndLID;
return XrdSecsssRR_Data_HdrLen;
}
// Otherwise we use a static ID or a mapped id. Note that we disallow sending
// credentials unless mutual authentication occurs.
//
if (myUrlID && idMap)
{if ((dLen = idMap->Find(myUrlID, (char *&)dP, myIP, dataOpts)) <= 0)
return Fatal(einfo, "getCred", ESRCH, "No loginid mapping.");
} else {
int theOpts = dataOpts & ~XrdSecsssEnt::addCreds;
dLen = staticID->RR_Data((char *&)dP, myIP, theOpts);
}
// Return response length
//
dP->Options = XrdSecsssRR_DataHdr::UseData;
return dLen;
}
/******************************************************************************/
int XrdSecProtocolsss::getCred(XrdOucErrInfo *einfo,
XrdSecsssRR_DataHdr *&dP,
const char *myUrlID,
const char *myIP,
XrdSecParameters *parm)
{
XrdSecsssKT::ktEnt decKey;
XrdSecsssRR_Data prData;
char *lidP = 0, *bP, *idP, *eodP, idType;
int idSz, dLen, theOpts;
// Make sure we can decode this and not overrun our buffer
//
if (parm->size > (int)sizeof(prData.Data))
return Fatal(einfo, "getCred", EINVAL, "Invalid server response size.");
// Decode the credentials
//
if ((dLen = Decode(einfo, decKey, parm->buffer, &prData, parm->size)) <= 0)
return Fatal(einfo, "getCred", EINVAL, "Unable to decode server response.");
// Extract out the loginid. This messy code is for backwards compatibility.
//
bP = prData.Data; eodP = dLen + (char *)&prData;
while(bP < eodP)
{idType = *bP++;
if (!XrdOucPup::Unpack(&bP, eodP, &idP, idSz) || !idP || *idP == 0)
return Fatal(einfo, "getCred", EINVAL, "Invalid id string.");
switch(idType)
{case XrdSecsssRR_Data::theLgid: lidP = idP; break;
case XrdSecsssRR_Data::theHost: break;
case XrdSecsssRR_Data::theRand: break;
default: return Fatal(einfo,"getCred",EINVAL,"Invalid id type.");
}
}
// Verify that we have the loginid
//
if (!lidP) return Fatal(einfo, "getCred", ENOENT, "No loginid returned.");
// Try to map the id appropriately
//
if (!idMap) return staticID->RR_Data((char *&)dP, myIP, dataOpts);
// Map the loginid. We disallow sending credentials unless the key allows it.
//
if (!myUrlID) myUrlID = lidP;
if (!(decKey.Data.Opts & XrdSecsssKT::ktEnt::allUSR))
theOpts = dataOpts & ~XrdSecsssEnt::addCreds;
else theOpts = dataOpts;
if ((dLen = idMap->Find(lidP, (char *&)dP, myIP, theOpts)) <= 0)
return Fatal(einfo, "getCred", ESRCH, "No loginid mapping.");
// All done
//
dP->Options = XrdSecsssRR_DataHdr::UseData;
return dLen;
}
/******************************************************************************/
/* g e t C r e d e n t i a l s */
/******************************************************************************/
XrdSecCredentials *XrdSecProtocolsss::getCredentials(XrdSecParameters *parms,
XrdOucErrInfo *einfo)
{
static const int nOpts = XrdNetUtils::oldFmt;
XrdSecsssRR_Hdr2 rrHdr;
sssRR_DataHdr rrDataHdr;
XrdSecsssKT::ktEnt encKey;
XrdOucEnv *errEnv;
const char *myIP = 0, *myUD = 0;
char ipBuff[64];
int dLen;
// Make sure we can extract out required information and get it as needed
//
if (einfo && (errEnv=einfo->getEnv()))
{if (isMapped) myUD = errEnv->Get("username");
if (!(myIP=errEnv->Get("sockname")))
{int fd = epAddr->SockFD();
if (fd > 0 && XrdNetUtils::IPFormat(-fd,ipBuff,sizeof(ipBuff),nOpts))
myIP = ipBuff;
else myIP = 0;
}
}
// Do some debugging here
//
CLDBG("getCreds: " <<static_cast<int>(Sequence)
<< " ud: '" <<(myUD ? myUD : "")
<<"' ip: '" <<(myIP ? myIP : "") <<"'");
// Get the actual data portion
//
if (Sequence) dLen = getCred(einfo, rrDataHdr.P, myUD, myIP, parms);
else dLen = getCred(einfo, rrDataHdr.P, myUD, myIP);
if (!dLen) return (XrdSecCredentials *)0;
// Get an encryption key
//
if (keyTab->getKey(encKey))
{Fatal(einfo, "getCredentials", ENOENT, "Encryption key not found.");
return (XrdSecCredentials *)0;
}
// Fill out the header
//
strcpy(rrHdr.ProtID, XrdsssPROTOIDENT);
memset(rrHdr.Pad, 0, sizeof(rrHdr.Pad));
rrHdr.KeyID = htonll(encKey.Data.ID);
rrHdr.EncType = Crypto->Type();
// Determine if we should send the keyname (v2 servers only)
//
if (v2EndPnt)
{int k = strlen(encKey.Data.Name), n = (k + 8) & ~7;
if (strlcpy(rrHdr.keyName, encKey.Data.Name, sizeof(rrHdr.keyName)) >= sizeof(rrHdr.keyName))
{ Fatal(einfo, "getCredentials", EINVAL, "Encryption key name is too long.");
return nullptr;
}
if (n - k > 1) memset(rrHdr.keyName + k, 0, n - k);
rrHdr.knSize = static_cast<uint8_t>(n);
} else rrHdr.knSize = 0;
// Now simply encode the data and return the result
//
return Encode(einfo, encKey, &rrHdr, rrDataHdr.P, dLen);
}
/******************************************************************************/
/* Private: g e t L I D */
/******************************************************************************/
char *XrdSecProtocolsss::getLID(char *buff, int blen)
{
const char *dot;
// Extract out the loginid from the trace id
//
if (!Entity.tident
|| !(dot = index(Entity.tident,'.'))
|| dot == Entity.tident
|| dot >= (Entity.tident+blen)) strcpy(buff,"nobody");
else {int idsz = dot - Entity.tident;
strncpy(buff, Entity.tident, idsz);
*(buff+idsz) = '\0';
}
// All done
//
return buff;
}
/******************************************************************************/
/* I n i t _ C l i e n t */
/******************************************************************************/
int XrdSecProtocolsss::Init_Client(XrdOucErrInfo *erp, const char *pP)
{
XrdSysMutexHelper initMon(&initMutex);
XrdSecsssKT *ktP;
struct stat buf;
char *Colon;
int lifeTime;
// We must have <enccode>.[+]<lifetime>:<keytab>
//
if (!pP || !*pP) return Fatal(erp, "Init_Client", EINVAL,
"Client parameters missing.");
// Get encryption object
//
if (!*pP || *(pP+1) != '.') return Fatal(erp, "Init_Client", EINVAL,
"Encryption type missing.");
if (!(Crypto = Load_Crypto(erp, *pP))) return 0;
pP += 2;
// Check if this is a v2 server and if credentials are to be sent
//
if (*pP == '+')
{v2EndPnt = true;
dataOpts |= XrdSecsssEnt::addExtra;
if (*(pP+1) == '0') dataOpts |= XrdSecsssEnt::addCreds;
}
// The next item is the cred lifetime
//
lifeTime = strtol(pP, &Colon, 10);
if (!lifeTime || *Colon != ':') return Fatal(erp, "Init_Client", EINVAL,
"Credential lifetime missing.");
deltaTime = lifeTime; pP = Colon+1;
// Get the correct keytab
//
if (ktFixed || (ktObject && ktObject->Same(pP))) keyTab = ktObject;
else if (*pP == '/' && !stat(pP, &buf))
{if (!(ktP=new XrdSecsssKT(erp,pP,XrdSecsssKT::isClient,3600)))
return Fatal(erp, "Init_Client", ENOMEM,
"Unable to create keytab object.");
if (erp->getErrInfo()) {delete ktP; return 0;}
if (!ktObject) ktObject = ktP;
keyTab = ktP;
CLDBG("Client keytab='" <<pP <<"'");
} else keyTab = ktObject;
if (!keyTab)
return Fatal(erp, "Init_Client", ENOENT,
"Unable to determine keytab location.");
// All done
//
return 1;
}
/******************************************************************************/
/* I n i t _ S e r v e r */
/******************************************************************************/
int XrdSecProtocolsss::Init_Server(XrdOucErrInfo *erp, const char *pP)
{
// This is a trivial init
//
keyTab = ktObject;
Crypto = CryptObj;
return 1;
}
/******************************************************************************/
/* L o a d _ C l i e n t */
/******************************************************************************/
char *XrdSecProtocolsss::Load_Client(XrdOucErrInfo *erp, const char *parms)
{
static const char *KTPath = XrdSecsssKT::genFN();
static const int rfrHR = 60*60;
struct stat buf;
XrdSecsssID::authType aType = XrdSecsssID::idStatic;
const char *kP = 0;
char *myName;
// Get our full host name
//
if (!(myName = XrdNetUtils::MyHostName(0)))
{Fatal(erp, "Load_Client", ENOENT, "Unable to obtain local hostname.");
return (char *)0;
}
// Tell the entity serialization object who we are
//
XrdSecsssEnt::setHostName(myName);
free(myName);
// Check for the presence of a registry object
//
idMap = XrdSecsssID::getObj(aType, staticID);
switch(aType)
{case XrdSecsssID::idDynamic: isMutual = true; break;
case XrdSecsssID::idStaticM: isMutual = true;
idMap = 0; break;
case XrdSecsssID::idStatic: idMap = 0; break;
case XrdSecsssID::idMapped: isMapped = true; break;
case XrdSecsssID::idMappedM: isMapped = true; break;
default: idMap = 0; break;
}
// We want to establish the default location of the keytable. First check
// the environment passed from the client then the envar. We support two
// version of the envar for backward compatibility due to an early mistake.
//
if( erp && erp->getEnv() && ( kP = erp->getEnv()->Get( "xrd.sss" ) ) )
ktFixed = true;
else if ( ( (kP = getenv("XrdSecSSSKT")) || (kP = getenv("XrdSecsssKT")) )
&& *kP && !stat(kP, &buf))
ktFixed = true;
else kP = 0;
if (!kP && !stat(KTPath, &buf)) kP = KTPath;
// Build the keytable if we actual have a path (if none, then the server
// will have to supply the path)
//
if (kP)
{if (!(ktObject=new XrdSecsssKT(erp,kP,XrdSecsssKT::isClient,rfrHR)))
{Fatal(erp, "Load_Client", ENOMEM, "Unable to create keytab object.");
return (char *)0;
}
if (erp && erp->getErrInfo())
{delete ktObject, ktObject = 0; return (char *)0;}
CLDBG("Client keytab='" <<kP <<"'");
}
// All done
//
return (char *)"";
}
/******************************************************************************/
/* Private: L o a d _ C r y p t o */
/******************************************************************************/
XrdCryptoLite *XrdSecProtocolsss::Load_Crypto(XrdOucErrInfo *erp,
const char *eN)
{
XrdCryptoLite *cP;
char buff[128];
int rc, i = 0;
// Find correct crypto object
//
while(CryptoTab[i].cName && strcmp(CryptoTab[i].cName, eN)) i++;
// If we didn't find it, complain
//
if (!CryptoTab[i].cName)
{sprintf(buff, "Secsss: %s cryptography not supported.", eN);
Fatal(erp, "Load_Crypto", EINVAL, buff);
return (XrdCryptoLite *)0;
}
// Return load result
//
if ((cP = XrdCryptoLite::Create(rc, eN, CryptoTab[i].cType))) return cP;
sprintf(buff,"Secsss: %s cryptography load failed; %s",eN,XrdSysE2T(rc));
Fatal(erp, "Load_Crypto", EINVAL, buff);
return (XrdCryptoLite *)0;
}
/******************************************************************************/
XrdCryptoLite *XrdSecProtocolsss::Load_Crypto(XrdOucErrInfo *erp,
const char eT)
{
XrdCryptoLite *cP;
char buff[128];
int rc, i = 0;
// Check if we can use the satic object
//
if (CryptObj && eT == CryptObj->Type()) return CryptObj;
// Find correct crypto object
//
while(CryptoTab[i].cName && CryptoTab[i].cType != eT) i++;
// If we didn't find it, complain
//
if (!CryptoTab[i].cName)
{sprintf(buff, "Secsss: 0x%hhx cryptography not supported.", eT);
Fatal(erp, "Load_Crypto", EINVAL, buff);
return (XrdCryptoLite *)0;
}
// Return load result
//
if ((cP = XrdCryptoLite::Create(rc, CryptoTab[i].cName, eT))) return cP;
sprintf(buff,"Secsss: 0x%hhx cryptography load failed; %s",eT,XrdSysE2T(rc));
Fatal(erp, "Load_Crypto", EINVAL, buff);
return (XrdCryptoLite *)0;
}
/******************************************************************************/
/* L o a d _ S e r v e r */
/******************************************************************************/
char *XrdSecProtocolsss::Load_Server(XrdOucErrInfo *erp, const char *parms)
{
const char *msg = 0;
const char *encName = "bf32", *ktClient = "", *ktServer = 0;
char buff[2048], parmbuff[2048], *op, *od, *eP;
int lifeTime = 13, rfrTime = 60*60;
XrdOucTokenizer inParms(parmbuff);
const char *ask4Creds = "";
// Duplicate the parms
//
if (parms) strlcpy(parmbuff, parms, sizeof(parmbuff));
// Expected parameters: [{-c | --clientkt} <ckt_path>]
// [{-e | --encrypt} <enctype>]
// [{-g | --getcreds}]
// [{-k | --keyname}]
// [{-l | --lifetime} <seconds>]
// [{-p | --proxy} <prots>]
// [{-r | --refresh} <minutes>]
// [{-s | --serverkt} <skt_path>]
//
if (parms && inParms.GetLine())
while((op = inParms.GetToken()))
{if (!strcmp("-k", op) || !strcmp("--keyname", op))
{sssUseKN = true;
continue;
}
if (!strcmp("-g", op) || !strcmp("--getcreds", op))
{ask4Creds = "0";
continue;
}
if (!(od = inParms.GetToken()))
{sprintf(buff,"Secsss: Missing %s parameter argument",op);
msg = buff; break;
}
if (!strcmp("-c", op) || !strcmp("--clientkt", op))
ktClient = od;
else if (!strcmp("-e", op) || !strcmp("--encrypt", op))
encName = od;
else if (!strcmp("-l", op) || !strcmp("--lifetime", op))
{lifeTime = strtol(od, &eP, 10) * 60;
if (errno || *eP || lifeTime < 1)
{msg = "Secsss: Invalid life time"; break;}
}
else if (!strcmp("-p", op) || !strcmp("--proxy", op))
{int n = strlen(od) + 2;
aProts = (char *)malloc(n);
*aProts = ':';
strcpy(aProts+1, od);
}
else if (!strcmp("-r", op) || !strcmp("--rfresh", op))
{rfrTime = strtol(od, &eP, 10) * 60;
if (errno || *eP || rfrTime < 600)
{msg = "Secsss: Invalid refresh time"; break;}
}
else if (!strcmp("-s", op) || !strcmp("-serverkt", op))
ktServer = od;
else {sprintf(buff,"Secsss: Invalid parameter - %s",op);
msg = buff; break;
}
}
// Check for errors
//
if (msg) {Fatal(erp, "Load_Server", EINVAL, msg); return (char *)0;}
// Load the right crypto object
//
if (!(CryptObj = Load_Crypto(erp, encName))) return (char *)0;
// Supply default keytab location if not specified
//
if (!ktServer) ktServer = XrdSecsssKT::genFN();
// Set the delta time used to expire credentials
//
deltaTime = lifeTime;
// Create a keytab object (only one for the server)
//
if (!(ktObject = new XrdSecsssKT(erp, ktServer, XrdSecsssKT::isServer,
rfrTime)))
{Fatal(erp, "Load_Server", ENOMEM, "Unable to create keytab object.");
return (char *)0;
}
if (erp->getErrInfo()) return (char *)0;
ktFixed = true;
CLDBG("Server keytab='" <<ktServer <<"'");
// Construct client parameter <enccode>.+<lifetime>:<keytab>
// Note: The plus preceding the <lifetime> indicates that we are a V2 server.
// V1 clients will simply ignore this and treat us as a V1 server.
//
sprintf(buff, "%c.+%s%d:%s", CryptObj->Type(),ask4Creds,lifeTime,ktClient);
CLDBG("client parms='" <<buff <<"'");
return strdup(buff);
}
/******************************************************************************/
/* m y C l o c k */
/******************************************************************************/
int XrdSecProtocolsss::myClock()
{
static const time_t baseTime = 1222183880;
return static_cast<int>(time(0)-baseTime);
}
/******************************************************************************/
/* s e t I D */
/******************************************************************************/
char *XrdSecProtocolsss::setID(char *id, char **idP)
{
if (id)
{int n = strlen(id);
strcpy(*idP, id); id = *idP; *idP = *idP + n + 1;
}
return id;
}
/******************************************************************************/
/* s e t I P */
/******************************************************************************/
void XrdSecProtocolsss::setIP(XrdNetAddrInfo &endPoint)
{
if (!endPoint.Format(urIP, sizeof(urIP), XrdNetAddrInfo::fmtAdv6)) *urIP=0;
if (!endPoint.Format(urIQ, sizeof(urIQ), XrdNetAddrInfo::fmtAdv6,
XrdNetAddrInfo::old6Map4)) *urIQ=0;
Entity.addrInfo = epAddr = &endPoint;
}
/******************************************************************************/
/* X r d S e c P r o t o c o l s s s I n i t */
/******************************************************************************/
extern "C"
{
char *XrdSecProtocolsssInit(const char mode,
const char *parms,
XrdOucErrInfo *erp)
{
// Set debug option
//
if (getenv("XrdSecDEBUG")) sssDEBUG = true;
// Perform load-time initialization
//
return (mode == 'c' ? XrdSecProtocolsss::Load_Client(erp, parms)
: XrdSecProtocolsss::Load_Server(erp, parms));
}
}
/******************************************************************************/
/* X r d S e c P r o t o c o l s s s O b j e c t */
/******************************************************************************/
XrdVERSIONINFO(XrdSecProtocolsssObject,secsss);
extern "C"
{
XrdSecProtocol *XrdSecProtocolsssObject(const char mode,
const char *hostname,
XrdNetAddrInfo &endPoint,
const char *parms,
XrdOucErrInfo *erp)
{
XrdSecProtocolsss *prot;
int Ok;
// Get a new protocol object
//
if (!(prot = new XrdSecProtocolsss(endPoint.Name(hostname), endPoint)))
XrdSecProtocolsss::Fatal(erp, "sss_Object", ENOMEM,
"Secsss: Insufficient memory for protocol.");
else {Ok = (mode == 'c' ? prot->Init_Client(erp, parms)
: prot->Init_Server(erp, parms));
if (!Ok) {prot->Delete(); prot = 0;}
}
// All done
//
return (XrdSecProtocol *)prot;
}
}
XrdNetUtils.hh
XrdOucCRC.hh
XrdOucEnv.hh
XrdOucErrInfo.hh
XrdOucPup.hh
XrdOucTokenizer.hh
XrdOucUtils.hh
stat
#define stat(a, b)
Definition XrdPosix.hh:101
XrdSecEntityAttr.hh
XrdSecPROTOIDSIZE
#define XrdSecPROTOIDSIZE
Definition XrdSecEntity.hh:47
XrdSecParameters
XrdSecBuffer XrdSecParameters
Definition XrdSecInterface.hh:79
XrdSecCredentials
XrdSecBuffer XrdSecCredentials
Definition XrdSecInterface.hh:69
CLDBG
#define CLDBG(x)
Definition XrdSecProtocolkrb5.cc:82
XrdsssPROTOIDENT
#define XrdsssPROTOIDENT
Definition XrdSecProtocolsss.cc:63
XrdSecProtocolsssObject
XrdSecProtocol * XrdSecProtocolsssObject(const char mode, const char *hostname, XrdNetAddrInfo &endPoint, const char *parms, XrdOucErrInfo *erp)
Definition XrdSecProtocolsss.cc:1113
XrdVERSIONINFO
XrdVERSIONINFO(XrdSecProtocolsssObject, secsss)
XrdSecProtocolsssInit
char * XrdSecProtocolsssInit(const char mode, const char *parms, XrdOucErrInfo *erp)
Definition XrdSecProtocolsss.cc:1089
XrdSecProtocolsss.hh
eMsg
#define eMsg(x)
Definition XrdSecsssAdmin.cc:53
XrdSecsssEnt.hh
XrdSecsssRR_Data_HdrLen
static const int XrdSecsssRR_Data_HdrLen
Definition XrdSecsssRR.hh:77
emsg
int emsg(int rc, char *msg)
Definition XrdSectestServer.cc:309
XrdSysE2T
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104
XrdSysE2T.hh
strlcpy
size_t strlcpy(char *dst, const char *src, size_t sz)
Definition XrdSysPlatform.cc:60
XrdSysPlatform.hh
XrdSysPthread.hh
XrdCryptoLite
Definition XrdCryptoLite.hh:40
XrdCryptoLite::Create
static XrdCryptoLite * Create(int &rc, const char *Name, const char Type='\0')
Definition XrdCryptoLite.cc:50
XrdNetAddrInfo
Definition XrdNetAddrInfo.hh:54
XrdNetAddrInfo::old6Map4
static const int old6Map4
Use deprecated IPV6 mapped format.
Definition XrdNetAddrInfo.hh:106
XrdNetAddrInfo::Format
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
Definition XrdNetAddrInfo.cc:81
XrdNetAddrInfo::fmtAdv6
@ fmtAdv6
Definition XrdNetAddrInfo.hh:102
XrdNetAddrInfo::Name
const char * Name(const char *eName=0, const char **eText=0)
Definition XrdNetAddrInfo.cc:309
XrdNetUtils::MyHostName
static char * MyHostName(const char *eName="*unknown*", const char **eText=0)
Definition XrdNetUtils.cc:702
XrdNetUtils::IPFormat
static int IPFormat(const struct sockaddr *sAddr, char *bP, int bL, int opts=0)
Definition XrdNetUtils.cc:619
XrdNetUtils::oldFmt
static const int oldFmt
Definition XrdNetUtils.hh:274
XrdOucEnv
Definition XrdOucEnv.hh:42
XrdOucEnv::Get
char * Get(const char *varname)
Definition XrdOucEnv.hh:69
XrdOucErrInfo
Definition XrdOucErrInfo.hh:101
XrdOucErrInfo::getEnv
XrdOucEnv * getEnv()
Definition XrdOucErrInfo.hh:307
XrdOucErrInfo::setErrInfo
int setErrInfo(int code, const char *emsg)
Definition XrdOucErrInfo.hh:147
XrdOucErrInfo::getErrInfo
int getErrInfo()
Definition XrdOucErrInfo.hh:243
XrdOucPup::Unpack
static int Unpack(char **buff, const char *bend, char **data, int &dlen)
Definition XrdOucPup.cc:250
XrdOucPup::Pack
static int Pack(struct iovec **, const char *, unsigned short &buff)
Definition XrdOucPup.cc:52
XrdOucTokenizer
Definition XrdOucTokenizer.hh:33
XrdOucTokenizer::GetToken
char * GetToken(char **rest=0, int lowcase=0)
Definition XrdOucTokenizer.cc:93
XrdOucTokenizer::GetLine
char * GetLine()
Definition XrdOucTokenizer.cc:55
XrdOucUtils::getGID
static bool getGID(const char *gName, gid_t &gID)
Definition XrdOucUtils.cc:559
XrdOucUtils::getUID
static bool getUID(const char *uName, uid_t &uID, gid_t *gID=0)
Definition XrdOucUtils.cc:575
XrdSecEntity::tident
const char * tident
Trace identifier always preset.
Definition XrdSecEntity.hh:81
XrdSecProtocol
Definition XrdSecInterface.hh:131
XrdSecProtocol::Entity
XrdSecEntity Entity
Definition XrdSecInterface.hh:139
XrdSecProtocolsss
Definition XrdSecProtocolsss.hh:45
XrdSecProtocolsss::eMsg
static int eMsg(const char *epn, int rc, const char *txt1, const char *txt2=0, const char *txt3=0, const char *txt4=0)
Definition XrdSecProtocolsss.cc:461
XrdSecProtocolsss::Load_Client
static char * Load_Client(XrdOucErrInfo *erp, const char *Parms)
Definition XrdSecProtocolsss.cc:815
XrdSecProtocolsss::Init_Server
int Init_Server(XrdOucErrInfo *erp, const char *Parms)
Definition XrdSecProtocolsss.cc:801
XrdSecProtocolsss::getCredentials
XrdSecCredentials * getCredentials(XrdSecParameters *parms=0, XrdOucErrInfo *einfo=0)
Definition XrdSecProtocolsss.cc:644
XrdSecProtocolsss::Load_Server
static char * Load_Server(XrdOucErrInfo *erp, const char *Parms)
Definition XrdSecProtocolsss.cc:948
XrdSecProtocolsss::Authenticate
int Authenticate(XrdSecCredentials *cred, XrdSecParameters **parms, XrdOucErrInfo *einfo=0)
Definition XrdSecProtocolsss.cc:162
XrdSecProtocolsss::Fatal
static int Fatal(XrdOucErrInfo *erP, const char *epn, int rc, const char *etxt)
Definition XrdSecProtocolsss.cc:531
XrdSecProtocolsss::Delete
void Delete()
Delete the protocol object. DO NOT use C++ delete() on this object.
Definition XrdSecProtocolsss.cc:444
XrdSecProtocolsss::Init_Client
int Init_Client(XrdOucErrInfo *erp, const char *Parms)
Definition XrdSecProtocolsss.cc:740
XrdSecProtocolsss::Crypto
Definition XrdSecProtocolsss.hh:80
XrdSecsssEnt
Definition XrdSecsssEnt.hh:43
XrdSecsssEnt::setHostName
static void setHostName(const char *hnP)
Definition XrdSecsssEnt.cc:313
XrdSecsssEnt::addExtra
static const int addExtra
Add v2 data.
Definition XrdSecsssEnt.hh:77
XrdSecsssEnt::addCreds
static const int addCreds
Add v2 data plus creds.
Definition XrdSecsssEnt.hh:78
XrdSecsssID
Definition XrdSecsssID.hh:54
XrdSecsssID::authType
authType
Definition XrdSecsssID.hh:80
XrdSecsssID::idStatic
@ idStatic
Definition XrdSecsssID.hh:86
XrdSecsssID::idMappedM
@ idMappedM
Definition XrdSecsssID.hh:84
XrdSecsssID::idDynamic
@ idDynamic
Definition XrdSecsssID.hh:80
XrdSecsssID::idStaticM
@ idStaticM
Definition XrdSecsssID.hh:89
XrdSecsssID::idMapped
@ idMapped
Definition XrdSecsssID.hh:82
XrdSecsssKT::ktEnt
Definition XrdSecsssKT.hh:45
XrdSecsssKT::ktEnt::ktData::User
char User[UserSZ]
Definition XrdSecsssKT.hh:62
XrdSecsssKT::ktEnt::anyUSR
static const int anyUSR
Definition XrdSecsssKT.hh:67
XrdSecsssKT::ktEnt::Data
struct XrdSecsssKT::ktEnt::ktData Data
XrdSecsssKT::ktEnt::noIPCK
static const int noIPCK
Definition XrdSecsssKT.hh:70
XrdSecsssKT::ktEnt::ktData::Opts
int Opts
Definition XrdSecsssKT.hh:58
XrdSecsssKT::ktEnt::anyGRP
static const int anyGRP
Definition XrdSecsssKT.hh:68
XrdSecsssKT::ktEnt::allUSR
static const int allUSR
Definition XrdSecsssKT.hh:66
XrdSecsssKT::ktEnt::ktData::Val
char Val[maxKLen]
Definition XrdSecsssKT.hh:60
XrdSecsssKT::ktEnt::usrGRP
static const int usrGRP
Definition XrdSecsssKT.hh:69
XrdSecsssKT::ktEnt::NameSZ
static const int NameSZ
Definition XrdSecsssKT.hh:49
XrdSecsssKT::ktEnt::ktData::Name
char Name[NameSZ]
Definition XrdSecsssKT.hh:61
XrdSecsssKT::ktEnt::ktData::ID
long long ID
Definition XrdSecsssKT.hh:54
XrdSecsssKT::ktEnt::ktData::Len
int Len
Definition XrdSecsssKT.hh:59
XrdSecsssKT::ktEnt::ktData::Grup
char Grup[GrupSZ]
Definition XrdSecsssKT.hh:63
XrdSecsssKT
Definition XrdSecsssKT.hh:41
XrdSecsssKT::genFN
static char * genFN()
Definition XrdSecsssKT.cc:249
XrdSecsssKT::isClient
@ isClient
Definition XrdSecsssKT.hh:114
XrdSecsssKT::isServer
@ isServer
Definition XrdSecsssKT.hh:114
XrdSecsssKT::genKey
static void genKey(char *Buff, int blen)
Definition XrdSecsssKT.cc:268
XrdSysMutexHelper
Definition XrdSysPthread.hh:263
XrdSysMutex
Definition XrdSysPthread.hh:165
XrdSecBuffer::buffer
char * buffer
Pointer to the buffer.
Definition XrdSecInterface.hh:53
XrdSecBuffer::size
int size
Size of the buffer or length of data in the buffer.
Definition XrdSecInterface.hh:52
XrdSecsssRR_DataHdr
Definition XrdSecsssRR.hh:66
XrdSecsssRR_DataHdr::Options
char Options
Definition XrdSecsssRR.hh:70
XrdSecsssRR_DataHdr::SndLID
static const char SndLID
Definition XrdSecsssRR.hh:72
XrdSecsssRR_DataHdr::UseData
static const char UseData
Definition XrdSecsssRR.hh:71
XrdSecsssRR_DataResp
Definition XrdSecsssRR.hh:112
XrdSecsssRR_DataResp::Data
char Data[XrdSecsssRR_Data::MinDSz+16]
Definition XrdSecsssRR.hh:113
XrdSecsssRR_Data
Definition XrdSecsssRR.hh:80
XrdSecsssRR_Data::theHost
static const char theHost
Definition XrdSecsssRR.hh:106
XrdSecsssRR_Data::theUser
static const char theUser
Definition XrdSecsssRR.hh:101
XrdSecsssRR_Data::theAKey
static const char theAKey
Definition XrdSecsssRR.hh:99
XrdSecsssRR_Data::theCaps
static const char theCaps
Definition XrdSecsssRR.hh:103
XrdSecsssRR_Data::Data
char Data[DataSz]
Definition XrdSecsssRR.hh:85
XrdSecsssRR_Data::theAuth
static const char theAuth
Definition XrdSecsssRR.hh:97
XrdSecsssRR_Data::theRole
static const char theRole
Definition XrdSecsssRR.hh:91
XrdSecsssRR_Data::theName
static const char theName
Definition XrdSecsssRR.hh:89
XrdSecsssRR_Data::theLgid
static const char theLgid
Definition XrdSecsssRR.hh:105
XrdSecsssRR_Data::theGrps
static const char theGrps
Definition XrdSecsssRR.hh:92
XrdSecsssRR_Data::theRand
static const char theRand
Definition XrdSecsssRR.hh:95
XrdSecsssRR_Data::theEndo
static const char theEndo
Definition XrdSecsssRR.hh:93
XrdSecsssRR_Data::theAVal
static const char theAVal
Definition XrdSecsssRR.hh:100
XrdSecsssRR_Data::theVorg
static const char theVorg
Definition XrdSecsssRR.hh:90
XrdSecsssRR_Data::theGrup
static const char theGrup
Definition XrdSecsssRR.hh:102
XrdSecsssRR_Data::theTID
static const char theTID
Definition XrdSecsssRR.hh:98
XrdSecsssRR_Data::MaxDSz
static const int MaxDSz
Definition XrdSecsssRR.hh:82
XrdSecsssRR_Data::theCred
static const char theCred
Definition XrdSecsssRR.hh:94
XrdSecsssRR_Hdr2
Definition XrdSecsssRR.hh:58
XrdSecsssRR_Hdr2::keyName
char keyName[XrdSecsssKT::ktEnt::NameSZ]
Definition XrdSecsssRR.hh:59
XrdSecsssRR_Hdr
Definition XrdSecsssRR.hh:42
XrdSecsssRR_Hdr::KeyID
long long KeyID
Definition XrdSecsssRR.hh:49
XrdSecsssRR_Hdr::knSize
uint8_t knSize
Definition XrdSecsssRR.hh:45
XrdSecsssRR_Hdr::EncType
char EncType
Definition XrdSecsssRR.hh:46
XrdSecsssRR_Hdr::ProtID
char ProtID[4]
Definition XrdSecsssRR.hh:43
XrdSecsssRR_Hdr::etBFish32
static const char etBFish32
Definition XrdSecsssRR.hh:47
XrdSecsssRR_Hdr::Pad
char Pad[2]
Definition XrdSecsssRR.hh:44