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    10200
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 char *(*XrdSecgsiAuthz_t)(const char *, int);
00123 
00124 //
00125 // This a small class to set the relevant options in one go
00126 //
00127 class gsiOptions {
00128 public:
00129    short  debug;  // [cs] debug flag
00130    short  mode;   // [cs] 'c' or 's'
00131    char  *clist;  // [s] list of crypto modules ["ssl" ]
00132    char  *certdir;// [cs] dir with CA info [/etc/grid-security/certificates]
00133    char  *crldir; // [cs] dir with CRL info [/etc/grid-security/certificates]
00134    char  *crlext; // [cs] extension of CRL files [.r0]
00135    char  *cert;   // [s] server certificate [/etc/grid-security/root/rootcert.pem]
00136                   // [c] user certificate [$HOME/.globus/usercert.pem]
00137    char  *key;    // [s] server private key [/etc/grid-security/root/rootkey.pem]
00138                   // [c] user private key [$HOME/.globus/userkey.pem]
00139    char  *cipher; // [s] list of ciphers [aes-128-cbc:bf-cbc:des-ede3-cbc]
00140    char  *md;     // [s] list of MDs [sha1:md5]
00141    int    crl;    // [cs] check level of CRL's [1] 
00142    int    ca;     // [cs] verification level of CA's [1] 
00143    char  *proxy;  // [c] user proxy  [/tmp/x509up_u<uid>]
00144    char  *valid;  // [c] proxy validity  [12:00]
00145    int    deplen; // [c] depth of signature path for proxies [0] 
00146    int    bits;   // [c] bits in PKI for proxies [512] 
00147    char  *gridmap;// [s] gridmap file [/etc/grid-security/gridmap]
00148    int    gmapto; // [s] validity in secs of grid-map cache entries [-1 => unlimited]
00149    char  *gmapfun;// [s] file with the function to map DN to usernames [0]
00150    char  *gmapfunparms;// [s] parameters for the function to map DN to usernames [0]
00151    char  *authzfun;// [s] file with the function to map DN to usernames [0]
00152    char  *authzfunparms;// [s] parameters for the function to map DN to usernames [0]
00153    int    ogmap;  // [s] gridmap file checking option 
00154    int    dlgpxy; // [c] explicitely ask the creation of a delegated proxy 
00155                   // [s] ask client for proxies
00156    int    sigpxy; // [c] accept delegated proxy requests 
00157    char  *srvnames;// [c] '|' separated list of allowed server names
00158    char  *exppxy; // [s] template for the exported file with proxies (dlgpxy == 3)
00159    int    authzpxy; // [s] if 1 make proxy available in exported form in the 'endorsement'
00160                     //     field of the XrdSecEntity object for use in XrdAcc
00161 
00162    gsiOptions() { debug = -1; mode = 's'; clist = 0; 
00163                   certdir = 0; crldir = 0; crlext = 0; cert = 0; key = 0;
00164                   cipher = 0; md = 0; ca = 1 ; crl = 1;
00165                   proxy = 0; valid = 0; deplen = 0; bits = 512;
00166                   gridmap = 0; gmapto = -1;
00167                   gmapfun = 0; gmapfunparms = 0; authzfun = 0; authzfunparms = 0;
00168                   ogmap = 1; dlgpxy = 0; sigpxy = 1; srvnames = 0; exppxy = 0; authzpxy = 0;}
00169    virtual ~gsiOptions() { } // Cleanup inside XrdSecProtocolgsiInit
00170 };
00171 
00172 class XrdSecProtocolgsi;
00173 class gsiHSVars {
00174 public:
00175    int               Iter;          // iteration number
00176    int               TimeStamp;     // Time of last call
00177    String            CryptoMod;     // crypto module in use
00178    int               RemVers;       // Version run by remote counterpart
00179    XrdCryptoCipher  *Rcip;          // reference cipher
00180    XrdSutBucket     *Cbck;          // Bucket with the certificate in export form
00181    String            ID;            // Handshake ID (dummy for clients)
00182    XrdSutPFEntry    *Cref;          // Cache reference
00183    XrdSutPFEntry    *Pent;          // Pointer to relevant file entry 
00184    X509Chain        *Chain;         // Chain to be eventually verified 
00185    XrdCryptoX509Crl *Crl;           // Pointer to CRL, if required 
00186    X509Chain        *PxyChain;      // Proxy Chain on clients
00187    bool              RtagOK;        // Rndm tag checked / not checked
00188    bool              Tty;           // Terminal attached / not attached
00189    int               LastStep;      // Step required at previous iteration
00190    int               Options;       // Handshake options;
00191    XrdSutBuffer     *Parms;         // Buffer with server parms on first iteration 
00192 
00193    gsiHSVars() { Iter = 0; TimeStamp = -1; CryptoMod = "";
00194                  RemVers = -1; Rcip = 0;
00195                  Cbck = 0;
00196                  ID = ""; Cref = 0; Pent = 0; Chain = 0; Crl = 0; PxyChain = 0;
00197                  RtagOK = 0; Tty = 0; LastStep = 0; Options = 0; Parms = 0;}
00198 
00199    ~gsiHSVars() { SafeDelete(Cref);
00200                   if (Options & kOptsDelChn) {
00201                      // Do not delete the CA certificate in the cached reference
00202                      if (Chain) Chain->Cleanup(1);
00203                      SafeDelete(Chain);
00204                   }
00205                   // The proxy chain is owned by the proxy cache; invalid proxies are
00206                   // detected (and eventually removed) by QueryProxy
00207                   PxyChain = 0;
00208                   SafeDelete(Parms); }
00209    void Dump(XrdSecProtocolgsi *p = 0);
00210 };
00211 
00212 // From a proxy query
00213 typedef struct {
00214    X509Chain        *chain;
00215    XrdCryptoRSA     *ksig;
00216    XrdSutBucket     *cbck;
00217 } ProxyOut_t;
00218 
00219 // To query proxies
00220 typedef struct {
00221    const char *cert;
00222    const char *key;
00223    const char *certdir;
00224    const char *out;
00225    const char *valid;
00226    int         deplen;
00227    int         bits;
00228 } ProxyIn_t;
00229 
00230 /******************************************************************************/
00231 /*              X r d S e c P r o t o c o l g s i   C l a s s                 */
00232 /******************************************************************************/
00233 
00234 class XrdSecProtocolgsi : public XrdSecProtocol
00235 {
00236 public:
00237         int                Authenticate  (XrdSecCredentials *cred,
00238                                           XrdSecParameters **parms,
00239                                           XrdOucErrInfo     *einfo=0);
00240 
00241         XrdSecCredentials *getCredentials(XrdSecParameters  *parm=0,
00242                                           XrdOucErrInfo     *einfo=0);
00243 
00244         XrdSecProtocolgsi(int opts, const char *hname,
00245                           const struct sockaddr *ipadd, const char *parms = 0);
00246         virtual ~XrdSecProtocolgsi() {} // Delete() does it all
00247 
00248         // Initialization methods
00249         static char      *Init(gsiOptions o, XrdOucErrInfo *erp);
00250 
00251         void              Delete();
00252 
00253         // Encrypt / Decrypt methods
00254         int               Encrypt(const char *inbuf, int inlen,
00255                                   XrdSecBuffer **outbuf);
00256         int               Decrypt(const char *inbuf, int inlen,
00257                                   XrdSecBuffer **outbuf);
00258         // Sign / Verify methods
00259         int               Sign(const char *inbuf, int inlen,
00260                                XrdSecBuffer **outbuf);
00261         int               Verify(const char *inbuf, int inlen,
00262                                  const char *sigbuf, int siglen);
00263 
00264         // Export session key
00265         int               getKey(char *kbuf=0, int klen=0);
00266         // Import a key
00267         int               setKey(char *kbuf, int klen);
00268 
00269 private:
00270 
00271    // Static members initialized at startup
00272    static XrdSysMutex      gsiContext;
00273    static String           CAdir;
00274    static String           CRLdir;
00275    static String           DefCRLext;
00276    static String           SrvCert;
00277    static String           SrvKey;
00278    static String           UsrProxy;
00279    static String           UsrCert;
00280    static String           UsrKey;
00281    static String           PxyValid;
00282    static int              DepLength;
00283    static int              DefBits;
00284    static int              CACheck;
00285    static int              CRLCheck;
00286    static String           DefCrypto;
00287    static String           DefCipher;
00288    static String           DefMD;
00289    static String           DefError;
00290    static String           GMAPFile;
00291    static int              GMAPOpt;
00292    static bool             GMAPuseDNname;
00293    static int              GMAPCacheTimeOut;
00294    static XrdSysPlugin    *GMAPPlugin;
00295    static XrdSecgsiGMAP_t  GMAPFun;
00296    static XrdSysPlugin    *AuthzPlugin;
00297    static XrdSecgsiAuthz_t AuthzFun; 
00298    static int              PxyReqOpts;
00299    static int              AuthzPxyWhat;
00300    static int              AuthzPxyWhere;
00301    static String           SrvAllowedNames;
00302    //
00303    // Crypto related info
00304    static int              ncrypt;                  // Number of factories
00305    static XrdCryptoFactory *cryptF[XrdCryptoMax];   // their hooks 
00306    static int              cryptID[XrdCryptoMax];   // their IDs 
00307    static String           cryptName[XrdCryptoMax]; // their names 
00308    static XrdCryptoCipher *refcip[XrdCryptoMax];    // ref for session ciphers 
00309    //
00310    // Caches 
00311    static XrdSutCache      cacheCA;   // Info about trusted CA's
00312    static XrdSutCache      cacheCert; // Cache for available server certs
00313    static XrdSutCache      cachePxy;  // Cache for client proxies
00314    static XrdSutCache      cacheGMAP; // Cache for gridmap entries
00315    static XrdSutCache      cacheGMAPFun; // Cache for entries mapped by GMAPFun
00316    //
00317    // Running options / settings
00318    static int              Debug;          // [CS] Debug level
00319    static bool             Server;         // [CS] If server mode 
00320    static int              TimeSkew;       // [CS] Allowed skew in secs for time stamps 
00321    //
00322    // for error logging and tracing
00323    static XrdSysLogger     Logger;
00324    static XrdSysError      eDest;
00325    static XrdOucTrace     *GSITrace;
00326 
00327    // Information local to this instance
00328    int              options;
00329    struct sockaddr  hostaddr;      // Client-side only
00330    XrdCryptoFactory *sessionCF;    // Chosen crypto factory
00331    XrdCryptoCipher *sessionKey;    // Session Key (result of the handshake)
00332    XrdSutBucket    *bucketKey;     // Bucket with the key in export form
00333    XrdCryptoMsgDigest *sessionMD;  // Message Digest instance
00334    XrdCryptoRSA    *sessionKsig;   // RSA key to sign
00335    XrdCryptoRSA    *sessionKver;   // RSA key to verify
00336    X509Chain       *proxyChain;    // Chain with the delegated proxy on servers
00337    bool             srvMode;       // TRUE if server mode 
00338 
00339    // Temporary Handshake local info
00340    gsiHSVars     *hs;
00341 
00342    // Parsing received buffers: client
00343    int            ParseClientInput(XrdSutBuffer *br, XrdSutBuffer **bm,
00344                                    String &emsg);
00345    int            ClientDoInit(XrdSutBuffer *br, XrdSutBuffer **bm,
00346                                String &cmsg);
00347    int            ClientDoCert(XrdSutBuffer *br,  XrdSutBuffer **bm,
00348                                String &cmsg);
00349    int            ClientDoPxyreq(XrdSutBuffer *br,  XrdSutBuffer **bm,
00350                                  String &cmsg);
00351 
00352    // Parsing received buffers: server
00353    int            ParseServerInput(XrdSutBuffer *br, XrdSutBuffer **bm,
00354                                    String &cmsg);
00355    int            ServerDoCertreq(XrdSutBuffer *br, XrdSutBuffer **bm,
00356                                   String &cmsg);
00357    int            ServerDoCert(XrdSutBuffer *br,  XrdSutBuffer **bm,
00358                                String &cmsg);
00359    int            ServerDoSigpxy(XrdSutBuffer *br,  XrdSutBuffer **bm,
00360                                  String &cmsg);
00361 
00362    // Auxilliary functions
00363    int            ParseCrypto(String cryptlist);
00364    int            ParseCAlist(String calist);
00365 
00366    // Load CA certificates
00367    static int     LoadCADir(int timestamp);
00368    int            GetCA(const char *cahash);
00369    static String  GetCApath(const char *cahash);
00370    static bool    VerifyCA(int opt, X509Chain *cca, XrdCryptoFactory *cf);
00371    bool           ServerCertNameOK(const char *subject, String &e);
00372 
00373    // Load CRLs
00374    static XrdCryptoX509Crl *LoadCRL(XrdCryptoX509 *xca,
00375                                     XrdCryptoFactory *CF);
00376 
00377    // Updating proxies
00378    static int     QueryProxy(bool checkcache, XrdSutCache *cache, const char *tag,
00379                              XrdCryptoFactory *cf, int timestamp,
00380                              ProxyIn_t *pi, ProxyOut_t *po);
00381    static int     InitProxy(ProxyIn_t *pi,
00382                             X509Chain *ch = 0, XrdCryptoRSA **key = 0);
00383 
00384    // Error functions
00385    static void    ErrF(XrdOucErrInfo *einfo, kXR_int32 ecode,
00386                        const char *msg1, const char *msg2 = 0,
00387                        const char *msg3 = 0);
00388    XrdSecCredentials *ErrC(XrdOucErrInfo *einfo, XrdSutBuffer *b1,
00389                            XrdSutBuffer *b2,XrdSutBuffer *b3,
00390                            kXR_int32 ecode, const char *msg1 = 0,
00391                            const char *msg2 = 0, const char *msg3 = 0);
00392    int            ErrS(String ID, XrdOucErrInfo *einfo, XrdSutBuffer *b1,
00393                        XrdSutBuffer *b2, XrdSutBuffer *b3,
00394                        kXR_int32 ecode, const char *msg1 = 0,
00395                        const char *msg2 = 0, const char *msg3 = 0);
00396 
00397    // Check Time stamp
00398    bool           CheckTimeStamp(XrdSutBuffer *b, int skew, String &emsg);
00399 
00400    // Check random challenge
00401    bool           CheckRtag(XrdSutBuffer *bm, String &emsg);
00402 
00403    // Auxilliary methods
00404    int            AddSerialized(char opt, kXR_int32 step, String ID, 
00405                                 XrdSutBuffer *bls, XrdSutBuffer *buf,
00406                                 kXR_int32 type, XrdCryptoCipher *cip);
00407    // Grid map cache handling
00408    static int     LoadGMAP(int now); // Init or refresh the cache
00409    static XrdSecgsiGMAP_t            // Load alternative function for mapping
00410                   LoadGMAPFun(const char *plugin, const char *parms);
00411    static XrdSecgsiAuthz_t           // Load alternative function for mapping based on the PEM string
00412                   LoadAuthzFun(const char *plugin, const char *parms);
00413    static void    QueryGMAP(XrdCryptoX509Chain* chain, int now, String &name); //Lookup info for DN
00414 };