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