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)
XrdSecCredentials * | getCredentials (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 XrdOucTrace * | EnableTracing ()
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.

: XrdSecProtocol("gsi")
{
// Default constructor
EPNAME("XrdSecProtocolgsi");
if (QTRACE(Authen)) { PRINT("constructing: "<<this); }
// Create instance of the handshake vars
if ((hs = new gsiHSVars())) {
// Update time stamp
hs->TimeStamp = time(0);
// Local handshake variables
hs->Tty = (isatty(0) == 0 || isatty(1) == 0) ? 0 : 1;
} else {
PRINT("could not create handshake vars object");
}
// Set host name and address
// The hostname is critical for the GSI protocol; it must match the potential
// names on the remote EEC. We default to the hostname requested by the user to
// the client (or proxy). However, as we may have been redirected to an IP
// address instead of an actual hostname, we must fallback to a reverse DNS lookup.
// As of time of testing (June 2018), EOS will redirect to an IP address to handle
// metadata commands and rely on the reverse DNS lookup for GSI security to function.
// Hence, this fallback likely needs to be kept for some time.
//
// We provide servers a switch and clients an environment variable to override all
// usage of DNS (processed on XrdSecProtocolgsiInit).
// Default is to fallback to DNS lookups in limited
// cases for backward compatibility.
expectedHost = NULL;
if (TrustDNS) {
if (!hname || !XrdNetAddrInfo::isHostName(hname)) {
Entity.host = strdup(endPoint.Name(""));
} else {
// At this point, hname still may possibly be a non-qualified domain name.
// If there is a '.' character, then we assume it is a qualified domain name --
// otherwise, we use DNS.
//
// NOTE: We can definitively test whether this is a qualified domain name by
// simply appending a '.' to `hname` and performing a lookup. However, this
// causes DNS to be used by every lookup - meaning we rely on the security
// of DNS for all cases; we want to avoid this.
if (strchr(hname, '.')) {
// We have a valid hostname; proceed.
Entity.host = strdup(hname);
} else {
XrdNetAddr xrd_addr;
char canonname[256];
if (!xrd_addr.Set(hname) || (xrd_addr.Format(canonname, 256, XrdNetAddrInfo::fmtName, XrdNetAddrInfo::noPort) <= 0)) {
Entity.host = strdup(hname);
} else {
Entity.host = strdup(canonname);
}
}
}
} else {
// We have been told via environment variable to not trust DNS; use the exact
// hostname provided by the user.
// char dnBuff[256];
// getdomainname(dnBuff, sizeof(dnBuff));
Entity.host = strdup(hname);
expectedHost = strdup(hname);
}
epAddr = endPoint;
Entity.addrInfo = &epAddr;
// Init session variables
sessionCF = 0;
sessionKey = 0;
bucketKey = 0;
sessionMD = 0;
sessionKsig = 0;
sessionKver = 0;
sessionKver = 0;
proxyChain = 0;
useIV = false;
//
// Notify, if required
DEBUG("constructing: host: "<< Entity.host);
DEBUG("p: "<<XrdSecPROTOIDENT<<", plen: "<<XrdSecPROTOIDLEN);
//
// basic settings
options = opts;
srvMode = 0;
//
// Mode specific initializations
if (Server) {
srvMode = 1;
DEBUG("mode: server");
} else {
DEBUG("mode: client");
//
// Decode received buffer
if (parms) {
XrdOucString p("&P=gsi,");
p += parms;
hs->Parms = new XrdSutBuffer(p.c_str(), p.length());
}
}
// We are done
String vers = Version;
vers.insert('.',vers.length()-2);
vers.insert('.',vers.length()-5);
DEBUG("object created: v"<<vers.c_str());
}
DEBUG
#define DEBUG(x)
Definition XrdBwmTrace.hh:54
EPNAME
#define EPNAME(x)
Definition XrdBwmTrace.hh:56
QTRACE
#define QTRACE(act)
Definition XrdCmsTrace.hh:49
PRINT
#define PRINT(y)
Definition XrdCryptosslTrace.hh:39
Version
static const kXR_int32 Version
Definition XrdSecProtocolgsi.cc:79
String
XrdOucString String
Definition XrdSecProtocolgsi.hh:62
XrdSecPROTOIDLEN
#define XrdSecPROTOIDLEN
Definition XrdSecProtocolgsi.hh:66
XrdSecPROTOIDENT
#define XrdSecPROTOIDENT
Definition XrdSecProtocolgsi.hh:65
opts
struct myOpts opts
XrdNetAddrInfo::noPort
static const int noPort
Do not add port number.
Definition XrdNetAddrInfo.hh:104
XrdNetAddrInfo::isHostName
static bool isHostName(const char *name)
Definition XrdNetAddrInfo.cc:278
XrdNetAddrInfo::Format
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
Definition XrdNetAddrInfo.cc:81
XrdNetAddrInfo::fmtName
@ fmtName
Hostname if it is resolvable o/w use fmtAddr.
Definition XrdNetAddrInfo.hh:100
XrdNetAddrInfo::Name
const char * Name(const char *eName=0, const char **eText=0)
Definition XrdNetAddrInfo.cc:309
XrdNetAddr::Set
const char * Set(const char *hSpec, int pNum=PortInSpec)
Definition XrdNetAddr.cc:216
XrdOucString::insert
void insert(const int i, int start=-1)
Definition XrdOucString.cc:691
XrdOucString::length
int length() const
Definition XrdOucString.hh:279
XrdOucString::c_str
const char * c_str() const
Definition XrdOucString.hh:278
XrdSecProtocol::Entity
XrdSecEntity Entity
Definition XrdSecInterface.hh:139
XrdSecProtocol::XrdSecProtocol
XrdSecProtocol(const char *pName)
Constructor.
Definition XrdSecInterface.hh:317
XrdSecProtocolgsi::gsiHSVars
friend class gsiHSVars
Definition XrdSecProtocolgsi.hh:283

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

Here is the call graph for this function:

## ~XrdSecProtocolgsi()

virtual XrdSecProtocolgsi::~XrdSecProtocolgsi | ( |  | ) |

inline virtual

Definition at line 294 of file XrdSecProtocolgsi.hh.

{} // Delete() does it all

## Member Function Documentation

## Authenticate()

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

virtual

Authenticate a client.

Parameters

  cred | Credentials supplied by the client.
  parms | Place where the address of additional authentication data is to be placed for another autrhentication handshake.
  einfo | The 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 succeeded) < 0 -> einfo present (error has occurred)

Implements XrdSecProtocol.

Definition at line 1748 of file XrdSecProtocolgsi.cc.

