From 5fbc685b0760f2ac83ee644e0d064057481ddaa4 Mon Sep 17 00:00:00 2001
From: Fons Rademakers <Fons.Rademakers@cern.ch>
Date: Tue, 18 Nov 2003 19:28:25 +0000
Subject: [PATCH] From Gerri: net/inc/TAuthenticate.h  o drop method
 CheckHostWild()

net/src/TAuthenticate.cxx
 o drop method CheckHostWild()
 o Modified hostname checking in CheckHost()

etc/example.rootauthrc
 o updated documentation


git-svn-id: http://root.cern.ch/svn/root/trunk@7614 27541ba8-7e3a-0410-8455-c3a389f83636
---
 etc/example.rootauthrc    |  32 ++++---
 net/inc/TAuthenticate.h   |   3 +-
 net/src/TAuthenticate.cxx | 193 +++++++++-----------------------------
 3 files changed, 63 insertions(+), 165 deletions(-)

diff --git a/etc/example.rootauthrc b/etc/example.rootauthrc
index fe7dccb8403..31136bad4c9 100644
--- a/etc/example.rootauthrc
+++ b/etc/example.rootauthrc
@@ -42,22 +42,26 @@
 #      applies; if absent, the info applies to all users.
 #
 #      <host>:
-#         - hosts can specified either with their FQDN (e.g. pcepsft43.cern.ch)
-#           or their IP address (e.g. 137.138.99.73).
-#         - if <host>=default the following i<key> <info> applies to all 
-#           hosts, unless host-specific entries are found.
-#         - the '*' character can be used in the first field of the name to 
-#           indicate a set of machines, e.g. pcepsft*.cern.ch applies to all 
-#           'pcepsft' machines in the domain 'cern.ch'
+#         - hosts can specified either with their name (e.g. pcepsft43), 
+#           their FQDN (e.g. pcepsft43.cern.ch) or their IP address 
+#           (e.g. 137.138.99.73).
+#         - if <host>=default or <host>='*' the following <key> <info> 
+#           applies to all hosts, unless host-specific entries are found.
+#         - the '*' character can be used in the any field of the name to 
+#           indicate a set of machines or domains, e.g. pcepsft*.cern.ch 
+#           applies to all 'pcepsft' machines in the domain 'cern.ch'
 #           (to indicate all 'lxplus' machines you should use 'lxplus*.cern.ch'
 #           because internally the generic lxplus machine has a real name of
-#           the form lxplusnnn.cern.ch).
-#         - a whole domain can be indicated by its name, with at least two non 
-#           null fields, eg 'cern.ch' or '.cern.ch', '.ch' is not accepted.
-#         - subsets of the IP address can also be used to indicate a set of
-#           machines; however, it is mandatory to end the subset with a '.', 
-#           e.g. '137.138.' is an alternative way to indicate the 'cern.ch'
-#           domain, but '137.138' is invalid because ambiguous.
+#           the form lxplusnnn.cern.ch; you can also use 'lxplus' if you
+#           don't care about domain name checking)
+#         - a whole domain can be indicated by its name, eg 'cern.ch', 
+#           'cnaf.infn.it' or '.ch'
+#         - truncated IP address can also be used to indicate a set of
+#           machines; they are interpreted as the very first or very last 
+#           part of the address; for example, to select 137.138.99.73, 
+#           any of these is valid: '137.138.99', '137.138', '137`, '99.73'; 
+#           or with wild cards: '137.13*' or '*.99.73`; however, '138.99' 
+#           is invalid because ambigous.
 #
 #      <key> <info>:
 #         - valid keys are 'list' and 'method';
