XrdCmsLogin.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                        X r d C m s L o g i n . 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: XrdCmsLogin.cc 38011 2011-02-08 18:35:57Z ganis $
00012 
00013 const char *XrdCmsLoginCVSID = "$Id: XrdCmsLogin.cc 38011 2011-02-08 18:35:57Z ganis $";
00014 
00015 #include <netinet/in.h>
00016 
00017 #include "XProtocol/YProtocol.hh"
00018 
00019 #include "Xrd/XrdLink.hh"
00020 
00021 #include "XrdCms/XrdCmsLogin.hh"
00022 #include "XrdCms/XrdCmsParser.hh"
00023 #include "XrdCms/XrdCmsTalk.hh"
00024 #include "XrdCms/XrdCmsSecurity.hh"
00025 #include "XrdCms/XrdCmsTrace.hh"
00026 
00027 #include "XrdOuc/XrdOucPup.hh"
00028 
00029 #include "XrdSys/XrdSysError.hh"
00030 #include "XrdSys/XrdSysPthread.hh"
00031 
00032 using namespace XrdCms;
00033 
00034 /******************************************************************************/
00035 /* Public:                         A d m i t                                  */
00036 /******************************************************************************/
00037   
00038 int XrdCmsLogin::Admit(XrdLink *Link, CmsLoginData &Data)
00039 {
00040    CmsRRHdr      myHdr;
00041    CmsLoginData  myData;
00042    const char   *eText, *Token;
00043             int  myDlen, Toksz;
00044 
00045 // Get complete request
00046 //
00047    if ((eText = XrdCmsTalk::Attend(Link, myHdr, myBuff, myBlen, myDlen)))
00048       return Emsg(Link, eText, 0);
00049 
00050 // If we need to do authentication, do so now
00051 //
00052    if ((Token = XrdCmsSecurity::getToken(Toksz, Link->Host()))
00053    &&  !XrdCmsSecurity::Authenticate(Link, Token, Toksz)) return 0;
00054 
00055 // Fiddle with the login data structures
00056 //
00057    Data.SID = Data.Paths = 0;
00058    memset(&myData, 0, sizeof(myData));
00059    myData.Mode     = Data.Mode;
00060    myData.HoldTime = Data.HoldTime;
00061    myData.Version  = Data.Version = kYR_Version;
00062 
00063 // Decode the data pointers ans grab the login data
00064 //
00065    if (!Parser.Parse(&Data, myBuff, myBuff+myDlen)) 
00066       return Emsg(Link, "invalid login data", 0);
00067 
00068 // Do authentication now, if needed
00069 //
00070    if ((Token = XrdCmsSecurity::getToken(Toksz, Link->Host())))
00071       if (!XrdCmsSecurity::Authenticate(Link, Token, Toksz)) return 0;
00072 
00073 // Send off login reply
00074 //
00075    return (sendData(Link, myData) ? 0 : 1);
00076 }
00077 
00078 /******************************************************************************/
00079 /* Private:                         E m s g                                   */
00080 /******************************************************************************/
00081 
00082 int XrdCmsLogin::Emsg(XrdLink *Link, const char *msg, int ecode)
00083 {
00084    Say.Emsg("Login", Link->Name(), "login failed;", msg);
00085    return ecode;
00086 }
00087   
00088 /******************************************************************************/
00089 /* Public:                         L o g i n                                  */
00090 /******************************************************************************/
00091   
00092 int XrdCmsLogin::Login(XrdLink *Link, CmsLoginData &Data, int timeout)
00093 {
00094    CmsRRHdr LIHdr;
00095    char WorkBuff[4096], *hList, *wP = WorkBuff;
00096    int n, dataLen;
00097 
00098 // Send the data
00099 //
00100    if (sendData(Link, Data)) return kYR_EINVAL;
00101 
00102 // Get the response.
00103 //
00104    if ((n = Link->RecvAll((char *)&LIHdr, sizeof(LIHdr), timeout)) < 0)
00105       return Emsg(Link, (n == -ETIMEDOUT ? "timed out" : "rejected"));
00106 
00107 // Receive and decode the response. We apparently have protocol version 2.
00108 //
00109    if ((dataLen = static_cast<int>(ntohs(LIHdr.datalen))))
00110       {if (dataLen > (int)sizeof(WorkBuff)) 
00111           return Emsg(Link, "login reply too long");
00112        if (Link->RecvAll(WorkBuff, dataLen, timeout) < 0)
00113           return Emsg(Link, "login receive error");
00114       }
00115 
00116 // Check if we are being asked to identify ourselves
00117 //
00118    if (LIHdr.rrCode == kYR_xauth)
00119       {if (!XrdCmsSecurity::Identify(Link, LIHdr, WorkBuff, sizeof(WorkBuff)))
00120           return kYR_EINVAL;
00121        dataLen = static_cast<int>(ntohs(LIHdr.datalen));
00122        if (dataLen > (int)sizeof(WorkBuff))
00123           return Emsg(Link, "login reply too long");
00124       }
00125 
00126 // The response can also be a login redirect (i.e., a try request).
00127 //
00128    if (!(Data.Mode & CmsLoginData::kYR_director)
00129    &&  LIHdr.rrCode == kYR_try)
00130       {if (!XrdOucPup::Unpack(&wP, wP+dataLen, &hList, n))
00131           return Emsg(Link, "malformed try host data");
00132        Data.Paths = (kXR_char *)strdup(n ? hList : "");
00133        return kYR_redirect;
00134       }
00135 
00136 // Process error reply
00137 //
00138    if (LIHdr.rrCode == kYR_error)
00139       return (dataLen < (int)sizeof(kXR_unt32)+8
00140              ? Emsg(Link, "invalid error reply")
00141              : Emsg(Link, WorkBuff+sizeof(kXR_unt32)));
00142 
00143 // Process normal reply
00144 //
00145    if (LIHdr.rrCode != kYR_login
00146    || !Parser.Parse(&Data, WorkBuff, WorkBuff+dataLen))
00147       return Emsg(Link, "invalid login response");
00148    return 0;
00149 }
00150 
00151 /******************************************************************************/
00152 /* Private:                     s e n d D a t a                               */
00153 /******************************************************************************/
00154   
00155 int XrdCmsLogin::sendData(XrdLink *Link, CmsLoginData &Data)
00156 {
00157    static const int xNum   = 16;
00158 
00159    int          iovcnt;
00160    char         Work[xNum*12];
00161    struct iovec Liov[xNum];
00162    CmsRRHdr     Resp={0, kYR_login, 0, 0};
00163 
00164 // Pack the response (ignore the auth token for now)
00165 //
00166    if (!(iovcnt=Parser.Pack(kYR_login,&Liov[1],&Liov[xNum],(char *)&Data,Work)))
00167       return Emsg(Link, "too much login reply data");
00168 
00169 // Complete I/O vector
00170 //
00171    Resp.datalen = Data.Size;
00172    Liov[0].iov_base = (char *)&Resp;
00173    Liov[0].iov_len  = sizeof(Resp);
00174 
00175 // Send off the data
00176 //
00177    Link->Send(Liov, iovcnt+1);
00178 
00179 // Return success
00180 //
00181    return 0;
00182 }

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