{
//
// Check if we have any credentials or if no credentials really needed.
// In either case, use host name as client name
EPNAME("Authenticate");
//
// If cred buffer is two small or empty assume host protocol
if (cred->size <= (int)XrdSecPROTOIDLEN || !cred->buffer) {
strncpy(Entity.prot, "host", sizeof(Entity.prot));
return 0;
}
// Handshake vars conatiner must be initialized at this point
if (!hs)
return ErrS(Entity.tident,ei,0,0,0,kGSErrError,
"handshake var container missing",
"protocol initialization problems");
// Update time stamp
hs->TimeStamp = time(0);
//
// ID of this handshaking
if (hs->ID.length() <= 0)
hs->ID = Entity.tident;
DEBUG("handshaking ID: " << hs->ID);
// Local vars
int kS_rc = kgST_more;
int step = 0;
int nextstep = 0;
char *bpub = 0;
int lpub = 0;
bool vomsFailed = false;
const char *stepstr = 0;
String Message;
String CryptList;
String Ciphers;
String Host;
String SrvPuKExp;
String Salt;
String RndmTag;
String ClntMsg(256);
// Buffer related
XrdSutBuffer *bpar = 0; // Global buffer
XrdSutBuffer *bmai = 0; // Main buffer
XrdSutBucket *bck = 0; // Generic bucket
// Proxy export related
XrdOucString spxy;
XrdSutBucket *bpxy = 0;
//
// Decode received buffer
if (!(bpar = new XrdSutBuffer((const char *)cred->buffer,cred->size)))
return ErrS(hs->ID,ei,0,0,0,kGSErrDecodeBuffer,"global",stepstr);
//
// Check protocol ID name
if (strcmp(bpar->GetProtocol(),XrdSecPROTOIDENT))
return ErrS(hs->ID,ei,bpar,bmai,0,kGSErrBadProtocol,stepstr);
//
// The step indicates what we are supposed to do
step = bpar->GetStep();
stepstr = ClientStepStr(step);
// Dump, if requested
XrdOucString bmsg;
if (QTRACE(Dump)) {
bmsg.form("IN: bpar: %s", stepstr);
bpar->Dump(bmsg.c_str());
}
//
// Parse input buffer
if (ParseServerInput(bpar, &bmai, ClntMsg) == -1) {
DEBUG(ClntMsg);
return ErrS(hs->ID,ei,bpar,bmai,0,kGSErrParseBuffer,ClntMsg.c_str(),stepstr);
}
//
// Version
DEBUG("version run by client: "<< hs->RemVers);
DEBUG("options req by client: "<< hs->Options);
//
// Dump, if requested
if (QTRACE(Dump)) {
if (bmai) {
bmsg.form("IN: bmai: %s", stepstr);
bmai->Dump(bmsg.c_str());
}
}
//
// Check random challenge
if (!CheckRtag(bmai, ClntMsg))
return ErrS(hs->ID,ei,bpar,bmai,0,kGSErrBadRndmTag,stepstr,ClntMsg.c_str());
// Extract the VOMS attrbutes, if required
XrdCryptoX509ExportChain_t X509ExportChain = (sessionCF) ? sessionCF->X509ExportChain() : 0;
if (!X509ExportChain) {
// Error
return ErrS(hs->ID,ei,0,0,0,kGSErrError,
"crypto factory function for chain export not found");
}
//
// Now action depens on the step
switch (step) {
case kXGC_certreq:
//
// Client required us to send our certificate and cipher DH public parameters:
// add first this last one.
// Extract buffer with public info for the cipher agreement
if (!(bpub = hs->Rcip->Public(lpub)))
return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrNoPublic,
"session",stepstr);
// If client supports decoding of signed DH, do sign them
if (hs->RemVers >= XrdSecgsiVersDHsigned) {
bck = new XrdSutBucket(bpub,lpub,kXRS_cipher);
if (sessionKsig) {
//
// Encrypt server DH public parameters with server key
if (sessionKsig->EncryptPrivate(*bck) <= 0)
return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrExportPuK,
"encrypting server DH public parameters",stepstr);
} else {
return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrExportPuK,
"server signing key undefined!",stepstr);
}
} else {
// Previous naming
bck = new XrdSutBucket(bpub,lpub,kXRS_puk);
}
//
// Add it to the global list
if (bpar->AddBucket(bck) != 0)
return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrAddBucket,
"main",stepstr);
//
// Add bucket with list of supported ciphers
if (bpar->AddBucket(DefCipher,kXRS_cipher_alg) != 0)
return ErrS(hs->ID,ei,bpar,bmai,0,
kGSErrAddBucket,XrdSutBuckStr(kXRS_cipher_alg),stepstr);
//
// Add bucket with list of supported MDs
if (bpar->AddBucket(DefMD,kXRS_md_alg) != 0)
return ErrS(hs->ID,ei,bpar,bmai,0,
kGSErrAddBucket,XrdSutBuckStr(kXRS_md_alg),stepstr);
//
// Add the server certificate
bpar->AddBucket(hs->Cbck);
// We are done for the moment
nextstep = kXGS_cert;
break;
case kXGC_cert:
//
// Client sent its own credentials: their are checked in
// ParseServerInput, so if we are here they are OK
kS_rc = kgST_ok;
nextstep = kXGS_none;
if (GMAPOpt > 0) {
// Get name from gridmap
String name;
QueryGMAP(hs->Chain, hs->TimeStamp, name);
DEBUG("username(s) associated with this DN: "<<name);
if (name.length() <= 0) {
// Grid map lookup failure
if (GMAPOpt == 2) {
// It was required, so we fail
kS_rc = kgST_error;
PRINT("ERROR: user mapping required, but lookup failed - failure");
break;
} else {
NOTIFY("WARNING: user mapping lookup failed - use DN or DN-hash as name");
}
} else {
//
// Extract user login name, if any
XrdSutBucket *bck = 0;
String user;
if ((bck = bmai->GetBucket(kXRS_user))) {
bck->ToString(user);
bmai->Deactivate(kXRS_user);
}
DEBUG("target user: "<<user);
if (user.length() > 0) {
// Check if the wanted username is authorized
String u;
int from = 0;
bool ok = 0;
while ((from = name.tokenize(u, from, ',')) != -1) {
if (user == u) { ok = 1; break; }
}
if (ok) {
name = u;
DEBUG("DN mapping: requested user is authorized: name is '"<<name<<"'");
} else {
// The requested username is not in the list; we warn and default to the first
// found (to be Globus compliant)
if (name.find(',') != STR_NPOS) name.erase(name.find(','));
PRINT("WARNING: user mapping lookup ok, but the requested user is not"
" authorized ("<<user<<"). Instead, mapped as " << name << ".");
}
} else {
// No username requested: we default to the first found (to be Globus compliant)
if (name.find(',') != STR_NPOS) name.erase(name.find(','));
DEBUG("user mapping lookup successful: name is '"<<name<<"'");
}
Entity.name = strdup(name.c_str());
Entity.eaAPI->Add("gridmap.name", "1", true);
}
}
// If not set, use DN
if (!Entity.name || (strlen(Entity.name) <= 0)) {
// No grid map: set the hash of the client DN as name
if (!GMAPuseDNname && hs->Chain->EEChash()) {
Entity.name = strdup(hs->Chain->EEChash());
} else if (GMAPuseDNname && hs->Chain->EECname()) {
Entity.name = strdup(hs->Chain->EECname());
} else {
PRINT("WARNING: DN missing: corruption? ");
}
}
// Add the DN as default moninfo if requested (the authz plugin may change this)
if (MonInfoOpt > 0 || ShowDN) {
const char *theDN = hs->Chain->EECname();
if (theDN) {
if (ShowDN && !GMAPuseDNname) {
PRINT(Entity.name<<" Subject DN='"<<theDN<<"'");
}
if (MonInfoOpt > 0) Entity.moninfo = strdup(theDN);
}
}
if (VOMSAttrOpt > vatIgnore && VOMSFun) {
// Fill the information needed by the external function
if (VOMSCertFmt == 1) {
// PEM base64
bpxy = (*X509ExportChain)(hs->Chain, true);
bpxy->ToString(spxy);
delete bpxy;
Entity.creds = strdup(spxy.c_str());
Entity.credslen = spxy.length();
} else {
// Raw (opaque) format, to be used with XrdCrypto
Entity.creds = (char *) hs->Chain;
Entity.credslen = 0;
}
if ((*VOMSFun)(Entity) != 0) {
vomsFailed = true;
if (VOMSAttrOpt == vatRequire) {
// Error
kS_rc = kgST_error;
PRINT("ERROR: the VOMS extraction plug-in reported "
"authentication failure");
break;
}
}
NOTIFY("VOMS: Entity.vorg: "<< (Entity.vorg ? Entity.vorg : "<none>"));
NOTIFY("VOMS: Entity.grps: "<< (Entity.grps ? Entity.grps : "<none>"));
NOTIFY("VOMS: Entity.role: "<< (Entity.role ? Entity.role : "<none>"));
NOTIFY("VOMS: Entity.endorsements: "<< (Entity.endorsements ? Entity.endorsements : "<none>"));
}
// Here prepare/extract the information for authorization
spxy = "";
bpxy = 0;
if (AuthzFun && AuthzKey && (AuthzAlways || vomsFailed)) {
// Fill the information needed by the external function
if (AuthzCertFmt == 1) {
// May have been already done
if (!Entity.creds || (Entity.creds && Entity.credslen == 0)) {
// PEM base64
bpxy = (*X509ExportChain)(hs->Chain, true);
bpxy->ToString(spxy);
Entity.creds = strdup(spxy.c_str());
Entity.credslen = spxy.length();
// If not empty Entity.creds is a pointer to hs->Chain and
// we need not to free it
}
} else {
// May have been already done
if (Entity.creds && Entity.credslen > 0) {
// Entity.creds is in PEM form, we need to free it
free(Entity.creds);
// Raw (opaque) format, to be used with XrdCrypto
Entity.creds = (char *) hs->Chain;
Entity.credslen = 0;
}
}
// Get the key
char *key = 0;
int lkey = 0;
if ((lkey = (*AuthzKey)(Entity, &key)) < 0) {
// Fatal error
kS_rc = kgST_error;
PRINT("ERROR: unable to get the key associated to this user");
break;
}
const char *dn = (const char *)key;
time_t now = hs->TimeStamp;
// We may have it in the cache
XrdSutCERef ceref;
bool rdlock = false;
XrdSutCacheArg_t arg = {kCE_ok, now, AuthzCacheTimeOut, kCE_disabled};
XrdSutCacheEntry *cent = cacheAuthzFun.Get(dn, rdlock, AuthzFunCheck, (void *) &arg);
if (!cent) {
// Fatal error
kS_rc = kgST_error;
PRINT("ERROR: unable to get cache entry for dn: "<<dn);
break;
}
ceref.Set(&(cent->rwmtx));
if (!rdlock) {
if (cent->buf1.buf)
FreeEntity((XrdSecEntity *) cent->buf1.buf);
SafeDelete(cent->buf1.buf);
SafeDelete(cent->buf2.buf);
}
if (cent->status != kCE_ok) {
int authzrc = 0;
if ((authzrc = (*AuthzFun)(Entity)) != 0) {
// Error
kS_rc = kgST_error;
PRINT("ERROR: the authz plug-in reported failure");
SafeDelete(key);
ceref.UnLock();
break;
} else {
cent->status = kCE_ok;
// Save a copy of the relevant Entity fields
XrdSecEntity *se = new XrdSecEntity();
int slen = 0;
CopyEntity(&Entity, se, &slen);
FreeEntity((XrdSecEntity *) cent->buf1.buf);
SafeDelete(cent->buf1.buf);
cent->buf1.buf = (char *) se;
cent->buf1.len = slen;
// Proxy expiration time
int notafter = hs->Chain->End() ? hs->Chain->End()->NotAfter() : -1;
cent->buf2.buf = (char *) new int(notafter);
cent->buf2.len = sizeof(int);
// Fill up the rest
cent->cnt = 0;
cent->mtime = now; // creation time
// Notify
DEBUG("Saved Entity to cacheAuthzFun ("<<slen<<" bytes)");
}
} else {
// Fetch a copy of the saved entity
int slen = 0;
FreeEntity(&Entity);
CopyEntity((XrdSecEntity *) cent->buf1.buf, &Entity, &slen);
// Notify
DEBUG("Got Entity from cacheAuthzFun ("<<slen<<" bytes)");
}
// Release lock
ceref.UnLock();
// Cleanup
SafeDelArray(key);
}
// Export proxy for authorization, if required
if (AuthzPxyWhat >= azFull) {
if (bpxy && AuthzPxyWhat == azLast) {
SafeDelete(bpxy); spxy = "";
SafeFree(Entity.creds);
Entity.credslen = 0;
}
if (!bpxy) {
if (AuthzPxyWhat == 1 && hs->Chain->End()) {
bpxy = hs->Chain->End()->Export();
} else {
bpxy = (*X509ExportChain)(hs->Chain, true);
}
bpxy->ToString(spxy);
}
if (AuthzPxyWhere == azCred) {
Entity.creds = strdup(spxy.c_str());
Entity.credslen = spxy.length();
} else {
// This should be deprecated
Entity.endorsements = strdup(spxy.c_str());
}
delete bpxy;
NOTIFY("Entity.endorsements: "<<(void *)Entity.endorsements);
NOTIFY("Entity.creds: "<<(void *)Entity.creds);
NOTIFY("Entity.credslen: "<<Entity.credslen);
} else if (bpxy) {
// Cleanup
SafeDelete(bpxy); spxy = "";
}
if (hs->RemVers >= 10100) {
if (hs->PxyChain) {
// The client is going to send over info for delegation
kS_rc = kgST_more;
nextstep = kXGS_pxyreq;
}
}
break;
case kXGC_sigpxy:
//
// Nothing to do after this
kS_rc = kgST_ok;
nextstep = kXGS_none;
//
// If something went wrong, print explanation
if (ClntMsg.length() > 0) {
PRINT(ClntMsg);
}
break;
default:
return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrBadOpt, stepstr);
}
if (kS_rc == kgST_more) {
//
// Add message to client
if (ClntMsg.length() > 0)
if (bmai->AddBucket(ClntMsg,kXRS_message) != 0) {
NOTIFY("problems adding bucket with message for client");
}
//
// Serialize, encrypt and add to the global list
if (AddSerialized('s', nextstep, hs->ID,
bpar, bmai, kXRS_main, sessionKey) != 0) {
return ErrS(hs->ID,ei,bpar,bmai,0, kGSErrSerialBuffer,
"main / session cipher",stepstr);
}
//
// Serialize the global buffer
char *bser = 0;
int nser = bpar->Serialized(&bser,'f');
//
// Dump, if requested
if (QTRACE(Authen)) {
bmsg.form("OUT: bpar: %s", ServerStepStr(bpar->GetStep()));
bpar->Dump(bmsg.c_str());
bmsg.form("OUT: bmai: %s", ServerStepStr(bpar->GetStep()));
bmai->Dump(bmsg.c_str());
}
//
// Create buffer for client
*parms = new XrdSecParameters(bser,nser);
} else {
//
// Cleanup handshake vars
SafeDelete(hs);
}
//
// We may release the buffers now
REL2(bpar,bmai);
//
// All done
return kS_rc;
}
XrdCryptoX509ExportChain_t
XrdSutBucket *(* XrdCryptoX509ExportChain_t)(XrdCryptoX509Chain *, bool)
Definition XrdCryptoFactory.hh:75
STR_NPOS
#define STR_NPOS
Definition XrdOucString.hh:250
XrdSecParameters
XrdSecBuffer XrdSecParameters
Definition XrdSecInterface.hh:79
ClientStepStr
static const char * ClientStepStr(int kclt)
Definition XrdSecProtocolgsi.cc:223
ServerStepStr
static const char * ServerStepStr(int ksrv)
Definition XrdSecProtocolgsi.cc:239
AuthzFunCheck
static bool AuthzFunCheck(XrdSutCacheEntry *e, void *a)
Definition XrdSecProtocolgsi.cc:1720
SafeDelete
#define SafeDelete(x)
Definition XrdSecProtocolgsi.hh:154
REL2
#define REL2(x, y)
Definition XrdSecProtocolgsi.hh:151
kXGS_cert
@ kXGS_cert
Definition XrdSecProtocolgsi.hh:101
kXGS_none
@ kXGS_none
Definition XrdSecProtocolgsi.hh:99
kXGS_pxyreq
@ kXGS_pxyreq
Definition XrdSecProtocolgsi.hh:102
XrdSecgsiVersDHsigned
#define XrdSecgsiVersDHsigned
Definition XrdSecProtocolgsi.hh:75
kgST_ok
@ kgST_ok
Definition XrdSecProtocolgsi.hh:84
kgST_error
@ kgST_error
Definition XrdSecProtocolgsi.hh:83
kgST_more
@ kgST_more
Definition XrdSecProtocolgsi.hh:85
SafeFree
#define SafeFree(x)
Definition XrdSecProtocolgsi.hh:156
SafeDelArray
#define SafeDelArray(x)
Definition XrdSecProtocolgsi.hh:155
kXGC_sigpxy
@ kXGC_sigpxy
Definition XrdSecProtocolgsi.hh:93
kXGC_cert
@ kXGC_cert
Definition XrdSecProtocolgsi.hh:92
kXGC_certreq
@ kXGC_certreq
Definition XrdSecProtocolgsi.hh:91
kGSErrExportPuK
@ kGSErrExportPuK
Definition XrdSecProtocolgsi.hh:130
kGSErrBadRndmTag
@ kGSErrBadRndmTag
Definition XrdSecProtocolgsi.hh:132
kGSErrParseBuffer
@ kGSErrParseBuffer
Definition XrdSecProtocolgsi.hh:121
kGSErrBadProtocol
@ kGSErrBadProtocol
Definition XrdSecProtocolgsi.hh:124
kGSErrNoPublic
@ kGSErrNoPublic
Definition XrdSecProtocolgsi.hh:142
kGSErrSerialBuffer
@ kGSErrSerialBuffer
Definition XrdSecProtocolgsi.hh:128
kGSErrDecodeBuffer
@ kGSErrDecodeBuffer
Definition XrdSecProtocolgsi.hh:122
kGSErrBadOpt
@ kGSErrBadOpt
Definition XrdSecProtocolgsi.hh:136
kGSErrAddBucket
@ kGSErrAddBucket
Definition XrdSecProtocolgsi.hh:143
kGSErrError
@ kGSErrError
Definition XrdSecProtocolgsi.hh:147
NOTIFY
#define NOTIFY(y)
Definition XrdSecgsiTrace.hh:41
CryptList
XrdOucString CryptList
Definition XrdSecpwdSrvAdmin.cc:187
XrdSutBuckStr
const char * XrdSutBuckStr(int kbck)
Definition XrdSutAux.cc:121
kXRS_user
@ kXRS_user
Definition XrdSutAux.hh:65
kXRS_cipher_alg
@ kXRS_cipher_alg
Definition XrdSutAux.hh:82
kXRS_message
@ kXRS_message
Definition XrdSutAux.hh:68
kXRS_puk
@ kXRS_puk
Definition XrdSutAux.hh:61
kXRS_cipher
@ kXRS_cipher
Definition XrdSutAux.hh:62
kXRS_main
@ kXRS_main
Definition XrdSutAux.hh:58
kXRS_md_alg
@ kXRS_md_alg
Definition XrdSutAux.hh:83
kCE_ok
@ kCE_ok
Definition XrdSutCacheEntry.hh:45
kCE_disabled
@ kCE_disabled
Definition XrdSutCacheEntry.hh:42
XrdOucString::erase
int erase(int start=0, int size=0)
Definition XrdOucString.cc:827
XrdOucString::find
int find(const char c, int start=0, bool forward=1)
Definition XrdOucString.cc:260
XrdOucString::form
int form(const char *fmt,...)
Definition XrdOucString.cc:225
XrdOucString::tokenize
int tokenize(XrdOucString &tok, int from, char del=':')
Definition XrdOucString.cc:1220
XrdSutBucket::ToString
void ToString(XrdOucString &s)
Definition XrdSutBucket.cc:155
XrdSutBuffer::AddBucket
int AddBucket(char *bp=0, int sz=0, int ty=0)
Definition XrdSutBuffer.hh:59
XrdSutBuffer::Serialized
int Serialized(char **buffer, char opt='n')
Definition XrdSutBuffer.cc:438
XrdSutBuffer::GetProtocol
const char * GetProtocol() const
Definition XrdSutBuffer.hh:88
XrdSutBuffer::Dump
void Dump(const char *stepstr=0, bool all=false)
Definition XrdSutBuffer.cc:240
XrdSutBuffer::GetStep
int GetStep() const
Definition XrdSutBuffer.hh:89
XrdSutBuffer::GetBucket
XrdSutBucket * GetBucket(kXR_int32 type, const char *tag=0)
Definition XrdSutBuffer.cc:388
XrdSutBuffer::Deactivate
void Deactivate(kXR_int32 type)
Definition XrdSutBuffer.cc:417
XrdSutCERef::UnLock
void UnLock(bool reset=true)
Definition XrdSutCacheEntry.hh:120
XrdSutCERef::Set
void Set(XrdSysRWLock *lock)
Definition XrdSutCacheEntry.hh:113
XrdSutCacheEntryBuf::len
kXR_int32 len
Definition XrdSutCacheEntry.hh:55
XrdSutCacheEntryBuf::buf
char * buf
Definition XrdSutCacheEntry.hh:54
XrdSutCacheEntry::status
short status
Definition XrdSutCacheEntry.hh:78
XrdSutCacheEntry::rwmtx
XrdSysRWLock rwmtx
Definition XrdSutCacheEntry.hh:85
XrdSutCacheEntry::cnt
short cnt
Definition XrdSutCacheEntry.hh:79
XrdSutCacheEntry::mtime
kXR_int32 mtime
Definition XrdSutCacheEntry.hh:80
XrdSutCacheEntry::buf2
XrdSutCacheEntryBuf buf2
Definition XrdSutCacheEntry.hh:82
XrdSutCacheEntry::buf1
XrdSutCacheEntryBuf buf1
Definition XrdSutCacheEntry.hh:81
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

