Loading...
Searching...
No Matches
XrdSecProtect Class Reference

`#include <XrdSecProtect.hh>`

Collaboration diagram for XrdSecProtect:

## Public Member Functions

virtual | ~XrdSecProtect ()
| Destructor.
virtual void | Delete ()
| Delete this object. Use this method as opposed to operator delete.
virtual int | Secure (SecurityRequest *&newreq, ClientRequest &thereq, const char *thedata)
virtual const char * | Verify (SecurityRequest &secreq, ClientRequest &thereq, const char *thedata)

## Public Attributes

bool(XrdSecProtect::* | Need2Secure )(ClientRequest &thereq)

## Protected Member Functions

| XrdSecProtect (XrdSecProtocol *aprot, XrdSecProtect &pRef, bool edok=true)
| XrdSecProtect (XrdSecProtocol *aprot=0, bool edok=true)
void | SetProtection (const ServerResponseReqs_Protocol &inReqs)

## Friends

class | XrdSecProtector

## Detailed Description

Definition at line 55 of file XrdSecProtect.hh.

## Constructor & Destructor Documentation

## ~XrdSecProtect()

virtual XrdSecProtect::~XrdSecProtect | ( |  | ) |

inline virtual

Destructor.

Definition at line 132 of file XrdSecProtect.hh.

{}

## XrdSecProtect() [1/2]

XrdSecProtect::XrdSecProtect | ( | XrdSecProtocol * | aprot = 0,
|  | bool | edok = true )

inline protected

Definition at line 136 of file XrdSecProtect.hh.

: Need2Secure(&XrdSecProtect::Screen),
authProt(aprot), secVec(0), lastSeqno(1),
edOK(edok), secVerData(false)
{}
XrdSecProtect::Need2Secure
bool(XrdSecProtect::* Need2Secure)(ClientRequest &thereq)
Definition XrdSecProtect.hh:76

References XrdSecProtect(), and Need2Secure.

Referenced by XrdSecProtect(), and XrdSecProtect().

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

## XrdSecProtect() [2/2]

XrdSecProtect::XrdSecProtect | ( | XrdSecProtocol * | aprot,
|  | XrdSecProtect & | pRef,
|  | bool | edok = true )

inline protected

Definition at line 142 of file XrdSecProtect.hh.

: Need2Secure(&XrdSecProtect::Screen),
authProt(aprot), secVec(pRef.secVec),
lastSeqno(0), edOK(edok),
secVerData(pRef.secVerData) {}

References XrdSecProtect(), and Need2Secure.

Here is the call graph for this function:

## Member Function Documentation

## Delete()

virtual void XrdSecProtect::Delete | ( |  | ) |

inline virtual

Delete this object. Use this method as opposed to operator delete.

Definition at line 64 of file XrdSecProtect.hh.

{delete this;}

## Secure()

int XrdSecProtect::Secure | ( | SecurityRequest *& | newreq,
|  | ClientRequest & | thereq,
|  | const char * | thedata )

virtual

Secure a request.

Request securement is optional and this call should be gaurded by an if statement to avoid securing requests that need not be secured as follows:

if (NEED2SECURE(<protP>)(thereq)) result = <protP>->Secure(....); else result = 0;

Modify the above to your particuar needs but gaurd the call!

Parameters

  newreq | A reference to a pointer where the new request, if needed, will be placed. The new request will consist of a kXR_sigver request followed by hash. The request buffer must be freed using free() when it is no longer needed.
  thereq | Reference to the client request header/body that needs to be secured. The request must be in network byte order.
  thedata | The request data whose length resides in theReq.dlen. If thedata is nil but thereq.dlen is not zero then the request data must follow the request header in the thereq buffer.

Returns
  <0 An error occurred and the return value is -errno.
  >0 The length of the new request whose pointer is in newreq. This is the nuber of bytes that must be sent.

Definition at line 254 of file XrdSecProtect.cc.

