From beacbef7dc7b8bef6c5309aeb4492d3546d463ee Mon Sep 17 00:00:00 2001 From: Fons Rademakers <Fons.Rademakers@cern.ch> Date: Fri, 7 Nov 2003 03:29:42 +0000 Subject: [PATCH] From Gerri: Index: README/README.AUTH o Update explaining tutorial use Index: base/src/TFile.cxx o ::Open(): call TNetFile also if same host but different user (to access files protected by password) Index: globusauth/src/GlobusAuth.cxx o Aestethic changes (shortening of a few lines) Index: krb5auth/src/Krb5Auth.cxx o Simplify two debug printouts o Change debug print to stderr in Info(...; add gDebug control. Index: net/inc/THostAuth.h o Modify default ctor o Add method HasMethod to test method availability Index: net/src/TAuthenticate.cxx o make sure that if fgUser (and nothing else) is set, this is the default user name o Make sure that requiring roots/rootk uses correctly details found for those methods in .rootauthrc o Fix return of GetPromptUser() o Fix problem with wild cards o Add check for wildcard host names in method GetHostAuth o Remove debug printout in method ReadAuthRc Index: net/src/THostAuth.cxx o Modify default ctor o Add method HaveMethod to test method availability o Aestethic changes (shortening of a few lines) Index: net/src/TNetFile.cxx o Remove precompiler unused #if's in method ConnectServer Index: proof/inc/TProofServ.h o Remove method ReadProofAuth, add method RecvHostAuth (To receive directly the authentication info in ProofServ instead of reading it from temporary files /usr/tmp/proofserv.<id>) Index: proof/src/TProofServ.cxx o All mods needed to remove method ReadProofAuth and add method RecvHostAuth (see above). Modified methods: Setup, CollectAuthInfo . o Fix bug in CollectAuthInfo switching ReUse off by default for method UsrPwd o Removing automatic choice of UidGid for local slaves o Setting order of default UidGid authentication to last o Aestethic changes in CheckAuth Index: proof/src/TSlave.cxx o transmit passwd for UsrPwd and SRP authentication also to slaves o All mods needed to send auth info to ProofServ instead of proofd (see above) Index: proofd/src/proofd.cxx o Fix compiling problem with namespaces for Kerberos o Remove redundant 'access' calls o Authenticate: do not recive auth info (done in ProofServ) o ProofExec: send TmpDir to proofserv (for key location) o Define gSystemdaemonc as $ROOTETCDIR/system.rootdaemonrc Index: rootd/src/rootd.cxx o Define gSystemdaemonc as $ROOTETCDIR/system.rootdaemonrc Index: rpdutils/inc/rpdp.h o Rename gAuthAllow as gSystemDaemonRc o Rename kDaemonAccess as kDaemonRc Index: rpdutils/src/rpdutils.cxx o Fix compiling problem with namespaces for Kerberos o Define kDaemonRc as .rootdaemonrc (it was daemon.access) o Add support for $HOME/.rootdaemonrc o Add support for daemon dependent access rules o Aestethic changes in CheckAuth (drop commented lines) Index: srputils/src/SRPAuth.cxx o set static flags only when authentication is successful Index: tutorials/TestAuth.C o Test using TFTP instead of TNetFile (faster and runs also with local host fqdn) o Add test for kerberos git-svn-id: http://root.cern.ch/svn/root/trunk@7534 27541ba8-7e3a-0410-8455-c3a389f83636 --- README/README.AUTH | 108 ++++- base/src/TFile.cxx | 10 +- etc/{daemon.access => system.rootdaemonrc} | 16 +- globusauth/src/GlobusAuth.cxx | 4 +- io/src/TFile.cxx | 10 +- krb5auth/inc/Krb5Auth.h | 4 +- krb5auth/src/Krb5Auth.cxx | 25 +- net/inc/THostAuth.h | 8 +- net/src/TAuthenticate.cxx | 154 +++--- net/src/THostAuth.cxx | 74 +-- net/src/TNetFile.cxx | 16 +- proof/inc/TProofServ.h | 4 +- proof/src/TProofServ.cxx | 354 +++++++------- proof/src/TSlave.cxx | 45 +- proofd/src/proofd.cxx | 89 ++-- rootd/src/rootd.cxx | 11 +- rpdutils/inc/rpdp.h | 9 +- rpdutils/src/net.cxx | 9 +- rpdutils/src/rpdutils.cxx | 65 ++- srputils/src/SRPAuth.cxx | 19 +- tutorials/TestAuth.C | 527 +++++++++++---------- 21 files changed, 845 insertions(+), 716 deletions(-) rename etc/{daemon.access => system.rootdaemonrc} (85%) diff --git a/README/README.AUTH b/README/README.AUTH index c1ed0f8a46b..825ca208a52 100644 --- a/README/README.AUTH +++ b/README/README.AUTH @@ -1,14 +1,12 @@ - - Authentication to rootd/proofd servers ====================================== -The rootd/proofd daemon servers accept 6 methods of authentication, listed +The rootd/proofd daemon servers accept 6 methods of authentication, listed in Table 1, together with their internal codes and short names. Method 5 (rfio) is provided for fast access when security is not an issue. -Method 0 is 'secured' by using a session public key, automatically +Method 0 is 'secured' by using a session public key, automatically generated, which allows to avoid direct exchange of passwords; since this -may slow down the process, it can be switched of if not needed. +may slow down the process, it can be switched of if not needed. Table 1: authentication methods available +-------------------------------------------------------------------------+ @@ -28,6 +26,10 @@ $ROOTSYS/etc/system.rootrc), the file $HOME/.rootauthrc (superseded by the variable ROOTAUTHRC, if defined), or during the root session as explained below. +A test macro TestAuth.C is provided under the tutorials directory. Its use +is explained at the end of this file. + + Controlling access ================== @@ -35,10 +37,11 @@ Upon request of access, rootd/proofd build a list of secure methods available locally; the list always comprises UsrPwd; SRP, Kerberos and Globus, are added if ROOT has been compiled with support for them; SSH is added if the 'sshd' daemon is running. By default the two daemons accept authentications only via -the methods in such a list. The administrator of the daemons can, however, +the methods in such a list. The administrator of the daemons can, however, grant access via other authentication methods (or deny any access) by defining -a host specific list in etc/daemon.access (see the example for this file -under etc for more details). +a host specific list in etc/system.rootdaemonrc or $HOME/.rootdaemonrc +(see the example for this file under etc for more details). + Negotiation =========== @@ -51,6 +54,7 @@ the server sends back the list of the remaining methods accepted (if any); the client compares the server list with its own list of remaining methods and makes a new attempt if the overlap of the two lists is not empty; and so on. + Slave/Data servers authentication during a PROOF session ======================================================== @@ -58,8 +62,8 @@ During a PROOF session there is the potential problem of Master/Slave or Slave/Data_Server authentication. For slaves, the list of methods to be tried is specified in the proof.conf file as a list of methods short names. However, before build the corresponding entry in THostAuth (see below) TProofServ checks -that the method can be applied, i.e. that there exist valid credentials. -The way the latters are transmitted depends on the method and on the +that the method can be applied, i.e. that there exist valid credentials. +The way the latters are transmitted depends on the method and on the Client/Master authentication method. * UsrPwd: to authenticate 'usrpwd' to slaves, the master needs the relevant @@ -72,7 +76,7 @@ Client/Master authentication method. in the .netrc or .rootnetrc files; the syntax is the same as for 'clear' authentication with the keyword 'secure' at the place of 'machine'. However, if the client/master authentication was also - 'SRP', the master can receive the password from the client; the + 'SRP', the master can receive the password from the client; the password is sent encrypted with the internal RSA key generated for the session. To use this option, set 'Proofd.SendSRPPwd 1' in your .rootrc (default is 0). @@ -91,7 +95,7 @@ Client/Master authentication method. * UidGid to authenticate 'uidgid' to slaves, the user must have the same (uid,gid) on master and slaves. -Negotiation is active also between master and slaves, so may be a good habit +Negotiation is active also between master and slaves, so may be a good habit to ask for 'uidgid' first to accelerate as possible the authentication process. The method actually used is listed by gProof->Print(). @@ -144,12 +148,12 @@ directives are the following: * The <method>.ReUse directives specify whether root reuse valid authentication once established; possible values are '0' or 'no' for OFF, '1' or 'yes' for ON. - When this option is active, the client generates a session RSA key pair and - transmits the public key to the server; the server generates a session 'token' - which can be used by the client for later access to the server. - This facility is implemented for all methods except UidGid (for which there would + When this option is active, the client generates a session RSA key pair and + transmits the public key to the server; the server generates a session 'token' + which can be used by the client for later access to the server. + This facility is implemented for all methods except UidGid (for which there would be no advantage); it is switched ON by default for UsrPwd, SRP, Globus and SSH, - since it allows to speed up repeated access to the same server. + since it allows to speed up repeated access to the same server. For Krb5 it is implemented but switched OFF by default, since it does not improve on authentication time. @@ -159,7 +163,7 @@ directives are the following: Globus.ReUse: yes SSH.ReUse: 1 - NB: unless 'UsrPwd.Crypt 0' (see below), for UsrPwd the password is always sent + NB: unless 'UsrPwd.Crypt 0' (see below), for UsrPwd the password is always sent encrypted with the session RSA key, even if UsrPwd.ReUse is OFF. * Other directives @@ -375,7 +379,6 @@ classes: methods are the ones listed in meths[nmet]. - TAuthDetails ============ @@ -385,7 +388,74 @@ during the same session. Each THostAuth contains a list of TAuthDetails objects pertaining to {host,user) +TestAuth.C +========== + +This macro is provided to test the authentication methods available. +The macro is located under $ROOTSYS/tutorials. +Before executing it, start a rootd daemon on a separate window + + rootd -d 3 -f + +The "-d 3" option allows to get some debugging info, useful in the +case something goes wrong. + +Then run + + root -q -l $ROOTSYS/tutorials/TestAuth.C + +and answer to the requests for passwords or similar to initialize +credentials. Upon success, you should get at the end something like this + + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + + Result of the tests: + + + + + + Method: 0 (UsrPwd): successful! (reuse: successful!) + + + Method: 1 (SRP): successful! (reuse: successful!) + + + Method: 2 (Krb5): successful! (reuse: successful!) + + + Method: 3 (Globus): successful! (reuse: successful!) + + + Method: 4 (SSH): successful! (reuse: successful!) + + + Method: 5 (UidGid): successful! + + + + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The macro assumes rootd accepting connections on port 1094; if this +is not the case you can pass the port number as the first argument to +the macro. + +The macro assumes hat you are trying to login as yourself to rootd, +ie with the username your are logged in. You may change this passing +a different username "newuser" as second argument. In this case you +have to start rootd from the "newuser" account or as supersuser, +to be avoid access problems. Also, for SSH, make sure that "newuser" +can execute $ROOTSYS/bin/ssh2rpd. + +The macro assumes that the kerberos principal is in the form + + <current_user>@<DEFAULT_REALM> + +where <DEFAULT_REALM> is searched for in the Kerberos conf file +/etc/krb5.conf (or $KRB5_CONFIG). If the principal for the current +user is different, you have to pass it as third argument to TestAuth.C. +Finally, for Globus, if the certicate files and directories are not +standard, you should pass the ones to be used as fourth argument, the +syntax being the same as for $HOME/.rootauthrc . +This is a summary of the arguments to TestAuth.C: + TestAuth.C(<port>,"<user>","<krb5_princ","<globus_det>") + <port> = rootd port (default 1094) + <user> = login user name for the test + (default from getpwuid) + <krb5_princ> = Principal to be used for Krb5 authentication + in the form user@THE.REA.LM + ( default: <running_user@Default_Realm with + Default_realm taken from /etc/krb5.conf + or the $KRB5_CONFIG file ) + <globus_det> = details for the globus authentication + ( default: ad:certificates cd:$HOME/.globus + cf:usercert.pem kf:userkey.pem ) diff --git a/base/src/TFile.cxx b/base/src/TFile.cxx index 8bf55bd381e..fa1da2b5096 100644 --- a/base/src/TFile.cxx +++ b/base/src/TFile.cxx @@ -1,4 +1,4 @@ -// @(#)root/base:$Name: $:$Id: TFile.cxx,v 1.101 2003/09/21 21:38:31 rdm Exp $ +// @(#)root/base:$Name: $:$Id: TFile.cxx,v 1.102 2003/09/27 18:45:45 rdm Exp $ // Author: Rene Brun 28/11/94 /************************************************************************* @@ -1927,10 +1927,16 @@ TFile *TFile::Open(const char *name, Option_t *option, const char *ftitle, if (!strncmp(name, "root:", 5) || !strncmp(name, "roots:", 6) || !strncmp(name, "rootk:", 6)) { + // if the url points to the local user on the localhost + // do not operate network machinery + Bool_t sameUser = kFALSE; TUrl url(name); + UserGroup_t *u = gSystem->GetUserInfo(); + if (u && !strcmp(u->fUser, url.GetUser())) sameUser = kTRUE; + delete u; TInetAddress a(gSystem->GetHostByName(url.GetHost())); TInetAddress b(gSystem->GetHostByName(gSystem->HostName())); - if (strcmp(a.GetHostName(), b.GetHostName())) { + if (strcmp(a.GetHostName(), b.GetHostName()) || !sameUser) { if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) && h->LoadPlugin() == 0) f = (TFile*) h->ExecPlugin(5, name, option, ftitle, compress, netopt); diff --git a/etc/daemon.access b/etc/system.rootdaemonrc similarity index 85% rename from etc/daemon.access rename to etc/system.rootdaemonrc index ffa8c6101ba..4ae3f9cdd0c 100644 --- a/etc/daemon.access +++ b/etc/system.rootdaemonrc @@ -1,8 +1,12 @@ # -# daemon.access This file describes the names of the hosts for which -# the allowed authentication methods are not the default ones -# as specified in system.rootc (if any). -# This file is used by the 'rootd' and 'proofd' daemons. +# $ROOTSYS/etc/system.rootdaemonrc, $HOME/.rootdaemonrc +# This files describe the names of the hosts for which +# the allowed authentication methods are not the default ones +# as specified in system.rootc (if any). +# This file is used by the 'rootd' and 'proofd' daemons. +# +# If existing, $HOME/.rootdaemonrc has priority over +# $ROOTSYS/etc/system.rootdaemonrc # # Format: # - lines starting with '#' are comment lines. @@ -10,6 +14,9 @@ # - hosts can specified either with their FQDN (eg, pcepsft43.cern.ch) or # their IP address (eg 137.138.99.73). # +# - host names can be followed by :rootd or :proofd to define directives +# applying only to the given service +# # - 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' @@ -76,6 +83,7 @@ # lxplus*.cern.ch 4 1 globus 0:ganis:gganis 5 # pcepsft43.cern.ch 4 3 1 5 2 0 # afal57.cern.ch 0 5 4 +# pcep*.cern.ch:rootd 4 1 3 2 5 0 # # Everything allowed from the local host (for testing) # diff --git a/globusauth/src/GlobusAuth.cxx b/globusauth/src/GlobusAuth.cxx index 05319535e3b..f024a41e1c4 100644 --- a/globusauth/src/GlobusAuth.cxx +++ b/globusauth/src/GlobusAuth.cxx @@ -1,4 +1,4 @@ -// @(#)root/globus:$Name: $:$Id: GlobusAuth.cxx,v 1.4 2003/10/07 21:09:55 rdm Exp $ +// @(#)root/globus:$Name: $:$Id: GlobusAuth.cxx,v 1.5 2003/10/22 18:48:36 rdm Exp $ // Author: Gerardo Ganis 15/01/2003 /************************************************************************* @@ -111,7 +111,7 @@ Int_t GlobusAuthenticate(TAuthenticate * Auth, TString & user, protocol = Auth->GetProtocol(); if (gDebug > 2) - Info("GlobusAuthenticate", " enter: %s %s", protocol.Data(), + Info("GlobusAuthenticate", " enter: protocol:'%s' user:'%s'", protocol.Data(), user.Data()); // If we are called for local cleanup, do it and return ... diff --git a/io/src/TFile.cxx b/io/src/TFile.cxx index 8bf55bd381e..fa1da2b5096 100644 --- a/io/src/TFile.cxx +++ b/io/src/TFile.cxx @@ -1,4 +1,4 @@ -// @(#)root/base:$Name: $:$Id: TFile.cxx,v 1.101 2003/09/21 21:38:31 rdm Exp $ +// @(#)root/base:$Name: $:$Id: TFile.cxx,v 1.102 2003/09/27 18:45:45 rdm Exp $ // Author: Rene Brun 28/11/94 /************************************************************************* @@ -1927,10 +1927,16 @@ TFile *TFile::Open(const char *name, Option_t *option, const char *ftitle, if (!strncmp(name, "root:", 5) || !strncmp(name, "roots:", 6) || !strncmp(name, "rootk:", 6)) { + // if the url points to the local user on the localhost + // do not operate network machinery + Bool_t sameUser = kFALSE; TUrl url(name); + UserGroup_t *u = gSystem->GetUserInfo(); + if (u && !strcmp(u->fUser, url.GetUser())) sameUser = kTRUE; + delete u; TInetAddress a(gSystem->GetHostByName(url.GetHost())); TInetAddress b(gSystem->GetHostByName(gSystem->HostName())); - if (strcmp(a.GetHostName(), b.GetHostName())) { + if (strcmp(a.GetHostName(), b.GetHostName()) || !sameUser) { if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) && h->LoadPlugin() == 0) f = (TFile*) h->ExecPlugin(5, name, option, ftitle, compress, netopt); diff --git a/krb5auth/inc/Krb5Auth.h b/krb5auth/inc/Krb5Auth.h index b6ebdf04bd8..d2813f8e003 100644 --- a/krb5auth/inc/Krb5Auth.h +++ b/krb5auth/inc/Krb5Auth.h @@ -1,4 +1,4 @@ -// @(#)root/krb5auth:$Name: $:$Id: Krb5Auth.h,v 1.2 2003/09/29 18:46:14 brun Exp $ +// @(#)root/krb5auth:$Name: $:$Id: Krb5Auth.h,v 1.3 2003/10/28 23:29:24 brun Exp $ // Author: Johannes Muelmenstaedt 17/03/2002 /************************************************************************* @@ -45,7 +45,7 @@ extern "C" { #include <com_err.h> #endif #include <krb5.h> - #if defined(linux)&&!defined(__COM_ERR_H) + #if defined(linux) && !defined(__COM_ERR_H) #include <com_err.h> #endif int krb5_net_read(krb5_context, int, char *, int); // ow ow ow! diff --git a/krb5auth/src/Krb5Auth.cxx b/krb5auth/src/Krb5Auth.cxx index 056e1f5be2e..231d9ad5318 100644 --- a/krb5auth/src/Krb5Auth.cxx +++ b/krb5auth/src/Krb5Auth.cxx @@ -1,4 +1,4 @@ -// @(#)root/krb5auth:$Name: $:$Id: Krb5Auth.cxx,v 1.11 2003/10/22 18:48:36 rdm Exp $ +// @(#)root/krb5auth:$Name: $:$Id: Krb5Auth.cxx,v 1.12 2003/10/27 09:48:35 rdm Exp $ // Author: Johannes Muelmenstaedt 17/03/2002 /************************************************************************* @@ -213,11 +213,11 @@ Int_t Krb5Authenticate(TAuthenticate *auth, TString &user, TString &det, Int_t v strcpy(User,client->data->data); if (gDebug > 3) { - char *Realm = StrDup(client->realm.data); - int k = 0, len = strlen(client->realm.data); - for (k = 0; k < len; k++ ) { if ((int)Realm[k] == 32) Realm[k] = '\0'; } + char *Realm = new char[client->realm.length+1]; + strncpy(Realm,client->realm.data,client->realm.length); + Realm[client->realm.length]= '\0'; Info("Krb5Authenticate", "cc_get_principal: client: %s %s (%d %d)", - client->data->data,Realm, strlen(client->data->data), strlen(Realm)); + client->data->data,Realm, client->data->length, client->realm.length); delete [] Realm; } @@ -319,11 +319,11 @@ Int_t Krb5Authenticate(TAuthenticate *auth, TString &user, TString &det, Int_t v cleanup.server = server; if (gDebug > 3) { - char *Realm = StrDup(server->realm.data); - int k = 0, len = strlen(server->realm.data); - for (k = 0; k < len; k++) { if ((int)Realm[k] == 32) Realm[k] = '\0'; } + char *Realm = new char[server->realm.length+1]; + strncpy(Realm,server->realm.data,server->realm.length); + Realm[server->realm.length]= '\0'; Info("Krb5Authenticate","sname_to_principal: server: %s %s (%d %d)", - server->data->data, Realm, strlen(server->data->data), strlen(Realm)); + server->data->data, Realm, server->data->length, server->realm.length); delete [] Realm; } @@ -381,8 +381,9 @@ Int_t Krb5Authenticate(TAuthenticate *auth, TString &user, TString &det, Int_t v // Send the targetUser name - fprintf(stderr,"client is %s target is %s\n", - User,targetUser.Data()); + if (gDebug > 0) + Info("Krb5Authenticate","client is %s target is %s", + User,targetUser.Data()); sock->Send(targetUser.Data(),kROOTD_KRB5); krb5_data outdata; @@ -523,7 +524,7 @@ void Krb5InitCred(char *ClientPrincipal) if (Krb5Init!=0) delete[] Krb5Init; Krb5Init = "/usr/kerberos/bin/kinit"; } - sprintf(cmd, "%s %s",Krb5Init,ClientPrincipal); + sprintf(cmd, "%s -f %s",Krb5Init,ClientPrincipal); if (gDebug > 2) Info("Krb5InitCred","executing: %s",cmd); gSystem->Exec(cmd); diff --git a/net/inc/THostAuth.h b/net/inc/THostAuth.h index a7730f4d565..48f3ca87907 100644 --- a/net/inc/THostAuth.h +++ b/net/inc/THostAuth.h @@ -1,4 +1,4 @@ -// @(#)root/net:$Name: $:$Id: THostAuth.h,v 1.1 2003/08/29 10:38:19 rdm Exp $ +// @(#)root/net:$Name: $:$Id: THostAuth.h,v 1.2 2003/08/29 17:23:31 rdm Exp $ // Author: G. Ganis 19/03/2003 /************************************************************************* @@ -47,15 +47,15 @@ private: public: - THostAuth(); - THostAuth(const char *host, const char *user, Int_t nmeth, Int_t *authmeth, - char **details); + THostAuth(const char *host = "localhost", const char *user = "", + Int_t nmeth = 0, Int_t *authmeth = 0, char **details = 0); THostAuth(const char *host, const char *user, Int_t authmeth, const char *details); virtual ~THostAuth(); Int_t NumMethods() const { return fNumMethods; } Int_t GetMethods(Int_t meth) const { return fMethods[meth]; } + Bool_t HasMethod(Int_t level); void AddMethod(Int_t level, const char *details); void RemoveMethod(Int_t level); void ReOrder(Int_t nmet, Int_t *fmet); diff --git a/net/src/TAuthenticate.cxx b/net/src/TAuthenticate.cxx index dbafa963281..2646188a594 100644 --- a/net/src/TAuthenticate.cxx +++ b/net/src/TAuthenticate.cxx @@ -1,4 +1,4 @@ -// @(#)root/net:$Name: $:$Id: TAuthenticate.cxx,v 1.25 2003/10/22 18:48:36 rdm Exp $ +// @(#)root/net:$Name: $:$Id: TAuthenticate.cxx,v 1.26 2003/10/27 09:48:35 rdm Exp $ // Author: Fons Rademakers 26/11/2000 /************************************************************************* @@ -125,8 +125,16 @@ TAuthenticate::TAuthenticate(TSocket *sock, const char *remote, } // Check or get user name + 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; @@ -152,7 +160,7 @@ TAuthenticate::TAuthenticate(TSocket *sock, const char *remote, GetAuthInfo()->GetSize()); // Check list of auth info for already loaded info about this host - fHostAuth = GetHostAuth(fqdn,fUser); + fHostAuth = GetHostAuth(fqdn, CheckUser); // If we did not find a good THostAuth instantiation, create one if (fHostAuth == 0) { @@ -198,6 +206,23 @@ TAuthenticate::TAuthenticate(TSocket *sock, const char *remote, if (usr[0]) delete[] usr[0]; } + // If a secific method has been requested via the protocol + // set it as first + Int_t Sec = -1; + if (fProtocol.Contains("roots") || fProtocol.Contains("proofs")) { + Sec = TAuthenticate::kSRP; + } else if (fProtocol.Contains("rootk") || fProtocol.Contains("proofk")) { + Sec = TAuthenticate::kKrb5; + } + if (Sec > -1 && Sec < kMAXSEC) { + if (fHostAuth->HasMethod(Sec)) { + fHostAuth->SetFirst(Sec); + } else { + TString Det(GetDefaultDetails(Sec, 1, CheckUser)); + fHostAuth->SetFirst(Sec, Det); + } + } + // This is what we have in memory if (gDebug > 3) { TIter next(fHostAuth->Established()); @@ -268,6 +293,8 @@ Bool_t TAuthenticate::Authenticate() if (GetUserPasswd(user, passwd, pwhash, (Bool_t &)kFALSE)) return kFALSE; } + fUser = user; + fPasswd = passwd; if (fUser != "root") st = ClearAuth(user, passwd, pwhash); @@ -284,6 +311,8 @@ Bool_t TAuthenticate::Authenticate() if (GetUserPasswd(user, passwd, pwhash, (Bool_t &)kTRUE)) return kFALSE; } + fUser = user; + fPasswd = passwd; if (!fgSecAuthHook) { char *p; @@ -301,6 +330,11 @@ Bool_t TAuthenticate::Authenticate() "no support for SRP authentication available"); return kFALSE; } + // Fill present user info ... + if (st == 1) { + fPwHash = kFALSE; + fSRPPwd = kTRUE; + } } else if (fSecurity == kKrb5) { @@ -675,10 +709,14 @@ void TAuthenticate::SetEnvironment() if (strlen(UsDef) > 0) { fgDefaultUser = UsDef; } else { - UserGroup_t *u = gSystem->GetUserInfo(); - if (u) - fgDefaultUser = u->fUser; - delete u; + if (fgUser != "") { + fgDefaultUser = fgUser; + } else { + UserGroup_t *u = gSystem->GetUserInfo(); + if (u) + fgDefaultUser = u->fUser; + delete u; + } } if (gDebug > 2) @@ -745,11 +783,6 @@ Bool_t TAuthenticate::GetUserPasswd(TString & user, TString & passwd, return 1; } } - // Fill present user info ... - fUser = user; - fPasswd = passwd; - fPwHash = pwhash; - fSRPPwd = srppwd; return 0; } @@ -947,7 +980,7 @@ Bool_t TAuthenticate::GetPromptUser() { // Static method returning the prompt user settings. - return fgDefaultUser; + return fgPromptUser; } //______________________________________________________________________________ @@ -1462,7 +1495,7 @@ Int_t TAuthenticate::GetAuthMeth(const char *Host, const char *Proto, // Space for AuthMeth and Details must be allocated outside // Default method is SSH. - int i; + Int_t i; if (gDebug > 2) ::Info("GetAuthMeth", "enter: h:%s p:%s u:%s (0x%lx 0x%lx) ", @@ -1471,66 +1504,6 @@ Int_t TAuthenticate::GetAuthMeth(const char *Host, const char *Proto, if (*User[0] == 0) *User[0] = StrDup(""); -#if 0 - // If 'host' is ourselves, then use rfio (to setup things correctly) - // Check and save the host FQDN ... - static TString LocalFQDN; - if (!gEnv->GetValue("Test.Auth",0)) { - if (LocalFQDN == "") { - TInetAddress addr = gSystem->GetHostByName(gSystem->HostName()); - if (addr.IsValid()) { - LocalFQDN = addr.GetHostName(); - if (LocalFQDN == "UnNamedHost") - LocalFQDN = addr.GetHostAddress(); - } - } - - - Bool_t SameUser = kFALSE; - UserGroup_t *u = gSystem->GetUserInfo(); - if (u) - if (!strcmp(u->fUser,*User[0])) SameUser = kTRUE; - delete u; - - if (LocalFQDN == Host && SameUser) { - if (gDebug > 3) - ::Info("GetAuthMeth", "remote host is the local one (%s)", - LocalFQDN.Data()); - *NumMeth = new int[1]; - *NumMeth[0] = 1; - AuthMeth[0] = new int[1]; - AuthMeth[0][0] = 5; - Details[0] = new char *[1]; - Details[0][0] = StrDup(Form("pt:0 ru:0 us:%s", *User[0])); - return 1; - } - } -#endif - - // If specific protocol was specified then it has absolute priority ... - if (!strcmp(Proto, "roots") || !strcmp(Proto, "proofs")) { - *NumMeth = new int[1]; - *NumMeth[0] = 1; - AuthMeth[0] = new int[1]; - AuthMeth[0][0] = 1; - Details[0] = new char *[1]; - Details[0][0] = StrDup(Form("pt:%s ru:%s us:%s", - gEnv->GetValue("SRP.LoginPrompt", "no"), - gEnv->GetValue("SRP.ReUse", "0"), - gEnv->GetValue("SRP.Login", *User[0]))); - return 1; - } else if (!strcmp(Proto, "rootk") || !strcmp(Proto, "proofk")) { - *NumMeth = new int[1]; - *NumMeth[0] = 1; - AuthMeth[0] = new int[1]; - AuthMeth[0][0] = 2; - Details[0] = new char *[1]; - Details[0][0] = StrDup(Form("pt:%s ru:%s us:%s", - gEnv->GetValue("Krb5.LoginPrompt", "no"), - gEnv->GetValue("Krb5.ReUse", "0"), - gEnv->GetValue("Krb5.Login", *User[0]))); - return 1; - } // Check then .rootauthrc (if there) char temp[kMAXPATHLEN]; Int_t *am[kMAXSEC], *nh, nu = 0, j = 0; @@ -1694,6 +1667,8 @@ Int_t TAuthenticate::CheckRootAuthrc(const char *Host, char ***user, // Skip comment lines if (line[0] == '#') continue; + if (!strncmp(line,"proofserv",9)) + continue; char *pstr = 0; char *pdef = strstr(line, "default"); sscanf(line,"%s %s",host,info); @@ -2123,7 +2098,7 @@ Bool_t TAuthenticate::CheckHost(const char *Host, const char *host) } } nn++; - } + } // Act accordingly ... if (name == 0) { @@ -2150,6 +2125,17 @@ Bool_t TAuthenticate::CheckHost(const char *Host, const char *host) goto exit; } } + } else { +#if 0 + const char *sp = strstr(Host, host); + if (sp == 0 || sp != Host) { + retval = kFALSE; + goto exit; + } +#else + retval = kFALSE; + goto exit; +#endif } } else { if (!CheckHostWild(Host, host)) { @@ -2491,6 +2477,8 @@ Int_t TAuthenticate::ClearAuth(TString & User, TString & Passwd, Bool_t & PwHash fPasswd = PasHash; fgPwHash = kTRUE; fPwHash = kTRUE; + fSRPPwd = kFALSE; + fgSRPPwd = kFALSE; fSocket->Send("\0", kROOTD_PASS); // Needs this for consistency if (SecureSend(fSocket, 1, PasHash) == -1) { @@ -2504,6 +2492,8 @@ Int_t TAuthenticate::ClearAuth(TString & User, TString & Passwd, Bool_t & PwHash fPasswd = Passwd; fgPwHash = kFALSE; fPwHash = kFALSE; + fSRPPwd = kFALSE; + fgSRPPwd = kFALSE; // Standard technique: invert passwd if (Passwd != "") { @@ -3010,14 +3000,28 @@ THostAuth *TAuthenticate::GetHostAuth(const char *host, const char *user) // Check list of auth info for already loaded info about this host TIter next(GetAuthInfo()); THostAuth *ai; + Bool_t NotFound = kTRUE; while ((ai = (THostAuth *) next())) { if (gDebug > 3) ai->Print("Authenticate:GetHostAuth"); // Use default entry if existing and nothing more specific is found - if (!strcmp(ai->GetHost(),"default")) + if (!strcmp(ai->GetHost(),"default") && NotFound) rHA = ai; + // Check + if (ulen > 0) { + if (CheckHost(lHost,ai->GetHost()) && !strcmp(user, ai->GetUser())) { + rHA = ai; + NotFound = kFALSE; + } + } else { + if (CheckHost(lHost,ai->GetHost())) { + rHA = ai; + NotFound = kFALSE; + } + } + if (ulen > 0) { if (lHost == ai->GetHost() && !strcmp(user, ai->GetUser())) { rHA = ai; diff --git a/net/src/THostAuth.cxx b/net/src/THostAuth.cxx index 947af11c283..6adf0db9550 100644 --- a/net/src/THostAuth.cxx +++ b/net/src/THostAuth.cxx @@ -1,4 +1,4 @@ -// @(#)root/net:$Name: $:$Id: THostAuth.cxx,v 1.3 2003/09/07 18:25:46 rdm Exp $ +// @(#)root/net:$Name: $:$Id: THostAuth.cxx,v 1.4 2003/10/07 14:03:03 rdm Exp $ // Author: G. Ganis 19/03/2003 /************************************************************************* @@ -30,22 +30,9 @@ ClassImp(THostAuth) -//______________________________________________________________________________ -THostAuth::THostAuth(): TObject() -{ - // Default constructor - - fHost = ""; - fUser = ""; - fNumMethods = 0; - fMethods = 0; - fDetails = 0; - fEstablished = 0; -} - //______________________________________________________________________________ THostAuth::THostAuth(const char *host, const char *user, Int_t nmeth, - Int_t *authmeth, char **details) + Int_t *authmeth, char **details) : TObject() { // Create hostauth object. @@ -73,14 +60,23 @@ THostAuth::THostAuth(const char *host, const char *user, Int_t nmeth, } fNumMethods = nmeth; - fMethods = new Int_t[nmeth]; - if (authmeth != 0) { - for (i = 0; i < nmeth; i++) { fMethods[i] = authmeth[i]; } + if (fNumMethods > 0) { + if (authmeth != 0) { + fMethods = new Int_t[fNumMethods]; + for (i = 0; i < nmeth; i++) { + fMethods[i] = authmeth[i]; + } + } else { + fNumMethods = 0; + } } - fDetails = new TString[nmeth]; - if (details) { - for (i = 0; i < nmeth; i++) { - if (details[i]) fDetails[i] = details[i]; + + if (fNumMethods > 0) { + fDetails = new TString[nmeth]; + if (details) { + for (i = 0; i < nmeth; i++) { + if (details[i]) fDetails[i] = details[i]; + } } } fEstablished = new TList; @@ -88,7 +84,7 @@ THostAuth::THostAuth(const char *host, const char *user, Int_t nmeth, //______________________________________________________________________________ THostAuth::THostAuth(const char *host, const char *user, Int_t authmeth, - const char *details) + const char *details) : TObject() { // Create hostauth object with one method only. @@ -216,7 +212,9 @@ const char *THostAuth::GetDetails(Int_t level) int i; for (i = 0; i < fNumMethods; i++) { if (fMethods[i] == level) { - if (gDebug > 3) Info("GetDetails"," %d: returning fDetails[%d]: %s", level,i,fDetails[i].Data()); + if (gDebug > 3) + Info("GetDetails"," %d: returning fDetails[%d]: %s", + level,i,fDetails[i].Data()); return fDetails[i]; } } @@ -224,6 +222,20 @@ const char *THostAuth::GetDetails(Int_t level) return empty; } +//______________________________________________________________________________ +Bool_t THostAuth::HasMethod(Int_t level) +{ + // Return kTRUE if method 'level' is in the list + + int i; + for (i = 0; i < fNumMethods; i++) { + if (fMethods[i] == level) { + return kTRUE; + } + } + return kFALSE; +} + //______________________________________________________________________________ void THostAuth::SetDetails(Int_t level, const char *details) { @@ -258,7 +270,8 @@ void THostAuth::Print(const char *proc) { // Print object content. - Info("Print","%s +------------------------------------------------------------------+",proc); + Info("Print", + "%s +------------------------------------------------------------------+",proc); Info("Print","%s + Host:%s - User:%s - # of available methods:%d", proc, fHost.Data(), fUser.Data(), fNumMethods); int i = 0; @@ -266,15 +279,17 @@ void THostAuth::Print(const char *proc) Info("Print","%s + Method: %d (%s) Details:%s", proc, fMethods[i], TAuthenticate::GetAuthMethod(fMethods[i]), fDetails[i].Data()); } - Info("Print","%s +------------------------------------------------------------------+",proc); + Info("Print", + "%s +------------------------------------------------------------------+",proc); } //______________________________________________________________________________ void THostAuth::PrintEstablished() { - // Print info about estalished authentication vis-a-vis of this Host. + // Print info about established authentication vis-a-vis of this Host. - Info("PrintEstablished","+------------------------------------------------------------------------------+"); + Info("PrintEstablished", + "+------------------------------------------------------------------------------+"); Info("PrintEstablished","+ Host:%s - Number of Established Authentications: %d", fHost.Data(), fEstablished->GetSize()); @@ -285,7 +300,8 @@ void THostAuth::PrintEstablished() while ((ai = (TAuthDetails*) next())) ai->Print("e"); } - Info("PrintEstablished","+------------------------------------------------------------------------------+"); + Info("PrintEstablished", + "+------------------------------------------------------------------------------+"); } //______________________________________________________________________________ diff --git a/net/src/TNetFile.cxx b/net/src/TNetFile.cxx index df41eb7c13e..e5006cec89a 100644 --- a/net/src/TNetFile.cxx +++ b/net/src/TNetFile.cxx @@ -1,4 +1,4 @@ -// @(#)root/net:$Name: $:$Id: TNetFile.cxx,v 1.37 2003/09/21 21:38:31 rdm Exp $ +// @(#)root/net:$Name: $:$Id: TNetFile.cxx,v 1.38 2003/10/22 18:48:36 rdm Exp $ // Author: Fons Rademakers 14/08/97 /************************************************************************* @@ -474,21 +474,9 @@ void TNetFile::ConnectServer(Int_t *stat, EMessageTypes *kind, Int_t netopt, // Authenticate remotely if (gDebug > 2) Info("Authenticate", "User from Url: %s", fUrl.GetUser()); -#if 0 - if (!strcmp(fUrl.GetProtocol(), "roots")) { - auth = new TAuthenticate(fSocket, fUrl.GetHost(), - Form("roots:%d", fProtocol), fUrl.GetUser()); - } else if (!strcmp(fUrl.GetProtocol(), "rootk")) { - auth = new TAuthenticate(fSocket, fUrl.GetHost(), - Form("rootk:%d", fProtocol), fUrl.GetUser()); - } else { - auth = new TAuthenticate(fSocket, fUrl.GetHost(), - Form("rootd:%d", fProtocol), fUrl.GetUser()); - } -#else auth = new TAuthenticate(fSocket, fUrl.GetHost(), Form("%s:%d",fUrl.GetProtocol(),fProtocol), fUrl.GetUser()); -#endif + // Attempt authentication if (!auth->Authenticate()) { Error("TNetFile", "%s authentication failed for host %s", diff --git a/proof/inc/TProofServ.h b/proof/inc/TProofServ.h index f7430f4941a..74a2ba6502a 100644 --- a/proof/inc/TProofServ.h +++ b/proof/inc/TProofServ.h @@ -1,4 +1,4 @@ -// @(#)root/proof:$Name: $:$Id: TProofServ.h,v 1.17 2003/10/07 14:03:03 rdm Exp $ +// @(#)root/proof:$Name: $:$Id: TProofServ.h,v 1.18 2003/10/07 21:09:55 rdm Exp $ // Author: Fons Rademakers 16/02/97 /************************************************************************* @@ -88,7 +88,7 @@ private: Int_t LockPackage() { return LockDir(fPackageLock); } Int_t UnlockPackage() { return UnlockDir(fPackageLock); } Int_t CheckAuth(Int_t sec, char **det); - void ReadProofAuth(); + void RecvHostAuth(); void CollectAuthInfo(); public: diff --git a/proof/src/TProofServ.cxx b/proof/src/TProofServ.cxx index 36143c418c5..0f605a782a0 100644 --- a/proof/src/TProofServ.cxx +++ b/proof/src/TProofServ.cxx @@ -1,4 +1,4 @@ -// @(#)root/proof:$Name: $:$Id: TProofServ.cxx,v 1.57 2003/11/05 18:11:38 rdm Exp $ +// @(#)root/proof:$Name: $:$Id: TProofServ.cxx,v 1.58 2003/11/06 15:08:36 rdm Exp $ // Author: Fons Rademakers 16/02/97 /************************************************************************* @@ -328,6 +328,9 @@ TProofServ::TProofServ(int *argc, char **argv) gProofServ = this; + // Collect authentication info ... + CollectAuthInfo(); + // if master, start slave servers if (IsMaster()) { TString master = "proof://__master__"; @@ -337,9 +340,6 @@ TProofServ::TProofServ(int *argc, char **argv) master += a.GetPort(); } - // Collect authentication info ... - CollectAuthInfo(); - fProof = new TProof(master, fConfFile, fConfDir, fLogLevel); SendLogFile(); } @@ -1468,8 +1468,6 @@ void TProofServ::Setup() gROOT->IsProofServ()) { // We got a file name ... extract the tmp directory path TString KeyFile = lApp->Argv()[3]; - Int_t lTmp = KeyFile.Index("/proofauth", strlen("/proofauth"), 0, TString::kExact); - KeyFile.Resize(lTmp); KeyFile += "/rpk_"; KeyFile += retval; @@ -1520,6 +1518,9 @@ void TProofServ::Setup() delete mess; + // Recv auth info transmitted from the client + RecvHostAuth(); + // deny write access for group and world gSystem->Umask(022); @@ -1703,155 +1704,12 @@ TProofServ *TProofServ::This() return gProofServ; } -//______________________________________________________________________________ -void TProofServ::ReadProofAuth() -{ - // Read the content of a proofauth.xxx file, if exists, create related - // THostAuth and add them to the authInfo list. - - TList *authInfo = 0; - THostAuth *hostAuth = 0; - - PDB(kGlobal,2) Info("ReadProofAuth","enter ..."); - - // Get pointer to list with authentication info - authInfo = TAuthenticate::GetAuthInfo(); - - // Check if we got a file name from the calling process - TApplication *lApp = gROOT->GetApplication(); - if (lApp) { - if (lApp->Argc() > 3) { - // We got a file name ... - char *FilePA = StrDup(lApp->Argv()[3]); - PDB(kGlobal,3) Info("ReadProofAuth","filename is: %s", FilePA); - - // Check accessibility ... - if (!gSystem->AccessPathName(FilePA, kReadPermission)) { - // Now open it - FILE *fpa = fopen(FilePA, "r"); - if (fpa) { - // now read it - char line[1024]; - int i, nmet, meth[kMAXSEC], len; - char *ptr, *pend, *host, *user, *rest, *det[kMAXSEC]; - while (fgets(line, sizeof(line),fpa)) { - // Reset entry - for (i = 0; i < kMAXSEC; i++) { meth[i]= -1; det[i]= 0; } - // get read of CR ... if any - if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; - // Now decode - rest = new char[strlen(line)+1]; rest[0]='\0'; - ptr = line; - - host = new char[strlen(line)+1]; host[0]='\0'; - sscanf(ptr+2, "%s %s", host, rest); - ptr = strstr(ptr, rest); - - user = new char[strlen(line)+1]; user[0]='\0'; - sscanf(ptr+2, "%s %s", user, rest); - if (!strcmp(user, "any")) user[0] = '\0'; - ptr = strstr(ptr, rest); - - sscanf(ptr+2, "%d %s", &nmet, rest); - PDB(kGlobal,3) - Info("ReadProofAuth","host user nmet: %s %s %d",host,user,nmet); - - ptr = strstr(ptr, rest); - for (i = 0; i < nmet; i++) { - sscanf(ptr+1, "%d %s", &meth[i], rest); - ptr = strstr(ptr, rest); - - PDB(kGlobal,3) Info("ReadProofAuth","meth[%d]: %d (%s)",i,meth[i]); - - pend = strstr(ptr+1,"'"); - len = pend-ptr; - det[i] = new char[len+5]; - strncpy(det[i], ptr, len); - det[i][len]='\0'; - // Turn off prompt - char *ppt = strstr(det[i], "pt:"); - if (ppt) { - if (!strncmp(ppt+3,"yes",3)) { - ppt[3]='n'; ppt[4]='o'; ppt[5]=' '; - } - if (!strncmp(ppt+3,"1",1)) { - ppt[3]='0'; - } - } - PDB(kGlobal,3) Info("ReadProofAuth", "det[%d]: %s",i,det[i]); - ptr = strstr(pend+1, "'"); - } - // Check if a HostAuth object for this (host,user) pair already exists - hostAuth = TAuthenticate::GetHostAuth(host,user); - if (!hostAuth) { - // Create HostAuth object ... - hostAuth = new THostAuth(host,user,nmet,meth,(char **)det); - PDB(kGlobal,3) hostAuth->Print(); - - // ... and add it to the list (static in TAuthenticate) - authInfo->Add(hostAuth); - } else { - PDB(kGlobal,3) { - Info("ReadProofAuth", "updating existing THostAuth for (%s,%s)",host,user); - hostAuth->Print(); - } - - int nold = hostAuth->NumMethods(); - int i,j; - for (i = 0; i < nmet; i++ ) { - int jm = -1; - for (j = 0; j < nold; j++ ) { - if (meth[i] == hostAuth->GetMethods(j)) { - jm= j; break; - } - } - if (jm == -1) { - // Add a method ... - hostAuth->AddMethod(meth[i], det[i]); - } else { - // Set a new details string ... - hostAuth->SetDetails(meth[i], det[i]); - } - } - } - // Delete allocate memory - if (host) delete[] host; - if (user) delete[] user; - if (rest) delete[] rest; - for (i = 0; i < kMAXSEC; i++) { - if (det[i]) delete[] det[i]; - det[i] = 0; meth[i] = -1; - } - nmet = 0; - } - // Close the file - fclose(fpa); - // Unlink (=delete) the file - gSystem->Unlink(FilePA); - } else { - PDB(kGlobal,3) - Info("ReadProofAuth","file %s cannot be opened", FilePA); - } - } else { - PDB(kGlobal,3) - Info("ReadProofAuth","file %s either non existing or not readable", FilePA); - } - delete [] FilePA; - } else { - PDB(kGlobal,3) - Info("ReadProofAuth","no file name received from calling process"); - } - } else { - PDB(kGlobal,3) Info("ReadProofAuth","unable to access calling arguments"); - } -} - //______________________________________________________________________________ void TProofServ::CollectAuthInfo() { // Collect information needed for authentication to slaves. - // Sources are proof.conf and proofauth.xxx files. - // THostAuth objects are created accordingly and added to the authInfo list. + // Source is proof.conf and THostAuth objects are created accordingly + // and added to the authInfo list. TList *authInfo = 0; THostAuth *hostAuth = 0; @@ -1873,7 +1731,7 @@ void TProofServ::CollectAuthInfo() for (i = 0; i < kMAXSEC; i++){ if (i == 0 && fUser != "" && fPasswd != "") { AuthAvailable[i] = 1; - AuthDet[i] = StrDup(Form("pt:0 ru:0 us:%s", fUser.Data())); + AuthDet[i] = StrDup(Form("pt:0 ru:1 us:%s", fUser.Data())); } else { AuthAvailable[i] = CheckAuth(i, &AuthDet[i]); } @@ -2031,29 +1889,13 @@ void TProofServ::CollectAuthInfo() PDB(kGlobal,3) hostAuth->Print(); } -#if 0 - // If 'host' is ourselves, then use rfio (to setup things correctly) - // Check and save the host FQDN ... - static TString LocalFqdn; - if (LocalFqdn == "") { - TInetAddress addr = gSystem->GetHostByName(gSystem->HostName()); - if (addr.IsValid()) { - LocalFqdn = addr.GetHostName(); - if (LocalFqdn == "UnNamedHost") - LocalFqdn = addr.GetHostAddress(); - } - } - if (SlaveFqdn == LocalFqdn || SlaveFqdn.Contains("localhost")) - hostAuth->SetFirst((int)TAuthenticate::kRfio); -#endif - // CleanUp memory int ks; for (ks = 0; ks < nSecs; ks++) { if (fDets[ks]) delete[] fDets[ks]; } - } // strcmp "slave" - } // fgets + } // strcmp "slave" + } // fgets } // fopen // close file @@ -2097,22 +1939,16 @@ void TProofServ::CollectAuthInfo() for (Int_t ks = 0; ks < 2; ks++) { if (fDets[ks]) delete[] fDets[ks]; } - - // Read info transmitted from the client ... - ReadProofAuth(); } - //______________________________________________________________________________ Int_t TProofServ::CheckAuth(Int_t cSec, char **Det) { // Check if the authentication method can be attempted for the client. - const char sshid[3][20] = { ".ssh/identity", ".ssh/id_dsa", ".ssh/id_rsa" }; - const char netrc[2][20] = { ".netrc", ".rootnetrc" }; + const char sshid[3][20] = { "/.ssh/identity", "/.ssh/id_dsa", "/.ssh/id_rsa" }; + const char netrc[2][20] = { "/.netrc", "/.rootnetrc" }; Int_t ok = 0; - char *home = 0; - char *infofile = 0; char *details = 0; char *user = 0; @@ -2122,17 +1958,16 @@ Int_t TProofServ::CheckAuth(Int_t cSec, char **Det) user = StrDup(pw->fUser); delete pw; } else { - Info("CheckAuth", "not properly logged on (getpwuid unable to find relevant info)!"); + Info("CheckAuth", + "not properly logged on (getpwuid unable to find relevant info)!"); return ok; } // UsrPwd if (cSec == (Int_t) TAuthenticate::kClear) { - home = StrDup(getenv("HOME")); - infofile = new char[sizeof(home)+25]; Int_t i; for (i = 0; i < 2; i++) { - sprintf(infofile,"%s/%s",home,netrc[i]); + TString infofile = TString(gSystem->HomeDirectory())+TString(netrc[i]); if (!gSystem->AccessPathName(infofile, kReadPermission)) ok = 1; } if (ok == 1) { @@ -2205,11 +2040,9 @@ Int_t TProofServ::CheckAuth(Int_t cSec, char **Det) // SSH if (cSec == (Int_t) TAuthenticate::kSSH) { - home = StrDup(getenv("HOME")); - infofile = new char[sizeof(home)+25]; int i; for (i = 0; i < 3; i++) { - sprintf(infofile,"%s/%s",home,sshid[i]); + TString infofile = TString(gSystem->HomeDirectory())+TString(sshid[i]); if (!gSystem->AccessPathName(infofile,kReadPermission)) ok = 1; } if (ok == 1) { @@ -2228,10 +2061,6 @@ Int_t TProofServ::CheckAuth(Int_t cSec, char **Det) // Fill output, if relevant ... if (details) { *Det= StrDup(details); delete [] details; } - // CleanUp remaining stuff ... - if (home) delete [] home; - if (infofile) delete [] infofile; - PDB(kGlobal,3) { if (ok == 1) { Info("CheckAuth","meth: %d ... is available: details: %s", cSec, *Det); @@ -2243,3 +2072,150 @@ Int_t TProofServ::CheckAuth(Int_t cSec, char **Det) // return return ok; } + +//______________________________________________________________________________ +void TProofServ::RecvHostAuth() +{ + // Receive from TSlave directives for future authentications, create related + // THostAuth and add them to the authInfo list. + + TList *authInfo = 0; + THostAuth *hostAuth = 0; + + PDB(kGlobal,2) Info("RecvHostAuth", "enter ..."); + + // Get pointer to list with authentication info + authInfo = TAuthenticate::GetAuthInfo(); + + // Receive buffer + Int_t kind; + const Int_t kBUF = 2048; + char buf[kBUF]; + Int_t nr = fSocket->Recv(buf, kBUF, kind); + if (nr < 0 || kind != kPROOF_SENDHOSTAUTH) { + Error("RecvHostAuth", "received: kind: %d (%d bytes)", kind, nr); + return; + } + PDB(kGlobal,2) + Info("RecvHostAuth", "received: (%d bytes) %s", nr, buf); + char rest[kBUF], host[kBUF], user[kBUF]; + Int_t i, nmet, meth[kMAXSEC], len; + char *ptr = 0, *pend = 0, *det[kMAXSEC] = {0}; + while (strcmp(buf, "END")) { + // Clean buffer + Int_t nc = (nr < kBUF)? nr : kBUF ; + buf[nc] = '\0'; + + // Init + rest[0] = '\0'; + host[0] = '\0'; + user[0] = '\0'; + + // Now decode + ptr = strstr(buf, "h:"); // The host string begins with "h:" + sscanf(ptr+2, "%s %s", host, rest); + + ptr = strstr(ptr, "u:"); // The user string begins with "u:" + sscanf(ptr+2, "%s %s", user, rest); + if (!strcmp(user, "any")) user[0] = '\0'; + + ptr = strstr(ptr, "n:"); // Methods info begins with "n:" + sscanf(ptr+2, "%d %s", &nmet, rest); + + // Notify if required + PDB(kGlobal,3) + Info("RecvHostAuth", "host user nmet: %s %s %d", host, user, nmet); + + // Details for methods should follow in the form of single-quote + // delimited strings with method number and details, eg + // '0 pt:0 ru:1 us:qwerty' + ptr = strstr(ptr, rest); + for (i = 0; i < nmet; i++) { + + // First the method number ... + sscanf(ptr+1, "%d %s", &meth[i], rest); + PDB(kGlobal,3) + Info("RecvHostAuth", "meth[%d]: %d (%s)", i, meth[i]); + + // ... then the details + ptr = strstr(ptr, rest); + pend = strstr(ptr+1, "'"); + len = pend-ptr; + det[i] = new char[len+5]; + strncpy(det[i], ptr, len); + det[i][len] = '\0'; + // Make sure that prompt is off + char *ppt = strstr(det[i], "pt:"); + if (ppt) { + if (!strncasecmp(ppt+3, "yes", 3)) { + ppt[3] = 'n'; ppt[4] = 'o'; ppt[5] = ' '; + } + if (!strncmp(ppt+3, "1", 1)) { + ppt[3] = '0'; + } + } + PDB(kGlobal,3) + Info("RecvHostAuth", "det[%d]: %s", i, det[i]); + ptr = strstr(pend+1, "'"); + } + + // Check if a HostAuth object for this (host,user) pair already exists + hostAuth = TAuthenticate::GetHostAuth(host, user); + if (!hostAuth || strcmp(hostAuth->GetHost(), host)) { + // Create HostAuth object ... + hostAuth = new THostAuth(host, user, nmet, meth, (char **)det); + PDB(kGlobal,3) hostAuth->Print(); + + // ... and add it to the list (static in TAuthenticate) + authInfo->Add(hostAuth); + } else { + PDB(kGlobal,3) { + Info("RecvHostAuth", "updating existing THostAuth for (%s,%s)", host, user); + hostAuth->Print(); + } + + Int_t nold = hostAuth->NumMethods(); + Int_t i,j; + // We add new methods or update details; in any case the + // should be the one we have found, so we start from the + // last ... + for (i = nmet-1; i > -1; i-- ) { + int jm = -1; + for (j = 0; j < nold; j++ ) { + if (meth[i] == hostAuth->GetMethods(j)) { + jm = j; + break; + } + } + if (jm == -1) { + // Add method as first ... + hostAuth->SetFirst(meth[i], det[i]); + } else { + // Set method as first ... + hostAuth->SetFirst(meth[i]); + // ... and update details string + hostAuth->SetDetails(meth[i], det[i]); + } + } + } + // Delete allocate memory + for (i = 0; i < kMAXSEC; i++) { + if (det[i]) + delete[] det[i]; + det[i] = 0; + meth[i] = -1; + } + nmet = 0; + ptr = 0; + pend = 0; + + // Get the next one + nr = fSocket->Recv(buf, kBUF, kind); + if (nr < 0 || kind != kPROOF_SENDHOSTAUTH) { + Info("RecvHostAuth","Error: received: kind: %d (%d bytes)", kind, nr); + return; + } + PDB(kGlobal,2) + Info("RecvHostAuth"," received: (%d bytes) %s", nr, buf); + } +} diff --git a/proof/src/TSlave.cxx b/proof/src/TSlave.cxx index 9f35ec66348..1ff5489e100 100644 --- a/proof/src/TSlave.cxx +++ b/proof/src/TSlave.cxx @@ -1,4 +1,4 @@ -// @(#)root/proof:$Name: $:$Id: TSlave.cxx,v 1.18 2003/10/07 14:03:03 rdm Exp $ +// @(#)root/proof:$Name: $:$Id: TSlave.cxx,v 1.19 2003/10/07 21:09:55 rdm Exp $ // Author: Fons Rademakers 14/02/97 /************************************************************************* @@ -116,14 +116,6 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf, Info("TSlave", "Remote Client: fUser is .... %s", proof->fUser.Data()); } - if (ProofdProto > 6) { - // Now we send authentication details to access, eg, data servers - // not in the proof cluster and to be propagated to slaves. - // This is triggered by the 'proofserv <dserv1> <dserv2> ...' - // card in .rootauthrc - SendHostAuth(this, 0); - } - } else { // we are a master server... authenticate either: @@ -164,10 +156,6 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf, auth->GetHostAuth()->PrintEstablished(); Info("TSlave", "Master Server: fUser is .... %s", fUser.Data()); } - - if (ProofdProto > 6) { - SendHostAuth(this, 1); - } } // fSecurity is the method successfully tried ... @@ -211,10 +199,18 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf, TString passwd = ""; Bool_t pwhash = kFALSE; Bool_t srppwd = kFALSE; + Bool_t sndsrp = kFALSE; - if (!fProof->IsMaster() && - (fSecurity == TAuthenticate::kClear || - (fSecurity == TAuthenticate::kSRP && gEnv->GetValue("Proofd.SendSRPPwd",0)))) { + if (!fProof->IsMaster()) { + if (gEnv->GetValue("Proofd.SendSRPPwd",0)) + sndsrp = kTRUE; + } else { + if (fProof->fSRPPwd && fProof->fPasswd != "") + sndsrp = kTRUE; + } + + if (fSecurity == TAuthenticate::kClear || + (fSecurity == TAuthenticate::kSRP && sndsrp)) { // Send offset to identify remotely the public part of RSA key fSocket->Send(RemoteOffSet,kROOTD_RSAKEY); @@ -240,7 +236,7 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf, TMessage mess; mess << passwd; fSocket->Send(mess); - } + } } else { @@ -251,12 +247,23 @@ TSlave::TSlave(const char *host, Int_t port, Int_t ord, Int_t perf, TMessage mess; if (!fProof->IsMaster()) - mess << fProof->fUser << pwhash << srppwd << fProof->fConfFile; + mess << fProof->fUser << pwhash << srppwd << fProof->fConfFile; else - mess << fProof->fUser << pwhash << srppwd << fOrdinal; + mess << fProof->fUser << pwhash << srppwd << fOrdinal; fSocket->Send(mess); + if (ProofdProto > 6) { + // Now we send authentication details to access, eg, data servers + // not in the proof cluster and to be propagated to slaves. + // This is triggered by the 'proofserv <dserv1> <dserv2> ...' + // card in .rootauthrc + if (!fProof->IsMaster()) + SendHostAuth(this, 0); + else + SendHostAuth(this, 1); + } + // set some socket options fSocket->SetOption(kNoDelay, 1); } diff --git a/proofd/src/proofd.cxx b/proofd/src/proofd.cxx index c9c718210ad..26a3761c393 100644 --- a/proofd/src/proofd.cxx +++ b/proofd/src/proofd.cxx @@ -1,4 +1,4 @@ -// @(#)root/proofd:$Name: $:$Id: proofd.cxx,v 1.51 2003/10/27 09:48:35 rdm Exp $ +// @(#)root/proofd:$Name: $:$Id: proofd.cxx,v 1.52 2003/10/28 16:32:43 rdm Exp $ // Author: Fons Rademakers 02/02/97 /************************************************************************* @@ -235,7 +235,6 @@ int gDebug = 0; int gForegroundFlag = 0; int gInetdFlag = 0; int gMaster =-1; -int gPort = 0; int gProtocol = 8; // increase when protocol changes char gRcFile[kMAXPATHLEN] = { 0 }; int gRootLog = 0; @@ -704,16 +703,18 @@ void Authenticate() gAuthListSent = 1; goto next; } else { - Error(ErrFatal,kErrNotAllowed, "Authenticate: method not in the list sent to the client"); + Error(ErrFatal,kErrNotAllowed, + "Authenticate: method not in the list sent to the client"); } } else - Error(ErrFatal,kErrConnectionRefused, "Authenticate: connection refused from host %s", gOpenHost); + Error(ErrFatal,kErrConnectionRefused, + "Authenticate: connection refused from host %s", gOpenHost); } // Then check if a previous authentication exists and is valid // ReUse does not apply for RFIO if (kind != kROOTD_RFIO && ProofdReUseAuth(recvbuf, kind)) - goto recvauth; + goto next; } switch (kind) { @@ -753,7 +754,8 @@ void Authenticate() if (gClientProtocol > 8) { if (gDebug > 2) - ErrorInfo("Authenticate: here we are: kind:%d -- Meth:%d -- gAuth:%d -- gNumLeft:%d", kind, Meth, gAuth, gNumLeft); + ErrorInfo("Authenticate: kind:%d -- Meth:%d -- gAuth:%d -- gNumLeft:%d", + kind, Meth, gAuth, gNumLeft); // If authentication failure, check if other methods could be tried ... if ((Meth != -1 || kind==kROOTD_PASS) && gAuth == 0) { @@ -768,39 +770,6 @@ void Authenticate() } } -recvauth: - // If authentication successfull, receive info for later authentications - if (gAuth == 1 && gClientProtocol > 8) { - - sprintf(gFilePA, "%s/proofauth.%ld", gTmpDir, (long)getpid()); - if (gDebug > 2) ErrorInfo("Authenticate: file with hostauth info is: %s", gFilePA); - - FILE *fpa = fopen(gFilePA, "w"); - if (fpa == 0) { - ErrorInfo("Authenticate: error creating file: %s", gFilePA); - goto next; - } - - // Receive buffer - EMessageTypes kindauth; - int nr = NetRecv(recvbuf, kMaxBuf, kindauth); - if (nr < 0 || kindauth != kPROOF_SENDHOSTAUTH) - ErrorInfo("Authenticate: SENDHOSTAUTH: received: %d (%d bytes)", kindauth, nr); - if (gDebug > 2) ErrorInfo("Authenticate: received: (%d) %s", nr, recvbuf); - while (strcmp(recvbuf, "END")) { - // Clean buffer - recvbuf[nr+1] = '\0'; - // Write it to file - fprintf(fpa, "%s\n", recvbuf); - // Get the next one - nr = NetRecv(recvbuf, kMaxBuf, kindauth); - if (nr < 0 || kindauth != kPROOF_SENDHOSTAUTH) - ErrorInfo("Authenticate: SENDHOSTAUTH: received: %d (%d bytes)", kindauth, nr); - if (gDebug > 2) ErrorInfo("Authenticate: received: (%d) %s", nr, recvbuf); - } - // Close suth file - fclose(fpa); - } next: continue; } @@ -1007,7 +976,7 @@ void ProofdExec() argvv[0] = arg0; argvv[1] = (char *)(gMaster ? "proofserv" : "proofslave"); argvv[2] = gConfDir; - argvv[3] = gFilePA; + argvv[3] = gTmpDir; argvv[4] = gOpenHost; sprintf(rpid, "%d", gRemPid); argvv[5] = rpid; @@ -1130,8 +1099,10 @@ int main(int argc, char **argv) case 'b': if (--argc <= 0) { if (!gInetdFlag) - fprintf(stderr, "-b requires a buffersize in bytes as argument\n"); - Error(ErrFatal, -1, "-b requires a buffersize in bytes as argument"); + fprintf(stderr, + "-b requires a buffersize in bytes as argument\n"); + Error(ErrFatal, -1, + "-b requires a buffersize in bytes as argument"); } tcpwindowsize = atoi(*++argv); break; @@ -1139,8 +1110,10 @@ int main(int argc, char **argv) case 'T': if (--argc <= 0) { if (!gInetdFlag) - fprintf(stderr, "-T requires a dir path for temporary files [/usr/tmp]\n"); - Error(ErrFatal, kErrFatal, "-T requires a dir path for temporary files [/usr/tmp]"); + fprintf(stderr, + "-T requires a dir path for temporary files [/usr/tmp]\n"); + Error(ErrFatal, kErrFatal, + "-T requires a dir path for temporary files [/usr/tmp]"); } sprintf(gTmpDir, "%s", *++argv); break; @@ -1148,8 +1121,10 @@ int main(int argc, char **argv) case 's': if (--argc <= 0) { if (!gInetdFlag) - fprintf(stderr, "-s requires as argument a port number for the sshd daemon\n"); - Error(ErrFatal, kErrFatal, "-s requires as argument a port number for the sshd daemon"); + fprintf(stderr, + "-s requires as argument a port number for the sshd daemon\n"); + Error(ErrFatal, kErrFatal, + "-s requires as argument a port number for the sshd daemon"); } gSshdPort = atoi(*++argv); break; @@ -1184,8 +1159,10 @@ int main(int argc, char **argv) case 'C': if (--argc <= 0) { if (!gInetdFlag) - fprintf(stderr, "-C requires a file name for the host certificates file location\n"); - Error(ErrFatal, -1, "-C requires a file name for the host certificates file location"); + fprintf(stderr, + "-C requires a file name for the host certificates file location\n"); + Error(ErrFatal, -1, + "-C requires a file name for the host certificates file location"); } sprintf(gHostCertConf, "%s", *++argv); break; @@ -1214,15 +1191,17 @@ int main(int argc, char **argv) strncpy(gConfDir, *argv, kMAXPATHLEN-1); gConfDir[kMAXPATHLEN-1] = 0; sprintf(gExecDir, "%s/bin", gConfDir); - sprintf(gAuthAllow, "%s/etc/%s", gConfDir, kDaemonAccess); + sprintf(gSystemDaemonRc, "%s/etc/system%s", gConfDir, kDaemonRc); } else { // try to guess the config directory... #ifndef ROOTPREFIX if (getenv("ROOTSYS")) { strcpy(gConfDir, getenv("ROOTSYS")); sprintf(gExecDir, "%s/bin", gConfDir); - sprintf(gAuthAllow, "%s/etc/%s", gConfDir, kDaemonAccess); - if (gDebug > 0) ErrorInfo("main: no config directory specified using ROOTSYS (%s)", gConfDir); + sprintf(gSystemDaemonRc, "%s/etc/system%s", gConfDir, kDaemonRc); + if (gDebug > 0) + ErrorInfo("main: no config directory specified using ROOTSYS (%s)", + gConfDir); } else { if (!gInetdFlag) fprintf(stderr, "proofd: no config directory specified\n"); @@ -1235,7 +1214,7 @@ int main(int argc, char **argv) strcpy(gExecDir, ROOTBINDIR); #endif #ifdef ROOTETCDIR - sprintf(gAuthAllow, "%s/%s", ROOTETCDIR, kDaemonAccess); + sprintf(gSystemDaemonRc, "%s/system%s", ROOTETCDIR, kDaemonRc); #endif } @@ -1244,8 +1223,10 @@ int main(int argc, char **argv) sprintf(arg0, "%s/bin/proofserv", gConfDir); if (access(arg0, X_OK) == -1) { if (!gInetdFlag) - fprintf(stderr, "proofd: incorrect config directory specified (%s)\n", gConfDir); - Error(ErrFatal, -1, "main: incorrect config directory specified (%s)", gConfDir); + fprintf(stderr, + "proofd: incorrect config directory specified (%s)\n", gConfDir); + Error(ErrFatal, -1, + "main: incorrect config directory specified (%s)", gConfDir); } // Log to stderr if not started as daemon ... diff --git a/rootd/src/rootd.cxx b/rootd/src/rootd.cxx index 41602cbef2c..eb613e51fe0 100644 --- a/rootd/src/rootd.cxx +++ b/rootd/src/rootd.cxx @@ -1,4 +1,4 @@ -// @(#)root/rootd:$Name: $:$Id: rootd.cxx,v 1.67 2003/10/27 09:48:35 rdm Exp $ +// @(#)root/rootd:$Name: $:$Id: rootd.cxx,v 1.68 2003/10/28 16:32:43 rdm Exp $ // Author: Fons Rademakers 11/08/97 /************************************************************************* @@ -2359,7 +2359,7 @@ int main(int argc, char **argv) strncpy(gConfDir, *argv, kMAXPATHLEN-1); gConfDir[kMAXPATHLEN-1] = 0; sprintf(gExecDir, "%s/bin", gConfDir); - sprintf(gAuthAllow, "%s/etc/%s", gConfDir, kDaemonAccess); + sprintf(gSystemDaemonRc, "%s/etc/system%s", gConfDir, kDaemonRc); } else { // try to guess the config directory... #ifndef ROOTPREFIX @@ -2367,7 +2367,7 @@ int main(int argc, char **argv) if (getenv("ROOTSYS")) { strcpy(gConfDir, getenv("ROOTSYS")); sprintf(gExecDir, "%s/bin", gConfDir); - sprintf(gAuthAllow, "%s/etc/%s", gConfDir, kDaemonAccess); + sprintf(gSystemDaemonRc, "%s/etc/system%s", gConfDir, kDaemonRc); if (gDebug > 0) ErrorInfo("main: no config directory specified using ROOTSYS (%s)", gConfDir); } else { if (!gInetdFlag) @@ -2382,7 +2382,7 @@ int main(int argc, char **argv) strcpy(gExecDir, ROOTBINDIR); #endif #ifdef ROOTETCDIR - sprintf(gAuthAllow, "%s/%s", ROOTETCDIR, kDaemonAccess); + sprintf(gSystemDaemonRc, "%s/system%s", ROOTETCDIR, kDaemonRc); #endif } @@ -2392,7 +2392,8 @@ int main(int argc, char **argv) // Also initialize the network connection - create the socket // and bind our well-know address to it. - int fdkeep = NetInit(gService, gPort1, gPort2, tcpwindowsize); + gPort = gPort1; + int fdkeep = NetInit(gService, gPort, gPort2, tcpwindowsize); if (!gForegroundFlag) DaemonStart(1, fdkeep, kROOTD); } diff --git a/rpdutils/inc/rpdp.h b/rpdutils/inc/rpdp.h index 78fef34f057..f9d638e0efc 100644 --- a/rpdutils/inc/rpdp.h +++ b/rpdutils/inc/rpdp.h @@ -1,4 +1,4 @@ -// @(#)root/rpdutils:$Name: $:$Id: rpdp.h,v 1.6 2003/10/07 14:03:03 rdm Exp $ +// @(#)root/rpdutils:$Name: $:$Id: rpdp.h,v 1.7 2003/10/22 18:48:36 rdm Exp $ // Author: Gerardo Ganis 7/4/2003 /************************************************************************* @@ -62,6 +62,7 @@ extern int gNumAllow; extern int gNumLeft; extern int gOffSet; extern int gParallel; +extern int gPort; extern int gRemPid; extern int gReUseAllow; extern int gReUseRequired; @@ -71,7 +72,7 @@ extern int gSshdPort; extern char gAltSRPPass[kMAXPATHLEN]; extern char gAnonUser[64]; -extern char gAuthAllow[kMAXPATHLEN]; +extern char gSystemDaemonRc[kMAXPATHLEN]; extern char gExecDir[kMAXPATHLEN]; // for use in rootd ... extern char gFile[kMAXPATHLEN]; extern char gFileLog[kMAXPATHLEN]; @@ -84,7 +85,7 @@ extern char gUser[64]; extern char gPasswd[64]; // only used for anonymous access extern const char *kAuthMeth[kMAXSEC]; // authentication method list -extern const char kDaemonAccess[]; // file containing daemon access rules +extern const char kDaemonRc[]; // file containing daemon access rules extern SigPipe_t gSigPipeHook; @@ -124,7 +125,7 @@ int NetRecv(char *msg, int max); int NetOpen(int inetdflag, EService service); void NetClose(); const char *NetRemoteHost(); -int NetInit(const char *service, int port1, int port2, int tcpwindowsize); +int NetInit(const char *service, int &port1, int port2, int tcpwindowsize); void NetInit(const char *service, int port, int tcpwindowsize); void NetSetOptions(EService service, int sock, int tcpwindowsize); diff --git a/rpdutils/src/net.cxx b/rpdutils/src/net.cxx index 5b4442a6a9b..a1a9c9f7785 100644 --- a/rpdutils/src/net.cxx +++ b/rpdutils/src/net.cxx @@ -1,4 +1,4 @@ -// @(#)root/rpdutils:$Name: $:$Id: net.cxx,v 1.16 2002/10/28 14:22:51 rdm Exp $ +// @(#)root/rpdutils:$Name: $:$Id: net.cxx,v 1.1 2003/08/29 10:38:19 rdm Exp $ // Author: Fons Rademakers 12/08/97 /************************************************************************* @@ -415,7 +415,7 @@ void NetClose() } //______________________________________________________________________________ -int NetInit(const char *service, int port1, int port2, int tcpwindowsize) +int NetInit(const char *service, int &port1, int port2, int tcpwindowsize) { // Initialize the network connection for the server, when it has *not* // been invoked by inetd. Used by rootd. @@ -474,6 +474,7 @@ int NetInit(const char *service, int port1, int port2, int tcpwindowsize) } printf("ROOTD_PORT=%d\n", port); + port1 = port; // And set the listen parameter, telling the system that we're // ready to accept incoming connection requests. @@ -539,7 +540,9 @@ void NetInit(const char *service, int port, int tcpwindowsize) if (bind(tcp_srv_sock, (struct sockaddr *) &tcp_srv_addr, sizeof(tcp_srv_addr)) < 0) - Error(gErrSys,-1,"NetInit: can't bind local address (sock: %d) : errno: %d",tcp_srv_sock,GetErrno()); + Error(gErrSys,-1, + "NetInit: can't bind local address (sock: %d) : errno: %d", + tcp_srv_sock,GetErrno()); // And set the listen parameter, telling the system that we're // ready to accept incoming connection requests. diff --git a/rpdutils/src/rpdutils.cxx b/rpdutils/src/rpdutils.cxx index 1d6d38aa389..80c37765118 100644 --- a/rpdutils/src/rpdutils.cxx +++ b/rpdutils/src/rpdutils.cxx @@ -1,4 +1,4 @@ -// @(#)root/rpdutils:$Name: $:$Id: rpdutils.cxx,v 1.21 2003/10/27 17:46:17 rdm Exp $ +// @(#)root/rpdutils:$Name: $:$Id: rpdutils.cxx,v 1.22 2003/10/28 16:32:43 rdm Exp $ // Author: Gerardo Ganis 7/4/2003 /************************************************************************* @@ -192,7 +192,7 @@ const char *kAuthMeth[kMAXSEC] = { "UsrPwd", "SRP", "Krb5", "Globus", "SSH", "Ui const char kMethods[] = "usrpwd srp krb5 globus ssh uidgid"; const char kRootdPass[] = ".rootdpass"; const char kSRootdPass[] = ".srootdpass"; -const char kDaemonAccess[] = "daemon.access"; // file containing daemon access rules +const char kDaemonRc[] = ".rootdaemonrc"; // file containing daemon access rules // To control user access char *gUserAllow[kMAXSEC] = { 0 }; @@ -202,7 +202,7 @@ unsigned int gUserIgnLen[kMAXSEC] = { 0 }; char gAltSRPPass[kMAXPATHLEN] = { 0 }; char gAnonUser[64] = "rootd"; -char gAuthAllow[kMAXPATHLEN] = { 0 }; // path to kDaemonAccess +char gSystemDaemonRc[kMAXPATHLEN] = { 0 }; // path to kDaemonRc char gExecDir[kMAXPATHLEN] = { 0 }; // needed to localize ssh2rpd char gFileLog[kMAXPATHLEN] = { 0 }; char gOpenHost[256] = "????"; // same length as in net.cxx ... @@ -221,6 +221,7 @@ int gGlobus = -1; int gNumAllow = -1; int gNumLeft = -1; int gOffSet = -1; +int gPort = 0; int gRemPid = -1; int gReUseAllow = 0x1F; // define methods for which previous auth can be reused int gRootLog = 0; @@ -261,7 +262,6 @@ const int kAUTH_KRB_MSK = 0x4; const int kAUTH_GLB_MSK = 0x8; const int kAUTH_SSH_MSK = 0x10; - //______________________________________________________________________________ static int rpdstrncasecmp(const char *str1, const char *str2, int n) { @@ -1037,14 +1037,24 @@ int RpdCheckAuthAllow(int Sec, char *Host) // If 'yes', returns 0, if 'no', returns 1, the number of allowed // methods in NumAllow, and the codes of the allowed methods (in order // of preference) in AllowMeth. Memory for AllowMeth must be allocated - // outside. Info read from gAuthAllow. + // outside. Info read from gSystemDaemonRc. int retval = 1, found = 0; + char theDaemonRc[kMAXPATHLEN] = { 0 }; + + // Check if user has a private daemon access file ... + struct passwd *pw = getpwuid(getuid()); + if (pw != 0) { + sprintf(theDaemonRc, "%s/%s", pw->pw_dir, kDaemonRc); + } + if (pw == 0 || access(theDaemonRc, R_OK)) { + strcpy(theDaemonRc, gSystemDaemonRc); + } if (gDebug > 2) ErrorInfo ("RpdCheckAuthAllow: Checking file: %s for meth:%d host:%s (gNumAllow: %d)", - gAuthAllow, Sec, Host, gNumAllow); + theDaemonRc, Sec, Host, gNumAllow); // Check if info already loaded (not first call ...) if (gMethInit == 1) { @@ -1072,16 +1082,16 @@ int RpdCheckAuthAllow(int Sec, char *Host) gMethInit = 1; // First check if file exists and can be read - if (access(gAuthAllow, R_OK)) { + if (access(theDaemonRc, R_OK)) { ErrorInfo("RpdCheckAuthAllow: can't read file %s (errno: %d)", - gAuthAllow, GetErrno()); + theDaemonRc, GetErrno()); return retval; } // Open file - FILE *ftab = fopen(gAuthAllow, "r"); + FILE *ftab = fopen(theDaemonRc, "r"); if (ftab == 0) { ErrorInfo("RpdCheckAuthAllow: error opening %s (errno: %d)", - gAuthAllow, GetErrno()); + theDaemonRc, GetErrno()); return retval; } // Get IP of the host in form of a string @@ -1116,8 +1126,19 @@ int RpdCheckAuthAllow(int Sec, char *Host) nw = sscanf(pstr, "%s %s", host, rest); if (nw < 2) continue; // no method defined for this host - // pstr = strstr(line,rest); pstr = line + strlen(host) + 1; + + // Check if a service is specified + char *pcol = strstr(host, ":"); + if (pcol) { + if (!strstr(pcol+1, gService)) + continue; + else + host[(int)(pcol-host)] = '\0'; + } + if (strlen(host) == 0) + strcpy(host, "default"); + if (gDebug > 2) ErrorInfo("RpdCheckAuthAllow: found host: %s ", host); @@ -1732,21 +1753,26 @@ void RpdKrb5Auth(const char *sstr) // get service principal const char *service = gService; - int port = 0; // need to retrieve that information - if ((strcmp(gService, "rootd") == 0 && port == 1094) || - (strcmp(gService, "proofd") == 0 && port == 1093)) { + if (gDebug > 2) + ErrorInfo("RpdKrb5Auth: gService: %s, Port: %d ",gService,gPort); + + if ((strcmp(gService, "rootd") == 0 && gPort == 1094) || + (strcmp(gService, "proofd") == 0 && gPort == 1093)) { // keep the real service name } else { // default to host service = "host"; } + if (gDebug > 2) + ErrorInfo("RpdKrb5Auth: using service: %s ",service); + krb5_principal server; if ((retval = krb5_sname_to_principal(gKcontext, 0, service, KRB5_NT_SRV_HST, &server))) { ErrorInfo("RpdKrb5Auth: while generating service name (%s): %d %s", - gService, retval, error_message(retval)); + service, retval, error_message(retval)); return; } @@ -2918,12 +2944,9 @@ void RpdDefaultAuthAllow() // Kerberos #ifdef R__KRB5 -// if (getuid() == 0) { - gAllowMeth[gNumAllow] = 2; - gNumAllow++; - gNumLeft++; -// } else -// gHaveMeth[2] = 0; + gAllowMeth[gNumAllow] = 2; + gNumAllow++; + gNumLeft++; #else // Don't have this method gHaveMeth[2] = 0; diff --git a/srputils/src/SRPAuth.cxx b/srputils/src/SRPAuth.cxx index 445977d39b4..f79fc4fe5e6 100644 --- a/srputils/src/SRPAuth.cxx +++ b/srputils/src/SRPAuth.cxx @@ -1,4 +1,4 @@ -// @(#)root/srputils:$Name: $:$Id: SRPAuth.cxx,v 1.9 2003/10/07 14:03:03 rdm Exp $ +// @(#)root/srputils:$Name: $:$Id: SRPAuth.cxx,v 1.10 2003/10/07 21:09:55 rdm Exp $ // Author: Fons Rademakers 15/02/2000 /************************************************************************* @@ -182,13 +182,6 @@ Int_t SRPAuthenticate(TAuthenticate *auth, const char *user, const char *passwd, if (version > 1) { - // Save passwd for later use ... - TAuthenticate::SetGlobalUser(user); - TAuthenticate::SetGlobalPasswd(psswd); - TAuthenticate::SetGlobalPwHash(kFALSE); - TAuthenticate::SetGlobalSRPPwd(kTRUE); - - // Receive result of the overall process sock->Recv(stat, kind); if (kind == kROOTD_ERR) { @@ -196,10 +189,18 @@ Int_t SRPAuthenticate(TAuthenticate *auth, const char *user, const char *passwd, goto out; } + // Save passwd for later use ... + TAuthenticate::SetGlobalUser(user); + TAuthenticate::SetGlobalPasswd(psswd); + TAuthenticate::SetGlobalPwHash(kFALSE); + TAuthenticate::SetGlobalSRPPwd(kTRUE); + if (ReUse == 1) { if (kind != kROOTD_RSAKEY) - Warning("SRPAuthenticate", "problems recvn RSA key flag: got message %d, flag: %d",kind,gRSAKey); + Warning("SRPAuthenticate", + "problems recvn RSA key flag: got message %d, flag: %d", + kind,gRSAKey); gRSAKey = 1; // Send the key securely diff --git a/tutorials/TestAuth.C b/tutorials/TestAuth.C index a15bf5deedc..cfb9a312902 100644 --- a/tutorials/TestAuth.C +++ b/tutorials/TestAuth.C @@ -1,19 +1,21 @@ -////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// // // Macro test authentication methods stand alone // -// NB: Kerberos cannot be tested in standalone -// +// See $ROOTSYS/README/README.AUTH for additional details // // Syntax: // -// .x TestAuth.C("<user>","<write path>",<port>,"<globus_det>") +// .x TestAuth.C(<port>,"<user>","<krb5_princ","<globus_det>") // +// <port> = rootd port (default 1094) // <user> = login user name for the test // (default from getpwuid) -// <write path> = path writable by <user> -// (default /tmp) -// <port> = rootd port (default 1094) +// <krb5_princ> = Principal to be used for Krb5 authentication +// in the form user@THE.REA.LM +// ( default: <running_user@Default_Realm with +// Default_realm taken from /etc/krb5.conf +// or the $KRB5_CONFIG file ) // <globus_det> = details for the globus authentication // ( default: ad:certificates cd:$HOME/.globus // cf:usercert.pem kf:userkey.pem ) @@ -22,84 +24,87 @@ // // Example of successful output: // -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// + + -// + TestAuth.C + -// + + -// + Test of authentication methods + -// + + -// + Syntax: + -// + + -// + .x TestAuth.C("<user>","<write path>",<port>,"<globus_det>") + -// + + -// + <user> = login user name for the test + -// + (default from getpwuid) + -// + <write path> = path writable by <user> + -// + (default /tmp) + -// + <port> = rootd port (default 1094) + -// + <globus_det> = details for the globus authentication + -// + ( default ad:certificates cd:$HOME/.globus + -// + cf:usercert.pem kf:userkey.pem ) + -// + + -// + >>> MAKE SURE that rootd is running <<< + -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + + +// + TestAuth.C + +// + + +// + Test of authentication methods + +// + + +// + Syntax: + +// + + +// + .x TestAuth.C(<port>,"<user>","<krb5_princ>","<globus_det>") + +// + + +// + <port> = rootd port (default 1094) + +// + <user> = login user name for the test + +// + (default from getpwuid) + +// + <krb5_princ> = Principal to be used for Krb5 authentication + +// + in the form user@THE.REA.LM + +// + ( default: <running_user@Default_Realm with + +// + Default_realm taken from /etc/krb5.conf + +// + or the $KRB5_CONFIG file ) + +// + <globus_det> = details for the globus authentication + +// + ( default ad:certificates cd:$HOME/.globus + +// + cf:usercert.pem kf:userkey.pem ) + +// + + +// + >>> MAKE SURE that rootd is running <<< + +// + + +// + See $ROOTSYS/README/README.AUTH for additional details + +// + + +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// + + -// + Basic test parameters: + -// + + -// + Local User is : ganis -// + Authentication Details : pt:0 ru:1 us:ganis -// + Current directory is : /afs/cern.ch/aleph/scratch/ganis/root/Linux.Standard/tutorials -// + Test File : /tmp/TestFile.root -// + TFile::Open string : root://localhost:5000//tmp/TestFile.root -// + + -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// + + -// + Testing UsrPwd ... + -// qwerty@localhost password: -// + + -// + Testing SRP ... + -// qwerty@localhost SRP password: -// + + -// + Testing Krb5 ... + -// + Krb5 authentication cannot be tested in standalone + -// + + -// + Testing Globus ... + -// Local Globus Certificates ( ) -// Enter <key>:<new value> to change: -// Your identity: /O=Grid/OU=GlobusTest/OU=simpleCA-arthux.cern.ch/OU=cern.ch/CN=ganis -// Enter GRID pass phrase for this identity: -// Creating proxy ............................ Done -// Your proxy is valid until: Sat Oct 18 14:23:00 2003 -// + + -// + Testing SSH ... + -// qwerty@localhost's password: -// + + -// + Testing UidGid ... + -// + + -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + + +// + Basic test parameters: + +// + + +// + Local User is : ganis +// + Authentication Details : pt:0 ru:1 us:ganis +// + Current directory is : /home/ganis/local/root/root/tutorials +// + TFTP string : root://localhost:1094 +// + Krb5 Details : pt:0 ru:1 us:ganis@PCEPSFT43.CERN.CH +// + + +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + + +// + Testing UsrPwd ... + +// ganis@localhost password: +// + + +// + Testing SRP ... + +// ganis@localhost SRP password: +// + + +// + Testing Krb5 ... + +// Password for ganis@PCEPSFT43.CERN.CH: +// + + +// + Testing Globus ... + +// Local Globus Certificates ( ) +// Enter <key>:<new value> to change: +// Your identity: /O=Grid/OU=GlobusTest/OU=simpleCA-arthux.cern.ch/OU=cern.ch/CN=ganis +// Enter GRID pass phrase for this identity: +// Creating proxy ............................ Done +// Your proxy is valid until: Fri Oct 31 09:33:04 2003 +// + + +// + Testing SSH ... + +// ganis@localhost's password: +// + + +// + Testing UidGid ... + +// + + +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// + + -// + Result of the tests: + -// + + -// + Method: 0 (UsrPwd): successful! (reuse: successful!) + -// + Method: 1 (SRP): successful! (reuse: successful!) + -// + Method: 3 (Globus): successful! (reuse: successful!) + -// + Method: 4 (SSH): successful! (reuse: successful!) + -// + Method: 5 (UidGid): successful! + -// + + -// + Could not be tested: + -// + + -// + Method: 2 (Krb5): not testable + -// + + -// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + + +// + Result of the tests: + +// + + +// + Method: 0 (UsrPwd): successful! (reuse: successful!) + +// + Method: 1 (SRP): successful! (reuse: successful!) + +// + Method: 2 (Krb5): successful! (reuse: successful!) + +// + Method: 3 (Globus): successful! (reuse: successful!) + +// + Method: 4 (SSH): successful! (reuse: successful!) + +// + Method: 5 (UidGid): successful! + +// + + +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // -/////////////////////////////////////////////////////////////////////// // -int TestAuth(char *user = "", char *workdir = "/tmp", - int port = 1094, char *globus = "") +/////////////////////////////////////////////////////////////////////////////////////// +// +int TestAuth(int port = 1094, char *user = "", char *krb5 = "", char *globus = "") { // // This macro tests the authentication methods @@ -109,63 +114,40 @@ int TestAuth(char *user = "", char *workdir = "/tmp", // Getting debug flag Int_t lDebug = gEnv->GetValue("Root.Debug",0); -// Setting test flag - gEnv->SetValue("Test.Auth",1); - // Useful flags Bool_t HaveMeth[6] = {1,0,0,0,0,1}; Int_t TestMeth[6] = {0,0,0,0,0,0}; Int_t TestReUse[6] = {3,3,3,3,3,3}; -// Testing availibilities - char *p; - -// TString HaveSRP = "@srpdir@"; - if ((p = gSystem->DynamicPathName("libSRPAuth", kTRUE))) { - HaveMeth[1] = 1; - } - delete[] p; - -// Check if Kerberos is available - if ((p = gSystem->DynamicPathName("libKrb5Auth", kTRUE))) { - HaveMeth[2] = 1; - } - delete[] p; - -// Check if Globus is available - if ((p = gSystem->DynamicPathName("libGlobusAuth", kTRUE))) { - HaveMeth[3] = 1; - } - delete[] p; - -// Check if SSH available - if (gSystem->Which(gSystem->Getenv("PATH"), "ssh", kExecutePermission)) { - HaveMeth[4] = 1; - } // Some Printout - printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); - printf(" + +\n"); - printf(" + TestAuth.C +\n"); - printf(" + +\n"); - printf(" + Test of authentication methods +\n"); - printf(" + +\n"); - printf(" + Syntax: +\n"); - printf(" + +\n"); - printf(" + .x TestAuth.C(\"<user>\",\"<write path>\",<port>,\"<globus_det>\") +\n"); - printf(" + +\n"); - printf(" + <user> = login user name for the test +\n"); - printf(" + (default from getpwuid) +\n"); - printf(" + <write path> = path writable by <user> +\n"); - printf(" + (default /tmp) +\n"); - printf(" + <port> = rootd port (default 1094) +\n"); - printf(" + <globus_det> = details for the globus authentication +\n"); - printf(" + ( default ad:certificates cd:$HOME/.globus +\n"); - printf(" + cf:usercert.pem kf:userkey.pem ) +\n"); - printf(" + +\n"); - printf(" + >>> MAKE SURE that rootd is running <<< +\n"); - printf(" + +\n"); - printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"); + printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + printf(" + +\n"); + printf(" + TestAuth.C +\n"); + printf(" + +\n"); + printf(" + Test of authentication methods +\n"); + printf(" + +\n"); + printf(" + Syntax: +\n"); + printf(" + +\n"); + printf(" + .x TestAuth.C(<port>,\"<user>\",\"<krb5_princ>\",\"<globus_det>\") +\n"); + printf(" + +\n"); + printf(" + <port> = rootd port (default 1094) +\n"); + printf(" + <user> = login user name for the test +\n"); + printf(" + (default from getpwuid) +\n"); + printf(" + <krb5_princ> = Principal to be used for Krb5 authentication +\n"); + printf(" + in the form user@THE.REA.LM +\n"); + printf(" + ( default: <running_user@Default_Realm with +\n"); + printf(" + Default_realm taken from /etc/krb5.conf +\n"); + printf(" + or the $KRB5_CONFIG file ) +\n"); + printf(" + <globus_det> = details for the globus authentication +\n"); + printf(" + ( default ad:certificates cd:$HOME/.globus +\n"); + printf(" + cf:usercert.pem kf:userkey.pem ) +\n"); + printf(" + +\n"); + printf(" + >>> MAKE SURE that rootd is running <<< +\n"); + printf(" + +\n"); + printf(" + See $ROOTSYS/README/README.AUTH for additional details +\n"); + printf(" + +\n"); + printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n"); // Useful variables @@ -190,72 +172,109 @@ int TestAuth(char *user = "", char *workdir = "/tmp", } -// Working Dir - TString WorkDir = workdir; - if (WorkDir == "" || - gSystem->AccessPathName(WorkDir, kWritePermission)) { - if (lDebug > 0) - printf(">>>> Path: %s not writable!\n",WorkDir.Data()); - WorkDir = "/tmp"; - if (gSystem->AccessPathName(WorkDir, kWritePermission)) { - if (lDebug > 0) - printf(">>>> Path: %s not writable!\n",WorkDir.Data()); - WorkDir = gSystem->WorkingDirectory(); - if (WorkDir == "" || - gSystem->AccessPathName(WorkDir, kWritePermission)) { - if (lDebug > 0) - printf(">>>> Path: %s not writable!\n",WorkDir.Data()); - printf("unable to find writable dir for temporary test file: return!\n"); - return 1; - } - } - } - -// TempFile path - TString FileTemp = WorkDir + "/TestFile.root"; - -// Create test file first - TFile *TestFile = new TFile(FileTemp.Data(),"RECREATE"); - if (TestFile && TestFile->IsOpen()) { - Real_t theVector[5] = {0.,1.,2.,3.,4.}; - TVector vc(5,theVector); - vc.Write(); - if (lDebug > 1) - TestFile->ls(); - if (TestFile) delete TestFile; - } else { - printf("Cannot open test file: return!\n"); - return 1; - } - -// File path string for TFile::Open - TString WkgFile = - TString("root://localhost:") + port + "/" + WorkDir + "/TestFile.root"; - // Host TString Host = "localhost"; + TString HostName = gSystem->HostName(); + +// File path string for TFTP + //TString TFTPPath = TString("root://localhost:")+ port ; + TString TFTPPath = TString("root://")+User+TString("@localhost:")+ port ; + //TString TFTPPathKrb5 = TString("root://") + HostName + TString(":")+ port ; + TString TFTPPathKrb5 = TString("root://") + User+ TString("@") + + HostName + TString(":")+ port ; // Details TString Details = TString("pt:0 ru:1 us:") + User; - TString GlobusDetails = TString("pt:0 ru:1 ") + TString(globus); + +// Testing availibilities + char *p; + +// TString HaveSRP = "@srpdir@"; + if ((p = gSystem->DynamicPathName("libSRPAuth", kTRUE))) { + HaveMeth[1] = 1; + } + delete[] p; + +// Check if Kerberos is available + TString Krb5Details; + TString Krb5Open; + if ((p = gSystem->DynamicPathName("libKrb5Auth", kTRUE))) { + HaveMeth[2] = 1; + // Special details string for Kerberos + if (strlen(krb5) > 0) { + Krb5Details = TString("pt:0 ru:1 us:") + TString(krb5); + } else { + // Must determine a default ... look in config file + TString Krb5Conf, Realm; + if (gSystem->Getenv("KRB5_CONFIG")) { + if (!gSystem->AccessPathName(gSystem->Getenv("KRB5_CONFIG"), kReadPermission)) { + Krb5Conf = gSystem->Getenv("KRB5_CONFIG"); + } + } else if (!gSystem->AccessPathName("/etc/krb5.conf", kReadPermission)) { + Krb5Conf = "/etc/krb5.conf"; + } else { + printf("\n >>>> Kerberos Principal undefined\n"); + printf("\n >>>> unable to localize Kerberos config file to build a default\n"); + printf("\n >>>> Switching off Kerberos\n"); + printf("\n >>>> Run again with giving the principal as 3rd argument\n"); + printf("\n >>>> or define the variable KRB5_CONFIG with the full path \n"); + printf("\n >>>> to the config file (usually /etc/krb5.conf)\n"); + HaveMeth[2] = 0; + } + if (HaveMeth[2] == 1) { + FILE *fc = fopen(Krb5Conf.Data(),"r"); + if (fc) { + char line[1024], fs1[1024], fs2[1024], fs3[1024]; + while (fgets(line, sizeof(line), fc) != 0) { + int nf = sscanf(line,"%s %s %s",fs1,fs2,fs3); + if (nf == 3 && !strcmp(fs1,"default_realm")) { + Realm = fs3; + break; + } + } + Krb5Details = TString("pt:0 ru:1 us:") + User + TString("@") + Realm; + fclose(fc); + } else { + HaveMeth[2] = 0; + } + } + } + } + delete[] p; + +// Check if Globus is available + TString GlobusDetails; + if ((p = gSystem->DynamicPathName("libGlobusAuth", kTRUE))) { + HaveMeth[3] = 1; + // Special details string for Globus + GlobusDetails = TString("pt:0 ru:1 ") + TString(globus); + } + delete[] p; + +// Check if SSH available + if (gSystem->Which(gSystem->Getenv("PATH"), "ssh", kExecutePermission)) { + HaveMeth[4] = 1; + } // Test parameter Printout - printf("\n +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); - printf(" + +\n"); - printf(" + Basic test parameters: +\n"); - printf(" + +\n"); + printf("\n +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + printf(" + +\n"); + printf(" + Basic test parameters: +\n"); + printf(" + +\n"); printf(" + Local User is : %s \n",User.Data()); printf(" + Authentication Details : %s \n",Details.Data()); printf(" + Current directory is : %s \n",gSystem->WorkingDirectory()); - printf(" + Test File : %s \n",FileTemp.Data()); - printf(" + TFile::Open string : %s \n",WkgFile.Data()); - printf(" + +\n"); - printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + printf(" + TFTP string : %s \n",TFTPPath.Data()); + if (HaveMeth[2]) { + printf(" + Krb5 Details : %s \n",Krb5Details.Data()); + } + printf(" + +\n"); + printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); // UsrPwd method - printf(" + +\n"); - printf(" + Testing UsrPwd ... +\n"); + printf(" + +\n"); + printf(" + Testing UsrPwd ... +\n"); // Create a THostAuth instantiation for the local host THostAuth *hawk = new THostAuth(Host.Data(),User.Data(),0,Details.Data()); @@ -267,17 +286,14 @@ int TestAuth(char *user = "", char *workdir = "/tmp", if (lDebug > 0) hawk->Print(); + { // First authentication attempt - TFile *f1 = TFile::Open(WkgFile.Data(),"read"); - if (f1 && f1->IsOpen()) { + TFTP t1(TFTPPath.Data()); + if (t1.IsOpen()) { TestMeth[0] = 1; - if (lDebug > 1) - f1->ls(); } else { printf(" >>>>>>>>>>>>>>>> Test of UsrPwd authentication failed \n"); - } - // Delete file - if (f1) delete f1; + }} // Get pointer to relevant HostAuth THostAuth *ha = TAuthenticate::GetHostAuth(Host.Data(),User.Data()); @@ -301,8 +317,8 @@ int TestAuth(char *user = "", char *workdir = "/tmp", // SRP method if ( HaveMeth[1] ) { - printf(" + +\n"); - printf(" + Testing SRP ... +\n"); + printf(" + +\n"); + printf(" + Testing SRP ... +\n"); // Add relevant info to HostAuth ha->SetFirst(1,Details.Data()); @@ -310,16 +326,12 @@ int TestAuth(char *user = "", char *workdir = "/tmp", ha->Print(); // Authentication attempt - TFile *f1 = TFile::Open(WkgFile.Data(),"read"); - if (f1 && f1->IsOpen()) { + TFTP t1(TFTPPath.Data()); + if (t1.IsOpen()) { TestMeth[1] = 1; - if (lDebug > 1) - f1->ls(); } else { printf(" >>>>>>>>>>>>>>>> Test of SRP authentication failed \n"); } - // Delete file - if (f1) delete f1; // Try ReUse if (TestMeth[1] == 1) { @@ -342,19 +354,51 @@ int TestAuth(char *user = "", char *workdir = "/tmp", // Kerberos method if ( HaveMeth[2] ) { - printf(" + +\n"); - printf(" + Testing Krb5 ... +\n"); + printf(" + +\n"); + printf(" + Testing Krb5 ... +\n"); + + // Create a special THostAuth instantiation for kerberos + THostAuth *hak = new THostAuth(HostName.Data(),User.Data(),2,Krb5Details.Data()); + + // Add object to list + TAuthenticate::GetAuthInfo()->Add(hak); + if (lDebug > 0) + hak->Print(); + + // Authentication attempt + TFTP t1(TFTPPathKrb5.Data()); + if (t1.IsOpen()) { + TestMeth[2] = 1; + } else { + printf(" >>>>>>>>>>>>>>>> Test of Kerberos authentication failed \n"); + if (strlen(krb5) > 0) { + printf(" >>>>>>>>>>>>>>>> details used: '%s' \n",krb5); + } + } - // Standalone test not possible - TestMeth[2] = 2; - printf(" + Krb5 authentication cannot be tested in standalone +\n"); + // Try ReUse + if (TestMeth[2] == 1) { + TIter next(hak->Established()); + TAuthDetails *ai; + while ((ai = (TAuthDetails *) next())) { + if (ai->GetMethod() == 2) { + Int_t OffSet = ai->GetOffSet(); + TestReUse[2] = 0; + if (OffSet > -1) { + TestReUse[2] = 1; + } + } + } + } + // remove method from available list + hak->RemoveMethod(2); } // Globus method if ( HaveMeth[3] ) { - printf(" + +\n"); - printf(" + Testing Globus ... +\n"); + printf(" + +\n"); + printf(" + Testing Globus ... +\n"); // Add relevant info to HostAuth ha->SetFirst(3,GlobusDetails.Data()); @@ -362,11 +406,9 @@ int TestAuth(char *user = "", char *workdir = "/tmp", ha->Print(); // Authentication attempt - TFile *f1 = TFile::Open(WkgFile.Data(),"read"); - if (f1 && f1->IsOpen()) { + TFTP t1(TFTPPath.Data()); + if (t1.IsOpen()) { TestMeth[3] = 1; - if (lDebug > 1) - f1->ls(); } else { printf(" >>>>>>>>>>>>>>>> Test of Globus authentication failed \n"); if (strlen(globus) > 0) { @@ -382,18 +424,16 @@ int TestAuth(char *user = "", char *workdir = "/tmp", printf(" >>>>>>>>>>>>>>>> You are not root,"); printf(" you may not have the right privileges\n"); printf(" >>>>>>>>>>>>>>>> Make sure that the used details are correct! \n"); - } + } } } - // Delete file - if (f1) delete f1; // Try ReUse if (TestMeth[3] == 1) { TIter next(ha->Established()); TAuthDetails *ai; while ((ai = (TAuthDetails *) next())) { - if (ai->GetMethod() == 1) { + if (ai->GetMethod() == 3) { Int_t OffSet = ai->GetOffSet(); TestReUse[3] = 0; if (OffSet > -1) { @@ -409,8 +449,8 @@ int TestAuth(char *user = "", char *workdir = "/tmp", // SSH methodg if ( HaveMeth[4] ) { - printf(" + +\n"); - printf(" + Testing SSH ... +\n"); + printf(" + +\n"); + printf(" + Testing SSH ... +\n"); // Add relevant info to HostAuth ha->SetFirst(4,Details.Data()); @@ -418,16 +458,12 @@ int TestAuth(char *user = "", char *workdir = "/tmp", ha->Print(); // Authentication attempt - TFile *f1 = TFile::Open(WkgFile.Data(),"read"); - if (f1 && f1->IsOpen()) { + TFTP t1(TFTPPath.Data()); + if (t1.IsOpen()) { TestMeth[4] = 1; - if (lDebug > 0) - f1->ls(); } else { printf(" >>>>>>>>>>>>>>>> Test of SSH authentication failed \n"); } - // Delete file - if (f1) delete f1; // Try ReUse if (TestMeth[4] == 1) { @@ -449,8 +485,8 @@ int TestAuth(char *user = "", char *workdir = "/tmp", // Rfio method - printf(" + +\n"); - printf(" + Testing UidGid ... +\n"); + printf(" + +\n"); + printf(" + Testing UidGid ... +\n"); // Add relevant info to HostAuth ha->SetFirst(5,Details.Data()); @@ -458,22 +494,19 @@ int TestAuth(char *user = "", char *workdir = "/tmp", ha->Print(); // Authentication attempt - TFile *f1 = TFile::Open(WkgFile.Data(),"read"); - if (f1 && f1->IsOpen()) { + { + TFTP t1(TFTPPath.Data()); + if (t1.IsOpen()) { TestMeth[5] = 1; - if (lDebug > 1) - f1->ls(); } else { printf(" >>>>>>>>>>>>>>>> Test of UidGid authentication failed \n"); - } - // Delete file - if (f1) delete f1; + }} // remove method from available list ha->RemoveMethod(5); - printf(" + +\n"); - printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + printf(" + +\n"); + printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); // Print available host auth info if (lDebug > 0) @@ -486,35 +519,39 @@ int TestAuth(char *user = "", char *workdir = "/tmp", gEnv->SetValue("Test.Auth",0); // Final Printout - printf("\n +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); - printf(" + +\n"); - printf(" + Result of the tests: +\n"); - printf(" + +\n"); + printf("\n +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + printf(" + +\n"); + printf(" + Result of the tests: +\n"); + printf(" + +\n"); char status[4][20] = {"failed!","successful!","not testable","not tested"}; int i = 0; for( i=0; i<6; i++ ) { if (HaveMeth[i] && TestMeth[i] < 2) { if (i < 5) { - printf(" + Method: %d %8s: %11s (reuse: %11s) +\n",i, + printf(" + Method: %d %8s: %11s (reuse: %11s) +\n",i, Form("(%s)",TAuthenticate::GetAuthMethod(i)), status[TestMeth[i]],status[TestReUse[i]]); } else - printf(" + Method: %d %8s: %11s +\n",i, + printf(" + Method: %d %8s: %11s +\n",i, Form("(%s)",TAuthenticate::GetAuthMethod(i)), status[TestMeth[i]]); } } - printf(" + +\n"); - printf(" + Could not be tested: +\n"); - printf(" + +\n"); + Bool_t NotPrinted = kTRUE; for( i=0; i<6; i++ ) { if (HaveMeth[i] && TestMeth[i] > 1) { - printf(" + Method: %d %8s: %11s +\n",i, + if (NotPrinted) { + printf(" + +\n"); + printf(" + Could not be tested: +\n"); + printf(" + +\n"); + NotPrinted = kFALSE; + } + printf(" + Method: %d %8s: %11s +\n",i, Form("(%s)",TAuthenticate::GetAuthMethod(i)), status[TestMeth[i]]); } } - printf(" + +\n"); - printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + printf(" + +\n"); + printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); } -- GitLab