00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <string.h>
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 #include <signal.h>
00026 #include <sys/socket.h>
00027 #include <netinet/in.h>
00028 #include <netinet/tcp.h>
00029 #include <arpa/inet.h>
00030 #include <netdb.h>
00031 #include <errno.h>
00032
00033 #if defined(linux)
00034 # include <features.h>
00035 # if __GNU_LIBRARY__ == 6
00036 # ifndef R__GLIBC
00037 # define R__GLIBC
00038 # endif
00039 # endif
00040 #endif
00041 #if defined(__MACH__) && !defined(__APPLE__)
00042 # define R__GLIBC
00043 #endif
00044
00045 #ifdef __sun
00046 # ifndef _REENTRANT
00047 # if __SUNPRO_CC > 0x420
00048 # define GLOBAL_ERRNO
00049 # endif
00050 # endif
00051 #endif
00052
00053 #include "Rtypes.h"
00054 #include "Varargs.h"
00055 #include "DaemonUtils.h"
00056 #include "TAuthenticate.h"
00057 #include "TSecContext.h"
00058 #include "TEnv.h"
00059 #include "TROOT.h"
00060
00061
00062
00063
00064 static TSocket *gSocket;
00065
00066
00067
00068
00069 static Int_t gSrvProtocol = 1;
00070 static EService gService = kSOCKD;
00071 static Int_t gReuseAllow = 0x1F;
00072
00073 using namespace std;
00074 using namespace ROOT;
00075
00076 extern "C" {
00077 Int_t SrvAuthenticate(TSocket *socket,
00078 const char *confdir, const char *tmpdir,
00079 string &user, Int_t &meth, Int_t &type, string &ctkn,
00080 TSeqCollection *secctxlist) {
00081 return SrvAuthImpl(socket, confdir, tmpdir, user, meth, type, ctkn, secctxlist);
00082 }
00083 }
00084
00085 extern "C" {
00086 Int_t SrvAuthCleanup(TSeqCollection *sls) {
00087 return SrvClupImpl(sls);
00088 }
00089 }
00090
00091
00092 static Int_t SrvSetVars(string confdir)
00093 {
00094
00095
00096
00097
00098 string execdir, etcdir;
00099 #ifdef ROOTBINDIR
00100 execdir = string(ROOTBINDIR);
00101 #endif
00102 #ifdef ROOTETCDIR
00103 etcdir = string(ROOTETCDIR);
00104 #endif
00105
00106
00107 if (!execdir.length())
00108 execdir = string(confdir).append("/bin");
00109
00110 if (execdir.length()) {
00111 int len = 15 + execdir.length();
00112 char *tmp = new char[len+1];
00113 if (tmp) {
00114 snprintf(tmp,len+1, "ROOTBINDIR=%.*s", len, execdir.c_str());
00115 putenv(tmp);
00116 } else
00117 return -1;
00118 }
00119
00120
00121 if (!etcdir.length())
00122 etcdir = string(confdir).append("/etc");
00123
00124 if (etcdir.length()) {
00125 int len = 15 + etcdir.length();
00126 char *tmp = new char[len+1];
00127 if (tmp) {
00128 snprintf(tmp, len+1, "ROOTETCDIR=%.*s", len, etcdir.c_str());
00129 putenv(tmp);
00130 } else
00131 return -1;
00132 }
00133
00134
00135 string daemonrc = string(gEnv->GetValue("SrvAuth.DaemonRc",""));
00136 if (daemonrc.length()) {
00137 int len = 15 + daemonrc.length();
00138 char *tmp = new char[len+1];
00139 if (tmp) {
00140 snprintf(tmp, len+1, "ROOTDAEMONRC=%.*s", len, daemonrc.c_str());
00141 putenv(tmp);
00142 } else
00143 return -1;
00144 }
00145
00146
00147 string gridmap = string(gEnv->GetValue("SrvAuth.GridMap",""));
00148 if (gridmap.length()) {
00149 int len = 15 + gridmap.length();
00150 char *tmp = new char[len+1];
00151 if (tmp) {
00152 snprintf(tmp, len+1, "GRIDMAP=%.*s", len, gridmap.c_str());
00153 putenv(tmp);
00154 } else
00155 return -1;
00156 }
00157
00158
00159 string hcconf = string(gEnv->GetValue("SrvAuth.HostCert",""));
00160 if (hcconf.length()) {
00161 int len = 15 + hcconf.length();
00162 char *tmp = new char[len+1];
00163 if (tmp) {
00164 snprintf(tmp, len+1, "ROOTHOSTCERT=%.*s", len, hcconf.c_str());
00165 putenv(tmp);
00166 } else
00167 return -1;
00168 }
00169
00170 return 0;
00171 }
00172
00173
00174
00175 void Err(int level, const char *msg, int size)
00176 {
00177 Perror((char *)msg, size);
00178 if (level > -1) NetSend(level, kROOTD_ERR);
00179 }
00180
00181
00182 void ErrFatal(int level, const char *msg, int size)
00183 {
00184 Perror((char *)msg, size);
00185 if (level > -1) NetSend(msg, kMESS_STRING);
00186 }
00187
00188
00189 void ErrSys(int level, const char *msg, int size)
00190 {
00191 Perror((char *)msg, size);
00192 ErrFatal(level, msg, size);
00193 }
00194
00195
00196 Int_t SrvClupImpl(TSeqCollection *secls)
00197 {
00198
00199 TIter next(secls);
00200 TSecContext *nsc ;
00201 while ((nsc = (TSecContext *)next())) {
00202 if (!strncmp(nsc->GetID(),"server",6)) {
00203 int rc = RpdCleanupAuthTab(nsc->GetToken());
00204 if (gDebug > 0 && rc < 0)
00205 ErrorInfo("SrvClupImpl: operation unsuccessful (rc: %d, ctkn: %s)",
00206 rc, nsc->GetToken());
00207 }
00208 }
00209 return 0;
00210 }
00211
00212
00213 Int_t SrvAuthImpl(TSocket *socket, const char *confdir, const char *tmpdir,
00214 string &user, Int_t &meth, Int_t &type, string &ctoken,
00215 TSeqCollection *secctxlist)
00216 {
00217
00218
00219
00220
00221 Int_t rc = 0;
00222
00223
00224 Bool_t hequiv = gEnv->GetValue("SrvAuth.CheckHostsEquivalence",0);
00225
00226
00227 string altSRPpass = string(gEnv->GetValue("SrvAuth.SRPpassfile",""));
00228
00229
00230 Int_t sshdport = gEnv->GetValue("SrvAuth.SshdPort",22);
00231
00232
00233 if (SrvSetVars(string(confdir)) == -1)
00234
00235 return rc;
00236
00237
00238 int parentid = getpid();
00239
00240
00241 unsigned int options = kDMN_RQAUTH | kDMN_HOSTEQ;
00242 if (!hequiv)
00243 options &= ~kDMN_HOSTEQ;
00244
00245
00246 RpdSetErrorHandler(Err, ErrSys, ErrFatal);
00247
00248
00249 RpdInit(gService, parentid, gSrvProtocol, options,
00250 gReuseAllow, sshdport,
00251 tmpdir, altSRPpass.c_str());
00252
00253
00254 if (RpdGenRSAKeys(0))
00255
00256 return rc;
00257
00258
00259 RpdSetMethInitFlag(0);
00260
00261
00262 SrvSetSocket(socket);
00263
00264
00265
00266
00267 int clientprotocol = 0;
00268 rc = RpdInitSession(gService, user, clientprotocol, meth, type, ctoken);
00269
00270 TSecContext *seccontext = 0;
00271 if (rc > 0) {
00272 string openhost(socket->GetInetAddress().GetHostName());
00273
00274 if (type == 1) {
00275
00276
00277 TIter next(gROOT->GetListOfSecContexts());
00278 while ((seccontext = (TSecContext *)next())) {
00279 if (!(strncmp(seccontext->GetID(),"server",6))) {
00280 if (seccontext->GetMethod() == meth) {
00281 if (!strcmp(openhost.c_str(),seccontext->GetHost())) {
00282 if (!strcmp(user.c_str(),seccontext->GetUser()))
00283 break;
00284 }
00285 }
00286 }
00287 }
00288 }
00289
00290 if (!seccontext) {
00291
00292
00293 seccontext = new TSecContext(user.c_str(), openhost.c_str(), meth, -1,
00294 "server", ctoken.c_str());
00295 if (seccontext) {
00296
00297 secctxlist->Add(seccontext);
00298
00299 socket->SetSecContext(seccontext);
00300 } else {
00301 if (gDebug > 0)
00302 ErrorInfo("SrvAuthImpl: could not create sec context object"
00303 ": potential problems in cleaning");
00304 }
00305 }
00306 }
00307
00308
00309
00310 return rc;
00311 }
00312
00313
00314 namespace ROOT {
00315
00316 static int gSockFd = -1;
00317
00318
00319 void SrvSetSocket(TSocket *Socket)
00320 {
00321
00322
00323 gSocket = Socket;
00324 gSockFd = Socket->GetDescriptor();
00325 }
00326
00327
00328 static int Recvn(int sock, void *buffer, int length)
00329 {
00330
00331
00332
00333 if (sock < 0) return -1;
00334
00335 int n, nrecv = 0;
00336 char *buf = (char *)buffer;
00337
00338 for (n = 0; n < length; n += nrecv) {
00339 while ((nrecv = recv(sock, buf+n, length-n, 0)) == -1
00340 && GetErrno() == EINTR)
00341 ResetErrno();
00342 if (nrecv < 0) {
00343 Error(gErrFatal,-1,
00344 "Recvn: error (sock: %d): errno: %d",sock,GetErrno());
00345 return nrecv;
00346 } else if (nrecv == 0)
00347 break;
00348 }
00349
00350 return n;
00351 }
00352
00353
00354 void NetClose()
00355 {
00356
00357 return;
00358 }
00359
00360
00361 int NetGetSockFd()
00362 {
00363
00364 return gSockFd;
00365 }
00366
00367
00368 int NetParOpen(int port, int size)
00369 {
00370
00371 if (port+size)
00372 return (port+size);
00373 else
00374 return 1;
00375 }
00376
00377
00378 int NetRecv(char *msg, int max)
00379 {
00380
00381
00382 return gSocket->Recv(msg, max);
00383 }
00384
00385
00386 int NetRecv(char *msg, int len, EMessageTypes &kind)
00387 {
00388
00389
00390
00391 Int_t tmpkind;
00392 Int_t rc = gSocket->Recv(msg, len, tmpkind);
00393 kind = (EMessageTypes)tmpkind;
00394 return rc;
00395 }
00396
00397
00398 int NetRecv(void *&buf, int &len, EMessageTypes &kind)
00399 {
00400
00401
00402
00403 int hdr[2];
00404
00405 if (NetRecvRaw(hdr, sizeof(hdr)) < 0)
00406 return -1;
00407
00408 len = ntohl(hdr[0]) - sizeof(int);
00409 kind = (EMessageTypes) ntohl(hdr[1]);
00410 if (len) {
00411 buf = new char* [len];
00412 return NetRecvRaw(buf, len);
00413 }
00414 buf = 0;
00415 return 0;
00416
00417 }
00418
00419
00420 int NetRecvRaw(void *buf, int len)
00421 {
00422
00423
00424 return gSocket->RecvRaw(buf,len);
00425 }
00426
00427
00428 int NetRecvRaw(int sock, void *buf, int len)
00429 {
00430
00431
00432 if (sock == -1) return -1;
00433
00434 if (Recvn(sock, buf, len) < 0) {
00435 Error(gErrFatal,-1,
00436 "NetRecvRaw: Recvn error (sock: %d, errno: %d)",sock,GetErrno());
00437 }
00438
00439 return len;
00440 }
00441
00442
00443 int NetSend(int code, EMessageTypes kind)
00444 {
00445
00446
00447 int hdr[3];
00448 int hlen = sizeof(int) + sizeof(int);
00449 hdr[0] = htonl(hlen);
00450 hdr[1] = htonl(kind);
00451 hdr[2] = htonl(code);
00452
00453 return gSocket->SendRaw(hdr, sizeof(hdr));
00454 }
00455
00456
00457 int NetSend(const char *msg, EMessageTypes kind)
00458 {
00459
00460
00461 return gSocket->Send(msg, kind);
00462 }
00463
00464
00465 int NetSend(const void *buf, int len, EMessageTypes kind)
00466 {
00467
00468
00469 int hdr[2];
00470 int hlen = sizeof(int) + len;
00471 hdr[0] = htonl(hlen);
00472 hdr[1] = htonl(kind);
00473 if (gSocket->SendRaw(hdr, sizeof(hdr)) < 0)
00474 return -1;
00475
00476 return gSocket->SendRaw(buf, len);
00477 }
00478
00479
00480 int NetSendAck()
00481 {
00482
00483
00484 return NetSend(0, kROOTD_ACK);
00485 }
00486
00487
00488 int NetSendError(ERootdErrors err)
00489 {
00490
00491
00492 return NetSend(err, kROOTD_ERR);
00493 }
00494
00495
00496 int NetSendRaw(const void *buf, int len)
00497 {
00498
00499
00500 return gSocket->SendRaw(buf, len);
00501 }
00502
00503
00504 void NetGetRemoteHost(std::string &openhost)
00505 {
00506
00507
00508
00509 openhost = string(gSocket->GetInetAddress().GetHostName());
00510 }
00511
00512
00513 int GetErrno()
00514 {
00515
00516 #ifdef GLOBAL_ERRNO
00517 return ::errno;
00518 #else
00519 return errno;
00520 #endif
00521 }
00522
00523 void ResetErrno()
00524 {
00525
00526 #ifdef GLOBAL_ERRNO
00527 ::errno = 0;
00528 #else
00529 errno = 0;
00530 #endif
00531 }
00532
00533
00534 void Perror(char *buf, int size)
00535 {
00536
00537
00538 int len = strlen(buf);
00539 #if (defined(__sun) && defined (__SVR4)) || defined (__linux) || \
00540 defined(_AIX) || defined(__MACH__)
00541 snprintf(buf+len, size, " (%s)", strerror(GetErrno()));
00542 #else
00543 if (GetErrno() >= 0 && GetErrno() < sys_nerr)
00544 snprintf(buf+len, size, " (%s)", sys_errlist[GetErrno()]);
00545 #endif
00546 }
00547
00548
00549 void ErrorInfo(const char *va_(fmt), ...)
00550 {
00551
00552
00553
00554
00555 char buf[1024];
00556 va_list ap;
00557 va_start(ap,va_(fmt));
00558 vsprintf(buf, fmt, ap);
00559 va_end(ap);
00560 printf("%s\n", buf);
00561 fflush(stdout);
00562 }
00563
00564
00565 void Error(ErrorHandler_t func,int code,const char *va_(fmt), ...)
00566 {
00567
00568
00569 char buf[1024];
00570 va_list ap;
00571 va_start(ap,va_(fmt));
00572 vsprintf(buf, fmt, ap);
00573 va_end(ap);
00574 printf("%s\n", buf);
00575 fflush(stdout);
00576
00577
00578
00579 if (func) (*func)(code,(const char *)buf, sizeof(buf));
00580 }
00581
00582 }