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