References XrdSutBuffer::AddBucket(), AuthzFunCheck(), XrdSutCacheEntryBuf::buf, XrdSutCacheEntry::buf1, XrdSutCacheEntry::buf2, XrdSecBuffer::buffer, XrdOucString::c_str(), ClientStepStr(), XrdSutCacheEntry::cnt, CryptList, XrdSutBuffer::Deactivate(), DEBUG, XrdSutBuffer::Dump(), XrdSecProtocol::Entity, EPNAME, XrdOucString::erase(), XrdOucString::find(), XrdOucString::form(), XrdSutBuffer::GetBucket(), XrdSutBuffer::GetProtocol(), XrdSutBuffer::GetStep(), 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(), XrdSutCacheEntry::mtime, NOTIFY, PRINT, QTRACE, REL2, XrdSutCacheEntry::rwmtx, SafeDelArray, SafeDelete, SafeFree, XrdSutBuffer::Serialized(), ServerStepStr(), XrdSutCERef::Set(), XrdSecBuffer::size, XrdSutCacheEntry::status, STR_NPOS, XrdOucString::tokenize(), XrdSutBucket::ToString(), XrdSutCERef::UnLock(), 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

  inbuff | buffer holding data to be decrypted.
  inlen | length of the data.
  outbuff | place 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.

