SRPAuth.cxx

Go to the documentation of this file.
00001 // @(#)root/srputils:$Id: SRPAuth.cxx 20882 2007-11-19 11:31:26Z rdm $
00002 // Author: Fons Rademakers   15/02/2000
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 
00013 #include <stdio.h>
00014 extern "C" {
00015 #include <t_pwd.h>
00016 #include <t_client.h>
00017 }
00018 
00019 #include "TSocket.h"
00020 #include "TAuthenticate.h"
00021 #include "THostAuth.h"
00022 #include "TError.h"
00023 #include "TSystem.h"
00024 #include "TEnv.h"
00025 #include "rpderr.h"
00026 
00027 
00028 Int_t SRPAuthenticate(TAuthenticate *, const char *user, const char *passwd,
00029                       const char *remote, TString &, Int_t);
00030 Int_t SRPCheckSecCtx(const char *, TSecContext *);
00031 
00032 class SRPAuthInit {
00033 public:
00034    SRPAuthInit() { TAuthenticate::SetSecureAuthHook(&SRPAuthenticate); }
00035 };
00036 static SRPAuthInit srpauth_init;
00037 
00038 
00039 //______________________________________________________________________________
00040 Int_t SRPAuthenticate(TAuthenticate *auth, const char *user, const char *passwd,
00041                       const char *remote, TString &det, Int_t version)
00042 {
00043    // Authenticate to remote rootd/proofd server using the SRP (secure remote
00044    // password) protocol. Returns 0 if authentication failed, 1 if
00045    // authentication succeeded and 2 if SRP is not available and standard
00046    // authentication should be tried. Called via TAuthenticate class.
00047 
00048    Int_t  result = 0;
00049    char  *usr = 0;
00050    char  *psswd = 0;
00051    Int_t  stat, kind;
00052    TSocket *sock = auth->GetSocket();
00053 
00054    // send user name
00055    if (user && user[0])
00056       usr = StrDup(user);
00057    else
00058       usr = TAuthenticate::PromptUser(remote); // Should never get here ...
00059 
00060    Int_t ReUse= 1, Prompt= 0;
00061    TString Details;
00062 
00063    if (version > 1) {
00064 
00065      // Check ReUse
00066      ReUse  = TAuthenticate::GetAuthReUse();
00067      Prompt = TAuthenticate::GetPromptUser();
00068 
00069      // Build auth details
00070      Details = Form("pt:%d ru:%d us:%s",Prompt,ReUse,usr);
00071 
00072      // Create Options string
00073      int Opt = ReUse * kAUTH_REUSE_MSK +
00074                auth->GetRSAKeyType() * kAUTH_RSATY_MSK;
00075      TString Options(Form("%d %d %s",Opt,strlen(usr),usr));
00076 
00077      // Now we are ready to send a request to the rootd/proofd
00078      // daemons to check if we have already a valid security context
00079      // and eventually to start a negotiation to get one ...
00080      kind = kROOTD_SRPUSER;
00081      stat = ReUse;
00082      int rc = 0;
00083      if ((rc = auth->AuthExists(TString(usr), TAuthenticate::kSRP,
00084                Options, &kind, &stat, &SRPCheckSecCtx)) == 1) {
00085        // A valid authentication exists: we are done ...
00086        return 1;
00087      }
00088      if (rc == -2) {
00089        return rc;
00090      }
00091      if (kind == kROOTD_ERR) {
00092         TString Server = "sockd";
00093         if (strstr(auth->GetProtocol(),"root"))
00094            Server = "rootd";
00095         if (strstr(auth->GetProtocol(),"proof"))
00096            Server = "proofd";
00097         if (stat == kErrConnectionRefused) {
00098            if (gDebug > 0)
00099               Error("SRPAuthenticate",
00100                  "%s@%s does not accept connections from %s%s",
00101                  Server.Data(),auth->GetRemoteHost(),
00102                  auth->GetUser(),gSystem->HostName());
00103            return -2;
00104         } else if (stat == kErrNotAllowed) {
00105            if (gDebug > 0)
00106               Error("SRPAuthenticate",
00107                  "%s@%s does not accept %s authentication from %s@%s",
00108                  Server.Data(),auth->GetRemoteHost(),
00109                  TAuthenticate::GetAuthMethod(1),
00110                  auth->GetUser(),gSystem->HostName());
00111         } else
00112            TAuthenticate::AuthError("SRPAuthenticate", stat);
00113         return 0;
00114      }
00115 
00116    } else {
00117 
00118      sock->Send(usr, kROOTD_SRPUSER);
00119      sock->Recv(stat, kind);
00120 
00121      // stat == 2 when no SRP support compiled in remote rootd
00122      if (kind == kROOTD_SRPUSER && stat == 0)
00123         return 2;
00124 
00125      if (kind == kROOTD_ERR) {
00126         TAuthenticate::AuthError("SRPAuthenticate", stat);
00127         return 0;
00128      }
00129 
00130    }
00131 
00132    struct t_num     n, g, s, B, *A;
00133    struct t_client *tc;
00134    char    hexbuf[MAXHEXPARAMLEN];
00135    UChar_t buf1[MAXPARAMLEN], buf2[MAXPARAMLEN], buf3[MAXSALTLEN];
00136 
00137    // receive n from server
00138    sock->Recv(hexbuf, MAXHEXPARAMLEN, kind);
00139    if (kind != kROOTD_SRPN) {
00140       if (gDebug>0) ::Error("SRPAuthenticate", "expected kROOTD_SRPN message");
00141       goto out;
00142    }
00143    n.data = buf1;
00144    n.len  = t_fromb64((char*)n.data, hexbuf);
00145 
00146    // receive g from server
00147    sock->Recv(hexbuf, MAXHEXPARAMLEN, kind);
00148    if (kind != kROOTD_SRPG) {
00149       if (gDebug>0) ::Error("SRPAuthenticate", "expected kROOTD_SRPG message");
00150       goto out;
00151    }
00152    g.data = buf2;
00153    g.len  = t_fromb64((char*)g.data, hexbuf);
00154 
00155    // receive salt from server
00156    sock->Recv(hexbuf, MAXHEXPARAMLEN, kind);
00157    if (kind != kROOTD_SRPSALT) {
00158       if (gDebug>0) ::Error("SRPAuthenticate", "expected kROOTD_SRPSALT message");
00159       goto out;
00160    }
00161    s.data = buf3;
00162    s.len  = t_fromb64((char*)s.data, hexbuf);
00163 
00164    tc = t_clientopen(usr, &n, &g, &s);
00165 
00166    A = t_clientgenexp(tc);
00167 
00168    // send A to server
00169    sock->Send(t_tob64(hexbuf, (char*)A->data, A->len), kROOTD_SRPA);
00170 
00171    if (passwd && passwd[0])
00172       psswd = StrDup(passwd);
00173    else {
00174       psswd = TAuthenticate::PromptPasswd(Form("%s@%s SRP password: ",user,remote));
00175       if (!psswd)
00176          if (gDebug>0) ::Error("SRPAuthenticate", "password not set");
00177    }
00178 
00179    t_clientpasswd(tc, psswd);
00180 
00181    // receive B from server
00182    sock->Recv(hexbuf, MAXHEXPARAMLEN, kind);
00183    if (kind != kROOTD_SRPB) {
00184       if (gDebug>0) ::Error("SRPAuthenticate", "expected kROOTD_SRPB message");
00185       goto out;
00186    }
00187    B.data = buf1;
00188    B.len  = t_fromb64((char*)B.data, hexbuf);
00189 
00190    t_clientgetkey(tc, &B);
00191 
00192    // send response to server
00193    sock->Send(t_tohex(hexbuf, (char*)t_clientresponse(tc), RESPONSE_LEN),
00194               kROOTD_SRPRESPONSE);
00195 
00196    t_clientclose(tc);
00197 
00198    if (version > 1) {
00199 
00200      // Receive result of the overall process
00201      sock->Recv(stat, kind);
00202      if (kind == kROOTD_ERR) {
00203        TAuthenticate::AuthError("SRPAuthenticate", stat);
00204        goto out;
00205      }
00206 
00207      // Save passwd for later use ...
00208      TAuthenticate::SetGlobalUser(user);
00209      TAuthenticate::SetGlobalPasswd(psswd);
00210      TAuthenticate::SetGlobalPwHash(kFALSE);
00211      TAuthenticate::SetGlobalSRPPwd(kTRUE);
00212 
00213      Int_t  RSAKey = 0;
00214      if (ReUse == 1) {
00215 
00216        if (kind != kROOTD_RSAKEY || stat < 1 || stat > 2)
00217           Warning("SRPAuthenticate",
00218                   "problems recvn RSA key flag: got message %d, flag: %d",
00219                   kind,RSAKey);
00220        RSAKey = stat - 1;
00221 
00222        // Send the key securely
00223        TAuthenticate::SendRSAPublicKey(sock,RSAKey);
00224 
00225        // Receive result of the overall process
00226        sock->Recv(stat, kind);
00227        if (kind == kROOTD_ERR)
00228           TAuthenticate::AuthError("SRPAuthenticate", stat);
00229      }
00230 
00231      if (kind == kROOTD_SRPUSER && stat == 1)
00232         result = 1;
00233 
00234      if (kind == kROOTD_SRPUSER && stat > 0) {
00235        char *rfrm= new char[stat+1];
00236        sock->Recv(rfrm,stat+1, kind);  // receive user,offset) info
00237        // Parse answer
00238        char *lUser = new char[stat];
00239        int OffSet = -1;
00240        sscanf(rfrm,"%s %d",lUser,&OffSet);
00241 
00242        // Decode Token
00243        char *Token = 0;
00244        if (ReUse == 1 && OffSet > -1) {
00245          if (TAuthenticate::SecureRecv(sock,1,RSAKey,&Token) == -1) {
00246            Warning("SRPAuthenticate",
00247                    "Problems secure-receiving Token - may result in corrupted Token");
00248          }
00249        } else {
00250          Token = StrDup("");
00251        }
00252 
00253        // Create SecContext object
00254        TPwdCtx *pwdctx = new TPwdCtx((const char *)psswd,kFALSE);
00255        TSecContext *ctx = 
00256           auth->GetHostAuth()->CreateSecContext((const char *)lUser, 
00257               remote, (Int_t)TAuthenticate::kSRP,OffSet,Details,
00258               (const char *)Token, TAuthenticate::GetGlobalExpDate(), 
00259               (void *)pwdctx, RSAKey);
00260        // Transmit it to TAuthenticate
00261        auth->SetSecContext(ctx);
00262        det = Details;
00263        if (Token) delete[] Token;
00264 
00265        // Receive result from remote Login process
00266        sock->Recv(stat, kind);
00267        if (stat==1 && kind==kROOTD_AUTH) {
00268          if (gDebug>0)
00269             Info("SRPAuthenticate",
00270                  "Remotely authenticated as %s (OffSet:%d)",lUser,OffSet);
00271          result = 1;
00272        }
00273 
00274      } else {
00275        if (kind != kROOTD_ERR )
00276          if (gDebug>0)
00277             Warning("SRPAuthenticate",
00278                     "problems recvn (user,offset) length (%d:%d)",kind,stat);
00279        TAuthenticate::AuthError("SRPAuthenticate", stat);
00280      }
00281 
00282    } else {
00283 
00284      // Old protocol
00285 
00286      // Receive result of the overall process
00287      sock->Recv(stat, kind);
00288 
00289      if (kind == kROOTD_ERR)
00290         TAuthenticate::AuthError("SRPAuthenticate", stat);
00291 
00292      if (kind == kROOTD_AUTH && stat == 1) {
00293         // Get a SecContext for the record and avoid problems
00294         // with fSecContext undefined in TAuthenticate
00295         TSecContext *ctx = 
00296            auth->GetHostAuth()->CreateSecContext((const char *)usr, 
00297                        remote, (Int_t)TAuthenticate::kSRP,-1,Details,0);
00298         // Transmit it to TAuthenticate
00299         auth->SetSecContext(ctx);
00300         result = 1;
00301      }
00302    }
00303 out:
00304    delete [] usr;
00305    delete [] psswd;
00306 
00307    return result;
00308 }
00309 
00310 
00311 //______________________________________________________________________________
00312 Int_t SRPCheckSecCtx(const char *User, TSecContext *Ctx)
00313 {
00314    // SRP version of CheckSecCtx to be passed to TAuthenticate::AuthExists
00315    // Check if User is matches the one in Ctx
00316    // Returns: 1 if ok, 0 if not
00317    // Deactivates Ctx is not valid 
00318  
00319    Int_t rc = 0;
00320  
00321    if (Ctx->IsActive()) {
00322       if (!strcmp(User,Ctx->GetUser()))
00323          rc = 1;
00324    }
00325    return rc;
00326 }

Generated on Tue Jul 5 14:46:13 2011 for ROOT_528-00b_version by  doxygen 1.5.1