{
static const ClientSigverRequest initSigVer = {{0,0}, htons(kXR_sigver),
0, kXR_secver_0, 0, 0,
kXR_SHA256, {0, 0, 0}, 0
};
struct buffHold {XrdSecReq *P;
XrdSecBuffer *bP;
buffHold() : P(0), bP(0) {}
~buffHold() {if (P) free(P); if (bP) delete bP;}
};
static const int iovNum = 3;
struct iovec iov[iovNum];
buffHold myReq;
kXR_unt64 mySeq;
const char *sigBuff, *payload = thedata;
unsigned char secHash[SHA256_DIGEST_LENGTH];
int sigSize, n, newSize, rc, paysize = 0;
bool nodata = false;
// Generate a new sequence number
//
mySeq = nextSeqno++;
mySeq = htonll(mySeq);
// Determine if we are going to sign the payload and its location
//
if (thereq.header.dlen)
{kXR_unt16 reqid = htons(thereq.header.requestid);
paysize = ntohl(thereq.header.dlen);
if (!payload) payload = ((char *)&thereq) + sizeof(ClientRequest);
if (reqid == kXR_write || reqid == kXR_pgwrite) n = (secVerData ? 3 : 2);
else n = 3;
} else n = 2;
// Fill out the iovec
//
iov[0].iov_base = (char *)&mySeq;
iov[0].iov_len = sizeof(mySeq);
iov[1].iov_base = (char *)&thereq;
iov[1].iov_len = sizeof(ClientRequest);
if (n < 3) nodata = true;
else {iov[2].iov_base = (char *)payload;
iov[2].iov_len = paysize;
}
// Compute the hash
//
if (!GetSHA2(secHash, iov, n)) return -EDOM;
// Now encrypt the hash
//
if (edOK)
{rc = authProt->Encrypt((const char *)secHash,sizeof(secHash),&myReq.bP);
if (rc < 0) return rc;
sigSize = myReq.bP->size;
sigBuff = myReq.bP->buffer;
} else {
sigSize = sizeof(secHash);
sigBuff = (char *)secHash;
}
// Allocate a new request object
//
newSize = sizeof(SecurityRequest) + sigSize;
myReq.P = (XrdSecReq *)malloc(newSize);
if (!myReq.P) return -ENOMEM;
// Setup the security request (we only support signing)
//
memcpy(&(myReq.P->secReq), &initSigVer, sizeof(ClientSigverRequest));
memcpy(&(myReq.P->secReq.header.streamid ), thereq.header.streamid,
sizeof(myReq.P->secReq.header.streamid));
memcpy(&(myReq.P->secReq.sigver.expectrid),&thereq.header.requestid,
sizeof(myReq.P->secReq.sigver.expectrid));
myReq.P->secReq.sigver.seqno = mySeq;
if (nodata) myReq.P->secReq.sigver.flags |= kXR_nodata;
myReq.P->secReq.sigver.dlen = htonl(sigSize);
// Append the signature to the request
//
memcpy(&(myReq.P->secSig), sigBuff, sigSize);
// Return pointer to he security request and its size
//
newreq = &(myReq.P->secReq); myReq.P = 0;
return newSize;
}
ClientRequestHdr::streamid
kXR_char streamid[2]
Definition XProtocol.hh:156
ClientRequest::header
struct ClientRequestHdr header
Definition XProtocol.hh:846
ClientRequestHdr::requestid
kXR_unt16 requestid
Definition XProtocol.hh:157
kXR_sigver
@ kXR_sigver
Definition XProtocol.hh:141
kXR_write
@ kXR_write
Definition XProtocol.hh:131
kXR_pgwrite
@ kXR_pgwrite
Definition XProtocol.hh:138
kXR_nodata
@ kXR_nodata
Definition XProtocol.hh:738
kXR_secver_0
#define kXR_secver_0
Definition XProtocol.hh:1146
ClientRequestHdr::dlen
kXR_int32 dlen
Definition XProtocol.hh:159
kXR_SHA256
@ kXR_SHA256
Definition XProtocol.hh:731
kXR_unt64
unsigned long long kXR_unt64
Definition XPtypes.hh:99
kXR_unt16
unsigned short kXR_unt16
Definition XPtypes.hh:67

References ClientRequestHdr::dlen, ClientRequest::header, kXR_nodata, kXR_pgwrite, kXR_secver_0, kXR_SHA256, kXR_sigver, kXR_write, ClientRequestHdr::requestid, and ClientRequestHdr::streamid.

Referenced by XrdCl::XRootDTransport::GetSignature().

Here is the caller graph for this function:

## SetProtection()

void XrdSecProtect::SetProtection | ( | const ServerResponseReqs_Protocol & | inReqs | ) |