{
// Decrypt data in inbuff and place it in outbuff.
//
// Returns: < 0 Failed,the return value is -errno (see Encrypt).
// = 0 Success, outbuff contains a pointer to the encrypted data.
EPNAME("Decrypt");
// We must have a key
if (!sessionKey)
return -ENOENT;
// And something to decrypt
if (!inbuf || inlen <= 0 || !outbuf)
return -EINVAL;
// Size
int liv = (useIV) ? sessionKey->MaxIVLength() : 0;
int sz = inlen - liv;
// Get output buffer
char *buf = (char *)malloc(sessionKey->DecOutLength(sz) + liv);
if (!buf)
return -ENOMEM;
// Get and set IV
if (useIV) {
char *iv = new char[liv];
memcpy(iv, inbuf, liv);
sessionKey->SetIV(liv, iv);
delete[] iv;
}
// Decrypt
int len = sessionKey->Decrypt(inbuf + liv, sz, buf);
if (len <= 0) {
SafeFree(buf);
return -EINVAL;
}
// Create and fill output buffer
*outbuf = new XrdSecBuffer(buf, len);
// We are done
DEBUG("decrypted buffer has "<<len<<" bytes");
return 0;
}

References DEBUG, EPNAME, and SafeFree.

## 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.

{
// Deletes the protocol
SafeFree(Entity.name);
SafeFree(Entity.host);
SafeFree(Entity.vorg);
SafeFree(Entity.role);
SafeFree(Entity.grps);
SafeFree(Entity.caps);
SafeFree(Entity.endorsements);
if (Entity.creds && Entity.credslen > 0) {
SafeFree(Entity.creds);
} else {
Entity.creds = 0;
}
Entity.credslen = 0;
SafeFree(Entity.moninfo);
// Cleanup the handshake variables, if still there
SafeDelete(hs);
// Cleanup any other instance specific to this protocol
SafeDelete(sessionKey); // Session Key (result of the handshake)
SafeDelete(bucketKey); // Bucket with the key in export form
SafeDelete(sessionMD); // Message Digest instance
SafeDelete(sessionKsig); // RSA key to sign
SafeDelete(sessionKver); // RSA key to verify
if (proxyChain) proxyChain->Cleanup();
SafeDelete(proxyChain); // Chain with delegated proxies
SafeFree(expectedHost);
delete this;
}

References XrdSecProtocol::Entity, SafeDelete, and SafeFree.

## EnableTracing()

XrdOucTrace * XrdSecProtocolgsi::EnableTracing | ( |  | ) |

static

Definition at line 2276 of file XrdSecProtocolgsi.cc.

{
// Initiate error logging and tracing
eDest.logger(&Logger);
GSITrace = new XrdOucTrace(&eDest);
return GSITrace;
}

Referenced by XrdSecProtocolgsiInit().

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

  inbuff | buffer holding data to be encrypted.
  inlen | length of the data.
  outbuff | place 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.

{
// Encrypt data in inbuff and place it in outbuff.
//
// Returns: < 0 Failed, the return value is -errno of the reason. Typically,
// -EINVAL - one or more arguments are invalid.
// -ENOTSUP - encryption not supported by the protocol
// -EOVERFLOW - outbuff is too small to hold result
// -ENOENT - Context not initialized
// = 0 Success, outbuff contains a pointer to the encrypted data.
//
EPNAME("Encrypt");
// We must have a key
if (!sessionKey)
return -ENOENT;
// And something to encrypt
if (!inbuf || inlen <= 0 || !outbuf)
return -EINVAL;
// Regenerate IV
int liv = 0;
char *iv = 0;
if (useIV) {
iv = sessionKey->RefreshIV(liv); // no need to call sessionKeySetIV as
// RefreshIV will set the internal value
}
// Get output buffer
char *buf = (char *)malloc(sessionKey->EncOutLength(inlen) + liv);
if (!buf)
return -ENOMEM;
// IV at beginning
memcpy(buf, iv, liv);
// Encrypt
int len = sessionKey->Encrypt(inbuf, inlen, buf + liv) + liv; // the size of initialization vector which is being appended at
// the beginning of the output buffer has to be taken into account
if (len <= 0) {
SafeFree(buf);
return -EINVAL;
}
// Create and fill output buffer
*outbuf = new XrdSecBuffer(buf, len);
// We are done
DEBUG("encrypted buffer has "<<len<<" bytes");
return 0;
}

References DEBUG, EPNAME, and SafeFree.

## getCredentials()

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

virtual

Generate client credentials to be used in the authentication process.

Parameters

  parm | Pointer to the information returned by the server either in the initial login response or the authmore response.
  einfo | The 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.

