00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "TServerSocket.h"
00025 #include "TSocket.h"
00026 #include "TSystem.h"
00027 #include "TROOT.h"
00028 #include "TError.h"
00029 #include <string>
00030 #include "TVirtualMutex.h"
00031
00032
00033 SrvAuth_t TServerSocket::fgSrvAuthHook = 0;
00034 SrvClup_t TServerSocket::fgSrvAuthClupHook = 0;
00035
00036
00037 UChar_t TServerSocket::fgAcceptOpt = kSrvNoAuth;
00038
00039 TVirtualMutex *gSrvAuthenticateMutex = 0;
00040
00041 ClassImp(TServerSocket)
00042
00043
00044 static void setaccopt(UChar_t &Opt, UChar_t Mod)
00045 {
00046
00047
00048 R__LOCKGUARD2(gSrvAuthenticateMutex);
00049
00050 if (!Mod) return;
00051
00052 if ((Mod & kSrvAuth)) Opt |= kSrvAuth;
00053 if ((Mod & kSrvNoAuth)) Opt &= ~kSrvAuth;
00054 }
00055
00056
00057 TServerSocket::TServerSocket(const char *service, Bool_t reuse, Int_t backlog,
00058 Int_t tcpwindowsize)
00059 {
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 R__ASSERT(gROOT);
00079 R__ASSERT(gSystem);
00080
00081 SetName("ServerSocket");
00082
00083 fSecContext = 0;
00084 fSecContexts = new TList;
00085
00086
00087 ResetBit(TSocket::kIsUnix);
00088 if (service && (!gSystem->AccessPathName(service) ||
00089 #ifndef WIN32
00090 service[0] == '/')) {
00091 #else
00092 service[0] == '/' || (service[1] == ':' && service[2] == '/'))) {
00093 #endif
00094 SetBit(TSocket::kIsUnix);
00095 fService = "unix:";
00096 fService += service;
00097 fSocket = gSystem->AnnounceUnixService(service, backlog);
00098 if (fSocket >= 0) {
00099 R__LOCKGUARD2(gROOTMutex);
00100 gROOT->GetListOfSockets()->Add(this);
00101 }
00102 } else {
00103
00104 fService = service;
00105 int port = gSystem->GetServiceByName(service);
00106 if (port != -1) {
00107 fSocket = gSystem->AnnounceTcpService(port, reuse, backlog, tcpwindowsize);
00108 if (fSocket >= 0) {
00109 R__LOCKGUARD2(gROOTMutex);
00110 gROOT->GetListOfSockets()->Add(this);
00111 }
00112 } else {
00113 fSocket = -1;
00114 }
00115 }
00116 }
00117
00118
00119 TServerSocket::TServerSocket(Int_t port, Bool_t reuse, Int_t backlog,
00120 Int_t tcpwindowsize)
00121 {
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 R__ASSERT(gROOT);
00142 R__ASSERT(gSystem);
00143
00144 SetName("ServerSocket");
00145
00146 fSecContext = 0;
00147 fSecContexts = new TList;
00148 fService = gSystem->GetServiceByPort(port);
00149 SetTitle(fService);
00150
00151 fSocket = gSystem->AnnounceTcpService(port, reuse, backlog, tcpwindowsize);
00152 if (fSocket >= 0) {
00153 R__LOCKGUARD2(gROOTMutex);
00154 gROOT->GetListOfSockets()->Add(this);
00155 }
00156 }
00157
00158
00159 TServerSocket::~TServerSocket()
00160 {
00161
00162
00163 R__LOCKGUARD2(gSrvAuthenticateMutex);
00164 if (fSecContexts) {
00165 if (fgSrvAuthClupHook) {
00166
00167 (*fgSrvAuthClupHook)(fSecContexts);
00168 }
00169
00170 fSecContexts->Delete();
00171 SafeDelete(fSecContexts);
00172 fSecContexts = 0;
00173 }
00174
00175 Close();
00176 }
00177
00178
00179 TSocket *TServerSocket::Accept(UChar_t Opt)
00180 {
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 if (fSocket == -1) { return 0; }
00206
00207 TSocket *socket = new TSocket;
00208
00209 Int_t soc = gSystem->AcceptConnection(fSocket);
00210 if (soc == -1) { delete socket; return 0; }
00211 if (soc == -2) { delete socket; return (TSocket*) -1; }
00212
00213
00214 UChar_t acceptOpt = fgAcceptOpt;
00215 setaccopt(acceptOpt,Opt);
00216 Bool_t auth = (Bool_t)(acceptOpt & kSrvAuth);
00217
00218 socket->fSocket = soc;
00219 socket->fSecContext = 0;
00220 socket->fService = fService;
00221 if (!TestBit(TSocket::kIsUnix))
00222 socket->fAddress = gSystem->GetPeerName(socket->fSocket);
00223 if (socket->fSocket >= 0) {
00224 R__LOCKGUARD2(gROOTMutex);
00225 gROOT->GetListOfSockets()->Add(socket);
00226 }
00227
00228
00229 if (auth) {
00230 if (!Authenticate(socket)) {
00231 delete socket;
00232 socket = 0;
00233 }
00234 }
00235
00236 return socket;
00237 }
00238
00239
00240 TInetAddress TServerSocket::GetLocalInetAddress()
00241 {
00242
00243
00244
00245
00246 if (fSocket != -1) {
00247 if (fAddress.GetPort() == -1)
00248 fAddress = gSystem->GetSockName(fSocket);
00249 return fAddress;
00250 }
00251 return TInetAddress();
00252 }
00253
00254
00255 Int_t TServerSocket::GetLocalPort()
00256 {
00257
00258
00259 if (fSocket != -1) {
00260 if (fAddress.GetPort() == -1)
00261 fAddress = GetLocalInetAddress();
00262 return fAddress.GetPort();
00263 }
00264 return -1;
00265 }
00266
00267
00268
00269 UChar_t TServerSocket::GetAcceptOptions()
00270 {
00271
00272
00273 return fgAcceptOpt;
00274 }
00275
00276
00277 void TServerSocket::SetAcceptOptions(UChar_t mod)
00278 {
00279
00280
00281
00282
00283
00284 setaccopt(fgAcceptOpt,mod);
00285 }
00286
00287
00288 void TServerSocket::ShowAcceptOptions()
00289 {
00290
00291
00292 ::Info("ShowAcceptOptions"," Auth: %d",(Bool_t)(fgAcceptOpt & kSrvAuth));
00293 }
00294
00295
00296 Bool_t TServerSocket::Authenticate(TSocket *sock)
00297 {
00298
00299
00300
00301 if (!fgSrvAuthHook) {
00302 R__LOCKGUARD2(gSrvAuthenticateMutex);
00303
00304
00305 TString srvlib = "libSrvAuth";
00306 char *p = 0;
00307
00308 if ((p = gSystem->DynamicPathName(srvlib, kTRUE))) {
00309 delete[] p;
00310 if (gSystem->Load(srvlib) == -1) {
00311 Error("Authenticate", "can't load %s",srvlib.Data());
00312 return kFALSE;
00313 }
00314 } else {
00315 Error("Authenticate", "can't locate %s",srvlib.Data());
00316 return kFALSE;
00317 }
00318
00319
00320 Func_t f = gSystem->DynFindSymbol(srvlib,"SrvAuthenticate");
00321 if (f)
00322 fgSrvAuthHook = (SrvAuth_t)(f);
00323 else {
00324 Error("Authenticate", "can't find SrvAuthenticate");
00325 return kFALSE;
00326 }
00327
00328
00329 f = gSystem->DynFindSymbol(srvlib,"SrvAuthCleanup");
00330 if (f)
00331 fgSrvAuthClupHook = (SrvClup_t)(f);
00332 else {
00333 Warning("Authenticate", "can't find SrvAuthCleanup");
00334 }
00335 }
00336
00337 TString confdir;
00338 #ifndef ROOTPREFIX
00339
00340 if (gSystem->Getenv("ROOTSYS")) {
00341 confdir = TString(gSystem->Getenv("ROOTSYS"));
00342 } else {
00343
00344 char *rootexe = gSystem->Which(gSystem->Getenv("PATH"),
00345 "root.exe", kExecutePermission);
00346 confdir = rootexe;
00347 confdir.Resize(confdir.Last('/'));
00348 delete [] rootexe;
00349 }
00350 #else
00351 confdir = TString(ROOTPREFIX);
00352 #endif
00353 if (!confdir.Length()) {
00354 Error("Authenticate", "config dir undefined");
00355 return kFALSE;
00356 }
00357
00358
00359 TString tmpdir = TString(gSystem->TempDirectory());
00360 if (gSystem->AccessPathName(tmpdir, kWritePermission))
00361 tmpdir = TString("/tmp");
00362
00363
00364 TString openhost(sock->GetInetAddress().GetHostName());
00365 if (gDebug > 2)
00366 Info("Authenticate","OpenHost = %s", openhost.Data());
00367
00368
00369 std::string user;
00370 Int_t meth = -1;
00371 Int_t auth = 0;
00372 Int_t type = 0;
00373 std::string ctkn = "";
00374 if (fgSrvAuthHook)
00375 auth = (*fgSrvAuthHook)(sock, confdir, tmpdir, user,
00376 meth, type, ctkn, fSecContexts);
00377
00378 if (gDebug > 2)
00379 Info("Authenticate","auth = %d, type= %d, ctkn= %s",
00380 auth, type, ctkn.c_str());
00381
00382 return auth;
00383 }