protected

Definition at line 349 of file XrdSecProtect.cc.

{
unsigned int lvl, vsz;
// Check for no security, the simlplest case
//
if (inReqs.secvsz == 0 && inReqs.seclvl == 0)
{memset(&myReqs, 0, sizeof(myReqs));
secVec = 0;
secVerData = false;
return;
}
// Precheck the security level
//
lvl = inReqs.seclvl;
if (lvl > kXR_secPedantic) lvl = kXR_secPedantic;
// Perform the default setup (the usual case)
//
secVec = secTable.Vec[lvl-1];
myReqs.seclvl = lvl;
myReqs.secvsz = 0;
myReqs.secver = kXR_secver_0;
myReqs.secopt = inReqs.secopt;
// Set options
//
secVerData = (inReqs.secopt & kXR_secOData) != 0;
// Create a modified vectr if there are overrides
//
if (inReqs.secvsz != 0)
{const ServerResponseSVec_Protocol *urVec = &inReqs.secvec;
memcpy(myVec, secVec, maxRIX);
vsz = inReqs.secvsz;
for (unsigned int i = 0; i < vsz; i++, urVec++)
{if (urVec->reqindx < maxRIX)
{if (urVec->reqsreq > kXR_signNeeded)
myVec[urVec->reqindx] = kXR_signNeeded;
else myVec[urVec->reqindx] = urVec->reqsreq;
}
}
secVec = myVec;
}
}
ServerResponseReqs_Protocol::secopt
kXR_char secopt
Definition XProtocol.hh:1111
ServerResponseSVec_Protocol::reqsreq
kXR_char reqsreq
Definition XProtocol.hh:1104
ServerResponseReqs_Protocol::secvec
ServerResponseSVec_Protocol secvec
Definition XProtocol.hh:1114
ServerResponseReqs_Protocol::secvsz
kXR_char secvsz
Definition XProtocol.hh:1113
kXR_secOData
#define kXR_secOData
Definition XProtocol.hh:1126
ServerResponseSVec_Protocol::reqindx
kXR_char reqindx
Definition XProtocol.hh:1103
kXR_secPedantic
#define kXR_secPedantic
Definition XProtocol.hh:1135
ServerResponseReqs_Protocol::seclvl
kXR_char seclvl
Definition XProtocol.hh:1112
kXR_signNeeded
#define kXR_signNeeded
Definition XProtocol.hh:1141

References kXR_secOData, kXR_secPedantic, kXR_secver_0, kXR_signNeeded, ServerResponseSVec_Protocol::reqindx, ServerResponseSVec_Protocol::reqsreq, ServerResponseReqs_Protocol::seclvl, ServerResponseReqs_Protocol::secopt, ServerResponseReqs_Protocol::secvec, and ServerResponseReqs_Protocol::secvsz.

Referenced by XrdSecProtector::Config(), and XrdSecProtector::New4Client().

Here is the caller graph for this function:

## Verify()

const char * XrdSecProtect::Verify | ( | SecurityRequest & | secreq,
|  | ClientRequest & | thereq,
|  | const char * | thedata )

virtual

Verify that a request was properly secured.

Parameters

  secreq | A reference to the kXR_sigver request followed by whatever data was sent (normally an encrypted verification hash). All but the request code must be in network byte order.
  thereq | Reference to the client request header/body that needs to be verified. The request must be in network byte order.
  thedata | The request data whose length resides in theReq.dlen.

Returns
  Upon success zero is returned. Otherwise a pointer to a null delimited string describing the problem is returned.

Definition at line 400 of file XrdSecProtect.cc.