{
// Query client for the password; remote username and host
// are specified in 'parm'. File '.rootnetrc' is checked.
EPNAME("getCredentials");
// If we are a server the only reason to be here is to get the forwarded
// or saved client credentials
if (srvMode) {
XrdSecCredentials *creds = 0;
if (proxyChain) {
// Export the proxy chain into a bucket
XrdCryptoX509ExportChain_t ExportChain = sessionCF->X509ExportChain();
if (ExportChain) {
XrdSutBucket *bck = (*ExportChain)(proxyChain, 1);
if (bck) {
// We need to duplicate it because XrdSecCredentials uses
// {malloc, free} instead of {new, delete}
char *nbuf = (char *) malloc(bck->size);
if (nbuf) {
memcpy(nbuf, bck->buffer, bck->size);
// Import the buffer in a XrdSecCredentials object
creds = new XrdSecCredentials(nbuf, bck->size);
}
delete bck;
}
}
}
return creds;
}
// Handshake vars container must be initialized at this point
if (!hs)
return ErrC(ei,0,0,0,kGSErrError,
"handshake var container missing","getCredentials");
//
// Nothing to do if buffer is empty
if ((!parm && !hs->Parms) || (parm && (!(parm->buffer) || parm->size <= 0))) {
if (hs->Iter == 0)
return ErrC(ei,0,0,0,kGSErrNoBuffer,"missing parameters","getCredentials");
else
return (XrdSecCredentials *)0;
}
// We support passing the user {proxy, cert, key} paths via Url parameter
char *upp = (ei && ei->getEnv()) ? ei->getEnv()->Get("xrd.gsiusrpxy") : 0;
if (upp) urlUsrProxy = upp;
upp = (ei && ei->getEnv()) ? ei->getEnv()->Get("xrd.gsiusrcrt") : 0;
if (upp) urlUsrCert = upp;
upp = (ei && ei->getEnv()) ? ei->getEnv()->Get("xrd.gsiusrkey") : 0;
if (upp) urlUsrKey = upp;
// Count interations
(hs->Iter)++;
// Update time stamp
hs->TimeStamp = time(0);
// Local vars
int step = 0;
int nextstep = 0;
const char *stepstr = 0;
char *bpub = 0;
int lpub = 0;
String CryptoMod = "";
String Host = "";
String RemID = "";
String Emsg;
String specID = "";
String issuerHash = "";
// Buffer / Bucket related
XrdSutBuffer *bpar = 0; // Global buffer
XrdSutBuffer *bmai = 0; // Main buffer
XrdSutBucket *bck = 0; // Generic bucket
//
// Decode received buffer
bpar = hs->Parms;
if (!bpar && !(bpar = new XrdSutBuffer((const char *)parm->buffer,parm->size)))
return ErrC(ei,0,0,0,kGSErrDecodeBuffer,"global",stepstr);
// Ownership has been transferred
hs->Parms = 0;
//
// Check protocol ID name
if (strcmp(bpar->GetProtocol(),XrdSecPROTOIDENT))
return ErrC(ei,bpar,bmai,0,kGSErrBadProtocol,stepstr);
//
// The step indicates what we are supposed to do
if (!(step = bpar->GetStep())) {
// The first, fake, step
step = kXGS_init;
bpar->SetStep(step);
}
stepstr = ServerStepStr(step);
// Dump, if requested
XrdOucString bmsg;
if (QTRACE(Dump)) {
bmsg.form("IN: bpar: %s", stepstr);
bpar->Dump(bmsg.c_str());
}
//
// Parse input buffer
if (ParseClientInput(bpar, &bmai, Emsg) == -1) {
DEBUG(Emsg<<" CF: "<<sessionCF);
return ErrC(ei,bpar,bmai,0,kGSErrParseBuffer,Emsg.c_str(),stepstr);
}
// Dump, if requested
if (QTRACE(Dump)) {
if (bmai) {
bmsg.form("IN: bmai: %s", stepstr);
bmai->Dump(bmsg.c_str());
}
}
//
// Version
DEBUG("version run by server: "<< hs->RemVers);
//
// Check random challenge
if (!CheckRtag(bmai, Emsg))
return ErrC(ei,bpar,bmai,0,kGSErrBadRndmTag,Emsg.c_str(),stepstr);
//
// Login name if any
String user(Entity.name);
if (user.length() <= 0) user = getenv("XrdSecUSER");
//
// Now action depens on the step
nextstep = kXGC_none;
XrdCryptoX509 *c = 0;
switch (step) {
case kXGS_init:
//
// Add bucket with cryptomod to the global list
// (This must be always visible from now on)
CryptoMod = hs->CryptoMod;
if (hs->RemVers >= XrdSecgsiVersDHsigned && !(hs->HasPad)) CryptoMod += gNoPadTag;
if (bpar->AddBucket(CryptoMod,kXRS_cryptomod) != 0)
return ErrC(ei,bpar,bmai,0,
kGSErrCreateBucket,XrdSutBuckStr(kXRS_cryptomod),stepstr);
//
// Add bucket with our version to the main list
if (bpar->MarshalBucket(kXRS_version,(kXR_int32)(Version)) != 0)
return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
XrdSutBuckStr(kXRS_version),"global",stepstr);
//
// Add our issuer hash
c = hs->PxyChain->Begin();
if (c->type == XrdCryptoX509::kCA) {
issuerHash = c->SubjectHash();
if (HashCompatibility && c->SubjectHash(1)) {
issuerHash += "|"; issuerHash += c->SubjectHash(1); }
} else {
issuerHash = c->IssuerHash();
if (HashCompatibility && c->IssuerHash(1)
&& strcmp(c->IssuerHash(1),c->IssuerHash())) {
issuerHash += "|"; issuerHash += c->IssuerHash(1); }
}
while ((c = hs->PxyChain->Next()) != 0) {
if (c->type != XrdCryptoX509::kCA)
break;
issuerHash = c->SubjectHash();
if (HashCompatibility && c->SubjectHash(1)
&& strcmp(c->IssuerHash(1),c->IssuerHash())) {
issuerHash += "|"; issuerHash += c->SubjectHash(1); }
}
DEBUG("Client issuer hash: " << issuerHash);
if (bpar->AddBucket(issuerHash,kXRS_issuer_hash) != 0)
return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
XrdSutBuckStr(kXRS_issuer_hash),stepstr);
//
// Add bucket with our delegate proxy options
if (hs->RemVers >= 10100) {
if (bpar->MarshalBucket(kXRS_clnt_opts,(kXR_int32)(hs->Options)) != 0)
return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
XrdSutBuckStr(kXRS_clnt_opts),"global",stepstr);
}
//
nextstep = kXGC_certreq;
break;
case kXGS_cert:
//
// We must have a session cipher at this point
if (!(sessionKey))
return ErrC(ei,bpar,bmai,0,
kGSErrNoCipher,"session cipher",stepstr);
//
// Extract buffer with public info for the cipher agreement
if (!(bpub = sessionKey->Public(lpub)))
return ErrC(ei,bpar,bmai,0,
kGSErrNoPublic,"session",stepstr);
//
// If server supports decoding of signed DH, do sign them
if (hs->RemVers >= XrdSecgsiVersDHsigned) {
bck = new XrdSutBucket(bpub,lpub,kXRS_cipher);
if (sessionKsig) {
// Encrypt client DH public parameters with client private key
if (sessionKsig->EncryptPrivate(*bck) <= 0)
return ErrC(ei,bpar,bmai,0, kGSErrExportPuK,
"encrypting client DH public parameters",stepstr);
} else {
return ErrC(ei,bpar,bmai,0, kGSErrExportPuK,
"client signing key undefined!",stepstr);
}
//
// Add it to the global list
if (bpar->AddBucket(bck) != 0)
return ErrC(ei,bpar,bmai,0, kGSErrAddBucket, "main",stepstr);
//
// Export client public key
XrdOucString cpub;
if (sessionKsig->ExportPublic(cpub) < 0)
return ErrC(ei,bpar,bmai,0, kGSErrExportPuK,
"exporting client public key",stepstr);
// Add it to the global list
if (bpar->UpdateBucket(cpub.c_str(),cpub.length(),kXRS_puk) != 0)
return ErrC(ei,bpar,bmai,0, kGSErrAddBucket,
XrdSutBuckStr(kXRS_puk),"global",stepstr);
} else {
//
// Add it to the global list
if (bpar->UpdateBucket(bpub,lpub,kXRS_puk) != 0)
return ErrC(ei,bpar,bmai,0, kGSErrAddBucket,
XrdSutBuckStr(kXRS_puk),"global",stepstr);
delete[] bpub; // bpub is being duplicated inside of 'UpdateBucket'
}
//
// Add the proxy certificate
bmai->AddBucket(hs->Cbck);
//
// Add login name if any, needed while chosing where to export the proxies
if (user.length() > 0) {
if (bmai->AddBucket(user, kXRS_user) != 0)
return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
XrdSutBuckStr(kXRS_user),stepstr);
}
//
nextstep = kXGC_cert;
break;
case kXGS_pxyreq:
//
// If something went wrong, send explanation
if (Emsg.length() > 0) {
if (bmai->AddBucket(Emsg,kXRS_message) != 0)
return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
XrdSutBuckStr(kXRS_message),stepstr);
}
//
// Add login name if any, needed while chosing where to export the proxies
if (user.length() > 0) {
if (bmai->AddBucket(user, kXRS_user) != 0)
return ErrC(ei,bpar,bmai,0, kGSErrCreateBucket,
XrdSutBuckStr(kXRS_user),stepstr);
}
//
// The relevant buckets should already be in the buffers
nextstep = kXGC_sigpxy;
break;
default:
return ErrC(ei,bpar,bmai,0, kGSErrBadOpt,stepstr);
}
//
// Serialize and encrypt
if (AddSerialized('c', nextstep, hs->ID,
bpar, bmai, kXRS_main, sessionKey) != 0) {
return ErrC(ei,bpar,bmai,0,
kGSErrSerialBuffer,"main",stepstr);
}
//
// Serialize the global buffer
char *bser = 0;
int nser = bpar->Serialized(&bser,'f');
if (QTRACE(Authen)) {
bmsg.form("OUT: bpar: %s", ClientStepStr(bpar->GetStep()));
bpar->Dump(bmsg.c_str());
bmsg.form("OUT: bmai: %s", ClientStepStr(bpar->GetStep()));
bmai->Dump(bmsg.c_str());
}
//
// We may release the buffers now
REL2(bpar,bmai);
//
// Return serialized buffer
if (nser > 0) {
DEBUG("returned " << nser <<" bytes of credentials");
return new XrdSecCredentials(bser, nser);
} else {
NOTIFY("problems with final serialization");
return (XrdSecCredentials *)0;
}
}
kXR_int32
int kXR_int32
Definition XPtypes.hh:89
XrdSecCredentials
XrdSecBuffer XrdSecCredentials
Definition XrdSecInterface.hh:69
gNoPadTag
static const char * gNoPadTag
Definition XrdSecProtocolgsi.cc:132
kXGS_init
@ kXGS_init
Definition XrdSecProtocolgsi.hh:100
kXGC_none
@ kXGC_none
Definition XrdSecProtocolgsi.hh:90
kGSErrNoCipher
@ kGSErrNoCipher
Definition XrdSecProtocolgsi.hh:134
kGSErrCreateBucket
@ kGSErrCreateBucket
Definition XrdSecProtocolgsi.hh:125
kGSErrNoBuffer
@ kGSErrNoBuffer
Definition XrdSecProtocolgsi.hh:140
CryptoMod
XrdOucString CryptoMod
Definition XrdSecgsiProxy.cc:99
kXRS_issuer_hash
@ kXRS_issuer_hash
Definition XrdSutAux.hh:80
kXRS_version
@ kXRS_version
Definition XrdSutAux.hh:71
kXRS_cryptomod
@ kXRS_cryptomod
Definition XrdSutAux.hh:57
kXRS_clnt_opts
@ kXRS_clnt_opts
Definition XrdSutAux.hh:76
XrdCryptoX509::kCA
@ kCA
Definition XrdCryptoX509.hh:55
XrdCryptoX509::SubjectHash
virtual const char * SubjectHash(int)
Definition XrdCryptoX509.cc:165
XrdCryptoX509::IssuerHash
virtual const char * IssuerHash(int)
Definition XrdCryptoX509.cc:173
XrdCryptoX509::type
EX509Type type
Definition XrdCryptoX509.hh:56
XrdSutBucket::size
kXR_int32 size
Definition XrdSutBucket.hh:47
XrdSutBucket::buffer
char * buffer
Definition XrdSutBucket.hh:48
XrdSutBuffer::UpdateBucket
int UpdateBucket(const char *bp, int sz, int ty)
Definition XrdSutBuffer.cc:208
XrdSutBuffer::SetStep
void SetStep(int s)
Definition XrdSutBuffer.hh:90
XrdSutBuffer::MarshalBucket
kXR_int32 MarshalBucket(kXR_int32 type, kXR_int32 code)
Definition XrdSutBuffer.cc:318

References XrdSutBuffer::AddBucket(), XrdSecBuffer::buffer, XrdSutBucket::buffer, XrdOucString::c_str(), ClientStepStr(), CryptoMod, DEBUG, XrdSutBuffer::Dump(), XrdSecProtocol::Entity, EPNAME, XrdOucString::form(), XrdOucEnv::Get(), XrdOucErrInfo::getEnv(), XrdSutBuffer::GetProtocol(), XrdSutBuffer::GetStep(), gNoPadTag, XrdCryptoX509::IssuerHash(), 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(), NOTIFY, QTRACE, REL2, XrdSutBuffer::Serialized(), ServerStepStr(), XrdSutBuffer::SetStep(), XrdSecBuffer::size, XrdSutBucket::size, XrdCryptoX509::SubjectHash(), XrdCryptoX509::type, XrdSutBuffer::UpdateBucket(), Version, 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

  buff | buffer to hold the key, and may be null.
  size | size 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.

{
// Get the current encryption key
//
// 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 0, only the
// size of the key is returned.
//
EPNAME("getKey");
// Check if we have to serialize the key
if (!bucketKey) {
// We must have a key for that
if (!sessionKey)
// Invalid call
return -ENOENT;
// Create bucket
bucketKey = sessionKey->AsBucket();
}
// Prepare output now, if we have any
if (bucketKey) {
// If are asked only the size, we are done
if (kbuf == 0)
return bucketKey->size;
// Check the size of the buffer
if (klen < bucketKey->size)
// Too small
return -EOVERFLOW;
// Copy the buffer
memcpy(kbuf, bucketKey->buffer, bucketKey->size);
// We are done
DEBUG("session key exported");
return bucketKey->size;
}
// Key exists but we could export it in bucket format
return -ENOMEM;
}

References DEBUG, and EPNAME.

## Init()

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

static

Definition at line 406 of file XrdSecProtocolgsi.cc.

