xrootd
XrdSecProtocolgsi.hh
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S e c P r o t o c o l g s i . h h */
4 /* */
5 /* (c) 2005 G. Ganis / CERN */
6 /* */
7 /* This file is part of the XRootD software suite. */
8 /* */
9 /* XRootD is free software: you can redistribute it and/or modify it under */
10 /* the terms of the GNU Lesser General Public License as published by the */
11 /* Free Software Foundation, either version 3 of the License, or (at your */
12 /* option) any later version. */
13 /* */
14 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
15 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
16 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
17 /* License for more details. */
18 /* */
19 /* You should have received a copy of the GNU Lesser General Public License */
20 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
21 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
22 /* */
23 /* The copyright holder's institutional names and contributor's names may not */
24 /* be used to endorse or promote products derived from this software without */
25 /* specific prior written permission of the institution or contributor. */
26 /* */
27 /******************************************************************************/
28 #include <time.h>
29 
30 #include "XrdOuc/XrdOucErrInfo.hh"
31 #include "XrdOuc/XrdOucHash.hh"
32 #include "XrdSys/XrdSysPthread.hh"
33 #include "XrdOuc/XrdOucString.hh"
35 
38 
39 #include "XrdSut/XrdSutPFEntry.hh"
40 #include "XrdSut/XrdSutPFile.hh"
41 #include "XrdSut/XrdSutBuffer.hh"
42 #include "XrdSut/XrdSutRndm.hh"
43 
48 
50 
51 /******************************************************************************/
52 /* D e f i n e s */
53 /******************************************************************************/
54 
57 
58 #define XrdSecPROTOIDENT "gsi"
59 #define XrdSecPROTOIDLEN sizeof(XrdSecPROTOIDENT)
60 #define XrdSecgsiVERSION 10300
61 #define XrdSecNOIPCHK 0x0001
62 #define XrdSecDEBUG 0x1000
63 #define XrdCryptoMax 10
64 
65 #define kMAXBUFLEN 1024
66 
67 //
68 // Message codes either returned by server or included in buffers
69 enum kgsiStatus {
70  kgST_error = -1, // error occured
71  kgST_ok = 0, // ok
72  kgST_more = 1 // need more info
73 };
74 
75 // Client steps
77  kXGC_none = 0,
78  kXGC_certreq = 1000, // 1000: request server certificate
79  kXGC_cert, // 1001: packet with (proxy) certificate
80  kXGC_sigpxy, // 1002: packet with signed proxy certificate
82 };
83 
84 // Server steps
86  kXGS_none = 0,
87  kXGS_init = 2000, // 2000: fake code used the first time
88  kXGS_cert, // 2001: packet with certificate
89  kXGS_pxyreq, // 2002: packet with proxy req to be signed
91 };
92 
93 // Handshake options
95  kOptsDlgPxy = 1, // 0x0001: Ask for a delegated proxy
96  kOptsFwdPxy = 2, // 0x0002: Forward local proxy
97  kOptsSigReq = 4, // 0x0004: Accept to sign delegated proxy
98  kOptsSrvReq = 8, // 0x0008: Server request for delegated proxy
99  kOptsPxFile = 16, // 0x0010: Save delegated proxies in file
100  kOptsDelChn = 32 // 0x0020: Delete chain
101 };
102 
103 // Error codes
105  kGSErrParseBuffer = 10000, // 10000
113  kGSErrGenCipher, // 10008
114  kGSErrExportPuK, // 10009
117  kGSErrNoRndmTag, // 10012
118  kGSErrNoCipher, // 10013
119  kGSErrNoCreds, // 10014
120  kGSErrBadOpt, // 10015
121  kGSErrMarshal, // 10016
122  kGSErrUnmarshal, // 10017
123  kGSErrSaveCreds, // 10018
124  kGSErrNoBuffer, // 10019
125  kGSErrRefCipher, // 10020
126  kGSErrNoPublic, // 10021
127  kGSErrAddBucket, // 10022
128  kGSErrFinCipher, // 10023
129  kGSErrInit, // 10024
130  kGSErrBadCreds, // 10025
131  kGSErrError // 10026
132 };
133 
134 #define REL1(x) { if (x) delete x; }
135 #define REL2(x,y) { if (x) delete x; if (y) delete y; }
136 #define REL3(x,y,z) { if (x) delete x; if (y) delete y; if (z) delete z; }
137 
138 #define SafeDelete(x) { if (x) delete x ; x = 0; }
139 #define SafeDelArray(x) { if (x) delete [] x ; x = 0; }
140 #define SafeFree(x) { if (x) free(x) ; x = 0; }
141 
142 // External functions for generic mapping
143 typedef char *(*XrdSecgsiGMAP_t)(const char *, int);
144 typedef int (*XrdSecgsiAuthz_t)(XrdSecEntity &);
145 typedef int (*XrdSecgsiAuthzInit_t)(const char *);
146 typedef int (*XrdSecgsiAuthzKey_t)(XrdSecEntity &, char **);
147 // VOMS extraction
150 //
151 // This a small class to set the relevant options in one go
152 //
153 class XrdOucTrace;
154 class gsiOptions {
155 public:
156  short debug; // [cs] debug flag
157  char mode; // [cs] 'c' or 's'
158  char *clist; // [s] list of crypto modules ["ssl" ]
159  char *certdir;// [cs] dir with CA info [/etc/grid-security/certificates]
160  char *crldir; // [cs] dir with CRL info [/etc/grid-security/certificates]
161  char *crlext; // [cs] extension of CRL files [.r0]
162  char *cert; // [s] server certificate [/etc/grid-security/root/rootcert.pem]
163  // [c] user certificate [$HOME/.globus/usercert.pem]
164  char *key; // [s] server private key [/etc/grid-security/root/rootkey.pem]
165  // [c] user private key [$HOME/.globus/userkey.pem]
166  char *cipher; // [s] list of ciphers [aes-128-cbc:bf-cbc:des-ede3-cbc]
167  char *md; // [s] list of MDs [sha1:md5]
168  int crl; // [cs] check level of CRL's [1]
169  int ca; // [cs] verification level of CA's [1]
170  int crlrefresh; // [cs] CRL refresh or expiration period in secs [1 day]
171  char *proxy; // [c] user proxy [/tmp/x509up_u<uid>]
172  char *valid; // [c] proxy validity [12:00]
173  int deplen; // [c] depth of signature path for proxies [0]
174  int bits; // [c] bits in PKI for proxies [512]
175  char *gridmap;// [s] gridmap file [/etc/grid-security/gridmap]
176  int gmapto; // [s] validity in secs of grid-map cache entries [-1 => unlimited]
177  char *gmapfun;// [s] file with the function to map DN to usernames [0]
178  char *gmapfunparms;// [s] parameters for the function to map DN to usernames [0]
179  char *authzfun;// [s] file with the function to fill entities [0]
180  char *authzfunparms;// [s] parameters for the function to fill entities [0]
181  int authzto; // [s] validity in secs of authz cache entries [-1 => unlimited]
182  int ogmap; // [s] gridmap file checking option
183  int dlgpxy; // [c] explicitely ask the creation of a delegated proxy
184  // [s] ask client for proxies
185  int sigpxy; // [c] accept delegated proxy requests
186  char *srvnames;// [c] '|' separated list of allowed server names
187  char *exppxy; // [s] template for the exported file with proxies (dlgpxy == 3)
188  int authzpxy; // [s] if 1 make proxy available in exported form in the 'endorsement'
189  // field of the XrdSecEntity object for use in XrdAcc
190  int vomsat; // [s] 0 do not look for; 1 extract if any
191  char *vomsfun;// [s] file with the function to fill VOMS [0]
192  char *vomsfunparms;// [s] parameters for the function to fill VOMS [0]
193  int moninfo; // [s] 0 do not look for; 1 use DN as default
194  int hashcomp; // [cs] 1 send hash names with both algorithms; 0 send only the default [1]
195 
196  gsiOptions() { debug = -1; mode = 's'; clist = 0;
197  certdir = 0; crldir = 0; crlext = 0; cert = 0; key = 0;
198  cipher = 0; md = 0; ca = 1 ; crl = 1; crlrefresh = 86400;
199  proxy = 0; valid = 0; deplen = 0; bits = 512;
200  gridmap = 0; gmapto = -1;
201  gmapfun = 0; gmapfunparms = 0; authzfun = 0; authzfunparms = 0; authzto = -1;
202  ogmap = 1; dlgpxy = 0; sigpxy = 1; srvnames = 0;
203  exppxy = 0; authzpxy = 0;
204  vomsat = 1; vomsfun = 0; vomsfunparms = 0; moninfo = 0; hashcomp = 1; }
205  virtual ~gsiOptions() { } // Cleanup inside XrdSecProtocolgsiInit
206  void Print(XrdOucTrace *t); // Print summary of gsi option status
207 };
208 
209 class XrdSecProtocolgsi;
210 class gsiHSVars;
211 
212 // From a proxy query
213 typedef struct {
217 } ProxyOut_t;
218 
219 // To query proxies
220 typedef struct {
221  const char *cert;
222  const char *key;
223  const char *certdir;
224  const char *out;
225  const char *valid;
226  int deplen;
227  int bits;
228 } ProxyIn_t;
229 
230 
231 class GSICrlStack {
232 public:
233  void Add(XrdCryptoX509Crl *crl) {
234  char k[40]; snprintf(k, 40, "%p", crl);
235  mtx.Lock();
236  if (!stack.Find(k)) stack.Add(k, crl, 0, Hash_count);
237  stack.Add(k, crl, 0, Hash_count);
238  mtx.UnLock();
239  }
240  void Del(XrdCryptoX509Crl *crl) {
241  char k[40]; snprintf(k, 40, "%p", crl);
242  mtx.Lock();
243  if (stack.Find(k)) stack.Del(k, Hash_count);
244  mtx.UnLock();
245  }
246 private:
249 };
250 
251 
252 /******************************************************************************/
253 /* X r d S e c P r o t o c o l g s i C l a s s */
254 /******************************************************************************/
255 
257 {
258 friend class gsiOptions;
259 friend class gsiHSVars;
260 public:
261  int Authenticate (XrdSecCredentials *cred,
262  XrdSecParameters **parms,
263  XrdOucErrInfo *einfo=0);
264 
266  XrdOucErrInfo *einfo=0);
267 
268  XrdSecProtocolgsi(int opts, const char *hname,
269  const struct sockaddr *ipadd, const char *parms = 0);
270  virtual ~XrdSecProtocolgsi() {} // Delete() does it all
271 
272  // Initialization methods
273  static char *Init(gsiOptions o, XrdOucErrInfo *erp);
274 
275  void Delete();
276 
277  // Encrypt / Decrypt methods
278  int Encrypt(const char *inbuf, int inlen,
279  XrdSecBuffer **outbuf);
280  int Decrypt(const char *inbuf, int inlen,
281  XrdSecBuffer **outbuf);
282  // Sign / Verify methods
283  int Sign(const char *inbuf, int inlen,
284  XrdSecBuffer **outbuf);
285  int Verify(const char *inbuf, int inlen,
286  const char *sigbuf, int siglen);
287 
288  // Export session key
289  int getKey(char *kbuf=0, int klen=0);
290  // Import a key
291  int setKey(char *kbuf, int klen);
292 
293  // Enable tracing
294  static XrdOucTrace *EnableTracing();
295 
296 private:
297 
298  // Static members initialized at startup
300  static String CAdir;
301  static String CRLdir;
303  static String SrvCert;
304  static String SrvKey;
305  static String UsrProxy;
306  static String UsrCert;
307  static String UsrKey;
308  static String PxyValid;
309  static int DepLength;
310  static int DefBits;
311  static int CACheck;
312  static int CRLCheck;
313  static int CRLDownload;
314  static int CRLRefresh;
317  static String DefMD;
318  static String DefError;
319  static String GMAPFile;
320  static int GMAPOpt;
321  static bool GMAPuseDNname;
322  static int GMAPCacheTimeOut;
328  static int AuthzCertFmt;
329  static int AuthzCacheTimeOut;
330  static int PxyReqOpts;
331  static int AuthzPxyWhat;
332  static int AuthzPxyWhere;
334  static int VOMSAttrOpt;
337  static int VOMSCertFmt;
338  static int MonInfoOpt;
339  static bool HashCompatibility;
340  //
341  // Crypto related info
342  static int ncrypt; // Number of factories
343  static XrdCryptoFactory *cryptF[XrdCryptoMax]; // their hooks
344  static int cryptID[XrdCryptoMax]; // their IDs
345  static String cryptName[XrdCryptoMax]; // their names
346  static XrdCryptoCipher *refcip[XrdCryptoMax]; // ref for session ciphers
347  //
348  // Caches
349  static XrdSutCache cacheCA; // Info about trusted CA's
350  static XrdSutCache cacheCert; // Cache for available server certs
351  static XrdSutCache cachePxy; // Cache for client proxies
352  static XrdSutCache cacheGMAP; // Cache for gridmap entries
353  static XrdSutCache cacheGMAPFun; // Cache for entries mapped by GMAPFun
354  static XrdSutCache cacheAuthzFun; // Cache for entities filled by AuthzFun
355  //
356  // CRL stack
357  static GSICrlStack stackCRL; // Stack of CRL in use
358  //
359  // GMAP control vars
360  static time_t lastGMAPCheck; // time of last check on GMAP
361  static XrdSysMutex mutexGMAP; // mutex to control GMAP reloads
362  //
363  // Running options / settings
364  static int Debug; // [CS] Debug level
365  static bool Server; // [CS] If server mode
366  static int TimeSkew; // [CS] Allowed skew in secs for time stamps
367  //
368  // for error logging and tracing
372 
373  // Information local to this instance
374  int options;
375  struct sockaddr hostaddr; // Client-side only
376  XrdCryptoFactory *sessionCF; // Chosen crypto factory
377  XrdCryptoCipher *sessionKey; // Session Key (result of the handshake)
378  XrdSutBucket *bucketKey; // Bucket with the key in export form
379  XrdCryptoMsgDigest *sessionMD; // Message Digest instance
380  XrdCryptoRSA *sessionKsig; // RSA key to sign
381  XrdCryptoRSA *sessionKver; // RSA key to verify
382  X509Chain *proxyChain; // Chain with the delegated proxy on servers
383  bool srvMode; // TRUE if server mode
384 
385  // Temporary Handshake local info
387 
388  // Parsing received buffers: client
390  String &emsg);
391  int ClientDoInit(XrdSutBuffer *br, XrdSutBuffer **bm,
392  String &cmsg);
393  int ClientDoCert(XrdSutBuffer *br, XrdSutBuffer **bm,
394  String &cmsg);
396  String &cmsg);
397 
398  // Parsing received buffers: server
400  String &cmsg);
402  String &cmsg);
403  int ServerDoCert(XrdSutBuffer *br, XrdSutBuffer **bm,
404  String &cmsg);
406  String &cmsg);
407 
408  // Auxilliary functions
409  int ParseCrypto(String cryptlist);
410  int ParseCAlist(String calist);
411 
412  // Load CA certificates
413  static int GetCA(const char *cahash,
414  XrdCryptoFactory *cryptof, gsiHSVars *hs = 0);
415  static String GetCApath(const char *cahash);
416  static bool VerifyCA(int opt, X509Chain *cca, XrdCryptoFactory *cf);
417  bool ServerCertNameOK(const char *subject, String &e);
419  XrdCryptoFactory *cf,
420  time_t timestamp, String &cal);
421 
422  // Load CRLs
423  static XrdCryptoX509Crl *LoadCRL(XrdCryptoX509 *xca, const char *sjhash,
424  XrdCryptoFactory *CF, int dwld);
425 
426  // Updating proxies
427  static int QueryProxy(bool checkcache, XrdSutCache *cache, const char *tag,
428  XrdCryptoFactory *cf, time_t timestamp,
429  ProxyIn_t *pi, ProxyOut_t *po);
430  static int InitProxy(ProxyIn_t *pi,
431  X509Chain *ch = 0, XrdCryptoRSA **key = 0);
432 
433  // Error functions
434  static void ErrF(XrdOucErrInfo *einfo, kXR_int32 ecode,
435  const char *msg1, const char *msg2 = 0,
436  const char *msg3 = 0);
438  XrdSutBuffer *b2,XrdSutBuffer *b3,
439  kXR_int32 ecode, const char *msg1 = 0,
440  const char *msg2 = 0, const char *msg3 = 0);
441  int ErrS(String ID, XrdOucErrInfo *einfo, XrdSutBuffer *b1,
442  XrdSutBuffer *b2, XrdSutBuffer *b3,
443  kXR_int32 ecode, const char *msg1 = 0,
444  const char *msg2 = 0, const char *msg3 = 0);
445 
446  // Check Time stamp
447  bool CheckTimeStamp(XrdSutBuffer *b, int skew, String &emsg);
448 
449  // Check random challenge
450  bool CheckRtag(XrdSutBuffer *bm, String &emsg);
451 
452  // Auxilliary methods
453  int AddSerialized(char opt, kXR_int32 step, String ID,
454  XrdSutBuffer *bls, XrdSutBuffer *buf,
455  kXR_int32 type, XrdCryptoCipher *cip);
456  // Grid map cache handling
457  static int LoadGMAP(int now); // Init or refresh the cache
458  static XrdSecgsiGMAP_t // Load alternative function for mapping
459  LoadGMAPFun(const char *plugin, const char *parms);
460  static XrdSecgsiAuthz_t // Load alternative function to fill XrdSecEntity
461  LoadAuthzFun(const char *plugin, const char *parms, int &fmt);
462  static XrdSecgsiVOMS_t // Load alternative function to extract VOMS
463  LoadVOMSFun(const char *plugin, const char *parms, int &fmt);
464  static void QueryGMAP(XrdCryptoX509Chain* chain, int now, String &name); //Lookup info for DN
465 
466  // Entity handling
467  void CopyEntity(XrdSecEntity *in, XrdSecEntity *out, int *lout = 0);
468  void FreeEntity(XrdSecEntity *in);
469 
470  // VOMS parsing
471  int ExtractVOMS(X509Chain *c, XrdSecEntity &ent);
472 };
473 
474 class gsiHSVars {
475 public:
476  int Iter; // iteration number
477  time_t TimeStamp; // Time of last call
478  String CryptoMod; // crypto module in use
479  int RemVers; // Version run by remote counterpart
480  XrdCryptoCipher *Rcip; // reference cipher
481  XrdSutBucket *Cbck; // Bucket with the certificate in export form
482  String ID; // Handshake ID (dummy for clients)
483  XrdSutPFEntry *Cref; // Cache reference
484  XrdSutPFEntry *Pent; // Pointer to relevant file entry
485  X509Chain *Chain; // Chain to be eventually verified
486  XrdCryptoX509Crl *Crl; // Pointer to CRL, if required
487  X509Chain *PxyChain; // Proxy Chain on clients
488  bool RtagOK; // Rndm tag checked / not checked
489  bool Tty; // Terminal attached / not attached
490  int LastStep; // Step required at previous iteration
491  int Options; // Handshake options;
492  int HashAlg; // Hash algorithm of peer hash name;
493  XrdSutBuffer *Parms; // Buffer with server parms on first iteration
494 
495  gsiHSVars() { Iter = 0; TimeStamp = -1; CryptoMod = "";
496  RemVers = -1; Rcip = 0;
497  Cbck = 0;
498  ID = ""; Cref = 0; Pent = 0; Chain = 0; Crl = 0; PxyChain = 0;
499  RtagOK = 0; Tty = 0; LastStep = 0; Options = 0; HashAlg = 0; Parms = 0;}
500 
502  if (Options & kOptsDelChn) {
503  // Do not delete the CA certificate in the cached reference
504  if (Chain) Chain->Cleanup(1);
505  SafeDelete(Chain);
506  }
507  if (Crl) {
508  // This decreases the counter and actually deletes the object only
509  // when no instance is using it
511  Crl = 0;
512  }
513  // The proxy chain is owned by the proxy cache; invalid proxies are
514  // detected (and eventually removed) by QueryProxy
515  PxyChain = 0;
516  SafeDelete(Parms); }
517  void Dump(XrdSecProtocolgsi *p = 0);
518 };