00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "RConfigure.h"
00022
00023 #include "TAuthenticate.h"
00024 #include "TApplication.h"
00025 #include "THostAuth.h"
00026 #include "TRootSecContext.h"
00027 #include "TPluginManager.h"
00028 #include "TNetFile.h"
00029 #include "TPSocket.h"
00030 #include "TMessage.h"
00031 #include "TSystem.h"
00032 #include "TError.h"
00033 #include "Getline.h"
00034 #include "TROOT.h"
00035 #include "TEnv.h"
00036 #include "TList.h"
00037 #include "NetErrors.h"
00038 #include "TRegexp.h"
00039 #include "TVirtualMutex.h"
00040 #include "TTimer.h"
00041 #include "TBase64.h"
00042
00043 #ifndef R__LYNXOS
00044 #include <sys/stat.h>
00045 #endif
00046 #include <errno.h>
00047 #include <sys/types.h>
00048 #include <time.h>
00049 #if !defined(R__WIN32) && !defined(R__MACOSX) && !defined(R__FBSD) && \
00050 !defined(R__OBSD)
00051 #include <crypt.h>
00052 #endif
00053 #ifdef WIN32
00054 # include <io.h>
00055 #endif
00056 #if defined(R__LINUX) || defined(R__FBSD) || defined(R__OBSD)
00057 # include <unistd.h>
00058 #endif
00059 #include <stdlib.h>
00060 #ifndef WIN32
00061 # include <sys/time.h>
00062 #endif
00063
00064 #if defined(R__ALPHA) || defined(R__SGI) || defined(R__MACOSX)
00065 extern "C" char *crypt(const char *, const char *);
00066 #endif
00067
00068 #ifdef R__GLBS
00069 # include <sys/ipc.h>
00070 # include <sys/shm.h>
00071 #endif
00072
00073 #ifdef R__SSL
00074
00075 # include <openssl/bio.h>
00076 # include <openssl/err.h>
00077 # include <openssl/pem.h>
00078 # include <openssl/rand.h>
00079 # include <openssl/rsa.h>
00080 # include <openssl/ssl.h>
00081 #endif
00082
00083
00084 TList *TAuthenticate::fgAuthInfo = 0;
00085 TString TAuthenticate::fgAuthMeth[] = { "UsrPwd", "SRP", "Krb5",
00086 "Globus", "SSH", "UidGid" };
00087 Bool_t TAuthenticate::fgAuthReUse;
00088 TString TAuthenticate::fgDefaultUser;
00089 TDatime TAuthenticate::fgExpDate;
00090 GlobusAuth_t TAuthenticate::fgGlobusAuthHook;
00091 Krb5Auth_t TAuthenticate::fgKrb5AuthHook;
00092 TString TAuthenticate::fgKrb5Principal;
00093 TDatime TAuthenticate::fgLastAuthrc;
00094 TString TAuthenticate::fgPasswd;
00095 TPluginHandler *TAuthenticate::fgPasswdDialog = (TPluginHandler *)(-1);
00096 Bool_t TAuthenticate::fgPromptUser;
00097 TList *TAuthenticate::fgProofAuthInfo = 0;
00098 Bool_t TAuthenticate::fgPwHash;
00099 Bool_t TAuthenticate::fgReadHomeAuthrc = kTRUE;
00100 TString TAuthenticate::fgRootAuthrc;
00101 Int_t TAuthenticate::fgRSAKey = -1;
00102 Int_t TAuthenticate::fgRSAInit = 0;
00103 rsa_KEY TAuthenticate::fgRSAPriKey;
00104 rsa_KEY_export TAuthenticate::fgRSAPubExport[2] = {{0,0},{0,0}};
00105 rsa_KEY TAuthenticate::fgRSAPubKey;
00106 #ifdef R__SSL
00107 BF_KEY TAuthenticate::fgBFKey;
00108 #endif
00109 SecureAuth_t TAuthenticate::fgSecAuthHook;
00110 Bool_t TAuthenticate::fgSRPPwd;
00111 TString TAuthenticate::fgUser;
00112 Bool_t TAuthenticate::fgUsrPwdCrypt;
00113 Int_t TAuthenticate::fgLastError = -1;
00114 Int_t TAuthenticate::fgAuthTO = -2;
00115
00116
00117 Int_t TAuthenticate::fgProcessID = -1;
00118
00119 TVirtualMutex *gAuthenticateMutex = 0;
00120
00121
00122 Int_t StdCheckSecCtx(const char *, TRootSecContext *);
00123
00124
00125 ClassImp(TAuthenticate)
00126
00127
00128 static int auth_rand()
00129 {
00130
00131
00132 #ifndef WIN32
00133 int frnd = open("/dev/urandom", O_RDONLY);
00134 if (frnd < 0) frnd = open("/dev/random", O_RDONLY);
00135 int r;
00136 if (frnd >= 0) {
00137 ssize_t rs = read(frnd, (void *) &r, sizeof(int));
00138 close(frnd);
00139 if (r < 0) r = -r;
00140 if (rs == sizeof(int)) return r;
00141 }
00142 Printf("+++ERROR+++ : auth_rand: neither /dev/urandom nor /dev/random are available or readable!");
00143 struct timeval tv;
00144 if (gettimeofday(&tv,0) == 0) {
00145 int t1, t2;
00146 memcpy((void *)&t1, (void *)&tv.tv_sec, sizeof(int));
00147 memcpy((void *)&t2, (void *)&tv.tv_usec, sizeof(int));
00148 r = t1 + t2;
00149 if (r < 0) r = -r;
00150 return r;
00151 }
00152 return -1;
00153 #else
00154
00155 return rand();
00156 #endif
00157 }
00158
00159
00160 TAuthenticate::TAuthenticate(TSocket *sock, const char *remote,
00161 const char *proto, const char *user)
00162 {
00163
00164
00165 if (gDebug > 2 && gAuthenticateMutex)
00166 Info("Authenticate", "locking mutex (pid: %d)",gSystem->GetPid());
00167 R__LOCKGUARD2(gAuthenticateMutex);
00168
00169
00170 if (gROOT->IsProofServ())
00171 ProofAuthSetup();
00172
00173
00174 if (fgProcessID < 0)
00175 fgProcessID = gSystem->GetPid();
00176
00177 if (fgAuthTO == -2)
00178 fgAuthTO = gEnv->GetValue("Auth.Timeout",-1);
00179
00180 fSocket = sock;
00181 fRemote = remote;
00182 fHostAuth = 0;
00183 fVersion = 5;
00184 fSecContext = 0;
00185
00186 if (gDebug > 2)
00187 Info("TAuthenticate", "Enter: local host: %s, user is: %s (proto: %s)",
00188 gSystem->HostName(), user, proto);
00189
00190
00191
00192 char *pdd;
00193 Int_t servtype = TSocket::kSOCKD;
00194 if (proto && strlen(proto) > 0) {
00195 char *sproto = StrDup(proto);
00196 if ((pdd = strstr(sproto, ":")) != 0) {
00197 int rproto = atoi(pdd + 1);
00198 *pdd = '\0';
00199 if (strstr(sproto, "root") != 0) {
00200 if (rproto < 12 ) {
00201 fVersion = 4;
00202 if (rproto < 11 ) {
00203 fVersion = 3;
00204 if (rproto < 9 ) {
00205 fVersion = 2;
00206 if (rproto < 8) {
00207 fVersion = 1;
00208 if (rproto < 6)
00209 fVersion = 0;
00210 }
00211 }
00212 }
00213 }
00214 servtype = TSocket::kROOTD;
00215 }
00216 if (strstr(sproto, "proof") != 0) {
00217 if (rproto < 11) {
00218 fVersion = 4;
00219 if (rproto < 10) {
00220 fVersion = 3;
00221 if (rproto < 8) {
00222 fVersion = 2;
00223 if (rproto < 7)
00224 fVersion = 1;
00225 }
00226 }
00227 }
00228 servtype = TSocket::kPROOFD;
00229 }
00230 if (gDebug > 3)
00231 Info("TAuthenticate",
00232 "service: %s (remote protocol: %d): fVersion: %d", sproto,
00233 rproto, fVersion);
00234 }
00235 fProtocol = sproto;
00236 delete [] sproto;
00237 }
00238
00239
00240 fUser = "";
00241 TString checkUser;
00242 if (user && strlen(user) > 0) {
00243 fUser = user;
00244 checkUser = user;
00245 } else {
00246 UserGroup_t *u = gSystem->GetUserInfo();
00247 if (u)
00248 checkUser = u->fUser;
00249 delete u;
00250 }
00251 fPasswd = "";
00252 fPwHash = kFALSE;
00253 fSRPPwd = kFALSE;
00254
00255
00256 if (fgRSAKey < 0) {
00257 fgRSAKey = 0;
00258 #if R__SSL
00259
00260 if (gEnv->GetValue("RSA.KeyType",0) == 1)
00261 fgRSAKey = 1;
00262 #endif
00263 }
00264
00265
00266 fRSAKey = fgRSAKey;
00267 if (gDebug > 3)
00268 Info("TAuthenticate","RSA key: default type %d", fgRSAKey);
00269
00270
00271 if (!fgRSAInit) {
00272 GenRSAKeys();
00273 fgRSAInit = 1;
00274 }
00275
00276
00277 TString fqdn;
00278 TInetAddress addr = gSystem->GetHostByName(fRemote);
00279 if (addr.IsValid())
00280 fqdn = addr.GetHostName();
00281 TString fqdnsrv(Form("%s:%d",fqdn.Data(),servtype));
00282
00283
00284 TAuthenticate::ReadRootAuthrc();
00285
00286 if (gDebug > 3) {
00287 Info("TAuthenticate",
00288 "number of HostAuth Instantiations in memory: %d",
00289 GetAuthInfo()->GetSize());
00290 TAuthenticate::Show("H");
00291 TAuthenticate::Show("P");
00292 }
00293
00294
00295 fHostAuth = GetHostAuth(fqdnsrv, checkUser);
00296
00297
00298
00299
00300 if (!fHostAuth) {
00301
00302 TString tmp;
00303 if (fProtocol.Contains("proof")) {
00304 tmp = TString(gEnv->GetValue("Proofd.Authentication", "0"));
00305 } else if (fProtocol.Contains("root")) {
00306 tmp = TString(gEnv->GetValue("Rootd.Authentication", "0"));
00307 }
00308 char am[kMAXSEC][10];
00309 Int_t nw = sscanf(tmp.Data(), "%5s %5s %5s %5s %5s %5s",
00310 am[0], am[1], am[2], am[3], am[4], am[5]);
00311
00312 Int_t i = 0, nm = 0, me[kMAXSEC];
00313 for( ; i < nw; i++) {
00314 Int_t met = -1;
00315 if (strlen(am[i]) > 1) {
00316 met = GetAuthMethodIdx(am[i]);
00317 } else {
00318 met = atoi(am[i]);
00319 }
00320 if (met > -1 && met < kMAXSEC) {
00321 me[nm++] = met;
00322 }
00323 }
00324
00325
00326 if (nm)
00327 fHostAuth = new THostAuth(fRemote,fUser,nm,me,0);
00328 else
00329 fHostAuth = new THostAuth(fRemote,fUser,0,(const char *)0);
00330 }
00331
00332
00333
00334
00335 if (strchr(fHostAuth->GetHost(),'*') || strchr(fHostAuth->GetHost(),'*') ||
00336 fHostAuth->GetServer() == -1 ) {
00337 fHostAuth = new THostAuth(*fHostAuth);
00338 fHostAuth->SetHost(fqdn);
00339 fHostAuth->SetUser(checkUser);
00340 fHostAuth->SetServer(servtype);
00341 }
00342
00343
00344
00345 Int_t sec = -1;
00346 TString tmp = fProtocol;
00347 tmp.ReplaceAll("root",4,"",0);
00348 tmp.ReplaceAll("proof",5,"",0);
00349 tmp.ReplaceAll("sock",4,"",0);
00350 if (!strncmp(tmp.Data(),"up",2))
00351 sec = 0;
00352 else if (!strncmp(tmp.Data(),"s",1))
00353 sec = 1;
00354 else if (!strncmp(tmp.Data(),"k",1))
00355 sec = 2;
00356 else if (!strncmp(tmp.Data(),"g",1))
00357 sec = 3;
00358 else if (!strncmp(tmp.Data(),"h",1))
00359 sec = 4;
00360 else if (!strncmp(tmp.Data(),"ug",2))
00361 sec = 5;
00362 if (sec > -1 && sec < kMAXSEC) {
00363 if (fHostAuth->HasMethod(sec)) {
00364 fHostAuth->SetFirst(sec);
00365 } else {
00366 char *dtmp = GetDefaultDetails(sec, 1, checkUser);
00367 TString det(dtmp);
00368 fHostAuth->AddFirst(sec, det);
00369 if (dtmp)
00370 delete [] dtmp;
00371 }
00372 }
00373
00374
00375 if (gDebug > 3) {
00376 TIter next(fHostAuth->Established());
00377 TRootSecContext *ctx;
00378 while ((ctx = (TRootSecContext *) next()))
00379 ctx->Print("0");
00380 }
00381 }
00382
00383
00384 void TAuthenticate::CatchTimeOut()
00385 {
00386
00387
00388 Info("CatchTimeOut", "%d sec timeout expired (protocol: %s)",
00389 fgAuthTO, fgAuthMeth[fSecurity].Data());
00390
00391 fTimeOut = 1;
00392 if (fSocket)
00393 fSocket->Close("force");
00394
00395 return;
00396 }
00397
00398
00399 Bool_t TAuthenticate::Authenticate()
00400 {
00401
00402
00403
00404 if (gDebug > 2 && gAuthenticateMutex)
00405 Info("Authenticate", "locking mutex (pid: %d)",gSystem->GetPid());
00406 R__LOCKGUARD2(gAuthenticateMutex);
00407
00408 Bool_t rc = kFALSE;
00409 Int_t st = -1;
00410 Int_t remMeth = 0, rMth[kMAXSEC], tMth[kMAXSEC] = {0};
00411 Int_t meth = 0;
00412 char noSupport[80] = { 0 };
00413 char triedMeth[80] = { 0 };
00414 Int_t ntry = 0;
00415
00416 TString user, passwd;
00417 Bool_t pwhash;
00418
00419 if (gDebug > 2)
00420 Info("Authenticate", "enter: fUser: %s", fUser.Data());
00421
00422
00423
00424 TTimer *alarm = 0;
00425 if (fgAuthTO > 0) {
00426 alarm = new TTimer(0, kFALSE);
00427 alarm->SetInterruptSyscalls();
00428
00429 alarm->Connect("Timeout()", "TAuthenticate", this, "CatchTimeOut()");
00430 }
00431
00432 negotia:
00433 st = -1;
00434 tMth[meth] = 1;
00435 ntry++;
00436 if (gDebug > 2)
00437 Info("Authenticate", "try #: %d", ntry);
00438
00439 user = "";
00440 passwd = "";
00441 pwhash = kFALSE;
00442
00443
00444 fSecurity = (ESecurity) fHostAuth->GetMethod(meth);
00445 fDetails = fHostAuth->GetDetails((Int_t) fSecurity);
00446 if (gDebug > 2)
00447 Info("Authenticate",
00448 "trying authentication: method:%d, default details:%s",
00449 fSecurity, fDetails.Data());
00450
00451
00452 if (strlen(triedMeth) > 0)
00453 snprintf(triedMeth, 80, "%s %s", triedMeth, fgAuthMeth[fSecurity].Data());
00454 else
00455 snprintf(triedMeth, 80, "%s", fgAuthMeth[fSecurity].Data());
00456
00457
00458 SetEnvironment();
00459
00460 st = -1;
00461
00462
00463
00464 fTimeOut = 0;
00465 if (fgAuthTO > 0 && alarm) {
00466 alarm->Start(fgAuthTO*1000, kTRUE);
00467 }
00468
00469
00470 if (fSecurity == kClear) {
00471
00472 rc = kFALSE;
00473
00474
00475 user = fgDefaultUser;
00476 if (user != "")
00477 CheckNetrc(user, passwd, pwhash, kFALSE);
00478 if (passwd == "") {
00479 if (fgPromptUser)
00480 user = PromptUser(fRemote);
00481 rc = GetUserPasswd(user, passwd, pwhash, kFALSE);
00482 }
00483 fUser = user;
00484 fPasswd = passwd;
00485
00486 if (!rc) {
00487
00488 if (fUser != "root")
00489 st = ClearAuth(user, passwd, pwhash);
00490 } else {
00491 Error("Authenticate",
00492 "unable to get user name for UsrPwd authentication");
00493 }
00494
00495 } else if (fSecurity == kSRP) {
00496
00497 rc = kFALSE;
00498
00499
00500 user = fgDefaultUser;
00501 if (user != "")
00502 CheckNetrc(user, passwd, pwhash, kTRUE);
00503 if (passwd == "") {
00504 if (fgPromptUser)
00505 user = PromptUser(fRemote);
00506 rc = GetUserPasswd(user, passwd, pwhash, kTRUE);
00507 }
00508 fUser = user;
00509 fPasswd = passwd;
00510
00511 if (!fgSecAuthHook) {
00512
00513 char *p;
00514 TString lib = "libSRPAuth";
00515 if ((p = gSystem->DynamicPathName(lib, kTRUE))) {
00516 delete [] p;
00517 gSystem->Load(lib);
00518 }
00519 }
00520 if (!rc && fgSecAuthHook) {
00521
00522 st = (*fgSecAuthHook) (this, user, passwd, fRemote, fDetails,
00523 fVersion);
00524 } else {
00525 if (!fgSecAuthHook)
00526 Error("Authenticate",
00527 "no support for SRP authentication available");
00528 if (rc)
00529 Error("Authenticate",
00530 "unable to get user name for SRP authentication");
00531 }
00532
00533 if (st == 1) {
00534 fPwHash = kFALSE;
00535 fSRPPwd = kTRUE;
00536 }
00537
00538 } else if (fSecurity == kKrb5) {
00539
00540 if (fVersion > 0) {
00541
00542
00543 if (!fgKrb5AuthHook) {
00544 char *p;
00545 TString lib = "libKrb5Auth";
00546 if ((p = gSystem->DynamicPathName(lib, kTRUE))) {
00547 delete [] p;
00548 gSystem->Load(lib);
00549 }
00550 }
00551 if (fgKrb5AuthHook) {
00552 fUser = fgDefaultUser;
00553 st = (*fgKrb5AuthHook) (this, fUser, fDetails, fVersion);
00554 } else {
00555 Error("Authenticate",
00556 "support for kerberos5 auth locally unavailable");
00557 }
00558 } else {
00559 if (gDebug > 0)
00560 Info("Authenticate",
00561 "remote daemon does not support Kerberos authentication");
00562 if (strlen(noSupport) > 0)
00563 snprintf(noSupport, 80, "%s/Krb5", noSupport);
00564 else
00565 snprintf(noSupport, 80, "Krb5");
00566 }
00567
00568 } else if (fSecurity == kGlobus) {
00569 if (fVersion > 1) {
00570
00571
00572 if (!fgGlobusAuthHook) {
00573 char *p;
00574 TString lib = "libGlobusAuth";
00575 if ((p = gSystem->DynamicPathName(lib, kTRUE))) {
00576 delete [] p;
00577 gSystem->Load(lib);
00578 }
00579 }
00580 if (fgGlobusAuthHook) {
00581 st = (*fgGlobusAuthHook) (this, fUser, fDetails);
00582 } else {
00583 Error("Authenticate",
00584 "no support for Globus authentication available");
00585 }
00586 } else {
00587 if (gDebug > 0)
00588 Info("Authenticate",
00589 "remote daemon does not support Globus authentication");
00590 if (strlen(noSupport) > 0)
00591 snprintf(noSupport, 80, "%s/Globus", noSupport);
00592 else
00593 snprintf(noSupport, 80, "Globus");
00594 }
00595
00596
00597 } else if (fSecurity == kSSH) {
00598
00599 if (fVersion > 1) {
00600
00601
00602 st = SshAuth(fUser);
00603
00604 } else {
00605 if (gDebug > 0)
00606 Info("Authenticate",
00607 "remote daemon does not support SSH authentication");
00608 if (strlen(noSupport) > 0)
00609 snprintf(noSupport, 80, "%s/SSH", noSupport);
00610 else
00611 snprintf(noSupport, 80, "SSH");
00612 }
00613
00614 } else if (fSecurity == kRfio) {
00615
00616 if (fVersion > 1) {
00617
00618
00619 st = RfioAuth(fUser);
00620
00621 } else {
00622 if (gDebug > 0)
00623 Info("Authenticate",
00624 "remote daemon does not support UidGid authentication");
00625 if (strlen(noSupport) > 0)
00626 snprintf(noSupport, 80, "%s/UidGid", noSupport);
00627 else
00628 snprintf(noSupport, 80, "UidGid");
00629 }
00630 }
00631
00632
00633 if (alarm) alarm->Stop();
00634
00635
00636 st = (fTimeOut > 0) ? -3 : st;
00637
00638
00639
00640
00641
00642
00643 Int_t action = 0;
00644 Int_t nmet = fHostAuth->NumMethods();
00645 Int_t remloc = nmet - ntry;
00646 if (gDebug > 0)
00647 Info("Authenticate","remloc: %d, ntry: %d, meth: %d, fSecurity: %d",
00648 remloc, ntry, meth, fSecurity);
00649 Int_t kind, stat;
00650 switch (st) {
00651
00652 case 1:
00653
00654
00655 fHostAuth->CountSuccess((Int_t)fSecurity);
00656 if (gDebug > 2)
00657 fSecContext->Print();
00658 if (fSecContext->IsActive())
00659 fSecContext->AddForCleanup(fSocket->GetPort(),
00660 fSocket->GetRemoteProtocol(),fSocket->GetServType());
00661 rc = kTRUE;
00662 break;
00663
00664 case 0:
00665
00666
00667 fHostAuth->CountFailure((Int_t)fSecurity);
00668 if (fVersion < 2) {
00669
00670
00671 if (gDebug > 2)
00672 Info("Authenticate",
00673 "negotiation not supported remotely: try next method, if any");
00674 if (meth < nmet - 1) {
00675 meth++;
00676 action = 1;
00677 } else {
00678 action = 2;
00679 }
00680 rc = kFALSE;
00681 break;
00682 }
00683
00684
00685 if (fSocket->Recv(stat, kind) < 0) {
00686 action = 0;
00687 rc = kFALSE;
00688 }
00689 if (gDebug > 2)
00690 Info("Authenticate",
00691 "after failed attempt: kind= %d, stat= %d", kind, stat);
00692 if (kind == kROOTD_ERR) {
00693 action = 2;
00694 rc = kFALSE;
00695 } else if (kind == kROOTD_NEGOTIA) {
00696 if (stat > 0) {
00697 int len = 3 * stat;
00698 char *answer = new char[len];
00699 int nrec = fSocket->Recv(answer, len, kind);
00700 if (nrec < 0) {
00701 action = 0;
00702 rc = kFALSE;
00703 break;
00704 }
00705 if (kind != kMESS_STRING)
00706 Warning("Authenticate",
00707 "strings with accepted methods not received (%d:%d)",
00708 kind, nrec);
00709 remMeth =
00710 sscanf(answer, "%d %d %d %d %d %d", &rMth[0], &rMth[1],
00711 &rMth[2], &rMth[3], &rMth[4], &rMth[5]);
00712 if (gDebug > 0 && remloc > 0)
00713 Info("Authenticate",
00714 "remotely allowed methods not yet tried: %s",
00715 answer);
00716 delete[] answer;
00717 } else if (stat == 0) {
00718 Info("Authenticate",
00719 "no more methods accepted remotely to be tried");
00720 action = 3;
00721 rc = kFALSE;
00722 break;
00723 }
00724
00725 if (remloc < 1) {
00726 action = 2;
00727 rc = kFALSE;
00728 break;
00729 }
00730
00731 int i, j;
00732 char locav[40] = { 0 };
00733 Bool_t methfound = kFALSE;
00734 for (i = 0; i < remMeth; i++) {
00735 for (j = 0; j < nmet; j++) {
00736 if (fHostAuth->GetMethod(j) == rMth[i] && tMth[j] == 0) {
00737 meth = j;
00738 action = 1;
00739 methfound = kTRUE;
00740 break;
00741 }
00742 if (i == 0)
00743 snprintf(locav, 40, "%s %d", locav, fHostAuth->GetMethod(j));
00744 }
00745 if (methfound) break;
00746 }
00747 if (methfound) break;
00748
00749
00750 if (gDebug > 0)
00751 Warning("Authenticate",
00752 "no match with those locally available: %s", locav);
00753 action = 2;
00754 rc = kFALSE;
00755 break;
00756 } else {
00757 action = 3;
00758 rc = kFALSE;
00759 break;
00760 }
00761 break;
00762
00763 case -1:
00764
00765
00766 fHostAuth->CountFailure((Int_t)fSecurity);
00767 if (gDebug > 2)
00768 Info("Authenticate",
00769 "method not even started: insufficient or wrong info: %s",
00770 "try with next method, if any");
00771 fHostAuth->RemoveMethod(fSecurity);
00772 nmet--;
00773 if (nmet > 0) {
00774 action = 1;
00775 } else
00776 action = 2;
00777
00778 break;
00779
00780 case -2:
00781
00782
00783 fHostAuth->CountFailure((Int_t)fSecurity);
00784 if (fVersion <= 2)
00785 if (gDebug > 2)
00786 Warning("Authenticate",
00787 "status code -2 not expected from old daemons");
00788 rc = kFALSE;
00789 break;
00790
00791 case -3:
00792
00793
00794
00795
00796
00797 fHostAuth->CountFailure((Int_t)fSecurity);
00798 if (gDebug > 2)
00799 Info("Authenticate", "got a timeout");
00800 fHostAuth->SetLast(fSecurity);
00801 if (meth < nmet - 1) {
00802 fTimeOut = 2;
00803 } else
00804 fTimeOut = 1;
00805 rc = kFALSE;
00806 break;
00807
00808 default:
00809 fHostAuth->CountFailure((Int_t)fSecurity);
00810 if (gDebug > 2)
00811 Info("Authenticate", "unknown status code: %d - assume failure",st);
00812 rc = kFALSE;
00813 action = 0;
00814 break;
00815 }
00816
00817 switch (action) {
00818 case 1:
00819 goto negotia;
00820
00821 case 2:
00822 fSocket->Send("0", kROOTD_BYE);
00823
00824 case 3:
00825 if (strlen(noSupport) > 0)
00826 Info("Authenticate", "attempted methods %s are not supported"
00827 " by remote server version", noSupport);
00828 Info("Authenticate",
00829 "failure: list of attempted methods: %s", triedMeth);
00830 AuthError("Authenticate",-1);
00831 rc = kFALSE;
00832 break;
00833 default:
00834 break;
00835 }
00836
00837
00838 if (alarm)
00839 SafeDelete(alarm);
00840
00841 return rc;
00842
00843 }
00844
00845
00846 void TAuthenticate::SetEnvironment()
00847 {
00848
00849
00850
00851 R__LOCKGUARD2(gAuthenticateMutex);
00852
00853 if (gDebug > 2)
00854 Info("SetEnvironment",
00855 "setting environment: fSecurity:%d, fDetails:%s", fSecurity,
00856 fDetails.Data());
00857
00858
00859 fgDefaultUser = fgUser;
00860 if (fSecurity == kKrb5 ||
00861 (fSecurity == kGlobus && gROOT->IsProofServ()))
00862 fgAuthReUse = kFALSE;
00863 else
00864 fgAuthReUse = kTRUE;
00865 fgPromptUser = kFALSE;
00866
00867
00868 if (fDetails != "") {
00869 char usdef[kMAXPATHLEN] = { 0 };
00870 char pt[5] = { 0 }, ru[5] = { 0 };
00871 Int_t hh = 0, mm = 0;
00872 char us[kMAXPATHLEN] = {0}, cp[kMAXPATHLEN] = {0}, pp[kMAXPATHLEN] = {0};
00873 char cd[kMAXPATHLEN] = {0}, cf[kMAXPATHLEN] = {0}, kf[kMAXPATHLEN] = {0}, ad[kMAXPATHLEN] = {0};
00874 const char *ptr;
00875
00876 TString usrPromptDef = TString(GetAuthMethod(fSecurity)) + ".LoginPrompt";
00877 if ((ptr = strstr(fDetails, "pt:")) != 0) {
00878 sscanf(ptr + 3, "%4s %8191s", pt, usdef);
00879 } else {
00880 if (!strncasecmp(gEnv->GetValue(usrPromptDef,""),"no",2) ||
00881 !strncmp(gEnv->GetValue(usrPromptDef,""),"0",1))
00882 strncpy(pt,"0",1);
00883 else
00884 strncpy(pt,"1",1);
00885 }
00886 TString usrReUseDef = TString(GetAuthMethod(fSecurity)) + ".ReUse";
00887 if ((ptr = strstr(fDetails, "ru:")) != 0) {
00888 sscanf(ptr + 3, "%4s %8191s", ru, usdef);
00889 } else {
00890 if (!strncasecmp(gEnv->GetValue(usrReUseDef,""),"no",2) ||
00891 !strncmp(gEnv->GetValue(usrReUseDef,""),"0",1))
00892 strncpy(ru,"0",1);
00893 else
00894 strncpy(ru,"1",1);
00895 }
00896 TString usrValidDef = TString(GetAuthMethod(fSecurity)) + ".Valid";
00897 TString hours(gEnv->GetValue(usrValidDef,"24:00"));
00898 Int_t pd = 0;
00899 if ((pd = hours.Index(":")) > -1) {
00900 TString minutes = hours;
00901 hours.Resize(pd);
00902 minutes.Replace(0,pd+1,"");
00903 hh = atoi(hours.Data());
00904 mm = atoi(minutes.Data());
00905 } else {
00906 hh = atoi(hours.Data());
00907 mm = 0;
00908 }
00909
00910
00911 if (fSecurity == kGlobus) {
00912 if ((ptr = strstr(fDetails, "cd:")) != 0)
00913 sscanf(ptr, "%8191s %8191s", cd, usdef);
00914 if ((ptr = strstr(fDetails, "cf:")) != 0)
00915 sscanf(ptr, "%8191s %8191s", cf, usdef);
00916 if ((ptr = strstr(fDetails, "kf:")) != 0)
00917 sscanf(ptr, "%8191s %8191s", kf, usdef);
00918 if ((ptr = strstr(fDetails, "ad:")) != 0)
00919 sscanf(ptr, "%8191s %8191s", ad, usdef);
00920 if (gDebug > 2) {
00921 Info("SetEnvironment",
00922 "details:%s, pt:%s, ru:%s, cd:%s, cf:%s, kf:%s, ad:%s",
00923 fDetails.Data(), pt, ru, cd, cf, kf, ad);
00924 }
00925 } else if (fSecurity == kClear) {
00926 if ((ptr = strstr(fDetails, "us:")) != 0)
00927 sscanf(ptr + 3, "%8191s %8191s", us, usdef);
00928 if ((ptr = strstr(fDetails, "cp:")) != 0)
00929 sscanf(ptr + 3, "%8191s %8191s", cp, usdef);
00930 if (gDebug > 2)
00931 Info("SetEnvironment", "details:%s, pt:%s, ru:%s, us:%s cp:%s",
00932 fDetails.Data(), pt, ru, us, cp);
00933 } else if (fSecurity == kKrb5) {
00934 if ((ptr = strstr(fDetails, "us:")) != 0)
00935 sscanf(ptr + 3, "%8191s %8191s", us, usdef);
00936 if ((ptr = strstr(fDetails, "pp:")) != 0)
00937 sscanf(ptr + 3, "%8191s %8191s", pp, usdef);
00938 if (gDebug > 2)
00939 Info("SetEnvironment", "details:%s, pt:%s, ru:%s, us:%s pp:%s",
00940 fDetails.Data(), pt, ru, us, pp);
00941 } else {
00942 if ((ptr = strstr(fDetails, "us:")) != 0)
00943 sscanf(ptr + 3, "%8191s %8191s", us, usdef);
00944 if (gDebug > 2)
00945 Info("SetEnvironment", "details:%s, pt:%s, ru:%s, us:%s",
00946 fDetails.Data(), pt, ru, us);
00947 }
00948
00949
00950 if (!strncasecmp(pt, "yes",3) || !strncmp(pt, "1", 1))
00951 fgPromptUser = kTRUE;
00952
00953
00954 if (fSecurity == kKrb5) {
00955 fgAuthReUse = kFALSE;
00956 if (!strncasecmp(ru, "yes",3) || !strncmp(ru, "1",1))
00957 fgAuthReUse = kTRUE;
00958 } else {
00959 if (fSecurity != kGlobus || !(gROOT->IsProofServ())) {
00960 fgAuthReUse = kTRUE;
00961 if (!strncasecmp(ru, "no",2) || !strncmp(ru, "0",1))
00962 fgAuthReUse = kFALSE;
00963 }
00964 }
00965
00966
00967 fgExpDate = TDatime();
00968 fgExpDate.Set(fgExpDate.Convert() + hh*3600 + mm*60);
00969
00970
00971 if (fSecurity == kClear) {
00972 fgUsrPwdCrypt = kTRUE;
00973 if (!strncmp(cp, "no", 2) || !strncmp(cp, "0", 1))
00974 fgUsrPwdCrypt = kFALSE;
00975 }
00976
00977 usdef[0] = '\0';
00978 if (fSecurity == kGlobus) {
00979 if (strlen(cd) > 0) { snprintf(usdef,8192," %s",cd); }
00980 if (strlen(cf) > 0) { snprintf(usdef,8192,"%s %s",usdef, cf); }
00981 if (strlen(kf) > 0) { snprintf(usdef,8192,"%s %s",usdef, kf); }
00982 if (strlen(ad) > 0) { snprintf(usdef,8192,"%s %s",usdef, ad); }
00983 } else {
00984 if (fSecurity == kKrb5) {
00985
00986 if (strlen(pp) > 0) {
00987 fgKrb5Principal = TString(pp);
00988 } else {
00989
00990 if (strlen(us) > 0 && strstr(us,"@"))
00991 fgKrb5Principal = TString(us);
00992 }
00993
00994 if (fUser.Length()) {
00995 snprintf(usdef, kMAXPATHLEN, "%s", fUser.Data());
00996 } else {
00997 if (strlen(us) > 0 && !strstr(us,"@"))
00998 snprintf(usdef, kMAXPATHLEN, "%s", us);
00999 }
01000 } else {
01001
01002 if (fUser == "") {
01003 if (strlen(us) > 0) snprintf(usdef, kMAXPATHLEN, "%s", us);
01004 } else
01005 snprintf(usdef, kMAXPATHLEN, "%s", fUser.Data());
01006 }
01007 }
01008 if (strlen(usdef) > 0) {
01009 fgDefaultUser = usdef;
01010 } else {
01011 if (fgUser != "") {
01012 fgDefaultUser = fgUser;
01013 } else {
01014 UserGroup_t *u = gSystem->GetUserInfo();
01015 if (u)
01016 fgDefaultUser = u->fUser;
01017 delete u;
01018 }
01019 }
01020 if (fgDefaultUser == "anonymous" || fgDefaultUser == "rootd" ||
01021 fgUser != "" || fUser != "") {
01022
01023 fgPromptUser = kFALSE;
01024 }
01025
01026 if (gDebug > 2)
01027 Info("SetEnvironment", "usdef:%s", fgDefaultUser.Data());
01028 }
01029 }
01030
01031
01032 Bool_t TAuthenticate::GetUserPasswd(TString &user, TString &passwd,
01033 Bool_t &pwhash, Bool_t srppwd)
01034 {
01035
01036
01037 if (gDebug > 3)
01038 Info("GetUserPasswd", "Enter: User: '%s' Hash:%d SRP:%d",
01039 user.Data(),(Int_t)pwhash,(Int_t)srppwd);
01040
01041
01042 if (user == "") {
01043 if (fgUser != "")
01044 user = fgUser;
01045 if (passwd == "" && fgPasswd != "" && srppwd == fgSRPPwd) {
01046 passwd = fgPasswd;
01047 pwhash = fgPwHash;
01048 }
01049 } else {
01050 if (fgUser != "" && user == fgUser) {
01051 if (passwd == "" && fgPasswd != "" && srppwd == fgSRPPwd) {
01052 passwd = fgPasswd;
01053 pwhash = fgPwHash;
01054 }
01055 }
01056 }
01057 if (gDebug > 3)
01058 Info("GetUserPasswd", "In memory: User: '%s' Hash:%d",
01059 user.Data(),(Int_t)pwhash);
01060
01061
01062 if (user == "") {
01063 UserGroup_t *u = gSystem->GetUserInfo();
01064 if (u)
01065 user = u->fUser;
01066 delete u;
01067 if (gDebug > 3)
01068 Info("GetUserPasswd", "In memory: User: '%s' Hash:%d",
01069 user.Data(),(Int_t)pwhash);
01070 }
01071
01072
01073
01074 if (user == "" || passwd == "") {
01075 if (gDebug > 3)
01076 Info("GetUserPasswd", "Checking .netrc family ...");
01077 CheckNetrc(user, passwd, pwhash, srppwd);
01078 }
01079 if (gDebug > 3)
01080 Info("GetUserPasswd", "From .netrc family: User: '%s' Hash:%d",
01081 user.Data(),(Int_t)pwhash);
01082
01083
01084 if (user == "") {
01085 char *p = PromptUser(fRemote);
01086 user = p;
01087 delete [] p;
01088 if (user == "") {
01089 Error("GetUserPasswd", "user name not set");
01090 return 1;
01091 }
01092 }
01093
01094 return 0;
01095 }
01096
01097
01098 Bool_t TAuthenticate::CheckNetrc(TString &user, TString &passwd)
01099 {
01100
01101
01102
01103
01104 Bool_t hash, srppwd;
01105
01106
01107 srppwd = (fSecurity == kSRP) ? kTRUE : kFALSE;
01108
01109 return CheckNetrc(user, passwd, hash, srppwd);
01110 }
01111
01112
01113 Bool_t TAuthenticate::CheckNetrc(TString &user, TString &passwd,
01114 Bool_t &pwhash, Bool_t srppwd)
01115 {
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 Bool_t result = kFALSE;
01142 Bool_t first = kTRUE;
01143 TString remote = fRemote;
01144
01145 passwd = "";
01146 pwhash = kFALSE;
01147
01148 char *net =
01149 gSystem->ConcatFileName(gSystem->HomeDirectory(), ".rootnetrc");
01150
01151
01152 TInetAddress addr = gSystem->GetHostByName(fRemote);
01153 if (addr.IsValid())
01154 remote = addr.GetHostName();
01155
01156 again:
01157
01158 FileStat_t buf;
01159 if (gSystem->GetPathInfo(net, buf) == 0) {
01160 #ifdef WIN32
01161
01162 if (R_ISREG(buf.fMode) && !R_ISDIR(buf.fMode)) {
01163 #else
01164 if (R_ISREG(buf.fMode) && !R_ISDIR(buf.fMode) &&
01165 (buf.fMode & 0777) == (kS_IRUSR | kS_IWUSR)) {
01166 #endif
01167 FILE *fd = fopen(net, "r");
01168 char line[256];
01169 while (fgets(line, sizeof(line), fd) != 0) {
01170 if (line[0] == '#')
01171 continue;
01172 char word[6][64];
01173 int nword = sscanf(line, "%63s %63s %63s %63s %63s %63s",
01174 word[0], word[1], word[2], word[3], word[4], word[5]);
01175 if (nword != 6)
01176 continue;
01177 if (srppwd && strcmp(word[0], "secure"))
01178 continue;
01179 if (!srppwd && strcmp(word[0], "machine"))
01180 continue;
01181 if (strcmp(word[2], "login"))
01182 continue;
01183 if (srppwd && strcmp(word[4], "password"))
01184 continue;
01185 if (!srppwd &&
01186 strcmp(word[4], "password") && strcmp(word[4], "password-hash"))
01187 continue;
01188
01189
01190
01191 TString href(word[1]);
01192 href.ReplaceAll("*",".*");
01193 TRegexp rg(href);
01194 if (remote.Index(rg) != kNPOS) {
01195 if (user == "") {
01196 user = word[3];
01197 passwd = word[5];
01198 if (!strcmp(word[4], "password-hash"))
01199 pwhash = kTRUE;
01200 result = kTRUE;
01201 break;
01202 } else {
01203 if (!strcmp(word[3], user.Data())) {
01204 passwd = word[5];
01205 if (!strcmp(word[4], "password-hash"))
01206 pwhash = kTRUE;
01207 result = kTRUE;
01208 break;
01209 }
01210 }
01211 }
01212 }
01213 fclose(fd);
01214 } else
01215 Warning("CheckNetrc",
01216 "file %s exists but has not 0600 permission", net);
01217 }
01218 delete [] net;
01219
01220 if (first && !srppwd && !result) {
01221 net = gSystem->ConcatFileName(gSystem->HomeDirectory(), ".netrc");
01222 first = kFALSE;
01223 goto again;
01224 }
01225
01226 return result;
01227 }
01228
01229
01230 const char *TAuthenticate::GetGlobalUser()
01231 {
01232
01233
01234 return fgUser;
01235 }
01236
01237
01238 Bool_t TAuthenticate::GetGlobalPwHash()
01239 {
01240
01241
01242 return fgPwHash;
01243 }
01244
01245
01246 Bool_t TAuthenticate::GetGlobalSRPPwd()
01247 {
01248
01249
01250 return fgSRPPwd;
01251 }
01252
01253
01254 TDatime TAuthenticate::GetGlobalExpDate()
01255 {
01256
01257
01258 return fgExpDate;
01259 }
01260
01261
01262 const char *TAuthenticate::GetDefaultUser()
01263 {
01264
01265
01266 return fgDefaultUser;
01267 }
01268
01269
01270 const char *TAuthenticate::GetKrb5Principal()
01271 {
01272
01273
01274 return fgKrb5Principal;
01275 }
01276
01277
01278 Bool_t TAuthenticate::GetAuthReUse()
01279 {
01280
01281
01282 return fgAuthReUse;
01283 }
01284
01285
01286 Bool_t TAuthenticate::GetPromptUser()
01287 {
01288
01289
01290 return fgPromptUser;
01291 }
01292
01293
01294 const char *TAuthenticate::GetAuthMethod(Int_t idx)
01295 {
01296
01297
01298 R__LOCKGUARD2(gAuthenticateMutex);
01299
01300 if (idx < 0 || idx > kMAXSEC-1) {
01301 ::Error("Authenticate::GetAuthMethod", "idx out of bounds (%d)", idx);
01302 idx = 0;
01303 }
01304 return fgAuthMeth[idx];
01305 }
01306
01307
01308 Int_t TAuthenticate::GetAuthMethodIdx(const char *meth)
01309 {
01310
01311
01312
01313 R__LOCKGUARD2(gAuthenticateMutex);
01314
01315 if (meth && meth[0]) {
01316 for (Int_t i = 0; i < kMAXSEC; i++) {
01317 if (!fgAuthMeth[i].CompareTo(meth, TString::kIgnoreCase))
01318 return i;
01319 }
01320 }
01321
01322 return -1;
01323 }
01324
01325
01326 char *TAuthenticate::PromptUser(const char *remote)
01327 {
01328
01329
01330
01331
01332
01333 R__LOCKGUARD2(gAuthenticateMutex);
01334
01335 const char *user;
01336 if (fgDefaultUser != "")
01337 user = fgDefaultUser;
01338 else
01339 user = gSystem->Getenv("USER");
01340 #ifdef R__WIN32
01341 if (!user)
01342 user = gSystem->Getenv("USERNAME");
01343 #endif
01344 if (isatty(0) == 0 || isatty(1) == 0) {
01345 ::Warning("TAuthenticate::PromptUser",
01346 "not tty: cannot prompt for user, returning default");
01347 if (strlen(user))
01348 return StrDup(user);
01349 else
01350 return StrDup("None");
01351 }
01352
01353 char *usr = Getline(Form("Name (%s:%s): ", remote, user));
01354 if (usr[0]) {
01355 usr[strlen(usr) - 1] = 0;
01356 if (strlen(usr))
01357 return StrDup(usr);
01358 else
01359 return StrDup(user);
01360 }
01361 return 0;
01362 }
01363
01364
01365 char *TAuthenticate::PromptPasswd(const char *prompt)
01366 {
01367
01368
01369
01370
01371
01372 if (isatty(0) == 0 || isatty(1) == 0) {
01373 ::Warning("TAuthenticate::PromptPasswd",
01374 "not tty: cannot prompt for passwd, returning -1");
01375 static char noint[4] = {"-1"};
01376 return StrDup(noint);
01377 }
01378
01379 char buf[128];
01380 char *pw = buf;
01381
01382 if (!gROOT->IsBatch() && (fgPasswdDialog == (TPluginHandler *)(-1)) &&
01383 gEnv->GetValue("Auth.UsePasswdDialogBox", 1) == 1) {
01384 if ((fgPasswdDialog =
01385 gROOT->GetPluginManager()->FindHandler("TGPasswdDialog"))) {
01386 if (fgPasswdDialog->LoadPlugin() == -1) {
01387 fgPasswdDialog = 0;
01388 ::Warning("TAuthenticate",
01389 "could not load plugin for the password dialog box");
01390 }
01391 }
01392 }
01393 if (fgPasswdDialog && (fgPasswdDialog != (TPluginHandler *)(-1))) {
01394
01395
01396 fgPasswdDialog->ExecPlugin(3, prompt, buf, 128);
01397
01398
01399 while (gROOT->IsInterrupted())
01400 gSystem->DispatchOneEvent(kFALSE);
01401
01402 } else {
01403 Gl_config("noecho", 1);
01404 pw = Getline((char *) prompt);
01405 Gl_config("noecho", 0);
01406 }
01407
01408
01409 if (pw[0]) {
01410 if (pw[strlen(pw)-1] == '\n')
01411 pw[strlen(pw) - 1] = 0;
01412 char *rpw = StrDup(pw);
01413 memset(pw, 0, strlen(pw));
01414 return rpw;
01415 }
01416 return 0;
01417 }
01418
01419
01420 GlobusAuth_t TAuthenticate::GetGlobusAuthHook()
01421 {
01422
01423
01424 return fgGlobusAuthHook;
01425 }
01426
01427
01428 const char *TAuthenticate::GetRSAPubExport(Int_t key)
01429 {
01430
01431
01432 key = (key >= 0 && key <= 1) ? key : 0;
01433 return fgRSAPubExport[key].keys;
01434 }
01435
01436
01437 Int_t TAuthenticate::GetRSAInit()
01438 {
01439
01440
01441 return fgRSAInit;
01442 }
01443
01444
01445 void TAuthenticate::SetDefaultRSAKeyType(Int_t key)
01446 {
01447
01448
01449 if (key >= 0 && key <= 1)
01450 fgRSAKey = key;
01451 }
01452
01453
01454 void TAuthenticate::SetRSAInit(Int_t init)
01455 {
01456
01457
01458 fgRSAInit = init;
01459 }
01460
01461
01462 TList *TAuthenticate::GetAuthInfo()
01463 {
01464
01465
01466 R__LOCKGUARD2(gAuthenticateMutex);
01467
01468 if (!fgAuthInfo)
01469 fgAuthInfo = new TList;
01470 return fgAuthInfo;
01471 }
01472
01473
01474 TList *TAuthenticate::GetProofAuthInfo()
01475 {
01476
01477
01478
01479 R__LOCKGUARD2(gAuthenticateMutex);
01480
01481 if (!fgProofAuthInfo)
01482 fgProofAuthInfo = new TList;
01483 return fgProofAuthInfo;
01484 }
01485
01486
01487 void TAuthenticate::AuthError(const char *where, Int_t err)
01488 {
01489
01490
01491 R__LOCKGUARD2(gAuthenticateMutex);
01492
01493
01494 err = (err < kErrError) ? ((err > -1) ? err : -1) : kErrError;
01495
01496 Int_t erc = err;
01497 Bool_t forceprint = kFALSE;
01498 TString lasterr = "";
01499 if (err == -1) {
01500 forceprint = kTRUE;
01501 erc = fgLastError;
01502 lasterr = "(last error only; re-run with gDebug > 0 for more details)";
01503 }
01504
01505 if (erc > -1)
01506 if (gDebug > 0 || forceprint) {
01507 if (gRootdErrStr[erc])
01508 ::Error(Form("TAuthenticate::%s", where), "%s %s",
01509 gRootdErrStr[erc], lasterr.Data());
01510 else
01511 ::Error(Form("TAuthenticate::%s", where),
01512 "unknown error code: server must be running a newer ROOT version %s",
01513 lasterr.Data());
01514 }
01515
01516
01517 fgLastError = err;
01518 }
01519
01520
01521 void TAuthenticate::SetGlobalUser(const char *user)
01522 {
01523
01524
01525 R__LOCKGUARD2(gAuthenticateMutex);
01526
01527 if (fgUser != "")
01528 fgUser = "";
01529
01530 if (user && user[0])
01531 fgUser = user;
01532 }
01533
01534
01535 void TAuthenticate::SetGlobalPasswd(const char *passwd)
01536 {
01537
01538
01539 R__LOCKGUARD2(gAuthenticateMutex);
01540
01541 if (fgPasswd != "")
01542 fgPasswd = "";
01543
01544 if (passwd && passwd[0])
01545 fgPasswd = passwd;
01546 }
01547
01548
01549 void TAuthenticate::SetGlobalPwHash(Bool_t pwhash)
01550 {
01551
01552
01553 fgPwHash = pwhash;
01554 }
01555
01556
01557 void TAuthenticate::SetGlobalSRPPwd(Bool_t srppwd)
01558 {
01559
01560
01561 fgSRPPwd = srppwd;
01562 }
01563
01564
01565 void TAuthenticate::SetReadHomeAuthrc(Bool_t readhomeauthrc)
01566 {
01567
01568
01569
01570
01571 fgReadHomeAuthrc = readhomeauthrc;
01572 }
01573
01574
01575 void TAuthenticate::SetGlobalExpDate(TDatime expdate)
01576 {
01577
01578
01579 fgExpDate = expdate;
01580 }
01581
01582
01583 void TAuthenticate::SetDefaultUser(const char *defaultuser)
01584 {
01585
01586
01587 if (fgDefaultUser != "")
01588 fgDefaultUser = "";
01589
01590 if (defaultuser && defaultuser[0])
01591 fgDefaultUser = defaultuser;
01592 }
01593
01594
01595 void TAuthenticate::SetTimeOut(Int_t to)
01596 {
01597
01598
01599 fgAuthTO = (to <= 0) ? -1 : to;
01600 }
01601
01602
01603 void TAuthenticate::SetAuthReUse(Bool_t authreuse)
01604 {
01605
01606
01607 fgAuthReUse = authreuse;
01608 }
01609
01610
01611 void TAuthenticate::SetPromptUser(Bool_t promptuser)
01612 {
01613
01614
01615 fgPromptUser = promptuser;
01616 }
01617
01618
01619 void TAuthenticate::SetSecureAuthHook(SecureAuth_t func)
01620 {
01621
01622
01623
01624 fgSecAuthHook = func;
01625 }
01626
01627
01628 void TAuthenticate::SetKrb5AuthHook(Krb5Auth_t func)
01629 {
01630
01631
01632
01633 fgKrb5AuthHook = func;
01634 }
01635
01636
01637 void TAuthenticate::SetGlobusAuthHook(GlobusAuth_t func)
01638 {
01639
01640
01641
01642 fgGlobusAuthHook = func;
01643 }
01644
01645
01646 Int_t TAuthenticate::SshError(const char *errorfile)
01647 {
01648
01649
01650
01651
01652 Int_t error = 0;
01653
01654 if (!gSystem->AccessPathName(errorfile, kReadPermission)) {
01655 FILE *ferr = fopen(errorfile,"r");
01656 if (ferr) {
01657
01658 char *serr = StrDup(gEnv->GetValue("SSH.ErrorRetry", ""));
01659
01660 Int_t lerr = strlen(serr);
01661 char *pc = (char *)memchr(serr,'"',lerr);
01662 while (pc) {
01663 *pc = '\0';
01664 pc = (char *)memchr(pc+1,'"',strlen(pc+1));
01665 }
01666
01667 char line[kMAXPATHLEN];
01668 while (fgets(line,sizeof(line),ferr)) {
01669
01670 if (line[strlen(line)-1] == '\n')
01671 line[strlen(line)-1] = '\0';
01672 if (gDebug > 2)
01673 Info("SshError","read line: %s",line);
01674 pc = serr;
01675 while (pc < serr + lerr) {
01676 if (pc[0] == '\0' || pc[0] == ' ')
01677 pc++;
01678 else {
01679 if (gDebug > 2)
01680 Info("SshError","checking error: '%s'",pc);
01681 if (strstr(line,pc))
01682 error = 1;
01683 pc += strlen(pc);
01684 }
01685 }
01686 }
01687
01688 fclose(ferr);
01689
01690 if (serr) delete [] serr;
01691 }
01692 }
01693 return error;
01694 }
01695
01696
01697 Int_t TAuthenticate::SshAuth(TString &user)
01698 {
01699
01700
01701
01702
01703
01704
01705 if (gROOT->IsProofServ()) {
01706 if (!(gEnv->GetValue("ProofServ.UseSSH",0))) {
01707 if (gDebug > 0)
01708 Info("SshAuth", "SSH protocol is switched OFF by default"
01709 " for PROOF servers: use 'ProofServ.UseSSH 1'"
01710 " to enable it (see system.rootrc)");
01711 return -1;
01712 }
01713 }
01714
01715 Int_t sshproto = 1;
01716 if (fVersion < 4)
01717 sshproto = 0;
01718
01719
01720 char cmdref[2][5] = {"ssh", "scp"};
01721 char scmd[5] = "";
01722 char *gSshExe = 0;
01723 Bool_t notfound = kTRUE;
01724
01725 while (notfound && sshproto > -1) {
01726
01727 strlcpy(scmd,cmdref[sshproto],5);
01728
01729
01730 gSshExe = gSystem->Which(gSystem->Getenv("PATH"),
01731 scmd, kExecutePermission);
01732 if (!gSshExe) {
01733 if (gDebug > 2)
01734 Info("SshAuth", "%s not found in $PATH", scmd);
01735
01736
01737 if (strcmp(gEnv->GetValue("SSH.ExecDir", "-1"), "-1")) {
01738 if (gDebug > 2)
01739 Info("SshAuth", "searching user defined path ...");
01740 gSshExe = StrDup(Form("%s/%s",
01741 (char *)gEnv->GetValue("SSH.ExecDir", ""), scmd));
01742 if (gSystem->AccessPathName(gSshExe, kExecutePermission)) {
01743 if (gDebug > 2)
01744 Info("SshAuth", "%s not executable", gSshExe);
01745 } else
01746 notfound = kFALSE;
01747 }
01748 } else
01749 notfound = kFALSE;
01750 if (notfound) sshproto--;
01751 }
01752
01753
01754 if (notfound) {
01755 if (gSshExe) delete [] gSshExe;
01756 return -1;
01757 }
01758 if (gDebug > 2)
01759 Info("SshAuth", "%s is %s (sshproto: %d)", scmd, gSshExe, sshproto);
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769 char secName[kMAXPATHLEN] = { 0 };
01770
01771
01772 user = GetSshUser(user);
01773
01774
01775 Int_t reuse = (int)fgAuthReUse;
01776 fDetails = TString(Form("pt:%d ru:%d us:",(int)fgPromptUser,(int)fgAuthReUse))
01777 + user;
01778
01779
01780 int opt = reuse * kAUTH_REUSE_MSK + fRSAKey * kAUTH_RSATY_MSK;
01781 TString options(Form("%d none %ld %s %d", opt,
01782 (Long_t)user.Length(),user.Data(),sshproto));
01783
01784
01785 Int_t kind = kROOTD_SSH;
01786 Int_t retval = reuse;
01787 Int_t rc = 0;
01788 if ((rc = AuthExists(user, (Int_t) TAuthenticate::kSSH, options,
01789 &kind, &retval, &StdCheckSecCtx)) == 1) {
01790
01791 return 1;
01792 }
01793 if (rc == -2) {
01794 return rc;
01795 }
01796 if (retval == kErrNotAllowed && kind == kROOTD_ERR) {
01797 return 0;
01798 }
01799
01800 if (kind != kROOTD_SSH)
01801 return 0;
01802 if (retval == 0)
01803 return 0;
01804 if (retval == -2)
01805 return 0;
01806
01807
01808
01809 char cmdinfo[kMAXPATHLEN] = { 0 };
01810 Int_t reclen = (retval+1 > kMAXPATHLEN) ? kMAXPATHLEN : retval+1 ;
01811 if (fSocket->Recv(cmdinfo, reclen, kind) < 0)
01812 return 0;
01813 if (kind != kROOTD_SSH)
01814 return 0;
01815 if (gDebug > 3)
01816 Info("SshAuth", "received from server command info: %s", cmdinfo);
01817
01818 int rport = -1;
01819 TString ci(cmdinfo), tkn;
01820 Ssiz_t from = 0;
01821 while (ci.Tokenize(tkn, from, " ")) {
01822 if (from > 0) cmdinfo[from-1] = '\0';
01823 if (tkn.BeginsWith("p:")) {
01824 tkn.ReplaceAll("p:", "");
01825 if (tkn.IsDigit()) rport = tkn.Atoi();
01826 #ifdef R__SSL
01827 } else if (tkn.BeginsWith("k:")) {
01828 tkn.ReplaceAll("k:", "");
01829 if (tkn.IsDigit() && tkn.Atoi() == 1) fRSAKey = 1;
01830 #endif
01831 }
01832 }
01833
01834
01835 TString noPrompt = "";
01836 if (isatty(0) == 0 || isatty(1) == 0) {
01837 noPrompt = TString("-o 'PasswordAuthentication no' ");
01838 noPrompt += TString("-o 'StrictHostKeyChecking no' ");
01839 if (gDebug > 3)
01840 Info("SshAuth", "using noprompt options: %s", noPrompt.Data());
01841 }
01842
01843
01844 Int_t srvtyp = fSocket->GetServType();
01845 Int_t rproto = fSocket->GetRemoteProtocol();
01846
01847
01848
01849 int ssh_rc = 1;
01850 Int_t ntry = gEnv->GetValue("SSH.MaxRetry",100);
01851 TString fileErr = "";
01852 if (sshproto == 0) {
01853
01854 fileErr = "rootsshtmp_";
01855 FILE *floc = gSystem->TempFileName(fileErr,gSystem->HomeDirectory());
01856 if (floc == 0) {
01857
01858 fileErr = "rootsshtmp_";
01859 if ((floc = gSystem->TempFileName(fileErr)))
01860 fclose(floc);
01861 }
01862 fileErr.Append(".error");
01863 TString sshcmd(Form("%s -x -l %s %s",
01864 gSshExe, user.Data(), noPrompt.Data()));
01865 if (rport != -1)
01866 sshcmd += TString(Form(" -p %d",rport));
01867 sshcmd += TString(Form(" %s %s",fRemote.Data(), cmdinfo));
01868 sshcmd += TString(Form(" 1> /dev/null 2> %s",fileErr.Data()));
01869
01870
01871 Int_t again = 1;
01872 while (ssh_rc && again && ntry--) {
01873 ssh_rc = gSystem->Exec(sshcmd);
01874 if (ssh_rc) {
01875 again = SshError(fileErr);
01876 if (gDebug > 3)
01877 Info("SshAuth", "%d: sleeping: rc: %d, again:%d, ntry: %d",
01878 fgProcessID, ssh_rc, again, ntry);
01879 if (again)
01880 gSystem->Sleep(1);
01881 }
01882 }
01883 } else {
01884
01885
01886
01887 Bool_t addhost = ((srvtyp == TSocket::kROOTD && rproto < 15) ||
01888 (srvtyp == TSocket::kPROOFD && rproto < 13)||
01889 (srvtyp == TSocket::kSOCKD && rproto < 1)) ? 1 : 0;
01890
01891
01892 TString fileLoc = "rootsshtmp_";
01893 FILE *floc = gSystem->TempFileName(fileLoc,gSystem->HomeDirectory());
01894 if (floc == 0) {
01895
01896 fileLoc = "rootsshtmp_";
01897 floc = gSystem->TempFileName(fileLoc);
01898 }
01899
01900 if (floc != 0) {
01901
01902 fclose(floc);
01903 if (chmod(fileLoc, 0600) == -1) {
01904 Info("SshAuth", "fchmod error: %d", errno);
01905 ssh_rc = 2;
01906 } else {
01907 floc = fopen(fileLoc, "w");
01908 if (reuse == 1) {
01909
01910 if (fVersion > 4) {
01911 fprintf(floc,"k: %d\n",fRSAKey+1);
01912 fwrite(fgRSAPubExport[fRSAKey].keys,1,
01913 fgRSAPubExport[fRSAKey].len,floc);
01914 } else {
01915 fprintf(floc,"k: %s\n",fgRSAPubExport[0].keys);
01916 }
01917 } else
01918
01919 fprintf(floc,"k: -1\n");
01920 fclose(floc);
01921 ssh_rc = 0;
01922 }
01923 if (!ssh_rc) {
01924 fileErr = TString(fileLoc).Append(".error");
01925 TString sshcmd(Form("%s -p %s", gSshExe, noPrompt.Data()));
01926 if (rport != -1)
01927 sshcmd += TString(Form(" -P %d",rport));
01928 sshcmd += TString(Form(" %s",fileLoc.Data()));
01929 if (addhost) {
01930 sshcmd += TString(Form(" %s@%s:%s 1> /dev/null",
01931 user.Data(),fRemote.Data(),cmdinfo));
01932 } else {
01933 sshcmd += TString(Form("%s 1> /dev/null", cmdinfo));
01934 }
01935 sshcmd += TString(Form(" 2> %s",fileErr.Data()));
01936
01937 ssh_rc = 1;
01938 Int_t again = 1;
01939 while (ssh_rc && again && ntry--) {
01940 ssh_rc = gSystem->Exec(sshcmd);
01941 if (ssh_rc) {
01942 again = SshError(fileErr);
01943 if (gDebug > 3)
01944 Info("SshAuth", "%d: sleeping: rc: %d, again:%d, ntry: %d",
01945 fgProcessID, ssh_rc, again, ntry);
01946 if (again)
01947
01948 gSystem->Sleep(1000);
01949 }
01950 }
01951 }
01952 } else {
01953
01954 ssh_rc = 1;
01955 }
01956
01957 if (!gSystem->AccessPathName(fileLoc,kFileExists)) {
01958 gSystem->Unlink(fileLoc);
01959 }
01960 }
01961
01962 if (!gSystem->AccessPathName(fileErr,kFileExists)) {
01963 gSystem->Unlink(fileErr);
01964 }
01965 if (gDebug > 3)
01966 Info("SshAuth", "%d: system return code: %d (%d)",
01967 fgProcessID, ssh_rc, ntry+1);
01968
01969 if (ssh_rc && sshproto == 0) {
01970
01971 srvtyp = fSocket->GetServType();
01972 rproto = fSocket->GetRemoteProtocol();
01973 Int_t level = 2;
01974 if ((srvtyp == TSocket::kROOTD && rproto < 10) ||
01975 (srvtyp == TSocket::kPROOFD && rproto < 9))
01976 level = 1;
01977 if ((srvtyp == TSocket::kROOTD && rproto < 8) ||
01978 (srvtyp == TSocket::kPROOFD && rproto < 7))
01979 level = 0;
01980 if (level) {
01981 Int_t port = fSocket->GetPort();
01982 TSocket *newsock = 0;
01983 TString url(Form("sockd://%s",fRemote.Data()));
01984 if (srvtyp == TSocket::kROOTD) {
01985
01986 url.ReplaceAll("sockd",5,"rootd",5);
01987 newsock = new TPSocket(url.Data(),port,1,-1);
01988 } else {
01989 if (srvtyp == TSocket::kPROOFD)
01990 url.ReplaceAll("sockd",5,"proofd",6);
01991 newsock = new TSocket(fRemote.Data(),port,-1);
01992 if (srvtyp == TSocket::kPROOFD)
01993 newsock->Send("failure notification");
01994 }
01995
01996 char cd1[1024], pipe[1024], dum[1024];
01997 Int_t id3;
01998 sscanf(cmdinfo, "%1023s %d %1023s %1023s", cd1, &id3, pipe, dum);
01999 snprintf(secName, kMAXPATHLEN, "%d -1 0 %s %d %s %d",
02000 -fgProcessID, pipe,
02001 (int)strlen(user), user.Data(), TSocket::GetClientProtocol());
02002 newsock->Send(secName, kROOTD_SSH);
02003 if (level > 1) {
02004
02005
02006 if (newsock->Recv(retval, kind) >= 0) {
02007 char *buf = new char[retval+1];
02008 if (newsock->Recv(buf, retval+1, kind) >= 0) {
02009 if (strncmp(buf,"OK",2)) {
02010 Info("SshAuth", "from remote host %s:", fRemote.Data());
02011 Info("SshAuth", ">> nothing listening on port %s %s",buf,
02012 "(supposed to be associated to sshd)");
02013 Info("SshAuth", ">> contact the daemon administrator at %s",
02014 fRemote.Data());
02015 } else {
02016 if (gDebug > 0) {
02017 Info("SshAuth", "from remote host %s:", fRemote.Data());
02018 Info("SshAuth", ">> something listening on the port"
02019 " supposed to be associated to sshd.");
02020 Info("SshAuth", ">> You have probably mistyped your"
02021 " password. Or you tried to hack the"
02022 " system.");
02023 Info("SshAuth", ">> If the problem persists you may"
02024 " consider contacting the daemon");
02025 Info("SshAuth", ">> administrator at %s.",fRemote.Data());
02026 }
02027 }
02028 }
02029 if (buf)
02030 delete [] buf;
02031 }
02032 }
02033 SafeDelete(newsock);
02034
02035 if (fSocket->Recv(retval, kind) >= 0) {
02036 if (kind == kROOTD_ERR)
02037 AuthError("SshAuth", retval);
02038 }
02039 }
02040 return 0;
02041 } else if (ssh_rc && sshproto > 0) {
02042
02043 if (fSocket->Send("0", kROOTD_SSH) < 0)
02044 Info("SshAuth", "error communicating failure");
02045 return 0;
02046 }
02047
02048
02049 if (sshproto > 0) {
02050 if (fSocket->Send("1", kROOTD_SSH) < 0)
02051 Info("SshAuth", "error communicating success");
02052 }
02053
02054 Int_t nrec = 0;
02055
02056 if ((nrec = fSocket->Recv(retval, kind)) < 0)
02057 return 0;
02058 if (gDebug > 3)
02059 Info("SshAuth", "got message %d, flag: %d", kind, retval);
02060
02061
02062 if (kind == kROOTD_ERR) {
02063 AuthError("SshAuth", retval);
02064 return 0;
02065 }
02066
02067 if (reuse == 1 && sshproto == 0) {
02068
02069
02070 if (kind != kROOTD_RSAKEY || retval < 1 || retval > 2) {
02071 Error("SshAuth",
02072 "problems recvn RSA key flag: got message %d, flag: %d",
02073 kind, retval);
02074 return 0;
02075 }
02076
02077 fRSAKey = retval - 1;
02078
02079
02080 if (SendRSAPublicKey(fSocket,fRSAKey) < 0)
02081 return 0;
02082
02083
02084 if ((nrec = fSocket->Recv(retval, kind)) < 0)
02085 return 0;
02086 if (gDebug > 3)
02087 Info("SshAuth", "got message %d, flag: %d", kind, retval);
02088 }
02089
02090 if (kind != kROOTD_SSH || retval < 1) {
02091 Warning("SshAuth",
02092 "problems recvn (user,offset) length (%d:%d bytes:%d)", kind,
02093 retval, nrec);
02094 return 0;
02095 }
02096
02097 char answer[256];
02098 reclen = (retval+1 > 256) ? 256 : retval+1;
02099 if ((nrec = fSocket->Recv(answer, reclen, kind)) < 0)
02100 return 0;
02101 if (kind != kMESS_STRING)
02102 Warning("SshAuth", "username and offset not received (%d:%d)", kind,
02103 nrec);
02104
02105
02106 char lUser[128];
02107 int offset = -1;
02108 sscanf(answer, "%127s %d", lUser, &offset);
02109 if (gDebug > 3)
02110 Info("SshAuth", "received from server: user: %s, offset: %d", lUser,
02111 offset);
02112
02113
02114 char *token = 0;
02115 if (reuse == 1 && offset > -1) {
02116 if (SecureRecv(fSocket, 1, fRSAKey, &token) == -1) {
02117 Warning("SshAuth", "problems secure-receiving token -"
02118 " may result in corrupted token");
02119 delete [] token;
02120 return 0;
02121 }
02122 if (gDebug > 3)
02123 Info("SshAuth", "received from server: token: '%s' ", token);
02124 } else {
02125 token = StrDup("");
02126 }
02127
02128
02129 fSecContext = fHostAuth->CreateSecContext((const char *)lUser, fRemote,
02130 (Int_t)kSSH, offset, fDetails,
02131 (const char *)token, fgExpDate, 0, fRSAKey);
02132
02133
02134 if (token) delete [] token;
02135
02136
02137 if (fSocket->Recv(retval, kind) < 0)
02138 return 0;
02139 if (gDebug > 3)
02140 Info("SshAuth", "received from server: kind: %d, retval: %d", kind,
02141 retval);
02142
02143 if (kind != kROOTD_AUTH) {
02144 return 0;
02145 } else {
02146 return retval;
02147 }
02148 }
02149
02150
02151 const char *TAuthenticate::GetSshUser(TString user) const
02152 {
02153
02154
02155
02156
02157 R__LOCKGUARD2(gAuthenticateMutex);
02158
02159 static TString usr = "";
02160
02161 if (user == "") {
02162 if (fgPromptUser) {
02163 char *p = PromptUser(fRemote);
02164 usr = p;
02165 delete [] p;
02166 } else {
02167 usr = fgDefaultUser;
02168 if (usr == "") {
02169 char *p = PromptUser(fRemote);
02170 usr = p;
02171 delete [] p;
02172 }
02173 }
02174 } else {
02175 usr = user;
02176 }
02177
02178 return usr;
02179 }
02180
02181
02182 Bool_t TAuthenticate::CheckHost(const char *host, const char *href)
02183 {
02184
02185
02186
02187
02188
02189 R__LOCKGUARD2(gAuthenticateMutex);
02190
02191 Bool_t retval = kTRUE;
02192
02193
02194 if (!host || !href)
02195 return kFALSE;
02196
02197
02198 if (!strcmp(href,"*"))
02199 return kTRUE;
02200
02201
02202
02203
02204 Bool_t name = kFALSE;
02205 TRegexp rename("[+a-zA-Z]");
02206 Int_t len;
02207 if (rename.Index(href,&len) != -1 || strstr(href,"-"))
02208 name = kTRUE;
02209
02210
02211 Bool_t wild = kFALSE;
02212 if (strstr(href,"*"))
02213 wild = kTRUE;
02214
02215
02216 TRegexp rehost(href,wild);
02217
02218
02219 TString theHost(host);
02220 if (!name) {
02221 TInetAddress addr = gSystem->GetHostByName(host);
02222 theHost = addr.GetHostAddress();
02223 if (gDebug > 2)
02224 ::Info("TAuthenticate::CheckHost", "checking host IP: %s", theHost.Data());
02225 }
02226
02227
02228 Ssiz_t pos = rehost.Index(theHost,&len);
02229 if (pos == -1)
02230 retval = kFALSE;
02231
02232
02233
02234 if (!wild) {
02235 if (pos > 0 && pos != (Ssiz_t)(theHost.Length()-strlen(href)))
02236 retval = kFALSE;
02237 }
02238
02239 return retval;
02240 }
02241
02242
02243 Int_t TAuthenticate::RfioAuth(TString &username)
02244 {
02245
02246
02247
02248
02249
02250 if (gDebug > 2)
02251 Info("RfioAuth", "enter ... username %s", username.Data());
02252
02253
02254 UserGroup_t *pw = gSystem->GetUserInfo(gSystem->GetEffectiveUid());
02255 if (pw) {
02256
02257
02258 username = pw->fUser;
02259 fDetails = TString("pt:0 ru:0 us:") + username;
02260
02261
02262 if (pw->fUid != 0) {
02263
02264 UserGroup_t *grp = gSystem->GetGroupInfo(gSystem->GetEffectiveGid());
02265
02266
02267 Int_t uid = pw->fUid;
02268 Int_t gid = grp ? grp->fGid : pw->fGid;
02269
02270 delete grp;
02271
02272
02273 TString sstr = TString(Form("%d %d", uid, gid));
02274 if (gDebug > 3)
02275 Info("RfioAuth", "sending ... %s", sstr.Data());
02276 Int_t ns = 0;
02277 if ((ns = fSocket->Send(sstr.Data(), kROOTD_RFIO)) < 0)
02278 return 0;
02279 if (gDebug > 3)
02280 Info("RfioAuth", "sent ... %d bytes (expected > %d)", ns,
02281 sstr.Length());
02282
02283
02284 Int_t stat, kind;
02285 if (fSocket->Recv(stat, kind) < 0)
02286 return 0;
02287 if (gDebug > 3)
02288 Info("RfioAuth", "after kROOTD_RFIO: kind= %d, stat= %d", kind,
02289 stat);
02290
02291
02292 if (kind == kROOTD_AUTH && stat >= 1) {
02293
02294 fSecContext =
02295 fHostAuth->CreateSecContext((const char *)pw->fUser,
02296 fRemote, kRfio, -stat, fDetails, 0);
02297 delete pw;
02298 return 1;
02299 } else {
02300 TString server = "sockd";
02301 if (fProtocol.Contains("root"))
02302 server = "rootd";
02303 if (fProtocol.Contains("proof"))
02304 server = "proofd";
02305
02306
02307 if (stat == kErrConnectionRefused) {
02308 if (gDebug > 0)
02309 Error("RfioAuth",
02310 "%s@%s does not accept connections from %s%s",
02311 server.Data(),fRemote.Data(),
02312 fUser.Data(),gSystem->HostName());
02313 delete pw;
02314 return -2;
02315 } else if (stat == kErrNotAllowed) {
02316 if (gDebug > 0)
02317 Error("RfioAuth",
02318 "%s@%s does not accept %s authentication from %s@%s",
02319 server.Data(),fRemote.Data(),
02320 TAuthenticate::fgAuthMeth[5].Data(),
02321 fUser.Data(),gSystem->HostName());
02322 } else {
02323 AuthError("RfioAuth", stat);
02324 }
02325 delete pw;
02326 return 0;
02327 }
02328 } else {
02329 Warning("RfioAuth", "UidGid login as \"root\" not allowed");
02330 return -1;
02331 }
02332 }
02333 return -1;
02334 }
02335
02336
02337 Int_t TAuthenticate::ClearAuth(TString &user, TString &passwd, Bool_t &pwdhash)
02338 {
02339
02340
02341
02342
02343 R__LOCKGUARD2(gAuthenticateMutex);
02344
02345 if (gDebug > 2)
02346 Info("ClearAuth", "enter: user: %s (passwd hashed?: %d)",
02347 user.Data(),(Int_t)pwdhash);
02348
02349 Int_t reuse = fgAuthReUse;
02350 Int_t prompt = fgPromptUser;
02351 Int_t cryptopt = fgUsrPwdCrypt;
02352 Int_t needsalt = 1;
02353 if (pwdhash)
02354 needsalt = 0;
02355 fDetails = TString(Form("pt:%d ru:%d cp:%d us:",
02356 fgPromptUser, fgAuthReUse, fgUsrPwdCrypt)) + user;
02357 if (gDebug > 2)
02358 Info("ClearAuth", "ru:%d pt:%d cp:%d ns:%d rk:%d",
02359 fgAuthReUse,fgPromptUser,fgUsrPwdCrypt,needsalt,fgRSAKey);
02360 #ifdef R__WIN32
02361 needsalt = 0;
02362 #endif
02363 Int_t stat, kind;
02364
02365 if (fVersion > 1) {
02366
02367
02368
02369
02370 Int_t anon = 0;
02371 TString salt = "";
02372 TString pashash = "";
02373
02374
02375 UserGroup_t *pw = gSystem->GetUserInfo(gSystem->GetEffectiveUid());
02376 TString effUser;
02377 if (pw) {
02378 effUser = TString(pw->fUser);
02379 delete pw;
02380 } else
02381 effUser = user;
02382
02383
02384 int opt = (reuse * kAUTH_REUSE_MSK) + (cryptopt * kAUTH_CRYPT_MSK) +
02385 (needsalt * kAUTH_SSALT_MSK) + (fRSAKey * kAUTH_RSATY_MSK);
02386 TString options(Form("%d %ld %s %ld %s", opt,
02387 (Long_t)user.Length(), user.Data(),
02388 (Long_t)effUser.Length(), effUser.Data()));
02389
02390
02391 kind = kROOTD_USER;
02392 stat = reuse;
02393 Int_t rc = 0;
02394 if ((rc = AuthExists(user, (Int_t) TAuthenticate::kClear, options,
02395 &kind, &stat, &StdCheckSecCtx)) == 1) {
02396
02397 return 1;
02398 }
02399 if (rc == -2) {
02400 return rc;
02401 }
02402 if (stat == kErrNotAllowed && kind == kROOTD_ERR) {
02403 return 0;
02404 }
02405
02406 if (kind == kROOTD_AUTH && stat == -1) {
02407 if (gDebug > 3)
02408 Info("ClearAuth", "anonymous user");
02409 anon = 1;
02410 cryptopt = 0;
02411 reuse = 0;
02412 needsalt = 0;
02413 }
02414
02415
02416
02417 char ctag[11] = {0};
02418 if (anon == 0 && cryptopt == 1) {
02419
02420
02421 if (kind != kROOTD_RSAKEY || stat < 1 || stat > 2 ) {
02422
02423 if (kind != kROOTD_ERR) {
02424 Warning("ClearAuth",
02425 "problems recvn RSA key flag: got message %d, flag: %d",
02426 kind, stat);
02427 }
02428 return 0;
02429 }
02430 if (gDebug > 3)
02431 Info("ClearAuth", "get key request ...");
02432
02433
02434 fRSAKey = stat - 1;
02435
02436
02437 if (SendRSAPublicKey(fSocket,fRSAKey) < 0)
02438 return 0;
02439
02440 int slen = 0;
02441 if (needsalt) {
02442
02443 char *tmpsalt = 0;
02444 if ((slen = SecureRecv(fSocket, 1, fRSAKey, &tmpsalt)) == -1) {
02445 Warning("ClearAuth", "problems secure-receiving salt -"
02446 " may result in corrupted salt");
02447 Warning("ClearAuth", "switch off reuse for this session");
02448 needsalt = 0;
02449 return 0;
02450 }
02451 if (slen) {
02452
02453 if (slen > 9) {
02454 int ltmp = slen;
02455 while (ltmp && tmpsalt[ltmp-1] != '#') ltmp--;
02456 if (ltmp) {
02457 if (tmpsalt[ltmp-1] == '#' &&
02458 tmpsalt[ltmp-10] == '#') {
02459 strlcpy(ctag,&tmpsalt[ltmp-10],11);
02460
02461 ltmp -= 10;
02462 tmpsalt[ltmp] = 0;
02463
02464 slen -= 10;
02465 }
02466 }
02467 if (!strlen(tmpsalt)) {
02468
02469 needsalt = 0;
02470 slen = 0;
02471 }
02472 }
02473 if (slen)
02474 salt = TString(tmpsalt);
02475 delete [] tmpsalt;
02476 }
02477 if (gDebug > 2)
02478 Info("ClearAuth", "got salt: '%s' (len: %d)", salt.Data(), slen);
02479 } else {
02480 if (gDebug > 2)
02481 Info("ClearAuth", "Salt not required");
02482 char *tmptag = 0;
02483 if (SecureRecv(fSocket, 1, fRSAKey, &tmptag) == -1) {
02484 Warning("ClearAuth", "problems secure-receiving rndmtag -"
02485 " may result in corrupted rndmtag");
02486 }
02487 if (tmptag) {
02488 strlcpy(ctag, tmptag, 11);
02489 delete [] tmptag;
02490 }
02491 }
02492
02493
02494 if (!slen)
02495 needsalt = 0;
02496 }
02497
02498 if (anon == 1) {
02499
02500 if (fgPasswd.Contains("@")) {
02501
02502 passwd = fgPasswd;
02503 } else {
02504
02505 TString localuser;
02506 pw = gSystem->GetUserInfo();
02507 if (pw)
02508 localuser = StrDup(pw->fUser);
02509 delete pw;
02510 static TString localFQDN;
02511 if (localFQDN == "") {
02512 TInetAddress addr = gSystem->GetHostByName(gSystem->HostName());
02513 if (addr.IsValid())
02514 localFQDN = addr.GetHostName();
02515 }
02516 passwd = Form("%s@%s", localuser.Data(), localFQDN.Data());
02517 if (gDebug > 2)
02518 Info("ClearAuth",
02519 "automatically generated anonymous passwd: %s",
02520 passwd.Data());
02521 }
02522
02523 } else {
02524
02525 if (prompt == 1 || pashash.Length() == 0) {
02526
02527 if (passwd == "") {
02528 TString xp(Form("%s@%s password: ", user.Data(),fRemote.Data()));
02529 char *pwd = PromptPasswd(xp);
02530 passwd = TString(pwd);
02531 delete [] pwd;
02532 if (passwd == "") {
02533 Error("ClearAuth", "password not set");
02534 fSocket->Send("-1", kROOTD_PASS);
02535 return 0;
02536 }
02537 }
02538 if (needsalt && !pwdhash) {
02539 #ifndef R__WIN32
02540 pashash = TString(crypt(passwd, salt));
02541 if (!pashash.BeginsWith(salt)) {
02542
02543
02544 pashash = passwd;
02545 }
02546 #else
02547 pashash = passwd;
02548 #endif
02549 } else {
02550 pashash = passwd;
02551 }
02552 }
02553
02554 }
02555
02556
02557 fgUser = fUser;
02558 fgPwHash = kFALSE;
02559 fPwHash = kFALSE;
02560 fgPasswd = passwd;
02561 fPasswd = passwd;
02562 fSRPPwd = kFALSE;
02563 fgSRPPwd = kFALSE;
02564
02565
02566 if (anon == 0 && cryptopt == 1) {
02567
02568
02569 if (fSocket->Send("\0", kROOTD_PASS) < 0)
02570 return 0;
02571
02572
02573
02574 if (strlen(ctag))
02575 pashash += ctag;
02576
02577 if (SecureSend(fSocket, 1, fRSAKey, pashash.Data()) == -1) {
02578 Warning("ClearAuth", "problems secure-sending pass hash"
02579 " - may result in authentication failure");
02580 return 0;
02581 }
02582 } else {
02583
02584
02585 if (passwd != "") {
02586 for (int i = 0; i < passwd.Length(); i++) {
02587 char inv = ~passwd(i);
02588 passwd.Replace(i, 1, inv);
02589 }
02590 }
02591 if (fSocket->Send(passwd.Data(), kROOTD_PASS) < 0)
02592 return 0;
02593 }
02594
02595 Int_t nrec = 0;
02596
02597 if ((nrec = fSocket->Recv(stat, kind)) < 0 )
02598 return 0;
02599 if (gDebug > 3)
02600 Info("ClearAuth", "after kROOTD_PASS: kind= %d, stat= %d", kind,
02601 stat);
02602
02603
02604 if (kind == kROOTD_ERR) {
02605 AuthError("ClearAuth", stat);
02606 fgPasswd = "";
02607 return 0;
02608 }
02609
02610 if (kind != kROOTD_PASS || stat < 1)
02611 Warning("ClearAuth",
02612 "problems recvn (user,offset) length (%d:%d bytes:%d)",
02613 kind, stat, nrec);
02614
02615
02616 char answer[256];
02617 int reclen = (stat+1 > 256) ? 256 : stat+1;
02618 if ((nrec = fSocket->Recv(answer, reclen, kind)) < 0)
02619 return 0;
02620 if (kind != kMESS_STRING)
02621 Warning("ClearAuth",
02622 "username and offset not received (%d:%d)", kind,
02623 nrec);
02624
02625
02626 char lUser[128];
02627 Int_t offset = -1;
02628 sscanf(answer, "%127s %d", lUser, &offset);
02629 if (gDebug > 3)
02630 Info("ClearAuth",
02631 "received from server: user: %s, offset: %d (%s)", lUser,
02632 offset, answer);
02633
02634
02635 user = lUser;
02636
02637 char *token = 0;
02638 if (reuse == 1 && offset > -1) {
02639
02640 if (cryptopt == 1) {
02641 if (SecureRecv(fSocket, 1, fRSAKey, &token) == -1) {
02642 Warning("ClearAuth",
02643 "problems secure-receiving token -"
02644 " may result in corrupted token");
02645 return 0;
02646 }
02647 } else {
02648 Int_t tlen = 9;
02649 token = new char[tlen];
02650 if (fSocket->Recv(token, tlen, kind) < 0) {
02651 delete [] token;
02652 return 0;
02653 }
02654 if (kind != kMESS_STRING)
02655 Warning("ClearAuth", "token not received (%d:%d)", kind,
02656 nrec);
02657
02658 for (int i = 0; i < (int) strlen(token); i++) {
02659 token[i] = ~token[i];
02660 }
02661
02662 }
02663 if (gDebug > 3)
02664 Info("ClearAuth", "received from server: token: '%s' ",
02665 token);
02666 }
02667 TPwdCtx *pwdctx = new TPwdCtx(fPasswd,fPwHash);
02668
02669 fSecContext = fHostAuth->CreateSecContext((const char *)lUser, fRemote,
02670 kClear, offset, fDetails, (const char *)token,
02671 fgExpDate, (void *)pwdctx, fRSAKey);
02672
02673
02674 if (token)
02675 delete [] token;
02676
02677
02678 if (fSocket->Recv(stat, kind) < 0)
02679 return 0;
02680
02681
02682 if (kind == kROOTD_AUTH && stat >= 1) {
02683 if (stat == 5 && fSocket->GetServType() == TSocket::kPROOFD)
02684
02685
02686
02687
02688 fSecContext->SetID("AFS authentication");
02689 return 1;
02690 } else {
02691 fgPasswd = "";
02692 if (kind == kROOTD_ERR)
02693 AuthError("ClearAuth", stat);
02694 return 0;
02695 }
02696
02697 } else {
02698
02699
02700
02701
02702 if (fSocket->Send(user.Data(), kROOTD_USER) < 0)
02703 return 0;
02704
02705
02706 if (fSocket->Recv(stat, kind) < 0)
02707 return 0;
02708
02709
02710
02711 if (kind == kROOTD_AUTH && stat == 1) {
02712 fSecContext =
02713 fHostAuth->CreateSecContext(user,fRemote,kClear,-1,fDetails,0);
02714 return 1;
02715 }
02716
02717 if (kind == kROOTD_ERR) {
02718 TString server = "sockd";
02719 if (fProtocol.Contains("root"))
02720 server = "rootd";
02721 if (fProtocol.Contains("proof"))
02722 server = "proofd";
02723 if (stat == kErrConnectionRefused) {
02724 if (gDebug > 0)
02725 Error("ClearAuth",
02726 "%s@%s does not accept connections from %s@%s",
02727 server.Data(),fRemote.Data(),
02728 fUser.Data(),gSystem->HostName());
02729 return -2;
02730 } else if (stat == kErrNotAllowed) {
02731 if (gDebug > 0)
02732 Error("ClearAuth",
02733 "%s@%s does not accept %s authentication from %s@%s",
02734 server.Data(),fRemote.Data(),
02735 TAuthenticate::fgAuthMeth[0].Data(),
02736 fUser.Data(),gSystem->HostName());
02737 } else
02738 AuthError("ClearAuth", stat);
02739 return 0;
02740 }
02741
02742 badpass1:
02743 if (passwd == "") {
02744 TString xp(Form("%s@%s password: ", user.Data(),fRemote.Data()));
02745 char *p = PromptPasswd(xp);
02746 passwd = p;
02747 delete [] p;
02748 if (passwd == "")
02749 Error("ClearAuth", "password not set");
02750 }
02751 if (fUser == "anonymous" || fUser == "rootd") {
02752 if (!passwd.Contains("@")) {
02753 Warning("ClearAuth",
02754 "please use passwd of form: user@host.do.main");
02755 passwd = "";
02756 goto badpass1;
02757 }
02758 }
02759
02760 fgPasswd = passwd;
02761 fPasswd = passwd;
02762
02763
02764 if (passwd != "") {
02765 for (int i = 0; i < passwd.Length(); i++) {
02766 char inv = ~passwd(i);
02767 passwd.Replace(i, 1, inv);
02768 }
02769 }
02770
02771 if (fSocket->Send(passwd, kROOTD_PASS) < 0)
02772 return 0;
02773
02774
02775 if (fSocket->Recv(stat, kind) < 0)
02776 return 0;
02777 if (gDebug > 3)
02778 Info("ClearAuth", "after kROOTD_PASS: kind= %d, stat= %d", kind,
02779 stat);
02780
02781 if (kind == kROOTD_AUTH && stat == 1) {
02782 fSecContext =
02783 fHostAuth->CreateSecContext(user,fRemote,kClear,-1,fDetails,0);
02784 return 1;
02785 } else {
02786 if (kind == kROOTD_ERR)
02787 AuthError("ClearAuth", stat);
02788 return 0;
02789 }
02790 }
02791 return 0;
02792 }
02793
02794
02795 THostAuth *TAuthenticate::GetHostAuth(const char *host, const char *user,
02796 Option_t *opt, Int_t *exact)
02797 {
02798
02799
02800
02801
02802
02803 if (exact)
02804 *exact = 0;
02805
02806 if (gDebug > 2)
02807 ::Info("TAuthenticate::GetHostAuth", "enter ... %s ... %s", host, user);
02808
02809
02810 Int_t srvtyp = -1;
02811 TString hostname = host;
02812 if (hostname.Contains(":")) {
02813 char *ps = (char *)strstr(host,":");
02814 if (ps)
02815 srvtyp = atoi(ps+1);
02816 hostname.Remove(hostname.Index(":"));
02817 }
02818 TString hostFQDN = hostname;
02819 if (strncmp(host,"default",7) && !hostFQDN.Contains("*")) {
02820 TInetAddress addr = gSystem->GetHostByName(hostFQDN);
02821 if (addr.IsValid())
02822 hostFQDN = addr.GetHostName();
02823 }
02824 TString usr = user;
02825 if (!usr.Length())
02826 usr = "*";
02827 THostAuth *rHA = 0;
02828
02829
02830 TIter *next = new TIter(GetAuthInfo());
02831 if (!strncasecmp(opt,"P",1)) {
02832 SafeDelete(next);
02833 next = new TIter(GetProofAuthInfo());
02834 }
02835
02836 THostAuth *ai;
02837 Bool_t notFound = kTRUE;
02838 Bool_t serverOK = kTRUE;
02839 while ((ai = (THostAuth *) (*next)())) {
02840 if (gDebug > 3)
02841 ai->Print("Authenticate::GetHostAuth");
02842
02843
02844 if (!(serverOK = (ai->GetServer() == -1) ||
02845 (ai->GetServer() == srvtyp)))
02846 continue;
02847
02848
02849 if (!strcmp(ai->GetHost(),"default") && serverOK && notFound)
02850 rHA = ai;
02851
02852
02853 if (CheckHost(hostFQDN,ai->GetHost()) &&
02854 CheckHost(usr,ai->GetUser()) && serverOK) {
02855 rHA = ai;
02856 notFound = kFALSE;
02857 }
02858
02859 if (hostFQDN == ai->GetHost() &&
02860 usr == ai->GetUser() && srvtyp == ai->GetServer() ) {
02861 rHA = ai;
02862 if (exact)
02863 *exact = 1;
02864 break;
02865 }
02866 }
02867 SafeDelete(next);
02868 return rHA;
02869 }
02870
02871
02872 THostAuth *TAuthenticate::HasHostAuth(const char *host, const char *user,
02873 Option_t *opt)
02874 {
02875
02876
02877
02878
02879
02880 if (gDebug > 2)
02881 ::Info("TAuthenticate::HasHostAuth", "enter ... %s ... %s", host, user);
02882
02883
02884 Int_t srvtyp = -1;
02885 TString hostFQDN = host;
02886 if (hostFQDN.Contains(":")) {
02887 char *ps = (char *)strstr(host,":");
02888 if (ps)
02889 srvtyp = atoi(ps+1);
02890 hostFQDN.Remove(hostFQDN.Index(":"));
02891 }
02892 if (strncmp(host,"default",7) && !hostFQDN.Contains("*")) {
02893 TInetAddress addr = gSystem->GetHostByName(hostFQDN);
02894 if (addr.IsValid())
02895 hostFQDN = addr.GetHostName();
02896 }
02897
02898 TIter *next = new TIter(GetAuthInfo());
02899 if (!strncasecmp(opt,"P",1)) {
02900 SafeDelete(next);
02901 next = new TIter(GetProofAuthInfo());
02902 }
02903 THostAuth *ai;
02904 while ((ai = (THostAuth *) (*next)())) {
02905
02906 if (hostFQDN == ai->GetHost() &&
02907 !strcmp(user, ai->GetUser()) && srvtyp == ai->GetServer()) {
02908 SafeDelete(next);
02909 return ai;
02910 }
02911 }
02912 SafeDelete(next);
02913 return 0;
02914 }
02915
02916
02917 void TAuthenticate::FileExpand(const char *fexp, FILE *ftmp)
02918 {
02919
02920
02921
02922
02923 FILE *fin;
02924 char line[kMAXPATHLEN];
02925 char cinc[20], fileinc[kMAXPATHLEN];
02926
02927 if (gDebug > 2)
02928 ::Info("TAuthenticate::FileExpand", "enter ... '%s' ... 0x%lx", fexp, (Long_t)ftmp);
02929
02930 fin = fopen(fexp, "r");
02931 if (fin == 0)
02932 return;
02933
02934 while (fgets(line, sizeof(line), fin) != 0) {
02935
02936 if (line[0] == '#')
02937 continue;
02938 if (line[strlen(line) - 1] == '\n')
02939 line[strlen(line) - 1] = '\0';
02940 if (gDebug > 2)
02941 ::Info("TAuthenticate::FileExpand", "read line ... '%s'", line);
02942 int nw = sscanf(line, "%19s %8191s", cinc, fileinc);
02943 if (nw < 1)
02944 continue;
02945 if (strcmp(cinc, "include") != 0) {
02946
02947 fprintf(ftmp, "%s\n", line);
02948 } else {
02949
02950
02951 TString ln(line);
02952 ln.ReplaceAll("\"",1,"",0);
02953 ln.ReplaceAll("'",1,"",0);
02954 sscanf(ln.Data(), "%19s %8191s", cinc, fileinc);
02955
02956
02957 if (fileinc[0] == '$') {
02958 TString finc(fileinc);
02959 TString edir(fileinc);
02960 if (edir.Contains("/")) {
02961 edir.Remove(edir.Index("/"));
02962 edir.Remove(0,1);
02963 if (gSystem->Getenv(edir.Data())) {
02964 finc.Remove(0,1);
02965 finc.ReplaceAll(edir.Data(),gSystem->Getenv(edir.Data()));
02966 fileinc[0] = '\0';
02967 strncpy(fileinc,finc.Data(),kMAXPATHLEN);
02968 fileinc[kMAXPATHLEN-1] = '\0';
02969 }
02970 }
02971 }
02972
02973
02974 if (fileinc[0] == '~') {
02975
02976 int flen =
02977 strlen(fileinc) + strlen(gSystem->HomeDirectory()) + 10;
02978 char *ffull = new char[flen];
02979 snprintf(ffull, flen, "%s/%s", gSystem->HomeDirectory(), fileinc + 1);
02980 if (strlen(ffull) < kMAXPATHLEN - 1) strlcpy(fileinc, ffull,kMAXPATHLEN);
02981 delete [] ffull;
02982 }
02983
02984 if (!gSystem->AccessPathName(fileinc, kReadPermission)) {
02985 FileExpand(fileinc, ftmp);
02986 } else {
02987 ::Warning("TAuthenticate::FileExpand",
02988 "file specified by 'include' cannot be open or read (%s)",
02989 fileinc);
02990 }
02991 }
02992 }
02993 fclose(fin);
02994 }
02995
02996
02997 char *TAuthenticate::GetDefaultDetails(int sec, int opt, const char *usr)
02998 {
02999
03000
03001
03002 char temp[kMAXPATHLEN] = { 0 };
03003 const char copt[2][5] = { "no", "yes" };
03004
03005 if (gDebug > 2)
03006 ::Info("TAuthenticate::GetDefaultDetails",
03007 "enter ... %d ...pt:%d ... '%s'", sec, opt, usr);
03008
03009 if (opt < 0 || opt > 1)
03010 opt = 1;
03011
03012
03013 if (sec == TAuthenticate::kClear) {
03014 if (strlen(usr) == 0 || !strncmp(usr,"*",1))
03015 usr = gEnv->GetValue("UsrPwd.Login", "");
03016 snprintf(temp, kMAXPATHLEN, "pt:%s ru:%s cp:%s us:%s",
03017 gEnv->GetValue("UsrPwd.LoginPrompt", copt[opt]),
03018 gEnv->GetValue("UsrPwd.ReUse", "1"),
03019 gEnv->GetValue("UsrPwd.Crypt", "1"), usr);
03020
03021
03022 } else if (sec == TAuthenticate::kSRP) {
03023 if (strlen(usr) == 0 || !strncmp(usr,"*",1))
03024 usr = gEnv->GetValue("SRP.Login", "");
03025 snprintf(temp, kMAXPATHLEN, "pt:%s ru:%s us:%s",
03026 gEnv->GetValue("SRP.LoginPrompt", copt[opt]),
03027 gEnv->GetValue("SRP.ReUse", "0"), usr);
03028
03029
03030 } else if (sec == TAuthenticate::kKrb5) {
03031 if (strlen(usr) == 0 || !strncmp(usr,"*",1))
03032 usr = gEnv->GetValue("Krb5.Login", "");
03033 snprintf(temp, kMAXPATHLEN, "pt:%s ru:%s us:%s",
03034 gEnv->GetValue("Krb5.LoginPrompt", copt[opt]),
03035 gEnv->GetValue("Krb5.ReUse", "0"), usr);
03036
03037
03038 } else if (sec == TAuthenticate::kGlobus) {
03039 snprintf(temp, kMAXPATHLEN,"pt:%s ru:%s %s",
03040 gEnv->GetValue("Globus.LoginPrompt", copt[opt]),
03041 gEnv->GetValue("Globus.ReUse", "1"),
03042 gEnv->GetValue("Globus.Login", ""));
03043
03044
03045 } else if (sec == TAuthenticate::kSSH) {
03046 if (strlen(usr) == 0 || !strncmp(usr,"*",1))
03047 usr = gEnv->GetValue("SSH.Login", "");
03048 snprintf(temp, kMAXPATHLEN, "pt:%s ru:%s us:%s",
03049 gEnv->GetValue("SSH.LoginPrompt", copt[opt]),
03050 gEnv->GetValue("SSH.ReUse", "1"), usr);
03051
03052
03053 } else if (sec == TAuthenticate::kRfio) {
03054 if (strlen(usr) == 0 || !strncmp(usr,"*",1))
03055 usr = gEnv->GetValue("UidGid.Login", "");
03056 snprintf(temp, kMAXPATHLEN, "pt:%s us:%s",
03057 gEnv->GetValue("UidGid.LoginPrompt", copt[opt]), usr);
03058 }
03059 if (gDebug > 2)
03060 ::Info("TAuthenticate::GetDefaultDetails", "returning ... %s", temp);
03061
03062 return StrDup(temp);
03063 }
03064
03065
03066 void TAuthenticate::RemoveHostAuth(THostAuth * ha, Option_t *opt)
03067 {
03068
03069
03070 if (!strncasecmp(opt,"P",1))
03071 GetProofAuthInfo()->Remove(ha);
03072 else
03073 GetAuthInfo()->Remove(ha);
03074
03075 delete ha;
03076 }
03077
03078
03079 void TAuthenticate::Show(Option_t *opt)
03080 {
03081
03082
03083
03084
03085
03086 TString sopt(opt);
03087
03088 if (sopt.Contains("s",TString::kIgnoreCase)) {
03089
03090
03091 TIter next(gROOT->GetListOfSecContexts());
03092 TSecContext *sc = 0;
03093 while ((sc = (TSecContext *)next()))
03094 sc->Print();
03095
03096 } else {
03097
03098 ::Info("::Print",
03099 " +--------------------------- BEGIN --------------------------------+");
03100 ::Info("::Print",
03101 " + +");
03102 if (sopt.Contains("p",TString::kIgnoreCase)) {
03103 ::Info("::Print",
03104 " + List fgProofAuthInfo has %4d members +",
03105 GetProofAuthInfo()->GetSize());
03106 ::Info("::Print",
03107 " + +");
03108 ::Info("::Print",
03109 " +------------------------------------------------------------------+");
03110 TIter next(GetProofAuthInfo());
03111 THostAuth *ai;
03112 while ((ai = (THostAuth *) next())) {
03113 ai->Print();
03114 }
03115 } else {
03116 ::Info("::Print",
03117 " + List fgAuthInfo has %4d members +",
03118 GetAuthInfo()->GetSize());
03119 ::Info("::Print",
03120 " + +");
03121 ::Info("::Print",
03122 " +------------------------------------------------------------------+");
03123 TIter next(GetAuthInfo());
03124 THostAuth *ai;
03125 while ((ai = (THostAuth *) next())) {
03126 ai->Print();
03127 ai->PrintEstablished();
03128 }
03129 }
03130 ::Info("::Print",
03131 " +---------------------------- END ---------------------------------+");
03132 }
03133 }
03134
03135
03136 Int_t TAuthenticate::AuthExists(TString username, Int_t method, const char *options,
03137 Int_t *message, Int_t *rflag,
03138 CheckSecCtx_t checksecctx)
03139 {
03140
03141
03142
03143
03144
03145
03146 if (gDebug > 2)
03147 Info("AuthExists","%d: enter: msg: %d options: '%s'",
03148 method,*message, options);
03149
03150
03151 Bool_t notHA = kFALSE;
03152
03153
03154 TIter next(fHostAuth->Established());
03155 TRootSecContext *secctx;
03156 while ((secctx = (TRootSecContext *)next())) {
03157 if (secctx->GetMethod() == method) {
03158 if (fRemote == secctx->GetHost()) {
03159 if (checksecctx &&
03160 (*checksecctx)(username,secctx) == 1)
03161 break;
03162 }
03163 }
03164 }
03165
03166
03167 if (!secctx) {
03168 next = TIter(gROOT->GetListOfSecContexts());
03169 while ((secctx = (TRootSecContext *)next())) {
03170 if (secctx->GetMethod() == method) {
03171 if (fRemote == secctx->GetHost()) {
03172 if (checksecctx &&
03173 (*checksecctx)(username,secctx) == 1) {
03174 notHA = kTRUE;
03175 break;
03176 }
03177 }
03178 }
03179 }
03180 }
03181
03182
03183 Int_t offset = -1;
03184 TString token;
03185 if (secctx) {
03186 offset = secctx->GetOffSet();
03187 token = secctx->GetToken();
03188 if (gDebug > 2)
03189 Info("AuthExists",
03190 "found valid TSecContext: offset: %d token: '%s'",
03191 offset, token.Data());
03192 }
03193
03194
03195 TString sstr(Form("%d %d %s", fgProcessID, offset, options));
03196
03197
03198 if (fSocket->Send(sstr, *message) < 0)
03199 return -2;
03200
03201 Int_t reuse = *rflag;
03202 if (reuse == 1 && offset > -1) {
03203
03204
03205
03206
03207
03208 Int_t rproto = fSocket->GetRemoteProtocol();
03209 Bool_t oldsrv = ((fProtocol.BeginsWith("root") && rproto == 9) ||
03210 (fProtocol.BeginsWith("proof") && rproto == 8));
03211 Int_t stat = 1, kind;
03212 if (!oldsrv) {
03213 if (fSocket->Recv(stat, kind) < 0)
03214 return -2;
03215 if (kind != kROOTD_AUTH)
03216 Warning("AuthExists","protocol error: expecting %d got %d"
03217 " (value: %d)",kROOTD_AUTH,kind,stat);
03218 }
03219
03220 if (stat > 0) {
03221 if (gDebug > 2)
03222 Info("AuthExists","offset OK");
03223
03224 Int_t rsaKey = secctx->GetRSAKey();
03225 if (gDebug > 2)
03226 Info("AuthExists", "key type: %d", rsaKey);
03227
03228 if (rsaKey > -1) {
03229
03230
03231
03232 if (stat > 1) {
03233
03234 char tag[9] = {0};
03235 snprintf(tag, 9, "%08x",stat);
03236
03237 token += tag;
03238 }
03239
03240
03241 if (SecureSend(fSocket, 1, rsaKey, token) == -1) {
03242 Warning("AuthExists", "problems secure-sending token %s",
03243 "- may trigger problems in proofing Id ");
03244 return -2;
03245 }
03246 } else {
03247
03248 for (int i = 0; i < token.Length(); i++) {
03249 char inv = ~token(i);
03250 token.Replace(i, 1, inv);
03251 }
03252 if (fSocket->Send(token, kMESS_STRING) < 0)
03253 return -2;
03254 }
03255 } else {
03256 if (gDebug > 0)
03257 Info("AuthExists","offset not OK - rerun authentication");
03258
03259 if (secctx)
03260 secctx->DeActivate("");
03261 }
03262 }
03263
03264 Int_t stat, kind;
03265 if (fSocket->Recv(stat, kind) < 0)
03266 return -2;
03267 if (gDebug > 3)
03268 Info("AuthExists","%d: after msg %d: kind= %d, stat= %d",
03269 method,*message, kind, stat);
03270
03271
03272 *message = kind;
03273 *rflag = stat;
03274
03275 if (kind == kROOTD_ERR) {
03276 TString server = "sockd";
03277 if (fSocket->GetServType() == TSocket::kROOTD)
03278 server = "rootd";
03279 if (fSocket->GetServType() == TSocket::kPROOFD)
03280 server = "proofd";
03281 if (stat == kErrConnectionRefused) {
03282 Error("AuthExists","%s@%s does not accept connections from %s@%s",
03283 server.Data(),fRemote.Data(),fUser.Data(),gSystem->HostName());
03284 return -2;
03285 } else if (stat == kErrNotAllowed) {
03286 if (gDebug > 0)
03287 Info("AuthExists",
03288 "%s@%s does not accept %s authentication from %s@%s",
03289 server.Data(),fRemote.Data(), fgAuthMeth[method].Data(),
03290 fUser.Data(),gSystem->HostName());
03291 } else
03292 AuthError("AuthExists", stat);
03293
03294
03295 if (secctx)
03296 secctx->DeActivate("");
03297 return 0;
03298 }
03299
03300 if (kind == kROOTD_AUTH && stat >= 1) {
03301 if (!secctx)
03302 secctx =
03303 fHostAuth->CreateSecContext(fUser,fRemote,method,-stat,fDetails,0);
03304 if (gDebug > 3) {
03305 if (stat == 1)
03306 Info("AuthExists", "valid authentication exists");
03307 if (stat == 2)
03308 Info("AuthExists", "valid authentication exists: offset changed");
03309 if (stat == 3)
03310 Info("AuthExists", "remote access authorized by /etc/hosts.equiv");
03311 if (stat == 4)
03312 Info("AuthExists", "no authentication required remotely");
03313 }
03314
03315 if (stat == 2) {
03316 int newOffSet;
03317
03318 if (fSocket->Recv(newOffSet, kind) < 0)
03319 return -2;
03320
03321 secctx->SetOffSet(newOffSet);
03322 }
03323
03324 fSecContext = secctx;
03325
03326 if (notHA)
03327 fHostAuth->Established()->Add(secctx);
03328 return 1;
03329 }
03330 return 0;
03331 }
03332
03333
03334 void TAuthenticate::InitRandom()
03335 {
03336
03337
03338
03339 static Bool_t notinit = kTRUE;
03340
03341 if (notinit) {
03342 const char *randdev = "/dev/urandom";
03343 Int_t fd;
03344 UInt_t seed;
03345 if ((fd = open(randdev, O_RDONLY)) != -1) {
03346 if (gDebug > 2)
03347 ::Info("InitRandom", "taking seed from %s", randdev);
03348 if (read(fd, &seed, sizeof(seed)) != sizeof(seed))
03349 ::Warning("InitRandom", "could not read seed from %s", randdev);
03350 close(fd);
03351 } else {
03352 if (gDebug > 2)
03353 ::Info("InitRandom", "%s not available: using time()", randdev);
03354 seed = time(0);
03355 }
03356 srand(seed);
03357 notinit = kFALSE;
03358 }
03359 }
03360
03361
03362 Int_t TAuthenticate::GenRSAKeys()
03363 {
03364
03365
03366
03367 if (gDebug > 2)
03368 Info("GenRSAKeys", "enter");
03369
03370 if (fgRSAInit == 1) {
03371 if (gDebug > 2)
03372 Info("GenRSAKeys", "Keys prviously generated - return");
03373 }
03374
03375
03376 TString lib = "libRsa";
03377
03378
03379 if (!TRSA_fun::RSA_genprim()) {
03380 char *p;
03381 if ((p = gSystem->DynamicPathName(lib, kTRUE))) {
03382 delete [] p;
03383 gSystem->Load(lib);
03384 }
03385 }
03386
03387
03388 TAuthenticate::InitRandom();
03389
03390 #ifdef R__SSL
03391 if (fgRSAKey == 1) {
03392
03393 if (gDebug > 2)
03394 Info("GenRSAKeys","SSL: Generate Blowfish key");
03395
03396
03397 SSL_library_init();
03398
03399
03400 SSL_load_error_strings();
03401
03402
03403 OpenSSL_add_all_ciphers();
03404
03405
03406 Int_t nbits = gEnv->GetValue("SSL.BFBits",256);
03407
03408
03409 nbits = (nbits >= 128) ? nbits : 128;
03410
03411
03412 nbits = (nbits <= 15912) ? nbits : 15912;
03413
03414
03415 Int_t klen = nbits / 8 ;
03416
03417
03418 char *rbuf = GetRandString(0,klen);
03419 RAND_seed(rbuf,strlen(rbuf));
03420
03421
03422 fgRSAPubExport[1].len = klen;
03423 fgRSAPubExport[1].keys = rbuf;
03424 if (gDebug > 2)
03425 Info("GenRSAKeys","SSL: BF key length: %d", fgRSAPubExport[1].len);
03426
03427
03428 BF_set_key(&fgBFKey, klen, (const unsigned char *)rbuf);
03429 }
03430 #endif
03431
03432
03433
03434
03435 Bool_t notOk = 1;
03436 rsa_NUMBER p1, p2, rsa_n, rsa_e, rsa_d;
03437 Int_t l_n = 0, l_e = 0, l_d = 0;
03438 char buf_n[rsa_STRLEN], buf_e[rsa_STRLEN], buf_d[rsa_STRLEN];
03439 #if R__RSADEB
03440 char buf[rsa_STRLEN];
03441 #endif
03442
03443 Int_t nAttempts = 0;
03444 Int_t thePrimeLen = kPRIMELENGTH;
03445 Int_t thePrimeExp = kPRIMEEXP;
03446 while (notOk && nAttempts < kMAXRSATRIES) {
03447
03448 nAttempts++;
03449 if (gDebug > 2 && nAttempts > 1) {
03450 Info("GenRSAKeys", "retry no. %d",nAttempts);
03451 srand(auth_rand());
03452 }
03453
03454
03455 p1 = TRSA_fun::RSA_genprim()(thePrimeLen, thePrimeExp);
03456 p2 = TRSA_fun::RSA_genprim()(thePrimeLen+1, thePrimeExp);
03457
03458
03459 Int_t nPrimes = 0;
03460 while (TRSA_fun::RSA_cmp()(&p1, &p2) == 0 && nPrimes < kMAXRSATRIES) {
03461 nPrimes++;
03462 if (gDebug > 2)
03463 Info("GenRSAKeys", "equal primes: regenerate (%d times)",nPrimes);
03464 srand(auth_rand());
03465 p1 = TRSA_fun::RSA_genprim()(thePrimeLen, thePrimeExp);
03466 p2 = TRSA_fun::RSA_genprim()(thePrimeLen+1, thePrimeExp);
03467 }
03468 #if R__RSADEB
03469 if (gDebug > 3) {
03470 TRSA_fun::RSA_num_sput()(&p1, buf, rsa_STRLEN);
03471 Info("GenRSAKeys", "local: p1: '%s' ", buf);
03472 TRSA_fun::RSA_num_sput()(&p2, buf, rsa_STRLEN);
03473 Info("GenRSAKeys", "local: p2: '%s' ", buf);
03474 }
03475 #endif
03476
03477 if (TRSA_fun::RSA_genrsa()(p1, p2, &rsa_n, &rsa_e, &rsa_d)) {
03478 if (gDebug > 2 && nAttempts > 1)
03479 Info("GenRSAKeys"," genrsa: unable to generate keys (%d)",
03480 nAttempts);
03481 continue;
03482 }
03483
03484
03485 TRSA_fun::RSA_num_sput()(&rsa_n, buf_n, rsa_STRLEN);
03486 l_n = strlen(buf_n);
03487 TRSA_fun::RSA_num_sput()(&rsa_e, buf_e, rsa_STRLEN);
03488 l_e = strlen(buf_e);
03489 TRSA_fun::RSA_num_sput()(&rsa_d, buf_d, rsa_STRLEN);
03490 l_d = strlen(buf_d);
03491
03492 #if R__RSADEB
03493 if (gDebug > 3) {
03494 Info("GenRSAKeys", "local: n: '%s' length: %d", buf_n, l_n);
03495 Info("GenRSAKeys", "local: e: '%s' length: %d", buf_e, l_e);
03496 Info("GenRSAKeys", "local: d: '%s' length: %d", buf_d, l_d);
03497 }
03498 #endif
03499 if (TRSA_fun::RSA_cmp()(&rsa_n, &rsa_e) <= 0)
03500 continue;
03501 if (TRSA_fun::RSA_cmp()(&rsa_n, &rsa_d) <= 0)
03502 continue;
03503
03504
03505 char test[2 * rsa_STRLEN] = "ThisIsTheStringTest01203456-+/";
03506 Int_t lTes = 31;
03507 char *tdum = GetRandString(0, lTes - 1);
03508 strlcpy(test, tdum, lTes+1);
03509 delete [] tdum;
03510 char buf[2 * rsa_STRLEN];
03511 if (gDebug > 3)
03512 Info("GenRSAKeys", "local: test string: '%s' ", test);
03513
03514
03515 strlcpy(buf, test, lTes+1);
03516
03517
03518 int lout = TRSA_fun::RSA_encode()(buf, lTes, rsa_n, rsa_e);
03519 if (gDebug > 3)
03520 Info("GenRSAKeys",
03521 "local: length of crypted string: %d bytes", lout);
03522
03523
03524 TRSA_fun::RSA_decode()(buf, lout, rsa_n, rsa_d);
03525 buf[lTes] = 0;
03526 if (gDebug > 3)
03527 Info("GenRSAKeys", "local: after private/public : '%s' ", buf);
03528
03529 if (strncmp(test, buf, lTes))
03530 continue;
03531
03532
03533 strlcpy(buf, test, lTes+1);
03534
03535
03536 lout = TRSA_fun::RSA_encode()(buf, lTes, rsa_n, rsa_d);
03537 if (gDebug > 3)
03538 Info("GenRSAKeys", "local: length of crypted string: %d bytes ",
03539 lout);
03540
03541
03542 TRSA_fun::RSA_decode()(buf, lout, rsa_n, rsa_e);
03543 buf[lTes] = 0;
03544 if (gDebug > 3)
03545 Info("GenRSAKeys", "local: after public/private : '%s' ", buf);
03546
03547 if (strncmp(test, buf, lTes))
03548 continue;
03549
03550 notOk = 0;
03551 }
03552
03553
03554 TRSA_fun::RSA_assign()(&fgRSAPriKey.n, &rsa_n);
03555 TRSA_fun::RSA_assign()(&fgRSAPriKey.e, &rsa_e);
03556
03557
03558 TRSA_fun::RSA_assign()(&fgRSAPubKey.n, &rsa_n);
03559 TRSA_fun::RSA_assign()(&fgRSAPubKey.e, &rsa_d);
03560
03561 #if R__RSADEB
03562 if (gDebug > 2) {
03563
03564 Info("GenRSAKeys", "local: generated keys are:");
03565 Info("GenRSAKeys", "local: n: '%s' length: %d", buf_n, l_n);
03566 Info("GenRSAKeys", "local: e: '%s' length: %d", buf_e, l_e);
03567 Info("GenRSAKeys", "local: d: '%s' length: %d", buf_d, l_d);
03568 }
03569 #endif
03570
03571 if (fgRSAPubExport[0].keys) {
03572 delete [] fgRSAPubExport[0].keys;
03573 fgRSAPubExport[0].len = 0;
03574 }
03575 fgRSAPubExport[0].len = l_n + l_d + 4;
03576 fgRSAPubExport[0].keys = new char[fgRSAPubExport[0].len];
03577
03578 fgRSAPubExport[0].keys[0] = '#';
03579 memcpy(fgRSAPubExport[0].keys + 1, buf_n, l_n);
03580 fgRSAPubExport[0].keys[l_n + 1] = '#';
03581 memcpy(fgRSAPubExport[0].keys + l_n + 2, buf_d, l_d);
03582 fgRSAPubExport[0].keys[l_n + l_d + 2] = '#';
03583 fgRSAPubExport[0].keys[l_n + l_d + 3] = 0;
03584 #if R__RSADEB
03585 if (gDebug > 2)
03586 Info("GenRSAKeys", "local: export pub: '%s'", fgRSAPubExport[0].keys);
03587 #else
03588 if (gDebug > 2)
03589 Info("GenRSAKeys", "local: export pub length: %d bytes", fgRSAPubExport[0].len);
03590 #endif
03591
03592
03593 fgRSAInit = 1;
03594
03595 return 0;
03596 }
03597
03598
03599 char *TAuthenticate::GetRandString(Int_t opt, Int_t len)
03600 {
03601
03602
03603
03604
03605
03606
03607
03608 int iimx[4][4] = {
03609 {0x0, 0xffffff08, 0xafffffff, 0x2ffffffe},
03610 {0x0, 0x3ff0000, 0x7fffffe, 0x7fffffe},
03611 {0x0, 0x3ff0000, 0x7e, 0x7e},
03612 {0x0, 0x3ffc000, 0x7fffffe, 0x7fffffe}
03613 };
03614
03615 const char *cOpt[4] = { "Any", "LetNum", "Hex", "Crypt" };
03616
03617
03618 if (opt < 0 || opt > 2) {
03619 opt = 0;
03620 if (gDebug > 2)
03621 Info("GetRandString", "unknown option: %d : assume 0", opt);
03622 }
03623 if (gDebug > 2)
03624 Info("GetRandString", "enter ... len: %d %s", len, cOpt[opt]);
03625
03626
03627 char *buf = new char[len + 1];
03628
03629
03630 TAuthenticate::InitRandom();
03631
03632
03633 Int_t k = 0;
03634 Int_t i, j, l, m, frnd;
03635 while (k < len) {
03636 frnd = auth_rand();
03637 for (m = 7; m < 32; m += 7) {
03638 i = 0x7F & (frnd >> m);
03639 j = i / 32;
03640 l = i - j * 32;
03641 if ((iimx[opt][j] & (1 << l))) {
03642 buf[k] = i;
03643 k++;
03644 }
03645 if (k == len)
03646 break;
03647 }
03648 }
03649
03650
03651 buf[len] = 0;
03652 if (gDebug > 3)
03653 Info("GetRandString", "got '%s' ", buf);
03654
03655 return buf;
03656 }
03657
03658
03659 Int_t TAuthenticate::SecureSend(TSocket *sock, Int_t enc,
03660 Int_t key, const char *str)
03661 {
03662
03663
03664
03665
03666
03667 char buftmp[kMAXSECBUF];
03668 char buflen[20];
03669
03670 if (gDebug > 2)
03671 ::Info("TAuthenticate::SecureSend", "local: enter ... (enc: %d)", enc);
03672
03673 Int_t slen = strlen(str) + 1;
03674 Int_t ttmp = 0;
03675 Int_t nsen = -1;
03676
03677 if (key == 0) {
03678 strlcpy(buftmp, str, slen+1);
03679
03680 if (enc == 1)
03681 ttmp = TRSA_fun::RSA_encode()(buftmp, slen, fgRSAPriKey.n,
03682 fgRSAPriKey.e);
03683 else if (enc == 2)
03684 ttmp = TRSA_fun::RSA_encode()(buftmp, slen, fgRSAPubKey.n,
03685 fgRSAPubKey.e);
03686 else
03687 return nsen;
03688 } else if (key == 1) {
03689
03690 #ifdef R__SSL
03691 ttmp = strlen(str);
03692 if ((ttmp % 8) > 0)
03693 ttmp = ((ttmp + 8)/8) * 8;
03694 unsigned char iv[8];
03695 memset((void *)&iv[0],0,8);
03696 BF_cbc_encrypt((const unsigned char *)str, (unsigned char *)buftmp,
03697 strlen(str), &fgBFKey, iv, BF_ENCRYPT);
03698 #else
03699 if (gDebug > 0)
03700 ::Info("TAuthenticate::SecureSend","not compiled with SSL support:"
03701 " you should not have got here!");
03702 #endif
03703 } else {
03704 if (gDebug > 0)
03705 ::Info("TAuthenticate::SecureSend","unknown key type (%d)",key);
03706 return nsen;
03707 }
03708
03709 snprintf(buflen,20,"%d",ttmp);
03710 if (sock->Send(buflen, kROOTD_ENCRYPT) < 0)
03711 return -1;
03712 nsen = sock->SendRaw(buftmp, ttmp);
03713 if (gDebug > 3)
03714 ::Info("TAuthenticate::SecureSend",
03715 "local: sent %d bytes (expected: %d)", nsen,ttmp);
03716
03717 return nsen;
03718 }
03719
03720
03721 Int_t TAuthenticate::SecureRecv(TSocket *sock, Int_t dec, Int_t key, char **str)
03722 {
03723
03724
03725
03726
03727
03728 char buftmp[kMAXSECBUF];
03729 char buflen[20];
03730
03731 Int_t nrec = -1;
03732
03733 if (!str)
03734 return nrec;
03735
03736 Int_t kind;
03737 if (sock->Recv(buflen, 20, kind) < 0)
03738 return -1;
03739 Int_t len = atoi(buflen);
03740 if (gDebug > 3)
03741 ::Info("TAuthenticate::SecureRecv", "got len '%s' %d (msg kind: %d)",
03742 buflen, len, kind);
03743 if (len == 0) {
03744 return len;
03745 }
03746 if (!strncmp(buflen, "-1", 2))
03747 return nrec;
03748
03749
03750 if ((nrec = sock->RecvRaw(buftmp, len)) < 0)
03751 return nrec;
03752 if (key == 0) {
03753 if (dec == 1)
03754 TRSA_fun::RSA_decode()(buftmp, len, fgRSAPriKey.n, fgRSAPriKey.e);
03755 else if (dec == 2)
03756 TRSA_fun::RSA_decode()(buftmp, len, fgRSAPubKey.n, fgRSAPubKey.e);
03757 else
03758 return -1;
03759
03760
03761 *str = new char[strlen(buftmp) + 1];
03762 strlcpy(*str, buftmp,strlen(buftmp) + 1);
03763
03764 } else if (key == 1) {
03765 #ifdef R__SSL
03766 unsigned char iv[8];
03767 memset((void *)&iv[0],0,8);
03768 *str = new char[nrec + 1];
03769 BF_cbc_encrypt((const unsigned char *)buftmp, (unsigned char *)(*str),
03770 nrec, &fgBFKey, iv, BF_DECRYPT);
03771 (*str)[nrec] = '\0';
03772 #else
03773 if (gDebug > 0)
03774 ::Info("TAuthenticate::SecureRecv","not compiled with SSL support:"
03775 " you should not have got here!");
03776 #endif
03777 } else {
03778 if (gDebug > 0)
03779 ::Info("TAuthenticate::SecureRecv","unknown key type (%d)",key);
03780 return -1;
03781 }
03782
03783 nrec= strlen(*str);
03784
03785 return nrec;
03786 }
03787
03788
03789 Int_t TAuthenticate::DecodeRSAPublic(const char *rsaPubExport, rsa_NUMBER &rsa_n,
03790 rsa_NUMBER &rsa_d, char **rsassl)
03791 {
03792
03793
03794 if (!rsaPubExport)
03795 return -1;
03796
03797 if (gDebug > 2)
03798 ::Info("TAuthenticate::DecodeRSAPublic",
03799 "enter: string length: %ld bytes", (Long_t)strlen(rsaPubExport));
03800
03801 char str[kMAXPATHLEN] = { 0 };
03802 Int_t klen = strlen(rsaPubExport);
03803 if (klen > kMAXPATHLEN - 1) {
03804 ::Info("TAuthenticate::DecodeRSAPublic",
03805 "key too long (%d): truncate to %d",klen,kMAXPATHLEN);
03806 klen = kMAXPATHLEN - 1;
03807 }
03808 memcpy(str, rsaPubExport, klen);
03809 str[klen] ='\0';
03810
03811 Int_t keytype = -1;
03812
03813 if (klen > 0) {
03814
03815
03816 int k = 0;
03817 while (str[k] == 32) k++;
03818
03819 if (str[k] == '#') {
03820
03821 keytype = 0;
03822
03823
03824 char *pd1 = strstr(str, "#");
03825 char *pd2 = pd1 ? strstr(pd1 + 1, "#") : (char *)0;
03826 char *pd3 = pd2 ? strstr(pd2 + 1, "#") : (char *)0;
03827 if (pd1 && pd2 && pd3) {
03828
03829 int l1 = (int) (pd2 - pd1 - 1);
03830 char *rsa_n_exp = new char[l1 + 1];
03831 strlcpy(rsa_n_exp, pd1 + 1, l1+1);
03832 if (gDebug > 2)
03833 ::Info("TAuthenticate::DecodeRSAPublic",
03834 "got %ld bytes for rsa_n_exp", (Long_t)strlen(rsa_n_exp));
03835
03836 int l2 = (int) (pd3 - pd2 - 1);
03837 char *rsa_d_exp = new char[l2 + 1];
03838 strlcpy(rsa_d_exp, pd2 + 1, 13);
03839 if (gDebug > 2)
03840 ::Info("TAuthenticate::DecodeRSAPublic",
03841 "got %ld bytes for rsa_d_exp", (Long_t)strlen(rsa_d_exp));
03842
03843 TRSA_fun::RSA_num_sget()(&rsa_n, rsa_n_exp);
03844 TRSA_fun::RSA_num_sget()(&rsa_d, rsa_d_exp);
03845
03846 if (rsa_n_exp)
03847 if (rsa_n_exp) delete[] rsa_n_exp;
03848 if (rsa_d_exp)
03849 if (rsa_d_exp) delete[] rsa_d_exp;
03850
03851 } else
03852 ::Info("TAuthenticate::DecodeRSAPublic","bad format for input string");
03853 #ifdef R__SSL
03854 } else {
03855
03856 keytype = 1;
03857
03858 RSA *rsatmp;
03859
03860
03861 BIO *bpub = BIO_new(BIO_s_mem());
03862
03863
03864 BIO_write(bpub,(void *)str,strlen(str));
03865
03866
03867 if (!(rsatmp = PEM_read_bio_RSAPublicKey(bpub, 0, 0, 0))) {
03868 if (gDebug > 0)
03869 ::Info("TAuthenticate::DecodeRSAPublic",
03870 "unable to read pub key from bio");
03871 } else
03872 if (rsassl)
03873 *rsassl = (char *)rsatmp;
03874 else
03875 ::Info("TAuthenticate::DecodeRSAPublic",
03876 "no space allocated for output variable");
03877 BIO_free(bpub);
03878 }
03879 #else
03880 } else {
03881 if (rsassl) { }
03882 if (gDebug > 0)
03883 ::Info("TAuthenticate::DecodeRSAPublic","not compiled with SSL support:"
03884 " you should not have got here!");
03885 }
03886 #endif
03887 }
03888
03889 return keytype;
03890 }
03891
03892
03893 Int_t TAuthenticate::SetRSAPublic(const char *rsaPubExport, Int_t klen)
03894 {
03895
03896
03897
03898 if (gDebug > 2)
03899 ::Info("TAuthenticate::SetRSAPublic",
03900 "enter: string length %ld bytes", (Long_t)strlen(rsaPubExport));
03901
03902 Int_t rsakey = -1;
03903 if (!rsaPubExport)
03904 return rsakey;
03905
03906 if (klen > 0) {
03907
03908
03909 int k0 = 0;
03910 while (rsaPubExport[k0] == 32) k0++;
03911 int k2 = klen - 1;
03912
03913
03914
03915
03916
03917
03918 rsakey = 1;
03919 if (rsaPubExport[k0] == '#' && rsaPubExport[k2] == '#') {
03920 char *p0 = (char *)&rsaPubExport[k0];
03921 char *p2 = (char *)&rsaPubExport[k2];
03922 char *p1 = strchr(p0+1,'#');
03923 if (p1 > p0 && p1 < p2) {
03924 Int_t l01 = (Int_t)(p1-p0)-1;
03925 Int_t l12 = (Int_t)(p2-p1)-1;
03926 if (l01 >= kPRIMELENGTH*2 && l12 >= kPRIMELENGTH*2) {
03927
03928 char *c = p0+1;
03929 while (c < p1 && ((*c < 58 && *c > 47) || (*c < 91 && *c > 64)))
03930 c++;
03931 if (c == p1) {
03932 c++;
03933 while (c < p2 && ((*c < 58 && *c > 47) || (*c < 91 && *c > 64)))
03934 c++;
03935 if (c == p2)
03936 rsakey = 0;
03937 }
03938 }
03939 }
03940 }
03941 if (gDebug > 3)
03942 ::Info("TAuthenticate::SetRSAPublic"," Key type: %d",rsakey);
03943 if (rsakey == 0) {
03944
03945
03946 rsa_NUMBER rsa_n, rsa_d;
03947 rsakey = TAuthenticate::DecodeRSAPublic(rsaPubExport,rsa_n,rsa_d);
03948
03949
03950 TRSA_fun::RSA_assign()(&fgRSAPubKey.n, &rsa_n);
03951 TRSA_fun::RSA_assign()(&fgRSAPubKey.e, &rsa_d);
03952
03953 } else {
03954 rsakey = 1;
03955 #ifdef R__SSL
03956
03957 BF_set_key(&fgBFKey, klen, (const unsigned char *)rsaPubExport);
03958 #else
03959 if (gDebug > 0)
03960 ::Info("TAuthenticate::SetRSAPublic",
03961 "not compiled with SSL support:"
03962 " you should not have got here!");
03963 #endif
03964 }
03965 }
03966
03967 return rsakey;
03968 }
03969
03970
03971 Int_t TAuthenticate::SendRSAPublicKey(TSocket *socket, Int_t key)
03972 {
03973
03974
03975
03976
03977 char serverPubKey[kMAXSECBUF];
03978 int kind, nr = 0;
03979 if ((nr = socket->Recv(serverPubKey, kMAXSECBUF, kind)) < 0)
03980 return nr;
03981 if (gDebug > 3)
03982 ::Info("TAuthenticate::SendRSAPublicKey",
03983 "received key from server %ld bytes", (Long_t)strlen(serverPubKey));
03984
03985
03986 rsa_NUMBER rsa_n, rsa_d;
03987 #ifdef R__SSL
03988 char *tmprsa = 0;
03989 if (TAuthenticate::DecodeRSAPublic(serverPubKey,rsa_n,rsa_d,
03990 &tmprsa) != key) {
03991 if (tmprsa)
03992 RSA_free((RSA *)tmprsa);
03993 return -1;
03994 }
03995 RSA *RSASSLServer = (RSA *)tmprsa;
03996 #else
03997 if (TAuthenticate::DecodeRSAPublic(serverPubKey,rsa_n,rsa_d) != key)
03998 return -1;
03999 #endif
04000
04001
04002 char buftmp[kMAXSECBUF] = {0};
04003 char buflen[20] = {0};
04004 Int_t slen = fgRSAPubExport[key].len;
04005 Int_t ttmp = 0;
04006 if (key == 0) {
04007 strlcpy(buftmp,fgRSAPubExport[key].keys,slen+1);
04008 ttmp = TRSA_fun::RSA_encode()(buftmp, slen, rsa_n, rsa_d);
04009 snprintf(buflen, 20, "%d", ttmp);
04010 } else if (key == 1) {
04011 #ifdef R__SSL
04012 Int_t lcmax = RSA_size(RSASSLServer) - 11;
04013 Int_t kk = 0;
04014 Int_t ke = 0;
04015 Int_t ns = slen;
04016 while (ns > 0) {
04017 Int_t lc = (ns > lcmax) ? lcmax : ns ;
04018 if ((ttmp = RSA_public_encrypt(lc,
04019 (unsigned char *)&fgRSAPubExport[key].keys[kk],
04020 (unsigned char *)&buftmp[ke],
04021 RSASSLServer,RSA_PKCS1_PADDING)) < 0) {
04022 char cerr[120];
04023 ERR_error_string(ERR_get_error(), cerr);
04024 ::Info("TAuthenticate::SendRSAPublicKey","SSL: error: '%s' ",cerr);
04025 }
04026 kk += lc;
04027 ke += ttmp;
04028 ns -= lc;
04029 }
04030 ttmp = ke;
04031 snprintf(buflen, 20, "%d", ttmp);
04032 #else
04033 if (gDebug > 0)
04034 ::Info("TAuthenticate::SendRSAPublicKey","not compiled with SSL support:"
04035 " you should not have got here!");
04036 return -1;
04037 #endif
04038 } else {
04039 if (gDebug > 0)
04040 ::Info("TAuthenticate::SendRSAPublicKey","unknown key type (%d)",key);
04041 #ifdef R__SSL
04042 if (RSASSLServer)
04043 RSA_free(RSASSLServer);
04044 #endif
04045 return -1;
04046 }
04047
04048
04049 if ((nr = socket->Send(buflen, kROOTD_ENCRYPT)) < 0)
04050 return nr;
04051
04052 Int_t nsen = socket->SendRaw(buftmp, ttmp);
04053 if (gDebug > 3)
04054 ::Info("TAuthenticate::SendRSAPublicKey",
04055 "local: sent %d bytes (expected: %d)", nsen,ttmp);
04056 #ifdef R__SSL
04057 if (RSASSLServer)
04058 RSA_free(RSASSLServer);
04059 #endif
04060 return nsen;
04061 }
04062
04063
04064 Int_t TAuthenticate::ReadRootAuthrc()
04065 {
04066
04067
04068
04069
04070
04071
04072 char *authrc = 0;
04073 if (gSystem->Getenv("ROOTAUTHRC") != 0) {
04074 authrc = StrDup(gSystem->Getenv("ROOTAUTHRC"));
04075 } else {
04076 if (fgReadHomeAuthrc)
04077 authrc = gSystem->ConcatFileName(gSystem->HomeDirectory(), ".rootauthrc");
04078 }
04079 if (authrc && gDebug > 2)
04080 ::Info("TAuthenticate::ReadRootAuthrc", "Checking file: %s", authrc);
04081 if (!authrc || gSystem->AccessPathName(authrc, kReadPermission)) {
04082 if (authrc && gDebug > 1)
04083 ::Info("TAuthenticate::ReadRootAuthrc",
04084 "file %s cannot be read (errno: %d)", authrc, errno);
04085 delete [] authrc;
04086 #ifdef ROOTETCDIR
04087 authrc = gSystem->ConcatFileName(ROOTETCDIR,"system.rootauthrc");
04088 #else
04089 char etc[1024];
04090 #ifdef WIN32
04091 snprintf(etc, 1024, "%s\\etc", gRootDir);
04092 #else
04093 snprintf(etc, 1024, "%s/etc", gRootDir);
04094 #endif
04095 authrc = gSystem->ConcatFileName(etc,"system.rootauthrc");
04096 #endif
04097 if (gDebug > 2)
04098 ::Info("TAuthenticate::ReadRootAuthrc", "Checking system file:%s",authrc);
04099 if (gSystem->AccessPathName(authrc, kReadPermission)) {
04100 if (gDebug > 1)
04101 ::Info("TAuthenticate::ReadRootAuthrc",
04102 "file %s cannot be read (errno: %d)", authrc, errno);
04103 delete [] authrc;
04104 return 0;
04105 }
04106 }
04107
04108
04109 TString tRootAuthrc = authrc;
04110 if (tRootAuthrc == fgRootAuthrc) {
04111 struct stat si;
04112 stat(tRootAuthrc, &si);
04113 if ((UInt_t)si.st_mtime < fgLastAuthrc.Convert()) {
04114 if (gDebug > 1)
04115 ::Info("TAuthenticate::ReadRootAuthrc",
04116 "file %s already read", authrc);
04117 delete [] authrc;
04118 return 0;
04119 }
04120 }
04121
04122
04123 fgRootAuthrc = tRootAuthrc;
04124 fgLastAuthrc = TDatime();
04125
04126
04127 TList *authinfo = TAuthenticate::GetAuthInfo();
04128 TList *proofauthinfo = TAuthenticate::GetProofAuthInfo();
04129
04130
04131 int expand = 1;
04132 TString filetmp = "rootauthrc";
04133 FILE *ftmp = gSystem->TempFileName(filetmp);
04134 if (gDebug > 2)
04135 ::Info("TAuthenticate::ReadRootAuthrc", "got tmp file: %s open at 0x%lx",
04136 filetmp.Data(), (Long_t)ftmp);
04137 if (ftmp == 0)
04138 expand = 0;
04139
04140 FILE *fd = 0;
04141
04142 if (expand == 1) {
04143 TAuthenticate::FileExpand(authrc, ftmp);
04144 fd = ftmp;
04145 rewind(fd);
04146 } else {
04147
04148 fd = fopen(authrc, "r");
04149 if (fd == 0) {
04150 if (gDebug > 2)
04151 ::Info("TAuthenticate::ReadRootAuthrc",
04152 "file %s cannot be open (errno: %d)", authrc, errno);
04153 delete [] authrc;
04154 return 0;
04155 }
04156 }
04157
04158
04159 TList tmpAuthInfo;
04160 char line[kMAXPATHLEN];
04161 Bool_t cont = kFALSE;
04162 TString proofserv;
04163 while (fgets(line, sizeof(line), fd) != 0) {
04164
04165
04166 if (line[0] == '#')
04167 continue;
04168
04169
04170 if (line[strlen(line) - 1] == '\n')
04171 line[strlen(line) - 1] = '\0';
04172
04173
04174 if (strlen(line) == 0)
04175 continue;
04176
04177
04178 char *tmp = new char[strlen(line)+1];
04179 if (!tmp) {
04180 ::Error("TAuthenticate::ReadRootAuthrc",
04181 "could not allocate temporary buffer");
04182 return 0;
04183 }
04184 strlcpy(tmp,line,strlen(line)+1);
04185 char *nxt = strtok(tmp," ");
04186
04187 if (!strcmp(nxt, "proofserv") || cont) {
04188
04189
04190 char *ph = 0;
04191 if (cont)
04192 ph = nxt;
04193 else
04194 ph = strtok(0," ");
04195 while (ph) {
04196 if (*ph != 92) {
04197 proofserv += TString((const char *)ph);
04198 proofserv += TString(" ");
04199 cont = kFALSE;
04200 } else {
04201 cont = kTRUE;
04202 }
04203 ph = strtok(0," ");
04204 }
04205
04206 } else {
04207
04208 TString hostsrv = nxt;
04209 TString host = hostsrv;
04210 TString server = "";
04211 if (hostsrv.Contains(":")) {
04212 server = hostsrv;
04213 host.Remove(host.Index(":"));
04214 server.Remove(0,server.Index(":")+1);
04215 }
04216 Int_t srvtyp = -1;
04217 if (server.Length()) {
04218 if (server == "0" || server.BeginsWith("sock"))
04219 srvtyp = TSocket::kSOCKD;
04220 else if (server == "1" || server.BeginsWith("root"))
04221 srvtyp = TSocket::kROOTD;
04222 else if (server == "2" || server.BeginsWith("proof"))
04223 srvtyp = TSocket::kPROOFD;
04224 }
04225
04226
04227 TString user = "*";
04228
04229 nxt = strtok(0," ");
04230 if (!strncmp(nxt,"user",4)) {
04231 nxt = strtok(0," ");
04232 if (strncmp(nxt,"list",4) && strncmp(nxt,"method",6)) {
04233 user = TString(nxt);
04234 nxt = strtok(0," ");
04235 }
04236 }
04237
04238
04239 TIter next(&tmpAuthInfo);
04240 THostAuth *ha;
04241 while ((ha = (THostAuth *)next())) {
04242 if (host == ha->GetHost() && user == ha->GetUser() &&
04243 srvtyp == ha->GetServer())
04244 break;
04245 }
04246 if (!ha) {
04247
04248 ha = new THostAuth(host,srvtyp,user);
04249 tmpAuthInfo.Add(ha);
04250 }
04251
04252 if (!strncmp(nxt,"list",4)) {
04253
04254 Int_t nm = 0, me[kMAXSEC] = {0};
04255 char *mth = strtok(0," ");
04256 while (mth) {
04257 Int_t met = -1;
04258 if (strlen(mth) > 1) {
04259
04260 met = GetAuthMethodIdx(mth);
04261 if (met == -1 && gDebug > 2)
04262 ::Info("TAuthenticate::ReadRootAuthrc",
04263 "unrecognized method (%s): ", mth);
04264 } else {
04265 met = atoi(mth);
04266 }
04267 if (met > -1 && met < kMAXSEC)
04268 me[nm++] = met;
04269 mth = strtok(0," ");
04270 }
04271 if (nm)
04272 ha->ReOrder(nm,me);
04273
04274 } else if (!strncmp(nxt,"method",6)) {
04275
04276
04277 char *mth = strtok(0," ");
04278 Int_t met = -1;
04279 if (strlen(mth) > 1) {
04280
04281 met = GetAuthMethodIdx(mth);
04282 if (met == -1 && gDebug > 2)
04283 ::Info("TAuthenticate::ReadRootAuthrc",
04284 "unrecognized method (%s): ", mth);
04285 } else {
04286 met = atoi(mth);
04287 }
04288 if (met > -1 && met < kMAXSEC) {
04289 const char *det = 0;
04290 nxt = strtok(0," ");
04291 if (nxt) {
04292 det = (const char *)strstr(line,nxt);
04293 }
04294 if (ha->HasMethod(met))
04295 ha->SetDetails(met,det);
04296 else
04297 ha->AddMethod(met,det);
04298 }
04299 }
04300 }
04301 if (tmp) delete [] tmp;
04302 }
04303
04304 fclose(fd);
04305 if (expand == 1)
04306 gSystem->Unlink(filetmp);
04307
04308 delete [] authrc;
04309
04310
04311 TAuthenticate::MergeHostAuthList(authinfo,&tmpAuthInfo);
04312
04313
04314 if (gDebug > 2)
04315 TAuthenticate::Show();
04316
04317
04318
04319 TList tmpproofauthinfo;
04320 if (proofserv.Length() > 0) {
04321 char *tmps = new char[proofserv.Length()+1];
04322 strlcpy(tmps,proofserv.Data(),proofserv.Length()+1);
04323 char *nxt = strtok(tmps," ");
04324 while (nxt) {
04325 TString tmp((const char *)nxt);
04326 Int_t pdd = -1;
04327
04328 TString host;
04329 if ((pdd = tmp.Index(":")) == -1) {
04330 host = tmp;
04331 } else {
04332 host = tmp;
04333 host.Resize(pdd);
04334 if (!host.Length())
04335 host = "*";
04336 tmp.Remove(0,pdd+1);
04337 }
04338
04339 TString user;
04340 if ((pdd = tmp.Index(":")) == -1) {
04341 user = tmp;
04342 } else {
04343 user = tmp;
04344 user.Resize(pdd);
04345 if (!user.Length())
04346 user = "*";
04347 tmp.Remove(0,pdd+1);
04348 }
04349
04350 TString meth;
04351 Int_t nm = 0, me[kMAXSEC] = {0}, met = -1;
04352 while (tmp.Length() > 0) {
04353 meth = tmp;
04354 if ((pdd = tmp.Index(":")) > -1)
04355 meth.Resize(pdd);
04356 if (meth.Length() > 1) {
04357
04358 met = GetAuthMethodIdx(meth.Data());
04359 if (met == -1 && gDebug > 2)
04360 ::Info("TAuthenticate::ReadRootAuthrc",
04361 "unrecognized method (%s): ",meth.Data());
04362 } else if (meth.Length() == 1) {
04363 met = atoi(meth.Data());
04364 if (met > -1 && met < kMAXSEC)
04365 me[nm++] = met;
04366 }
04367 if (pdd > -1)
04368 tmp.Remove(0,pdd+1);
04369 else
04370 tmp.Resize(0);
04371 }
04372
04373
04374 THostAuth *ha = 0;
04375 THostAuth *hatmp = TAuthenticate::GetHostAuth(host,user);
04376 if (!hatmp) {
04377 ha = new THostAuth(host,user,nm,me,0);
04378 } else {
04379
04380 ha = new THostAuth(host,user);
04381
04382 ha->Update(hatmp);
04383
04384 ha->ReOrder(nm,me);
04385 }
04386
04387 tmpproofauthinfo.Add(ha);
04388
04389 nxt = strtok(0," ");
04390 }
04391 delete [] tmps;
04392 }
04393
04394
04395 TAuthenticate::MergeHostAuthList(proofauthinfo,&tmpproofauthinfo,"P");
04396
04397 if (gDebug > 2)
04398 TAuthenticate::Show("P");
04399
04400 return authinfo->GetSize();
04401 }
04402
04403
04404 Bool_t TAuthenticate::CheckProofAuth(Int_t cSec, TString &out)
04405 {
04406
04407
04408 Bool_t rc = kFALSE;
04409 const char sshid[3][20] = { "/.ssh/identity", "/.ssh/id_dsa", "/.ssh/id_rsa" };
04410 const char netrc[2][20] = { "/.netrc", "/.rootnetrc" };
04411 TString user;
04412
04413
04414 UserGroup_t *pw = gSystem->GetUserInfo();
04415 if (pw) {
04416 user = TString(pw->fUser);
04417 delete pw;
04418 } else {
04419 ::Info("CheckProofAuth",
04420 "not properly logged on (getpwuid unable to find relevant info)!");
04421 out = "";
04422 return rc;
04423 }
04424
04425
04426 if (cSec == (Int_t) TAuthenticate::kClear) {
04427 Int_t i = 0;
04428 for (; i < 2; i++) {
04429 TString infofile = TString(gSystem->HomeDirectory())+TString(netrc[i]);
04430 if (!gSystem->AccessPathName(infofile, kReadPermission))
04431 rc = kTRUE;
04432 }
04433 if (rc)
04434 out = Form("pt:0 ru:1 us:%s",user.Data());
04435 }
04436
04437
04438 if (cSec == (Int_t) TAuthenticate::kSRP) {
04439 #ifdef R__SRP
04440 out = Form("pt:0 ru:1 us:%s",user.Data());
04441 rc = kTRUE;
04442 #endif
04443 }
04444
04445
04446 if (cSec == (Int_t) TAuthenticate::kKrb5) {
04447 #ifdef R__KRB5
04448 out = Form("pt:0 ru:0 us:%s",user.Data());
04449 rc = kTRUE;
04450 #endif
04451 }
04452
04453
04454 if (cSec == (Int_t) TAuthenticate::kGlobus) {
04455 #ifdef R__GLBS
04456 TApplication *lApp = gROOT->GetApplication();
04457 if (lApp != 0 && lApp->Argc() > 9) {
04458 if (gROOT->IsProofServ()) {
04459
04460 Int_t ShmId = -1;
04461 if (gSystem->Getenv("ROOTSHMIDCRED"))
04462 ShmId = strtol(gSystem->Getenv("ROOTSHMIDCRED"),
04463 (char **)0, 10);
04464 if (ShmId != -1) {
04465 struct shmid_ds shm_ds;
04466 if (shmctl(ShmId, IPC_STAT, &shm_ds) == 0)
04467 rc = kTRUE;
04468 }
04469 if (rc) {
04470
04471 TString Adir(gSystem->Getenv("X509_CERT_DIR"));
04472
04473 TString Ucer(gSystem->Getenv("X509_USER_CERT"));
04474
04475 TString Ukey(gSystem->Getenv("X509_USER_KEY"));
04476
04477 TString Cdir = Ucer;
04478 Cdir.Resize(Cdir.Last('/')+1);
04479
04480 out = Form("pt=0 ru:0 cd:%s cf:%s kf:%s ad:%s",
04481 Cdir.Data(),Ucer.Data(),Ukey.Data(),Adir.Data());
04482 }
04483 }
04484 }
04485 #endif
04486 }
04487
04488
04489 if (cSec == (Int_t) TAuthenticate::kSSH) {
04490 Int_t i = 0;
04491 for (; i < 3; i++) {
04492 TString infofile = TString(gSystem->HomeDirectory())+TString(sshid[i]);
04493 if (!gSystem->AccessPathName(infofile,kReadPermission))
04494 rc = kTRUE;
04495 }
04496 if (rc)
04497 out = Form("pt:0 ru:1 us:%s",user.Data());
04498 }
04499
04500
04501 if (cSec == (Int_t) TAuthenticate::kRfio) {
04502 out = Form("pt:0 ru:0 us:%s",user.Data());
04503 rc = kTRUE;
04504 }
04505
04506 if (gDebug > 3) {
04507 if (strlen(out) > 0)
04508 ::Info("CheckProofAuth",
04509 "meth: %d ... is available: details: %s", cSec, out.Data());
04510 else
04511 ::Info("CheckProofAuth",
04512 "meth: %d ... is NOT available", cSec);
04513 }
04514
04515
04516 return rc;
04517 }
04518
04519
04520 Int_t StdCheckSecCtx(const char *user, TRootSecContext *ctx)
04521 {
04522
04523
04524
04525
04526
04527 Int_t rc = 0;
04528
04529 if (ctx->IsActive()) {
04530 if (!strcmp(user,ctx->GetUser()) &&
04531 strncmp("AFS", ctx->GetID(), 3))
04532 rc = 1;
04533 }
04534 return rc;
04535 }
04536
04537
04538 void TAuthenticate::MergeHostAuthList(TList *std, TList *nin, Option_t *opt)
04539 {
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549 TIter nxstd(std);
04550 THostAuth *ha;
04551 while ((ha = (THostAuth *) nxstd())) {
04552 if (!ha->IsActive()) {
04553 std->Remove(ha);
04554 SafeDelete(ha);
04555 }
04556 }
04557
04558
04559 TIter nxnew(nin);
04560 THostAuth *hanew;
04561 while ((hanew = (THostAuth *)nxnew())) {
04562 if (hanew->NumMethods()) {
04563 TString hostsrv(Form("%s:%d",hanew->GetHost(),hanew->GetServer()));
04564 THostAuth *hastd =
04565 TAuthenticate::HasHostAuth(hostsrv,hanew->GetUser(),opt);
04566 if (hastd) {
04567
04568 hastd->Update(hanew);
04569
04570 hanew->DeActivate();
04571 } else {
04572
04573 std->Add(hanew);
04574 }
04575 } else
04576
04577 hanew->DeActivate();
04578 }
04579
04580
04581 nxnew.Reset();
04582 while ((hanew = (THostAuth *)nxnew())) {
04583 if (!hanew->IsActive()) {
04584 nin->Remove(hanew);
04585 SafeDelete(hanew);
04586 }
04587 }
04588
04589 }
04590
04591
04592 void TAuthenticate::RemoveSecContext(TRootSecContext *ctx)
04593 {
04594
04595
04596
04597 THostAuth *ha = 0;
04598
04599
04600 TIter nxai(GetAuthInfo());
04601 while ((ha = (THostAuth *)nxai())) {
04602 TIter next(ha->Established());
04603 TRootSecContext *lctx = 0;
04604 while ((lctx = (TRootSecContext *) next())) {
04605 if (lctx == ctx) {
04606 ha->Established()->Remove(ctx);
04607 break;
04608 }
04609 }
04610 }
04611
04612
04613 TIter nxpa(GetProofAuthInfo());
04614 while ((ha = (THostAuth *)nxpa())) {
04615 TIter next(ha->Established());
04616 TRootSecContext *lctx = 0;
04617 while ((lctx = (TRootSecContext *) next())) {
04618 if (lctx == ctx) {
04619 ha->Established()->Remove(ctx);
04620 break;
04621 }
04622 }
04623 }
04624
04625 }
04626
04627
04628 Int_t TAuthenticate::ProofAuthSetup()
04629 {
04630
04631
04632
04633
04634
04635 static Bool_t done = kFALSE;
04636
04637
04638 if (done)
04639 return 0;
04640 done = kTRUE;
04641
04642
04643 const char *p = gSystem->Getenv("ROOTPROOFAUTHSETUP");
04644 if (!p) {
04645 if (gDebug > 2)
04646 Info("ProofAuthSetup","Buffer not found: nothing to do");
04647 return 0;
04648 }
04649 TString mbuf = TBase64::Decode(p);
04650
04651
04652 TMessage *mess = new TMessage((void*)mbuf.Data(), mbuf.Length()+sizeof(UInt_t));
04653
04654
04655 TString user = "";
04656 TString passwd = "";
04657 Bool_t pwhash = kFALSE;
04658 Bool_t srppwd = kFALSE;
04659 Int_t rsakey = -1;
04660 *mess >> user >> passwd >> pwhash >> srppwd >> rsakey;
04661
04662
04663 TAuthenticate::SetGlobalUser(user);
04664 TAuthenticate::SetGlobalPasswd(passwd);
04665 TAuthenticate::SetGlobalPwHash(pwhash);
04666 TAuthenticate::SetGlobalSRPPwd(srppwd);
04667 TAuthenticate::SetDefaultRSAKeyType(rsakey);
04668 const char *h = gSystem->Getenv("ROOTHOMEAUTHRC");
04669 if (h) {
04670 Bool_t rha = (Bool_t)(strtol(h, (char **)0, 10));
04671 TAuthenticate::SetReadHomeAuthrc(rha);
04672 }
04673
04674
04675 TList *pha = (TList *)mess->ReadObject(TList::Class());
04676 if (!pha) {
04677 if (gDebug > 0)
04678 Info("ProofAuthSetup","List of THostAuth not found");
04679 return 0;
04680 }
04681
04682 Bool_t master = gROOT->IsProofServ();
04683 TIter next(pha);
04684 THostAuth *ha = 0;
04685 while ((ha = (THostAuth *)next())) {
04686
04687
04688 Int_t kExact = 0;
04689 THostAuth *haex = 0;
04690 Bool_t fromProofAI = kFALSE;
04691 if (master) {
04692
04693 haex = TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"P",&kExact);
04694
04695 if (!haex) {
04696 haex =
04697 TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"R",&kExact);
04698 } else
04699 fromProofAI = kTRUE;
04700 } else {
04701
04702 haex = TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"R",&kExact);
04703 }
04704
04705 if (haex) {
04706
04707 if (kExact == 1) {
04708
04709
04710 if (!master || fromProofAI) {
04711
04712
04713 haex->Update(ha);
04714
04715 SafeDelete(ha);
04716 } else
04717
04718
04719 TAuthenticate::GetProofAuthInfo()->Add(ha);
04720 } else {
04721
04722
04723 Int_t i = 0;
04724 for (; i < haex->NumMethods(); i++) {
04725 Int_t met = haex->GetMethod(i);
04726 if (!ha->HasMethod(met))
04727 ha->AddMethod(met,haex->GetDetails(met));
04728 }
04729 if (master)
04730
04731 TAuthenticate::GetProofAuthInfo()->Add(ha);
04732 else
04733
04734 TAuthenticate::GetAuthInfo()->Add(ha);
04735 }
04736 } else {
04737 if (master)
04738
04739 TAuthenticate::GetProofAuthInfo()->Add(ha);
04740 else
04741
04742 TAuthenticate::GetAuthInfo()->Add(ha);
04743 }
04744 }
04745
04746
04747 return 0;
04748 }
04749
04750
04751 Int_t TAuthenticate::ProofAuthSetup(TSocket *sock, Bool_t client)
04752 {
04753
04754
04755
04756
04757
04758 TSecContext *sc = sock->GetSecContext();
04759 TString user = sc->GetUser();
04760 Int_t remoteOffSet = sc->GetOffSet();
04761
04762
04763
04764 TMessage pubkey;
04765 TString passwd = "";
04766 Bool_t pwhash = kFALSE;
04767 Bool_t srppwd = kFALSE;
04768 Bool_t sndsrp = kFALSE;
04769
04770 Bool_t upwd = sc->IsA("UsrPwd");
04771 Bool_t srp = sc->IsA("SRP");
04772
04773 TPwdCtx *pwdctx = 0;
04774 if (remoteOffSet > -1 && (upwd || srp))
04775 pwdctx = (TPwdCtx *)(sc->GetContext());
04776
04777 if (client) {
04778 if ((gEnv->GetValue("Proofd.SendSRPPwd",0)) && (remoteOffSet > -1))
04779 sndsrp = kTRUE;
04780 } else {
04781 if (srp && pwdctx) {
04782 if (strcmp(pwdctx->GetPasswd(), "") && remoteOffSet > -1)
04783 sndsrp = kTRUE;
04784 }
04785 }
04786
04787 if ((upwd && pwdctx) || (srp && sndsrp)) {
04788 if (pwdctx) {
04789 passwd = pwdctx->GetPasswd();
04790 pwhash = pwdctx->IsPwHash();
04791 }
04792 }
04793
04794 Int_t keytyp = ((TRootSecContext *)sc)->GetRSAKey();
04795
04796
04797 TMessage mess;
04798 mess << user << passwd << pwhash << srppwd << keytyp;
04799
04800
04801 mess.WriteObject(TAuthenticate::GetProofAuthInfo());
04802
04803
04804 char *mbuf = mess.Buffer();
04805 Int_t mlen = mess.Length();
04806 TString messb64 = TBase64::Encode(mbuf, mlen);
04807
04808 if (gDebug > 2)
04809 ::Info("ProofAuthSetup","sending %d bytes", messb64.Length());
04810
04811
04812 if (remoteOffSet > -1) {
04813 if (TAuthenticate::SecureSend(sock, 1, keytyp, messb64.Data()) == -1) {
04814 ::Error("ProofAuthSetup","problems secure-sending message buffer");
04815 return -1;
04816 }
04817 } else {
04818
04819 char buflen[20];
04820 snprintf(buflen,20, "%d", messb64.Length());
04821 if (sock->Send(buflen, kMESS_ANY) < 0) {
04822 ::Error("ProofAuthSetup","plain: problems sending message length");
04823 return -1;
04824 }
04825 if (sock->SendRaw(messb64.Data(), messb64.Length()) < 0) {
04826 ::Error("ProofAuthSetup","problems sending message buffer");
04827 return -1;
04828 }
04829 }
04830
04831
04832 return 0;
04833 }
04834
04835
04836 Int_t TAuthenticate::GetClientProtocol()
04837 {
04838
04839
04840 return TSocket::GetClientProtocol();
04841 }
04842
04843
04844
04845
04846
04847
04848
04849 static Int_t SendHostAuth(TSocket *s)
04850 {
04851
04852
04853
04854
04855
04856
04857
04858
04859 Int_t retval = 0, ns = 0;
04860
04861 if (!s) {
04862 Error("SendHostAuth","invalid input: socket undefined");
04863 return -1;
04864 }
04865
04866
04867 TIter next(TAuthenticate::GetProofAuthInfo());
04868 THostAuth *ha;
04869 while ((ha = (THostAuth *)next())) {
04870 TString buf;
04871 ha->AsString(buf);
04872 if((ns = s->Send(buf, kPROOF_HOSTAUTH)) < 1) {
04873 retval = -1;
04874 break;
04875 }
04876 if (gDebug > 2)
04877 Info("SendHostAuth","sent %d bytes (%s)",ns,buf.Data());
04878 }
04879
04880
04881 if ((ns = s->Send("END", kPROOF_HOSTAUTH)) < 1)
04882 retval = -2;
04883 if (gDebug > 2)
04884 Info("SendHostAuth","sent %d bytes for closing",ns);
04885
04886 return retval;
04887 }
04888
04889
04890 static Int_t RecvHostAuth(TSocket *s, Option_t *opt)
04891 {
04892
04893
04894
04895
04896
04897 if (!s) {
04898 Error("RecvHostAuth","invalid input: socket undefined");
04899 return -1;
04900 }
04901
04902
04903 Bool_t master = !strncasecmp(opt,"M",1) ? kTRUE : kFALSE;
04904
04905
04906 TAuthenticate::ReadRootAuthrc();
04907
04908
04909 Int_t kind;
04910 char buf[kMAXSECBUF];
04911 Int_t nr = s->Recv(buf, kMAXSECBUF, kind);
04912 if (nr < 0 || kind != kPROOF_HOSTAUTH) {
04913 Error("RecvHostAuth", "received: kind: %d (%d bytes)", kind, nr);
04914 return -1;
04915 }
04916 if (gDebug > 2)
04917 Info("RecvHostAuth","received %d bytes (%s)",nr,buf);
04918
04919 while (strcmp(buf, "END")) {
04920
04921 Int_t nc = (nr >= kMAXSECBUF) ? kMAXSECBUF - 1 : nr ;
04922 buf[nc] = '\0';
04923
04924
04925 THostAuth *ha = new THostAuth((const char *)&buf);
04926
04927
04928 Int_t kExact = 0;
04929 THostAuth *haex = 0;
04930 Bool_t fromProofAI = kFALSE;
04931 if (master) {
04932
04933 haex = TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"P",&kExact);
04934
04935 if (!haex) {
04936 haex =
04937 TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"R",&kExact);
04938 } else
04939 fromProofAI = kTRUE;
04940 } else {
04941
04942 haex = TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"R",&kExact);
04943 }
04944
04945 if (haex) {
04946
04947 if (kExact == 1) {
04948
04949
04950 if (!master || fromProofAI) {
04951
04952
04953 haex->Update(ha);
04954
04955 SafeDelete(ha);
04956 } else
04957
04958
04959 TAuthenticate::GetProofAuthInfo()->Add(ha);
04960 } else {
04961
04962
04963 Int_t i = 0;
04964 for (; i < haex->NumMethods(); i++) {
04965 Int_t met = haex->GetMethod(i);
04966 if (!ha->HasMethod(met))
04967 ha->AddMethod(met,haex->GetDetails(met));
04968 }
04969 if (master)
04970
04971 TAuthenticate::GetProofAuthInfo()->Add(ha);
04972 else
04973
04974 TAuthenticate::GetAuthInfo()->Add(ha);
04975 }
04976 } else {
04977 if (master)
04978
04979 TAuthenticate::GetProofAuthInfo()->Add(ha);
04980 else
04981
04982 TAuthenticate::GetAuthInfo()->Add(ha);
04983 }
04984
04985
04986
04987 nr = s->Recv(buf, kMAXSECBUF, kind);
04988 if (nr < 0 || kind != kPROOF_HOSTAUTH) {
04989 Info("RecvHostAuth","Error: received: kind: %d (%d bytes)", kind, nr);
04990 return -1;
04991 }
04992 if (gDebug > 2)
04993 Info("RecvHostAuth","received %d bytes (%s)",nr,buf);
04994 }
04995
04996 return 0;
04997 }
04998
04999 extern "C" {
05000
05001
05002 Int_t OldSlaveAuthSetup(TSocket *sock,
05003 Bool_t master, TString ord, TString conf)
05004 {
05005
05006
05007
05008
05009
05010
05011 TSecContext *sc = sock->GetSecContext();
05012 TString user = sc->GetUser();
05013 Int_t proofdProto = sock->GetRemoteProtocol();
05014 Int_t remoteOffSet = sc->GetOffSet();
05015
05016
05017
05018 TMessage pubkey;
05019 TString passwd = "";
05020 Bool_t pwhash = kFALSE;
05021 Bool_t srppwd = kFALSE;
05022 Bool_t sndsrp = kFALSE;
05023
05024 Bool_t upwd = sc->IsA("UsrPwd");
05025 Bool_t srp = sc->IsA("SRP");
05026
05027 TPwdCtx *pwdctx = 0;
05028 if (remoteOffSet > -1 && (upwd || srp))
05029 pwdctx = (TPwdCtx *)(sc->GetContext());
05030
05031 if (!master) {
05032 if ((gEnv->GetValue("Proofd.SendSRPPwd",0)) && (remoteOffSet > -1))
05033 sndsrp = kTRUE;
05034 } else {
05035 if (srp && pwdctx) {
05036 if (strcmp(pwdctx->GetPasswd(), "") && remoteOffSet > -1)
05037 sndsrp = kTRUE;
05038 }
05039 }
05040
05041 if ((upwd && pwdctx) || (srp && sndsrp)) {
05042
05043
05044 if (sock->Send(remoteOffSet, kROOTD_RSAKEY) != 2*sizeof(Int_t)) {
05045 Error("OldAuthSetup", "failed to send offset in RSA key");
05046 return -1;
05047 }
05048
05049 if (pwdctx) {
05050 passwd = pwdctx->GetPasswd();
05051 pwhash = pwdctx->IsPwHash();
05052 }
05053
05054 Int_t keytyp = ((TRootSecContext *)sc)->GetRSAKey();
05055 if (TAuthenticate::SecureSend(sock, 1, keytyp, passwd.Data()) == -1) {
05056 if (remoteOffSet > -1)
05057 Warning("OldAuthSetup","problems secure-sending pass hash %s",
05058 "- may result in failures");
05059
05060 if (upwd) {
05061 for (int i = 0; i < passwd.Length(); i++) {
05062 char inv = ~passwd(i);
05063 passwd.Replace(i, 1, inv);
05064 }
05065 TMessage mess;
05066 mess << passwd;
05067 if (sock->Send(mess) < 0) {
05068 Error("OldAuthSetup", "failed to send inverted password");
05069 return -1;
05070 }
05071 }
05072 }
05073
05074 } else {
05075
05076
05077 if (sock->Send(-2, kROOTD_RSAKEY) != 2*sizeof(Int_t)) {
05078 Error("OldAuthSetup", "failed to send no offset notification in RSA key");
05079 return -1;
05080 }
05081 }
05082
05083
05084 TMessage mess;
05085 mess << user << pwhash << srppwd << ord << conf;
05086
05087 if (sock->Send(mess) < 0) {
05088 Error("OldAuthSetup", "failed to send ordinal and config info");
05089 return -1;
05090 }
05091
05092 if (proofdProto > 6) {
05093
05094
05095
05096
05097 if (SendHostAuth(sock) < 0) {
05098 Error("OldAuthSetup", "failed to send HostAuth info");
05099 return -1;
05100 }
05101 }
05102
05103
05104 return 0;
05105 }
05106
05107
05108 Int_t OldProofServAuthSetup(TSocket *sock, Bool_t master, Int_t protocol,
05109 TString &user, TString &ord, TString &conf)
05110 {
05111
05112
05113
05114
05115
05116 Int_t retval, kind;
05117 if (sock->Recv(retval, kind) != 2*sizeof(Int_t)) {
05118
05119 Info("OldProofServAuthSetup",
05120 "socket has been closed due to protocol mismatch - Exiting");
05121 return -1;
05122 }
05123
05124 Int_t rsakey = 0;
05125 TString passwd;
05126 if (kind == kROOTD_RSAKEY) {
05127
05128 if (retval > -1) {
05129 if (gSystem->Getenv("ROOTKEYFILE")) {
05130
05131 TString keyfile = gSystem->Getenv("ROOTKEYFILE");
05132 keyfile += retval;
05133
05134 FILE *fKey = 0;
05135 char pubkey[kMAXPATHLEN] = { 0 };
05136 if (!gSystem->AccessPathName(keyfile.Data(), kReadPermission)) {
05137 if ((fKey = fopen(keyfile.Data(), "r"))) {
05138 Int_t klen = fread((void *)pubkey,1,sizeof(pubkey),fKey);
05139 if (klen <= 0) {
05140 Error("OldProofServAuthSetup",
05141 "failed to read public key from '%s'", keyfile.Data());
05142 fclose(fKey);
05143 return -1;
05144 }
05145 pubkey[klen] = 0;
05146
05147 rsakey = TAuthenticate::SetRSAPublic(pubkey,klen);
05148 fclose(fKey);
05149 } else {
05150 Error("OldProofServAuthSetup", "failed to open '%s'", keyfile.Data());
05151 return -1;
05152 }
05153 }
05154 }
05155
05156
05157 char *pwd = 0;
05158 if (TAuthenticate::SecureRecv(sock, 2, rsakey, &pwd) < 0) {
05159 Error("OldProofServAuthSetup", "failed to receive password");
05160 return -1;
05161 }
05162 passwd = pwd;
05163 delete[] pwd;
05164
05165 } else if (retval == -1) {
05166
05167
05168 TMessage *mess;
05169 if ((sock->Recv(mess) <= 0) || !mess) {
05170 Error("OldProofServAuthSetup", "failed to receive inverted password");
05171 return -1;
05172 }
05173 (*mess) >> passwd;
05174 delete mess;
05175
05176 for (Int_t i = 0; i < passwd.Length(); i++) {
05177 char inv = ~passwd(i);
05178 passwd.Replace(i, 1, inv);
05179 }
05180
05181 }
05182 }
05183
05184
05185 TMessage *mess;
05186 if ((sock->Recv(mess) <= 0) || !mess) {
05187 Error("OldProofServAuthSetup", "failed to receive ordinal and config info");
05188 return -1;
05189 }
05190
05191
05192 Bool_t pwhash, srppwd;
05193 if (master) {
05194 if (protocol < 4) {
05195 (*mess) >> user >> pwhash >> srppwd >> conf;
05196 ord = "0";
05197 } else {
05198 (*mess) >> user >> pwhash >> srppwd >> ord >> conf;
05199 }
05200 } else {
05201 if (protocol < 4) {
05202 Int_t iord;
05203 (*mess) >> user >> pwhash >> srppwd >> iord;
05204 ord = "0.";
05205 ord += iord;
05206 } else {
05207 (*mess) >> user >> pwhash >> srppwd >> ord >> conf;
05208 }
05209 }
05210 delete mess;
05211
05212
05213 TAuthenticate::SetGlobalUser(user);
05214 TAuthenticate::SetGlobalPasswd(passwd);
05215 TAuthenticate::SetGlobalPwHash(pwhash);
05216 TAuthenticate::SetGlobalSRPPwd(srppwd);
05217 TAuthenticate::SetDefaultRSAKeyType(rsakey);
05218 const char *h = gSystem->Getenv("ROOTHOMEAUTHRC");
05219 if (h) {
05220 Bool_t rha = (Bool_t)(strtol(h, (char **)0, 10));
05221 TAuthenticate::SetReadHomeAuthrc(rha);
05222 }
05223
05224
05225
05226 Int_t harc = master ? RecvHostAuth(sock, "M") : RecvHostAuth(sock, "S");
05227
05228 if (harc < 0) {
05229 Error("OldProofServAuthSetup", "failed to receive HostAuth info");
05230 return -1;
05231 }
05232
05233
05234 return 0;
05235 }
05236
05237 }