{
// Static method to the configure the static part of the protocol
// Called once by XrdSecProtocolgsiInit
EPNAME("Init");
char *Failure = 0, *Parms = 0;
//
// Debug an tracing
Debug = (opt.debug > -1) ? opt.debug : Debug;
// We must have the tracing object at this point
// (initialized in XrdSecProtocolgsiInit)
if (!gsiTrace) {
ErrF(erp,kGSErrInit,"tracing object (gsiTrace) not initialized! cannot continue");
return Failure;
}
// Set debug mask ... also for auxilliary libs
int trace = 0, traceSut = 0, traceCrypto = 0;
if (Debug >= 3) {
trace = cryptoTRACE_Dump;
traceSut = sutTRACE_Dump;
traceCrypto = cryptoTRACE_Dump;
GSITrace->What = TRACE_ALL;
} else if (Debug >= 2) {
trace = cryptoTRACE_Debug;
traceSut = sutTRACE_Debug;
traceCrypto = cryptoTRACE_Debug;
GSITrace->What = TRACE_Debug;
GSITrace->What |= TRACE_Authen;
} else if (Debug >= 1) {
trace = cryptoTRACE_Debug;
traceSut = sutTRACE_Notify;
traceCrypto = cryptoTRACE_Notify;
GSITrace->What = TRACE_Debug;
}
// ... also for auxilliary libs
XrdSutSetTrace(traceSut);
XrdCryptoSetTrace(traceCrypto);
// Name hashing algorithm compatibility
if (opt.hashcomp == 0) HashCompatibility = 0;
//
// Operation mode
Server = (opt.mode == 's');
//
// CA verification level
//
// 0 do not verify
// 1 verify if self-signed; warn if not
// 2 verify in all cases; fail if not possible
//
if (opt.ca >= caNoVerify && opt.ca <= caVerify)
CACheck = opt.ca;
DEBUG("option CACheck: "<<getOptName(caVerOpts,CACheck));
//
// Check existence of CA directory
struct stat st;
if (opt.certdir) {
DEBUG("testing CA dir(s): "<<opt.certdir);
String CAtmp;
String tmp = opt.certdir;
String dp;
int from = 0;
while ((from = tmp.tokenize(dp, from, ',')) != -1) {
if (dp.length() > 0) {
if (XrdSutExpand(dp) == 0) {
if (stat(dp.c_str(),&st) == -1) {
if (errno == ENOENT) {
ErrF(erp,kGSErrError,"CA directory non existing",dp.c_str());
PRINT(erp->getErrText());
} else {
ErrF(erp,kGSErrError,"cannot stat CA directory",dp.c_str());
PRINT(erp->getErrText());
}
} else {
if (!(dp.endswith('/'))) dp += '/';
if (!(CAtmp.endswith(','))) CAtmp += ',';
CAtmp += dp;
}
} else {
PRINT("Warning: could not expand: "<<dp);
}
}
}
if (CAtmp.length() > 0)
CAdir = CAtmp;
}
DEBUG("using CA dir(s): "<<CAdir);
//
// CRL check level
//
// 0 do not care
// 1 use if available
// 2 require
// 3 require not expired
// 12 require; try download if missing
// 13 require not expired; try download if missing
//
const char *cocrl[] = { "do-not-care", "use-if-available", "require", "require-not-expired" };
const char *codwld[] = { "no", "yes"};
if (opt.crl >= crlUpdate) {
CRLDownload = 1;
opt.crl %= 10;
}
if (opt.crl >= crlIgnore && opt.crl <= crlRequire)
CRLCheck = opt.crl;
DEBUG("option CRLCheck: "<<CRLCheck<<" ('"<<cocrl[CRLCheck]<<"'; download? "<<
codwld[CRLDownload]<<")");
//
// Check existence of CRL directory
if (opt.crldir) {
DEBUG("testing CRL dir(s): "<<opt.crldir);
String CRLtmp;
String tmp = opt.crldir;
String dp;
int from = 0;
while ((from = tmp.tokenize(dp, from, ',')) != -1) {
if (dp.length() > 0) {
if (XrdSutExpand(dp) == 0) {
if (stat(dp.c_str(),&st) == -1) {
if (errno == ENOENT) {
ErrF(erp,kGSErrError,"CRL directory non existing:",dp.c_str());
PRINT(erp->getErrText());
} else {
ErrF(erp,kGSErrError,"cannot stat CRL directory:",dp.c_str());
PRINT(erp->getErrText());
}
} else {
if (!(dp.endswith('/'))) dp += '/';
if (!(CRLtmp.endswith(','))) CRLtmp += ',';
CRLtmp += dp;
}
} else {
PRINT("Warning: could not expand: "<<dp);
}
}
}
if (CRLtmp.length() > 0)
CRLdir = CRLtmp;
} else {
// Use CAdir
CRLdir = CAdir;
}
if (CRLCheck > 0)
DEBUG("using CRL dir(s): "<<CRLdir);
//
// Default extension for CRL files
if (opt.crlext)
DefCRLext = opt.crlext;
//
// Refresh or expiration time for CRLs
if (opt.crlrefresh)
CRLRefresh = opt.crlrefresh;
DEBUG("CRL information refreshed every "<<CRLRefresh<<" secs");
//
// Honour trust / unstrust DNS settings (switch or env)
TrustDNS = opt.trustdns;
DEBUG("trust DNS option: "<<TrustDNS);
//
// Enable/disable displaying the DN
ShowDN = opt.showDN;
DEBUG("show DN option: "<<ShowDN);
//
// Server specific options
if (Server) {
//
// List of supported / wanted crypto modules
if (opt.clist)
DefCrypto = opt.clist;
//
// List of crypto modules
String cryptlist;
String crypts(DefCrypto,0,-1,64);
//
// Load crypto modules
XrdSutPFEntry ent;
XrdCryptoFactory *cf = 0;
if (crypts.length()) {
String ncpt = "";
int from = 0;
while ((from = crypts.tokenize(ncpt, from, '|')) != -1) {
if (ncpt.length() > 0 && ncpt[0] != '-') {
// Try loading
if ((cf = XrdCryptoFactory::GetCryptoFactory(ncpt.c_str()))) {
// Add it to the list
cryptF[ncrypt] = cf;
cryptID[ncrypt] = cf->ID();
cryptName[ncrypt].insert(cf->Name(),0,strlen(cf->Name())+1);
cf->SetTrace(trace);
cf->Notify();
// Ref cipher
if (!(refcip[ncrypt] = cf->Cipher(0,0,0))) {
PRINT("ref cipher for module "<<ncpt<<
" cannot be instantiated : disable");
from -= ncpt.length();
} else {
ncrypt++;
if (ncrypt >= XrdCryptoMax) {
PRINT("max number of crypto modules ("
<< XrdCryptoMax <<") reached ");
break;
}
if (cryptlist.length()) cryptlist += ":";
cryptlist += ncpt;
if (!cf->HasPaddingSupport()) cryptlist += gNoPadTag;
}
} else {
PRINT("cannot instantiate crypto factory "<<ncpt<<
": disable");
from -= ncpt.length();
}
}
}
}
//
// We need at least one valid crypto module
if (ncrypt <= 0) {
ErrF(erp,kGSErrInit,"could not find any valid crypto module");
PRINT(erp->getErrText());
return Failure;
}
//
// List of supported / wanted ciphers
if (opt.cipher)
DefCipher = opt.cipher;
// make sure we support all of them
String cip = "";
int from = 0;
while ((from = DefCipher.tokenize(cip, from, ':')) != -1) {
if (cip.length() > 0) {
int i = 0;
for (; i < ncrypt; i++) {
if (!(cryptF[i]->SupportedCipher(cip.c_str()))) {
// Not supported: drop from the list
DEBUG("cipher type not supported ("<<cip<<") - disabling");
from -= cip.length();
DefCipher.erase(cip);
}
}
}
}
//
// List of supported / wanted Message Digest
if (opt.md)
DefMD = opt.md;
// make sure we support all of them
String md = "";
from = 0;
while ((from = DefMD.tokenize(md, from, ':')) != -1) {
if (md.length() > 0) {
int i = 0;
for (; i < ncrypt; i++) {
if (!(cryptF[i]->SupportedMsgDigest(md.c_str()))) {
// Not supported: drop from the list
PRINT("MD type not supported ("<<md<<") - disabling");
from -= md.length();
DefMD.erase(md);
}
}
}
}
//
// Load server certificate and key
if (opt.cert) {
String TmpCert = opt.cert;
if (XrdSutExpand(TmpCert) == 0) {
SrvCert = TmpCert;
} else {
PRINT("Could not expand: "<<opt.cert<<": use default");
}
}
if (opt.key) {
String TmpKey = opt.key;
if (XrdSutExpand(TmpKey) == 0) {
SrvKey = TmpKey;
} else {
PRINT("Could not expand: "<<opt.key<<": use default");
}
}
//
// Check if we can read the certificate key
if (access(SrvKey.c_str(), R_OK)) {
PRINT("WARNING: process has no permission to read the certificate key file: "<<SrvKey);
}
int i = 0;
String certcalist = ""; // list of CA for server certificates
XrdSutCERef ceref;
for (; i<ncrypt; i++) {
if (!GetSrvCertEnt(ceref, cryptF[i], time(0), certcalist)) {
PRINT("problems loading srv cert");
ceref.UnLock();
continue;
}
}
// Rehash cache
ceref.UnLock();
//
// We must have got at least one valid certificate
if (cacheCert.Num() <= 0) {
ErrF(erp,kGSErrError,"no valid server certificate found");
PRINT(erp->getErrText());
return Failure;
}
DEBUG("CA list: "<<certcalist);
//
// GRID map check option
//
// 0 do not use (DN hash will be used as identifier)
// 1 use if available; otherwise as 0
// 2 require
// 10 do not use (DN name will be used as identifier)
// 11 use if available; otherwise as 10
const char *cogmap[] = { "do-not-use", "use-if-available", "require" };
const char *codnnm[] = { "DN hash", "DN name"};
if (opt.ogmap >= 10) {
GMAPuseDNname = 1;
opt.ogmap %= 10;
}
if (opt.ogmap >= 0 && opt.ogmap <= 2)
GMAPOpt = opt.ogmap;
DEBUG("user mapping file option: "<<cogmap[GMAPOpt]);
if (GMAPOpt < 2)
DEBUG("default option for entity name if no mapping available: "<<codnnm[(int)GMAPuseDNname]);
//
// Check existence of GRID map file
if (opt.gridmap) {
String GMAPTmp = opt.gridmap;
if (XrdSutExpand(GMAPTmp) == 0) {
GMAPFile = GMAPTmp;
} else {
PRINT("Could not expand: "<<opt.gridmap<<": use default");
}
}
bool hasgmap = 0;
if (GMAPOpt > 0) {
// Initialize the GMap service
//
String pars;
if (Debug) pars += "dbg|";
if (opt.gmapto > 0) { pars += "to="; pars += (int)opt.gmapto; }
if (!(servGMap = XrdOucgetGMap(&eDest, GMAPFile.c_str(), pars.c_str()))) {
if (GMAPOpt > 1) {
ErrF(erp,kGSErrError,"error loading grid map file",GMAPFile.c_str());
PRINT(erp->getErrText());
return Failure;
} else {
NOTIFY("Grid map file: "<<GMAPFile<<" cannot be 'access'ed: do not use");
}
} else {
DEBUG("using grid map file: "<<GMAPFile);
hasgmap = 1;
}
}
//
// Load function be used to map DN to usernames, if specified
bool hasgmapfun = 0;
if (opt.gmapfun && GMAPOpt > 0) {
if (!(GMAPFun = LoadGMAPFun((const char *) opt.gmapfun,
(const char *) opt.gmapfunparms))) {
ErrF(erp, kGSErrError, "GMAP plug-in could not be loaded", opt.gmapfun);
PRINT(erp->getErrText());
return Failure;
} else {
hasgmapfun = 1;
}
}
//
// Disable GMAP if neither a grid mapfile nor a GMAP function are available
if (!hasgmap && !hasgmapfun) {
if (GMAPOpt > 1) {
ErrF(erp,kGSErrError,"User mapping required, but neither a grid mapfile"
" nor a mapping function are available");
PRINT(erp->getErrText());
return Failure;
}
GMAPOpt = 0;
}
//
// Authentication function
bool hasauthzfun = 0;
AuthzAlways = opt.authzcall;
if (opt.authzfun) {
if (!(AuthzFun = LoadAuthzFun((const char *) opt.authzfun,
(const char *) opt.authzfunparms, AuthzCertFmt))) {
ErrF(erp, kGSErrError, "Authz plug-in could not be loaded", opt.authzfun);
PRINT(erp->getErrText());
return Failure;
} else {
hasauthzfun = 1;
// Notify certificate format
if (AuthzCertFmt >= 0 && AuthzCertFmt <= 1) {
const char *ccfmt[] = { "raw", "PEM base64" };
DEBUG("authzfun: proxy certificate format: "<<ccfmt[AuthzCertFmt]);
} else {
NOTIFY("authzfun: proxy certificate format: unknown (code: "<<AuthzCertFmt<<")");
}
// Expiration of Authz related cache entries
if (opt.authzto > 0) {
AuthzCacheTimeOut = opt.authzto;
DEBUG("grid-map cache entries expire after "<<AuthzCacheTimeOut<<" secs");
}
}
}
//
// Expiration of GRIDMAP related cache entries
if (GMAPOpt > 0 && !hasauthzfun && opt.gmapto > 0) {
GMAPCacheTimeOut = opt.gmapto;
DEBUG("grid-map cache entries expire after "<<GMAPCacheTimeOut<<" secs");
}
//
// Request for proxy export for authorization
// authzpxy = opt_what*10 + opt_where
// opt_what = 0 full chain
// 1 last proxy only
// opt_where = 1 Entity.creds
// 2 Entity.endorsements
if (opt.authzpxy) {
AuthzPxyWhat = opt.authzpxy / 10;
AuthzPxyWhere = opt.authzpxy % 10;
// Some notification
const char *capxy_what = (AuthzPxyWhat == 1) ? "'last proxy only'"
: "'full proxy chain'";
const char *capxy_where = (AuthzPxyWhere == 1) ? "XrdSecEntity.creds"
: "XrdSecEntity.endorsements";
DEBUG("Export proxy for authorization in '"<<capxy_where<<"': "<<capxy_what);
if (hasauthzfun) {
// Warn user about possible overwriting of Entity.creds or Entity.endorsements
PRINT("WARNING: proxy export for authz enabled: be aware that any setting of '"<<capxy_what<<
"' done by '"<<opt.authzfun<<"' will get overwritten with "<<capxy_what);
}
}
//
// Handle delegated proxies options
if (opt.dlgpxy == -1) {
// Will not accept any delegated proxies
DEBUG("Will not accept delegated proxies");
} else {
// Ask the client to sign a delegated proxy; client may decide to forward its proxy
if (opt.dlgpxy == dlgReqSign)
PxyReqOpts |= kOptsSrvReq;
// Exporting options (default none: delegated proxy kept in memory, in proxyChain)
if (opt.exppxy) {
if (!strcmp(opt.exppxy, "=creds")) {
// register the delegated proxy in Entity.creds (in HEX format)
PxyReqOpts |= kOptsPxCred;
DEBUG("Delegated proxy saved in Entity.creds ");
} else {
String TmpProxy = gUsrPxyDef;
if (strcmp(opt.exppxy, "=default"))
TmpProxy = opt.exppxy;
if (XrdSutExpand(TmpProxy) == 0) {
UsrProxy = TmpProxy;
} else {
UsrProxy = gUsrPxyDef;
UsrProxy += "u<uid>";
}
PxyReqOpts |= kOptsPxFile;
DEBUG("File template for delegated proxy: "<<UsrProxy);
}
}
DEBUG("Delegated proxies options: "<<PxyReqOpts);
}
//
// VOMS attributes switch
// vomsat = 0 do not look for
// 1 extract if any (fill 'vorg', 'role'; the full string in 'endorsements');
// 2 require (fill 'vorg', 'role'; the full string in 'endorsements');
VOMSAttrOpt = (opt.vomsat <= vatRequire && opt.vomsat >= vatIgnore)
? opt.vomsat : VOMSAttrOpt;
//
// Alternative VOMS extraction function
if (opt.vomsfun) {
if (!(VOMSFun = LoadVOMSFun((const char *) opt.vomsfun,
(const char *) opt.vomsfunparms, VOMSCertFmt))) {
ErrF(erp, kGSErrError, "VOMS plug-in loading failed", opt.vomsfun);
PRINT(erp->getErrText());
return Failure;
} else {
// Notify certificate format
if (VOMSCertFmt >= 0 && VOMSCertFmt <= 1) {
const char *ccfmt[] = { "raw", "PEM base64" };
DEBUG("vomsfun: proxy certificate format: "<<ccfmt[VOMSCertFmt]);
} else {
char fbuff[64];
snprintf(fbuff, sizeof(fbuff), "%d", VOMSCertFmt);
ErrF(erp, kGSErrError, "VOMS plug-in returned invalid cert "
"format", fbuff);
PRINT(erp->getErrText());
return Failure;
}
}
} else opt.authzcall = AuthzAlways = 1;
DEBUG("VOMS attributes options: "<<getOptName(vomsatOpts, VOMSAttrOpt));
//
// Default moninfo option
// 0 nothing
// 1 DN
MonInfoOpt = opt.moninfo;
const char *cmoninfo = (MonInfoOpt == 1) ? "DN" : "none";
DEBUG("Monitor information options: "<<cmoninfo);
// Make sure we have a calist as the client can't do anything without it.
// If the cryptlist is empty the client will use the default one.
//
if (certcalist.length() == 0)
{ErrF(erp,kGSErrInit,"unable to generate ca cert hash list!");
PRINT(erp->getErrText());
return Failure;
}
//
// Parms in the form:
// &P=gsi,v:<version>,c:<cryptomod>,ca:<list_of_srv_cert_ca>
Parms = new char[cryptlist.length()+3+12+certcalist.length()+5];
if (Parms) {
sprintf(Parms,"v:%d,c:%s,ca:%s",
Version,cryptlist.c_str(),certcalist.c_str());
} else {
ErrF(erp,kGSErrInit,"no system resources for 'Parms'");
PRINT(erp->getErrText());
return Failure;
}
// Some notification
DEBUG("available crypto modules: "<<cryptlist);
DEBUG("issuer CAs of server certs (hashes): "<<certcalist);
}
//
// Client specific options
if (!Server) {
// use default dir $(HOME)/.<prefix>
struct passwd *pw = getpwuid(getuid());
if (!pw) {
NOTIFY("WARNING: cannot get user information (uid:"<<getuid()<<")");
}
//
// Define user proxy file
UsrProxy = gUsrPxyDef;
if (opt.proxy) {
String TmpProxy = opt.proxy;
if (XrdSutExpand(TmpProxy) == 0) {
UsrProxy = TmpProxy;
} else {
PRINT("Could not expand: "<<opt.proxy<<": use default");
}
} else {
if (pw)
UsrProxy += (int)(pw->pw_uid);
}
// Define user certificate file
if (opt.cert) {
String TmpCert = opt.cert;
if (XrdSutExpand(TmpCert) == 0) {
UsrCert = TmpCert;
} else {
PRINT("Could not expand: "<<opt.cert<<": use default");
}
} else {
if (pw)
UsrCert.insert(XrdSutHome(),0);
}
// Define user private key file
if (opt.key) {
String TmpKey = opt.key;
if (XrdSutExpand(TmpKey) == 0) {
UsrKey = TmpKey;
} else {
PRINT("Could not expand: "<<opt.key<<": use default");
}
} else {
if (pw)
UsrKey.insert(XrdSutHome(),0);
}
// Define proxy validity at renewal
if (opt.valid)
PxyValid = opt.valid;
// Set depth of signature path
if (opt.deplen != DepLength)
DepLength = opt.deplen;
// Set number of bits for proxy key
if (opt.bits > DefBits)
DefBits = opt.bits;
//
// Delegate proxy options
if (opt.dlgpxy > dlgIgnore) {
PxyReqOpts |= kOptsSigReq;
if (opt.dlgpxy == dlgSendpxy) {
PxyReqOpts |= kOptsFwdPxy;
} else {
PxyReqOpts |= kOptsDlgPxy;
}
}
//
// No proxy options
if (opt.createpxy) {
PxyReqOpts |= kOptsCreatePxy;
}
//
// Define valid CNs for the server certificates; default is null, which means that
// the server CN must be in the form "*/<hostname>"
if (opt.srvnames)
SrvAllowedNames = opt.srvnames;
//
// Notify
TRACE(Authen, "using certificate file: "<<UsrCert);
TRACE(Authen, "using private key file: "<<UsrKey);
TRACE(Authen, "proxy: file: "<<UsrProxy);
TRACE(Authen, "proxy: validity: "<<PxyValid);
TRACE(Authen, "proxy: depth of signature path: "<<DepLength);
TRACE(Authen, "proxy: bits in key: "<<DefBits);
TRACE(Authen, "server cert: allowed names: "<<SrvAllowedNames);
if (!(PxyReqOpts & kOptsCreatePxy)) {
TRACE(Authen, "allowing for pure cert/key authentication (no proxy) ");
}
// We are done
Parms = (char *)"";
}
// We are done
return Parms;
}
TRACE_Debug
#define TRACE_Debug
Definition XrdCmsTrace.hh:37
XrdCryptoSetTrace
void XrdCryptoSetTrace(kXR_int32 trace)
Definition XrdCryptoAux.cc:49
cryptoTRACE_Notify
#define cryptoTRACE_Notify
Definition XrdCryptoAux.hh:49
cryptoTRACE_Dump
#define cryptoTRACE_Dump
Definition XrdCryptoAux.hh:47
cryptoTRACE_Debug
#define cryptoTRACE_Debug
Definition XrdCryptoAux.hh:48
XrdOucgetGMap
XrdOucGMap * XrdOucgetGMap(XrdOucGMapArgs)
Definition XrdOucGMap.cc:92
access
#define access(a, b)
Definition XrdPosix.hh:44
stat
#define stat(a, b)
Definition XrdPosix.hh:101
gUsrPxyDef
static const char * gUsrPxyDef
Definition XrdSecProtocolgsi.cc:130
kOptsSigReq
@ kOptsSigReq
Definition XrdSecProtocolgsi.hh:110
kOptsFwdPxy
@ kOptsFwdPxy
Definition XrdSecProtocolgsi.hh:109
kOptsPxCred
@ kOptsPxCred
Definition XrdSecProtocolgsi.hh:114
kOptsSrvReq
@ kOptsSrvReq
Definition XrdSecProtocolgsi.hh:111
kOptsDlgPxy
@ kOptsDlgPxy
Definition XrdSecProtocolgsi.hh:108
kOptsCreatePxy
@ kOptsCreatePxy
Definition XrdSecProtocolgsi.hh:115
kOptsPxFile
@ kOptsPxFile
Definition XrdSecProtocolgsi.hh:112
XrdCryptoMax
#define XrdCryptoMax
Definition XrdSecProtocolgsi.hh:70
kGSErrInit
@ kGSErrInit
Definition XrdSecProtocolgsi.hh:145
TRACE_Authen
#define TRACE_Authen
Definition XrdSecTrace.hh:62
gsiTrace
XrdOucTrace * gsiTrace
Definition XrdSecgsiProxy.cc:119
XrdSutExpand
int XrdSutExpand(XrdOucString &path)
Definition XrdSutAux.cc:360
XrdSutHome
const char * XrdSutHome()
Definition XrdSutAux.cc:459
XrdSutSetTrace
void XrdSutSetTrace(kXR_int32 trace)
Definition XrdSutAux.cc:93
sutTRACE_Notify
#define sutTRACE_Notify
Definition XrdSutAux.hh:100
sutTRACE_Debug
#define sutTRACE_Debug
Definition XrdSutAux.hh:99
sutTRACE_Dump
#define sutTRACE_Dump
Definition XrdSutAux.hh:98
TRACE
#define TRACE(act, x)
Definition XrdTrace.hh:63
TRACE_ALL
#define TRACE_ALL
Definition XrdTrace.hh:35
XrdCryptoFactory::HasPaddingSupport
virtual bool HasPaddingSupport()
Definition XrdCryptoFactory.cc:114
XrdCryptoFactory::SetTrace
virtual void SetTrace(kXR_int32 trace)
Definition XrdCryptoFactory.cc:69
XrdCryptoFactory::Name
char * Name() const
Definition XrdCryptoFactory.hh:134
XrdCryptoFactory::Cipher
virtual XrdCryptoCipher * Cipher(const char *t, int l=0)
Definition XrdCryptoFactory.cc:123
XrdCryptoFactory::ID
int ID() const
Definition XrdCryptoFactory.hh:135
XrdCryptoFactory::GetCryptoFactory
static XrdCryptoFactory * GetCryptoFactory(const char *factoryname)
Definition XrdCryptoFactory.cc:417
XrdCryptoFactory::Notify
virtual void Notify()
Definition XrdCryptoFactory.hh:141
XrdOucErrInfo::getErrText
const char * getErrText()
Definition XrdOucErrInfo.hh:262
XrdOucString::endswith
bool endswith(char c)
Definition XrdOucString.cc:406

