xrootd
XrdSecProtocolpwd.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 p w d . h h */
4 /* */
5 /* (c) 2005 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Gerri Ganis for CERN */
7 /* */
8 /* This file is part of the XRootD software suite. */
9 /* */
10 /* XRootD is free software: you can redistribute it and/or modify it under */
11 /* the terms of the GNU Lesser General Public License as published by the */
12 /* Free Software Foundation, either version 3 of the License, or (at your */
13 /* option) any later version. */
14 /* */
15 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
16 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
17 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
18 /* License for more details. */
19 /* */
20 /* You should have received a copy of the GNU Lesser General Public License */
21 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
22 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
23 /* */
24 /* The copyright holder's institutional names and contributor's names may not */
25 /* be used to endorse or promote products derived from this software without */
26 /* specific prior written permission of the institution or contributor. */
27 /******************************************************************************/
28 
29 #include "XrdOuc/XrdOucErrInfo.hh"
30 #include "XrdSys/XrdSysPthread.hh"
31 #include "XrdOuc/XrdOucString.hh"
33 
36 
37 #include "XrdSut/XrdSutPFEntry.hh"
38 #include "XrdSut/XrdSutPFile.hh"
39 #include "XrdSut/XrdSutBuffer.hh"
40 #include "XrdSut/XrdSutRndm.hh"
41 
45 
46 /******************************************************************************/
47 /* D e f i n e s */
48 /******************************************************************************/
49 
51 
52 #define XrdSecPROTOIDENT "pwd"
53 #define XrdSecPROTOIDLEN sizeof(XrdSecPROTOIDENT)
54 #define XrdSecpwdVERSION 10100
55 #define XrdSecNOIPCHK 0x0001
56 #define XrdSecDEBUG 0x1000
57 #define XrdCryptoMax 10
58 
59 #define kMAXBUFLEN 1024
60 #define kMAXUSRLEN 9
61 #define kMAXPWDLEN 64
62 
63 //
64 // Message codes either returned by server or included in buffers
65 enum kpwdStatus {
66  kpST_error = -1, // error occured
67  kpST_ok = 0, // ok
68  kpST_more = 1 // need more info
69 };
70 
71 //
72 // Auto-reg modes
74  kpAR_none = 0, // autoreg disabled
75  kpAR_users = 1, // only for tags in password files (local, system's)
76  kpAR_all = 2 // for all tags
77 };
78 
79 //
80 // Client update autologin modes
81 enum kpwdUpdate {
82  kpUP_none = 0, // no update
83  kpUP_remove = 1, // remove obsolete entries only
84  kpUP_all = 2 // remove obsolete entries and register new valid info
85 };
86 
87 //
88 // Creds input type
90  kpCI_undef = -1, // undefined
91  kpCI_prompt = 0, // from prompt
92  kpCI_exact = 1, // from FileNetRc, exact tag
93  kpCI_wildcard = 2 // from FileNetRc, wildcard tag
94 };
95 
96 //
97 // Creds type (for prompt)
99  kpCT_undef = -1, // undefined
100  kpCT_normal = 0, // confirmed credentials
101  kpCT_onetime = 1, // one-time credentials
102  kpCT_old = 2, // old credentials to be changed
103  kpCT_new = 3, // new credentials to be confirmed
104  kpCT_newagain = 4, // new credentials again for confirmation
105  kpCT_autoreg = 5, // autoreg: new creds to be confirmed
106  kpCT_ar_again = 6, // autoreg: new creds again for confirmation
107  kpCT_crypt = 7, // standard crypt hash
108  kpCT_afs = 8, // AFS plain password
109  kpCT_afsenc = 9 // AFS encrypted password
110 };
111 
112 //
113 // Creds actions
115  kpCA_undef = -1, // undefined
116  kpCA_check = 0, // normal check of credentials
117  kpCA_checkold = 1, // check current creds before asking for new ones
118  kpCA_cache = 2, // cache received (new) credentials
119  kpCA_checkcache = 3 // check cached credentials and save them, if ok
120 };
121 
122 // Client steps
125  kXPC_normal = 1000, // 1000: standard packet
126  kXPC_verifysrv, // 1001: request for server verification
127  kXPC_signedrtag, // 1002: signed rtag (after server request for verification)
128  kXPC_creds, // 1003: credentials packet
129  kXPC_autoreg, // 1004: query for autoregistration
130  kXPC_failureack, // 1005: failure acknowledgement
132 };
133 
134 // Server steps
137  kXPS_init = 2000, // 2000: fake code used the first time
138  kXPS_credsreq, // 2001: request for credentials
139  kXPS_rtag, // 2002: rndm tag to be signed (strong verification)
140  kXPS_signedrtag, // 2003: signed rtag (after client request for verification)
141  kXPS_newpuk, // 2004: new public part for session ciphers
142  kXPS_puk, // 2005: public part for session ciphers (after autoreg)
143  kXPS_failure, // 2006: signal failure to client to drop invalid cached info
145 };
146 
147 // Error codes
149  kPWErrParseBuffer = 10000, // 10000
154  kPWErrNoUser, // 10005
155  kPWErrNoHost, // 10006
156  kPWErrBadUser, // 10007
161  kPWErrGenCipher, // 10012
162  kPWErrExportPuK, // 10013
165  kPWErrNoRndmTag, // 10016
166  kPWErrNoCipher, // 10017
168  kPWErrNoCreds, // 10019
169  kPWErrBadPasswd, // 10020
170  kPWErrBadCache, // 10021
171  kPWErrNoCache, // 10022
172  kPWErrNoSessID, // 10023
173  kPWErrBadSessID, // 10024
174  kPWErrBadOpt, // 10025
175  kPWErrMarshal, // 10026
176  kPWErrUnmarshal, // 10027
177  kPWErrSaveCreds, // 10028
178  kPWErrNoSalt, // 10029
179  kPWErrNoBuffer, // 10030
180  kPWErrRefCipher, // 10031
181  kPWErrNoPublic, // 10032
182  kPWErrAddBucket, // 10033
183  kPWErrFinCipher, // 10034
184  kPWErrInit, // 10034
185  kPWErrBadCreds, // 10035
186  kPWErrError // 10036
187 };
188 
189 // Structuring the status word
190 typedef struct {
191  char ctype;
192  char action;
193  short options;
194 } pwdStatus_t;
195 
196 #define REL1(x) { if (x) delete x; }
197 #define REL2(x,y) { if (x) delete x; if (y) delete y; }
198 #define REL3(x,y,z) { if (x) delete x; if (y) delete y; if (z) delete z; }
199 #if 0
200 #ifndef NODEBUG
201 #define PRINT(y) {{SecTrace->Beg(epname); cerr <<y; SecTrace->End();}}
202 #else
203 #define PRINT(y) { }
204 #endif
205 #endif
206 #define SafeDelete(x) { if (x) delete x ; x = 0; }
207 #define SafeDelArray(x) { if (x) delete [] x ; x = 0; }
208 
209 //
210 // This a small class to set the relevant options in one go
211 //
212 class pwdOptions {
213 public:
214  short debug; // [cs] debug flag
215  short mode; // [cs] 'c' or 's'
216  short areg; // [cs] auto-registration opt (s); update-autolog-info opt (c)
217  short upwd; // [s] check / do-not-check pwd file in user's $HOME
218  short alog; // [c] check / do-not-check user's autologin info
219  short verisrv; // [c] verify / do-not-verify server ownership of srvpuk
220  short vericlnt; // [s] level of verification client ownership of clntpuk
221  short syspwd; // [s] check / do-not-check system pwd (requires privileges)
222  int lifecreds; // [s] lifetime in seconds of credentials
223  int maxprompts; // [c] max number of empty prompts
224  int maxfailures; // [s] max passwd failures before blocking
225  char *clist; // [s] list of crypto modules ["ssl"]
226  char *dir; // [s] directory with admin pwd files [$HOME/.xrd]
227  char *udir; // [s] users's sub-directory with pwd files [$HOME/.xrd]
228  char *cpass; // [s] users's crypt hash pwd file [$HOME/.xrootdpass]
229  char *alogfile; // [c] autologin file [$HOME/.xrd/pwdnetrc]
230  char *srvpuk; // [c] file with server puks [$HOME/.xrd/pwdsrvpuk]
231  short keepcreds; // [s] keep / do-not-keep client credentials
232  char *expcreds; // [s] (template for) file with exported creds
233  int expfmt; // [s] formta for exported credentials
234 
235  pwdOptions() { debug = -1; mode = 's'; areg = -1; upwd = -1; alog = -1;
236  verisrv = -1; vericlnt = -1;
237  syspwd = -1; lifecreds = -1; maxprompts = -1; maxfailures = -1;
238  clist = 0; dir = 0; udir = 0; cpass = 0;
239  alogfile = 0; srvpuk = 0; keepcreds = 0; expcreds = 0; expfmt = 0;}
240  virtual ~pwdOptions() { } // Cleanup inside XrdSecProtocolpwdInit
241  void Print(XrdOucTrace *t); // Print summary of pwd option status
242 };
243 
244 class pwdHSVars {
245 public:
246  int Iter; // iteration number
247  int TimeStamp; // Time of last call
248  String CryptoMod; // crypto module in use
249  String User; // remote username
250  String Tag; // tag for credentials
251  int RemVers; // Version run by remote counterpart
252  XrdCryptoFactory *CF; // crypto factory
253  XrdCryptoCipher *Hcip; // handshake cipher
254  XrdCryptoCipher *Rcip; // reference cipher
255  String ID; // Handshake ID (dummy for clients)
256  XrdSutPFEntry *Cref; // Cache reference
257  XrdSutPFEntry *Pent; // Pointer to relevant file entry
258  bool RtagOK; // Rndm tag checked / not checked
259  pwdStatus_t Status; // Some state flags
260  bool Tty; // Terminal attached / not attached
261  int Step; // Current step
262  int LastStep; // Step required at previous iteration
263  String ErrMsg; // Last error message
264  int SysPwd; // 0 = no, 1 = Unix sys pwd, 2 = AFS pwd
265  String AFScell; // AFS cell if it makes sense
266  XrdSutBuffer *Parms; // Buffer with server parms on first iteration
267 
268  pwdHSVars() { Iter = 0; TimeStamp = -1; CryptoMod = ""; User = ""; Tag = "";
269  RemVers = -1; CF = 0; Hcip = 0; Rcip = 0;
270  ID = ""; Cref = 0; Pent = 0; RtagOK = 0; Tty = 0;
271  Step = 0; LastStep = 0; ErrMsg = "";
272  SysPwd = 0; AFScell = "";
273  Status.ctype = 0; Status.action = 0; Status.options = 0; Parms = 0;}
274 
276 };
277 
278 
279 /******************************************************************************/
280 /* X r d S e c P r o t o c o l p w d C l a s s */
281 /******************************************************************************/
282 
284 {
285 public:
286  int Authenticate (XrdSecCredentials *cred,
287  XrdSecParameters **parms,
288  XrdOucErrInfo *einfo=0);
289 
291  XrdOucErrInfo *einfo=0);
292 
293  XrdSecProtocolpwd(int opts, const char *hname,
294  const struct sockaddr *ipadd,
295  const char *parms = 0);
296  virtual ~XrdSecProtocolpwd() {} // Delete() does it all
297 
298  // Initialization methods
299  static char *Init(pwdOptions o, XrdOucErrInfo *erp);
300 
301  void Delete();
302 
303  static void PrintTimeStat();
304 
305  // Enable tracing
306  static XrdOucTrace *EnableTracing();
307 
308 private:
309 
310  // Static members initialized at startup
313  static String FileExpCreds; // (Template for) file with exported creds [S]
314  static String FileUser;
317  static String SrvID;
318  static String SrvEmail;
320  static String DefError;
321  static XrdSutPFile PFAdmin; // Admin file [S]
322  static XrdSutPFile PFAlog; // Autologin file [CS]
323  static XrdSutPFile PFSrvPuk; // File with server public keys [CS]
324  //
325  // Crypto related info
326  static int ncrypt; // Number of factories
327  static int cryptID[XrdCryptoMax]; // their IDs
328  static String cryptName[XrdCryptoMax]; // their names
329  static XrdCryptoCipher *loccip[XrdCryptoMax]; // local ciphers
330  static XrdCryptoCipher *refcip[XrdCryptoMax]; // ref for session ciphers
331  //
332  // Caches for info files
333  static XrdSutCache cacheAdmin; // Admin file
334  static XrdSutCache cacheSrvPuk; // SrvPuk file
335  static XrdSutCache cacheUser; // User files
336  static XrdSutCache cacheAlog; // Autologin file
337  //
338  // Running options / settings
339  static int Debug; // [CS] Debug level
340  static bool Server; // [CS] If server mode
341  static int UserPwd; // [S] Check passwd file in user's <xrdsecdir>
342  static bool SysPwd; // [S] Check system passwd file if allowed
343  static int VeriClnt; // [S] Client verification level
344  static int VeriSrv; // [C] Server verification level
345  static int AutoReg; // [S] Autoreg mode
346  static int LifeCreds; // [S] if > 0, credential lifetime in secs
347  static int MaxPrompts; // [C] Repeating prompt
348  static int MaxFailures; // [S] Max passwd failures before blocking
349  static int AutoLogin; // [C] do-not-check/check/update autolog info
350  static int TimeSkew; // [CS] Allowed skew in secs for time stamps
351  static bool KeepCreds; // [S] Keep / Do-Not-Keep client creds
352  static int FmtExpCreds; // [S] Format for the exported credentials
353  //
354  // for error logging and tracing
358 
359  // Information local to this instance
360  int options;
361  struct sockaddr hostaddr; // Client-side only
362  char CName[256]; // Client-name
363  bool srvMode; // TRUE if server mode
364 
365  // Handshake local info
367 
368  // Acquired credentials (server side)
370 
371  // Parsing received buffers
373  String &emsg);
375  String &cmsg);
376  int ParseCrypto(XrdSutBuffer *buf);
377 
378  // Error functions
379  static void ErrF(XrdOucErrInfo *einfo, kXR_int32 ecode,
380  const char *msg1, const char *msg2 = 0,
381  const char *msg3 = 0);
383  XrdSutBuffer *b2,XrdSutBuffer *b3,
384  kXR_int32 ecode, const char *msg1 = 0,
385  const char *msg2 = 0, const char *msg3 = 0);
386  int ErrS(String ID, XrdOucErrInfo *einfo, XrdSutBuffer *b1,
387  XrdSutBuffer *b2, XrdSutBuffer *b3,
388  kXR_int32 ecode, const char *msg1 = 0,
389  const char *msg2 = 0, const char *msg3 = 0);
390 
391  // Query methods
392  XrdSutBucket *QueryCreds(XrdSutBuffer *bm, bool netrc, int &status);
393  int QueryUser(int &status, String &cmsg);
394  int QueryCrypt(String &fn, String &pwhash);
395  int QueryNetRc(String host, String &passwd, int &status);
396 
397  // Check credentials
398  bool CheckCreds(XrdSutBucket *creds, int credtype);
399  bool CheckCredsAFS(XrdSutBucket *creds, int ctype);
400 
401  // Check Time stamp
402  bool CheckTimeStamp(XrdSutBuffer *b, int skew, String &emsg);
403 
404  // Check random challenge
405  bool CheckRtag(XrdSutBuffer *bm, String &emsg);
406 
407  // Saving / Updating
408  int ExportCreds(XrdSutBucket *creds);
409  int SaveCreds(XrdSutBucket *creds);
410  int UpdateAlog();
411 
412  // Auxilliary methods
413  int GetUserHost(String &usr, String &host);
414  int AddSerialized(char opt, kXR_int32 step, String ID,
415  XrdSutBuffer *bls, XrdSutBuffer *buf,
416  kXR_int32 type, XrdCryptoCipher *cip);
418  XrdSutBucket *s1, XrdSutBucket *s2 = 0,
419  const char *tag = 0);
420 };