{
struct buffHold {XrdSecBuffer *bP;
buffHold() : bP(0) {}
~buffHold() {if (bP) delete bP;}
};
static const int iovNum = 3;
struct iovec iov[iovNum];
buffHold myReq;
unsigned char *inHash, secHash[SHA256_DIGEST_LENGTH];
int dlen, n, rc;
// First check for replay attacks. The incoming sequence number must be greater
// the previous one we have seen. Since it is in network byte order we can use
// a simple byte for byte compare (no need for byte swapping).
//
if (memcmp(&lastSeqno, &secreq.sigver.seqno, sizeof(lastSeqno)) >= 0)
return "Incorrect signature sequence";
// Do basic verification for this request
//
if (memcmp(secreq.header.streamid, thereq.header.streamid,
sizeof(secreq.header.streamid)))
return "Signature streamid mismatch";
if (secreq.sigver.expectrid != thereq.header.requestid)
return "Signature requestid mismatch";
if (secreq.sigver.version != kXR_secver_0)
return "Unsupported signature version";
if ((secreq.sigver.crypto & kXR_HashMask) != kXR_SHA256)
return "Unsupported signature hash";
if (secreq.sigver.crypto & kXR_rsaKey)
return "Unsupported signature key";
// Now get the hash information
//
dlen = ntohl(secreq.header.dlen);
inHash = ((unsigned char *)&secreq)+sizeof(SecurityRequest);
// Now decrypt the hash
//
if (edOK)
{rc = authProt->Decrypt((const char *)inHash, dlen, &myReq.bP);
if (rc < 0) return XrdSysE2T(-rc);
if (myReq.bP->size != (int)sizeof(secHash))
return "Invalid signature hash length";
inHash = (unsigned char *)myReq.bP->buffer;
} else {
if (dlen != (int)sizeof(secHash))
return "Invalid signature hash length";
}
// Fill out the iovec to recompute the hash
//
iov[0].iov_base = (char *)&secreq.sigver.seqno;
iov[0].iov_len = sizeof(secreq.sigver.seqno);
iov[1].iov_base = (char *)&thereq;
iov[1].iov_len = sizeof(ClientRequest);
if (thereq.header.dlen == 0 || secreq.sigver.flags & kXR_nodata) n = 2;
else {iov[2].iov_base = (char *)thedata;
iov[2].iov_len = ntohl(thereq.header.dlen);
n = 3;
}
// Compute the hash
//
if (!GetSHA2(secHash, iov, n))
return "Signature hash computation failed";
// Compare this hash with the hash we were given
//
if (memcmp(secHash, inHash, sizeof(secHash)))
return "Signature hash mismatch";
// This request has been verified (update the seqno)
//
lastSeqno = secreq.sigver.seqno;
return 0;
}
ClientSigverRequest::crypto
kXR_char crypto
Definition XProtocol.hh:753
SecurityRequest::header
struct ClientRequestHdr header
Definition XProtocol.hh:881
SecurityRequest::sigver
struct ClientSigverRequest sigver
Definition XProtocol.hh:882
ClientSigverRequest::expectrid
kXR_unt16 expectrid
Definition XProtocol.hh:749
ClientSigverRequest::seqno
kXR_unt64 seqno
Definition XProtocol.hh:752
ClientSigverRequest::flags
kXR_char flags
Definition XProtocol.hh:751
kXR_HashMask
@ kXR_HashMask
Definition XProtocol.hh:732
kXR_rsaKey
@ kXR_rsaKey
Definition XProtocol.hh:733
ClientSigverRequest::version
kXR_char version
Definition XProtocol.hh:750
XrdSysE2T
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104

References ClientSigverRequest::crypto, ClientRequestHdr::dlen, ClientSigverRequest::expectrid, ClientSigverRequest::flags, ClientRequest::header, SecurityRequest::header, kXR_HashMask, kXR_nodata, kXR_rsaKey, kXR_secver_0, kXR_SHA256, ClientRequestHdr::requestid, ClientSigverRequest::seqno, SecurityRequest::sigver, ClientRequestHdr::streamid, ClientSigverRequest::version, and XrdSysE2T().

Here is the call graph for this function:

## Friends And Related Symbol Documentation

## XrdSecProtector

friend class XrdSecProtector

friend

Definition at line 58 of file XrdSecProtect.hh.

References XrdSecProtector.

Referenced by XrdSecProtector.

## Member Data Documentation

## Need2Secure

bool(XrdSecProtect::* XrdSecProtect::Need2Secure) (ClientRequest &thereq)

Test whether or not a request needs to be secured. This method pointer should only be invoked via the NEED2SECURE macro (see above).

Parameters

  thereq | Reference to the request header/body in network byte order.

Returns
  false - request need not be secured (equals false).
  true - request needs to be secured.

Definition at line 76 of file XrdSecProtect.hh.

Referenced by XrdSecProtect(), and XrdSecProtect().

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

- XrdSecProtect.hh
- XrdSecProtect.cc