#ifdef R__HAVE_CONFIG
#include "RConfigure.h"
#endif
#include "TAuthenticate.h"
#include "TApplication.h"
#include "THostAuth.h"
#include "TRootSecContext.h"
#include "TPluginManager.h"
#include "TNetFile.h"
#include "TPSocket.h"
#include "TMessage.h"
#include "TSystem.h"
#include "TError.h"
#include "Getline.h"
#include "TROOT.h"
#include "TEnv.h"
#include "TList.h"
#include "NetErrors.h"
#include "TRegexp.h"
#include "snprintf.h"
#include "TVirtualMutex.h"
#include "TTimer.h"
#ifndef R__LYNXOS
#include <sys/stat.h>
#endif
#include <errno.h>
#include <sys/types.h>
#include <time.h>
#if !defined(R__WIN32) && !defined(R__MACOSX) && !defined(R__FBSD) && \
    !defined(R__OBSD)
#include <crypt.h>
#endif
#ifdef WIN32
#  include <io.h>
#endif /* WIN32 */
#if defined(R__LINUX) || defined(R__FBSD) || defined(R__OBSD)
#  include <unistd.h>
#endif
#if defined(R__ALPHA) || defined(R__SGI) || defined(R__MACOSX)
extern "C" char *crypt(const char *, const char *);
#endif
#ifdef R__GLBS
#   include <sys/ipc.h>
#   include <sys/shm.h>
#endif
#ifdef R__SSL
#   include <openssl/bio.h>
#   include <openssl/err.h>
#   include <openssl/pem.h>
#   include <openssl/rand.h>
#   include <openssl/rsa.h>
#   include <openssl/ssl.h>
#endif
TList          *TAuthenticate::fgAuthInfo = 0;
TString         TAuthenticate::fgAuthMeth[] = { "UsrPwd", "SRP", "Krb5",
                                                "Globus", "SSH", "UidGid" };
