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 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 };