References access, gsiOptions::authzcall, gsiOptions::authzfun, gsiOptions::authzfunparms, gsiOptions::authzpxy, gsiOptions::authzto, gsiOptions::bits, XrdOucString::c_str(), gsiOptions::ca, gsiOptions::cert, gsiOptions::certdir, XrdCryptoFactory::Cipher(), gsiOptions::cipher, gsiOptions::clist, gsiOptions::createpxy, gsiOptions::crl, gsiOptions::crldir, gsiOptions::crlext, gsiOptions::crlrefresh, cryptoTRACE_Debug, cryptoTRACE_Dump, cryptoTRACE_Notify, DEBUG, gsiOptions::debug, gsiOptions::deplen, gsiOptions::dlgpxy, XrdOucString::endswith(), EPNAME, gsiOptions::exppxy, XrdCryptoFactory::GetCryptoFactory(), XrdOucErrInfo::getErrText(), gsiOptions::gmapfun, gsiOptions::gmapfunparms, gsiOptions::gmapto, gNoPadTag, gsiOptions::gridmap, gsiOptions, gsiTrace, gUsrPxyDef, gsiOptions::hashcomp, XrdCryptoFactory::HasPaddingSupport(), XrdCryptoFactory::ID(), gsiOptions::key, kGSErrError, kGSErrInit, kOptsCreatePxy, kOptsDlgPxy, kOptsFwdPxy, kOptsPxCred, kOptsPxFile, kOptsSigReq, kOptsSrvReq, XrdOucString::length(), gsiOptions::md, gsiOptions::mode, gsiOptions::moninfo, XrdCryptoFactory::Name(), NOTIFY, XrdCryptoFactory::Notify(), 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, 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

  buff | buffer that holds the key.
  size | size 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.

