32 #include <sys/types.h>
33 #include <sys/socket.h>
51 const char XrdSecTLayer::TLayerRR::endData;
52 const char XrdSecTLayer::TLayerRR::xfrData;
60 secTid(0), mySem(0), Starter(who1st), myFD(-1), urFD(-1),
61 Tmax(275), Tcur(0), eCode(0), eText(0)
66 memset((
void *)&Hdr, 0,
sizeof(Hdr));
67 strncpy(Hdr.protName,pName,
sizeof(Hdr.protName)-1);
81 int Blen = 0, wrLen = 0;
82 char *bP, Req = TLayerRR::xfrData;
90 {Hdr.protCode = TLayerRR::xfrData;
91 bP = (
char *)malloc(hdrSz);
92 memcpy(bP, (
char *)&Hdr, hdrSz);
96 if (parm->
size < hdrSz)
97 {secError(
"Invalid parms length", EPROTO);
100 Req = ((TLayerRR *)parm->
buffer)->protCode;
101 wrLen= parm->
size - hdrSz;
109 {
case TLayerRR::xfrData:
110 if (wrLen > 0 &&
write(myFD, parm->
buffer+hdrSz, wrLen) < 0)
111 {secError(
"Socket write failed", errno);
return 0;}
112 Blen = Read(myFD, Buff, dataSz);
113 if (Blen < 0 && (Blen != -EPIPE) && (Blen != -ECONNRESET))
114 {secError(
"Socket read failed", -Blen);
return 0;}
116 case TLayerRR::endData:
117 if (myFD < 0) {secError(
"Protocol violation", EPROTO);
return 0;}
120 default: secError(
"Unknown parms request", EINVAL);
return 0;
127 if (Blen < 0) {
if (!secDone())
return 0;
128 Blen = 0; Hdr.protCode = TLayerRR::endData;}
129 else if (Blen || wrLen) {Tcur = 0; Hdr.protCode = TLayerRR::xfrData;}
130 else if (++Tcur <= Tmax) Hdr.protCode = TLayerRR::xfrData;
131 else {Tcur = 0; Hdr.protCode = TLayerRR::endData;}
135 bP = (
char *)malloc(hdrSz+Blen);
136 memcpy(bP, (
char *)&Hdr, hdrSz);
137 if (Blen) memcpy(bP+hdrSz, Buff, Blen);
156 if (myFD < 0 && !bootUp(
isServer))
return -1;
160 if (cred->
size < hdrSz) {secError(
"Invalid credentials",EBADMSG);
return -1;}
161 Req = ((TLayerRR *)cred->
buffer)->protCode;
162 wrLen= cred->
size - hdrSz;
169 {
case TLayerRR::xfrData:
170 if (wrLen > 0 &&
write(myFD, cred->
buffer+hdrSz, wrLen) < 0)
171 {secError(
"Socket write failed", errno);
return -1;}
172 Blen = Read(myFD, Buff, dataSz);
173 if (Blen < 0 && (Blen != -EPIPE) && (Blen != -ECONNRESET))
174 {secError(
"Socket read failed", -Blen);
return 0;}
176 case TLayerRR::endData:
return (secDone() ? 0 : -1);
177 default: secError(
"Unknown parms request", EINVAL);
return -1;
185 if (Blen < 0) {Blen = 0; Hdr.protCode = TLayerRR::endData;}
186 else if (Blen || wrLen) {Tcur = 0; Hdr.protCode = TLayerRR::xfrData;}
187 else if (++Tcur <= Tmax) Hdr.protCode = TLayerRR::xfrData;
188 else {Tcur = 0; Hdr.protCode = TLayerRR::endData;}
192 bP = (
char *)malloc(hdrSz+Blen);
193 memcpy(bP, (
char *)&Hdr, hdrSz);
194 if (Blen) memcpy(bP+hdrSz, Buff, Blen);
216 int XrdSecTLayer::bootUp(Initiator whoami)
222 if (XrdSysFD_Socketpair(AF_UNIX, SOCK_STREAM, 0, sv))
223 {secError(
"Unable to create socket pair", errno);
return 0;}
224 myFD = sv[0]; urFD = sv[1];
231 close(myFD); myFD = -1;
232 close(urFD); urFD = -1;
233 secError(
"Unable to create thread", rc);
246 int XrdSecTLayer::Read(
int FD,
char *Buff,
int rdLen)
248 struct pollfd polltab = {FD, POLLIN|POLLRDNORM|POLLHUP, 0};
249 int retc, xWt, Tlen = 0;
261 if (Tcur) xWt = (Tcur+10)/10;
266 do {
do {retc = poll(&polltab, 1, xWt);}
while(retc < 0 && errno == EINTR);
267 if (retc <= 0)
return (retc ? -errno : Tlen);
268 do {retc =
read(FD, Buff, rdLen);}
while(retc < 0 && errno == EINTR);
269 if (retc <= 0)
return (retc ? -errno : (Tlen ? Tlen : -EPIPE));
270 Tlen += retc; Buff += retc; rdLen -= retc; xWt = 1;
280 int XrdSecTLayer::secDone()
289 if (!eCode)
return 1;
293 secError((eText ? eText :
"?"), eCode, 0);
301 void XrdSecTLayer::secDrain()
304 {
close(myFD); myFD = -1;
313 const char *XrdSecTLayer::secErrno(
int rc,
char *buff)
315 sprintf(buff,
"err %d", rc);
323 void XrdSecTLayer::secError(
const char *Msg,
int rc,
int iserrno)
326 const char *tlist[] = {
"XrdSecProtocol", Hdr.protName,
": ", Msg,
"; ",
327 (iserrno ?
XrdSysE2T(rc) : secErrno(rc,buff))
329 int i, n =
sizeof(tlist)/
sizeof(
const char *);
332 else {
for (i = 0; i < n; i++) std::cerr <<tlist[i]; std::cerr <<std::endl;}
353 if (eText) {free(eText); eText = 0;}
354 if (eCode) eText = strdup(Msg ? Msg :
"Authentication failed");
358 if (urFD>0)
close(urFD);
static XrdSysError eDest(0,"crypto_")
ssize_t write(int fildes, const void *buf, size_t nbyte)
ssize_t read(int fildes, void *buf, size_t nbyte)
XrdSecBuffer XrdSecParameters
XrdSecBuffer XrdSecCredentials
void * XrdSecTLayerBootUp(void *carg)
const char * XrdSysE2T(int errcode)
#define XRDSYSTHREAD_HOLD
const char * getErrText()
virtual void secClient(int theFD, XrdOucErrInfo *einfo)=0
virtual int Authenticate(XrdSecCredentials *cred, XrdSecParameters **parms, XrdOucErrInfo *einfo=0)
virtual XrdSecCredentials * getCredentials(XrdSecParameters *parm=0, XrdOucErrInfo *einfo=0)
virtual void secServer(int theFD, XrdOucErrInfo *einfo)=0
XrdSecTLayer(const char *pName, Initiator who1st=isClient)
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
Generic structure to pass security information back and forth.
char * buffer
Pointer to the buffer.
int size
Size of the buffer or length of data in the buffer.