diff --git a/net/inc/TAuthenticate.h b/net/inc/TAuthenticate.h
index f8f9bd95c88..3ddb156ab11 100644
--- a/net/inc/TAuthenticate.h
+++ b/net/inc/TAuthenticate.h
@@ -1,4 +1,4 @@
-// @(#)root/net:$Name:  $:$Id: TAuthenticate.h,v 1.12 2003/09/16 00:39:23 rdm Exp $
+// @(#)root/net:$Name:  $:$Id: TAuthenticate.h,v 1.14 2003/10/07 21:09:55 rdm Exp $
 // Author: Fons Rademakers   26/11/2000
 
 /*************************************************************************
@@ -127,6 +127,7 @@ public:
    Bool_t             GetPwHash() const { return fPwHash; }
    Bool_t             GetSRPPwd() const { return fSRPPwd; }
    const char        *GetProtocol() const { return fProtocol; }
+   const char        *GetRemoteHost() const { return fRemote; }
    const char        *GetSshUser() const;
    void               SetUser(const char *user) { fUser = user; }
    void               SetPwHash(Bool_t pwhash) { fPwHash = pwhash; }
diff --git a/net/src/TAuthenticate.cxx b/net/src/TAuthenticate.cxx
index b479a7bbdc5..e85308d63fa 100644
--- a/net/src/TAuthenticate.cxx
+++ b/net/src/TAuthenticate.cxx
@@ -1,4 +1,4 @@
-// @(#)root/net:$Name:  $:$Id: TAuthenticate.cxx,v 1.28 2003/11/09 16:09:50 brun Exp $
+// @(#)root/net:$Name:  $:$Id: TAuthenticate.cxx,v 1.29 2003/11/10 14:40:07 rdm Exp $
 // Author: Fons Rademakers   26/11/2000
 
 /*************************************************************************
@@ -32,6 +32,7 @@
 #include "TEnv.h"
 #include "TList.h"
 #include "NetErrors.h"
+#include "TRegexp.h"
 
 #ifndef R__LYNXOS
 #include <sys/stat.h>
@@ -75,7 +76,6 @@ TList *TAuthenticate::fgAuthInfo = 0;
 
 TString TAuthenticate::fgAuthMeth[] = { "UsrPwd", "SRP", "Krb5", "Globus", "SSH", "UidGid" };
 
-
 ClassImp(TAuthenticate)
 
 //______________________________________________________________________________
@@ -2072,160 +2072,53 @@ Bool_t TAuthenticate::CheckHost(const char *Host, const char *host)
 
    Bool_t retval = kTRUE;
 
-   // Get IP of the host in form of a string
-   TInetAddress addr = gSystem->GetHostByName(Host);
-   char *IP = StrDup(addr.GetHostAddress());
-   if (gDebug > 2)
-      ::Info("CheckHost", "host: %s --> IP: %s", Host, IP);
-
-   // now check validity of 'host' format
-   // Try first to understand whether it is an address or a name ...
-   int i, name = 0, namew = 0, nd = 0, nn = 0, nnmx = 0,
-       nnmi = strlen(host);
-   for (i = 0; i < (int) strlen(host); i++) {
-      if (host[i] == '.') {
-         nd++;
-         if (nn > nnmx)
-            nnmx = nn;
-         if (nn < nnmi)
-            nnmi = nn;
-         nn = 0;
-         continue;
-      }
-      int j = (int) host[i];
-      if (j < 48 || j > 57)
-         name = 1;
-      if (host[i] == '*') {
-         namew = 1;
-         if (nd > 0) {
-            retval = kFALSE;
-            goto exit;
-         }
-      }
-      nn++;
-    }
-
-   // Act accordingly ...
-   if (name == 0) {
-      if (nd < 4) {
-         if (strlen(host) < 16) {
-            if (nnmx < 4) {
-               if (nd == 3 || host[strlen(host) - 1] == '.') {
-                  char *sp = strstr(IP, host);
-                  if (sp == 0 || sp != IP) {
-                     retval = kFALSE;
-                     goto exit;
-                  }
-               }
-            }
-         }
-      }
-   } else {
-      if (namew == 0) {
-         if (nd > 0) {
-            if (nd > 1 || nnmi > 0) {
-               const char *sp = strstr(Host, host);
-               if (sp == 0 || sp != Host) {
-                  retval = kFALSE;
-                  goto exit;
-               }
-            }
-         } else {
-            retval = kFALSE;
-            goto exit;
-         }
-      } else {
-         if (!CheckHostWild(Host, host)) {
-            retval = kFALSE;
-            goto exit;
-         }
-      }
-   }
-
-   if (gDebug > 2)
-      ::Info("CheckHost", "info for host found in table ");
-
- exit:
-   if (IP) delete[] IP;
-   return retval;
-}
-
-//______________________________________________________________________________
-Bool_t TAuthenticate::CheckHostWild(const char *Host, const char *host)
-{
-   // Checks if 'host' is compatible with 'Host' taking into account
-   // wild cards in the machine name (first field of FQDN) ...
-   // Returns 0 if successful, 1 otherwise ...
-
-   Bool_t rc = kTRUE;
-   char *fH, *sH, *dum, *sp, *k;
-   int i, j, lmax;
+   // Both strings should have been defined
+   if (!Host || !host) 
+      return kFALSE;
 
-   if (gDebug > 2)
-      ::Info("CheckHostWild", "enter: H: '%s' h: '%s'", Host, host);
-
-   // Max length for dinamic allocation
-   lmax = strlen(Host) > strlen(host) ? strlen(Host) : strlen(host);
-
-   // allocate
-   fH = new char[lmax];
-   sH = new char[lmax];
-   dum = new char[lmax];
+   // 'host' == '*' indicates any 'Host' ...
+   if (!strcmp(host,"*")) 
+      return kTRUE;
 
-   // Determine 'Host' first field (the name) ...
-   for (i = 0; i < (int) strlen(Host); i++) {
-      if (Host[i] == '.')
-         break;
+   // If 'host' contains at a letter or an hyphen it is assumed to be
+   // a host name. Otherwise a name.
+   // Check also for wild cards
+   Bool_t name = kFALSE;
+   TRegexp rename("[+a-zA-Z]");
+   Int_t len;
+   if (rename.Index(host,&len) != -1 || strstr(host,"-"))
+      name = kTRUE;
+
+   // Check also for wild cards
+   Bool_t wild = kFALSE;
+   if (strstr(host,"*"))
+      wild = kTRUE; 
+
+   // Now build the regular expression for final checking
+   TRegexp rehost(host,wild);
+
+   // Host to check
+   TString theHost(Host);
+   if (!name) {
+      TInetAddress addr = gSystem->GetHostByName(Host);
+      theHost = addr.GetHostAddress();
+      if (gDebug > 2)
+         ::Info("CheckHost", "checking host IP: %s", theHost.Data());
    }
-   strncpy(fH, Host, i);
-   fH[i] = '\0';
-   // ... and also the second one (the domain)
-   strcpy(sH, Host + i);
-   if (gDebug > 3)
-      ::Info("CheckHostWild", "fH:%s sH:%s", fH, sH);
 
-   // Now check the first field ...
-   j = 0;
-   k = fH;
-   for (i = 0; i < (int) strlen(host); i++) {
-      if (host[i] == '.')
-         break;
-      if (host[i] == '*') {
-         if (i > 0) {
-            // this is the part of name before the '*' ....
-            strncpy(dum, host + j, i - j);
-            dum[i - j] = '\0';
-            if (gDebug > 3)
-               ::Info("CheckHostWild", "k:%s dum:%s", k, dum);
-            sp = strstr(k, dum);
-            if (sp == 0) {
-               rc = kFALSE;
-               goto exit;
-            }
-            j = i + 1;
-            k = sp + strlen(dum) + 1;
-         } else
-            j++;
-      }
-   }
-   // Now check the domain name (if the name matches ...)
-   if (rc) {
-      strcpy(dum, host + i);
-      if (gDebug > 3)
-         ::Info("CheckHostWild", "sH:%s dum:%s", sH, dum);
-      sp = strstr(sH, dum);
-      if (sp == 0) {
-         rc = kFALSE;
-         goto exit;
-      }
+   // Check 'Host' against 'rehost'
+   Ssiz_t pos = rehost.Index(theHost,&len);
+   if (pos == -1)
+      retval = kFALSE;
+
+   // If IP and no wilds, it should match either 
+   // the beginning or the end of the string
+   if (!wild) {
+      if (pos > 0 && pos != (Ssiz_t)(theHost.Length()-strlen(host)))
+         retval = kFALSE;
    }
 
- exit:
-   // Release allocated memory ...
-   if (fH) delete[] fH;
-   if (sH) delete[] sH;
-   if (dum) delete[] dum;
-   return rc;
+   return retval;
 }
 
 //______________________________________________________________________________
-- 
GitLab