{
// Set the current encryption key
//
// Returns: < 0 Failed, returned value if -errno (see Encrypt)
// 0 The new key has been set.
//
EPNAME("setKey");
// Make sur that we can initialize the new key
if (!kbuf || klen <= 0)
// Invalid inputs
return -EINVAL;
if (!sessionCF)
// Invalid context
return -ENOENT;
// Put the buffer key into a bucket
XrdSutBucket *bck = new XrdSutBucket();
if (!bck)
// Cannot get buffer: out-of-resources?
return -ENOMEM;
// Set key buffer
bck->SetBuf(kbuf, klen);
// Init a new cipher from the bucket
XrdCryptoCipher *newKey = sessionCF->Cipher(bck);
if (!newKey) {
SafeDelete(bck);
return -ENOMEM;
}
// Delete current key
SafeDelete(sessionKey);
// Set the new key
sessionKey = newKey;
// Cleanup
SafeDelete(bck);
// Ok
DEBUG("session key update");
return 0;
}
XrdSutBucket::SetBuf
int SetBuf(const char *nb=0, int ns=0)
Definition XrdSutBucket.cc:132

References 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

  inbuff | buffer holding data to be signed.
  inlen | length of the data.
  outbuff | place 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.

{
// Sign data in inbuff and place the signature in outbuf.
//
// Returns: < 0 Failed, returned value is -errno (see Encrypt).
// = 0 Success, the return value is the length of the signature
// placed in outbuf.
//
EPNAME("Sign");
// We must have a PKI and a digest
if (!sessionKsig || !sessionMD)
return -ENOENT;
// And something to sign
if (!inbuf || inlen <= 0 || !outbuf)
return -EINVAL;
// Reset digest
sessionMD->Reset(0);
// Calculate digest
sessionMD->Update(inbuf, inlen);
sessionMD->Final();
// Output length
int lmax = sessionKsig->GetOutlen(sessionMD->Length());
char *buf = (char *)malloc(lmax);
if (!buf)
return -ENOMEM;
// Sign
int len = sessionKsig->EncryptPrivate(sessionMD->Buffer(),
sessionMD->Length(),
buf, lmax);
if (len <= 0) {
SafeFree(buf);
return -EINVAL;
}
// Create and fill output buffer
*outbuf = new XrdSecBuffer(buf, len);
// We are done
DEBUG("signature has "<<len<<" bytes");
return 0;
}

References DEBUG, EPNAME, and SafeFree.

## Verify()

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

virtual

Verify a signature using the session key.

Parameters

  inbuff | buffer holding data to be verified.
  inlen | length of the data.
  sigbuff | pointer to the signature data.
  siglen | length 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.

{
// Verify a signature
//
// Returns: < 0 Failed, returned value is -errno (see Encrypt).
// = 0 Signature matches the value in inbuff.
// > 0 Failed to verify, signature does not match inbuff data.
//
EPNAME("Verify");
// We must have a PKI and a digest
if (!sessionKver || !sessionMD)
return -ENOENT;
// And something to verify
if (!inbuf || inlen <= 0 || !sigbuf || siglen <= 0)
return -EINVAL;
// Reset digest
sessionMD->Reset(0);
// Calculate digest
sessionMD->Update(inbuf, inlen);
sessionMD->Final();
// Output length
int lmax = sessionKver->GetOutlen(siglen);
char *buf = new char[lmax];
if (!buf)
return -ENOMEM;
// Decrypt signature
int len = sessionKver->DecryptPublic(sigbuf, siglen, buf, lmax);
if (len <= 0) {
delete[] buf;
return -EINVAL;
}
// Verify signature
bool bad = 1;
if (len == sessionMD->Length()) {
if (!strncmp(buf, sessionMD->Buffer(), len)) {
// Signature matches
bad = 0;
DEBUG("signature successfully verified");
}
}
// Cleanup
if (buf) delete[] buf;
// We are done
return ((bad) ? 1 : 0);
}

References DEBUG, and EPNAME.

## Friends And Related Symbol Documentation

## gsiHSVars

friend class gsiHSVars

friend

Definition at line 283 of file XrdSecProtocolgsi.hh.

References gsiHSVars, and opts.

Referenced by XrdSecProtocolgsi(), and gsiHSVars.

## gsiOptions

friend class gsiOptions

friend

Definition at line 282 of file XrdSecProtocolgsi.hh.

References gsiOptions.

Referenced by gsiOptions, and Init().

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

- XrdSecProtocolgsi.hh
- XrdSecProtocolgsi.cc