XrdSecServer.cc

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                            */
00003 /*                       X r d S e c S e r v e r . c c                        */
00004 /*                                                                            */
00005 /* (c) 2005 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-AC03-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //       $Id: XrdSecServer.cc 38011 2011-02-08 18:35:57Z ganis $
00012 
00013 const char *XrdSecServerCVSID = "$Id: XrdSecServer.cc 38011 2011-02-08 18:35:57Z ganis $";
00014 
00015 #include <unistd.h>
00016 #include <ctype.h>
00017 #include <errno.h>
00018 #include <fcntl.h>
00019 #include <netdb.h>
00020 #include <stdlib.h>
00021 #include <strings.h>
00022 #include <stdio.h>
00023 #include <sys/param.h>
00024 
00025 #include "XrdNet/XrdNetDNS.hh"
00026 #include "XrdOuc/XrdOucEnv.hh"
00027 #include "XrdSys/XrdSysError.hh"
00028 #include "XrdOuc/XrdOucErrInfo.hh"
00029 #include "XrdSys/XrdSysLogger.hh"
00030 #include "XrdSys/XrdSysHeaders.hh"
00031 
00032 #include "XrdSec/XrdSecInterface.hh"
00033 #include "XrdSec/XrdSecServer.hh"
00034 #include "XrdSec/XrdSecTrace.hh"
00035 
00036 /******************************************************************************/
00037 /*                        X r d S e c P r o t B i n d                         */
00038 /******************************************************************************/
00039 
00040 class XrdSecProtBind 
00041 {
00042 public:
00043 XrdSecProtBind        *next;
00044 char                  *thost;
00045 int                    tpfxlen;
00046 char                  *thostsfx;
00047 int                    tsfxlen;
00048 XrdSecParameters       SecToken;
00049 XrdSecPMask_t          ValidProts;
00050 
00051 XrdSecProtBind        *Find(const char *hname);
00052 
00053 int                    Match(const char *hname);
00054 
00055                        XrdSecProtBind(char *th, char *st, XrdSecPMask_t pmask=0);
00056                       ~XrdSecProtBind()
00057                              {free(thost);
00058                               if (SecToken.buffer) free(SecToken.buffer);
00059                              }
00060 };
00061   
00062 /******************************************************************************/
00063 /*                           C o n s t r u c t o r                            */
00064 /******************************************************************************/
00065   
00066 XrdSecProtBind::XrdSecProtBind(char *th, char *st, XrdSecPMask_t pmask)
00067 {
00068    char *starp;
00069    next     = 0;
00070    thost    = th; 
00071    if (!(starp = index(thost, '*')))
00072       {tsfxlen = -1;
00073        thostsfx = (char *)0;
00074        tpfxlen = 0;
00075       } else {
00076        *starp = '\0';
00077        tpfxlen = strlen(thost);
00078        thostsfx = starp+1;
00079        tsfxlen = strlen(thostsfx);
00080       }
00081    if (st) {SecToken.buffer = strdup(st); SecToken.size = strlen(st);}
00082       else {SecToken.buffer = 0;          SecToken.size = 0;}
00083    ValidProts = (pmask ? pmask : ~(XrdSecPMask_t)0);
00084 }
00085  
00086 /******************************************************************************/
00087 /*                                  F i n d                                   */
00088 /******************************************************************************/
00089 
00090 XrdSecProtBind *XrdSecProtBind::Find(const char *hname)
00091 {
00092    XrdSecProtBind *bp = this;
00093 
00094    while(bp && !bp->Match(hname)) bp = bp->next;
00095 
00096    return bp;
00097 }
00098   
00099 /******************************************************************************/
00100 /*                                 M a t c h                                  */
00101 /******************************************************************************/
00102   
00103 int XrdSecProtBind::Match(const char *hname)
00104 {
00105     int i;
00106 
00107 // If an exact match wanted, return the result
00108 //
00109    if (tsfxlen < 0) return !strcmp(thost, hname);
00110 
00111 // Try to match the prefix
00112 //
00113    if (tpfxlen && strncmp(thost, hname, tpfxlen)) return 0;
00114 
00115 // If no suffix matching is wanted, then we have succeeded
00116 //
00117    if (!(thostsfx)) return 1;
00118 
00119 // Try to match the suffix
00120 //
00121    if ((i = (strlen(hname) - tsfxlen)) < 0) return 0;
00122    return !strcmp(&hname[i], thostsfx);
00123 }
00124 
00125 /******************************************************************************/
00126 /*                        X r d S e c P r o t P a r m                         */
00127 /******************************************************************************/
00128 
00129 class XrdSecProtParm
00130 {
00131 public:
00132 
00133        void            Add() {Next = First; First = this;}
00134 
00135        int             Cat(char *token);
00136 
00137 static XrdSecProtParm *Find(char *pid, int remove=0);
00138 
00139        int             Insert(char oct);
00140 
00141        int             isProto(char *proto) {return !strcmp(ProtoID, proto);}
00142 
00143        char           *Result(int &size) {size = bp-buff; return buff;}
00144 
00145        void            setProt(char *pid) {strcpy(ProtoID, pid);}
00146 
00147 static XrdSecProtParm *First;
00148        XrdSecProtParm *Next;
00149 
00150 char   ProtoID[XrdSecPROTOIDSIZE+1];
00151 
00152        XrdSecProtParm(XrdSysError *erp, const char *cid) : who(cid)
00153                      {*ProtoID = '\0';
00154                       bsize = 4096;
00155                       buff = (char *)malloc(bsize);
00156                       *buff = '\0';
00157                       bp   = buff;
00158                       eDest = erp;
00159                       Next = 0;
00160                      }
00161       ~XrdSecProtParm() {free(buff);}
00162 private:
00163 
00164 XrdSysError *eDest;
00165 int          bsize;
00166 char        *buff;
00167 char        *bp;
00168 const char  *who;
00169 };
00170 
00171 XrdSecProtParm *XrdSecProtParm::First = 0;
00172   
00173 /******************************************************************************/
00174 /*                                   C a t                                    */
00175 /******************************************************************************/
00176   
00177 int XrdSecProtParm::Cat(char *token)
00178 {
00179    int alen;
00180    alen = strlen(token);
00181    if (alen+1 > bsize-(bp-buff))
00182       {eDest->Emsg("Config",who,ProtoID,"argument string too long");
00183        return 0;
00184       }
00185    *bp++ = ' ';
00186    strcpy(bp, token); 
00187    bp += alen;
00188    return 1;
00189 }
00190 
00191 /******************************************************************************/
00192 /*                                  F i n d                                   */
00193 /******************************************************************************/
00194 
00195 XrdSecProtParm *XrdSecProtParm::Find(char *pid, int remove)
00196 {
00197    XrdSecProtParm *mp, *pp;
00198 
00199    mp = 0; pp = First;
00200    while(pp && !pp->isProto(pid)){mp = pp; pp = pp->Next;}
00201    if (pp && remove)
00202       {if (mp) mp->Next  = pp->Next;
00203           else First     = pp->Next;
00204       }
00205    return pp;
00206 }
00207   
00208 /******************************************************************************/
00209 /*                                I n s e r t                                 */
00210 /******************************************************************************/
00211   
00212 int XrdSecProtParm::Insert(char oct)
00213 {
00214    if (bsize-(bp-buff) < 1)
00215       {eDest->Emsg("Config",who,ProtoID,"argument string too long");
00216        return 0;
00217       }
00218    *bp++ = oct;
00219    return 1;
00220 }
00221 
00222 /******************************************************************************/
00223 /*                          X r d S e c S e r v e r                           */
00224 /******************************************************************************/
00225 XrdSecPManager XrdSecServer::PManager;
00226 /******************************************************************************/
00227 /*                           C o n s t r u c t o r                            */
00228 /******************************************************************************/
00229 XrdSecServer::XrdSecServer(XrdSysLogger *lp) : eDest(0, "sec_")
00230 {
00231 
00232 // Set default values
00233 //
00234    eDest.logger(lp);
00235    bpFirst     = 0;
00236    bpLast      = 0;
00237    bpDefault   = 0;
00238    STBlen      = 4096;
00239    STBuff      = (char *)malloc(STBlen);
00240   *STBuff      = '\0';
00241    SToken      = STBuff;
00242    SecTrace    = new XrdOucTrace(&eDest);
00243    if (getenv("XRDDEBUG") || getenv("XrdSecDEBUG")) SecTrace->What = TRACE_ALL;
00244    Enforce     = 0;
00245    implauth    = 0;
00246 }
00247   
00248 /******************************************************************************/
00249 /*                              g e t P a r m s                               */
00250 /******************************************************************************/
00251   
00252 const char *XrdSecServer::getParms(int &size, const char *hname)
00253 {
00254    EPNAME("getParms")
00255    XrdSecProtBind *bp;
00256 
00257 // Try to find a specific token binding for a host or return default binding
00258 //
00259    if (!hname) bp = 0;
00260       else if ((bp = bpFirst)) while(bp && !bp->Match(hname)) bp = bp->next;
00261 
00262 // If we have a binding, return that else return the default
00263 //
00264    if (!bp) bp = bpDefault;
00265    if (bp->SecToken.buffer) 
00266       {DEBUG(hname <<" sectoken=" <<bp->SecToken.buffer);
00267        size = bp->SecToken.size;
00268        return bp->SecToken.buffer;
00269       }
00270 
00271    DEBUG(hname <<" sectoken=''");
00272    size = 0;
00273    return (const char *)0;
00274 }
00275 
00276 /******************************************************************************/
00277 /*                           g e t P r o t o c o l                            */
00278 /******************************************************************************/
00279 
00280 XrdSecProtocol *XrdSecServer::getProtocol(const char              *host,
00281                                           const struct sockaddr   &hadr,
00282                                           const XrdSecCredentials *cred,
00283                                           XrdOucErrInfo           *einfo)
00284 {
00285    XrdSecProtBind *bp;
00286    XrdSecPMask_t pnum;
00287    XrdSecCredentials myCreds;
00288    const char *msgv[8];
00289 
00290 // If null credentials supplied, default to host protocol otherwise make sure
00291 // credentials data is actually supplied.
00292 //
00293    if (!cred) {myCreds.buffer=(char *)"host"; myCreds.size = 4; cred=&myCreds;}
00294       else if (cred->size < 1 || !(cred->buffer))
00295               {einfo->setErrInfo(EACCES,
00296                          (char *)"No authentication credentials supplied.");
00297                return 0;
00298               }
00299 
00300 // If protocol binding must be enforced, make sure the host is not using a
00301 // disallowed protocol.
00302 //
00303    if (Enforce)
00304       {if ((pnum = PManager.Find(cred->buffer)))
00305           {if (bpFirst && (bp = bpFirst->Find(host))
00306            &&  !(bp->ValidProts & pnum))
00307               {msgv[0] = host;
00308                msgv[1] = " not allowed to authenticate using ";
00309                msgv[2] = cred->buffer;
00310                msgv[3] = " protocol.";
00311                einfo->setErrInfo(EACCES, msgv, 4);
00312                return 0;
00313               }
00314           }
00315           else {msgv[0] = cred->buffer;
00316                 msgv[1] = " security protocol is not supported.";
00317                 einfo->setErrInfo(EPROTONOSUPPORT, msgv, 2);
00318                 return 0;
00319                }
00320       }
00321 
00322 // If we passed the protocol binding check, try to get an instance of the
00323 // protocol the host is using
00324 //
00325    return PManager.Get(host, hadr, cred->buffer, einfo);
00326 }
00327 
00328 /******************************************************************************/
00329 /*        C o n f i g   F i l e   P r o c e s s i n g   M e t h o d s         */
00330 /******************************************************************************/
00331 /******************************************************************************/
00332 /*                               d e f i n e s                                */
00333 /******************************************************************************/
00334 
00335 #define TS_Xeq(x,m)   if (!strcmp(x,var)) return m(Config,Eroute);
00336 
00337 #define TS_Str(x,m)   if (!strcmp(x,var)) {free(m); m = strdup(val); return 0;}
00338 
00339 #define TS_Chr(x,m)   if (!strcmp(x,var)) {m = val[0]; return 0;}
00340 
00341 #define TS_Bit(x,m,v) if (!strcmp(x,var)) {m = v; return 0;}
00342 
00343 #define Max(x,y) (x > y ? x : y)
00344 
00345 /******************************************************************************/
00346 /*                             C o n f i g u r e                              */
00347 /******************************************************************************/
00348   
00349 int XrdSecServer::Configure(const char *cfn)
00350 /*
00351   Function: Establish default values using a configuration file.
00352 
00353   Input:    None.
00354 
00355   Output:   0 upon success or !0 otherwise.
00356 */
00357 {
00358    int  NoGo;
00359    char *var;
00360 
00361 // Print warm-up message
00362 //
00363    eDest.Say("++++++ Authentication system initialization started.");
00364 
00365 // Perform initialization
00366 //
00367    NoGo = ConfigFile(cfn);
00368 
00369 // All done
00370 //
00371    var = (NoGo > 0 ? (char *)"failed." : (char *)"completed.");
00372    eDest.Say("------ Authentication system initialization ", var);
00373    return (NoGo > 0);
00374 }
00375 
00376 /******************************************************************************/
00377 /*                            C o n f i g F i l e                             */
00378 /******************************************************************************/
00379   
00380 int XrdSecServer::ConfigFile(const char *ConfigFN)
00381 /*
00382   Function: Establish default values using a configuration file.
00383 
00384   Input:    None.
00385 
00386   Output:   1 - Initialization failed.
00387             0 - Initialization succeeded.
00388 */
00389 {
00390    char *var;
00391    int  cfgFD, retc, NoGo = 0, recs = 0;
00392    XrdOucEnv myEnv;
00393    XrdOucStream Config(&eDest, getenv("XRDINSTANCE"), &myEnv, "=====> ");
00394    XrdSecProtParm *pp;
00395 
00396 // If there is no config file, return with the defaults sets.
00397 //
00398    if (!ConfigFN || !*ConfigFN)
00399      {eDest.Emsg("Config", "Authentication configuration file not specified.");
00400       return 1;
00401      }
00402 
00403 // Try to open the configuration file.
00404 //
00405    if ( (cfgFD = open(ConfigFN, O_RDONLY, 0)) < 0)
00406       {eDest.Emsg("Config", errno, "opening config file", ConfigFN);
00407        return 1;
00408       }
00409 
00410 // Now start reading records until eof.
00411 //
00412    Config.Attach(cfgFD); Config.Tabs(0);
00413    while((var = Config.GetMyFirstWord()))
00414         {if (!strncmp(var, "sec.", 4))
00415             {recs++;
00416              if (ConfigXeq(var+4, Config, eDest)) {Config.Echo(); NoGo = 1;}
00417             }
00418         }
00419 
00420 // Now check if any errors occured during file i/o
00421 //
00422    if ((retc = Config.LastError()))
00423       NoGo = eDest.Emsg("Config",-retc,"reading config file", ConfigFN);
00424       else {char buff[128];
00425             snprintf(buff, sizeof(buff), 
00426                      " %d authentication directives processed in ", recs);
00427             eDest.Say("Config", buff, ConfigFN);
00428            }
00429    Config.Close();
00430 
00431 // Determine whether we should initialize security
00432 //
00433    if (NoGo || ProtBind_Complete(eDest) ) NoGo = 1;
00434       else if ((pp = XrdSecProtParm::First))
00435               {NoGo = 1;
00436                while(pp) {eDest.Emsg("Config", "protparm", pp->ProtoID,
00437                                      "does not have a matching protocol.");
00438                           pp = pp->Next;
00439                          }
00440               }
00441 
00442 // All done
00443 //
00444    return NoGo;
00445 }
00446 
00447 /******************************************************************************/
00448 /*                       P r i v a t e   M e t h o d s                        */
00449 /******************************************************************************/
00450 /******************************************************************************/
00451 /*                             C o n f i g X e q                              */
00452 /******************************************************************************/
00453   
00454 int XrdSecServer::ConfigXeq(char *var, XrdOucStream &Config, XrdSysError &Eroute)
00455 {
00456 
00457     // Fan out based on the variable
00458     //
00459     TS_Xeq("protbind",      xpbind);
00460     TS_Xeq("protocol",      xprot);
00461     TS_Xeq("protparm",      xpparm);
00462     TS_Xeq("trace",         xtrace);
00463 
00464     // No match found, complain.
00465     //
00466     Eroute.Say("Config warning: ignoring unknown directive '",var,"'.");
00467     Config.Echo();
00468     return 0;
00469 }
00470   
00471 /******************************************************************************/
00472 /*                                x p b i n d                                 */
00473 /******************************************************************************/
00474 
00475 /* Function: xpbind
00476 
00477    Purpose:  To parse the directive: protbind <thost> [none | [only] <plist>]
00478 
00479              <thost> is a templated host name (e.g., bronco*.slac.stanford.edu)
00480              <plist> are the protocols to be bound to the <thost>. A special
00481                      protocol, none, indicates that no token is to be passed.
00482 
00483    Output: 0 upon success or !0 upon failure.
00484 */
00485 
00486 int XrdSecServer::xpbind(XrdOucStream &Config, XrdSysError &Eroute)
00487 {
00488     EPNAME("xpbind")
00489     char *val, *thost;
00490     XrdSecProtBind *bnow;
00491     char sectoken[4096], *secbuff = sectoken;
00492     int isdflt = 0, only = 0, anyprot = 0, noprot = 0, phost = 0;
00493     int sectlen = sizeof(sectoken)-1;
00494     XrdSecPMask_t PMask = 0;
00495     *secbuff = '\0';
00496 
00497 // Get the template host
00498 //
00499    val = Config.GetWord();
00500    if (!val || !val[0])
00501       {Eroute.Emsg("Config","protbind host not specified"); return 1;}
00502 
00503 // Verify that this host has not been bound before
00504 //
00505    if ((isdflt = !strcmp("*", val))) bnow = bpDefault;
00506       else {bnow = bpFirst;
00507             while(bnow) if (!strcmp(bnow->thost, val)) break;
00508                            else bnow = bnow->next;
00509            }
00510    if (bnow) {Eroute.Emsg("Config","duplicate protbind definition - ", val);
00511               return 1;
00512              }
00513    thost = strdup(val);
00514 
00515 // Now get each protocol to be used (there must be one).
00516 //
00517    while((val = Config.GetWord()))
00518         {if (!strcmp(val, "none")) {noprot = 1; break;}
00519               if (!strcmp(val, "only")) {only = 1; Enforce = 1;}
00520          else if (!strcmp(val, "host")) {phost = 1; anyprot = 1;}
00521          else if (!PManager.Find(val))
00522                  {Eroute.Emsg("Config","protbind", val,
00523                               "protocol not previously defined.");
00524                   return 1;
00525                  }
00526          else if (add2token(Eroute, val, &secbuff, sectlen, PMask))
00527                  {Eroute.Emsg("Config","Unable to bind protocols to",thost);
00528                   return 1;
00529                  } else anyprot = 1;
00530         }
00531 
00532 // Verify that no conflicts arose
00533 //
00534    if (val && (val = Config.GetWord()))
00535       {Eroute.Emsg("Config","conflicting protbind:", thost, val);
00536        return 1;
00537       }
00538 
00539 // Make sure we have some protocols bound to this host
00540 //
00541    if (!(anyprot || noprot))
00542       {Eroute.Emsg("Config","no protocols bound to", thost); return 1;}
00543    DEBUG("XrdSecConfig: Bound "<< thost<< " to "
00544          << (noprot ? "none" : (phost ? "host" : sectoken)));
00545 
00546 // Issue warning if the host protocol was bound to this host but other
00547 // protocols were also bound, making them rather useless.
00548 //
00549    if (phost && *sectoken)
00550       {Eroute.Say("Config warning: 'protbind", thost,
00551                           "host' negates all other bound protocols.");
00552        *sectoken = '\0';
00553       }
00554 
00555 // Translate "localhost" to our local hostname
00556 //
00557    if (!strcmp("localhost", thost))
00558       {free(thost); thost = XrdNetDNS::getHostName();}
00559 
00560 // Create new bind object
00561 //
00562    bnow = new XrdSecProtBind(thost,(noprot ? 0:sectoken),(only ? PMask:0));
00563 
00564 // Push the entry onto our bindings
00565 //
00566    if (isdflt) bpDefault = bnow;
00567       else {if (bpLast) bpLast->next = bnow;
00568                else bpFirst = bnow;
00569             bpLast = bnow;
00570            }
00571 
00572 // All done
00573 //
00574    return 0;
00575 }
00576 
00577 /******************************************************************************/
00578 /*                                 x p r o t                                  */
00579 /******************************************************************************/
00580 
00581 /* Function: xprot
00582 
00583    Purpose:  To parse the directive: protocol [<path>] <pid> [ <opts> ]
00584 
00585              <path> is the absolute path where the protocol library resides
00586              <pid>  is the 1-to-8 character protocol id.
00587              <opts> are the associated protocol specific options such as:
00588                     noipcheck         - don't check ip address origin
00589                     keyfile <kfn>     - the key file associated with protocol
00590                     args <args>       - associated non-blank arguments
00591                     Additional arguments may be passed to the protocol using the
00592                     protargs directive. ALl protargs directives must appear
00593                     prior to the protocol directive for the given protocol.
00594 
00595    Output: 0 upon success or !0 upon failure.
00596 */
00597 
00598 int XrdSecServer::xprot(XrdOucStream &Config, XrdSysError &Eroute)
00599 {
00600     XrdSecProtParm *pp, myParms(&Eroute, "protocol");
00601     char *pap, *val, pid[XrdSecPROTOIDSIZE+1], *args = 0;
00602     char pathbuff[1024], *path = 0;
00603     int psize;
00604     XrdOucErrInfo erp;
00605     XrdSecPMask_t mymask = 0;
00606 
00607 // Get the protocol id
00608 //
00609    val = Config.GetWord();
00610    if (val && *val == '/')
00611       {strlcpy(pathbuff, val, sizeof(pathbuff)); path = pathbuff;
00612        val = Config.GetWord();
00613       }
00614    if (!val || !val[0])
00615       {Eroute.Emsg("Config","protocol id not specified"); return 1;}
00616 
00617 // Verify that we don't have this protocol
00618 //
00619    if (strlen(val) > XrdSecPROTOIDSIZE)
00620       {Eroute.Emsg("Config","protocol id too long - ", val); return 1;}
00621 
00622    if (PManager.Find(val))
00623       {Eroute.Say("Config warning: protocol ",val," previously defined.");
00624        strcpy(pid, val);
00625        return add2token(Eroute, pid, &STBuff, STBlen, mymask);}
00626 
00627 // The builtin host protocol does not accept any parameters. Additionally, the
00628 // host protocol negates any other protocols we may have in the default set.
00629 //
00630    if (!strcmp("host", val))
00631       {if (Config.GetWord())
00632           {Eroute.Emsg("Config", "Builtin host protocol does not accept parms.");
00633            return 1;
00634           }
00635        implauth = 1;
00636        return 0;
00637       }
00638 
00639 // Grab additional parameters that we here and that we have accumulated
00640 //
00641    strcpy(pid, val);
00642    while((args = Config.GetWord())) if (!myParms.Cat(args)) return 1;
00643    if ((pp = myParms.Find(pid, 1)))
00644       {if ((*myParms.Result(psize) && !myParms.Insert('\n'))
00645        ||  !myParms.Cat(pp->Result(psize))) return 1;
00646           else delete pp;
00647       }
00648 
00649 // Load this protocol
00650 //
00651    pap = myParms.Result(psize);
00652    if (!PManager.Load(&erp, 's', pid, (psize ? pap : 0), path))
00653       {Eroute.Emsg("Config", erp.getErrText()); return 1;}
00654 
00655 // Add this protocol to the default security token
00656 //
00657    return add2token(Eroute, pid, &STBuff, STBlen, mymask);
00658 }
00659   
00660 /******************************************************************************/
00661 /*                                x p p a r m                                 */
00662 /******************************************************************************/
00663 
00664 /* Function: xpparm
00665 
00666    Purpose:  To parse the directive: protparm <prot> <args>
00667 
00668              <prot>  is the name of the protocol to which these args apply.
00669              <args>  are the protocol specific parameters. The remaing tokens
00670                      on the line will be passed to the protocol at during
00671                      protocol initialization. Each such line is separated by
00672                      a new line character.
00673 
00674    Output: 0 upon success or !0 upon failure.
00675 */
00676 
00677 int XrdSecServer::xpparm(XrdOucStream &Config, XrdSysError &Eroute)
00678 {
00679     XrdSecProtParm *pp;
00680     char *val, pid[XrdSecPROTOIDSIZE+1];
00681 
00682 // Get the protocol name
00683 //
00684    val = Config.GetWord();
00685    if (!val || !val[0])
00686       {Eroute.Emsg("Config","protparm protocol not specified"); return 1;}
00687 
00688 // The builtin host protocol does not accept any parameters
00689 //
00690    if (!strcmp("host", val))
00691       {Eroute.Emsg("Config", "Builtin host protocol does not accept protparms.");
00692        return 1;
00693       }
00694 
00695 // Verify that we don't have this protocol
00696 //
00697    if (strlen(val) > XrdSecPROTOIDSIZE)
00698       {Eroute.Emsg("Config","protocol id too long - ", val); return 1;}
00699 
00700    if (PManager.Find(val))
00701       {Eroute.Emsg("Config warning: protparm protocol ",val," already defined.");
00702        return 0;
00703       }
00704 
00705    strcpy(pid, val);
00706 
00707 // Make sure we have at least one parameter here
00708 //
00709    if (!(val = Config.GetWord()))
00710       {Eroute.Emsg("Config","protparm", pid, "parameter not specified");
00711        return 1;
00712       }
00713 
00714 // Try to find a previous incarnation of this parm
00715 //
00716    if ((pp = XrdSecProtParm::Find(pid))) {if (!pp->Insert('\n')) return 1;}
00717       else {pp = new XrdSecProtParm(&Eroute, "protparm");
00718             pp->setProt(pid);
00719             pp->Add();
00720            }
00721 
00722 // Grab the options for the protocol. They are pretty much opaque to us here
00723 //
00724   do {if (!pp->Cat(val)) return 1;} while((val = Config.GetWord()));
00725   return 0;
00726 }
00727   
00728 /******************************************************************************/
00729 /*                                x t r a c e                                 */
00730 /******************************************************************************/
00731 
00732 /* Function: xtrace
00733 
00734    Purpose:  To parse the directive: trace <events>
00735 
00736              <events> the blank separated list of events to trace. Trace
00737                       directives are cummalative.
00738 
00739    Output: 0 upon success or !0 upon failure.
00740 */
00741 
00742 int XrdSecServer::xtrace(XrdOucStream &Config, XrdSysError &Eroute)
00743 {
00744     static struct traceopts {const char *opname; int opval;} tropts[] =
00745        {
00746         {"all",            TRACE_ALL},
00747         {"debug",          TRACE_Debug},
00748         {"auth",           TRACE_Authen},
00749         {"authentication", TRACE_Authen}
00750        };
00751     int i, neg, trval = 0, numopts = sizeof(tropts)/sizeof(struct traceopts);
00752     char *val;
00753 
00754     val = Config.GetWord();
00755     if (!val || !val[0])
00756        {Eroute.Emsg("Config", "trace option not specified"); return 1;}
00757     while (val && val[0])
00758          {if (!strcmp(val, "off")) trval = 0;
00759              else {if ((neg = (val[0] == '-' && val[1]))) val++;
00760                    for (i = 0; i < numopts; i++)
00761                        {if (!strcmp(val, tropts[i].opname))
00762                            {if (neg) trval &= ~tropts[i].opval;
00763                                else  trval |=  tropts[i].opval;
00764                             break;
00765                            }
00766                        }
00767                    if (i >= numopts)
00768                       Eroute.Say("Config warning: ignoring invalid trace option '", val, "'.");
00769                   }
00770           val = Config.GetWord();
00771          }
00772 
00773     SecTrace->What = (SecTrace->What & ~TRACE_Authenxx) | trval;
00774 
00775 // Propogate the debug option
00776 //
00777 #ifndef NODEBUG
00778    if (QTRACE(Debug)) PManager.setDebug(1);
00779       else            PManager.setDebug(0);
00780 #endif
00781     return 0;
00782 }
00783 
00784 /******************************************************************************/
00785 /*                         M i s c e l l a n e o u s                          */
00786 /******************************************************************************/
00787 /******************************************************************************/
00788 /*                             a d d 2 t o k e n                              */
00789 /******************************************************************************/
00790 
00791 int XrdSecServer::add2token(XrdSysError &Eroute, char *pid,
00792                             char **tokbuff, int &toklen, XrdSecPMask_t &pmask)
00793 {
00794     int i;
00795     char *pargs;
00796     XrdSecPMask_t protnum;
00797 
00798 // Find the protocol argument string
00799 //
00800    if (!(protnum = PManager.Find(pid, &pargs)))
00801       {Eroute.Emsg("Config","Protocol",pid,"not found after being added!");
00802        return 1;
00803       }
00804 
00805 // Make sure we have enough room to add
00806 //
00807    i = 4+strlen(pid)+strlen(pargs);
00808    if (i >= toklen)
00809       {Eroute.Emsg("Config","Protocol",pid,"parms exceed overall maximum!");
00810        return 1;
00811       }
00812 
00813 // Insert protocol specification (we already checked for an overflow)
00814 //
00815    i = sprintf(*tokbuff, "&P=%s%s%s", pid, (*pargs ? "," : ""), pargs);
00816    toklen   -= i;
00817    *tokbuff += i;
00818    pmask    |= protnum;
00819    return 0;
00820 }
00821   
00822 /******************************************************************************/
00823 /*                     P r o t B i n d _ C o m p l e t e                      */
00824 /******************************************************************************/
00825   
00826 int XrdSecServer::ProtBind_Complete(XrdSysError &Eroute)
00827 {
00828     EPNAME("ProtBind_Complete")
00829     XrdOucErrInfo erp;
00830 
00831 // Check if we have a default token, create one otherwise
00832 //
00833    if (!bpDefault)
00834       {if (!*SToken) {Eroute.Say("Config warning: No protocols defined; "
00835                                   "only host authentication available.");
00836                       implauth = 1;
00837                      }
00838           else if (implauth)
00839                   {Eroute.Say("Config warning: enabled builtin host "
00840                    "protocol negates default use of any other protocols.");
00841                    *SToken = '\0';
00842                   }
00843        bpDefault = new XrdSecProtBind(strdup("*"), SToken);
00844        DEBUG("Default sectoken built: '" <<SToken <<"'");
00845       }
00846 
00847 // Add the host protocol to the set at this point to allow clients to
00848 // actually give use "host" as a protocol id if it's allowed. We do this so
00849 // that the right error message is generated. Otherwise, it ignored.
00850 //
00851    if (implauth && !PManager.Load(&erp, 's', "host", 0, 0))
00852       {Eroute.Emsg("Config", erp.getErrText()); return 1;}
00853 
00854 // Free up the constructed default sectoken
00855 //
00856    free(SToken); SToken = STBuff = 0; STBlen = 0;
00857    return 0;
00858 }
00859  
00860 /******************************************************************************/
00861 /*                      X r d S e c g e t S e r v i c e                       */
00862 /******************************************************************************/
00863 
00864 extern "C"
00865 {
00866 XrdSecService *XrdSecgetService(XrdSysLogger *lp, const char *cfn)
00867 {
00868    XrdSecServer *SecServer = new XrdSecServer(lp);
00869 
00870 // Configure the server object
00871 //
00872    if (SecServer->Configure(cfn)) return 0;
00873 
00874 // Return the server object
00875 //
00876    return (XrdSecService *)SecServer;
00877 }
00878 }

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