Bool_t          TAuthenticate::fgAuthReUse;
TString         TAuthenticate::fgDefaultUser;
TDatime         TAuthenticate::fgExpDate;
GlobusAuth_t    TAuthenticate::fgGlobusAuthHook;
Krb5Auth_t      TAuthenticate::fgKrb5AuthHook;
TString         TAuthenticate::fgKrb5Principal;
TDatime         TAuthenticate::fgLastAuthrc;    
TString         TAuthenticate::fgPasswd;
TPluginHandler *TAuthenticate::fgPasswdDialog = (TPluginHandler *)(-1);
Bool_t          TAuthenticate::fgPromptUser;
TList          *TAuthenticate::fgProofAuthInfo = 0;
Bool_t          TAuthenticate::fgPwHash;
Bool_t          TAuthenticate::fgReadHomeAuthrc = kTRUE; 
TString         TAuthenticate::fgRootAuthrc;    
Int_t           TAuthenticate::fgRSAKey  = -1;  
Int_t           TAuthenticate::fgRSAInit = 0;
rsa_KEY         TAuthenticate::fgRSAPriKey;
rsa_KEY_export  TAuthenticate::fgRSAPubExport[2] = {{0,0},{0,0}};
rsa_KEY         TAuthenticate::fgRSAPubKey;
#ifdef R__SSL
BF_KEY          TAuthenticate::fgBFKey;
#endif
SecureAuth_t    TAuthenticate::fgSecAuthHook;
Bool_t          TAuthenticate::fgSRPPwd;
TString         TAuthenticate::fgUser;
Bool_t          TAuthenticate::fgUsrPwdCrypt;
Int_t           TAuthenticate::fgLastError = -1;
Int_t           TAuthenticate::fgAuthTO = -2;       
Int_t           TAuthenticate::fgProcessID = -1;
TVirtualMutex *gAuthenticateMutex = 0;
Int_t StdCheckSecCtx(const char *, TRootSecContext *);
ClassImp(TAuthenticate)
TAuthenticate::TAuthenticate(TSocket *sock, const char *remote,
                             const char *proto, const char *user)
{
   
   if (gDebug > 2 && gAuthenticateMutex)
      Info("Authenticate", "locking mutex (pid:  %d)",gSystem->GetPid());
   R__LOCKGUARD2(gAuthenticateMutex);
   
   if (gROOT->IsProofServ())
      ProofAuthSetup();
   
   if (fgProcessID < 0)
      fgProcessID = gSystem->GetPid();
   if (fgAuthTO == -2)
      fgAuthTO = gEnv->GetValue("Auth.Timeout",-1);
   fSocket   = sock;
   fRemote   = remote;
   fHostAuth = 0;
   fVersion  = 5;                
   fSecContext = 0;
   if (gDebug > 2)
      Info("TAuthenticate", "Enter: local host: %s, user is: %s (proto: %s)",
           gSystem->HostName(), user, proto);
   
   
   char *pdd;
   Int_t servtype = TSocket::kSOCKD;
   if (proto && strlen(proto) > 0) {
      char *sproto = StrDup(proto);
      if ((pdd = strstr(sproto, ":")) != 0) {
         int rproto = atoi(pdd + 1);
         *pdd = '\0';
         if (strstr(sproto, "root") != 0) {
            if (rproto < 12 ) {
               fVersion = 4;
               if (rproto < 11 ) {
                  fVersion = 3;
                  if (rproto < 9 ) {
                     fVersion = 2;
                     if (rproto < 8) {
                        fVersion = 1;
                        if (rproto < 6)
                           fVersion = 0;
                     }
                  }
               }
            }
            servtype = TSocket::kROOTD;
         }
         if (strstr(sproto, "proof") != 0) {
            if (rproto < 11) {
               fVersion = 4;
               if (rproto < 10) {
                  fVersion = 3;
                  if (rproto < 8) {
                     fVersion = 2;
                     if (rproto < 7)
                        fVersion = 1;
                  }
               }
            }
            servtype = TSocket::kPROOFD;
         }
         if (gDebug > 3)
            Info("TAuthenticate",
                 "service: %s (remote protocol: %d): fVersion: %d", sproto,
                 rproto, fVersion);
      }
      fProtocol = sproto;
      delete [] sproto;
   }
   
   fUser = "";
   TString checkUser;
   if (user && strlen(user) > 0) {
      fUser = user;
      checkUser = user;
   } else {
      UserGroup_t *u = gSystem->GetUserInfo();
      if (u)
         checkUser = u->fUser;
      delete u;
   }
   fPasswd = "";
   fPwHash = kFALSE;
   fSRPPwd = kFALSE;
   
   if (fgRSAKey < 0) {
      fgRSAKey  = 0;                
#if R__SSL
      
      if (gEnv->GetValue("RSA.KeyType",0) == 1)
         fgRSAKey = 1;
#endif
   }
   
   
   fRSAKey = fgRSAKey;
   if (gDebug > 3)
      Info("TAuthenticate","RSA key: default type %d", fgRSAKey);
   
   if (!fgRSAInit) {
      GenRSAKeys();
      fgRSAInit = 1;
   }
   
   TString fqdn;
   TInetAddress addr = gSystem->GetHostByName(fRemote);
   if (addr.IsValid()) {
      fqdn = addr.GetHostName();
      if (fqdn == "UnNamedHost")
         fqdn = addr.GetHostAddress();
   }
   TString fqdnsrv(Form("%s:%d",fqdn.Data(),servtype));
   
   TAuthenticate::ReadRootAuthrc();
   if (gDebug > 3) {
      Info("TAuthenticate",
           "number of HostAuth Instantiations in memory: %d",
           GetAuthInfo()->GetSize());
      TAuthenticate::Show("H");
      TAuthenticate::Show("P");
   }
   
   fHostAuth = GetHostAuth(fqdnsrv, checkUser);
   
   
   
   if (!fHostAuth) {
      TString tmp;
      if (fProtocol.Contains("proof")) {
         tmp = TString(gEnv->GetValue("Proofd.Authentication", "0"));
      } else if (fProtocol.Contains("root")) {
         tmp = TString(gEnv->GetValue("Rootd.Authentication", "0"));
      }
      char am[kMAXSEC][10];
      Int_t nw = sscanf(tmp.Data(), "%s %s %s %s %s %s",
                        am[0], am[1], am[2], am[3], am[4], am[5]);
      Int_t i = 0, nm = 0, me[kMAXSEC];
      for( ; i < nw; i++) {
         Int_t met = -1;
         if (strlen(am[i]) > 1) {
            met = GetAuthMethodIdx(am[i]);
         } else {
            met = atoi(am[i]);
         }
         if (met > -1 && met < kMAXSEC) {
            me[nm++] = met;
         }
      }
      
      if (nm)
         fHostAuth = new THostAuth(fRemote,fUser,nm,me,0);
      else
         fHostAuth = new THostAuth(fRemote,fUser,0,(const char *)0);
   }
   
   
   
   if (strchr(fHostAuth->GetHost(),'*') || strchr(fHostAuth->GetHost(),'*') ||
       fHostAuth->GetServer() == -1 ) {
      fHostAuth = new THostAuth(*fHostAuth);
      fHostAuth->SetHost(fqdn);
      fHostAuth->SetUser(checkUser);
      fHostAuth->SetServer(servtype);
   }
   
   
   Int_t sec = -1;
   TString tmp = fProtocol;
   tmp.ReplaceAll("root",4,"",0);
   tmp.ReplaceAll("proof",5,"",0);
   tmp.ReplaceAll("sock",4,"",0);
   if (!strncmp(tmp.Data(),"up",2))
      sec = 0;
   else if (!strncmp(tmp.Data(),"s",1))
      sec = 1;
   else if (!strncmp(tmp.Data(),"k",1))
      sec = 2;
   else if (!strncmp(tmp.Data(),"g",1))
      sec = 3;
   else if (!strncmp(tmp.Data(),"h",1))
      sec = 4;
   else if (!strncmp(tmp.Data(),"ug",2))
      sec = 5;
   if (sec > -1 && sec < kMAXSEC) {
      if (fHostAuth->HasMethod(sec)) {
         fHostAuth->SetFirst(sec);
      } else {
         char *dtmp = GetDefaultDetails(sec, 1, checkUser);
         TString det(dtmp);
         fHostAuth->AddFirst(sec, det);
         if (dtmp)
            delete [] dtmp;
      }
   }
   
   if (gDebug > 3) {
      TIter next(fHostAuth->Established());
      TRootSecContext *ctx;
      while ((ctx = (TRootSecContext *) next()))
         ctx->Print("0");
   }
}
void TAuthenticate::CatchTimeOut()
{
   
   Info("CatchTimeOut", "%d sec timeout expired (protocol: %s)",
        fgAuthTO, fgAuthMeth[fSecurity].Data());
   fTimeOut = 1;
   if (fSocket)
      fSocket->Close("force");
   return;
}
Bool_t TAuthenticate::Authenticate()
{
   
   
   if (gDebug > 2 && gAuthenticateMutex)
      Info("Authenticate", "locking mutex (pid:  %d)",gSystem->GetPid());
   R__LOCKGUARD2(gAuthenticateMutex);
   Bool_t rc = kFALSE;
   Int_t st = -1;
   Int_t remMeth = 0, rMth[kMAXSEC], tMth[kMAXSEC] = {0};
   Int_t meth = 0;
   char noSupport[80] = { 0 };
   char triedMeth[80] = { 0 };
   Int_t ntry = 0;
   TString user, passwd;
   Bool_t pwhash;
   if (gDebug > 2)
      Info("Authenticate", "enter: fUser: %s", fUser.Data());
   
   
   TTimer *alarm = 0;
   if (fgAuthTO > 0) {
      alarm = new TTimer(0, kFALSE);
      alarm->SetInterruptSyscalls();
      
      alarm->Connect("Timeout()", "TAuthenticate", this, "CatchTimeOut()");
   }
negotia:
   st = -1;
   tMth[meth] = 1;
   ntry++;
   if (gDebug > 2)
      Info("Authenticate", "try #: %d", ntry);
   user = "";
   passwd = "";
   pwhash = kFALSE;
   
   fSecurity = (ESecurity) fHostAuth->GetMethod(meth);
   fDetails = fHostAuth->GetDetails((Int_t) fSecurity);
   if (gDebug > 2)
      Info("Authenticate",
           "trying authentication: method:%d, default details:%s",
           fSecurity, fDetails.Data());
   
   if (strlen(triedMeth) > 0)
      sprintf(triedMeth, "%s %s", triedMeth, fgAuthMeth[fSecurity].Data());
   else
      sprintf(triedMeth, "%s", fgAuthMeth[fSecurity].Data());
   
   SetEnvironment();
   st = -1;
   
   
   fTimeOut = 0;
   if (fgAuthTO > 0 && alarm) {
      alarm->Start(fgAuthTO*1000, kTRUE);
   }
   
   if (fSecurity == kClear) {
      Bool_t rc = kFALSE;
      
      user = fgDefaultUser;
      if (user != "")
         CheckNetrc(user, passwd, pwhash, kFALSE);
      if (passwd == "") {
         if (fgPromptUser)
            user = PromptUser(fRemote);
         rc = GetUserPasswd(user, passwd, pwhash, kFALSE);
      }
      fUser = user;
      fPasswd = passwd;
      if (!rc) {
         if (fUser != "root")
            st = ClearAuth(user, passwd, pwhash);
      } else {
         Error("Authenticate",
               "unable to get user name for UsrPwd authentication");
      }
   } else if (fSecurity == kSRP) {
      Bool_t rc = kFALSE;
      
      user = fgDefaultUser;
      if (user != "")
         CheckNetrc(user, passwd, pwhash, kTRUE);
      if (passwd == "") {
         if (fgPromptUser)
            user = PromptUser(fRemote);
         rc = GetUserPasswd(user, passwd, pwhash, kTRUE);
      }
      fUser = user;
      fPasswd = passwd;
      if (!fgSecAuthHook) {
         char *p;
         TString lib = "libSRPAuth";
         if ((p = gSystem->DynamicPathName(lib, kTRUE))) {
            delete [] p;
            gSystem->Load(lib);
         }
      }
      if (!rc && fgSecAuthHook) {
         st = (*fgSecAuthHook) (this, user, passwd, fRemote, fDetails,
                                fVersion);
      } else {
         if (!fgSecAuthHook)
            Error("Authenticate",
                  "no support for SRP authentication available");
         if (rc)
            Error("Authenticate",
                  "unable to get user name for SRP authentication");
      }
      
      if (st == 1) {
         fPwHash = kFALSE;
         fSRPPwd = kTRUE;
      }
   } else if (fSecurity == kKrb5) {
      if (fVersion > 0) {
         
         if (!fgKrb5AuthHook) {
            char *p;
            TString lib = "libKrb5Auth";
            if ((p = gSystem->DynamicPathName(lib, kTRUE))) {
               delete [] p;
               gSystem->Load(lib);
            }
         }
         if (fgKrb5AuthHook) {
            fUser = fgDefaultUser;
            st = (*fgKrb5AuthHook) (this, fUser, fDetails, fVersion);
         } else {
            Error("Authenticate",
                  "support for kerberos5 auth locally unavailable");
         }
      } else {
         if (gDebug > 0)
            Info("Authenticate",
                 "remote daemon does not support Kerberos authentication");
         if (strlen(noSupport) > 0)
            sprintf(noSupport, "%s/Krb5", noSupport);
         else
            sprintf(noSupport, "Krb5");
      }
   } else if (fSecurity == kGlobus) {
      if (fVersion > 1) {
         
         if (!fgGlobusAuthHook) {
            char *p;
            TString lib = "libGlobusAuth";
            if ((p = gSystem->DynamicPathName(lib, kTRUE))) {
               delete [] p;
               gSystem->Load(lib);
            }
         }
         if (fgGlobusAuthHook) {
            st = (*fgGlobusAuthHook) (this, fUser, fDetails);
         } else {
            Error("Authenticate",
                  "no support for Globus authentication available");
         }
      } else {
         if (gDebug > 0)
            Info("Authenticate",
                 "remote daemon does not support Globus authentication");
         if (strlen(noSupport) > 0)
            sprintf(noSupport, "%s/Globus", noSupport);
         else
            sprintf(noSupport, "Globus");
      }
   } else if (fSecurity == kSSH) {
      if (fVersion > 1) {
         
         st = SshAuth(fUser);
      } else {
         if (gDebug > 0)
            Info("Authenticate",
                 "remote daemon does not support SSH authentication");
         if (strlen(noSupport) > 0)
            sprintf(noSupport, "%s/SSH", noSupport);
         else
            sprintf(noSupport, "SSH");
      }
   } else if (fSecurity == kRfio) {
      if (fVersion > 1) {
         
         st = RfioAuth(fUser);
      } else {
         if (gDebug > 0)
            Info("Authenticate",
                 "remote daemon does not support UidGid authentication");
         if (strlen(noSupport) > 0)
            sprintf(noSupport, "%s/UidGid", noSupport);
         else
            sprintf(noSupport, "UidGid");
      }
   }
   
   
   if (alarm) alarm->Stop();
   
   st = (fTimeOut > 0) ? -3 : st;
   
   
   
   
   
   Int_t action = 0;
   Int_t nmet = fHostAuth->NumMethods();
   Int_t remloc = nmet - ntry;
   if (gDebug > 0)
      Info("Authenticate","remloc: %d, ntry: %d, meth: %d, fSecurity: %d",
                           remloc, ntry, meth, fSecurity);
   Int_t kind, stat;
   switch (st) {
   case 1:
      
      
      fHostAuth->CountSuccess((Int_t)fSecurity);
      if (gDebug > 2)
         fSecContext->Print();
      if (fSecContext->IsActive())
         fSecContext->AddForCleanup(fSocket->GetPort(),
                                    fSocket->GetRemoteProtocol(),fSocket->GetServType());
      rc = kTRUE;
      break;
   case 0:
      
      
      fHostAuth->CountFailure((Int_t)fSecurity);
      if (fVersion < 2) {
         
         
         if (gDebug > 2)
            Info("Authenticate",
                 "negotiation not supported remotely: try next method, if any");
         if (meth < nmet - 1) {
            meth++;
            action = 1;
         } else {
            action = 2;
         }
         rc = kFALSE;
         break;
      }
      
      
      if (fSocket->Recv(stat, kind) < 0) {
         action = 0;
         rc = kFALSE;
      }
      if (gDebug > 2)
         Info("Authenticate",
              "after failed attempt: kind= %d, stat= %d", kind, stat);
      if (kind == kROOTD_ERR) {
         action = 2;
         rc = kFALSE;
      } else if (kind == kROOTD_NEGOTIA) {
         if (stat > 0) {
            int len = 3 * stat;
            char *answer = new char[len];
            int nrec = fSocket->Recv(answer, len, kind);  
            if (nrec < 0) {
               action = 0;
               rc = kFALSE;
               break;
            }
            if (kind != kMESS_STRING)
               Warning("Authenticate",
                       "strings with accepted methods not received (%d:%d)",
                       kind, nrec);
            remMeth =
               sscanf(answer, "%d %d %d %d %d %d", &rMth[0], &rMth[1],
                      &rMth[2], &rMth[3], &rMth[4], &rMth[5]);
            if (gDebug > 0 && remloc > 0)
               Info("Authenticate",
                    "remotely allowed methods not yet tried: %s",
                    answer);
            if (answer)
               delete[] answer;
         } else if (stat == 0) {
            Info("Authenticate",
                 "no more methods accepted remotely to be tried");
            action = 3;
            rc = kFALSE;
            break;
         }
         
         if (remloc < 1) {
            action = 2;
            rc = kFALSE;
            break;
         }
         
         int i, j;
         char locav[40] = { 0 };
         Bool_t methfound = kFALSE;
         for (i = 0; i < remMeth; i++) {
            for (j = 0; j < nmet; j++) {
               if (fHostAuth->GetMethod(j) == rMth[i] && tMth[j] == 0) {
                  meth = j;
                  action = 1;
                  methfound = kTRUE;
                  break;
               }
               if (i == 0)
                  sprintf(locav, "%s %d", locav, fHostAuth->GetMethod(j));
            }
            if (methfound) break;
         }
         if (methfound) break;
         
         
         if (gDebug > 0)
            Warning("Authenticate",
                    "no match with those locally available: %s", locav);
         action = 2;
         rc = kFALSE;
         break;
      } else {        
         action = 3;
         rc = kFALSE;
         break;
      }
      break;
   case -1:
      
      
      fHostAuth->CountFailure((Int_t)fSecurity);
      if (gDebug > 2)
         Info("Authenticate",
              "method not even started: insufficient or wrong info: %s",
              "try with next method, if any");
      fHostAuth->RemoveMethod(fSecurity);
      nmet--;
      if (nmet > 0) {
         action = 1;
      } else
         action = 2;
      break;
   case -2:
      
      
      fHostAuth->CountFailure((Int_t)fSecurity);
      if (fVersion <= 2)
         if (gDebug > 2)
            Warning("Authenticate",
                    "status code -2 not expected from old daemons");
      rc = kFALSE;
      break;
   case -3:
      
      
      
      
      
      fHostAuth->CountFailure((Int_t)fSecurity);
      if (gDebug > 2)
         Info("Authenticate", "got a timeout");
      fHostAuth->SetLast(fSecurity);
      if (meth < nmet - 1) {
         fTimeOut = 2;
      } else
         fTimeOut = 1;
      rc = kFALSE;
      break;
   default:
      fHostAuth->CountFailure((Int_t)fSecurity);
      if (gDebug > 2)
         Info("Authenticate", "unknown status code: %d - assume failure",st);
      rc = kFALSE;
      action = 0;
      break;
   }
   switch (action) {
   case 1:
      goto negotia;
   case 2:
      fSocket->Send("0", kROOTD_BYE);
   case 3:
      if (strlen(noSupport) > 0)
         Info("Authenticate", "attempted methods %s are not supported"
              " by remote server version", noSupport);
      Info("Authenticate",
           "failure: list of attempted methods: %s", triedMeth);
      AuthError("Authenticate",-1);
      rc = kFALSE;
      break;
   default:
      break;
   }
   
   if (alarm)
      SafeDelete(alarm);
   return rc;
}
void TAuthenticate::SetEnvironment()
{
   
   
   R__LOCKGUARD2(gAuthenticateMutex);
   if (gDebug > 2)
      Info("SetEnvironment",
           "setting environment: fSecurity:%d, fDetails:%s", fSecurity,
           fDetails.Data());
   
   fgDefaultUser = fgUser;
   if (fSecurity == kKrb5 ||
       (fSecurity == kGlobus && gROOT->IsProofServ()))
      fgAuthReUse = kFALSE;
   else
      fgAuthReUse = kTRUE;
   fgPromptUser = kFALSE;
   
   if (fDetails != "") {
      char usdef[kMAXPATHLEN] = { 0 };
      Int_t lDet = strlen(fDetails.Data()) + 2;
      char pt[5] = { 0 }, ru[5] = { 0 };
      Int_t hh = 0, mm = 0;
      char *us = 0, *cd = 0, *cf = 0, *kf = 0, *ad = 0, *cp = 0, *pp = 0;
      const char *ptr;
      TString usrPromptDef = TString(GetAuthMethod(fSecurity)) + ".LoginPrompt";
      if ((ptr = strstr(fDetails, "pt:")) != 0) {
         sscanf(ptr + 3, "%s %s", pt, usdef);
      } else {
         if (!strncasecmp(gEnv->GetValue(usrPromptDef,""),"no",2) ||
             !strncmp(gEnv->GetValue(usrPromptDef,""),"0",1))
            strcpy(pt,"0");
         else
            strcpy(pt,"1");
      }
      TString usrReUseDef = TString(GetAuthMethod(fSecurity)) + ".ReUse";
      if ((ptr = strstr(fDetails, "ru:")) != 0) {
         sscanf(ptr + 3, "%s %s", ru, usdef);
      } else {
         if (!strncasecmp(gEnv->GetValue(usrReUseDef,""),"no",2) ||
             !strncmp(gEnv->GetValue(usrReUseDef,""),"0",1))
            strcpy(ru,"0");
         else
            strcpy(ru,"1");
      }
      TString usrValidDef = TString(GetAuthMethod(fSecurity)) + ".Valid";
      TString hours(gEnv->GetValue(usrValidDef,"24:00"));
      Int_t pd = 0;
      if ((pd = hours.Index(":")) > -1) {
         TString minutes = hours;
         hours.Resize(pd);
         minutes.Replace(0,pd+1,"");
         hh = atoi(hours.Data());
         mm = atoi(minutes.Data());
      } else {
         hh = atoi(hours.Data());
         mm = 0;
      }
      
      if (fSecurity == kGlobus) {
         cd = new char[lDet];
         cf = new char[lDet];
         kf = new char[lDet];
         ad = new char[lDet];
         cd[0] = '\0';
         cf[0] = '\0';
         kf[0] = '\0';
         ad[0] = '\0';
         if ((ptr = strstr(fDetails, "cd:")) != 0)
            sscanf(ptr, "%s %s", cd, usdef);
         if ((ptr = strstr(fDetails, "cf:")) != 0)
            sscanf(ptr, "%s %s", cf, usdef);
         if ((ptr = strstr(fDetails, "kf:")) != 0)
            sscanf(ptr, "%s %s", kf, usdef);
         if ((ptr = strstr(fDetails, "ad:")) != 0)
            sscanf(ptr, "%s %s", ad, usdef);
         if (gDebug > 2) {
            Info("SetEnvironment",
                 "details:%s, pt:%s, ru:%s, cd:%s, cf:%s, kf:%s, ad:%s",
                 fDetails.Data(), pt, ru, cd, cf, kf, ad);
         }
      } else if (fSecurity == kClear) {
         us = new char[lDet];
         us[0] = '\0';
         cp = new char[lDet];
         cp[0] = '\0';
         if ((ptr = strstr(fDetails, "us:")) != 0)
            sscanf(ptr + 3, "%s %s", us, usdef);
         if ((ptr = strstr(fDetails, "cp:")) != 0)
            sscanf(ptr + 3, "%s %s", cp, usdef);
         if (gDebug > 2)
            Info("SetEnvironment", "details:%s, pt:%s, ru:%s, us:%s cp:%s",
                 fDetails.Data(), pt, ru, us, cp);
      } else if (fSecurity == kKrb5) {
         us = new char[lDet];
         us[0] = '\0';
         pp = new char[lDet];
         pp[0] = '\0';
         if ((ptr = strstr(fDetails, "us:")) != 0)
            sscanf(ptr + 3, "%s %s", us, usdef);
         if ((ptr = strstr(fDetails, "pp:")) != 0)
            sscanf(ptr + 3, "%s %s", pp, usdef);
         if (gDebug > 2)
            Info("SetEnvironment", "details:%s, pt:%s, ru:%s, us:%s pp:%s",
                 fDetails.Data(), pt, ru, us, pp);
      } else {
         us = new char[lDet];
         us[0] = '\0';
         if ((ptr = strstr(fDetails, "us:")) != 0)
            sscanf(ptr + 3, "%s %s", us, usdef);
         if (gDebug > 2)
            Info("SetEnvironment", "details:%s, pt:%s, ru:%s, us:%s",
                 fDetails.Data(), pt, ru, us);
      }
      
      if (!strncasecmp(pt, "yes",3) || !strncmp(pt, "1", 1))
         fgPromptUser = kTRUE;
      
      if (fSecurity == kKrb5) {
         fgAuthReUse = kFALSE;
         if (!strncasecmp(ru, "yes",3) || !strncmp(ru, "1",1))
            fgAuthReUse = kTRUE;
      } else {
         if (fSecurity != kGlobus || !(gROOT->IsProofServ())) {
            fgAuthReUse = kTRUE;
            if (!strncasecmp(ru, "no",2) || !strncmp(ru, "0",1))
               fgAuthReUse = kFALSE;
         }
      }
      
      fgExpDate = TDatime();
      fgExpDate.Set(fgExpDate.Convert() + hh*3600 + mm*60);
      
      if (fSecurity == kClear) {
         fgUsrPwdCrypt = kTRUE;
         if (!strncmp(cp, "no", 2) || !strncmp(cp, "0", 1))
            fgUsrPwdCrypt = kFALSE;
      }
      
      usdef[0] = '\0';
      if (fSecurity == kGlobus) {
         if (cd != 0) {
            strcat(usdef," ");
            strcat(usdef,cd);
            delete [] cd;
            cd = 0;
         }
         if (cf != 0) {
            strcat(usdef," ");
            strcat(usdef,cf);
            delete [] cf;
            cf = 0;
         }
         if (kf != 0) {
            strcat(usdef," ");
            strcat(usdef,kf);
            delete [] kf;
            kf = 0;
         }
         if (ad != 0) {
            strcat(usdef," ");
            strcat(usdef,ad);
            delete [] ad;
            ad = 0;
         }
      } else {
         if (fSecurity == kKrb5) {
            
            if (pp && strlen(pp) > 0) {
               fgKrb5Principal = TString(pp);
               delete [] pp;
               pp = 0;
            } else {
               
               if (us && strlen(us) > 0 && strstr(us,"@")) {
                  fgKrb5Principal = TString(us);
                  delete [] us;
                  us = 0;
               }
            }
            
            if (fUser.Length()) {
               sprintf(usdef, "%s", fUser.Data());
            } else {
               if (us && strlen(us) > 0 && !strstr(us,"@")) {
                  sprintf(usdef, "%s", us);
                  delete [] us;
                  us = 0;
               }
            }
            if (us != 0) {
               delete [] us;
               us = 0;
            }
            if (pp != 0) {
               delete [] pp;
               pp = 0;
            }
         } else {
            
            if (fUser == "") {
               if (us != 0) {
                  sprintf(usdef, "%s", us);
                  delete [] us;
                  us = 0;
               }
            } else
               sprintf(usdef, "%s", fUser.Data());
         }
      }
      if (strlen(usdef) > 0) {
         fgDefaultUser = usdef;
      } else {
         if (fgUser != "") {
            fgDefaultUser = fgUser;
         } else {
            UserGroup_t *u = gSystem->GetUserInfo();
            if (u)
               fgDefaultUser = u->fUser;
            delete u;
         }
      }
      if (fgDefaultUser == "anonymous" || fgDefaultUser == "rootd" ||
          fgUser != "" || fUser != "") {
         
         fgPromptUser = kFALSE;
      }
      if (gDebug > 2)
         Info("SetEnvironment", "usdef:%s", fgDefaultUser.Data());
      if (us) delete [] us;
      if (cd) delete [] cd;
      if (cf) delete [] cf;
      if (kf) delete [] kf;
      if (ad) delete [] ad;
      if (cp) delete [] cp;
      if (pp) delete [] pp;
   }
}
Bool_t TAuthenticate::GetUserPasswd(TString &user, TString &passwd,
                                    Bool_t &pwhash, Bool_t srppwd)
{
   
   if (gDebug > 3)
      Info("GetUserPasswd", "Enter: User: '%s' Hash:%d SRP:%d",
           user.Data(),(Int_t)pwhash,(Int_t)srppwd);
   
   if (user == "") {
      if (fgUser != "")
         user = fgUser;
      if (passwd == "" && fgPasswd != "" && srppwd == fgSRPPwd) {
         passwd = fgPasswd;
         pwhash = fgPwHash;
      }
   } else {
      if (fgUser != "" && user == fgUser) {
         if (passwd == "" && fgPasswd != "" && srppwd == fgSRPPwd) {
            passwd = fgPasswd;
            pwhash = fgPwHash;
         }
      }
   }
   if (gDebug > 3)
      Info("GetUserPasswd", "In memory: User: '%s' Hash:%d",
           user.Data(),(Int_t)pwhash);
   
   if (user == "") {
      UserGroup_t *u = gSystem->GetUserInfo();
      if (u)
         user = u->fUser;
      delete u;
      if (gDebug > 3)
         Info("GetUserPasswd", "In memory: User: '%s' Hash:%d",
              user.Data(),(Int_t)pwhash);
   }
   
   
   if (user == "" || passwd == "") {
      if (gDebug > 3)
         Info("GetUserPasswd", "Checking .netrc family ...");
      CheckNetrc(user, passwd, pwhash, srppwd);
   }
   if (gDebug > 3)
      Info("GetUserPasswd", "From .netrc family: User: '%s' Hash:%d",
           user.Data(),(Int_t)pwhash);
   
   if (user == "") {
      user = PromptUser(fRemote);
      if (user == "") {
         Error("GetUserPasswd", "user name not set");
         return 1;
      }
   }
   return 0;
}
Bool_t TAuthenticate::CheckNetrc(TString &user, TString &passwd)
{
   
   
   
   Bool_t hash, srppwd;
   
   srppwd = (fSecurity == kSRP) ? kTRUE : kFALSE;
   return CheckNetrc(user, passwd, hash, srppwd);
}
Bool_t TAuthenticate::CheckNetrc(TString &user, TString &passwd,
                                 Bool_t &pwhash, Bool_t srppwd)
{
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   Bool_t result = kFALSE;
   Bool_t first = kTRUE;
   TString remote = fRemote;
   passwd = "";
   pwhash = kFALSE;
   char *net =
      gSystem->ConcatFileName(gSystem->HomeDirectory(), ".rootnetrc");
   
   TInetAddress addr = gSystem->GetHostByName(fRemote);
   if (addr.IsValid()) {
      remote = addr.GetHostName();
      if (remote == "UnNamedHost")
         remote = addr.GetHostAddress();
   }
again:
   
   FileStat_t buf;
   if (gSystem->GetPathInfo(net, buf) == 0) {
#ifdef WIN32
      
      if (R_ISREG(buf.fMode) && !R_ISDIR(buf.fMode)) {
#else
         if (R_ISREG(buf.fMode) && !R_ISDIR(buf.fMode) &&
             (buf.fMode & 0777) == (kS_IRUSR | kS_IWUSR)) {
#endif
            FILE *fd = fopen(net, "r");
            char line[256];
            while (fgets(line, sizeof(line), fd) != 0) {
               if (line[0] == '#')
                  continue;
               char word[6][64];
               int nword = sscanf(line, "%s %s %s %s %s %s", word[0], word[1],
                                  word[2], word[3], word[4], word[5]);
               if (nword != 6)
                  continue;
               if (srppwd && strcmp(word[0], "secure"))
                  continue;
               if (!srppwd && strcmp(word[0], "machine"))
                  continue;
               if (strcmp(word[2], "login"))
                  continue;
               if (srppwd && strcmp(word[4], "password"))
                  continue;
               if (!srppwd &&
                   strcmp(word[4], "password") && strcmp(word[4], "password-hash"))
                  continue;
               
               
               TString href(word[1]);
               href.ReplaceAll("*",".*");
               TRegexp rg(href);
               if (remote.Index(rg) != kNPOS) {
                  if (user == "") {
                     user = word[3];
                     passwd = word[5];
                     if (!strcmp(word[4], "password-hash"))
                        pwhash = kTRUE;
                     result = kTRUE;
                     break;
                  } else {
                     if (!strcmp(word[3], user.Data())) {
                        passwd = word[5];
                        if (!strcmp(word[4], "password-hash"))
                           pwhash = kTRUE;
                        result = kTRUE;
                        break;
                     }
                  }
               }
            }
            fclose(fd);
         } else
            Warning("CheckNetrc",
                    "file %s exists but has not 0600 permission", net);
      }
      delete [] net;
      if (first && !srppwd && !result) {
         net = gSystem->ConcatFileName(gSystem->HomeDirectory(), ".netrc");
         first = kFALSE;
         goto again;
      }
      return result;
   }
const char *TAuthenticate::GetGlobalUser()
{
   
   return fgUser;
}
Bool_t TAuthenticate::GetGlobalPwHash()
{
   
   return fgPwHash;
}
Bool_t TAuthenticate::GetGlobalSRPPwd()
{
   
   return fgSRPPwd;
}
TDatime TAuthenticate::GetGlobalExpDate()
{
   
   return fgExpDate;
}
const char *TAuthenticate::GetDefaultUser()
{
   
   return fgDefaultUser;
}
const char *TAuthenticate::GetKrb5Principal()
{
    
   return fgKrb5Principal;
}
Bool_t TAuthenticate::GetAuthReUse()
{
   
   return fgAuthReUse;
}
Bool_t TAuthenticate::GetPromptUser()
{
   
   return fgPromptUser;
}
const char *TAuthenticate::GetAuthMethod(Int_t idx)
{
   
   R__LOCKGUARD2(gAuthenticateMutex);
   if (idx < 0 || idx > kMAXSEC-1) {
      ::Error("Authenticate::GetAuthMethod", "idx out of bounds (%d)", idx);
      idx = 0;
   }
   return fgAuthMeth[idx];
}
Int_t TAuthenticate::GetAuthMethodIdx(const char *meth)
{
   
   
   R__LOCKGUARD2(gAuthenticateMutex);
   if (meth && meth[0]) {
      for (Int_t i = 0; i < kMAXSEC; i++) {
         if (!fgAuthMeth[i].CompareTo(meth, TString::kIgnoreCase))
            return i;
      }
   }
   return -1;
}
char *TAuthenticate::PromptUser(const char *remote)
{
   
   
   
   
   R__LOCKGUARD2(gAuthenticateMutex);
   const char *user;
   if (fgDefaultUser != "")
      user = fgDefaultUser;
   else
      user = gSystem->Getenv("USER");
#ifdef R__WIN32
   if (!user)
      user = gSystem->Getenv("USERNAME");
#endif
   if (isatty(0) == 0 || isatty(1) == 0) {
      ::Warning("TAuthenticate::PromptUser",
                "not tty: cannot prompt for user, returning default");
      if (strlen(user))
         return StrDup(user);
      else
         return StrDup("None");
   }
   char *usr = Getline(Form("Name (%s:%s): ", remote, user));
   if (usr[0]) {
      usr[strlen(usr) - 1] = 0; 
      if (strlen(usr))
         return StrDup(usr);
      else
         return StrDup(user);
   }
   return 0;
}
char *TAuthenticate::PromptPasswd(const char *prompt)
{
   
   
   
   
   if (isatty(0) == 0 || isatty(1) == 0) {
      ::Warning("TAuthenticate::PromptPasswd",
                "not tty: cannot prompt for passwd, returning -1");
      static char noint[4] = {"-1"};
      return StrDup(noint);
   }
   char buf[128];
   char *pw = buf;
   
   if (!gROOT->IsBatch() && (fgPasswdDialog == (TPluginHandler *)(-1)) &&
       gEnv->GetValue("Auth.UsePasswdDialogBox", 1) == 1) {
      if ((fgPasswdDialog =
           gROOT->GetPluginManager()->FindHandler("TGPasswdDialog"))) {
         if (fgPasswdDialog->LoadPlugin() == -1) {
            fgPasswdDialog = 0;
            ::Warning("TAuthenticate",
                      "could not load plugin for the password dialog box");
         }
      }
   }
   if (fgPasswdDialog && (fgPasswdDialog != (TPluginHandler *)(-1))) {
      
      fgPasswdDialog->ExecPlugin(3, prompt, buf, 128);
      
      while (gROOT->IsInterrupted())
         gSystem->DispatchOneEvent(kFALSE);
   } else {
      Gl_config("noecho", 1);
      pw = Getline((char *) prompt);
      Gl_config("noecho", 0);
   }
   
   if (pw[0]) {
      if (pw[strlen(pw)-1] == '\n')
         pw[strlen(pw) - 1] = 0;   
      char *rpw = StrDup(pw);
      memset(pw, 0, strlen(pw));
      return rpw;
   }
   return 0;
}
GlobusAuth_t TAuthenticate::GetGlobusAuthHook()
{
   
   return fgGlobusAuthHook;
}
const char *TAuthenticate::GetRSAPubExport(Int_t key)
{
   
   key = (key >= 0 && key <= 1) ? key : 0;
   return fgRSAPubExport[key].keys;
}
Int_t TAuthenticate::GetRSAInit()
{
   
   return fgRSAInit;
}
void TAuthenticate::SetDefaultRSAKeyType(Int_t key)
{
   
   if (key >= 0 && key <= 1)
      fgRSAKey = key;
}
void TAuthenticate::SetRSAInit(Int_t init)
{
   
   fgRSAInit = init;
}
TList *TAuthenticate::GetAuthInfo()
{
   
   R__LOCKGUARD2(gAuthenticateMutex);
   if (!fgAuthInfo)
      fgAuthInfo = new TList;
   return fgAuthInfo;
}
TList *TAuthenticate::GetProofAuthInfo()
{
   
   
   R__LOCKGUARD2(gAuthenticateMutex);
   if (!fgProofAuthInfo)
      fgProofAuthInfo = new TList;
   return fgProofAuthInfo;
}
void TAuthenticate::AuthError(const char *where, Int_t err)
{
   
   R__LOCKGUARD2(gAuthenticateMutex);
   
   err = (err < kErrError) ? ((err > -1) ? err : -1) : kErrError;
   Int_t erc = err;
   Bool_t forceprint = kFALSE;
   TString lasterr = "";
   if (err == -1) {
      forceprint = kTRUE;
      erc = fgLastError;
      lasterr = "(last error only; re-run with gDebug > 0 for more details)";
   }
   if (erc > -1)
      if (gDebug > 0 || forceprint)
         if (gRootdErrStr[erc])
            ::Error(Form("TAuthenticate::%s", where), "%s %s",
                    gRootdErrStr[erc], lasterr.Data());
         else
            ::Error(Form("TAuthenticate::%s", where),
                    "unknown error code: server must be running a newer ROOT version %s",
                    lasterr.Data());
   
   fgLastError = err;
}
void TAuthenticate::SetGlobalUser(const char *user)
{
   
   R__LOCKGUARD2(gAuthenticateMutex);
   if (fgUser != "")
      fgUser = "";
   if (user && user[0])
      fgUser = user;
}
void TAuthenticate::SetGlobalPasswd(const char *passwd)
{
   
   R__LOCKGUARD2(gAuthenticateMutex);
   if (fgPasswd != "")
      fgPasswd = "";
   if (passwd && passwd[0])
      fgPasswd = passwd;
}
void TAuthenticate::SetGlobalPwHash(Bool_t pwhash)
{
   
   fgPwHash = pwhash;
}
void TAuthenticate::SetGlobalSRPPwd(Bool_t srppwd)
{
   
   fgSRPPwd = srppwd;
}
void TAuthenticate::SetReadHomeAuthrc(Bool_t readhomeauthrc)
{
   
   
   
   fgReadHomeAuthrc = readhomeauthrc;
}
void TAuthenticate::SetGlobalExpDate(TDatime expdate)
{
   
   fgExpDate = expdate;
}
void TAuthenticate::SetDefaultUser(const char *defaultuser)
{
   
   if (fgDefaultUser != "")
      fgDefaultUser = "";
   if (defaultuser && defaultuser[0])
      fgDefaultUser = defaultuser;
}
void TAuthenticate::SetTimeOut(Int_t to)
{
   
   fgAuthTO = (to <= 0) ? -1 : to;
}
void TAuthenticate::SetAuthReUse(Bool_t authreuse)
{
   
   fgAuthReUse = authreuse;
}
void TAuthenticate::SetPromptUser(Bool_t promptuser)
{
   
   fgPromptUser = promptuser;
}
void TAuthenticate::SetSecureAuthHook(SecureAuth_t func)
{
   
   
   fgSecAuthHook = func;
}
void TAuthenticate::SetKrb5AuthHook(Krb5Auth_t func)
{
   
   
   fgKrb5AuthHook = func;
}
void TAuthenticate::SetGlobusAuthHook(GlobusAuth_t func)
{
   
   
   fgGlobusAuthHook = func;
}
Int_t TAuthenticate::SshError(const char *errorfile)
{
   
   
   
   Int_t error = 0;
   if (!gSystem->AccessPathName(errorfile, kReadPermission)) {
      FILE *ferr = fopen(errorfile,"r");
      if (ferr) {
         
         char *serr = StrDup(gEnv->GetValue("SSH.ErrorRetry", ""));
         
         Int_t lerr = strlen(serr);
         char *pc = (char *)memchr(serr,'"',lerr);
         while (pc) {
            *pc = '\0';
            pc = (char *)memchr(pc+1,'"',strlen(pc+1));
         }
         
         char line[kMAXPATHLEN];
         while (fgets(line,sizeof(line),ferr)) {
            
            if (line[strlen(line)-1] == '\n')
               line[strlen(line)-1] = '\0';
            if (gDebug > 2)
               Info("SshError","read line: %s",line);
            pc = serr;
            while (pc < serr + lerr) {
               if (pc[0] == '\0' || pc[0] == ' ')
                  pc++;
               else {
                  if (gDebug > 2)
                     Info("SshError","checking error: '%s'",pc);
                  if (strstr(line,pc))
                     error = 1;
                  pc += strlen(pc);
               }
            }
         }
         
         fclose(ferr);
         
         if (serr) delete [] serr;
      }
   }
   return error;
}
Int_t TAuthenticate::SshAuth(TString &user)
{
   
   
   
   
   if (gROOT->IsProofServ()) {
      if (!(gEnv->GetValue("ProofServ.UseSSH",0))) {
         if (gDebug > 0)
            Info("SshAuth", "SSH protocol is switched OFF by default"
                 " for PROOF servers: use 'ProofServ.UseSSH 1'"
                 " to enable it (see system.rootrc)");
         return -1;
      }
   }
   Int_t sshproto = 1;
   if (fVersion < 4)
      sshproto = 0;
   
   char cmdref[2][5] = {"ssh", "scp"};
   char scmd[5] = "";
   char *gSshExe = 0;
   Bool_t notfound = kTRUE;
   while (notfound && sshproto > -1) {
      strcpy(scmd,cmdref[sshproto]);
      
      gSshExe = gSystem->Which(gSystem->Getenv("PATH"),
                               scmd, kExecutePermission);
      if (!gSshExe) {
         if (gDebug > 2)
            Info("SshAuth", "%s not found in $PATH", scmd);
         
         if (strcmp(gEnv->GetValue("SSH.ExecDir", "-1"), "-1")) {
            if (gDebug > 2)
               Info("SshAuth", "searching user defined path ...");
            if (gSshExe) delete [] gSshExe;
            gSshExe = StrDup(Form("%s/%s",
                                  (char *)gEnv->GetValue("SSH.ExecDir", ""), scmd));
            if (gSystem->AccessPathName(gSshExe, kExecutePermission)) {
               if (gDebug > 2)
                  Info("SshAuth", "%s not executable", gSshExe);
            } else
               notfound = kFALSE;
         }
      } else
         notfound = kFALSE;
      if (notfound) sshproto--;
   }
   
   if (notfound) {
      if (gSshExe) delete [] gSshExe;
      return -1;
   }
   if (gDebug > 2)
      Info("SshAuth", "%s is %s (sshproto: %d)", scmd, gSshExe, sshproto);
   
   
   
   
   
   
   
   char secName[kMAXPATHLEN] = { 0 };
   
   user = GetSshUser(user);
   
   Int_t reuse = (int)fgAuthReUse;
   fDetails = TString(Form("pt:%d ru:%d us:",(int)fgPromptUser,(int)fgAuthReUse))
      + user;
   
   int opt = reuse * kAUTH_REUSE_MSK + fRSAKey * kAUTH_RSATY_MSK;
   TString options(Form("%d none %ld %s %d", opt,
                        (Long_t)user.Length(),user.Data(),sshproto));
   
   Int_t kind = kROOTD_SSH;
   Int_t retval = reuse;
   Int_t rc = 0;
   if ((rc = AuthExists(user, (Int_t) TAuthenticate::kSSH, options,
                        &kind, &retval, &StdCheckSecCtx)) == 1) {
      
      return 1;
   }
   if (rc == -2) {
      return rc;
   }
   if (retval == kErrNotAllowed && kind == kROOTD_ERR) {
      return 0;
   }
   
   if (kind != kROOTD_SSH)
      return 0;                 
   if (retval == 0)
      return 0;                 
   if (retval == -2)
      return 0;                 
   
   
   char cmdinfo[kMAXPATHLEN] = { 0 };
   Int_t reclen = (retval+1 > kMAXPATHLEN) ? kMAXPATHLEN : retval+1 ;
   if (fSocket->Recv(cmdinfo, reclen, kind) < 0)
      return 0;
   if (kind != kROOTD_SSH)
      return 0;                 
   if (gDebug > 3)
      Info("SshAuth", "received from server command info: %s", cmdinfo);
   int rport = -1;
   char *pd = 0;
   if ((pd = strstr(cmdinfo, "p:")) != 0 || (pd = strstr(cmdinfo, "k:"))) {
      Int_t clen = (Int_t) (pd - cmdinfo) - 1;
      cmdinfo[clen] = '\0';
      char ss[2][20] = {{0},{0}};
      Int_t ns = sscanf(pd-1,"%s %s",ss[0],ss[1]);
      Int_t i = 0;
      for( ; i < ns; i++ ) {
         if (strlen(ss[i])) {
            if (!strncmp(ss[i],"p:",2)) {
               char *pp = (char *)(ss[i])+2;
               rport = atoi(pp);
            }
#ifdef R__SSL
            if (!strncmp(ss[i],"k:",2)) {
               char *pk = (char *)(ss[i])+2;
               if (atoi(pk) == 1)
                  fRSAKey = 1;
            }
#endif
         }
      }
   }
   
   TString noPrompt = "";
   if (isatty(0) == 0 || isatty(1) == 0) {
      noPrompt  = TString("-o 'PasswordAuthentication no' ");
      noPrompt += TString("-o 'StrictHostKeyChecking no' ");
      if (gDebug > 3)
         Info("SshAuth", "using noprompt options: %s", noPrompt.Data());
   }
   
   Int_t srvtyp = fSocket->GetServType();
   Int_t rproto = fSocket->GetRemoteProtocol();
   
   
   int ssh_rc = 1;
   Int_t ntry = gEnv->GetValue("SSH.MaxRetry",100);
   TString fileErr = "";
   if (sshproto == 0) {
      
      TString fileErr = "rootsshtmp_";
      FILE *floc = gSystem->TempFileName(fileErr,gSystem->HomeDirectory());
      if (floc == 0) {
         
         fileErr = "rootsshtmp_";
         floc = gSystem->TempFileName(fileErr);
      }
      fileErr.Append(".error");
      TString sshcmd(Form("%s -x -l %s %s",
                          gSshExe, user.Data(), noPrompt.Data()));
      if (rport != -1)
         sshcmd += TString(Form(" -p %d",rport));
      sshcmd += TString(Form(" %s %s",fRemote.Data(), cmdinfo));
      sshcmd += TString(Form(" 1> /dev/null 2> %s",fileErr.Data()));
      
      Int_t again = 1;
      while (ssh_rc && again && ntry--) {
         ssh_rc = gSystem->Exec(sshcmd);
         if (ssh_rc) {
            again = SshError(fileErr);
            if (gDebug > 3)
               Info("SshAuth", "%d: sleeping: rc: %d, again:%d, ntry: %d",
                    fgProcessID, ssh_rc, again, ntry);
            if (again)
               gSystem->Sleep(1);
         }
      }
   } else {
      
      
      
      Bool_t addhost = ((srvtyp == TSocket::kROOTD && rproto < 15) ||
                        (srvtyp == TSocket::kPROOFD && rproto < 13)||
                        (srvtyp == TSocket::kSOCKD && rproto < 1)) ? 1 : 0;
      
      TString fileLoc = "rootsshtmp_";
      FILE *floc = gSystem->TempFileName(fileLoc,gSystem->HomeDirectory());
      if (floc == 0) {
         
         fileLoc = "rootsshtmp_";
         floc = gSystem->TempFileName(fileLoc);
      }
      if (floc != 0) {
         
         fclose(floc);
         if (chmod(fileLoc, 0600) == -1) {
            Info("SshAuth", "fchmod error: %d", errno);
            ssh_rc = 2;
         } else {
            floc = fopen(fileLoc, "w");
            if (reuse == 1) {
               
               if (fVersion > 4) {
                  fprintf(floc,"k: %d\n",fRSAKey+1);
                  fwrite(fgRSAPubExport[fRSAKey].keys,1,
                         fgRSAPubExport[fRSAKey].len,floc);
               } else {
                  fprintf(floc,"k: %s\n",fgRSAPubExport[0].keys);
               }
            } else
               
               fprintf(floc,"k: -1\n");
            fclose(floc);
            ssh_rc = 0;
         }
         if (!ssh_rc) {
            fileErr = TString(fileLoc).Append(".error");
            TString sshcmd(Form("%s -p %s", gSshExe, noPrompt.Data()));
            if (rport != -1)
               sshcmd += TString(Form(" -P %d",rport));
            sshcmd += TString(Form(" %s",fileLoc.Data()));
            if (addhost) {
               sshcmd += TString(Form(" %s@%s:%s 1> /dev/null",
                                        user.Data(),fRemote.Data(),cmdinfo));
            } else {
               sshcmd += TString(Form("%s 1> /dev/null", cmdinfo));
            }
            sshcmd += TString(Form(" 2> %s",fileErr.Data()));
            
            ssh_rc = 1;
            Int_t again = 1;
            while (ssh_rc && again && ntry--) {
               ssh_rc = gSystem->Exec(sshcmd);
               if (ssh_rc) {
                  again = SshError(fileErr);
                  if (gDebug > 3)
                     Info("SshAuth", "%d: sleeping: rc: %d, again:%d, ntry: %d",
                          fgProcessID, ssh_rc, again, ntry);
                  if (again)
                     
                     gSystem->Sleep(1000);
               }
            }
         }
      } else {
         
         ssh_rc = 1;
      }
      
      if (!gSystem->AccessPathName(fileLoc,kFileExists)) {
         gSystem->Unlink(fileLoc);
      }
   }
   
   if (!gSystem->AccessPathName(fileErr,kFileExists)) {
      gSystem->Unlink(fileErr);
   }
   if (gDebug > 3)
      Info("SshAuth", "%d: system return code: %d (%d)",
           fgProcessID, ssh_rc, ntry+1);
   if (ssh_rc && sshproto == 0) {
      Int_t srvtyp = fSocket->GetServType();
      Int_t rproto = fSocket->GetRemoteProtocol();
      Int_t level = 2;
      if ((srvtyp == TSocket::kROOTD && rproto < 10) ||
          (srvtyp == TSocket::kPROOFD && rproto < 9))
         level = 1;
      if ((srvtyp == TSocket::kROOTD && rproto < 8) ||
          (srvtyp == TSocket::kPROOFD && rproto < 7))
         level = 0;
      if (level) {
         Int_t port = fSocket->GetPort();
         TSocket *newsock = 0;
         TString url(Form("sockd://%s",fRemote.Data()));
         if (srvtyp == TSocket::kROOTD) {
            
            url.ReplaceAll("sockd",5,"rootd",5);
            newsock = new TPSocket(url.Data(),port,1,-1);
         } else {
            if (srvtyp == TSocket::kPROOFD)
               url.ReplaceAll("sockd",5,"proofd",6);
            newsock = new TSocket(fRemote.Data(),port,-1);
            if (srvtyp == TSocket::kPROOFD)
               newsock->Send("failure notification");
         }
         
         char cd1[1024], pipe[1024], dum[1024];
         Int_t id3;
         sscanf(cmdinfo, "%s %d %s %s", cd1, &id3, pipe, dum);
         snprintf(secName, kMAXPATHLEN, "%d -1 0 %s %d %s %d",
                  -fgProcessID, pipe,
                  (int)strlen(user), user.Data(), TSocket::GetClientProtocol());
         newsock->Send(secName, kROOTD_SSH);
         if (level > 1) {
            
            
            if (newsock->Recv(retval, kind) >= 0) {
               char *buf = new char[retval+1];
               if (newsock->Recv(buf, retval+1, kind) >= 0) {
                  if (strncmp(buf,"OK",2)) {
                     Info("SshAuth", "from remote host %s:", fRemote.Data());
                     Info("SshAuth", ">> nothing listening on port %s %s",buf,
                          "(supposed to be associated to sshd)");
                     Info("SshAuth", ">> contact the daemon administrator at %s",
                          fRemote.Data());
                  } else {
                     if (gDebug > 0) {
                        Info("SshAuth", "from remote host %s:", fRemote.Data());
                        Info("SshAuth", ">> something listening on the port"
                             " supposed to be associated to sshd.");
                        Info("SshAuth", ">> You have probably mistyped your"
                             " password. Or you tried to hack the"
                             " system.");
                        Info("SshAuth", ">> If the problem persists you may"
                             " consider contacting the daemon");
                        Info("SshAuth", ">> administrator at %s.",fRemote.Data());
                     }
                  }
               }
               if (buf)
                  delete [] buf;
            }
         }
         SafeDelete(newsock);
         
         if (fSocket->Recv(retval, kind) >= 0) {  
            if (kind == kROOTD_ERR)
               AuthError("SshAuth", retval);
         }
      }
      return 0;
   } else if (ssh_rc && sshproto > 0) {
      
      if (fSocket->Send("0", kROOTD_SSH) < 0)
         Info("SshAuth", "error communicating failure");
      return 0;
   }
   
   if (sshproto > 0) {
      if (fSocket->Send("1", kROOTD_SSH) < 0)
         Info("SshAuth", "error communicating success");
   }
   Int_t nrec = 0;
   
   if ((nrec = fSocket->Recv(retval, kind)) < 0)  
      return 0;
   if (gDebug > 3)
      Info("SshAuth", "got message %d, flag: %d", kind, retval);
   
   if (kind == kROOTD_ERR) {
      AuthError("SshAuth", retval);
      return 0;
   }
   if (reuse == 1 && sshproto == 0) {
      
      if (kind != kROOTD_RSAKEY  || retval < 1 || retval > 2)
         Warning("SshAuth",
                 "problems recvn RSA key flag: got message %d, flag: %d",
                 kind, retval);
      fRSAKey = retval - 1;
      
      if (SendRSAPublicKey(fSocket,fRSAKey) < 0)
         return 0;
      
      if ((nrec = fSocket->Recv(retval, kind)) < 0)  
         return 0;
      if (gDebug > 3)
         Info("SshAuth", "got message %d, flag: %d", kind, retval);
   }
   if (kind != kROOTD_SSH || retval < 1) {
      Warning("SshAuth",
              "problems recvn (user,offset) length (%d:%d bytes:%d)", kind,
              retval, nrec);
      return 0;
   }
   char answer[256];
   reclen = (retval+1 > 256) ? 256 : retval+1;
   if ((nrec = fSocket->Recv(answer, reclen, kind)) < 0)  
      return 0;
   if (kind != kMESS_STRING)
      Warning("SshAuth", "username and offset not received (%d:%d)", kind,
              nrec);
   
   char lUser[128];
   int offset = -1;
   sscanf(answer, "%s %d", lUser, &offset);
   if (gDebug > 3)
      Info("SshAuth", "received from server: user: %s, offset: %d", lUser,
           offset);
   
   char *token = 0;
   if (reuse == 1 && offset > -1) {
      if (SecureRecv(fSocket, 1, fRSAKey, &token) == -1) {
         Warning("SshAuth", "problems secure-receiving token -"
                 " may result in corrupted token");
         return 0;
      }
      if (gDebug > 3)
         Info("SshAuth", "received from server: token: '%s' ", token);
   } else {
      token = StrDup("");
   }
   
   fSecContext = fHostAuth->CreateSecContext((const char *)lUser, fRemote,
                                             (Int_t)kSSH, offset, fDetails,
                                             (const char *)token, fgExpDate, 0, fRSAKey);
   
   if (token) delete [] token;
   
   if (fSocket->Recv(retval, kind) < 0)
      return 0;
   if (gDebug > 3)
      Info("SshAuth", "received from server: kind: %d, retval: %d", kind,
           retval);
   if (kind != kROOTD_AUTH) {
      return 0;
   } else {
      return retval;
   }
}
const char *TAuthenticate::GetSshUser(TString user) const
{
   
   
   
   R__LOCKGUARD2(gAuthenticateMutex);
   static TString usr = "";
   if (user == "") {
      if (fgPromptUser) {
         usr = PromptUser(fRemote);
      } else {
         usr = fgDefaultUser;
         if (usr == "")
            usr = PromptUser(fRemote);
      }
   } else {
      usr = user;
   }
   return usr;
}
Bool_t TAuthenticate::CheckHost(const char *host, const char *href)
{
   
   
   
   
   R__LOCKGUARD2(gAuthenticateMutex);
   Bool_t retval = kTRUE;
   
   if (!host || !href)
      return kFALSE;
   
   if (!strcmp(href,"*"))
      return kTRUE;
   
   
   
   Bool_t name = kFALSE;
   TRegexp rename("[+a-zA-Z]");
   Int_t len;
   if (rename.Index(href,&len) != -1 || strstr(href,"-"))
      name = kTRUE;
   
   Bool_t wild = kFALSE;
   if (strstr(href,"*"))
      wild = kTRUE;
   
   TRegexp rehost(href,wild);
   
   TString theHost(host);
   if (!name) {
      TInetAddress addr = gSystem->GetHostByName(host);
      theHost = addr.GetHostAddress();
      if (gDebug > 2)
         ::Info("TAuthenticate::CheckHost", "checking host IP: %s", theHost.Data());
   }
   
   Ssiz_t pos = rehost.Index(theHost,&len);
   if (pos == -1)
      retval = kFALSE;
   
   
   if (!wild) {
      if (pos > 0 && pos != (Ssiz_t)(theHost.Length()-strlen(href)))
         retval = kFALSE;
   }
   return retval;
}
Int_t TAuthenticate::RfioAuth(TString &username)
{
   
   
   
   
   if (gDebug > 2)
      Info("RfioAuth", "enter ... username %s", username.Data());
   
   UserGroup_t *pw = gSystem->GetUserInfo(gSystem->GetEffectiveUid());
   if (pw) {
      
      username = pw->fUser;
      fDetails = TString("pt:0 ru:0 us:") + username;
      
      if (pw->fUid != 0) {
         UserGroup_t *grp = gSystem->GetGroupInfo(gSystem->GetEffectiveGid());
         
         Int_t uid = pw->fUid;
         Int_t gid = grp ? grp->fGid : pw->fGid;
         delete grp;
         
         TString sstr = TString(Form("%d %d", uid, gid));
         if (gDebug > 3)
            Info("RfioAuth", "sending ... %s", sstr.Data());
         Int_t ns = 0;
         if ((ns = fSocket->Send(sstr.Data(), kROOTD_RFIO)) < 0)
            return 0;
         if (gDebug > 3)
            Info("RfioAuth", "sent ... %d bytes (expected > %d)", ns,
                 sstr.Length());
         
         Int_t stat, kind;
         if (fSocket->Recv(stat, kind) < 0)
            return 0;
         if (gDebug > 3)
            Info("RfioAuth", "after kROOTD_RFIO: kind= %d, stat= %d", kind,
                 stat);
         
         if (kind == kROOTD_AUTH && stat >= 1) {
            
            fSecContext =
               fHostAuth->CreateSecContext((const char *)pw->fUser,
                                           fRemote, kRfio, -stat, fDetails, 0);
            delete pw;
            return 1;
         } else {
            TString server = "sockd";
            if (fProtocol.Contains("root"))
               server = "rootd";
            if (fProtocol.Contains("proof"))
               server = "proofd";
            
            if (stat == kErrConnectionRefused) {
               if (gDebug > 0)
                  Error("RfioAuth",
                        "%s@%s does not accept connections from %s%s",
                        server.Data(),fRemote.Data(),
                        fUser.Data(),gSystem->HostName());
               delete pw;
               return -2;
            } else if (stat == kErrNotAllowed) {
               if (gDebug > 0)
                  Error("RfioAuth",
                        "%s@%s does not accept %s authentication from %s@%s",
                        server.Data(),fRemote.Data(),
                        TAuthenticate::fgAuthMeth[5].Data(),
                        fUser.Data(),gSystem->HostName());
            } else {
               AuthError("RfioAuth", stat);
            }
            delete pw;
            return 0;
         }
      } else {
         Warning("RfioAuth", "UidGid login as \"root\" not allowed");
         return -1;
      }
   }
   delete pw;
   return -1;
}
Int_t TAuthenticate::ClearAuth(TString &user, TString &passwd, Bool_t &pwdhash)
{
   
   
   
   R__LOCKGUARD2(gAuthenticateMutex);
   if (gDebug > 2)
      Info("ClearAuth", "enter: user: %s (passwd hashed?: %d)",
           user.Data(),(Int_t)pwdhash);
   Int_t reuse    = fgAuthReUse;
   Int_t prompt   = fgPromptUser;
   Int_t cryptopt = fgUsrPwdCrypt;
   Int_t needsalt = 1;
   if (pwdhash)
      needsalt = 0;
   fDetails = TString(Form("pt:%d ru:%d cp:%d us:",
                           fgPromptUser, fgAuthReUse, fgUsrPwdCrypt)) + user;
   if (gDebug > 2)
      Info("ClearAuth", "ru:%d pt:%d cp:%d ns:%d rk:%d",
           fgAuthReUse,fgPromptUser,fgUsrPwdCrypt,needsalt,fgRSAKey);
#ifdef R__WIN32
   needsalt = 0;
#endif
   Int_t stat, kind;
   if (fVersion > 1) {
      
      
      
      Int_t anon = 0;
      TString salt = "";
      TString pashash = "";
      
      UserGroup_t *pw = gSystem->GetUserInfo(gSystem->GetEffectiveUid());
      TString effUser;
      if (pw) {
         effUser = TString(pw->fUser);
         delete pw;
      } else
         effUser = user;
      
      int opt = (reuse * kAUTH_REUSE_MSK) + (cryptopt * kAUTH_CRYPT_MSK) +
         (needsalt * kAUTH_SSALT_MSK) + (fRSAKey * kAUTH_RSATY_MSK);
      TString options(Form("%d %ld %s %ld %s", opt,
                           (Long_t)user.Length(), user.Data(),
                           (Long_t)effUser.Length(), effUser.Data()));
      
      kind = kROOTD_USER;
      stat = reuse;
      Int_t rc = 0;
      if ((rc = AuthExists(user, (Int_t) TAuthenticate::kClear, options,
                           &kind, &stat, &StdCheckSecCtx)) == 1) {
         
         return 1;
      }
      if (rc == -2) {
         return rc;
      }
      if (stat == kErrNotAllowed && kind == kROOTD_ERR) {
         return 0;
      }
      if (kind == kROOTD_AUTH && stat == -1) {
         if (gDebug > 3)
            Info("ClearAuth", "anonymous user");
         anon  = 1;
         cryptopt = 0;
         reuse = 0;
         needsalt = 0;
      }
      
      
      char ctag[11] = {0};
      if (anon == 0 && cryptopt == 1) {
         
         if (kind != kROOTD_RSAKEY || stat < 1 || stat > 2 ) {
            
            if (kind != kROOTD_ERR) {
               Warning("ClearAuth",
                       "problems recvn RSA key flag: got message %d, flag: %d",
                       kind, stat);
            }
            return 0;
         }
         if (gDebug > 3)
            Info("ClearAuth", "get key request ...");
         
         fRSAKey = stat - 1;
         
         if (SendRSAPublicKey(fSocket,fRSAKey) < 0)
            return 0;
         int slen = 0;
         if (needsalt) {
            
            char *tmpsalt = 0;
            if ((slen = SecureRecv(fSocket, 1, fRSAKey, &tmpsalt)) == -1) {
               Warning("ClearAuth", "problems secure-receiving salt -"
                       " may result in corrupted salt");
               Warning("ClearAuth", "switch off reuse for this session");
               needsalt = 0;
               return 0;
            }
            if (slen) {
               
               if (slen > 9) {
                  int ltmp = slen;
                  while (ltmp && tmpsalt[ltmp-1] != '#') ltmp--;
                  if (ltmp) {
                     if (tmpsalt[ltmp-1] == '#' &&
                         tmpsalt[ltmp-10] == '#') {
                        strncpy(ctag,&tmpsalt[ltmp-10],10);
                        
                        ltmp -= 10;
                        tmpsalt[ltmp] = 0;
                        
                        slen -= 10;
                     }
                  }
                  if (!strlen(tmpsalt)) {
                     
                     needsalt = 0;
                     slen = 0;
                  }
               }
               if (slen)
                  salt = TString(tmpsalt);
               delete [] tmpsalt;
            }
            if (gDebug > 2)
               Info("ClearAuth", "got salt: '%s' (len: %d)", salt.Data(), slen);
         } else {
            if (gDebug > 2)
               Info("ClearAuth", "Salt not required");
            char *tmptag = 0;
            if (SecureRecv(fSocket, 1, fRSAKey, &tmptag) == -1) {
               Warning("ClearAuth", "problems secure-receiving rndmtag -"
                       " may result in corrupted rndmtag");
            }
            if (tmptag) {
               strncpy(ctag, tmptag, 10);
               delete [] tmptag;
            }
         }
         
         
         if (!slen)
            needsalt = 0;
      }
      
      if (anon == 1) {
         if (fgPasswd.Contains("@")) {
            
            passwd = fgPasswd;
         } else {
            
            TString localuser;
            UserGroup_t *pw = gSystem->GetUserInfo();
            if (pw)
               localuser = StrDup(pw->fUser);
            delete pw;
            static TString localFQDN;
            if (localFQDN == "") {
               TInetAddress addr = gSystem->GetHostByName(gSystem->HostName());
               if (addr.IsValid()) {
                  localFQDN = addr.GetHostName();
                  if (localFQDN == "UnNamedHost")
                     localFQDN = addr.GetHostAddress();
               }
            }
            passwd = Form("%s@%s", localuser.Data(), localFQDN.Data());
            if (gDebug > 2)
               Info("ClearAuth",
                    "automatically generated anonymous passwd: %s",
                    passwd.Data());
         }
      } else {
         if (prompt == 1 || pashash.Length() == 0) {
            if (passwd == "") {
               char *pwd = PromptPasswd(Form("%s@%s password: ",
                                             user.Data(),fRemote.Data()));
               passwd = TString(pwd);
               delete [] pwd;
               if (passwd == "") {
                  Error("ClearAuth", "password not set");
                  fSocket->Send("-1", kROOTD_PASS);  
                  return 0;
               }
            }
            if (needsalt && !pwdhash) {
#ifndef R__WIN32
               pashash = TString(crypt(passwd, salt));
               if (!pashash.BeginsWith(salt)) {
                  
                  
                  pashash = passwd;
               }
#else
               pashash = passwd;
#endif
            } else {
               pashash = passwd;
            }
         }
      }
      
      fgUser = fUser;
      fgPwHash = kFALSE;
      fPwHash = kFALSE;
      fgPasswd = passwd;
      fPasswd = passwd;
      fSRPPwd = kFALSE;
      fgSRPPwd = kFALSE;
      
      if (anon == 0 && cryptopt == 1) {
         
         if (fSocket->Send("\0", kROOTD_PASS) < 0)
            return 0;
         
         
         if (strlen(ctag))
            pashash += ctag;
         if (SecureSend(fSocket, 1, fRSAKey, pashash.Data()) == -1) {
            Warning("ClearAuth", "problems secure-sending pass hash"
                    " - may result in authentication failure");
            return 0;
         }
      } else {
         
         if (passwd != "") {
            for (int i = 0; i < passwd.Length(); i++) {
               char inv = ~passwd(i);
               passwd.Replace(i, 1, inv);
            }
         }
         if (fSocket->Send(passwd.Data(), kROOTD_PASS) < 0)
            return 0;
      }
      Int_t nrec = 0;
      
      if ((nrec = fSocket->Recv(stat, kind)) < 0 )  
         return 0;
      if (gDebug > 3)
         Info("ClearAuth", "after kROOTD_PASS: kind= %d, stat= %d", kind,
              stat);
      
      if (kind == kROOTD_ERR) {
         AuthError("ClearAuth", stat);
         fgPasswd = "";
         return 0;
      }
      if (kind != kROOTD_PASS || stat < 1)
         Warning("ClearAuth",
                 "problems recvn (user,offset) length (%d:%d bytes:%d)",
                 kind, stat, nrec);
      
      char answer[256];
      int reclen = (stat+1 > 256) ? 256 : stat+1;
      if ((nrec = fSocket->Recv(answer, reclen, kind)) < 0)
         return 0;
      if (kind != kMESS_STRING)
         Warning("ClearAuth",
                 "username and offset not received (%d:%d)", kind,
                 nrec);
      
      Int_t offset = -1;
      char lUser[128];
      sscanf(answer, "%s %d", lUser, &offset);
      if (gDebug > 3)
         Info("ClearAuth",
              "received from server: user: %s, offset: %d (%s)", lUser,
              offset, answer);
      
      user = lUser;
      char *token = 0;
      if (reuse == 1 && offset > -1) {
         
         if (cryptopt == 1) {
            if (SecureRecv(fSocket, 1, fRSAKey, &token) == -1) {
               Warning("ClearAuth",
                       "problems secure-receiving token -"
                       " may result in corrupted token");
               return 0;
            }
         } else {
            Int_t tlen = 9;
            token = new char[tlen];
            if (fSocket->Recv(token, tlen, kind) < 0) {
               delete [] token;
               return 0;
            }
            if (kind != kMESS_STRING)
               Warning("ClearAuth", "token not received (%d:%d)", kind,
                       nrec);
            
            for (int i = 0; i < (int) strlen(token); i++) {
               token[i] = ~token[i];
            }
         }
         if (gDebug > 3)
            Info("ClearAuth", "received from server: token: '%s' ",
                 token);
      }
      TPwdCtx *pwdctx = new TPwdCtx(fPasswd,fPwHash);
      
      fSecContext = fHostAuth->CreateSecContext((const char *)lUser, fRemote,
                                                kClear, offset, fDetails, (const char *)token,
                                                fgExpDate, (void *)pwdctx, fRSAKey);
      
      if (token)
         delete [] token;
      
      if (fSocket->Recv(stat, kind) < 0)
         return 0;
      if (kind == kROOTD_AUTH && stat >= 1) {
         if (stat == 5 && fSocket->GetServType() == TSocket::kPROOFD)
            
            
            
            
            fSecContext->SetID("AFS authentication");
         return 1;
      } else {
         fgPasswd = "";
         if (kind == kROOTD_ERR)
            AuthError("ClearAuth", stat);
         return 0;
      }
   } else {
      
      
      if (fSocket->Send(user.Data(), kROOTD_USER) < 0)
         return 0;
      
      if (fSocket->Recv(stat, kind) < 0)
         return 0;
      
      
      if (kind == kROOTD_AUTH && stat == 1) {
         fSecContext =
            fHostAuth->CreateSecContext(user,fRemote,kClear,-1,fDetails,0);
         return 1;
      }
      if (kind == kROOTD_ERR) {
         TString server = "sockd";
         if (fProtocol.Contains("root"))
            server = "rootd";
         if (fProtocol.Contains("proof"))
            server = "proofd";
         if (stat == kErrConnectionRefused) {
            if (gDebug > 0)
               Error("ClearAuth",
                     "%s@%s does not accept connections from %s@%s",
                     server.Data(),fRemote.Data(),
                     fUser.Data(),gSystem->HostName());
            return -2;
         } else if (stat == kErrNotAllowed) {
            if (gDebug > 0)
               Error("ClearAuth",
                     "%s@%s does not accept %s authentication from %s@%s",
                     server.Data(),fRemote.Data(),
                     TAuthenticate::fgAuthMeth[0].Data(),
                     fUser.Data(),gSystem->HostName());
         } else
            AuthError("ClearAuth", stat);
         return 0;
      }
      
   badpass1:
      if (passwd == "") {
         passwd = PromptPasswd(
            Form("%s@%s password: ",user.Data(),fRemote.Data()));
         if (passwd == "")
            Error("ClearAuth", "password not set");
      }
      if (fUser == "anonymous" || fUser == "rootd") {
         if (!passwd.Contains("@")) {
            Warning("ClearAuth",
                    "please use passwd of form: user@host.do.main");
            passwd = "";
            goto badpass1;
         }
      }
      fgPasswd = passwd;
      fPasswd = passwd;
      
      if (passwd != "") {
         for (int i = 0; i < passwd.Length(); i++) {
            char inv = ~passwd(i);
            passwd.Replace(i, 1, inv);
         }
      }
      
      if (fSocket->Send(passwd, kROOTD_PASS) < 0)
         return 0;
      
      if (fSocket->Recv(stat, kind) < 0)  
         return 0;
      if (gDebug > 3)
         Info("ClearAuth", "after kROOTD_PASS: kind= %d, stat= %d", kind,
              stat);
      if (kind == kROOTD_AUTH && stat == 1) {
         fSecContext =
            fHostAuth->CreateSecContext(user,fRemote,kClear,-1,fDetails,0);
         return 1;
      } else {
         if (kind == kROOTD_ERR)
            AuthError("ClearAuth", stat);
         return 0;
      }
   }
   return 0;
}
THostAuth *TAuthenticate::GetHostAuth(const char *host, const char *user,
                                      Option_t *opt, Int_t *exact)
{
   
   
   
   
   if (exact)
      *exact = 0;
   if (gDebug > 2)
      ::Info("TAuthenticate::GetHostAuth", "enter ... %s ... %s", host, user);
   
   Int_t srvtyp = -1;
   TString hostname = host;
   if (hostname.Contains(":")) {
      char *ps = (char *)strstr(host,":");
      if (ps)
         srvtyp = atoi(ps+1);
      hostname.Remove(hostname.Index(":"));
   }
   TString hostFQDN = hostname;
   if (strncmp(host,"default",7) && !hostFQDN.Contains("*")) {
      TInetAddress addr = gSystem->GetHostByName(hostFQDN);
      if (addr.IsValid()) {
         hostFQDN = addr.GetHostName();
         if (hostFQDN == "UnNamedHost")
            hostFQDN = addr.GetHostAddress();
      }
   }
   TString usr = user;
   if (!usr.Length())
      usr = "*";
   THostAuth *rHA = 0;
   
   TIter *next = new TIter(GetAuthInfo());
   if (!strncasecmp(opt,"P",1)) {
      SafeDelete(next);
      next = new TIter(GetProofAuthInfo());
   }
   THostAuth *ai;
   Bool_t notFound = kTRUE;
   Bool_t serverOK = kTRUE;
   while ((ai = (THostAuth *) (*next)())) {
      if (gDebug > 3)
         ai->Print("Authenticate::GetHostAuth");
      
      if (!(serverOK = (ai->GetServer() == -1) ||
            (ai->GetServer() == srvtyp)))
         continue;
      
      if (!strcmp(ai->GetHost(),"default") && serverOK && notFound)
         rHA = ai;
      
      if (CheckHost(hostFQDN,ai->GetHost()) &&
          CheckHost(usr,ai->GetUser())     && serverOK) {
         rHA = ai;
         notFound = kFALSE;
      }
      if (hostFQDN == ai->GetHost() &&
          usr == ai->GetUser()     && srvtyp == ai->GetServer() ) {
         rHA = ai;
         if (exact)
            *exact = 1;
         break;
      }
   }
   SafeDelete(next);
   return rHA;
}
THostAuth *TAuthenticate::HasHostAuth(const char *host, const char *user,
                                      Option_t *opt)
{
   
   
   
   
   if (gDebug > 2)
      ::Info("TAuthenticate::HasHostAuth", "enter ... %s ... %s", host, user);
   
   Int_t srvtyp = -1;
   TString hostFQDN = host;
   if (hostFQDN.Contains(":")) {
      char *ps = (char *)strstr(host,":");
      if (ps)
         srvtyp = atoi(ps+1);
      hostFQDN.Remove(hostFQDN.Index(":"));
   }
   if (strncmp(host,"default",7) && !hostFQDN.Contains("*")) {
      TInetAddress addr = gSystem->GetHostByName(hostFQDN);
      if (addr.IsValid()) {
         hostFQDN = addr.GetHostName();
         if (hostFQDN == "UnNamedHost")
            hostFQDN = addr.GetHostAddress();
      }
   }
   TIter *next = new TIter(GetAuthInfo());
   if (!strncasecmp(opt,"P",1)) {
      SafeDelete(next);
      next = new TIter(GetProofAuthInfo());
   }
   THostAuth *ai;
   while ((ai = (THostAuth *) (*next)())) {
      if (hostFQDN == ai->GetHost() &&
          !strcmp(user, ai->GetUser()) && srvtyp == ai->GetServer()) {
         return ai;
      }
   }
   SafeDelete(next);
   return 0;
}
void TAuthenticate::FileExpand(const char *fexp, FILE *ftmp)
{
   
   
   
   FILE *fin;
   char line[kMAXPATHLEN];
   char cinc[20], fileinc[kMAXPATHLEN];
   if (gDebug > 2)
      ::Info("TAuthenticate::FileExpand", "enter ... '%s' ... 0x%lx", fexp, (Long_t)ftmp);
   fin = fopen(fexp, "r");
   if (fin == 0)
      return;
   while (fgets(line, sizeof(line), fin) != 0) {
      
      if (line[0] == '#')
         continue;
      if (line[strlen(line) - 1] == '\n')
         line[strlen(line) - 1] = '\0';
      if (gDebug > 2)
         ::Info("TAuthenticate::FileExpand", "read line ... '%s'", line);
      int nw = sscanf(line, "%s %s", cinc, fileinc);
      if (nw < 1)
         continue;              
      if (strcmp(cinc, "include") != 0) {
         
         fprintf(ftmp, "%s\n", line);
      } else {
         
         TString ln(line);
         ln.ReplaceAll("\"",1,"",0);
         ln.ReplaceAll("'",1,"",0);
         sscanf(ln.Data(), "%s %s", cinc, fileinc);
         
         if (fileinc[0] == '$') {
            TString finc(fileinc);
            TString edir(fileinc);
            if (edir.Contains("/")) {
               edir.Remove(edir.Index("/"));
               edir.Remove(0,1);
               if (gSystem->Getenv(edir.Data())) {
                  finc.Remove(0,1);
                  finc.ReplaceAll(edir.Data(),gSystem->Getenv(edir.Data()));
                  fileinc[0] = '\0';
                  strcpy(fileinc,finc.Data());
               }
            }
         }
         
         if (fileinc[0] == '~') {
            
            int flen =
               strlen(fileinc) + strlen(gSystem->HomeDirectory()) + 10;
            char *ffull = new char[flen];
            sprintf(ffull, "%s/%s", gSystem->HomeDirectory(), fileinc + 1);
            strcpy(fileinc, ffull);
         }
         
         if (!gSystem->AccessPathName(fileinc, kReadPermission)) {
            FileExpand(fileinc, ftmp);
         } else {
            ::Warning("TAuthenticate::FileExpand",
                      "file specified by 'include' cannot be open or read (%s)",
                      fileinc);
         }
      }
   }
   fclose(fin);
}
char *TAuthenticate::GetDefaultDetails(int sec, int opt, const char *usr)
{
   
   
   char temp[kMAXPATHLEN] = { 0 };
   const char copt[2][5] = { "no", "yes" };
   if (gDebug > 2)
      ::Info("TAuthenticate::GetDefaultDetails",
             "enter ... %d ...pt:%d ... '%s'", sec, opt, usr);
   if (opt < 0 || opt > 1)
      opt = 1;
   
   if (sec == TAuthenticate::kClear) {
      if (strlen(usr) == 0 || !strncmp(usr,"*",1))
         usr = gEnv->GetValue("UsrPwd.Login", "");
      sprintf(temp, "pt:%s ru:%s cp:%s us:%s",
              gEnv->GetValue("UsrPwd.LoginPrompt", copt[opt]),
              gEnv->GetValue("UsrPwd.ReUse", "1"),
              gEnv->GetValue("UsrPwd.Crypt", "1"), usr);
      
   } else if (sec == TAuthenticate::kSRP) {
      if (strlen(usr) == 0 || !strncmp(usr,"*",1))
         usr = gEnv->GetValue("SRP.Login", "");
      sprintf(temp, "pt:%s ru:%s us:%s",
              gEnv->GetValue("SRP.LoginPrompt", copt[opt]),
              gEnv->GetValue("SRP.ReUse", "0"), usr);
      
   } else if (sec == TAuthenticate::kKrb5) {
      if (strlen(usr) == 0 || !strncmp(usr,"*",1))
         usr = gEnv->GetValue("Krb5.Login", "");
      sprintf(temp, "pt:%s ru:%s us:%s",
              gEnv->GetValue("Krb5.LoginPrompt", copt[opt]),
              gEnv->GetValue("Krb5.ReUse", "0"), usr);
      
   } else if (sec == TAuthenticate::kGlobus) {
      sprintf(temp, "pt:%s ru:%s %s",
              gEnv->GetValue("Globus.LoginPrompt", copt[opt]),
              gEnv->GetValue("Globus.ReUse", "1"),
              gEnv->GetValue("Globus.Login", ""));
      
   } else if (sec == TAuthenticate::kSSH) {
      if (strlen(usr) == 0 || !strncmp(usr,"*",1))
         usr = gEnv->GetValue("SSH.Login", "");
      sprintf(temp, "pt:%s ru:%s us:%s",
              gEnv->GetValue("SSH.LoginPrompt", copt[opt]),
              gEnv->GetValue("SSH.ReUse", "1"), usr);
      
   } else if (sec == TAuthenticate::kRfio) {
      if (strlen(usr) == 0 || !strncmp(usr,"*",1))
         usr = gEnv->GetValue("UidGid.Login", "");
      sprintf(temp, "pt:%s us:%s",
              gEnv->GetValue("UidGid.LoginPrompt", copt[opt]), usr);
   }
   if (gDebug > 2)
      ::Info("TAuthenticate::GetDefaultDetails", "returning ... %s", temp);
   return StrDup(temp);
}
void TAuthenticate::RemoveHostAuth(THostAuth * ha, Option_t *opt)
{
   
   if (!strncasecmp(opt,"P",1))
      GetProofAuthInfo()->Remove(ha);
   else
      GetAuthInfo()->Remove(ha);
   
   delete ha;
}
void TAuthenticate::Show(Option_t *opt)
{
   
   
   
   
   TString sopt(opt);
   if (sopt.Contains("s",TString::kIgnoreCase)) {
      
      TIter next(gROOT->GetListOfSecContexts());
      TSecContext *sc = 0;
      while ((sc = (TSecContext *)next()))
         sc->Print();
   } else {
      ::Info("::Print",
             " +--------------------------- BEGIN --------------------------------+");
      ::Info("::Print",
             " +                                                                  +");
      if (sopt.Contains("p",TString::kIgnoreCase)) {
         ::Info("::Print",
                " + List fgProofAuthInfo has %4d members                            +",
                GetProofAuthInfo()->GetSize());
         ::Info("::Print",
                " +                                                                  +");
         ::Info("::Print",
                " +------------------------------------------------------------------+");
         TIter next(GetProofAuthInfo());
         THostAuth *ai;
         while ((ai = (THostAuth *) next())) {
            ai->Print();
         }
      } else {
         ::Info("::Print",
                " + List fgAuthInfo has %4d members                                 +",
                GetAuthInfo()->GetSize());
         ::Info("::Print",
                " +                                                                  +");
         ::Info("::Print",
                " +------------------------------------------------------------------+");
         TIter next(GetAuthInfo());
         THostAuth *ai;
         while ((ai = (THostAuth *) next())) {
            ai->Print();
            ai->PrintEstablished();
         }
      }
      ::Info("::Print",
             " +---------------------------- END ---------------------------------+");
   }
}
Int_t TAuthenticate::AuthExists(TString username, Int_t method, const char *options,
                                Int_t *message, Int_t *rflag,
                                CheckSecCtx_t checksecctx)
{
   
   
   
   
   
   if (gDebug > 2)
      Info("AuthExists","%d: enter: msg: %d options: '%s'",
           method,*message, options);
   
   Bool_t notHA = kFALSE;
   
   TIter next(fHostAuth->Established());
   TRootSecContext *secctx;
   while ((secctx = (TRootSecContext *)next())) {
      if (secctx->GetMethod() == method) {
         if (fRemote == secctx->GetHost()) {
            if (checksecctx &&
                (*checksecctx)(username,secctx) == 1)
               break;
         }
      }
   }
   
   if (!secctx) {
      next = TIter(gROOT->GetListOfSecContexts());
      while ((secctx = (TRootSecContext *)next())) {
         if (secctx->GetMethod() == method) {
            if (fRemote == secctx->GetHost()) {
               if (checksecctx &&
                   (*checksecctx)(username,secctx) == 1) {
                  notHA = kTRUE;
                  break;
               }
            }
         }
      }
   }
   
   Int_t offset = -1;
   TString token;
   if (secctx) {
      offset = secctx->GetOffSet();
      token = secctx->GetToken();
      if (gDebug > 2)
         Info("AuthExists",
              "found valid TSecContext: offset: %d token: '%s'",
              offset, token.Data());
   }
   
   TString sstr(Form("%d %d %s", fgProcessID, offset, options));
   
   if (fSocket->Send(sstr, *message) < 0)
      return -2;
   Int_t reuse = *rflag;
   if (reuse == 1 && offset > -1) {
      
      
      
      
      Int_t rproto = fSocket->GetRemoteProtocol();
      Bool_t oldsrv = ((fProtocol.BeginsWith("root") && rproto == 9) ||
                       (fProtocol.BeginsWith("proof") && rproto == 8));
      Int_t stat = 1, kind;
      if (!oldsrv) {
         if (fSocket->Recv(stat, kind) < 0)
            return -2;
         if (kind != kROOTD_AUTH)
            Warning("AuthExists","protocol error: expecting %d got %d"
                    " (value: %d)",kROOTD_AUTH,kind,stat);
      }
      if (stat > 0) {
         if (gDebug > 2)
            Info("AuthExists","offset OK");
         Int_t rsaKey = secctx->GetRSAKey();
         if (gDebug > 2)
            Info("AuthExists", "key type: %d", rsaKey);
         if (rsaKey > -1) {
            
            
            if (stat > 1) {
               
               char tag[9] = {0};
               sprintf(tag,"%08x",stat);
               
               token += tag;
            }
            
            if (SecureSend(fSocket, 1, rsaKey, token) == -1) {
               Warning("AuthExists", "problems secure-sending token %s",
                       "- may trigger problems in proofing Id ");
               return -2;
            }
         } else {
            
            for (int i = 0; i < token.Length(); i++) {
               char inv = ~token(i);
               token.Replace(i, 1, inv);
            }
            if (fSocket->Send(token, kMESS_STRING) < 0)
               return -2;
         }
      } else {
         if (gDebug > 0)
            Info("AuthExists","offset not OK - rerun authentication");
         
         if (secctx)
            secctx->DeActivate("");
      }
   }
   Int_t stat, kind;
   if (fSocket->Recv(stat, kind) < 0)
      return -2;
   if (gDebug > 3)
      Info("AuthExists","%d: after msg %d: kind= %d, stat= %d",
           method,*message, kind, stat);
   
   *message = kind;
   *rflag = stat;
   if (kind == kROOTD_ERR) {
      TString server = "sockd";
      if (fSocket->GetServType() == TSocket::kROOTD)
         server = "rootd";
      if (fSocket->GetServType() == TSocket::kPROOFD)
         server = "proofd";
      if (stat == kErrConnectionRefused) {
         Error("AuthExists","%s@%s does not accept connections from %s@%s",
               server.Data(),fRemote.Data(),fUser.Data(),gSystem->HostName());
         return -2;
      } else if (stat == kErrNotAllowed) {
         if (gDebug > 0)
            Info("AuthExists",
                 "%s@%s does not accept %s authentication from %s@%s",
                 server.Data(),fRemote.Data(), fgAuthMeth[method].Data(),
                 fUser.Data(),gSystem->HostName());
      } else
         AuthError("AuthExists", stat);
      
      if (secctx)
         secctx->DeActivate("");
      return 0;
   }
   if (kind == kROOTD_AUTH && stat >= 1) {
      if (!secctx)
         secctx =
            fHostAuth->CreateSecContext(fUser,fRemote,method,-stat,fDetails,0);
      if (gDebug > 3) {
         if (stat == 1)
            Info("AuthExists", "valid authentication exists");
         if (stat == 2)
            Info("AuthExists", "valid authentication exists: offset changed");
         if (stat == 3)
            Info("AuthExists", "remote access authorized by /etc/hosts.equiv");
         if (stat == 4)
            Info("AuthExists", "no authentication required remotely");
      }
      if (stat == 2) {
         int newOffSet;
         
         if (fSocket->Recv(newOffSet, kind) < 0)
            return -2;
         
         secctx->SetOffSet(newOffSet);
      }
      fSecContext = secctx;
      
      if (notHA)
         fHostAuth->Established()->Add(secctx);
      return 1;
   }
   return 0;
}
void TAuthenticate::InitRandom()
{
   
   
   static Bool_t notinit = kTRUE;
   if (notinit) {
      const char *randdev = "/dev/urandom";
      Int_t fd;
      UInt_t seed;
      if ((fd = open(randdev, O_RDONLY)) != -1) {
         if (gDebug > 2)
            ::Info("InitRandom", "taking seed from %s", randdev);
         read(fd, &seed, sizeof(seed));
         close(fd);
      } else {
         if (gDebug > 2)
            ::Info("InitRandom", "%s not available: using time()", randdev);
         seed = time(0);   
      }
      srand(seed);
      notinit = kFALSE;
   }
}
Int_t TAuthenticate::GenRSAKeys()
{
   
   
   if (gDebug > 2)
      Info("GenRSAKeys", "enter");
   if (fgRSAInit == 1) {
      if (gDebug > 2)
         Info("GenRSAKeys", "Keys prviously generated - return");
   }
   
   TString lib = "libRsa";
   
   if (!TRSA_fun::RSA_genprim()) {
      char *p;
      if ((p = gSystem->DynamicPathName(lib, kTRUE))) {
         delete [] p;
         gSystem->Load(lib);
      }
   }
   
   TAuthenticate::InitRandom();
#ifdef R__SSL
   if (fgRSAKey == 1) {
      
      if (gDebug > 2)
         Info("GenRSAKeys","SSL: Generate Blowfish key");
      
      SSL_library_init();
      
      SSL_load_error_strings();
      
      OpenSSL_add_all_ciphers();
      
      Int_t nbits = gEnv->GetValue("SSL.BFBits",256);
      
      nbits = (nbits >= 128) ? nbits : 128;
      
      nbits = (nbits <= 15912) ? nbits : 15912;
      
      Int_t klen = nbits / 8 ;
      
      char *rbuf = GetRandString(0,klen);
      RAND_seed(rbuf,strlen(rbuf));
      
      fgRSAPubExport[1].len = klen;
      fgRSAPubExport[1].keys = rbuf;
      if (gDebug > 2)
         Info("GenRSAKeys","SSL: BF key length: %d", fgRSAPubExport[1].len);
      
      BF_set_key(&fgBFKey, klen, (const unsigned char *)rbuf);
   }
#endif
   
   
   
   Bool_t notOk = 1;
   rsa_NUMBER p1, p2, rsa_n, rsa_e, rsa_d;
   Int_t l_n = 0, l_e = 0, l_d = 0;
   char buf_n[rsa_STRLEN], buf_e[rsa_STRLEN], buf_d[rsa_STRLEN];
#if R__RSADEB
   char buf[rsa_STRLEN];
#endif
   Int_t nAttempts = 0;
   Int_t thePrimeLen = kPRIMELENGTH;
   Int_t thePrimeExp = kPRIMEEXP;   
   while (notOk && nAttempts < kMAXRSATRIES) {
      nAttempts++;
      if (gDebug > 2 && nAttempts > 1) {
         Info("GenRSAKeys", "retry no. %d",nAttempts);
         srand(rand());
      }
      
      p1 = TRSA_fun::RSA_genprim()(thePrimeLen, thePrimeExp);
      p2 = TRSA_fun::RSA_genprim()(thePrimeLen+1, thePrimeExp);
      
      Int_t nPrimes = 0;
      while (TRSA_fun::RSA_cmp()(&p1, &p2) == 0 && nPrimes < kMAXRSATRIES) {
         nPrimes++;
         if (gDebug > 2)
            Info("GenRSAKeys", "equal primes: regenerate (%d times)",nPrimes);
         srand(rand());
         p1 = TRSA_fun::RSA_genprim()(thePrimeLen, thePrimeExp);
         p2 = TRSA_fun::RSA_genprim()(thePrimeLen+1, thePrimeExp);
      }
#if R__RSADEB
      if (gDebug > 3) {
         TRSA_fun::RSA_num_sput()(&p1, buf, rsa_STRLEN);
         Info("GenRSAKeys", "local: p1: '%s' ", buf);
         TRSA_fun::RSA_num_sput()(&p2, buf, rsa_STRLEN);
         Info("GenRSAKeys", "local: p2: '%s' ", buf);
      }
#endif
      
      if (TRSA_fun::RSA_genrsa()(p1, p2, &rsa_n, &rsa_e, &rsa_d)) {
         if (gDebug > 2 && nAttempts > 1)
            Info("GenRSAKeys"," genrsa: unable to generate keys (%d)",
                 nAttempts);
         continue;
      }
      
      TRSA_fun::RSA_num_sput()(&rsa_n, buf_n, rsa_STRLEN);
      l_n = strlen(buf_n);
      TRSA_fun::RSA_num_sput()(&rsa_e, buf_e, rsa_STRLEN);
      l_e = strlen(buf_e);
      TRSA_fun::RSA_num_sput()(&rsa_d, buf_d, rsa_STRLEN);
      l_d = strlen(buf_d);
#if R__RSADEB
      if (gDebug > 3) {
         Info("GenRSAKeys", "local: n: '%s' length: %d", buf_n, l_n);
         Info("GenRSAKeys", "local: e: '%s' length: %d", buf_e, l_e);
         Info("GenRSAKeys", "local: d: '%s' length: %d", buf_d, l_d);
      }
#endif
      if (TRSA_fun::RSA_cmp()(&rsa_n, &rsa_e) <= 0)
         continue;
      if (TRSA_fun::RSA_cmp()(&rsa_n, &rsa_d) <= 0)
         continue;
      
      char test[2 * rsa_STRLEN] = "ThisIsTheStringTest01203456-+/";
      Int_t lTes = 31;
      char *tdum = GetRandString(0, lTes - 1);
      strncpy(test, tdum, lTes);
      delete [] tdum;
      char buf[2 * rsa_STRLEN];
      if (gDebug > 3)
         Info("GenRSAKeys", "local: test string: '%s' ", test);
      
      strncpy(buf, test, lTes);
      buf[lTes] = 0;
      
      int lout = TRSA_fun::RSA_encode()(buf, lTes, rsa_n, rsa_e);
      if (gDebug > 3)
         Info("GenRSAKeys",
              "local: length of crypted string: %d bytes", lout);
      
      TRSA_fun::RSA_decode()(buf, lout, rsa_n, rsa_d);
      buf[lTes] = 0;
      if (gDebug > 3)
         Info("GenRSAKeys", "local: after private/public : '%s' ", buf);
      if (strncmp(test, buf, lTes))
         continue;
      
      strncpy(buf, test, lTes);
      buf[lTes] = 0;
      
      lout = TRSA_fun::RSA_encode()(buf, lTes, rsa_n, rsa_d);
      if (gDebug > 3)
         Info("GenRSAKeys", "local: length of crypted string: %d bytes ",
              lout);
      
      TRSA_fun::RSA_decode()(buf, lout, rsa_n, rsa_e);
      buf[lTes] = 0;
      if (gDebug > 3)
         Info("GenRSAKeys", "local: after public/private : '%s' ", buf);
      if (strncmp(test, buf, lTes))
         continue;
      notOk = 0;
   }
   
   TRSA_fun::RSA_assign()(&fgRSAPriKey.n, &rsa_n);
   TRSA_fun::RSA_assign()(&fgRSAPriKey.e, &rsa_e);
   
   TRSA_fun::RSA_assign()(&fgRSAPubKey.n, &rsa_n);
   TRSA_fun::RSA_assign()(&fgRSAPubKey.e, &rsa_d);
#if R__RSADEB
   if (gDebug > 2) {
      
      Info("GenRSAKeys", "local: generated keys are:");
      Info("GenRSAKeys", "local: n: '%s' length: %d", buf_n, l_n);
      Info("GenRSAKeys", "local: e: '%s' length: %d", buf_e, l_e);
      Info("GenRSAKeys", "local: d: '%s' length: %d", buf_d, l_d);
   }
#endif
   
   if (fgRSAPubExport[0].keys) {
      delete [] fgRSAPubExport[0].keys;
      fgRSAPubExport[0].len = 0;
   }
   fgRSAPubExport[0].len = l_n + l_d + 4;
   fgRSAPubExport[0].keys = new char[fgRSAPubExport[0].len];
   fgRSAPubExport[0].keys[0] = '#';
   memcpy(fgRSAPubExport[0].keys + 1, buf_n, l_n);
   fgRSAPubExport[0].keys[l_n + 1] = '#';
   memcpy(fgRSAPubExport[0].keys + l_n + 2, buf_d, l_d);
   fgRSAPubExport[0].keys[l_n + l_d + 2] = '#';
   fgRSAPubExport[0].keys[l_n + l_d + 3] = 0;
#if R__RSADEB
   if (gDebug > 2)
      Info("GenRSAKeys", "local: export pub: '%s'", fgRSAPubExport[0].keys);
#else
   if (gDebug > 2)
      Info("GenRSAKeys", "local: export pub length: %d bytes", fgRSAPubExport[0].len);
#endif
   
   fgRSAInit = 1;
   return 0;
}
char *TAuthenticate::GetRandString(Int_t opt, Int_t len)
{
   
   
   
   
   
   
   int iimx[4][4] = {
      {0x0, 0xffffff08, 0xafffffff, 0x2ffffffe}, 
      {0x0, 0x3ff0000, 0x7fffffe, 0x7fffffe},    
      {0x0, 0x3ff0000, 0x7e, 0x7e},              
      {0x0, 0x3ffc000, 0x7fffffe, 0x7fffffe}     
   };
   const char *cOpt[4] = { "Any", "LetNum", "Hex", "Crypt" };
   
   if (opt < 0 || opt > 2) {
      opt = 0;
      if (gDebug > 2)
         Info("GetRandString", "unknown option: %d : assume 0", opt);
   }
   if (gDebug > 2)
      Info("GetRandString", "enter ... len: %d %s", len, cOpt[opt]);
   
   char *buf = new char[len + 1];
   
   TAuthenticate::InitRandom();
   
   Int_t k = 0;
   Int_t i, j, l, m, frnd;
   while (k < len) {
      frnd = rand();
      for (m = 7; m < 32; m += 7) {
         i = 0x7F & (frnd >> m);
         j = i / 32;
         l = i - j * 32;
         if ((iimx[opt][j] & (1 << l))) {
            buf[k] = i;
            k++;
         }
         if (k == len)
            break;
      }
   }
   
   buf[len] = 0;
   if (gDebug > 3)
      Info("GetRandString", "got '%s' ", buf);
   return buf;
}
Int_t TAuthenticate::SecureSend(TSocket *sock, Int_t enc,
                                Int_t key, const char *str)
{
   
   
   
   
   char buftmp[kMAXSECBUF];
   char buflen[20];
   if (gDebug > 2)
      ::Info("TAuthenticate::SecureSend", "local: enter ... (enc: %d)", enc);
   Int_t slen = strlen(str) + 1;
   Int_t ttmp = 0;
   Int_t nsen = -1;
   if (key == 0) {
      strncpy(buftmp, str, slen);
      buftmp[slen] = 0;
      if (enc == 1)
         ttmp = TRSA_fun::RSA_encode()(buftmp, slen, fgRSAPriKey.n,
                                       fgRSAPriKey.e);
      else if (enc == 2)
         ttmp = TRSA_fun::RSA_encode()(buftmp, slen, fgRSAPubKey.n,
                                       fgRSAPubKey.e);
      else
         return nsen;
   } else if (key == 1) {
#ifdef R__SSL
      ttmp = strlen(str);
      if ((ttmp % 8) > 0)           
         ttmp = ((ttmp + 8)/8) * 8;
      unsigned char iv[8];
      memset((void *)&iv[0],0,8);
      BF_cbc_encrypt((const unsigned char *)str, (unsigned char *)buftmp,
                     strlen(str), &fgBFKey, iv, BF_ENCRYPT);
#else
      if (gDebug > 0)
         ::Info("TAuthenticate::SecureSend","not compiled with SSL support:"
                " you should not have got here!");
#endif
   } else {
      if (gDebug > 0)
         ::Info("TAuthenticate::SecureSend","unknown key type (%d)",key);
      return nsen;
   }
   snprintf(buflen,20,"%d",ttmp);
   if (sock->Send(buflen, kROOTD_ENCRYPT) < 0)
      return -1;
   nsen = sock->SendRaw(buftmp, ttmp);
   if (gDebug > 3)
      ::Info("TAuthenticate::SecureSend",
             "local: sent %d bytes (expected: %d)", nsen,ttmp);
   return nsen;
}
Int_t TAuthenticate::SecureRecv(TSocket *sock, Int_t dec, Int_t key, char **str)
{
   
   
   
   char buftmp[kMAXSECBUF];
   char buflen[20];
   Int_t nrec = -1;
   
   if (!str)
      return nrec;
   Int_t kind;
   if (sock->Recv(buflen, 20, kind) < 0)
      return -1;
   Int_t len = atoi(buflen);
   if (gDebug > 3)
      ::Info("TAuthenticate::SecureRecv", "got len '%s' %d (msg kind: %d)",
             buflen, len, kind);
   if (len == 0) {
      return len;
   }
   if (!strncmp(buflen, "-1", 2))
      return nrec;
   
   if ((nrec = sock->RecvRaw(buftmp, len)) < 0)
      return nrec;
   if (key == 0) {
      if (dec == 1)
         TRSA_fun::RSA_decode()(buftmp, len, fgRSAPriKey.n, fgRSAPriKey.e);
      else if (dec == 2)
         TRSA_fun::RSA_decode()(buftmp, len, fgRSAPubKey.n, fgRSAPubKey.e);
      else
         return -1;
      
      *str = new char[strlen(buftmp) + 1];
      strcpy(*str, buftmp);
   } else if (key == 1) {
#ifdef R__SSL
      unsigned char iv[8];
      memset((void *)&iv[0],0,8);
      *str = new char[nrec + 1];
      BF_cbc_encrypt((const unsigned char *)buftmp, (unsigned char *)(*str),
                     nrec, &fgBFKey, iv, BF_DECRYPT);
      (*str)[nrec] = '\0';
#else
      if (gDebug > 0)
         ::Info("TAuthenticate::SecureRecv","not compiled with SSL support:"
                " you should not have got here!");
#endif
   } else {
      if (gDebug > 0)
         ::Info("TAuthenticate::SecureRecv","unknown key type (%d)",key);
      return -1;
   }
   nrec= strlen(*str);
   return nrec;
}
Int_t TAuthenticate::DecodeRSAPublic(const char *rsaPubExport, rsa_NUMBER &rsa_n,
                                     rsa_NUMBER &rsa_d, void **rsassl)
{
   
   if (!rsaPubExport)
      return -1;
   if (gDebug > 2)
      ::Info("TAuthenticate::DecodeRSAPublic",
             "enter: string length: %d bytes", strlen(rsaPubExport));
   char str[kMAXPATHLEN] = { 0 };
   Int_t klen = strlen(rsaPubExport);
   if (klen > kMAXPATHLEN - 1) {
      ::Info("TAuthenticate::DecodeRSAPublic",
             "key too long (%d): truncate to %d",klen,kMAXPATHLEN);
      klen = kMAXPATHLEN - 1;
   }
   memcpy(str, rsaPubExport, klen);
   str[klen] ='\0';
   Int_t keytype = -1;
   if (klen > 0) {
      
      int k = 0;
      while (str[k] == 32) k++;
      if (str[k] == '#') {
         keytype = 0;
         
         char *pd1 = strstr(str, "#");
         char *pd2 = strstr(pd1 + 1, "#");
         char *pd3 = strstr(pd2 + 1, "#");
         if (pd1 && pd2 && pd3) {
            
            int l1 = (int) (pd2 - pd1 - 1);
            char *rsa_n_exp = new char[l1 + 1];
            strncpy(rsa_n_exp, pd1 + 1, l1);
            rsa_n_exp[l1] = 0;
            if (gDebug > 2)
               ::Info("TAuthenticate::DecodeRSAPublic",
                      "got %d bytes for rsa_n_exp", strlen(rsa_n_exp));
            
            int l2 = (int) (pd3 - pd2 - 1);
            char *rsa_d_exp = new char[l2 + 1];
            strncpy(rsa_d_exp, pd2 + 1, l2);
            rsa_d_exp[l2] = 0;
            if (gDebug > 2)
               ::Info("TAuthenticate::DecodeRSAPublic",
                      "got %d bytes for rsa_d_exp", strlen(rsa_d_exp));
            TRSA_fun::RSA_num_sget()(&rsa_n, rsa_n_exp);
            TRSA_fun::RSA_num_sget()(&rsa_d, rsa_d_exp);
            if (rsa_n_exp)
               if (rsa_n_exp) delete[] rsa_n_exp;
            if (rsa_d_exp)
               if (rsa_d_exp) delete[] rsa_d_exp;
         } else
            ::Info("TAuthenticate::DecodeRSAPublic","bad format for input string");
#ifdef R__SSL
         } else {
            
            keytype = 1;
            RSA *rsatmp;
            
            BIO *bpub = BIO_new(BIO_s_mem());
            
            BIO_write(bpub,(void *)str,strlen(str));
            
            if (!(rsatmp = PEM_read_bio_RSAPublicKey(bpub, 0, 0, 0))) {
               if (gDebug > 0)
                  ::Info("TAuthenticate::DecodeRSAPublic",
                         "unable to read pub key from bio");
            } else
               if (rsassl)
                  *rsassl = (void *)rsatmp;
               else
                  ::Info("TAuthenticate::DecodeRSAPublic",
                         "no space allocated for output variable");
            BIO_free(bpub);
         }
#else
      } else {
         if (rsassl) { }   
         if (gDebug > 0)
            ::Info("TAuthenticate::DecodeRSAPublic","not compiled with SSL support:"
                   " you should not have got here!");
      }
#endif
   }
   return keytype;
}
Int_t TAuthenticate::SetRSAPublic(const char *rsaPubExport, Int_t klen)
{
   
   
   if (gDebug > 2)
      ::Info("TAuthenticate::SetRSAPublic",
             "enter: string length %d bytes", strlen(rsaPubExport));
   Int_t rsakey = -1;
   if (!rsaPubExport)
      return rsakey;
   if (klen > 0) {
      
      int k0 = 0;
      while (rsaPubExport[k0] == 32) k0++;
      int k2 = klen - 1;
      
      
      
      
      
      rsakey = 1;
      if (rsaPubExport[k0] == '#' && rsaPubExport[k2] == '#') {
         char *p0 = (char *)&rsaPubExport[k0];
         char *p2 = (char *)&rsaPubExport[k2];
         char *p1 = strchr(p0+1,'#');
         if (p1 > p0 && p1 < p2) {
            Int_t l01 = (Int_t)(p1-p0)-1;
            Int_t l12 = (Int_t)(p2-p1)-1;
            if (l01 >= kPRIMELENGTH*2 && l12 >= kPRIMELENGTH*2) {
               
               char *c = p0+1;
               while (c < p1 && ((*c < 58 && *c > 47) || (*c < 91 && *c > 64)))
                  c++;
               if (c == p1) {
                  c++;
                  while (c < p2 && ((*c < 58 && *c > 47) || (*c < 91 && *c > 64)))
                     c++;
                  if (c == p2)
                     rsakey = 0;
               }
            }
         }
      }
      if (gDebug > 3)
         ::Info("TAuthenticate::SetRSAPublic"," Key type: %d",rsakey);
      if (rsakey == 0) {
         
         rsa_NUMBER rsa_n, rsa_d;
         rsakey = TAuthenticate::DecodeRSAPublic(rsaPubExport,rsa_n,rsa_d);
         
         TRSA_fun::RSA_assign()(&fgRSAPubKey.n, &rsa_n);
         TRSA_fun::RSA_assign()(&fgRSAPubKey.e, &rsa_d);
      } else {
         rsakey = 1;
#ifdef R__SSL
         
         BF_set_key(&fgBFKey, klen, (const unsigned char *)rsaPubExport);
#else
         if (gDebug > 0)
            ::Info("TAuthenticate::SetRSAPublic",
                   "not compiled with SSL support:"
                   " you should not have got here!");
#endif
      }
   }
   return rsakey;
}
Int_t TAuthenticate::SendRSAPublicKey(TSocket *socket, Int_t key)
{
   
   
   
   char serverPubKey[kMAXSECBUF];
   int kind, nr = 0;
   if ((nr = socket->Recv(serverPubKey, kMAXSECBUF, kind)) < 0)
      return nr;
   if (gDebug > 3)
      ::Info("TAuthenticate::SendRSAPublicKey",
             "received key from server %d bytes", strlen(serverPubKey));
   
   rsa_NUMBER rsa_n, rsa_d;
#ifdef R__SSL
   RSA *RSASSLServer = 0;
   if (TAuthenticate::DecodeRSAPublic(serverPubKey,rsa_n,rsa_d,
                                      (void **)&RSASSLServer) != key) {
      if (RSASSLServer)
         RSA_free(RSASSLServer);
      return -1;
   }
#else
   if (TAuthenticate::DecodeRSAPublic(serverPubKey,rsa_n,rsa_d) != key)
      return -1;
#endif
   
   char buftmp[kMAXSECBUF] = {0};
   char buflen[20] = {0};
   Int_t slen = fgRSAPubExport[key].len;
   Int_t ttmp = 0;
   if (key == 0) {
      strncpy(buftmp,fgRSAPubExport[key].keys,slen);
      buftmp[slen] = 0;
      ttmp = TRSA_fun::RSA_encode()(buftmp, slen, rsa_n, rsa_d);
      sprintf(buflen, "%d", ttmp);
   } else if (key == 1) {
#ifdef R__SSL
      Int_t lcmax = RSA_size(RSASSLServer) - 11;
      Int_t kk = 0;
      Int_t ke = 0;
      Int_t ns = slen;
      while (ns > 0) {
         Int_t lc = (ns > lcmax) ? lcmax : ns ;
         if ((ttmp = RSA_public_encrypt(lc,
                                        (unsigned char *)&fgRSAPubExport[key].keys[kk],
                                        (unsigned char *)&buftmp[ke],
                                        RSASSLServer,RSA_PKCS1_PADDING)) < 0) {
            char cerr[120];
            ERR_error_string(ERR_get_error(), cerr);
            ::Info("TAuthenticate::SendRSAPublicKey","SSL: error: '%s' ",cerr);
         }
         kk += lc;
         ke += ttmp;
         ns -= lc;
      }
      ttmp = ke;
      sprintf(buflen, "%d", ttmp);
#else
      if (gDebug > 0)
         ::Info("TAuthenticate::SendRSAPublicKey","not compiled with SSL support:"
                " you should not have got here!");
      return -1;
#endif
   } else {
      if (gDebug > 0)
         ::Info("TAuthenticate::SendRSAPublicKey","unknown key type (%d)",key);
#ifdef R__SSL
      if (RSASSLServer)
         RSA_free(RSASSLServer);
#endif
      return -1;
   }
   
   if ((nr = socket->Send(buflen, kROOTD_ENCRYPT)) < 0)
      return nr;
   
   Int_t nsen = socket->SendRaw(buftmp, ttmp);
   if (gDebug > 3)
      ::Info("TAuthenticate::SendRSAPublicKey",
             "local: sent %d bytes (expected: %d)", nsen,ttmp);
#ifdef R__SSL
   if (RSASSLServer)
      RSA_free(RSASSLServer);
#endif
   return nsen;
}
Int_t TAuthenticate::ReadRootAuthrc()
{
   
   
   
   
   
   char *authrc = 0;
   if (gSystem->Getenv("ROOTAUTHRC") != 0) {
      authrc = StrDup(gSystem->Getenv("ROOTAUTHRC"));
   } else {
      if (fgReadHomeAuthrc)
         authrc = gSystem->ConcatFileName(gSystem->HomeDirectory(), ".rootauthrc");
   }
   if (authrc && gDebug > 2)
      ::Info("TAuthenticate::ReadRootAuthrc", "Checking file: %s", authrc);
   if (!authrc || gSystem->AccessPathName(authrc, kReadPermission)) {
      if (authrc && gDebug > 1)
         ::Info("TAuthenticate::ReadRootAuthrc",
                "file %s cannot be read (errno: %d)", authrc, errno);
      delete [] authrc;
#ifdef ROOTETCDIR
      authrc = gSystem->ConcatFileName(ROOTETCDIR,"system.rootauthrc");
#else
      char etc[1024];
#ifdef WIN32
      sprintf(etc, "%s\\etc", gRootDir);
#else
      sprintf(etc, "%s/etc", gRootDir);
#endif
      authrc = gSystem->ConcatFileName(etc,"system.rootauthrc");
#endif
      if (gDebug > 2)
         ::Info("TAuthenticate::ReadRootAuthrc", "Checking system file:%s",authrc);
      if (gSystem->AccessPathName(authrc, kReadPermission)) {
         if (gDebug > 1)
            ::Info("TAuthenticate::ReadRootAuthrc",
                   "file %s cannot be read (errno: %d)", authrc, errno);
         delete [] authrc;
         return 0;
      }
   }
   
   TString tRootAuthrc = authrc;
   if (tRootAuthrc == fgRootAuthrc) {
      struct stat si;
      stat(tRootAuthrc, &si);
      if ((UInt_t)si.st_mtime < fgLastAuthrc.Convert()) {
         if (gDebug > 1)
            ::Info("TAuthenticate::ReadRootAuthrc",
                   "file %s already read", authrc);
         delete [] authrc;
         return 0;
      }
   }
   
   fgRootAuthrc = tRootAuthrc;
   fgLastAuthrc = TDatime();
   
   TList *authinfo = TAuthenticate::GetAuthInfo();
   TList *proofauthinfo = TAuthenticate::GetProofAuthInfo();
   
   int expand = 1;
   TString filetmp = "rootauthrc";
   FILE *ftmp = gSystem->TempFileName(filetmp);
   if (gDebug > 2)
      ::Info("TAuthenticate::ReadRootAuthrc", "got tmp file: %s open at 0x%lx",
             filetmp.Data(), (Long_t)ftmp);
   if (ftmp == 0)
      expand = 0;  
   FILE *fd = 0;
   
   if (expand == 1) {
      TAuthenticate::FileExpand(authrc, ftmp);
      fd = ftmp;
      rewind(fd);
   } else {
      
      fd = fopen(authrc, "r");
      if (fd == 0) {
         if (gDebug > 2)
            ::Info("TAuthenticate::ReadRootAuthrc",
                   "file %s cannot be open (errno: %d)", authrc, errno);
         delete [] authrc;
         return 0;
      }
   }
   
   TList tmpAuthInfo;
   char line[kMAXPATHLEN];
   Bool_t cont = kFALSE;
   TString proofserv;
   while (fgets(line, sizeof(line), fd) != 0) {
      
      if (line[0] == '#')
         continue;
      
      if (line[strlen(line) - 1] == '\n')
         line[strlen(line) - 1] = '\0';
      
      if (strlen(line) == 0)
         continue;
      
      char *tmp = new char[strlen(line)+1];
      if (!tmp) {
         ::Error("TAuthenticate::ReadRootAuthrc",
                 "could not allocate temporary buffer");
         return 0;
      }
      strcpy(tmp,line);
      char *nxt = strtok(tmp," ");
      if (!strcmp(nxt, "proofserv") || cont) {
         
         char *ph = 0;
         if (cont)
            ph = nxt;
         else
            ph = strtok(0," ");
         while (ph) {
            if (*ph != 92) {
               proofserv += TString((const char *)ph);
               proofserv += TString(" ");
               cont = kFALSE;
            } else {
               cont = kTRUE;
            }
            ph = strtok(0," ");
         }
      } else {
         TString hostsrv = nxt;
         TString host   = hostsrv;
         TString server = "";
         if (hostsrv.Contains(":")) {
            server = hostsrv;
            host.Remove(host.Index(":"));
            server.Remove(0,server.Index(":")+1);
         }
         Int_t srvtyp = -1;
         if (server.Length()) {
            if (server == "0" || server.BeginsWith("sock"))
               srvtyp = TSocket::kSOCKD;
            else if (server == "1" || server.BeginsWith("root"))
               srvtyp = TSocket::kROOTD;
            else if (server == "2" || server.BeginsWith("proof"))
               srvtyp = TSocket::kPROOFD;
         }
         
         TString user = "*";
         char *nxt = strtok(0," ");
         if (!strncmp(nxt,"user",4)) {
            nxt = strtok(0," ");
            if (strncmp(nxt,"list",4) && strncmp(nxt,"method",6)) {
               user = TString(nxt);
               nxt = strtok(0," ");
            }
         }
         
         TIter next(&tmpAuthInfo);
         THostAuth *ha;
         while ((ha = (THostAuth *)next())) {
            if (host == ha->GetHost() && user == ha->GetUser() &&
                srvtyp == ha->GetServer())
               break;
         }
         if (!ha) {
            
            ha = new THostAuth(host,srvtyp,user);
            tmpAuthInfo.Add(ha);
         }
         if (!strncmp(nxt,"list",4)) {
            
            Int_t nm = 0, me[kMAXSEC] = {0};
            char *mth = strtok(0," ");
            while (mth) {
               Int_t met = -1;
               if (strlen(mth) > 1) {
                  
                  met = GetAuthMethodIdx(mth);
                  if (met == -1 && gDebug > 2)
                     ::Info("TAuthenticate::ReadRootAuthrc",
                            "unrecognized method (%s): ", mth);
               } else {
                  met = atoi(mth);
               }
               if (met > -1 && met < kMAXSEC)
                  me[nm++] = met;
               mth = strtok(0," ");
            }
            if (nm)
               ha->ReOrder(nm,me);
         } else if (!strncmp(nxt,"method",6)) {
            
            char *mth = strtok(0," ");
            Int_t met = -1;
            if (strlen(mth) > 1) {
               
               met = GetAuthMethodIdx(mth);
               if (met == -1 && gDebug > 2)
                  ::Info("TAuthenticate::ReadRootAuthrc",
                         "unrecognized method (%s): ", mth);
            } else {
               met = atoi(mth);
            }
            if (met > -1 && met < kMAXSEC) {
               const char *det = 0;
               nxt = strtok(0," ");
               if (nxt) {
                  det = (const char *)strstr(line,nxt);
               }
               if (ha->HasMethod(met))
                  ha->SetDetails(met,det);
               else
                  ha->AddMethod(met,det);
            }
         }
      }
      if (tmp) delete [] tmp;
   }
   
   fclose(fd);
   if (expand == 1)
      gSystem->Unlink(filetmp);
   
   if (authrc) delete [] authrc;
   
   TAuthenticate::MergeHostAuthList(authinfo,&tmpAuthInfo);
   
   if (gDebug > 2)
      TAuthenticate::Show();
   
   
   TList tmpproofauthinfo;
   if (proofserv.Length() > 0) {
      char *tmp = new char[proofserv.Length()+1];
      strcpy(tmp,proofserv.Data());
      char *nxt = strtok(tmp," ");
      while (nxt) {
         TString tmp((const char *)nxt);
         Int_t pdd = -1;
         
         TString host;
         if ((pdd = tmp.Index(":")) == -1) {
            host = tmp;
         } else {
            host = tmp;
            host.Resize(pdd);
            if (!host.Length())
               host = "*";
            tmp.Remove(0,pdd+1);
         }
         
         TString user;
         if ((pdd = tmp.Index(":")) == -1) {
            user = tmp;
         } else {
            user = tmp;
            user.Resize(pdd);
            if (!user.Length())
               user = "*";
            tmp.Remove(0,pdd+1);
         }
         
         TString meth;
         Int_t nm = 0, me[kMAXSEC] = {0}, met = -1;
         while (tmp.Length() > 0) {
            meth = tmp;
            if ((pdd = tmp.Index(":")) > -1)
               meth.Resize(pdd);
            if (meth.Length() > 1) {
               
               met = GetAuthMethodIdx(meth.Data());
               if (met == -1 && gDebug > 2)
                  ::Info("TAuthenticate::ReadRootAuthrc",
                         "unrecognized method (%s): ",meth.Data());
            } else if (meth.Length() == 1) {
               met = atoi(meth.Data());
               if (met > -1 && met < kMAXSEC)
                  me[nm++] = met;
            }
            if (pdd > -1)
               tmp.Remove(0,pdd+1);
            else
               tmp.Resize(0);
         }
         
         THostAuth *ha = 0;
         THostAuth *hatmp = TAuthenticate::GetHostAuth(host,user);
         if (!hatmp) {
            ha = new THostAuth(host,user,nm,me,0);
         } else {
            
            ha = new THostAuth(host,user);
            
            ha->Update(hatmp);
            
            ha->ReOrder(nm,me);
         }
         
         tmpproofauthinfo.Add(ha);
         
         nxt = strtok(0," ");
      }
      if (tmp) delete [] tmp;
   }
   
   TAuthenticate::MergeHostAuthList(proofauthinfo,&tmpproofauthinfo,"P");
   
   if (gDebug > 2)
      TAuthenticate::Show("P");
   return authinfo->GetSize();
}
Bool_t TAuthenticate::CheckProofAuth(Int_t cSec, TString &out)
{
   
   Bool_t rc = kFALSE;
   const char sshid[3][20] = { "/.ssh/identity", "/.ssh/id_dsa", "/.ssh/id_rsa" };
   const char netrc[2][20] = { "/.netrc", "/.rootnetrc" };
   TString user;
   
   UserGroup_t *pw = gSystem->GetUserInfo();
   if (pw) {
      user = TString(pw->fUser);
      delete pw;
   } else {
      ::Info("CheckProofAuth",
             "not properly logged on (getpwuid unable to find relevant info)!");
      out = "";
      return rc;
   }
   
   if (cSec == (Int_t) TAuthenticate::kClear) {
      Int_t i = 0;
      for (; i < 2; i++) {
         TString infofile = TString(gSystem->HomeDirectory())+TString(netrc[i]);
         if (!gSystem->AccessPathName(infofile, kReadPermission))
            rc = kTRUE;
      }
      if (rc)
         out = Form("pt:0 ru:1 us:%s",user.Data());
   }
   
   if (cSec == (Int_t) TAuthenticate::kSRP) {
#ifdef R__SRP
      out = Form("pt:0 ru:1 us:%s",user.Data());
      rc = kTRUE;
#endif
   }
   
   if (cSec == (Int_t) TAuthenticate::kKrb5) {
#ifdef R__KRB5
      out = Form("pt:0 ru:0 us:%s",user.Data());
      rc = kTRUE;
#endif
   }
   
   if (cSec == (Int_t) TAuthenticate::kGlobus) {
#ifdef R__GLBS
      TApplication *lApp = gROOT->GetApplication();
      if (lApp != 0 && lApp->Argc() > 9) {
         if (gROOT->IsProofServ()) {
            
            Int_t ShmId = -1;
            if (gSystem->Getenv("ROOTSHMIDCRED"))
               ShmId = strtol(gSystem->Getenv("ROOTSHMIDCRED"),
                              (char **)0, 10);
            if (ShmId != -1) {
               struct shmid_ds shm_ds;
               if (shmctl(ShmId, IPC_STAT, &shm_ds) == 0)
                  rc = kTRUE;
            }
            if (rc) {
               
               TString Adir(gSystem->Getenv("X509_CERT_DIR"));
               
               TString Ucer(gSystem->Getenv("X509_USER_CERT"));
               
               TString Ukey(gSystem->Getenv("X509_USER_KEY"));
               
               TString Cdir = Ucer;
               Cdir.Resize(Cdir.Last('/')+1);
               
               out = Form("pt=0 ru:0 cd:%s cf:%s kf:%s ad:%s",
                          Cdir.Data(),Ucer.Data(),Ukey.Data(),Adir.Data());
            }
         }
      }
#endif
   }
   
   if (cSec == (Int_t) TAuthenticate::kSSH) {
      Int_t i = 0;
      for (; i < 3; i++) {
         TString infofile = TString(gSystem->HomeDirectory())+TString(sshid[i]);
         if (!gSystem->AccessPathName(infofile,kReadPermission))
            rc = kTRUE;
      }
      if (rc)
         out = Form("pt:0 ru:1 us:%s",user.Data());
   }
   
   if (cSec == (Int_t) TAuthenticate::kRfio) {
      out = Form("pt:0 ru:0 us:%s",user.Data());
      rc = kTRUE;
   }
   if (gDebug > 3) {
      if (strlen(out) > 0)
         ::Info("CheckProofAuth",
                "meth: %d ... is available: details: %s", cSec, out.Data());
      else
         ::Info("CheckProofAuth",
                "meth: %d ... is NOT available", cSec);
   }
   
   return rc;
}
Int_t StdCheckSecCtx(const char *user, TRootSecContext *ctx)
{
   
   
   
   
   Int_t rc = 0;
   if (ctx->IsActive()) {
      if (!strcmp(user,ctx->GetUser()) &&
          strncmp("AFS", ctx->GetID(), 3))
         rc = 1;
   }
   return rc;
}
void TAuthenticate::MergeHostAuthList(TList *std, TList *nin, Option_t *opt)
{
   
   
   
   
   
   
   
   
   TIter nxstd(std);
   THostAuth *ha;
   while ((ha = (THostAuth *) nxstd())) {
      if (!ha->IsActive()) {
         std->Remove(ha);
         SafeDelete(ha);
      }
   }
   
   TIter nxnew(nin);
   THostAuth *hanew;
   while ((hanew = (THostAuth *)nxnew())) {
      if (hanew->NumMethods()) {
         TString hostsrv(Form("%s:%d",hanew->GetHost(),hanew->GetServer()));
         THostAuth *hastd =
            TAuthenticate::HasHostAuth(hostsrv,hanew->GetUser(),opt);
         if (hastd) {
            
            hastd->Update(hanew);
            
            hanew->DeActivate();
         } else {
            
            std->Add(hanew);
         }
      } else
         
         hanew->DeActivate();
   }
   
   nxnew.Reset();
   while ((hanew = (THostAuth *)nxnew())) {
      if (!hanew->IsActive()) {
         nin->Remove(hanew);
         SafeDelete(hanew);
      }
   }
}
void TAuthenticate::RemoveSecContext(TRootSecContext *ctx)
{
   
   
   THostAuth *ha = 0;
   
   TIter nxai(GetAuthInfo());
   while ((ha = (THostAuth *)nxai())) {
      TIter next(ha->Established());
      TRootSecContext *lctx = 0;
      while ((lctx = (TRootSecContext *) next())) {
         if (lctx == ctx) {
            ha->Established()->Remove(ctx);
            break;
         }
      }
   }
   
   TIter nxpa(GetProofAuthInfo());
   while ((ha = (THostAuth *)nxpa())) {
      TIter next(ha->Established());
      TRootSecContext *lctx = 0;
      while ((lctx = (TRootSecContext *) next())) {
         if (lctx == ctx) {
            ha->Established()->Remove(ctx);
            break;
         }
      }
   }
}
static int ToB64low(const char *in, char *out, int mod)
{
   
   
   
   
   static char b64ref[64] = {'A','B','C','D','E','F','G','H','I','J',
                             'K','L','M','N','O','P','Q','R','S','T',
                             'U','V','W','X','Y','Z',
                             'a','b','c','d','e','f','g','h','i','j',
                             'k','l','m','n','o','p','q','r','s','t',
                             'u','v','w','x','y','z',
                             '0','1','2','3','4','5','6','7','8','9',
                             '+','/'};
   if (!in || !out)
      return -1;
   if (mod == 1) {
      *out++ = b64ref[ 0x3F & (in[0] >> 2) ];
      *out++ = b64ref[ 0x3F & (0x30 & (in[0] << 4)) ];
      *out++ = '=';
      *out++ = '=';
   } else if (mod == 2) {
      *out++ = b64ref[ 0x3F & (in[0] >> 2) ];
      *out++ = b64ref[ 0x3F & ((0x30 & (in[0] << 4)) | (0x0F & (in[1] >> 4))) ];
      *out++ = b64ref[ 0x3F & (0x3C & (in[1] << 2)) ];
      *out++ = '=';
   } else {
      *out++ = b64ref[ (int)(0x3F & (in[0] >> 2)) ];
      *out++ = b64ref[ 0x3F & ((0x30 & (in[0] << 4)) | (0x0F & (in[1] >> 4))) ];
      *out++ = b64ref[ 0x3F & ((0x3C & (in[1] << 2)) | (0x03 & (in[2] >> 6))) ];
      *out++ = b64ref[ 0x3F & in[2] ];
   }
   return 0;
}
Int_t TAuthenticate::EncodeBase64(const char *in, Int_t lin, TString &out)
{
   
   
   
   if (!in)
      return -1;
   int lout = (lin%3) ? ((lin/3) + 1)*4 : (lin/3) * 4;
   out = "";
   int i = 0;
   int mod = 0;
   char oo[5] = {0};
   for (; i < lin; i += 3) {
      mod = lin-i;
      ToB64low(in+i,oo,mod);
      oo[4] = 0;
      out += oo;
   }
   return lout;
}
static int FromB64low(const char *in, char *out)
{
   
   
   
   
   
   static int b64inv[256] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
                             52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,
                             -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
                             15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
                             -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
                             41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                             -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
   if (!in || !out)
      return -1;
   UInt_t i0 = (UInt_t)(in[0]);
   UInt_t i1 = (UInt_t)(in[1]);
   UInt_t i2 = (UInt_t)(in[2]);
   UInt_t i3 = (UInt_t)(in[3]);
   if (in[3] != '=') {
      *out++ = (0xFC & (b64inv[i0] << 2)) | (0x03 & (b64inv[i1] >> 4));
      *out++ = (0xF0 & (b64inv[i1] << 4)) | (0x0F & (b64inv[i2] >> 2));
      *out++ = (0xC0 & (b64inv[i2] << 6)) | (0x3F &  b64inv[i3]);
      return 3;
   } else if (in[2] == '=') {
      *out++ = (0xFC & (b64inv[i0] << 2)) | (0x03 & (b64inv[i1] >> 4));
      return 1;
   } else {
      *out++ = (0xFC & (b64inv[i0] << 2)) | (0x03 & (b64inv[i1] >> 4));
      *out++ = (0xF0 & (b64inv[i1] << 4)) | (0x0F & (b64inv[i2] >> 2));
      return 2;
   }
}
Int_t TAuthenticate::DecodeBase64(const char *in, char *out)
{
   
   
   
   
   
   
   
   
   
   if (!in)
      return -1;
   int lin = strlen(in);
   int lout = (lin/4)*3;
   if (!out)
      
      return lout;
   int i = 0;
   int k = 0;
   for (; i < lin; i += 4) {
      FromB64low(in+i,out+k);
      k += 3;
   }
   return lout;
}
Int_t TAuthenticate::ProofAuthSetup()
{
   
   
   
   
   static Bool_t done = kFALSE;
   
   if (done)
      return 0;
   done = kTRUE;
   
   const char *p = gSystem->Getenv("ROOTPROOFAUTHSETUP");
   if (!p) {
      if (gDebug > 2)
         Info("ProofAuthSetup","Buffer not found: nothing to do");
      return 0;
   }
   Int_t mlen = TAuthenticate::DecodeBase64(p, 0);
   char *mbuf = new char[mlen];
   if ((mlen = TAuthenticate::DecodeBase64(p, mbuf)) < 0) {
      Error("ProofAuthSetup","Problem decoding the buffer");
      return -1;
   }
   
   TMessage *mess = new TMessage(mbuf, mlen+sizeof(UInt_t));
   
   TString user = "";
   TString passwd = "";
   Bool_t  pwhash = kFALSE;
   Bool_t  srppwd = kFALSE;
   Int_t  rsakey = -1;
   *mess >> user >> passwd >> pwhash >> srppwd >> rsakey;
   
   TAuthenticate::SetGlobalUser(user);
   TAuthenticate::SetGlobalPasswd(passwd);
   TAuthenticate::SetGlobalPwHash(pwhash);
   TAuthenticate::SetGlobalSRPPwd(srppwd);
   TAuthenticate::SetDefaultRSAKeyType(rsakey);
   const char *h = gSystem->Getenv("ROOTHOMEAUTHRC");
   if (h) {
      Bool_t rha = (Bool_t)(strtol(h, (char **)0, 10));
      TAuthenticate::SetReadHomeAuthrc(rha);
   }
   
   TList *pha = (TList *)mess->ReadObject(TList::Class());
   if (!pha) {
      if (gDebug > 0)
         Info("ProofAuthSetup","List of THostAuth not found");
      return 0;
   }
   Bool_t master = gROOT->IsProofServ();
   TIter next(pha);
   THostAuth *ha = 0;
   while ((ha = (THostAuth *)next())) {
      
      Int_t kExact = 0;
      THostAuth *haex = 0;
      Bool_t fromProofAI = kFALSE;
      if (master) {
         
         haex = TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"P",&kExact);
         
         if (!haex) {
            haex =
               TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"R",&kExact);
         } else
            fromProofAI = kTRUE;
      } else {
         
         haex = TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"R",&kExact);
      }
      if (haex) {
         
         if (kExact == 1) {
            
            
            if (!master || fromProofAI) {
               
               
               haex->Update(ha);
               
               SafeDelete(ha);
            } else
               
               
               TAuthenticate::GetProofAuthInfo()->Add(ha);
         } else {
            
            
            Int_t i = 0;
            for (; i < haex->NumMethods(); i++) {
               Int_t met = haex->GetMethod(i);
               if (!ha->HasMethod(met))
                  ha->AddMethod(met,haex->GetDetails(met));
            }
            if (master)
               
               TAuthenticate::GetProofAuthInfo()->Add(ha);
            else
               
               TAuthenticate::GetAuthInfo()->Add(ha);
         }
      } else {
         if (master)
            
            TAuthenticate::GetProofAuthInfo()->Add(ha);
         else
            
            TAuthenticate::GetAuthInfo()->Add(ha);
      }
   }
   
   return 0;
}
Int_t TAuthenticate::ProofAuthSetup(TSocket *sock, Bool_t client)
{
   
   
   
   
   TSecContext *sc    = sock->GetSecContext();
   TString user       = sc->GetUser();
   Int_t remoteOffSet = sc->GetOffSet();
   
   
   TMessage pubkey;
   TString passwd = "";
   Bool_t  pwhash = kFALSE;
   Bool_t  srppwd = kFALSE;
   Bool_t  sndsrp = kFALSE;
   Bool_t upwd = sc->IsA("UsrPwd");
   Bool_t srp = sc->IsA("SRP");
   TPwdCtx *pwdctx = 0;
   if (remoteOffSet > -1 && (upwd || srp))
      pwdctx = (TPwdCtx *)(sc->GetContext());
   if (client) {
      if ((gEnv->GetValue("Proofd.SendSRPPwd",0)) && (remoteOffSet > -1))
         sndsrp = kTRUE;
   } else {
      if (srp && pwdctx) {
         if (pwdctx->GetPasswd() != "" && remoteOffSet > -1)
            sndsrp = kTRUE;
      }
   }
   if ((upwd && pwdctx) || (srp  && sndsrp)) {
      if (pwdctx) {
         passwd = pwdctx->GetPasswd();
         pwhash = pwdctx->IsPwHash();
      }
   }
   Int_t keytyp = ((TRootSecContext *)sc)->GetRSAKey();
   
   TMessage mess;
   mess << user << passwd << pwhash << srppwd << keytyp;
   
   mess.WriteObject(TAuthenticate::GetProofAuthInfo());
   
   char *mbuf = mess.Buffer();
   Int_t mlen = mess.Length();
   TString messb64;
   TAuthenticate::EncodeBase64(mbuf, mlen, messb64);
   if (gDebug > 2)
      ::Info("ProofAuthSetup","sending %d bytes", messb64.Length());
   
   if (remoteOffSet > -1) {
      if (TAuthenticate::SecureSend(sock, 1, keytyp, messb64.Data()) == -1) {
         ::Error("ProofAuthSetup","problems secure-sending message buffer");
         return -1;
      }
   } else {
      
      char buflen[20];
      snprintf(buflen,20, "%d", messb64.Length());
      if (sock->Send(buflen, kMESS_ANY) < 0) {
         ::Error("ProofAuthSetup","plain: problems sending message length");
         return -1;
      }
      if (sock->SendRaw(messb64.Data(), messb64.Length()) < 0) {
         ::Error("ProofAuthSetup","problems sending message buffer");
         return -1;
      }
   }
   
   return 0;
}
Int_t TAuthenticate::GetClientProtocol()
{
   
   return TSocket::GetClientProtocol();
}
static Int_t SendHostAuth(TSocket *s)
{
   
   
   
   
   
   
   
   Int_t retval = 0, ns = 0;
   if (!s) {
      Error("SendHostAuth","invalid input: socket undefined");
      return -1;
   }
   TIter next(TAuthenticate::GetProofAuthInfo());
   THostAuth *ha;
   while ((ha = (THostAuth *)next())) {
      TString buf;
      ha->AsString(buf);
      if((ns = s->Send(buf, kPROOF_HOSTAUTH)) < 1) {
         retval = -1;
         break;
      }
      if (gDebug > 2)
         Info("SendHostAuth","sent %d bytes (%s)",ns,buf.Data());
   }
   
   if ((ns = s->Send("END", kPROOF_HOSTAUTH)) < 1)
      retval = -2;
   if (gDebug > 2)
      Info("SendHostAuth","sent %d bytes for closing",ns);
   return retval;
}
static Int_t RecvHostAuth(TSocket *s, Option_t *opt)
{
   
   
   
   
   if (!s) {
      Error("RecvHostAuth","invalid input: socket undefined");
      return -1;
   }
   
   Bool_t master = !strncasecmp(opt,"M",1) ? kTRUE : kFALSE;
   
   TAuthenticate::ReadRootAuthrc();
   
   Int_t kind;
   char buf[kMAXSECBUF];
   Int_t nr = s->Recv(buf, kMAXSECBUF, kind);
   if (nr < 0 || kind != kPROOF_HOSTAUTH) {
      Error("RecvHostAuth", "received: kind: %d (%d bytes)", kind, nr);
      return -1;
   }
   if (gDebug > 2)
      Info("RecvHostAuth","received %d bytes (%s)",nr,buf);
   while (strcmp(buf, "END")) {
      
      Int_t nc = (nr < kMAXSECBUF)? nr : kMAXSECBUF ;
      buf[nc] = '\0';
      
      THostAuth *ha = new THostAuth((const char *)&buf);
      
      Int_t kExact = 0;
      THostAuth *haex = 0;
      Bool_t fromProofAI = kFALSE;
      if (master) {
         
         haex = TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"P",&kExact);
         
         if (!haex) {
            haex =
               TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"R",&kExact);
         } else
            fromProofAI = kTRUE;
      } else {
         
         haex = TAuthenticate::GetHostAuth(ha->GetHost(),ha->GetUser(),"R",&kExact);
      }
      if (haex) {
         
         if (kExact == 1) {
            
            
            if (!master || fromProofAI) {
               
               
               haex->Update(ha);
               
               SafeDelete(ha);
            } else
               
               
               TAuthenticate::GetProofAuthInfo()->Add(ha);
         } else {
            
            
            Int_t i = 0;
            for (; i < haex->NumMethods(); i++) {
               Int_t met = haex->GetMethod(i);
               if (!ha->HasMethod(met))
                  ha->AddMethod(met,haex->GetDetails(met));
            }
            if (master)
               
               TAuthenticate::GetProofAuthInfo()->Add(ha);
            else
               
               TAuthenticate::GetAuthInfo()->Add(ha);
         }
      } else {
         if (master)
            
            TAuthenticate::GetProofAuthInfo()->Add(ha);
         else
            
            TAuthenticate::GetAuthInfo()->Add(ha);
      }
      
      nr = s->Recv(buf, kMAXSECBUF, kind);
      if (nr < 0 || kind != kPROOF_HOSTAUTH) {
         Info("RecvHostAuth","Error: received: kind: %d (%d bytes)", kind, nr);
         return -1;
      }
      if (gDebug > 2)
         Info("RecvHostAuth","received %d bytes (%s)",nr,buf);
   }
   return 0;
}
extern "C" {
Int_t OldSlaveAuthSetup(TSocket *sock,
                        Bool_t master, TString ord, TString conf)
{
   
   
   
   
   TSecContext *sc    = sock->GetSecContext();
   TString user       = sc->GetUser();
   Int_t proofdProto  = sock->GetRemoteProtocol();
   Int_t remoteOffSet = sc->GetOffSet();
   
   
   TMessage pubkey;
   TString passwd = "";
   Bool_t  pwhash = kFALSE;
   Bool_t  srppwd = kFALSE;
   Bool_t  sndsrp = kFALSE;
   Bool_t upwd = sc->IsA("UsrPwd");
   Bool_t srp = sc->IsA("SRP");
   TPwdCtx *pwdctx = 0;
   if (remoteOffSet > -1 && (upwd || srp))
      pwdctx = (TPwdCtx *)(sc->GetContext());
   if (!master) {
      if ((gEnv->GetValue("Proofd.SendSRPPwd",0)) && (remoteOffSet > -1))
         sndsrp = kTRUE;
   } else {
      if (srp && pwdctx) {
         if (pwdctx->GetPasswd() != "" && remoteOffSet > -1)
            sndsrp = kTRUE;
      }
   }
   if ((upwd && pwdctx) || (srp  && sndsrp)) {
      
      if (sock->Send(remoteOffSet, kROOTD_RSAKEY) != 2*sizeof(Int_t)) {
         Error("OldAuthSetup", "failed to send offset in RSA key");
         return -1;
      }
      if (pwdctx) {
         passwd = pwdctx->GetPasswd();
         pwhash = pwdctx->IsPwHash();
      }
      Int_t keytyp = ((TRootSecContext *)sc)->GetRSAKey();
      if (TAuthenticate::SecureSend(sock, 1, keytyp, passwd.Data()) == -1) {
         if (remoteOffSet > -1)
            Warning("OldAuthSetup","problems secure-sending pass hash %s",
                    "- may result in failures");
         
         if (upwd) {
            for (int i = 0; i < passwd.Length(); i++) {
               char inv = ~passwd(i);
               passwd.Replace(i, 1, inv);
            }
            TMessage mess;
            mess << passwd;
            if (sock->Send(mess) < 0) {
               Error("OldAuthSetup", "failed to send inverted password");
               return -1;
            }
         }
      }
   } else {
      
      if (sock->Send(-2, kROOTD_RSAKEY) != 2*sizeof(Int_t)) {
         Error("OldAuthSetup", "failed to send no offset notification in RSA key");
         return -1;
      }
   }
   
   TMessage mess;
   mess << user << pwhash << srppwd << ord << conf;
   if (sock->Send(mess) < 0) {
      Error("OldAuthSetup", "failed to send ordinal and config info");
      return -1;
   }
   if (proofdProto > 6) {
      
      
      
      
      if (SendHostAuth(sock) < 0) {
         Error("OldAuthSetup", "failed to send HostAuth info");
         return -1;
      }
   }
   
   return 0;
}
Int_t OldProofServAuthSetup(TSocket *sock, Bool_t master, Int_t protocol,
                            TString &user, TString &ord, TString &conf)
{
   
   
   
   
   Int_t retval, kind;
   if (sock->Recv(retval, kind) != 2*sizeof(Int_t)) {
      
      Info("OldProofServAuthSetup",
           "socket has been closed due to protocol mismatch - Exiting");
      return -1;
   }
   Int_t rsakey = 0;
   TString passwd;
   if (kind == kROOTD_RSAKEY) {
      if (retval > -1) {
         if (gSystem->Getenv("ROOTKEYFILE")) {
            TString keyfile = gSystem->Getenv("ROOTKEYFILE");
            keyfile += retval;
            FILE *fKey = 0;
            char pubkey[kMAXPATHLEN] = { 0 };
            if (!gSystem->AccessPathName(keyfile.Data(), kReadPermission)) {
               fKey = fopen(keyfile.Data(), "r");
               if (fKey) {
                  Int_t klen = fread((void *)pubkey,1,sizeof(pubkey),fKey);
                  
                  rsakey = TAuthenticate::SetRSAPublic(pubkey,klen);
                  fclose(fKey);
               }
            }
         }
         
         char *pwd = 0;
         if (TAuthenticate::SecureRecv(sock, 2, rsakey, &pwd) < 0) {
            Error("OldProofServAuthSetup", "failed to receive password");
            return -1;
         }
         passwd = pwd;
         delete[] pwd;
      } else if (retval == -1) {
         
         TMessage *mess;
         if ((sock->Recv(mess) <= 0) || !mess) {
            Error("OldProofServAuthSetup", "failed to receive inverted password");
            return -1;
         }
         (*mess) >> passwd;
         delete mess;
         for (Int_t i = 0; i < passwd.Length(); i++) {
            char inv = ~passwd(i);
            passwd.Replace(i, 1, inv);
         }
      }
   }
   
   TMessage *mess;
   if ((sock->Recv(mess) <= 0) || !mess) {
      Error("OldProofServAuthSetup", "failed to receive ordinal and config info");
      return -1;
   }
   
   Bool_t pwhash, srppwd;
   if (master) {
      if (protocol < 4) {
         (*mess) >> user >> pwhash >> srppwd >> conf;
         ord = "0";
      } else {
         (*mess) >> user >> pwhash >> srppwd >> ord >> conf;
      }
   } else {
      if (protocol < 4) {
         Int_t iord;
         (*mess) >> user >> pwhash >> srppwd >> iord;
         ord = "0.";
         ord += iord;
      } else {
         (*mess) >> user >> pwhash >> srppwd >> ord >> conf;
      }
   }
   delete mess;
   
   TAuthenticate::SetGlobalUser(user);
   TAuthenticate::SetGlobalPasswd(passwd);
   TAuthenticate::SetGlobalPwHash(pwhash);
   TAuthenticate::SetGlobalSRPPwd(srppwd);
   TAuthenticate::SetDefaultRSAKeyType(rsakey);
   const char *h = gSystem->Getenv("ROOTHOMEAUTHRC");
   if (h) {
      Bool_t rha = (Bool_t)(strtol(h, (char **)0, 10));
      TAuthenticate::SetReadHomeAuthrc(rha);
   }
   
   
   Int_t harc = master ? RecvHostAuth(sock, "M") : RecvHostAuth(sock, "S");
   if (harc < 0) {
      Error("OldProofServAuthSetup", "failed to receive HostAuth info");
      return -1;
   }
   
   return 0;
}
}  
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.