27 #include "XrdNet/XrdNetAddr.hh"
45 #include "XrdOuc/XrdOucErrInfo.hh"
46 #include "XrdOuc/XrdOucString.hh"
47 #include "XrdSec/XrdSecInterface.hh"
48 #include "XrdSys/XrdSysLogger.hh"
49 #include "XrdSys/XrdSysPlatform.hh"
53 #if (defined(SUNCC) || defined(SUN))
54 #include <sys/isa_defs.h>
55 #if defined(_ILP32) && (_FILE_OFFSET_BITS != 32)
56 #undef _FILE_OFFSET_BITS
57 #define _FILE_OFFSET_BITS 32
58 #undef _LARGEFILE_SOURCE
64 #if !defined(__APPLE__)
74 # include <sys/socket.h>
76 #include <sys/types.h>
85 typedef XrdSecProtocol *(*secGetProt_t)(
const char *,
const struct sockaddr &,
86 const XrdSecParameters &, XrdOucErrInfo *);
88 XrdClientConnectionMgr *XrdProofConn::fgConnMgr = 0;
91 int XrdProofConn::fgMaxTry = 5;
92 int XrdProofConn::fgTimeWait = 2;
94 XrdSysPlugin *XrdProofConn::fgSecPlugin = 0;
95 void *XrdProofConn::fgSecGetProtocol = 0;
97 #define URLTAG "["<<fUrl.Host<<":"<<fUrl.Port<<"]"
112 XrdProofConn::XrdProofConn(
const char *url,
char m,
int psid,
char capver,
113 XrdClientAbsUnsolMsgHandler *uh,
const char *logbuf)
114 : fMode(m), fConnected(0), fLogConnID(-1), fStreamid(0), fRemoteProtocol(-1),
115 fServerProto(-1), fServerType(kSTNone), fSessionID(psid), fPort(-1),
116 fLastErr(kXR_noErrorYet), fCapVer(capver), fLoginBuffer(logbuf), fMutex(0),
117 fConnectInterruptMtx(0), fConnectInterrupt(0), fPhyConn(0),
118 fOpenSockFD(-1), fUnsolMsgHandler(uh), fSender(0), fSenderArg(0)
120 XPDLOC(ALL,
"XrdProofConn")
123 fMutex = new XrdSysRecMutex();
124 fConnectInterruptMtx = new XrdSysRecMutex();
127 if (url && !Init(url)) {
128 if (GetServType() != kSTProofd && !(fLastErr == kXR_NotAuthorized))
129 TRACE(XERR,
"XrdProofConn: severe error occurred while opening a"
130 " connection" <<
" to server "<<URLTAG);
140 void XrdProofConn::GetRetryParam(
int &maxtry,
int &timewait)
143 timewait = fgTimeWait;
150 void XrdProofConn::SetRetryParam(
int maxtry,
int timewait)
153 fgTimeWait = timewait;
159 bool XrdProofConn::Init(
const char *url,
int)
161 XPDLOC(ALL,
"Conn::Init")
165 if (!(fgConnMgr =
new XrdClientConnectionMgr())) {
166 TRACE(XERR,
"error initializing connection manager");
172 fUrl.TakeUrl(XrdOucString(url));
173 fUser = fUrl.User.c_str();
175 if (fUser.length() <= 0) {
178 struct passwd *pw = getpwuid(getuid());
179 fUser = pw ? pw->pw_name :
"";
182 DWORD length =
sizeof (name);
183 ::GetUserName(name, &length);
184 if (strlen(name) > 1)
188 fHost = fUrl.Host.c_str();
201 void XrdProofConn::Connect(
int)
203 XPDLOC(ALL,
"Conn::Connect")
206 int maxTry = (fgMaxTry > -1) ? fgMaxTry : EnvGetLong(NAME_FIRSTCONNECTMAXCNT);
207 int timeWait = (fgTimeWait > -1) ? fgTimeWait : EnvGetLong(NAME_CONNECTTIMEOUT);
212 for (; (i < maxTry) && (!fConnected); i++) {
215 logid = TryConnect();
218 if (ConnectInterrupt()) {
219 TRACE(ALL,
"got an interrupt while connecting - aborting attempts");
229 if (fPhyConn->IsLogged() == kNo) {
232 TRACE(DBG,
"new logical connection ID: "<<logid);
235 if (!GetAccessToSrv()) {
236 if (GetServType() == kSTProofd) {
240 if (fLastErr == kXR_NotAuthorized || fLastErr == kXR_InvalidRequest) {
243 if (fLastErr == kXR_InvalidRequest) {
244 XrdOucString msg = fLastErrMsg;
245 msg.erase(msg.rfind(
":"));
246 TRACE(XERR,
"failure: " << msg);
250 TRACE(XERR,
"access to server failed (" << fLastErrMsg <<
")");
258 TRACE(DBG,
"connection successfully created");
264 TRACE(REQ,
"disconnecting");
268 if (i < maxTry - 1) {
269 TRACE(DBG,
"connection attempt failed: sleep " << timeWait <<
" secs");
270 if (fUrl.Host ==
"lite" || fUrl.Host ==
"pod") {
271 const char *cdef = (fUrl.Host ==
"lite") ?
" (or \"\": check 'Proof.LocalDefault')" :
"";
272 const char *cnow = (fUrl.Host ==
"lite") ?
"now " :
"";
273 const char *cses = (fUrl.Host ==
"lite") ?
"PROOF-Lite" :
"PoD";
274 TRACE(ALL,
"connection attempt to server \""<<fUrl.Host<<
"\" failed. We are going to retry after some sleep,");
275 TRACE(ALL,
"but if you intended to start a "<<cses<<
" session instead, please note that you must");
276 TRACE(ALL, cnow<<
"use \""<<fUrl.Host<<
"://\" as connection string"<<cdef);
285 TRACE(XERR,
"failed to connect to " << fUrl.GetUrl());
292 XrdProofConn::~XrdProofConn()
297 if (fRemoteProtocol > 1004) {
299 SetConnectInterrupt();
301 XrdClientPhyConnLocker pcl(fPhyConn);
310 SafeDel(fConnectInterruptMtx);
316 void XrdProofConn::ReConnect()
318 XPDLOC(ALL,
"Conn::ReConnect")
321 if (fRemoteProtocol > 1004) {
324 XrdClientPhyConnLocker pcl(fPhyConn);
327 int maxtry, timewait;
328 XrdProofConn::GetRetryParam(maxtry, timewait);
329 XrdProofConn::SetRetryParam(300, 1);
331 XrdProofConn::SetRetryParam();
334 TRACE(DBG,
"server does not support reconnections (protocol: %d" <<
335 fRemoteProtocol <<
" < 1005)");
343 int XrdProofConn::TryConnect(
int)
345 XPDLOC(ALL,
"Conn::TryConnect")
351 static
int servdef = -1;
353 struct servent *ent = getservbyname(
"proofd",
"tcp");
354 servdef = (ent) ? (
int)ntohs(ent->s_port) : 1093;
359 char *haddr[10] = {0}, *hname[10] = {0};
360 int naddr = XrdSysDNS::getAddrName(fUrl.Host.c_str(), 10, haddr, hname);
363 for (; i < naddr; i++ ) {
365 fUrl.HostAddr = (
const char *) haddr[i];
367 fUrl.Host = (
const char *) hname[i];
369 TRACE(HDBG,
"found host "<<fUrl.Host<<
" with addr " << fUrl.HostAddr);
374 aNA.Set(fUrl.Host.c_str());
375 fUrl.Host = (
const char *) aNA.Name();
377 if (aNA.Format(ha, 256) <= 0) {
378 TRACE(DBG,
"failure resolving address name " <<URLTAG);
383 fUrl.HostAddr = (
const char *) ha;
385 TRACE(HDBG,
"found host "<<fUrl.Host<<
" with addr " << fUrl.HostAddr);
389 fUrl.Port = (fUrl.Port <= 0) ? servdef : fUrl.Port;
392 if ((logid = fgConnMgr->Connect(fUrl)) < 0) {
393 TRACE(DBG,
"failure creating logical connection to " <<URLTAG);
401 fStreamid = fgConnMgr->GetConnection(fLogConnID)->Streamid();
402 fPhyConn = fgConnMgr->GetConnection(fLogConnID)->GetPhyConnection();
405 TRACE(DBG,
"connect to "<<URLTAG<<
" returned {"<<fLogConnID<<
", "<< fStreamid<<
"}");
409 if (fRemoteProtocol < 0)
410 fRemoteProtocol = fPhyConn->fServerProto;
413 SetAsync(fUnsolMsgHandler);
422 void XrdProofConn::Close(
const char *opt)
424 XPDLOC(ALL,
"Conn::Close")
431 bool closephys = (opt[0] == 'P') ? 1 : 0;
432 TRACE(DBG, URLTAG <<": closing also physical connection ? "<< closephys);
436 fgConnMgr->Disconnect(GetLogConnID(), closephys);
452 UnsolRespProcResult XrdProofConn::ProcessUnsolicitedMsg(XrdClientUnsolMsgSender *,
455 XPDLOC(ALL,
"Conn::ProcessUnsolicitedMsg")
457 TRACE(DBG,"processing unsolicited response");
459 if (!m || m->IsError()) {
460 TRACE(XERR,
"Got empty or error unsolicited message");
464 if ((len = m->DataLen()) < (
int)
sizeof(kXR_int32)) {
465 TRACE(XERR,
"empty or bad-formed message - ignoring");
470 memcpy(&acod, m->GetData(),
sizeof(kXR_int32));
473 void *pdata = (
void *)((
char *)(m->GetData()) +
sizeof(kXR_int32));
476 if (acod == kXPD_srvmsg) {
479 memcpy(&opt, pdata,
sizeof(kXR_int32));
481 if (opt == 0 || opt == 1 || opt == 2) {
483 pdata = (
void *)((
char *)pdata +
sizeof(kXR_int32));
484 len -=
sizeof(kXR_int32);
490 (*fSender)((
const char *)pdata, len, fSenderArg);
501 void XrdProofConn::SetAsync(XrdClientAbsUnsolMsgHandler *uh,
502 XrdProofConnSender_t sender,
void *arg)
504 if (fgConnMgr && (fLogConnID > -1) && fgConnMgr->GetConnection(fLogConnID))
505 fgConnMgr->GetConnection(fLogConnID)->UnsolicitedMsgHandler = uh;
515 XrdClientMessage *XrdProofConn::ReadMsg()
517 return (fgConnMgr ? fgConnMgr->ReadMsg(fLogConnID) : (XrdClientMessage *)0);
528 XrdClientMessage *XrdProofConn::SendRecv(XPClientRequest *req,
const void *reqData,
531 XPDLOC(ALL,
"Conn::SendRecv")
533 XrdClientMessage *xmsg = 0;
539 SetSID(req->header.streamid);
543 XPD::smartPrintClientHeader(req);
546 int reqDataLen = req->header.dlen;
547 if (XPD::clientMarshall(req) != 0) {
548 TRACE(XERR,
"problems marshalling "<<URLTAG);
551 if (LowWrite(req, reqData, reqDataLen) != kOK) {
552 TRACE(XERR,
"problems sending request to server "<<URLTAG);
557 bool needalloc = (answData && !(*answData));
562 size_t dataRecvSize = 0;
567 kXR_int16 xst = kXR_error;
568 if (!(xmsg = ReadMsg()) || xmsg->IsError()) {
569 TRACE(XERR,
"reading msg from connmgr (server "<<URLTAG<<
")");
573 XPD::smartPrintServerHeader(&(xmsg->fHdr));
575 xst = xmsg->HeaderStatus();
580 if ((xst == kXR_ok) || (xst == kXR_oksofar) || (xst == kXR_authmore)) {
581 if (answData && xmsg->DataLen() > 0) {
583 *answData = (
char *) realloc(*answData, dataRecvSize + xmsg->DataLen());
586 TRACE(XERR,
"reallocating "<<dataRecvSize<<
" bytes");
587 free((
void *) *answData);
595 memcpy((*answData)+dataRecvSize,
596 xmsg->GetData(), xmsg->DataLen());
600 TRACE(DBG,
"dumping read data ...");
601 for (
int jj = 0; jj < xmsg->DataLen(); jj++) {
602 printf(
"0x%.2x ", *(((kXR_char *)xmsg->GetData())+jj));
603 if (!(jj%10)) printf(
"\n");
608 dataRecvSize += xmsg->DataLen();
610 }
else if (xst != kXR_error) {
613 TRACE(XERR,
"status in reply is unknown ["<<
614 XPD::convertRespStatusToChar(xmsg->fHdr.status)<<
615 "] (server "<<URLTAG<<
") - Abort");
621 if (xmsg && (xst == kXR_oksofar) && (xmsg->DataLen() == 0))
624 }
while (xmsg && (xmsg->HeaderStatus() == kXR_oksofar));
628 xmsg->fHdr.dlen = dataRecvSize;
636 XrdClientMessage *XrdProofConn::SendReq(XPClientRequest *req,
const void *reqData,
637 char **answData,
const char *CmdName,
640 XPDLOC(ALL,
"Conn::SendReq")
642 XrdClientMessage *answMex = 0;
644 TRACE(DBG,"len: "<<req->sendrcv.dlen);
647 bool resp = 0, abortcmd = 0;
648 int maxTry = (fgMaxTry > -1) ? fgMaxTry : kXR_maxReqRetry;
651 XPClientRequest reqsave;
652 memcpy(&reqsave, req, sizeof(XPClientRequest));
654 while (!abortcmd && !resp) {
656 TRACE(HDBG,
this <<
" locking phyconn: "<<fPhyConn);
662 memcpy(req, &reqsave,
sizeof(XPClientRequest));
666 TRACE(DBG,
"calling SendRecv");
667 answMex = SendRecv(req, reqData, answData);
672 if (!answMex || answMex->IsError()) {
674 TRACE(DBG,
"communication error detected with "<<URLTAG);
675 if (retry > maxTry) {
676 TRACE(XERR,
"max number of retries reached - Abort");
683 TRACE(XERR,
"not connected: nothing to do");
689 memcpy(req, &reqsave,
sizeof(XPClientRequest));
695 resp = CheckResp(&(answMex->fHdr), CmdName, notifyerr);
700 abortcmd = CheckErrorStatus(answMex, retry, CmdName, notifyerr);
702 if (retry > maxTry) {
703 TRACE(XERR,
"max number of retries reached - Abort");
713 TRACE(DBG,
"sleep "<<sleeptime<<
" secs ...");
727 bool XrdProofConn::CheckResp(
struct ServerResponseHeader *resp,
728 const char *method,
bool notifyerr)
730 XPDLOC(ALL,
"Conn::CheckResp")
732 if (MatchStreamID(resp)) {
734 if (resp->status != kXR_ok && resp->status != kXR_authmore &&
735 resp->status != kXR_wait) {
737 TRACE(XERR,
"server "<<URLTAG<<
738 " did not return OK replying to last request");
746 TRACE(XERR, method <<
" return message not belonging to this client"
747 " - protocol error");
756 bool XrdProofConn::MatchStreamID(
struct ServerResponseHeader *ServerResponse)
760 memcpy(sid, &fStreamid,
sizeof(sid));
763 return (memcmp(ServerResponse->streamid, sid,
sizeof(sid)) == 0 );
769 void XrdProofConn::SetSID(kXR_char *sid) {
770 memcpy((
void *)sid, (
const void*)&fStreamid, 2);
777 XReqErrorType XrdProofConn::LowWrite(XPClientRequest *req,
const void* reqData,
780 XPDLOC(ALL,
"Conn::LowWrite")
783 XrdClientPhyConnLocker pcl(fPhyConn);
788 int len = sizeof(req->header);
789 if ((wc = WriteRaw(req, len)) != len) {
790 TRACE(XERR,
"sending header to server "<<URLTAG<<
" (rc="<<wc<<
")");
796 if (reqDataLen > 0) {
798 if ((wc = WriteRaw(reqData, reqDataLen)) != reqDataLen) {
799 TRACE(XERR,
"sending data ("<<reqDataLen<<
" bytes) to server "<<URLTAG<<
811 bool XrdProofConn::CheckErrorStatus(XrdClientMessage *mex,
int &Retry,
812 const char *CmdName,
bool notifyerr)
814 XPDLOC(ALL,
"Conn::CheckErrorStatus")
816 TRACE(DBG, "parsing reply from server "<<URLTAG);
818 if (mex->HeaderStatus() == kXR_error) {
823 struct ServerResponseBody_Error *body_err;
825 body_err = (
struct ServerResponseBody_Error *)mex->GetData();
828 fLastErr = (XErrorCode)ntohl(body_err->errnum);
829 fLastErrMsg = body_err->errmsg;
832 if (fLastErr == (XErrorCode)kXP_reconnecting) {
833 TRACE(XERR, fLastErrMsg);
835 TRACE(XERR,
"error "<<fLastErr<<
": '"<<fLastErrMsg<<
"'");
839 if (fLastErr == (XErrorCode)kXP_reconnecting)
844 if (mex->HeaderStatus() == kXR_wait) {
849 struct ServerResponseBody_Wait *body_wait;
851 body_wait = (
struct ServerResponseBody_Wait *)mex->GetData();
854 int sleeptime = ntohl(body_wait->seconds);
855 if (mex->DataLen() > 4) {
856 TRACE(DBG,
"wait request ("<<sleeptime<<
857 " secs); message: "<<(
const char*)body_wait->infomsg);
859 TRACE(DBG,
"wait request ("<<sleeptime<<
" secs)");
870 TRACE(XERR,
"after: "<<CmdName<<
": server reply not recognized - protocol error");
879 bool XrdProofConn::GetAccessToSrv(XrdClientPhyConnection *p)
881 XPDLOC(ALL,
"Conn::GetAccessToSrv")
883 XrdClientPhyConnection *phyconn = (p) ? p : fPhyConn;
885 { XrdClientPhyConnLocker pcl(phyconn);
886 fServerType = DoHandShake(p);
889 switch (fServerType) {
893 TRACE(DBG,
"found server at "<<URLTAG);
896 if (phyconn == fPhyConn) fPhyConn->StartReader();
897 fPhyConn->fServerType = kSTBaseXrootd;
901 TRACE(DBG,
"server at "<<URLTAG<<
" is a proofd");
904 dum[0] = (kXR_int32)htonl(0);
905 dum[1] = (kXR_int32)htonl(2034);
906 WriteRaw(&dum[0],
sizeof(dum), p);
911 TRACE(XERR,
"handshake failed with server "<<URLTAG);
916 TRACE(XERR,
"server at "<<URLTAG<<
" is unknown");
921 bool ok = (phyconn == fPhyConn && fPhyConn->IsLogged() == kNo) ? Login() : 1;
923 TRACE(XERR,
"client could not login at "<<URLTAG);
934 int XrdProofConn::WriteRaw(
const void *buf,
int len, XrdClientPhyConnection *phyconn)
936 if (phyconn && phyconn->IsValid()) {
937 phyconn->WriteRaw(buf, len, 0);
938 }
else if (fgConnMgr) {
939 return fgConnMgr->WriteRaw(fLogConnID, buf, len, 0);
949 int XrdProofConn::ReadRaw(
void *buf,
int len, XrdClientPhyConnection *phyconn)
951 if (phyconn && phyconn->IsValid()) {
952 phyconn->ReadRaw(buf, len);
953 }
else if (fgConnMgr) {
954 return fgConnMgr->ReadRaw(fLogConnID, buf, len);
965 XrdProofConn::ESrvType XrdProofConn::DoHandShake(XrdClientPhyConnection *p)
967 XPDLOC(ALL,
"Conn::DoHandShake")
969 XrdClientPhyConnection *phyconn = (p) ? p : fPhyConn;
972 if (phyconn->fServerType == kSTBaseXrootd) {
974 TRACE(DBG,
"already connected to a PROOF server "<<URLTAG);
979 struct ClientInitHandShake initHS;
980 memset(&initHS, 0,
sizeof(initHS));
981 initHS.third = (kXR_int32)htonl((
int)1);
985 int len =
sizeof(initHS);
986 TRACE(HDBG,
"step 1: sending "<<len<<
" bytes to server "<<URLTAG);
988 int writeCount = WriteRaw(&initHS, len, p);
989 if (writeCount != len) {
990 TRACE(XERR,
"sending "<<len<<
" bytes to server "<<URLTAG);
996 dum[0] = (kXR_int32)htonl(4);
997 dum[1] = (kXR_int32)htonl(2012);
998 writeCount = WriteRaw(&dum[0],
sizeof(dum), p);
999 if (writeCount !=
sizeof(dum)) {
1000 TRACE(XERR,
"sending "<<
sizeof(dum)<<
" bytes to server "<<URLTAG);
1005 ServerResponseType type;
1007 TRACE(HDBG,
"step 2: reading "<<len<<
" bytes from server "<<URLTAG);
1011 int readCount = ReadRaw(&type, len, p);
1012 if (readCount != len) {
1013 if (readCount == (
int)TXSOCK_ERR_TIMEOUT) {
1014 TRACE(ALL,
"-----------------------");
1015 TRACE(ALL,
"TimeOut condition reached reading from remote server.");
1016 TRACE(ALL,
"This may indicate that the server is a 'proofd', version <= 12");
1017 TRACE(ALL,
"Retry commenting the 'Plugin.TSlave' line in system.rootrc or adding");
1018 TRACE(ALL,
"Plugin.TSlave: ^xpd TSlave Proof \"TSlave(const char *,const char"
1019 " *,int,const char *, TProof *,ESlaveType,const char *,const char *)\"");
1020 TRACE(ALL,
"to your $HOME/.rootrc .");
1021 TRACE(ALL,
"-----------------------");
1023 TRACE(XERR,
"reading "<<len<<
" bytes from server "<<URLTAG);
1034 struct ServerInitHandShake xbody;
1037 len =
sizeof(xbody);
1038 TRACE(HDBG,
"step 3: reading "<<len<<
" bytes from server "<<URLTAG);
1040 readCount = ReadRaw(&xbody, len, p);
1041 if (readCount != len) {
1042 TRACE(XERR,
"reading "<<len<<
" bytes from server "<<URLTAG);
1046 XPD::ServerInitHandShake2HostFmt(&xbody);
1048 fRemoteProtocol = xbody.protover;
1049 if (fPhyConn->fServerProto <= 0)
1050 fPhyConn->fServerProto = fRemoteProtocol;
1054 }
else if (type == 8) {
1059 TRACE(XERR,
"unknown server type ("<<type<<
")");
1067 int XrdProofConn::GetLowSocket()
1069 return (fPhyConn ? fPhyConn->GetSocket() : -1);
1076 bool XrdProofConn::Login()
1078 XPDLOC(ALL,
"Conn::Login")
1080 XPClientRequest reqhdr, reqsave;
1083 memset( &reqhdr, 0, sizeof(reqhdr));
1085 reqhdr.login.pid = getpid();
1088 XrdOucString ug = fUser;
1089 if (fUrl.Passwd.length() > 0) {
1095 if (ug.length() > 8) {
1098 strncpy( (
char *)reqhdr.login.username,
"?>buf",
sizeof(reqhdr.login.username));
1101 if (fLoginBuffer.find(
"|usr:") == STR_NPOS) {
1102 fLoginBuffer +=
"|usr:";
1105 }
else if (ug.length() >= 0) {
1106 memcpy((
void *)reqhdr.login.username, (
void *)(ug.c_str()), ug.length());
1107 if (ug.length() < 8) reqhdr.login.username[ug.length()] =
'\0';
1109 strncpy((
char *)reqhdr.login.username,
"????",
sizeof(reqhdr.login.username));
1114 const void *buf = (
const void *)(fLoginBuffer.c_str());
1115 reqhdr.header.dlen = fLoginBuffer.length();
1118 reqhdr.login.role[0] = fMode;
1123 short int sessID = fSessionID;
1125 memcpy(&reqhdr.login.reserved[0], &sessID, 2);
1128 reqhdr.login.capver[0] = fCapVer;
1132 XrdOucString usr((
const char *)&reqhdr.login.username[0], 8);
1133 TRACE(DBG,
"logging into server "<<URLTAG<<
"; pid="<<reqhdr.login.pid<<
1138 SetSID(reqhdr.header.streamid);
1139 reqhdr.header.requestid = kXP_login;
1141 memcpy(&reqsave, &reqhdr,
sizeof(XPClientRequest));
1144 fPhyConn->SetLogged(kNo);
1151 XrdSecProtocol *secp = 0;
1158 memcpy(&reqhdr, &reqsave,
sizeof(XPClientRequest));
1160 XrdClientMessage *xrsp = SendReq(&reqhdr, buf,
1161 &pltmp,
"XrdProofConn::Login", 0);
1164 char *plref = pltmp;
1168 int len = xrsp->DataLen();
1169 if (len >= (
int)
sizeof(kXR_int32)) {
1172 memcpy(&vers, pltmp,
sizeof(kXR_int32));
1173 fRemoteProtocol = ntohl(vers);
1174 pltmp = (
char *)((
char *)pltmp +
sizeof(kXR_int32));
1175 len -=
sizeof(kXR_int32);
1178 if (pltmp && (len > 0)) {
1185 if (EnvGetLong(NAME_DEBUG) > 0) {
1186 s =
new char [strlen(
"XrdSecDEBUG")+20];
1187 sprintf(s,
"XrdSecDEBUG=%ld", EnvGetLong(NAME_DEBUG));
1191 s =
new char [strlen(
"XrdSecUSER")+fUser.length()+2];
1192 sprintf(s,
"XrdSecUSER=%s", fUser.c_str());
1195 s =
new char [strlen(
"XrdSecHOST")+fHost.length()+2];
1196 sprintf(s,
"XrdSecHOST=%s", fHost.c_str());
1201 struct passwd *pw = getpwuid(getuid());
1204 netrc +=
"/.rootnetrc";
1207 if (netrc.length() > 0) {
1208 s =
new char [strlen(
"XrdSecNETRC")+netrc.length()+2];
1209 sprintf(s,
"XrdSecNETRC=%s", netrc.c_str());
1214 char *plist =
new char[len+1];
1215 memcpy(plist, pltmp, len);
1217 TRACE(DBG,
"server requires authentication");
1219 secp = Authenticate(plist, (
int)(len+1));
1220 resp = (secp != 0) ? 1 : 0;
1240 XPDPRT(fHost <<
": "<< GetLastErr());
1251 fPhyConn->SetLogged(kYes);
1252 fPhyConn->SetSecProtocol(secp);
1264 XrdSecProtocol *XrdProofConn::Authenticate(
char *plist,
int plsiz)
1266 XPDLOC(ALL,
"Conn::Authenticate")
1268 XrdSecProtocol *protocol = (XrdSecProtocol *)0;
1270 if (!plist || plsiz <= 0)
1273 TRACE(DBG, "host "<<URLTAG<< " sent a list of "<<plsiz<<" bytes");
1277 struct sockaddr_in netaddr;
1278 #ifndef ROOT_XrdFour
1279 char **hosterrmsg = 0;
1280 if (XrdSysDNS::getHostAddr((
char *)fUrl.HostAddr.c_str(),
1281 (
struct sockaddr &)netaddr, hosterrmsg) <= 0) {
1282 TRACE(XERR,
"getHostAddr: "<< *hosterrmsg);
1287 aNA.Set(fUrl.HostAddr.c_str());
1288 memcpy(&netaddr, aNA.NetAddr(),
sizeof(
struct sockaddr_in));
1290 netaddr.sin_port = fUrl.Port;
1293 XrdSecParameters *secToken = 0;
1294 XrdSecCredentials *credentials = 0;
1298 char *bpar = (
char *)malloc(plsiz + 1);
1300 TRACE(XERR,
"unable to allocate buffer for parameters");
1304 memcpy(bpar, plist, plsiz);
1306 XrdSecParameters Parms(bpar, plsiz + 1);
1309 if (!fgSecGetProtocol) {
1310 static XrdSysLogger log;
1311 static XrdSysError err(&log,
"XrdProofConn_");
1313 XrdOucString libsec;
1315 #if !defined(ROOT_XrdNoUtils)
1316 libsec =
"libXrdSec";
1317 libsec += LT_MODULE_EXT;
1319 libsec =
"libXrdSec.so";
1321 fgSecPlugin =
new XrdSysPlugin(&err, libsec.c_str());
1325 if (!(fgSecGetProtocol = fgSecPlugin->getPlugin(
"XrdSecGetProtocol"))) {
1326 TRACE(XERR,
"unable to load XrdSecGetProtocol()");
1332 while ((protocol = (*((secGetProt_t)fgSecGetProtocol))((
char *)fUrl.Host.c_str(),
1333 (
const struct sockaddr &)netaddr, Parms, 0))) {
1336 XrdOucString protname = protocol->Entity.prot;
1340 credentials = protocol->getCredentials(0, &ei);
1342 TRACE(XERR,
"cannot obtain credentials (protocol: "<<protname<<
")");
1344 fLastErr = kXR_NotAuthorized;
1345 if (fLastErrMsg.length() > 0) fLastErrMsg +=
":";
1346 fLastErrMsg +=
"cannot obtain credentials for protocol: ";
1347 fLastErrMsg += ei.getErrText();
1352 TRACE(HDBG,
"credentials size: " << credentials->size);
1356 XPClientRequest reqhdr;
1357 memset(reqhdr.auth.reserved, 0, 12);
1358 memset(reqhdr.auth.credtype, 0, 4);
1359 memcpy(reqhdr.auth.credtype, protname.c_str(), protname.length());
1362 int status = kXR_authmore;
1365 XrdClientMessage *xrsp = 0;
1366 while (status == kXR_authmore) {
1369 SetSID(reqhdr.header.streamid);
1370 reqhdr.header.requestid = kXP_auth;
1371 reqhdr.header.dlen = (credentials) ? credentials->size : 0;
1372 char *credbuf = (credentials) ? credentials->buffer : 0;
1373 xrsp = SendReq(&reqhdr, credbuf, &srvans,
"XrdProofConn::Authenticate");
1374 SafeDel(credentials);
1375 status = (xrsp) ? xrsp->HeaderStatus() : kXR_error;
1376 dlen = (xrsp) ? xrsp->DataLen() : 0;
1377 TRACE(HDBG,
"server reply: status: "<<status<<
" dlen: "<<dlen);
1379 if (xrsp && (status == kXR_authmore)) {
1384 secToken =
new XrdSecParameters(srvans, dlen);
1387 credentials = protocol->getCredentials(secToken, &ei);
1391 TRACE(XERR,
"cannot obtain credentials");
1393 fLastErr = kXR_NotAuthorized;
1394 if (fLastErrMsg.length() > 0) fLastErrMsg +=
":";
1395 fLastErrMsg +=
"cannot obtain credentials: ";
1396 fLastErrMsg += ei.getErrText();
1406 TRACE(HDBG,
"credentials size " << credentials->size);
1408 }
else if (status != kXR_ok) {
1411 TRACE(XERR, fHost <<
": "<< GetLastErr());
1423 fLastErr = kXR_noErrorYet;
1432 TRACE(XERR,
"unable to get protocol object.");
1434 fLastErr = kXR_NotAuthorized;
1435 if (fLastErrMsg.length() > 0) fLastErrMsg +=
":";
1436 fLastErrMsg +=
"unable to get protocol object.";
1437 TRACE(XERR, fLastErrMsg.c_str());
1448 void XrdProofConn::SetInterrupt()
1451 fPhyConn->SetInterrupt();
1457 void XrdProofConn::SetConnectInterrupt()
1459 XrdSysMutexHelper mhp(fConnectInterruptMtx);
1460 fConnectInterrupt = 1;
1466 bool XrdProofConn::ConnectInterrupt()
1469 { XrdSysMutexHelper mhp(fConnectInterruptMtx);
1470 rc = fConnectInterrupt;
1472 fConnectInterrupt = 0;
1481 bool XrdProofConn::IsValid()
const
1484 if (fPhyConn && fPhyConn->IsValid())