00001 #ifndef XRDSECTLAYER_HH 00002 #define XRDSECTLAYER_HH 00003 /******************************************************************************/ 00004 /* */ 00005 /* X r d S e c T L a y e r . h h */ 00006 /* */ 00007 /* */ 00008 /* (c) 2008 by the Board of Trustees of the Leland Stanford, Jr., University */ 00009 /* All Rights Reserved */ 00010 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 00011 /* DE-AC02-76-SFO0515 with the Department of Energy */ 00012 /******************************************************************************/ 00013 00014 // $Id: XrdSecTLayer.hh 34000 2010-06-21 06:49:56Z ganis $ 00015 00016 #include "XrdSec/XrdSecInterface.hh" 00017 #include "XrdSys/XrdSysPthread.hh" 00018 00019 /* The XrdSecTLayer class is meant to be used as a wrapper for security 00020 protocols that require transport-layer interactions to complete the 00021 authentication exchange (e.g., native ssl). This class virtualizes a 00022 transport-layer socket and provides the proper framing to allow stream 00023 socket level interactions to occur across an existing client/xrootd 00024 connection. To that extent, there are certain limitations in this 00025 virtualization: 00026 1) Interactions must complete within a window whose upper bound is set to 00027 CPU 10 seconds (i.e., Network RTT and artificial delays do not apply). 00028 The window has no lower bound so that an interaction may complete as fast 00029 as conditions allow. An interaction is whatever bytes produce a single 00030 request/response. These bytes need not be produced all at once but the 00031 last required byte of an interaction must be produced within 10 CPU 00032 seconds of the 1st byte. There is no limit on the number of interactions. 00033 2) The use of the supplied socket must use standard and common socket 00034 operations (e.g., read(), write(), send(), recv(), close()). 00035 3) The protocol must not be sensitive to the fact that the socket will 00036 identify itself as a local socket with an IPV4 address of 127.0.0.1. 00037 00038 For more information, see pure abstract methods secClient() and secServer() 00039 which must be implemented by the derived class (in addition to delete()). 00040 Finally, consider the parameters you may need to pass to the constructor of 00041 this class. 00042 */ 00043 00044 class XrdOucErrInfo; 00045 00046 class XrdSecTLayer : public XrdSecProtocol 00047 { 00048 public: 00049 00050 // The object inheriting this class should call the initializer indicating 00051 // the true name of the protocol (no more that 7 characters). To optimize the 00052 // start-up, indicate who is the initiator (i.e., first one to send data). Using 00053 // the enum below, specify isClient (the default) or isServer. If the initiator 00054 // is not known, use the default and the class will dynamically determine it. 00055 // 00056 enum Initiator {isClient = 0, isServer}; 00057 00058 XrdSecTLayer(const char *pName, Initiator who1st=isClient); 00059 00060 // This is a symmetric wrapper. At the start on each end, secClient() is 00061 // called on the client-side and secServer() is called on the server side. 00062 // The 1st parameter is the filedescriptor to be used for the security exchange. 00063 // It is the responsibility of each routine to close the file descriptor prior 00064 // to returning to the caller! No return value is expected as success or failure 00065 // is communicated via the esecond paramter, the XrdOucErrInfo object. 00066 00067 // Upon success, the error code must be set to zero (the initial value) and 00068 // for secServer() the Entity object defined in the topmost 00069 // XrdSecProtocol object must contain the client's identity. 00070 00071 // Upon failure, the error code must be set to a positive error number (usually 00072 // some errno value) as well as text explaining the problem. 00073 00074 // Client: theFD - file descriptor to be used 00075 // einfo - the error object where ending status must be returned 00076 // 00077 virtual void secClient(int theFD, XrdOucErrInfo *einfo)=0; 00078 00079 // Server: theFD - file descriptor to be used 00080 // einfo - the error object where ending status must be returned 00081 // 00082 virtual void secServer(int theFD, XrdOucErrInfo *einfo)=0; 00083 00084 // You must implete the proper delete(). Normally, do a "delete this" and join 00085 // the secTid thread: "if (secTid) {XrdSysThread::Join(secTid,NULL);secTid=0;}". 00086 // 00087 virtual void Delete()=0; 00088 00089 // Classes that must be public are only internally used 00090 // 00091 00092 virtual int Authenticate (XrdSecCredentials *cred, 00093 XrdSecParameters **parms, 00094 XrdOucErrInfo *einfo=0); 00095 00096 virtual XrdSecCredentials *getCredentials(XrdSecParameters *parm=0, 00097 XrdOucErrInfo *einfo=0); 00098 00099 void secXeq(); 00100 00101 protected: 00102 pthread_t secTid; 00103 00104 virtual ~XrdSecTLayer() {if (eText) {free(eText);eText=0;} 00105 if (myFD>0) {close(myFD);myFD=-1;} 00106 } 00107 00108 private: 00109 00110 int bootUp(Initiator Who); 00111 int Read(int FD, char *Buff, int rdLen); 00112 int secDone(); 00113 void secDrain(); 00114 const char *secErrno(int rc, char *buff); 00115 void secError(const char *Msg, int rc, int iserrno=1); 00116 00117 XrdSysSemaphore mySem; 00118 Initiator Starter; 00119 Initiator Responder; 00120 int myFD; 00121 int urFD; 00122 int Tmax; // Maximum timeslices per interaction 00123 int Tcur; // Current timeslice 00124 int eCode; 00125 char *eText; 00126 XrdOucErrInfo *eDest; 00127 00128 struct TLayerRR 00129 { 00130 char protName[8]; // via Constructor 00131 char protCode; // One of the below 00132 static const char endData = 0x00; 00133 static const char xfrData = 0x01; 00134 char protRsvd[7]; // Reserved 00135 } Hdr; 00136 00137 static const int buffSz = 8192; 00138 static const int hdrSz = sizeof(TLayerRR); 00139 static const int dataSz = buffSz - hdrSz; 00140 }; 00141 #endif