xrootd
XrdSecProtocolgsi.hh
Go to the documentation of this file.
00001 // $Id$
00002 /******************************************************************************/
00003 /*                                                                            */
00004 /*                 X r d S e c P r o t o c o l g s i . h h                    */
00005 /*                                                                            */
00006 /* (c) 2005 G. Ganis / CERN                                                   */
00007 /*                                                                            */
00008 /******************************************************************************/
00009 #include <XrdOuc/XrdOucErrInfo.hh>
00010 #include <XrdSys/XrdSysPthread.hh>
00011 #include <XrdOuc/XrdOucString.hh>
00012 #include <XrdOuc/XrdOucTokenizer.hh>
00013 
00014 #include <XrdSec/XrdSecInterface.hh>
00015 #include <XrdSecgsi/XrdSecgsiTrace.hh>
00016 
00017 #include <XrdSut/XrdSutPFEntry.hh>
00018 #include <XrdSut/XrdSutPFile.hh>
00019 #include <XrdSut/XrdSutBuffer.hh>
00020 #include <XrdSut/XrdSutRndm.hh>
00021 
00022 #include <XrdCrypto/XrdCryptoAux.hh>
00023 #include <XrdCrypto/XrdCryptoCipher.hh>
00024 #include <XrdCrypto/XrdCryptoFactory.hh>
00025 #include <XrdCrypto/XrdCryptoX509Crl.hh>
00026 
00027 #include <XrdCrypto/XrdCryptosslgsiX509Chain.hh>
00028 
00029 /******************************************************************************/
00030 /*                               D e f i n e s                                */
00031 /******************************************************************************/
00032 
00033 typedef XrdOucString String;
00034 typedef XrdCryptosslgsiX509Chain X509Chain;
00035   
00036 #define XrdSecPROTOIDENT    "gsi"
00037 #define XrdSecPROTOIDLEN    sizeof(XrdSecPROTOIDENT)
00038 #define XrdSecgsiVERSION    10300
00039 #define XrdSecNOIPCHK       0x0001
00040 #define XrdSecDEBUG         0x1000
00041 #define XrdCryptoMax        10
00042 
00043 #define kMAXBUFLEN          1024
00044 
00045 //
00046 // Message codes either returned by server or included in buffers
00047 enum kgsiStatus {
00048    kgST_error    = -1,      // error occured
00049    kgST_ok       =  0,      // ok
00050    kgST_more     =  1       // need more info
00051 };
00052 
00053 // Client steps
00054 enum kgsiClientSteps {
00055    kXGC_none = 0,
00056    kXGC_certreq     = 1000, // 1000: request server certificate
00057    kXGC_cert,               // 1001: packet with (proxy) certificate
00058    kXGC_sigpxy,             // 1002: packet with signed proxy certificate
00059    kXGC_reserved            // 
00060 };
00061 
00062 // Server steps
00063 enum kgsiServerSteps {
00064    kXGS_none = 0,
00065    kXGS_init       = 2000,   // 2000: fake code used the first time 
00066    kXGS_cert,                // 2001: packet with certificate 
00067    kXGS_pxyreq,              // 2002: packet with proxy req to be signed 
00068    kXGS_reserved             //
00069 };
00070 
00071 // Handshake options
00072 enum kgsiHandshakeOpts {
00073    kOptsDlgPxy     = 1,      // 0x0001: Ask for a delegated proxy
00074    kOptsFwdPxy     = 2,      // 0x0002: Forward local proxy
00075    kOptsSigReq     = 4,      // 0x0004: Accept to sign delegated proxy
00076    kOptsSrvReq     = 8,      // 0x0008: Server request for delegated proxy
00077    kOptsPxFile     = 16,     // 0x0010: Save delegated proxies in file
00078    kOptsDelChn     = 32      // 0x0020: Delete chain
00079 };
00080 
00081 // Error codes
00082 enum kgsiErrors {
00083    kGSErrParseBuffer = 10000,       // 10000
00084    kGSErrDecodeBuffer,              // 10001
00085    kGSErrLoadCrypto,                // 10002
00086    kGSErrBadProtocol,               // 10003
00087    kGSErrCreateBucket,              // 10004
00088    kGSErrDuplicateBucket,           // 10005
00089    kGSErrCreateBuffer,              // 10006
00090    kGSErrSerialBuffer,              // 10007
00091    kGSErrGenCipher,                 // 10008
00092    kGSErrExportPuK,                 // 10009
00093    kGSErrEncRndmTag,                // 10010
00094    kGSErrBadRndmTag,                // 10011
00095    kGSErrNoRndmTag,                 // 10012
00096    kGSErrNoCipher,                  // 10013
00097    kGSErrNoCreds,                   // 10014
00098    kGSErrBadOpt,                    // 10015
00099    kGSErrMarshal,                   // 10016
00100    kGSErrUnmarshal,                 // 10017
00101    kGSErrSaveCreds,                 // 10018
00102    kGSErrNoBuffer,                  // 10019
00103    kGSErrRefCipher,                 // 10020
00104    kGSErrNoPublic,                  // 10021
00105    kGSErrAddBucket,                 // 10022
00106    kGSErrFinCipher,                 // 10023
00107    kGSErrInit,                      // 10024
00108    kGSErrBadCreds,                  // 10025
00109    kGSErrError                      // 10026  
00110 };
00111 
00112 #define REL1(x)     { if (x) delete x; }
00113 #define REL2(x,y)   { if (x) delete x; if (y) delete y; }
00114 #define REL3(x,y,z) { if (x) delete x; if (y) delete y; if (z) delete z; }
00115 
00116 #define SafeDelete(x) { if (x) delete x ; x = 0; }
00117 #define SafeDelArray(x) { if (x) delete [] x ; x = 0; }
00118 #define SafeFree(x) { if (x) free(x) ; x = 0; }
00119 
00120 // External functions for generic mapping
00121 typedef char *(*XrdSecgsiGMAP_t)(const char *, int);
00122 typedef int (*XrdSecgsiAuthz_t)(XrdSecEntity &);
00123 typedef int (*XrdSecgsiAuthzInit_t)(const char *);
00124 typedef int (*XrdSecgsiAuthzKey_t)(XrdSecEntity &, char **);
00125 
00126 //
00127 // This a small class to set the relevant options in one go
00128 //
00129 class XrdOucTrace;
00130 class gsiOptions {
00131 public:
00132    short  debug;  // [cs] debug flag
00133    char   mode;   // [cs] 'c' or 's'
00134    char  *clist;  // [s] list of crypto modules ["ssl" ]
00135    char  *certdir;// [cs] dir with CA info [/etc/grid-security/certificates]
00136    char  *crldir; // [cs] dir with CRL info [/etc/grid-security/certificates]
00137    char  *crlext; // [cs] extension of CRL files [.r0]
00138    char  *cert;   // [s] server certificate [/etc/grid-security/root/rootcert.pem]
00139                   // [c] user certificate [$HOME/.globus/usercert.pem]
00140    char  *key;    // [s] server private key [/etc/grid-security/root/rootkey.pem]
00141                   // [c] user private key [$HOME/.globus/userkey.pem]
00142    char  *cipher; // [s] list of ciphers [aes-128-cbc:bf-cbc:des-ede3-cbc]
00143    char  *md;     // [s] list of MDs [sha1:md5]
00144    int    crl;    // [cs] check level of CRL's [1] 
00145    int    ca;     // [cs] verification level of CA's [1] 
00146    int    crlrefresh; // [cs] CRL refresh or expiration period in secs [1 day] 
00147    char  *proxy;  // [c] user proxy  [/tmp/x509up_u<uid>]
00148    char  *valid;  // [c] proxy validity  [12:00]
00149    int    deplen; // [c] depth of signature path for proxies [0] 
00150    int    bits;   // [c] bits in PKI for proxies [512] 
00151    char  *gridmap;// [s] gridmap file [/etc/grid-security/gridmap]
00152    int    gmapto; // [s] validity in secs of grid-map cache entries [-1 => unlimited]
00153    char  *gmapfun;// [s] file with the function to map DN to usernames [0]
00154    char  *gmapfunparms;// [s] parameters for the function to map DN to usernames [0]
00155    char  *authzfun;// [s] file with the function to fill entities [0]
00156    char  *authzfunparms;// [s] parameters for the function to fill entities [0]
00157    int    authzto; // [s] validity in secs of authz cache entries [-1 => unlimited]
00158    int    ogmap;  // [s] gridmap file checking option 
00159    int    dlgpxy; // [c] explicitely ask the creation of a delegated proxy 
00160                   // [s] ask client for proxies
00161    int    sigpxy; // [c] accept delegated proxy requests 
00162    char  *srvnames;// [c] '|' separated list of allowed server names
00163    char  *exppxy; // [s] template for the exported file with proxies (dlgpxy == 3)
00164    int    authzpxy; // [s] if 1 make proxy available in exported form in the 'endorsement'
00165                     //     field of the XrdSecEntity object for use in XrdAcc
00166    int    vomsat; // [s] 0 do not look for; 1 extract if any
00167    int    moninfo; // [s] 0 do not look for; 1 use DN as default
00168 
00169    gsiOptions() { debug = -1; mode = 's'; clist = 0; 
00170                   certdir = 0; crldir = 0; crlext = 0; cert = 0; key = 0;
00171                   cipher = 0; md = 0; ca = 1 ; crl = 1; crlrefresh = 86400;
00172                   proxy = 0; valid = 0; deplen = 0; bits = 512;
00173                   gridmap = 0; gmapto = -1;
00174                   gmapfun = 0; gmapfunparms = 0; authzfun = 0; authzfunparms = 0; authzto = -1;
00175                   ogmap = 1; dlgpxy = 0; sigpxy = 1; srvnames = 0;
00176                   exppxy = 0; authzpxy = 0; vomsat = 1; moninfo = 0;}
00177    virtual ~gsiOptions() { } // Cleanup inside XrdSecProtocolgsiInit
00178    void Print(XrdOucTrace *t); // Print summary of gsi option status
00179 };
00180 
00181 class XrdSecProtocolgsi;
00182 class gsiHSVars {
00183 public:
00184    int               Iter;          // iteration number
00185    int               TimeStamp;     // Time of last call
00186    String            CryptoMod;     // crypto module in use
00187    int               RemVers;       // Version run by remote counterpart
00188    XrdCryptoCipher  *Rcip;          // reference cipher
00189    XrdSutBucket     *Cbck;          // Bucket with the certificate in export form
00190    String            ID;            // Handshake ID (dummy for clients)
00191    XrdSutPFEntry    *Cref;          // Cache reference
00192    XrdSutPFEntry    *Pent;          // Pointer to relevant file entry 
00193    X509Chain        *Chain;         // Chain to be eventually verified 
00194    XrdCryptoX509Crl *Crl;           // Pointer to CRL, if required 
00195    X509Chain        *PxyChain;      // Proxy Chain on clients
00196    bool              RtagOK;        // Rndm tag checked / not checked
00197    bool              Tty;           // Terminal attached / not attached
00198    int               LastStep;      // Step required at previous iteration
00199    int               Options;       // Handshake options;
00200    XrdSutBuffer     *Parms;         // Buffer with server parms on first iteration 
00201 
00202    gsiHSVars() { Iter = 0; TimeStamp = -1; CryptoMod = "";
00203                  RemVers = -1; Rcip = 0;
00204                  Cbck = 0;
00205                  ID = ""; Cref = 0; Pent = 0; Chain = 0; Crl = 0; PxyChain = 0;
00206                  RtagOK = 0; Tty = 0; LastStep = 0; Options = 0; Parms = 0;}
00207 
00208    ~gsiHSVars() { SafeDelete(Cref);
00209                   if (Options & kOptsDelChn) {
00210                      // Do not delete the CA certificate in the cached reference
00211                      if (Chain) Chain->Cleanup(1);
00212                      SafeDelete(Chain);
00213                   }
00214                   // The proxy chain is owned by the proxy cache; invalid proxies are
00215                   // detected (and eventually removed) by QueryProxy
00216                   PxyChain = 0;
00217                   SafeDelete(Parms); }
00218    void Dump(XrdSecProtocolgsi *p = 0);
00219 };
00220 
00221 // From a proxy query
00222 typedef struct {
00223    X509Chain        *chain;
00224    XrdCryptoRSA     *ksig;
00225    XrdSutBucket     *cbck;
00226 } ProxyOut_t;
00227 
00228 // To query proxies
00229 typedef struct {
00230    const char *cert;
00231    const char *key;
00232    const char *certdir;
00233    const char *out;
00234    const char *valid;
00235    int         deplen;
00236    int         bits;
00237 } ProxyIn_t;
00238 
00239 /******************************************************************************/
00240 /*              X r d S e c P r o t o c o l g s i   C l a s s                 */
00241 /******************************************************************************/
00242 
00243 class XrdSecProtocolgsi : public XrdSecProtocol
00244 {
00245 friend class gsiOptions;
00246 public:
00247         int                Authenticate  (XrdSecCredentials *cred,
00248                                           XrdSecParameters **parms,
00249                                           XrdOucErrInfo     *einfo=0);
00250 
00251         XrdSecCredentials *getCredentials(XrdSecParameters  *parm=0,
00252                                           XrdOucErrInfo     *einfo=0);
00253 
00254         XrdSecProtocolgsi(int opts, const char *hname,
00255                           const struct sockaddr *ipadd, const char *parms = 0);
00256         virtual ~XrdSecProtocolgsi() {} // Delete() does it all
00257 
00258         // Initialization methods
00259         static char      *Init(gsiOptions o, XrdOucErrInfo *erp);
00260 
00261         void              Delete();
00262 
00263         // Encrypt / Decrypt methods
00264         int               Encrypt(const char *inbuf, int inlen,
00265                                   XrdSecBuffer **outbuf);
00266         int               Decrypt(const char *inbuf, int inlen,
00267                                   XrdSecBuffer **outbuf);
00268         // Sign / Verify methods
00269         int               Sign(const char *inbuf, int inlen,
00270                                XrdSecBuffer **outbuf);
00271         int               Verify(const char *inbuf, int inlen,
00272                                  const char *sigbuf, int siglen);
00273 
00274         // Export session key
00275         int               getKey(char *kbuf=0, int klen=0);
00276         // Import a key
00277         int               setKey(char *kbuf, int klen);
00278 
00279         // Enable tracing
00280         static XrdOucTrace *EnableTracing();
00281 
00282 private:
00283 
00284    // Static members initialized at startup
00285    static XrdSysMutex      gsiContext;
00286    static String           CAdir;
00287    static String           CRLdir;
00288    static String           DefCRLext;
00289    static String           SrvCert;
00290    static String           SrvKey;
00291    static String           UsrProxy;
00292    static String           UsrCert;
00293    static String           UsrKey;
00294    static String           PxyValid;
00295    static int              DepLength;
00296    static int              DefBits;
00297    static int              CACheck;
00298    static int              CRLCheck;
00299    static int              CRLDownload;
00300    static int              CRLRefresh;
00301    static String           DefCrypto;
00302    static String           DefCipher;
00303    static String           DefMD;
00304    static String           DefError;
00305    static String           GMAPFile;
00306    static int              GMAPOpt;
00307    static bool             GMAPuseDNname;
00308    static int              GMAPCacheTimeOut;
00309    static XrdSysPlugin    *GMAPPlugin;
00310    static XrdSecgsiGMAP_t  GMAPFun;
00311    static XrdSysPlugin    *AuthzPlugin;
00312    static XrdSecgsiAuthz_t AuthzFun; 
00313    static XrdSecgsiAuthzKey_t AuthzKey; 
00314    static int              AuthzCertFmt; 
00315    static int              AuthzCacheTimeOut;
00316    static int              PxyReqOpts;
00317    static int              AuthzPxyWhat;
00318    static int              AuthzPxyWhere;
00319    static String           SrvAllowedNames;
00320    static int              VOMSAttrOpt; 
00321    static int              MonInfoOpt; 
00322    //
00323    // Crypto related info
00324    static int              ncrypt;                  // Number of factories
00325    static XrdCryptoFactory *cryptF[XrdCryptoMax];   // their hooks 
00326    static int              cryptID[XrdCryptoMax];   // their IDs 
00327    static String           cryptName[XrdCryptoMax]; // their names 
00328    static XrdCryptoCipher *refcip[XrdCryptoMax];    // ref for session ciphers 
00329    //
00330    // Caches 
00331    static XrdSutCache      cacheCA;   // Info about trusted CA's
00332    static XrdSutCache      cacheCert; // Cache for available server certs
00333    static XrdSutCache      cachePxy;  // Cache for client proxies
00334    static XrdSutCache      cacheGMAP; // Cache for gridmap entries
00335    static XrdSutCache      cacheGMAPFun; // Cache for entries mapped by GMAPFun
00336    static XrdSutCache      cacheAuthzFun; // Cache for entities filled by AuthzFun
00337    //
00338    // Running options / settings
00339    static int              Debug;          // [CS] Debug level
00340    static bool             Server;         // [CS] If server mode 
00341    static int              TimeSkew;       // [CS] Allowed skew in secs for time stamps 
00342    //
00343    // for error logging and tracing
00344    static XrdSysLogger     Logger;
00345    static XrdSysError      eDest;
00346    static XrdOucTrace     *GSITrace;
00347 
00348    // Information local to this instance
00349    int              options;
00350    struct sockaddr  hostaddr;      // Client-side only
00351    XrdCryptoFactory *sessionCF;    // Chosen crypto factory
00352    XrdCryptoCipher *sessionKey;    // Session Key (result of the handshake)
00353    XrdSutBucket    *bucketKey;     // Bucket with the key in export form
00354    XrdCryptoMsgDigest *sessionMD;  // Message Digest instance
00355    XrdCryptoRSA    *sessionKsig;   // RSA key to sign
00356    XrdCryptoRSA    *sessionKver;   // RSA key to verify
00357    X509Chain       *proxyChain;    // Chain with the delegated proxy on servers
00358    bool             srvMode;       // TRUE if server mode 
00359 
00360    // Temporary Handshake local info
00361    gsiHSVars     *hs;
00362 
00363    // Parsing received buffers: client
00364    int            ParseClientInput(XrdSutBuffer *br, XrdSutBuffer **bm,
00365                                    String &emsg);
00366    int            ClientDoInit(XrdSutBuffer *br, XrdSutBuffer **bm,
00367                                String &cmsg);
00368    int            ClientDoCert(XrdSutBuffer *br,  XrdSutBuffer **bm,
00369                                String &cmsg);
00370    int            ClientDoPxyreq(XrdSutBuffer *br,  XrdSutBuffer **bm,
00371                                  String &cmsg);
00372 
00373    // Parsing received buffers: server
00374    int            ParseServerInput(XrdSutBuffer *br, XrdSutBuffer **bm,
00375                                    String &cmsg);
00376    int            ServerDoCertreq(XrdSutBuffer *br, XrdSutBuffer **bm,
00377                                   String &cmsg);
00378    int            ServerDoCert(XrdSutBuffer *br,  XrdSutBuffer **bm,
00379                                String &cmsg);
00380    int            ServerDoSigpxy(XrdSutBuffer *br,  XrdSutBuffer **bm,
00381                                  String &cmsg);
00382 
00383    // Auxilliary functions
00384    int            ParseCrypto(String cryptlist);
00385    int            ParseCAlist(String calist);
00386 
00387    // Load CA certificates
00388    static int     GetCA(const char *cahash,
00389                         XrdCryptoFactory *cryptof, gsiHSVars *hs = 0);
00390    static String  GetCApath(const char *cahash);
00391    static bool    VerifyCA(int opt, X509Chain *cca, XrdCryptoFactory *cf);
00392    bool           ServerCertNameOK(const char *subject, String &e);
00393    static XrdSutPFEntry *GetSrvCertEnt(XrdCryptoFactory *cf, int timestamp, String &cal);
00394 
00395    // Load CRLs
00396    static XrdCryptoX509Crl *LoadCRL(XrdCryptoX509 *xca,
00397                                     XrdCryptoFactory *CF, int dwld);
00398 
00399    // Updating proxies
00400    static int     QueryProxy(bool checkcache, XrdSutCache *cache, const char *tag,
00401                              XrdCryptoFactory *cf, int timestamp,
00402                              ProxyIn_t *pi, ProxyOut_t *po);
00403    static int     InitProxy(ProxyIn_t *pi,
00404                             X509Chain *ch = 0, XrdCryptoRSA **key = 0);
00405 
00406    // Error functions
00407    static void    ErrF(XrdOucErrInfo *einfo, kXR_int32 ecode,
00408                        const char *msg1, const char *msg2 = 0,
00409                        const char *msg3 = 0);
00410    XrdSecCredentials *ErrC(XrdOucErrInfo *einfo, XrdSutBuffer *b1,
00411                            XrdSutBuffer *b2,XrdSutBuffer *b3,
00412                            kXR_int32 ecode, const char *msg1 = 0,
00413                            const char *msg2 = 0, const char *msg3 = 0);
00414    int            ErrS(String ID, XrdOucErrInfo *einfo, XrdSutBuffer *b1,
00415                        XrdSutBuffer *b2, XrdSutBuffer *b3,
00416                        kXR_int32 ecode, const char *msg1 = 0,
00417                        const char *msg2 = 0, const char *msg3 = 0);
00418 
00419    // Check Time stamp
00420    bool           CheckTimeStamp(XrdSutBuffer *b, int skew, String &emsg);
00421 
00422    // Check random challenge
00423    bool           CheckRtag(XrdSutBuffer *bm, String &emsg);
00424 
00425    // Auxilliary methods
00426    int            AddSerialized(char opt, kXR_int32 step, String ID, 
00427                                 XrdSutBuffer *bls, XrdSutBuffer *buf,
00428                                 kXR_int32 type, XrdCryptoCipher *cip);
00429    // Grid map cache handling
00430    static int     LoadGMAP(int now); // Init or refresh the cache
00431    static XrdSecgsiGMAP_t            // Load alternative function for mapping
00432                   LoadGMAPFun(const char *plugin, const char *parms);
00433    static XrdSecgsiAuthz_t           // Load alternative function to fill XrdSecEntity
00434                   LoadAuthzFun(const char *plugin, const char *parms, int &fmt);
00435    static void    QueryGMAP(XrdCryptoX509Chain* chain, int now, String &name); //Lookup info for DN
00436    
00437    // Entity handling
00438    void CopyEntity(XrdSecEntity *in, XrdSecEntity *out, int *lout = 0);
00439    void FreeEntity(XrdSecEntity *in);
00440 
00441    // VOMS parsing
00442    void ExtractVOMS(XrdCryptoX509 *xp, XrdSecEntity &ent);
00443 };