XrdSecProtocolsss.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                  X r d S e c P r o t o c o l s s s . c c                   */
00004 /*                                                                            */
00005 /* (c) 2008 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 #include <unistd.h>
00012 #include <ctype.h>
00013 #include <errno.h>
00014 #include <stdlib.h>
00015 #include <strings.h>
00016 #include <stdio.h>
00017 #include <sys/param.h>
00018 
00019 #include "XrdNet/XrdNetDNS.hh"
00020 #include "XrdOuc/XrdOucCRC.hh"
00021 #include "XrdOuc/XrdOucErrInfo.hh"
00022 #include "XrdOuc/XrdOucPup.hh"
00023 #include "XrdOuc/XrdOucTokenizer.hh"
00024 #include "XrdSecsss/XrdSecProtocolsss.hh"
00025 #include "XrdSys/XrdSysHeaders.hh"
00026 #include "XrdSys/XrdSysPlatform.hh"
00027 #include "XrdSys/XrdSysPthread.hh"
00028 
00029 /******************************************************************************/
00030 /*                               D e f i n e s                                */
00031 /******************************************************************************/
00032   
00033 #define XrdSecPROTOIDENT    "sss"
00034 #define XrdSecPROTOIDLEN    sizeof(XrdSecPROTOIDENT)
00035 #define XrdSecDEBUG         0x1000
00036 
00037 #define CLDBG(x) if (options & XrdSecDEBUG) cerr <<"sec_sss: " <<x <<endl;
00038 
00039 /******************************************************************************/
00040 /*                           S t a t i c   D a t a                            */
00041 /******************************************************************************/
00042 
00043 const char    *XrdSecProtocolsss::myName;
00044 int            XrdSecProtocolsss::myNLen;
00045 
00046 XrdCryptoLite *XrdSecProtocolsss::CryptObj   = 0;
00047 XrdSecsssKT   *XrdSecProtocolsss::ktObject   = 0;
00048 XrdSecsssID   *XrdSecProtocolsss::idMap      = 0;
00049 char          *XrdSecProtocolsss::staticID   = 0;
00050 int            XrdSecProtocolsss::staticIDsz = 0;
00051 int            XrdSecProtocolsss::options    = 0;
00052 int            XrdSecProtocolsss::isMutual   = 0;
00053 int            XrdSecProtocolsss::deltaTime  =13;
00054 int            XrdSecProtocolsss::ktFixed    = 0;
00055 
00056 struct XrdSecProtocolsss::Crypto XrdSecProtocolsss::CryptoTab[] = {
00057        {"bf32", XrdSecsssRR_Hdr::etBFish32},
00058        {0, '0'}
00059        };
00060 
00061 /******************************************************************************/
00062 /*                          A u t h e n t i c a t e                           */
00063 /******************************************************************************/
00064 
00065 int XrdSecProtocolsss::Authenticate(XrdSecCredentials *cred,
00066                                     XrdSecParameters **parms,
00067                                     XrdOucErrInfo     *einfo)
00068 {
00069    XrdSecsssRR_Hdr    *rrHdr = (XrdSecsssRR_Hdr *)(cred->buffer);
00070    XrdSecsssRR_Data    rrData;
00071    XrdSecsssKT::ktEnt  decKey;
00072    XrdSecEntity        myID("sss");
00073    char lidBuff[16],  eType, *idP, *dP, *eodP, *theHost = 0;
00074    int idTLen = 0, idSz, dLen;
00075 
00076 // Decode the credentials
00077 //
00078    if ((dLen = Decode(einfo, decKey, cred->buffer, &rrData, cred->size)) <= 0)
00079       return -1;
00080 
00081 // Check if we should echo back the LID
00082 //
00083    if (rrData.Options == XrdSecsssRR_Data::SndLID)
00084       {rrData.Options = 0;
00085        getLID(lidBuff, sizeof(lidBuff));
00086        dP = rrData.Data;
00087        *dP++ = XrdSecsssRR_Data::theLgid;
00088        XrdOucPup::Pack(&dP, lidBuff);
00089        *parms = Encode(einfo, decKey, rrHdr, &rrData, dP-(char *)&rrData);
00090        return (*parms ? 1 : -1);
00091       }
00092 
00093 // Extract out the entity ID
00094 //
00095    dP = rrData.Data; eodP = dLen + (char *)&rrData;
00096    while(dP < eodP)
00097         {eType = *dP++;
00098          if (!XrdOucPup::Unpack(&dP, eodP, &idP, idSz) || *idP == '\0')
00099             {Fatal(einfo, "Authenticate", EINVAL, "Invalid id string.");
00100              return -1;
00101             }
00102          idTLen += idSz;
00103          switch(eType)
00104                {case XrdSecsssRR_Data::theName: myID.name         = idP; break;
00105                 case XrdSecsssRR_Data::theVorg: myID.vorg         = idP; break;
00106                 case XrdSecsssRR_Data::theRole: myID.role         = idP; break;
00107                 case XrdSecsssRR_Data::theGrps: myID.grps         = idP; break;
00108                 case XrdSecsssRR_Data::theEndo: myID.endorsements = idP; break;
00109                 case XrdSecsssRR_Data::theHost: theHost           = idP; break;
00110                 case XrdSecsssRR_Data::theRand: idTLen -= idSz;          break;
00111                 default: Fatal(einfo,"Authenticate",EINVAL,"Invalid id type.");
00112                          return -1;
00113                }
00114         }
00115 
00116 // Verify that we have some kind of identification
00117 //
00118    if (!idTLen)
00119       {Fatal(einfo, "Authenticate", ENOENT, "No id specified.");
00120        return -1;
00121       }
00122 
00123 // Verify the source of the information to largely prevent packet stealing
00124 //
00125    if (!theHost)
00126       {Fatal(einfo, "Authenticate", ENOENT, "No hostname specified.");
00127        return -1;
00128       }
00129    if (strcmp(theHost, urName))
00130       {Fatal(einfo, "Authenticate", EINVAL, "Hostname mismatch.");
00131        return -1;
00132       }
00133 
00134 // Set correct username
00135 //
00136         if (decKey.Data.Opts & XrdSecsssKT::ktEnt::anyUSR)
00137            {if (!myID.name) myID.name = (char *)"nobody";}
00138    else myID.name = decKey.Data.User;
00139 
00140 // Set correct group
00141 //
00142          if (decKey.Data.Opts & XrdSecsssKT::ktEnt::usrGRP) myID.grps = 0;
00143    else {if (decKey.Data.Opts & XrdSecsssKT::ktEnt::anyGRP)
00144             {if (!myID.grps) myID.grps = (char *)"nogroup";}
00145             else myID.grps = decKey.Data.Grup;
00146         }
00147 
00148 // Complete constructing our identification
00149 //
00150    if (idBuff) free(idBuff);
00151    idBuff = idP = (char *)malloc(idTLen);
00152    Entity.name         = setID(myID.name,         &idP);
00153    Entity.vorg         = setID(myID.vorg,         &idP);
00154    Entity.role         = setID(myID.role,         &idP);
00155    Entity.grps         = setID(myID.grps,         &idP);
00156    Entity.endorsements = setID(myID.endorsements, &idP);
00157 
00158 // All done
00159 //
00160    return 0;
00161 }
00162 
00163 /******************************************************************************/
00164 /*                                D e l e t e                                 */
00165 /******************************************************************************/
00166   
00167 void XrdSecProtocolsss::Delete()
00168 {
00169 // Delete things that get re-allocated every time. The staticID is allocated
00170 // only once so it must stick around for every instance of this object.
00171 //
00172      if (Entity.host)         free(Entity.host);
00173      if (urName)              free(urName);
00174      if (idBuff)              free(idBuff);
00175      if (keyTab && keyTab != ktObject) delete keyTab;
00176 
00177      delete this;
00178 }
00179 
00180 /******************************************************************************/
00181 /*                                  e M s g                                   */
00182 /******************************************************************************/
00183 
00184 int XrdSecProtocolsss::eMsg(const char *epname, int rc,
00185                             const char *txt1, const char *txt2,
00186                             const char *txt3, const char *txt4)
00187 {
00188               cerr <<"Secsss (" << epname <<"): ";
00189               cerr <<txt1;
00190    if (rc>0)  cerr <<"; " <<strerror(rc);
00191    if (txt2)  cerr <<txt2;
00192    if (txt3)  cerr <<txt3;
00193    if (txt4)  cerr <<txt4;
00194               cerr <<endl;
00195 
00196    return (rc ? (rc < 0 ? rc : -rc) : -1);
00197 }
00198 
00199 /******************************************************************************/
00200 /*                                 F a t a l                                  */
00201 /******************************************************************************/
00202 
00203 int XrdSecProtocolsss::Fatal(XrdOucErrInfo *erP, const char *epn, int rc,
00204                                                  const char *etxt)
00205 {
00206    if (erP) {erP->setErrInfo(rc, etxt);
00207              CLDBG(epn <<": " <<etxt);
00208             }
00209       else  eMsg(epn, rc, etxt);
00210    return 0;
00211 }
00212 
00213 /******************************************************************************/
00214 /*                        g e t C r e d e n t i a l s                         */
00215 /******************************************************************************/
00216 
00217 XrdSecCredentials *XrdSecProtocolsss::getCredentials(XrdSecParameters *parms,
00218                                                       XrdOucErrInfo   *einfo)
00219 {
00220    XrdSecsssRR_Hdr    rrHdr;
00221    XrdSecsssRR_Data   rrData;
00222    XrdSecsssKT::ktEnt encKey;
00223    int dLen;
00224 
00225 // Get the actual data portion
00226 //
00227    if ((dLen=(Sequence ? getCred(einfo,rrData,parms) 
00228                        : getCred(einfo,rrData      )))<=0)
00229       return (XrdSecCredentials *)0;
00230 
00231 // Get an encryption key
00232 //
00233    if (keyTab->getKey(encKey))
00234       {Fatal(einfo, "getCredentials", ENOENT, "Encryption key not found.");
00235        return (XrdSecCredentials *)0;
00236       }
00237 
00238 // Fill out the header
00239 //
00240    strcpy(rrHdr.ProtID, XrdSecPROTOIDENT);
00241    memset(rrHdr.Pad, 0, sizeof(rrHdr.Pad));
00242    rrHdr.KeyID = htonll(encKey.Data.ID);
00243    rrHdr.EncType = Crypto->Type();
00244 
00245 // Now simply encode the data and return the result
00246 //
00247    return Encode(einfo, encKey, &rrHdr, &rrData, dLen);
00248 }
00249 
00250 /******************************************************************************/
00251 /*                           I n i t _ C l i e n t                            */
00252 /******************************************************************************/
00253 
00254 int XrdSecProtocolsss::Init_Client(XrdOucErrInfo *erp, const char *pP)
00255 {
00256    XrdSecsssKT *ktP;
00257    struct stat buf;
00258    char *Colon;
00259    int lifeTime;
00260 
00261 // We must have <enctype>:[<ktpath>]
00262 //
00263    if (!pP || !*pP) return Fatal(erp, "Init_Client", EINVAL,
00264                                  "Client parameters missing.");
00265 
00266 // Get encryption object
00267 //
00268    if (!*pP || *(pP+1) != '.') return Fatal(erp, "Init_Client", EINVAL,
00269                                  "Encryption type missing.");
00270    if (!(Crypto = Load_Crypto(erp, *pP))) return 0;
00271    pP += 2;
00272 
00273 // The next item is the cred lifetime
00274 //
00275    lifeTime = strtol(pP, &Colon, 10);
00276    if (!lifeTime || *Colon != ':') return Fatal(erp, "Init_Client", EINVAL,
00277                                           "Credential lifetime missing.");
00278    deltaTime = lifeTime; pP = Colon+1;
00279 
00280 // Get the correct keytab
00281 //
00282         if (ktFixed || (ktObject && ktObject->Same(pP))) keyTab = ktObject;
00283    else if (*pP == '/' && !stat(pP, &buf))
00284            {if (!(ktP=new XrdSecsssKT(erp,pP,XrdSecsssKT::isClient,3600)))
00285                return Fatal(erp, "Init_Client", ENOMEM,
00286                                  "Unable to create keytab object.");
00287             if (erp->getErrInfo()) {delete ktP; return 0;}
00288             if (!ktObject) ktObject = ktP;
00289             keyTab = ktP;
00290             CLDBG("Client keytab='" <<pP <<"'");
00291            } else keyTab = ktObject;
00292 
00293    if (!keyTab)
00294       return Fatal(erp, "Init_Client", ENOENT, 
00295                         "Unable to determine keytab location.");
00296 
00297 // All done
00298 //
00299    return 1;
00300 }
00301 
00302 
00303 /******************************************************************************/
00304 /*                           I n i t _ S e r v e r                            */
00305 /******************************************************************************/
00306 
00307 int XrdSecProtocolsss::Init_Server(XrdOucErrInfo *erp, const char *pP)
00308 {
00309 
00310 // This is a trivial init
00311 //
00312    keyTab = ktObject;
00313    Crypto = CryptObj;
00314    return 1;
00315 }
00316 
00317 /******************************************************************************/
00318 /*                           L o a d _ C l i e n t                            */
00319 /******************************************************************************/
00320   
00321 char *XrdSecProtocolsss::Load_Client(XrdOucErrInfo *erp, const char *parms)
00322 {
00323    static const char *KTPath = XrdSecsssKT::genFN();
00324    static const int   rfrHR = 60*60;
00325    struct stat buf;
00326    XrdSecsssID::authType aType = XrdSecsssID::idStatic;
00327    const char *kP = 0;
00328 
00329 // Get our full host name
00330 //
00331    if (!(myName = XrdNetDNS::getHostName()))
00332       {Fatal(erp, "Load_Client", ENOENT, "Unable to obtain local hostname.");
00333        return (char *)0;
00334       }
00335    myNLen = strlen(myName)+1;
00336 
00337 // Check for the presence of a registry object
00338 //
00339    idMap = XrdSecsssID::getObj(aType, &staticID, staticIDsz);
00340    switch(aType)
00341          {case XrdSecsssID::idDynamic:  isMutual = 1; break;
00342           case XrdSecsssID::idStaticM:  isMutual = 1;
00343           case XrdSecsssID::idStatic:
00344                default:                 idMap    = 0; break;
00345           }
00346 
00347 // We want to establish the default location of the keytable
00348 //
00349    if ((kP = getenv("XrdSecsssKT")) && *kP && !stat(kP, &buf)) ktFixed = 1;
00350       else kP = 0;
00351 
00352    if (!kP && !stat(KTPath, &buf)) kP = KTPath;
00353 
00354 // Build the keytable if we actual have a path (if none, then the server
00355 // will have to supply the path)
00356 //
00357    if (kP)
00358       {if (!(ktObject=new XrdSecsssKT(erp,kP,XrdSecsssKT::isClient,rfrHR)))
00359           {Fatal(erp, "Load_Client", ENOMEM, "Unable to create keytab object.");
00360            return (char *)0;
00361           }
00362        if (erp->getErrInfo())
00363           {delete ktObject, ktObject = 0; return (char *)0;}
00364        CLDBG("Client keytab='" <<kP <<"'");
00365       }
00366 
00367 // All done
00368 //
00369    return strdup("");
00370 }
00371   
00372 /******************************************************************************/
00373 /*                           L o a d _ C r y p t o                            */
00374 /******************************************************************************/
00375   
00376 XrdCryptoLite *XrdSecProtocolsss::Load_Crypto(XrdOucErrInfo *erp,
00377                                               const char    *eN)
00378 {
00379    XrdCryptoLite *cP;
00380    char buff[128];
00381    int rc, i = 0;
00382 
00383 // Find correct crypto object
00384 //
00385    while(CryptoTab[i].cName && strcmp(CryptoTab[i].cName, eN)) i++;
00386 
00387 // If we didn't find it, complain
00388 //
00389    if (!CryptoTab[i].cName)
00390       {sprintf(buff, "Secsss: %s cryptography not supported.", eN);
00391        Fatal(erp, "Load_Crypto", EINVAL, buff);
00392        return (XrdCryptoLite *)0;
00393       }
00394 
00395 // Return load result
00396 //
00397    if ((cP = XrdCryptoLite::Create(rc, eN, CryptoTab[i].cType))) return cP;
00398    sprintf(buff,"Secsss: %s cryptography load failed; %s",eN,strerror(rc));
00399    Fatal(erp, "Load_Crypto", EINVAL, buff);
00400    return (XrdCryptoLite *)0;
00401 }
00402 
00403 /******************************************************************************/
00404   
00405 XrdCryptoLite *XrdSecProtocolsss::Load_Crypto(XrdOucErrInfo *erp,
00406                                               const char     eT)
00407 {
00408    XrdCryptoLite *cP;
00409    char buff[128];
00410    int rc, i = 0;
00411 
00412 // Check if we can use the satic object
00413 //
00414    if (CryptObj && eT == CryptObj->Type()) return CryptObj;
00415 
00416 // Find correct crypto object
00417 //
00418    while(CryptoTab[i].cName && CryptoTab[i].cType != eT) i++;
00419 
00420 // If we didn't find it, complain
00421 //
00422    if (!CryptoTab[i].cName)
00423       {sprintf(buff, "Secsss: 0x%hhx cryptography not supported.", eT);
00424        Fatal(erp, "Load_Crypto", EINVAL, buff);
00425        return (XrdCryptoLite *)0;
00426       }
00427 
00428 // Return load result
00429 //
00430    if ((cP = XrdCryptoLite::Create(rc, CryptoTab[i].cName, eT))) return cP;
00431    sprintf(buff,"Secsss: 0x%hhx cryptography load failed; %s",eT,strerror(rc));
00432    Fatal(erp, "Load_Crypto", EINVAL, buff);
00433    return (XrdCryptoLite *)0;
00434 }
00435 
00436 /******************************************************************************/
00437 /*                           L o a d _ S e r v e r                            */
00438 /******************************************************************************/
00439   
00440 char *XrdSecProtocolsss::Load_Server(XrdOucErrInfo *erp, const char *parms)
00441 {
00442    const char *msg = 0;
00443    const char *encName = "bf32", *ktClient = "", *ktServer = 0;
00444    char buff[2048], parmbuff[2048], *op, *od, *eP;
00445    int lifeTime = 13, rfrTime = 60*60;
00446    XrdOucTokenizer inParms(parmbuff);
00447 
00448 // Duplicate the parms
00449 //
00450    if (parms) strlcpy(parmbuff, parms, sizeof(parmbuff));
00451 
00452 // Expected parameters: [-c <ckt_path>] [-e <enctype>]
00453 //                      [-r <minutes>] [-l <seconds>]  [-s <skt_path>]
00454 //
00455    if (parms && inParms.GetLine())
00456       while((op = inParms.GetToken()))
00457            {if (!(od = inParms.GetToken()))
00458                {sprintf(buff,"Secsss: Missing %s parameter argument",op);
00459                 msg = buff; break;
00460                }
00461                  if (!strcmp("-c", op)) ktClient = od;
00462             else if (!strcmp("-e", op)) encName  = od;
00463             else if (!strcmp("-l", op))
00464                     {lifeTime = strtol(od, &eP, 10) * 60;
00465                      if (errno || *eP || lifeTime < 1)
00466                         {msg = "Secsss: Invalid life time"; break;}
00467                     }
00468             else if (!strcmp("-r", op))
00469                     {rfrTime = strtol(od, &eP, 10) * 60;
00470                      if (errno || *eP || rfrTime < 600)
00471                         {msg = "Secsss: Invalid refresh time"; break;}
00472                     }
00473             else if (!strcmp("-s", op)) ktServer = od;
00474             else {sprintf(buff,"Secsss: Invalid parameter - %s",op);
00475                   msg = buff; break;
00476                  }
00477            }
00478 
00479 // Check for errors
00480 //
00481    if (msg) {Fatal(erp, "Load_Server", EINVAL, msg); return (char *)0;}
00482 
00483 // Load the right crypto object
00484 //
00485    if (!(CryptObj = Load_Crypto(erp, encName))) return (char *)0;
00486 
00487 // Supply default keytab location if not specified
00488 //
00489    if (!ktServer) ktServer = XrdSecsssKT::genFN();
00490 
00491 // Set the delta time used to expire credentials
00492 //
00493    deltaTime = lifeTime;
00494 
00495 // Create a keytab object (only one for the server)
00496 //
00497    if (!(ktObject = new XrdSecsssKT(erp, ktServer, XrdSecsssKT::isServer,
00498                                          rfrTime)))
00499       {Fatal(erp, "Load_Server", ENOMEM, "Unable to create keytab object.");
00500        return (char *)0;
00501       }
00502    if (erp->getErrInfo()) return (char *)0;
00503    ktFixed = 1;
00504    CLDBG("Server keytab='" <<ktServer <<"'");
00505 
00506 // Construct client parameter <enccode>:<keytab>
00507 //
00508    sprintf(buff, "%c.%d:%s", CryptObj->Type(), lifeTime, ktClient);
00509    CLDBG("client parms='" <<buff <<"'");
00510    return strdup(buff);
00511 }
00512   
00513 /******************************************************************************/
00514 /*                       P r i v a t e   M e t h o d s                        */
00515 /******************************************************************************/
00516 /******************************************************************************/
00517 /*                                D e c o d e                                 */
00518 /******************************************************************************/
00519 
00520 int                XrdSecProtocolsss::Decode(XrdOucErrInfo      *error,
00521                                              XrdSecsssKT::ktEnt &decKey,
00522                                              char               *iBuff,
00523                                              XrdSecsssRR_Data   *rrData,
00524                                              int                 iSize)
00525 {
00526    static const int maxLen = sizeof(XrdSecsssRR_Hdr) + sizeof(XrdSecsssRR_Data);
00527    static const int minLen = maxLen - XrdSecsssRR_Data::DataSz;
00528    XrdSecsssRR_Hdr  *rrHdr  = (XrdSecsssRR_Hdr  *)iBuff;
00529    int rc, genTime, dLen = iSize - sizeof(XrdSecsssRR_Hdr);
00530 
00531 // Verify that some credentials exist
00532 //
00533    if (iSize <= minLen || !iBuff || iSize >= maxLen)
00534       return Fatal(error,"Decode",EINVAL,"Credentials missing or of invalid size.");
00535 
00536 // Check if this is a recognized protocol
00537 //
00538    if (strcmp(rrHdr->ProtID, XrdSecPROTOIDENT))
00539       {char emsg[256];
00540        snprintf(emsg, sizeof(emsg),
00541                 "Authentication protocol id mismatch (%.4s != %.4s).",
00542                 XrdSecPROTOIDENT,  rrHdr->ProtID);
00543        return Fatal(error, "Decode", EINVAL, emsg);
00544       }
00545 
00546 // Verify decryption method
00547 //
00548    if (rrHdr->EncType != Crypto->Type())
00549       return Fatal(error, "Decode", ENOTSUP, "Crypto type not supported.");
00550 
00551 // Get the key
00552 //
00553    decKey.Data.ID = ntohll(rrHdr->KeyID);
00554    decKey.Data.Name[0] = '\0';
00555    if (keyTab->getKey(decKey))
00556       return Fatal(error, "Decode", ENOENT, "Decryption key not found.");
00557 
00558 // Decrypt
00559 //
00560    if ((rc = Crypto->Decrypt(decKey.Data.Val, decKey.Data.Len,
00561                              iBuff+sizeof(XrdSecsssRR_Hdr), dLen,
00562                              (char *)rrData, sizeof(XrdSecsssRR_Data))) <= 0)
00563       return Fatal(error, "Decode", -rc, "Unable to decrypt credentials.");
00564 
00565 // Verify that the packet has not expired (OK to do before CRC check)
00566 //
00567    genTime = ntohl(rrData->GenTime);
00568    if (genTime + deltaTime <= myClock())
00569       return Fatal(error, "Decode", ESTALE, "Credentials expired.");
00570 
00571 // Return success (size of decrypted info)
00572 //
00573    return rc;
00574 }
00575   
00576 /******************************************************************************/
00577 /*                                E n c o d e                                 */
00578 /******************************************************************************/
00579 
00580 XrdSecCredentials *XrdSecProtocolsss::Encode(XrdOucErrInfo      *einfo,
00581                                              XrdSecsssKT::ktEnt &encKey,
00582                                              XrdSecsssRR_Hdr    *rrHdr,
00583                                              XrdSecsssRR_Data   *rrData,
00584                                              int                 dLen)
00585 {
00586    static const int hdrSZ = sizeof(XrdSecsssRR_Hdr);
00587    char *credP, *eodP = ((char *)rrData) + dLen;
00588    int knum, cLen;
00589 
00590 // Make sure we have enought space left in the buffer
00591 //
00592    if (dLen > (int)sizeof(rrData->Data) - (16+myNLen))
00593       {Fatal(einfo,"Encode",ENOBUFS,"Insufficient buffer space for credentials.");
00594        return (XrdSecCredentials *)0;
00595       }
00596 
00597 // Add in our host name for source verification
00598 //
00599    if (myName)
00600       {*eodP++ = XrdSecsssRR_Data::theHost;
00601        XrdOucPup::Pack(&eodP, myName, myNLen);
00602        dLen = eodP - (char *)rrData;
00603       }
00604 
00605 // Make sure we have at least 128 bytes of encrypted data
00606 //
00607    if (dLen < 128)
00608       {char  rBuff[128];
00609        int   rLen = 128 - dLen;
00610        *eodP++ = XrdSecsssRR_Data::theRand;
00611        XrdSecsssKT::genKey(rBuff, rLen);
00612        XrdOucPup::Pack(&eodP, rBuff, rLen);
00613        dLen = eodP - (char *)rrData;
00614       }
00615 
00616 // Complete the packet
00617 //
00618    XrdSecsssKT::genKey(rrData->Rand, sizeof(rrData->Rand));
00619    rrData->GenTime = htonl(myClock());
00620    memset(rrData->Pad, 0, sizeof(rrData->Pad));
00621 
00622 // Allocate an output buffer
00623 //
00624    cLen = hdrSZ + dLen + Crypto->Overhead();
00625    if (!(credP = (char *)malloc(cLen)))
00626       {Fatal(einfo, "Encode", ENOMEM, "Insufficient memory for credentials.");
00627        return (XrdSecCredentials *)0;
00628       }
00629 
00630 // Copy the header and encrypt the data
00631 //
00632    memcpy(credP, (const void *)rrHdr, hdrSZ);
00633    if ((dLen = Crypto->Encrypt(encKey.Data.Val, encKey.Data.Len, (char *)rrData,
00634                                dLen, credP+hdrSZ, cLen-hdrSZ)) <= 0)
00635       {Fatal(einfo, "Encode", -dLen, "Unable to encrypt credentials.");
00636        return (XrdSecCredentials *)0;
00637       }
00638 
00639 // Return new credentials
00640 //
00641    dLen += hdrSZ; knum = encKey.Data.ID&0x7fffffff;
00642    CLDBG("Ret " <<dLen <<" bytes of credentials; k=" <<knum);
00643    return new XrdSecCredentials(credP, dLen);
00644 }
00645 
00646 /******************************************************************************/
00647 /*                               g e t C r e d                                */
00648 /******************************************************************************/
00649 
00650 int XrdSecProtocolsss::getCred(XrdOucErrInfo    *einfo,
00651                                XrdSecsssRR_Data &rrData)
00652 {
00653 // Indicate we have been here
00654 //
00655    Sequence = 1;
00656 
00657 // If we need mutual authentication
00658 //
00659    if (isMutual)
00660       {rrData.Options = XrdSecsssRR_Data::SndLID;
00661        return XrdSecsssRR_Data_HdrLen;
00662       }
00663 
00664 // Send the static ID
00665 //
00666    memcpy(rrData.Data, staticID, staticIDsz);
00667    rrData.Options = 0;
00668    return XrdSecsssRR_Data_HdrLen + staticIDsz;
00669 }
00670 
00671 /******************************************************************************/
00672 
00673 int XrdSecProtocolsss::getCred(XrdOucErrInfo    *einfo,
00674                                XrdSecsssRR_Data &rrData,
00675                                XrdSecParameters *parm)
00676 {
00677    XrdSecsssKT::ktEnt  decKey;
00678    XrdSecsssRR_Data    prData;
00679    char *lidP = 0, *idP, *dP, *eodP, idType;
00680    int lidSz, idSz, dLen;
00681 
00682 // Decode the credentials
00683 //
00684    if ((dLen = Decode(einfo, decKey, parm->buffer, &prData, parm->size)) <= 0)
00685       return -1;
00686 
00687 // The only thing allowed here is an echoed loginid
00688 //
00689    if (prData.Options 
00690    ||  dLen >= (int)sizeof(XrdSecsssRR_Data)
00691    ||  prData.Data[0] != XrdSecsssRR_Data::theLgid)
00692       return Fatal(einfo, "getCred", EINVAL, "Invalid server response.");
00693 
00694 // Extract out the loginid
00695 //
00696    dP = prData.Data; eodP = dLen + (char *)&prData;
00697    while(dP < eodP)
00698         {idType = *dP++;
00699          if (!XrdOucPup::Unpack(&dP, eodP, &idP, idSz) 
00700          ||  !idP || *idP == '\0')
00701             return Fatal(einfo, "getCred", EINVAL, "Invalid id string.");
00702          switch(idType)
00703                {case XrdSecsssRR_Data::theLgid: lidP = idP; lidSz = idSz; break;
00704                 case XrdSecsssRR_Data::theRand:                           break;
00705                 default: return Fatal(einfo,"getCred",EINVAL,"Invalid id type.");
00706                }
00707         }
00708 
00709 // Verify that we have the loginid
00710 //
00711    if (!lidP) return Fatal(einfo, "getCred", ENOENT, "No loginid specified.");
00712 
00713 // Try to map the id appropriately
00714 //
00715    if (!idMap)
00716       {if (staticID && staticIDsz < (int)sizeof(rrData.Data))
00717           {memcpy(rrData.Data, staticID, staticIDsz); 
00718            idSz = staticIDsz;
00719            return XrdSecsssRR_Data_HdrLen + idSz;
00720           }
00721        return Fatal(einfo, "getCred", ENAMETOOLONG, "Authinfo too big.");
00722       }
00723 
00724 // Map the loginid
00725 //
00726    if ((dLen = idMap->Find(lidP, rrData.Data, sizeof(rrData.Data))) <= 0)
00727       return Fatal(einfo, "getCred", ESRCH, "No loginid mapping.");
00728 
00729 // All done
00730 //
00731    rrData.Options = XrdSecsssRR_Data::UseData;
00732    return XrdSecsssRR_Data_HdrLen + dLen;
00733 }
00734 
00735 /******************************************************************************/
00736 /*                                g e t L I D                                 */
00737 /******************************************************************************/
00738   
00739 char *XrdSecProtocolsss::getLID(char *buff, int blen)
00740 {
00741    char *dot;
00742 
00743 // Extract out the loginid from the trace id
00744 //
00745    if (!Entity.tident 
00746    ||  !(dot = index(Entity.tident,'.'))
00747    ||  dot == Entity.tident
00748    ||  dot >= (Entity.tident+blen)) strcpy(buff,"nobody");
00749       else {int idsz = dot - Entity.tident;
00750             strncpy(buff, Entity.tident, idsz);
00751             *(buff+idsz) = '\0';
00752            }
00753 
00754 // All done
00755 //
00756    return buff;
00757 }
00758 
00759 /******************************************************************************/
00760 /*                               m y C l o c k                                */
00761 /******************************************************************************/
00762   
00763 int XrdSecProtocolsss::myClock()
00764 {
00765    static const time_t baseTime = 1222183880;
00766 
00767    return static_cast<int>(time(0)-baseTime);
00768 }
00769 
00770 /******************************************************************************/
00771 /*                                 s e t I D                                  */
00772 /******************************************************************************/
00773   
00774 char *XrdSecProtocolsss::setID(char *id, char **idP)
00775 {
00776    if (id)
00777       {int n = strlen(id);
00778        strcpy(*idP, id); id = *idP; *idP = *idP + n + 1;
00779       }
00780    return id;
00781 }
00782 
00783 /******************************************************************************/
00784 /*                 X r d S e c P r o t o c o l s s s I n i t                  */
00785 /******************************************************************************/
00786   
00787 extern "C"
00788 {
00789 char  *XrdSecProtocolsssInit(const char     mode,
00790                              const char    *parms,
00791                              XrdOucErrInfo *erp)
00792 {
00793 
00794 // Set debug option
00795 //
00796    if (getenv("XrdSecDEBUG")) XrdSecProtocolsss::setOpts(XrdSecDEBUG);
00797 
00798 // Perform load-time initialization
00799 //
00800    return (mode == 'c' ? XrdSecProtocolsss::Load_Client(erp, parms)
00801                        : XrdSecProtocolsss::Load_Server(erp, parms));
00802 }
00803 }
00804 
00805 /******************************************************************************/
00806 /*               X r d S e c P r o t o c o l s s s O b j e c t                */
00807 /******************************************************************************/
00808   
00809 extern "C"
00810 {
00811 XrdSecProtocol *XrdSecProtocolsssObject(const char              mode,
00812                                         const char             *hostname,
00813                                         const struct sockaddr  &netaddr,
00814                                         const char             *parms,
00815                                               XrdOucErrInfo    *erp)
00816 {
00817    XrdSecProtocolsss *prot;
00818    int Ok;
00819 
00820 // Get a new protocol object
00821 //
00822    if (!(prot = new XrdSecProtocolsss(hostname, &netaddr)))
00823       XrdSecProtocolsss::Fatal(erp, "sss_Object", ENOMEM,
00824                          "Secsss: Insufficient memory for protocol.");
00825       else {Ok = (mode == 'c' ? prot->Init_Client(erp, parms)
00826                               : prot->Init_Server(erp, parms));
00827 
00828             if (!Ok) {prot->Delete(); prot = 0;}
00829            }
00830 
00831 // All done
00832 //
00833    return (XrdSecProtocol *)prot;
00834 }
00835 }

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