XrdCmsSecurity.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                     X r d C m s S e c u r i t y . c c                      */
00004 /*                                                                            */
00005 /* (c) 2007 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC02-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //          $Id: XrdCmsSecurity.cc 35287 2010-09-14 21:19:35Z ganis $
00012 
00013 const char *XrdCmsSecurityCVSID = "$Id: XrdCmsSecurity.cc 35287 2010-09-14 21:19:35Z ganis $";
00014 
00015 // Bypass Solaris ELF madness
00016 //
00017 #ifdef __solaris__
00018 #include <sys/isa_defs.h>
00019 #if defined(_ILP32) && (_FILE_OFFSET_BITS != 32)
00020 #undef  _FILE_OFFSET_BITS
00021 #define _FILE_OFFSET_BITS 32
00022 #undef  _LARGEFILE_SOURCE
00023 #endif
00024 #endif
00025   
00026 #include <dlfcn.h>
00027 #ifndef __macos__
00028 #include <link.h>
00029 #endif
00030 
00031 #include <stdlib.h>
00032 
00033 #include "XProtocol/YProtocol.hh"
00034 
00035 #include "Xrd/XrdLink.hh"
00036 
00037 #include "XrdCms/XrdCmsSecurity.hh"
00038 #include "XrdCms/XrdCmsTalk.hh"
00039 #include "XrdCms/XrdCmsTrace.hh"
00040 
00041 #include "XrdOuc/XrdOucEnv.hh"
00042 #include "XrdOuc/XrdOucErrInfo.hh"
00043 #include "XrdOuc/XrdOucTList.hh"
00044 #include "XrdSys/XrdSysError.hh"
00045 #include "XrdSys/XrdSysPthread.hh"
00046 
00047 using namespace XrdCms;
00048 
00049 /******************************************************************************/
00050 /*                        G l o b a l   S y m b o l s                         */
00051 /******************************************************************************/
00052   
00053 extern XrdSecProtocol *(*XrdXrootdSecGetProtocol)
00054                                           (const char             *hostname,
00055                                            const struct sockaddr  &netaddr,
00056                                            const XrdSecParameters &parms,
00057                                                  XrdOucErrInfo    *einfo);
00058 
00059 /******************************************************************************/
00060 /*                        S t a t i c   S y m b o l s                         */
00061 /******************************************************************************/
00062   
00063 namespace XrdCms
00064 {
00065 XrdSecProtocol        *(*secProtocol)
00066                                           (const char             *hostname,
00067                                            const struct sockaddr  &netaddr,
00068                                            const XrdSecParameters &parms,
00069                                                  XrdOucErrInfo    *einfo)=0;
00070 }
00071 
00072 XrdSecService *XrdCmsSecurity::DHS    = 0;
00073 
00074 /******************************************************************************/
00075 /*                          A u t h e n t i c a t e                           */
00076 /******************************************************************************/
00077   
00078 int XrdCmsSecurity::Authenticate(XrdLink *Link, const char *Token, int Toksz)
00079 {
00080    CmsRRHdr myHdr = {0, kYR_xauth, 0, 0};
00081    struct sockaddr netaddr;
00082    XrdSecCredentials cred;
00083    XrdSecProtocol   *AuthProt = 0;
00084    XrdSecParameters *parm = 0;
00085    XrdOucErrInfo     eMsg;
00086    const char       *eText = 0;
00087    char *authName, authBuff[4096];
00088    int rc, myDlen, abLen = sizeof(authBuff);
00089 
00090 // Send a request for authentication
00091 //
00092    if ((eText = XrdCmsTalk::Request(Link, myHdr, (char *)Token, Toksz+1)))
00093       {Say.Emsg("Auth",Link->Host(),"authentication failed;",eText);
00094        return 0;
00095       }
00096 
00097 // Perform standard authentication
00098 //
00099 do {
00100 
00101 // Get the response header and verify the request code
00102 //
00103    if ((eText = XrdCmsTalk::Attend(Link,myHdr,authBuff,abLen,myDlen))) break;
00104    if (myHdr.rrCode != kYR_xauth) {eText = "invalid auth response";    break;}
00105    cred.size = myDlen; cred.buffer = authBuff;
00106 
00107 // If we do not yet have a protocol, get one
00108 //
00109    if (!AuthProt)
00110       {const char *hname = Link->Name(&netaddr);
00111        if (!DHS
00112        ||  !(AuthProt=DHS->getProtocol((char *)hname,netaddr,&cred,&eMsg)))
00113           {eText = eMsg.getErrText(rc); break;}
00114       }
00115 
00116 // Perform the authentication
00117 //
00118     if (!(rc = AuthProt->Authenticate(&cred, &parm, &eMsg))) break;
00119     if (rc < 0) {eText = eMsg.getErrText(rc); break;}
00120     if (parm) 
00121        {eText = XrdCmsTalk::Request(Link, myHdr, parm->buffer, parm->size);
00122         delete parm;
00123         if (eText) break;
00124        } else {eText = "auth interface violation"; break;}
00125 
00126 } while(1);
00127 
00128 // Check if we succeeded
00129 //
00130    if (!eText)
00131       {if (!(authName = AuthProt->Entity.name)) eText = "entity name missing";
00132           else {Link->setID(authName,0);
00133                 Say.Emsg("Auth",Link->Host(),"authenticated as", authName);
00134                }
00135       }
00136 
00137 // Check if we failed
00138 //
00139    if (eText) Say.Emsg("Auth",Link->Host(),"authentication failed;",eText);
00140 
00141 // Perform final steps here
00142 //
00143    if (AuthProt) AuthProt->Delete();
00144    return (eText == 0);
00145 }
00146 
00147 /******************************************************************************/
00148 /*                             C o n f i g u r e                              */
00149 /******************************************************************************/
00150 
00151 int XrdCmsSecurity::Configure(const char *Lib, const char *Cfn)
00152 {
00153    static XrdSysMutex myMutex;
00154    XrdSysMutexHelper  hlpMtx(&myMutex);
00155    XrdSecService *(*ep)(XrdSysLogger *, const char *cfn);
00156    static void *libhandle = 0;
00157 
00158 // If we aleady have a security interface, return (may happen in client)
00159 //
00160    if (!Cfn)
00161       {if (secProtocol) return 1;
00162           else if (XrdXrootdSecGetProtocol)
00163                   {secProtocol = XrdXrootdSecGetProtocol; return 1;}
00164       }
00165 
00166 // Open the security library
00167 //
00168    if (!libhandle && !(libhandle = dlopen(Lib, RTLD_NOW)))
00169       {Say.Emsg("Config",dlerror(),"opening shared library",Lib);
00170        return 0;
00171       }
00172 
00173 // Get the client object creator (in case we are acting as a client)
00174 //
00175    if (! secProtocol
00176    &&  !(secProtocol = (XrdSecProtocol *(*)(const char             *,
00177                                             const struct sockaddr  &,
00178                                             const XrdSecParameters &,
00179                                                   XrdOucErrInfo    *))
00180                        dlsym(libhandle, "XrdSecGetProtocol")))
00181       {Say.Emsg("Config",dlerror(),"finding XrdSecGetProtocol() in",Lib);
00182        return 0;
00183       }
00184 
00185 // If only configuring a client or we already cnfigured a server, all done
00186 //
00187    if (!Cfn || DHS) return 1;
00188 
00189 // Get the server object creator
00190 //
00191    if (!(ep = (XrdSecService *(*)(XrdSysLogger *, const char *cfn))dlsym(libhandle,
00192               "XrdSecgetService")))
00193       {Say.Emsg("Config",dlerror(),"finding XrdSecgetService() in",Lib);
00194        return 0;
00195       }
00196 
00197 // Get the server object
00198 //
00199    if (!(DHS = (*ep)(Say.logger(), Cfn)))
00200       {Say.Emsg("Config","Unable to create security service object via",Lib);
00201        return 0;
00202       }
00203 
00204 // All done
00205 //
00206    return 1;
00207 }
00208 
00209 /******************************************************************************/
00210 /*                              g e t T o k e n                               */
00211 /******************************************************************************/
00212   
00213 const char *XrdCmsSecurity::getToken(int &size, const char *hostname)
00214 {
00215 
00216 // If not configured, return a null to indicate no authentication required
00217 //
00218    if (!DHS) {size = 0; return 0;}
00219 
00220 // Return actual token
00221 //
00222    return DHS->getParms(size, hostname);
00223 }
00224 
00225 /******************************************************************************/
00226 /*                              I d e n t i f y                               */
00227 /******************************************************************************/
00228   
00229 int XrdCmsSecurity::Identify(XrdLink *Link, XrdCms::CmsRRHdr &inHdr, 
00230                              char *authBuff, int abLen)
00231 {
00232    CmsRRHdr outHdr = {0, kYR_xauth, 0, 0};
00233    struct sockaddr netaddr;
00234    const char *hname = Link->Host(&netaddr);
00235    XrdSecCredentials *cred;
00236    XrdSecProtocol    *AuthProt = 0;
00237    XrdSecParameters   AuthParm, *AuthP = 0;
00238    XrdOucErrInfo      eMsg;
00239    const char        *eText = 0;
00240    int rc, myDlen;
00241 
00242 // Verify that we are configured
00243 //
00244    if (!secProtocol && !Configure("libXrdSec.so"))
00245       {Say.Emsg("Auth",Link->Host(),"authentication configuration failed.");
00246        return 0;
00247       }
00248 
00249 // Obtain the protocol
00250 //
00251    AuthParm.buffer = (char *)authBuff; AuthParm.size = strlen(authBuff);
00252    if (!(AuthProt = secProtocol((char *)hname, netaddr, AuthParm, &eMsg)))
00253       {Say.Emsg("Auth",hname,"getProtocol() failed;",eMsg.getErrText(rc));
00254        return 0;
00255       }
00256 
00257 // Perform standard authentication
00258 //
00259 do {
00260 
00261 // Get credentials
00262 //
00263    if (!(cred = AuthProt->getCredentials(AuthP, &eMsg)))
00264       {eText = eMsg.getErrText(rc); break;}
00265 
00266 // Send credentials to the server
00267 //
00268    eText = XrdCmsTalk::Request(Link, outHdr, cred->buffer, cred->size);
00269    delete cred;
00270    if (eText) break;
00271 
00272 // Get the response header and prepare for next iteration if need be
00273 //
00274    if ((eText = XrdCmsTalk::Attend(Link,inHdr,authBuff,abLen,myDlen))) break;
00275    AuthParm.size = myDlen; AuthParm.buffer = authBuff; AuthP = &AuthParm;
00276 
00277 } while(inHdr.rrCode == kYR_xauth);
00278 
00279 // Check if we failed
00280 //
00281    if (eText) Say.Emsg("Auth",Link->Host(),"authentication failed;",eText);
00282 
00283 // Perform final steps here
00284 //
00285    if (AuthProt) AuthProt->Delete();
00286    return (eText == 0);
00287 }
00288 
00289 /******************************************************************************/
00290 /*                           s e t S y s t e m I D                            */
00291 /******************************************************************************/
00292   
00293 char *XrdCmsSecurity::setSystemID(XrdOucTList *tp, const char *iName,
00294                                   const char  *iHost,    char  iType)
00295 {
00296    XrdOucTList *tpF;
00297    char sidbuff[8192], *sidend = sidbuff+sizeof(sidbuff)-32, *sp, *cP;
00298    char *fMan, *fp, *xp;
00299    int n;
00300 
00301 // The system ID starts with the semi-unique name of this node
00302 //
00303    if (!iName || !*iName) iName = "anon";
00304    if (!iHost || !*iHost) iHost = "localhost";
00305    strcpy(sidbuff, iName); strcat(sidbuff, "-");
00306    sp = sidbuff + strlen(sidbuff);
00307    *sp++ = iType; *sp++ = ' '; cP = sp;
00308 
00309 // Develop a unique cluster name for this cluster
00310 //
00311    if (!tp) sp += sprintf(sp, "%s@%s", iName, iHost);
00312       else {tpF = tp;
00313             fMan = tp->text + strlen(tp->text) - 1;
00314             while((tp = tp->next))
00315                  {fp = fMan; xp = tp->text + strlen(tp->text) - 1;
00316                   do {if (*fp != *xp) break;
00317                       xp--;
00318                      } while(fp-- != tpF->text);
00319                   if ((n = xp - tp->text + 1) > 0)
00320                      {sp += sprintf(sp, "%d", tp->val);
00321                       if (sp+n >= sidend) return (char *)0;
00322                       strncpy(sp, tp->text, n); sp += n;
00323                      }
00324                  }
00325             sp += sprintf(sp, "%d", tpF->val);
00326             n = strlen(tpF->text);
00327             if (sp+n >= sidend) return (char *)0;
00328             strcpy(sp, tpF->text); sp += n;
00329            }
00330 
00331 // Set envar to hold the cluster name
00332 //
00333    *sp = '\0';
00334    XrdOucEnv::Export("XRDCMSCLUSTERID", cP);
00335 
00336 // Return the system ID
00337 //
00338    return  strdup(sidbuff);
00339 }

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