XRootD
XrdSecProtocolsss.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S e c P r o t o c o l s s s . c c */
4 /* */
5 /* (c) 2008 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #if !defined(__FreeBSD__)
32 #include <alloca.h>
33 #endif
34 #include <cctype>
35 #include <iostream>
36 #include <cstdlib>
37 #include <cstring>
38 #include <strings.h>
39 #include <cstdio>
40 #include <sys/param.h>
41 #include <unistd.h>
42 
43 #include "XrdVersion.hh"
44 
45 #include "XrdNet/XrdNetUtils.hh"
46 #include "XrdOuc/XrdOucCRC.hh"
47 #include "XrdOuc/XrdOucErrInfo.hh"
48 #include "XrdOuc/XrdOucEnv.hh"
49 #include "XrdOuc/XrdOucPup.hh"
51 #include "XrdOuc/XrdOucUtils.hh"
55 #include "XrdSys/XrdSysE2T.hh"
56 #include "XrdSys/XrdSysPlatform.hh"
57 #include "XrdSys/XrdSysPthread.hh"
58 
59 /******************************************************************************/
60 /* D e f i n e s */
61 /******************************************************************************/
62 
63 #define XrdsssPROTOIDENT "sss"
64 
65 #define CLDBG(x) if (sssDEBUG) std::cerr<<"sec_sss: "<<x<<'\n'<<std::flush
66 
67 /******************************************************************************/
68 /* L o c a l C l a s s e s */
69 /******************************************************************************/
70 
71 namespace
72 {
73 class Persona
74 {
75 public:
76 XrdSecsssKT::ktEnt *kTab;
77 char *xAuth;
78 char *xUser;
79 char *xGrup;
80 char *name;
81 char *host;
82 char *vorg;
83 char *role;
84 char *grps;
85 char *caps;
86 char *endo;
87 char *creds;
88 int credslen;
89 char *pident;
90 
91  Persona(XrdSecsssKT::ktEnt *kP)
92  : kTab(kP),
93  xAuth(nullptr),
94  xUser(nullptr),
95  xGrup(nullptr),
96  name(nullptr),
97  host(nullptr),
98  vorg(nullptr),
99  role(nullptr),
100  grps(nullptr),
101  caps(nullptr),
102  endo(nullptr),
103  creds(nullptr),
104  credslen(0),
105  pident(nullptr)
106  {}
107 
108 bool Clonable(const char *aTypes)
109  {char aKey[XrdSecPROTOIDSIZE+2];
110  if (!xAuth || !name || !pident
111  || !(kTab->Data.Opts & XrdSecsssKT::ktEnt::allUSR)) return false;
112  int n = strlen(xAuth);
113  if (n < 2 || n >= XrdSecPROTOIDSIZE) return false;
114  *aKey = ':';
115  strcpy(aKey+1, xAuth);
116  return strstr(aTypes, aKey) != 0;
117  }
118  };
119 
120 // Struct to manage dynamically allocated data buffer
121 //
122 struct sssRR_DataHdr
123 {
125 
126  sssRR_DataHdr() : P(0) {}
127  ~sssRR_DataHdr() {if (P) free(P);}
128 };
129 }
130 
131 /******************************************************************************/
132 /* S t a t i c D a t a */
133 /******************************************************************************/
134 
135 XrdCryptoLite *XrdSecProtocolsss::CryptObj = 0;
136 XrdSecsssKT *XrdSecProtocolsss::ktObject = 0;
137 XrdSecsssID *XrdSecProtocolsss::idMap = 0;
138 char *XrdSecProtocolsss::aProts = 0;
139 XrdSecsssEnt *XrdSecProtocolsss::staticID = 0;
140 int XrdSecProtocolsss::deltaTime =13;
141 bool XrdSecProtocolsss::isMutual = false;
142 bool XrdSecProtocolsss::isMapped = false;
143 bool XrdSecProtocolsss::ktFixed = false;
144 
146  {"bf32", XrdSecsssRR_Hdr::etBFish32},
147  {0, '0'}
148  };
149 
150 namespace
151 {
152 XrdSysMutex initMutex;
153 
154 bool sssDEBUG = false;
155 bool sssUseKN = false;
156 }
157 
158 /******************************************************************************/
159 /* A u t h e n t i c a t e */
160 /******************************************************************************/
161 
163  XrdSecParameters **parms,
164  XrdOucErrInfo *einfo)
165 {
166  static const int minLen = sizeof(XrdSecsssRR_Hdr) + XrdSecsssRR_Data_HdrLen;
167  static const int maxLen = XrdSecsssRR_Data::MaxDSz + minLen;
168  static const int Special= XrdSecsssKT::ktEnt::anyUSR
170 
171  XrdSecsssRR_Hdr *rrHdr = (XrdSecsssRR_Hdr *)(cred->buffer);
172  XrdSecsssRR_Data *rrData;
173  XrdSecsssKT::ktEnt decKey;
174  Persona myID(&decKey);
175 
176  char *idP = 0, *dP = 0, *eodP = 0, *theIP = 0, *theHost = 0, *atKey = 0, eType = '\0';
177  int idNum = 0, idTLen, idSz, dLen;
178  bool badAttr = false;
179 
180 // Make sure we have atleast the header plus the data header
181 //
182  if (cred->size < minLen)
183  return Fatal(einfo, "Auth", EINVAL, "Credentials too small.");
184 
185 // Make sure the credentials are not too big (people misuse sss)
186 //
187  if (cred->size > maxLen)
188  return Fatal(einfo, "Auth", EINVAL, "Credentials too big.");
189 
190 // Allocate the buffer from the stack
191 //
192  rrData = (XrdSecsssRR_Data *)alloca(cred->size);
193 
194 // Decode the credentials
195 //
196  if ((dLen = Decode(einfo, decKey, cred->buffer, rrData, cred->size)) <= 0)
197  return -1;
198 
199 // Check if we should echo back the LID
200 //
201  if (rrData->Options == XrdSecsssRR_DataHdr::SndLID)
202  {XrdSecsssRR_DataResp rrResp;
203  char lidBuff[16];
204  rrResp.Options = 0;
205  getLID(lidBuff, sizeof(lidBuff));
206  dP = rrResp.Data;
208  XrdOucPup::Pack(&dP, lidBuff);
209  int n = dP-rrResp.Data + XrdSecsssRR_Data_HdrLen;
210  *parms = Encode(einfo, decKey, rrHdr, &rrResp, n);
211  return (*parms ? 1 : -1);
212  }
213 
214 // Extract out the entity information
215 //
216  dP = rrData->Data; eodP = dP + dLen - XrdSecsssRR_Data_HdrLen;
217  CLDBG("Processing " <<dLen <<" byes");
218  while(dP < eodP)
219  {eType = *dP++;
220  CLDBG("eType=" <<static_cast<int>(eType)
221  <<" Used " <<dP-rrData->Data <<" left " <<eodP-dP);
222  if (!XrdOucPup::Unpack(&dP, eodP, &idP, idSz) || (idP && *idP == '\0'))
223  {Fatal(einfo, "Authenticate", EINVAL, "Invalid id string.");
224  return -1;
225  }
226  idNum++;
227  switch(eType)
228  {case XrdSecsssRR_Data::theName: myID.name = idP; break;
229  case XrdSecsssRR_Data::theVorg: myID.vorg = idP; break;
230  case XrdSecsssRR_Data::theRole: myID.role = idP; break;
231  case XrdSecsssRR_Data::theGrps: myID.grps = idP; break;
232  case XrdSecsssRR_Data::theEndo: myID.endo = idP; break;
233  case XrdSecsssRR_Data::theCred: myID.creds = idP;
234  myID.credslen = idSz;break;
236  if (idP && *idP == '[')
237  myID.host = theIP = idP;
238 
239  else theHost = idP;
240  break;
241  case XrdSecsssRR_Data::theRand: idNum--; break;
242 
243  case XrdSecsssRR_Data::theAuth: myID.xAuth = idP; break;
244 
245  case XrdSecsssRR_Data::theTID: myID.pident = idP; break;
246  case XrdSecsssRR_Data::theAKey: if (atKey) badAttr = true;
247  atKey = idP; break;
249  if (!atKey) badAttr = true;
250  else {Entity.eaAPI->Add(std::string(atKey),
251  std::string(idP), true);
252  atKey = 0;
253  }
254  break;
255  case XrdSecsssRR_Data::theUser: myID.xUser = idP; break;
256  case XrdSecsssRR_Data::theGrup: myID.xGrup = idP; break;
257  case XrdSecsssRR_Data::theCaps: myID.caps = idP; break;
258  default: break;
259  }
260  }
261 
262 // Verify that we have some kind of identification
263 //
264  if (!idNum)
265  {Fatal(einfo, "Authenticate", ENOENT, "No identification specified.");
266  return -1;
267  }
268 
269 // Make sure we didn't encounter any attribute errors
270 //
271  if (badAttr)
272  {Fatal(einfo, "Authenticate", EINVAL, "Invalid attribute specification.");
273  return -1;
274  }
275 
276 // Verify the source of the information to largely prevent packet stealing. New
277 // version of the protocol will send an IP address which we prefrentially use.
278 // Older version used a hostname. This causes problems for multi-homed machines.
279 //
280 if (!(decKey.Data.Opts & XrdSecsssKT::ktEnt::noIPCK))
281  {if (!theHost && !theIP)
282  {Fatal(einfo,"Authenticate",ENOENT,"No hostname or IP address specified.");
283  return -1;
284  }
285  CLDBG(urName <<' ' <<urIP <<" or " <<urIQ << " must match "
286  <<(theHost ? theHost : "?") <<' ' <<(theIP ? theIP : "[?]"));
287  if (theIP)
288  {if (strcmp(theIP, urIP) && strcmp(theIP, urIQ))
289  {Fatal(einfo, "Authenticate", EINVAL, "IP address mismatch.");
290  return -1;
291  }
292  } else if (strcmp(theHost, urName))
293  {Fatal(einfo, "Authenticate", EINVAL, "Hostname mismatch.");
294  return -1;
295  }
296  } else {
297  CLDBG(urName <<' ' <<urIP <<" or " <<urIQ << " forwarded token from "
298  <<(theHost ? theHost : "?") <<' ' <<(theIP ? theIP : "[?]"));
299  }
300 
301 // At this point we need to check if this identity can be passed as a clone
302 //
303  if (aProts && myID.Clonable(aProts))
304  {strlcpy(Entity.prot, myID.xAuth, sizeof(Entity.prot));
306  if (myID.xUser) XrdOucUtils::getUID(myID.xUser,Entity.uid,&Entity.gid);
307  if (myID.xGrup) XrdOucUtils::getGID(myID.xGrup,Entity.gid);
308  } else {
309  // Set correct username
310  //
311  if (decKey.Data.Opts & Special)
312  {if (!myID.name) myID.name = (char *)"nobody";}
313  else myID.name = decKey.Data.User;
314 
315  // Set correct group
316  //
317  if (decKey.Data.Opts & XrdSecsssKT::ktEnt::usrGRP) myID.grps = 0;
318  else {if (decKey.Data.Opts & XrdSecsssKT::ktEnt::anyGRP)
319  {if (!myID.grps) myID.grps = (char *)"nogroup";}
320  else myID.grps = decKey.Data.Grup;
321  }
322 
323  // Set corresponding uid and gid
324  //
325  if (myID.name) XrdOucUtils::getUID(myID.name, Entity.uid, &Entity.gid);
326  if (myID.grps) XrdOucUtils::getGID(myID.grps, Entity.gid);
327  }
328 
329 // Calculate the amount of space we will need
330 //
331  idTLen = strlen(urName)
332  + (myID.name ? strlen(myID.name)+1 : 0)
333  + (myID.vorg ? strlen(myID.vorg)+1 : 0)
334  + (myID.role ? strlen(myID.role)+1 : 0)
335  + (myID.grps ? strlen(myID.grps)+1 : 0)
336  + (myID.caps ? strlen(myID.caps)+1 : 0)
337  + (myID.endo ? strlen(myID.endo)+1 : 0)
338  + (myID.creds ? myID.credslen : 0)
339  + (myID.pident ? strlen(myID.pident)+1 : 0);
340 
341 // Complete constructing our identification
342 //
343  if (idBuff) free(idBuff);
344  idBuff = idP = (char *)malloc(idTLen);
345  Entity.host = urName;
346  Entity.name = setID(myID.name, &idP);
347  Entity.vorg = setID(myID.vorg, &idP);
348  Entity.role = setID(myID.role, &idP);
349  Entity.grps = setID(myID.grps, &idP);
350  Entity.caps = setID(myID.caps, &idP);
351  Entity.endorsements = setID(myID.endo, &idP);
352 
353  if (myID.pident)
354  {strcpy(idP, myID.pident);
355  Entity.pident = idP;
356  idP += strlen(myID.pident) + 1;
357  }
358 
359  if (myID.creds)
360  {memcpy(idP, myID.creds, myID.credslen);
361  Entity.creds = idP;
362  Entity.credslen = myID.credslen;
363  }
364 
365 // All done
366 //
367  return 0;
368 }
369 
370 /******************************************************************************/
371 /* Private: D e c o d e */
372 /******************************************************************************/
373 
374 int XrdSecProtocolsss::Decode(XrdOucErrInfo *error,
375  XrdSecsssKT::ktEnt &decKey,
376  char *iBuff,
377  XrdSecsssRR_DataHdr *rrDHdr,
378  int iSize)
379 {
380  XrdSecsssRR_Hdr *rrHdr = (XrdSecsssRR_Hdr *)iBuff;
381  char *iData = iBuff+sizeof(XrdSecsssRR_Hdr);
382  int rc, genTime, dLen = iSize - sizeof(XrdSecsssRR_Hdr);
383 
384 // Check if this is a recognized protocol
385 //
386  if (strcmp(rrHdr->ProtID, XrdsssPROTOIDENT))
387  {char emsg[256];
388  snprintf(emsg, sizeof(emsg),
389  "Authentication protocol id mismatch (%.4s != %.4s).",
390  XrdsssPROTOIDENT, rrHdr->ProtID);
391  return Fatal(error, "Decode", EINVAL, emsg);
392  }
393 
394 // Verify decryption method
395 //
396  if (rrHdr->EncType != Crypto->Type())
397  return Fatal(error, "Decode", ENOTSUP, "Crypto type not supported.");
398 
399 // Check if this is a V2 client. V2 client always supply the keyname of the
400 // key which we may or may not use. If specified, make sure it's correct.
401 //
402  if (rrHdr->knSize)
403  {int knSize = static_cast<int>(rrHdr->knSize);
404  v2EndPnt = true;
405  if (knSize > XrdSecsssKT::ktEnt::NameSZ || knSize & 0x07
406  || knSize >= dLen || iData[knSize-1])
407  return Fatal(error, "Decode", EINVAL, "Invalid keyname specified.");
408  if (sssUseKN) strcpy(decKey.Data.Name, iData);
409  else decKey.Data.Name[0] = '\0';
410  CLDBG("V2 client using keyname '" <<iData <<"' dLen=" <<dLen
411  <<(sssUseKN ? "" : " (ignored)"));
412  iData += knSize; dLen -= knSize;
413  } else decKey.Data.Name[0] = '\0';
414 
415 // Get the key ID
416 //
417  decKey.Data.ID = ntohll(rrHdr->KeyID);
418  if (keyTab->getKey(decKey, *decKey.Data.Name))
419  return Fatal(error, "Decode", ENOENT, "Decryption key not found.");
420 
421 // Decrypt
422 //
423  CLDBG("Decode keyid: " <<decKey.Data.ID <<" bytes " <<dLen);
424  if ((rc = Crypto->Decrypt(decKey.Data.Val, decKey.Data.Len, iData, dLen,
425  (char *)rrDHdr, dLen)) <= 0)
426  return Fatal(error, "Decode", -rc, "Unable to decrypt credentials.");
427 
428 // Verify that the packet has not expired (OK to do before CRC check)
429 //
430  genTime = ntohl(rrDHdr->GenTime);
431  if (genTime + deltaTime <= myClock())
432  return Fatal(error, "Decode", ESTALE,
433  "Credentials expired (check for clock skew).");
434 
435 // Return success (size of decrypted info)
436 //
437  return rc;
438 }
439 
440 /******************************************************************************/
441 /* D e l e t e */
442 /******************************************************************************/
443 
445 {
446 // Delete things that get re-allocated every time. The staticID is allocated
447 // only once so it must stick around for every instance of this object.
448 //
449  if (urName) free(urName); // Same pointer as Entity.host
450  if (idBuff) free(idBuff);
451  if (Crypto && Crypto != CryptObj) delete Crypto;
452  if (keyTab && keyTab != ktObject) delete keyTab;
453 
454  delete this;
455 }
456 
457 /******************************************************************************/
458 /* Private: e M s g */
459 /******************************************************************************/
460 
461 int XrdSecProtocolsss::eMsg(const char *epname, int rc,
462  const char *txt1, const char *txt2,
463  const char *txt3, const char *txt4)
464 {
465  std::cerr <<"Secsss (" << epname <<"): ";
466  std::cerr <<txt1;
467  if (rc>0) std::cerr <<"; " <<XrdSysE2T(rc);
468  if (txt2) std::cerr <<txt2;
469  if (txt3) std::cerr <<txt3;
470  if (txt4) {std::cerr <<txt4;}
471  std::cerr <<"\n" <<std::flush;
472 
473  return (rc ? (rc < 0 ? rc : -rc) : -1);
474 }
475 
476 /******************************************************************************/
477 /* Private: E n c o d e */
478 /******************************************************************************/
479 
480 XrdSecCredentials *XrdSecProtocolsss::Encode(XrdOucErrInfo *einfo,
481  XrdSecsssKT::ktEnt &encKey,
482  XrdSecsssRR_Hdr *rrHdr,
483  XrdSecsssRR_DataHdr *rrDHdr,
484  int dLen)
485 {
486  char *credP;
487  int knum, cLen, hdrSZ = sizeof(XrdSecsssRR_Hdr) + rrHdr->knSize;
488 
489 // Make sure we don't overrun a 1 server's buffer. V2 servers are forgiving.
490 //
491  if (!v2EndPnt && dLen > (int)sizeof(XrdSecsssRR_Data))
492  {Fatal(einfo,"Encode",ENOBUFS,"Insufficient buffer space for credentials.");
493  return (XrdSecCredentials *)0;
494  }
495 
496 // Complete the packet
497 //
498  XrdSecsssKT::genKey(rrDHdr->Rand, sizeof(rrDHdr->Rand));
499  rrDHdr->GenTime = htonl(myClock());
500  memset(rrDHdr->Pad, 0, sizeof(rrDHdr->Pad));
501 
502 // Allocate an output buffer
503 //
504  cLen = hdrSZ + dLen + Crypto->Overhead();
505  if (!(credP = (char *)malloc(cLen)))
506  {Fatal(einfo, "Encode", ENOMEM, "Insufficient memory for credentials.");
507  return (XrdSecCredentials *)0;
508  }
509 
510 // Copy the header and encrypt the data
511 //
512  memcpy(credP, (const void *)rrHdr, hdrSZ);
513  CLDBG("Encode keyid: " <<encKey.Data.ID <<" bytes " <<cLen-hdrSZ);
514  if ((dLen = Crypto->Encrypt(encKey.Data.Val, encKey.Data.Len, (char *)rrDHdr,
515  dLen, credP+hdrSZ, cLen-hdrSZ)) <= 0)
516  {Fatal(einfo, "Encode", -dLen, "Unable to encrypt credentials.");
517  return (XrdSecCredentials *)0;
518  }
519 
520 // Return new credentials
521 //
522  dLen += hdrSZ; knum = encKey.Data.ID&0x7fffffff;
523  CLDBG("Ret " <<dLen <<" bytes of credentials; k=" <<knum);
524  return new XrdSecCredentials(credP, dLen);
525 }
526 
527 /******************************************************************************/
528 /* Private: F a t a l */
529 /******************************************************************************/
530 
531 int XrdSecProtocolsss::Fatal(XrdOucErrInfo *erP, const char *epn, int rc,
532  const char *etxt)
533 {
534  if (erP) {erP->setErrInfo(rc, etxt);
535  CLDBG(epn <<": " <<etxt);
536  }
537  else eMsg(epn, rc, etxt);
538  return 0;
539 }
540 
541 /******************************************************************************/
542 /* Private: g e t C r e d */
543 /******************************************************************************/
544 
545 int XrdSecProtocolsss::getCred(XrdOucErrInfo *einfo, XrdSecsssRR_DataHdr *&dP,
546  const char *myUrlID, const char *myIP)
547 {
548  int dLen;
549 
550 // Indicate we have been here
551 //
552  Sequence = 1;
553 
554 // For mutual authentication, the server needs to first send back a handshake.
555 //
556  if (isMutual)
560  }
561 
562 // Otherwise we use a static ID or a mapped id. Note that we disallow sending
563 // credentials unless mutual authentication occurs.
564 //
565  if (myUrlID && idMap)
566  {if ((dLen = idMap->Find(myUrlID, (char *&)dP, myIP, dataOpts)) <= 0)
567  return Fatal(einfo, "getCred", ESRCH, "No loginid mapping.");
568  } else {
569  int theOpts = dataOpts & ~XrdSecsssEnt::addCreds;
570  dLen = staticID->RR_Data((char *&)dP, myIP, theOpts);
571  }
572 
573 // Return response length
574 //
575  dP->Options = XrdSecsssRR_DataHdr::UseData;
576  return dLen;
577 }
578 
579 /******************************************************************************/
580 
581 int XrdSecProtocolsss::getCred(XrdOucErrInfo *einfo,
582  XrdSecsssRR_DataHdr *&dP,
583  const char *myUrlID,
584  const char *myIP,
585  XrdSecParameters *parm)
586 {
587  XrdSecsssKT::ktEnt decKey;
588  XrdSecsssRR_Data prData;
589  char *lidP = 0, *bP, *idP, *eodP, idType;
590  int idSz, dLen, theOpts;
591 
592 // Make sure we can decode this and not overrun our buffer
593 //
594  if (parm->size > (int)sizeof(prData.Data))
595  return Fatal(einfo, "getCred", EINVAL, "Invalid server response size.");
596 
597 // Decode the credentials
598 //
599  if ((dLen = Decode(einfo, decKey, parm->buffer, &prData, parm->size)) <= 0)
600  return Fatal(einfo, "getCred", EINVAL, "Unable to decode server response.");
601 
602 // Extract out the loginid. This messy code is for backwards compatibility.
603 //
604  bP = prData.Data; eodP = dLen + (char *)&prData;
605  while(bP < eodP)
606  {idType = *bP++;
607  if (!XrdOucPup::Unpack(&bP, eodP, &idP, idSz) || !idP || *idP == 0)
608  return Fatal(einfo, "getCred", EINVAL, "Invalid id string.");
609  switch(idType)
610  {case XrdSecsssRR_Data::theLgid: lidP = idP; break;
611  case XrdSecsssRR_Data::theHost: break;
612  case XrdSecsssRR_Data::theRand: break;
613  default: return Fatal(einfo,"getCred",EINVAL,"Invalid id type.");
614  }
615  }
616 
617 // Verify that we have the loginid
618 //
619  if (!lidP) return Fatal(einfo, "getCred", ENOENT, "No loginid returned.");
620 
621 // Try to map the id appropriately
622 //
623  if (!idMap) return staticID->RR_Data((char *&)dP, myIP, dataOpts);
624 
625 // Map the loginid. We disallow sending credentials unless the key allows it.
626 //
627  if (!myUrlID) myUrlID = lidP;
628  if (!(decKey.Data.Opts & XrdSecsssKT::ktEnt::allUSR))
629  theOpts = dataOpts & ~XrdSecsssEnt::addCreds;
630  else theOpts = dataOpts;
631  if ((dLen = idMap->Find(lidP, (char *&)dP, myIP, theOpts)) <= 0)
632  return Fatal(einfo, "getCred", ESRCH, "No loginid mapping.");
633 
634 // All done
635 //
636  dP->Options = XrdSecsssRR_DataHdr::UseData;
637  return dLen;
638 }
639 
640 /******************************************************************************/
641 /* g e t C r e d e n t i a l s */
642 /******************************************************************************/
643 
645  XrdOucErrInfo *einfo)
646 {
647  static const int nOpts = XrdNetUtils::oldFmt;
648  XrdSecsssRR_Hdr2 rrHdr;
649  sssRR_DataHdr rrDataHdr;
650  XrdSecsssKT::ktEnt encKey;
651  XrdOucEnv *errEnv;
652 
653  const char *myIP = 0, *myUD = 0;
654  char ipBuff[64];
655  int dLen;
656 
657 // Make sure we can extract out required information and get it as needed
658 //
659  if (einfo && (errEnv=einfo->getEnv()))
660  {if (isMapped) myUD = errEnv->Get("username");
661  if (!(myIP=errEnv->Get("sockname")))
662  {int fd = epAddr->SockFD();
663  if (fd > 0 && XrdNetUtils::IPFormat(-fd,ipBuff,sizeof(ipBuff),nOpts))
664  myIP = ipBuff;
665  else myIP = 0;
666  }
667  }
668 
669 // Do some debugging here
670 //
671  CLDBG("getCreds: " <<static_cast<int>(Sequence)
672  << " ud: '" <<(myUD ? myUD : "")
673  <<"' ip: '" <<(myIP ? myIP : "") <<"'");
674 
675 // Get the actual data portion
676 //
677  if (Sequence) dLen = getCred(einfo, rrDataHdr.P, myUD, myIP, parms);
678  else dLen = getCred(einfo, rrDataHdr.P, myUD, myIP);
679  if (!dLen) return (XrdSecCredentials *)0;
680 
681 // Get an encryption key
682 //
683  if (keyTab->getKey(encKey))
684  {Fatal(einfo, "getCredentials", ENOENT, "Encryption key not found.");
685  return (XrdSecCredentials *)0;
686  }
687 
688 // Fill out the header
689 //
690  strcpy(rrHdr.ProtID, XrdsssPROTOIDENT);
691  memset(rrHdr.Pad, 0, sizeof(rrHdr.Pad));
692  rrHdr.KeyID = htonll(encKey.Data.ID);
693  rrHdr.EncType = Crypto->Type();
694 
695 // Determine if we should send the keyname (v2 servers only)
696 //
697  if (v2EndPnt)
698  {int k = strlen(encKey.Data.Name), n = (k + 8) & ~7;
699  if (strlcpy(rrHdr.keyName, encKey.Data.Name, sizeof(rrHdr.keyName)) >= sizeof(rrHdr.keyName))
700  { Fatal(einfo, "getCredentials", EINVAL, "Encryption key name is too long.");
701  return nullptr;
702  }
703  if (n - k > 1) memset(rrHdr.keyName + k, 0, n - k);
704  rrHdr.knSize = static_cast<uint8_t>(n);
705  } else rrHdr.knSize = 0;
706 
707 // Now simply encode the data and return the result
708 //
709  return Encode(einfo, encKey, &rrHdr, rrDataHdr.P, dLen);
710 }
711 
712 /******************************************************************************/
713 /* Private: g e t L I D */
714 /******************************************************************************/
715 
716 char *XrdSecProtocolsss::getLID(char *buff, int blen)
717 {
718  const char *dot;
719 
720 // Extract out the loginid from the trace id
721 //
722  if (!Entity.tident
723  || !(dot = index(Entity.tident,'.'))
724  || dot == Entity.tident
725  || dot >= (Entity.tident+blen)) strcpy(buff,"nobody");
726  else {int idsz = dot - Entity.tident;
727  strncpy(buff, Entity.tident, idsz);
728  *(buff+idsz) = '\0';
729  }
730 
731 // All done
732 //
733  return buff;
734 }
735 
736 /******************************************************************************/
737 /* I n i t _ C l i e n t */
738 /******************************************************************************/
739 
741 {
742  XrdSysMutexHelper initMon(&initMutex);
743  XrdSecsssKT *ktP;
744  struct stat buf;
745  char *Colon;
746  int lifeTime;
747 
748 // We must have <enccode>.[+]<lifetime>:<keytab>
749 //
750  if (!pP || !*pP) return Fatal(erp, "Init_Client", EINVAL,
751  "Client parameters missing.");
752 
753 // Get encryption object
754 //
755  if (!*pP || *(pP+1) != '.') return Fatal(erp, "Init_Client", EINVAL,
756  "Encryption type missing.");
757  if (!(Crypto = Load_Crypto(erp, *pP))) return 0;
758  pP += 2;
759 
760 // Check if this is a v2 server and if credentials are to be sent
761 //
762  if (*pP == '+')
763  {v2EndPnt = true;
764  dataOpts |= XrdSecsssEnt::addExtra;
765  if (*(pP+1) == '0') dataOpts |= XrdSecsssEnt::addCreds;
766  }
767 
768 // The next item is the cred lifetime
769 //
770  lifeTime = strtol(pP, &Colon, 10);
771  if (!lifeTime || *Colon != ':') return Fatal(erp, "Init_Client", EINVAL,
772  "Credential lifetime missing.");
773  deltaTime = lifeTime; pP = Colon+1;
774 
775 // Get the correct keytab
776 //
777  if (ktFixed || (ktObject && ktObject->Same(pP))) keyTab = ktObject;
778  else if (*pP == '/' && !stat(pP, &buf))
779  {if (!(ktP=new XrdSecsssKT(erp,pP,XrdSecsssKT::isClient,3600)))
780  return Fatal(erp, "Init_Client", ENOMEM,
781  "Unable to create keytab object.");
782  if (erp->getErrInfo()) {delete ktP; return 0;}
783  if (!ktObject) ktObject = ktP;
784  keyTab = ktP;
785  CLDBG("Client keytab='" <<pP <<"'");
786  } else keyTab = ktObject;
787 
788  if (!keyTab)
789  return Fatal(erp, "Init_Client", ENOENT,
790  "Unable to determine keytab location.");
791 
792 // All done
793 //
794  return 1;
795 }
796 
797 /******************************************************************************/
798 /* I n i t _ S e r v e r */
799 /******************************************************************************/
800 
802 {
803 
804 // This is a trivial init
805 //
806  keyTab = ktObject;
807  Crypto = CryptObj;
808  return 1;
809 }
810 
811 /******************************************************************************/
812 /* L o a d _ C l i e n t */
813 /******************************************************************************/
814 
815 char *XrdSecProtocolsss::Load_Client(XrdOucErrInfo *erp, const char *parms)
816 {
817  static const char *KTPath = XrdSecsssKT::genFN();
818  static const int rfrHR = 60*60;
819  struct stat buf;
821  const char *kP = 0;
822  char *myName;
823 
824 // Get our full host name
825 //
826  if (!(myName = XrdNetUtils::MyHostName(0)))
827  {Fatal(erp, "Load_Client", ENOENT, "Unable to obtain local hostname.");
828  return (char *)0;
829  }
830 
831 // Tell the entity serialization object who we are
832 //
834  free(myName);
835 
836 // Check for the presence of a registry object
837 //
838  idMap = XrdSecsssID::getObj(aType, staticID);
839  switch(aType)
840  {case XrdSecsssID::idDynamic: isMutual = true; break;
841  case XrdSecsssID::idStaticM: isMutual = true;
842  idMap = 0; break;
843  case XrdSecsssID::idStatic: idMap = 0; break;
844  case XrdSecsssID::idMapped: isMapped = true; break;
845  case XrdSecsssID::idMappedM: isMapped = true; break;
846  default: idMap = 0; break;
847  }
848 
849 // We want to establish the default location of the keytable. First check
850 // the environment passed from the client then the envar. We support two
851 // version of the envar for backward compatibility due to an early mistake.
852 //
853  if( erp && erp->getEnv() && ( kP = erp->getEnv()->Get( "xrd.sss" ) ) )
854  ktFixed = true;
855  else if ( ( (kP = getenv("XrdSecSSSKT")) || (kP = getenv("XrdSecsssKT")) )
856  && *kP && !stat(kP, &buf))
857  ktFixed = true;
858  else kP = 0;
859 
860  if (!kP && !stat(KTPath, &buf)) kP = KTPath;
861 
862 // Build the keytable if we actual have a path (if none, then the server
863 // will have to supply the path)
864 //
865  if (kP)
866  {if (!(ktObject=new XrdSecsssKT(erp,kP,XrdSecsssKT::isClient,rfrHR)))
867  {Fatal(erp, "Load_Client", ENOMEM, "Unable to create keytab object.");
868  return (char *)0;
869  }
870  if (erp && erp->getErrInfo())
871  {delete ktObject, ktObject = 0; return (char *)0;}
872  CLDBG("Client keytab='" <<kP <<"'");
873  }
874 
875 // All done
876 //
877  return (char *)"";
878 }
879 
880 /******************************************************************************/
881 /* Private: L o a d _ C r y p t o */
882 /******************************************************************************/
883 
884 XrdCryptoLite *XrdSecProtocolsss::Load_Crypto(XrdOucErrInfo *erp,
885  const char *eN)
886 {
887  XrdCryptoLite *cP;
888  char buff[128];
889  int rc, i = 0;
890 
891 // Find correct crypto object
892 //
893  while(CryptoTab[i].cName && strcmp(CryptoTab[i].cName, eN)) i++;
894 
895 // If we didn't find it, complain
896 //
897  if (!CryptoTab[i].cName)
898  {sprintf(buff, "Secsss: %s cryptography not supported.", eN);
899  Fatal(erp, "Load_Crypto", EINVAL, buff);
900  return (XrdCryptoLite *)0;
901  }
902 
903 // Return load result
904 //
905  if ((cP = XrdCryptoLite::Create(rc, eN, CryptoTab[i].cType))) return cP;
906  sprintf(buff,"Secsss: %s cryptography load failed; %s",eN,XrdSysE2T(rc));
907  Fatal(erp, "Load_Crypto", EINVAL, buff);
908  return (XrdCryptoLite *)0;
909 }
910 
911 /******************************************************************************/
912 
913 XrdCryptoLite *XrdSecProtocolsss::Load_Crypto(XrdOucErrInfo *erp,
914  const char eT)
915 {
916  XrdCryptoLite *cP;
917  char buff[128];
918  int rc, i = 0;
919 
920 // Check if we can use the satic object
921 //
922  if (CryptObj && eT == CryptObj->Type()) return CryptObj;
923 
924 // Find correct crypto object
925 //
926  while(CryptoTab[i].cName && CryptoTab[i].cType != eT) i++;
927 
928 // If we didn't find it, complain
929 //
930  if (!CryptoTab[i].cName)
931  {sprintf(buff, "Secsss: 0x%hhx cryptography not supported.", eT);
932  Fatal(erp, "Load_Crypto", EINVAL, buff);
933  return (XrdCryptoLite *)0;
934  }
935 
936 // Return load result
937 //
938  if ((cP = XrdCryptoLite::Create(rc, CryptoTab[i].cName, eT))) return cP;
939  sprintf(buff,"Secsss: 0x%hhx cryptography load failed; %s",eT,XrdSysE2T(rc));
940  Fatal(erp, "Load_Crypto", EINVAL, buff);
941  return (XrdCryptoLite *)0;
942 }
943 
944 /******************************************************************************/
945 /* L o a d _ S e r v e r */
946 /******************************************************************************/
947 
948 char *XrdSecProtocolsss::Load_Server(XrdOucErrInfo *erp, const char *parms)
949 {
950  const char *msg = 0;
951  const char *encName = "bf32", *ktClient = "", *ktServer = 0;
952  char buff[2048], parmbuff[2048], *op, *od, *eP;
953  int lifeTime = 13, rfrTime = 60*60;
954  XrdOucTokenizer inParms(parmbuff);
955  const char *ask4Creds = "";
956 
957 // Duplicate the parms
958 //
959  if (parms) strlcpy(parmbuff, parms, sizeof(parmbuff));
960 
961 // Expected parameters: [{-c | --clientkt} <ckt_path>]
962 // [{-e | --encrypt} <enctype>]
963 // [{-g | --getcreds}]
964 // [{-k | --keyname}]
965 // [{-l | --lifetime} <seconds>]
966 // [{-p | --proxy} <prots>]
967 // [{-r | --refresh} <minutes>]
968 // [{-s | --serverkt} <skt_path>]
969 //
970  if (parms && inParms.GetLine())
971  while((op = inParms.GetToken()))
972  {if (!strcmp("-k", op) || !strcmp("--keyname", op))
973  {sssUseKN = true;
974  continue;
975  }
976  if (!strcmp("-g", op) || !strcmp("--getcreds", op))
977  {ask4Creds = "0";
978  continue;
979  }
980  if (!(od = inParms.GetToken()))
981  {sprintf(buff,"Secsss: Missing %s parameter argument",op);
982  msg = buff; break;
983  }
984  if (!strcmp("-c", op) || !strcmp("--clientkt", op))
985  ktClient = od;
986  else if (!strcmp("-e", op) || !strcmp("--encrypt", op))
987  encName = od;
988  else if (!strcmp("-l", op) || !strcmp("--lifetime", op))
989  {lifeTime = strtol(od, &eP, 10) * 60;
990  if (errno || *eP || lifeTime < 1)
991  {msg = "Secsss: Invalid life time"; break;}
992  }
993  else if (!strcmp("-p", op) || !strcmp("--proxy", op))
994  {int n = strlen(od) + 2;
995  aProts = (char *)malloc(n);
996  *aProts = ':';
997  strcpy(aProts+1, od);
998  }
999  else if (!strcmp("-r", op) || !strcmp("--rfresh", op))
1000  {rfrTime = strtol(od, &eP, 10) * 60;
1001  if (errno || *eP || rfrTime < 600)
1002  {msg = "Secsss: Invalid refresh time"; break;}
1003  }
1004  else if (!strcmp("-s", op) || !strcmp("-serverkt", op))
1005  ktServer = od;
1006  else {sprintf(buff,"Secsss: Invalid parameter - %s",op);
1007  msg = buff; break;
1008  }
1009  }
1010 
1011 // Check for errors
1012 //
1013  if (msg) {Fatal(erp, "Load_Server", EINVAL, msg); return (char *)0;}
1014 
1015 // Load the right crypto object
1016 //
1017  if (!(CryptObj = Load_Crypto(erp, encName))) return (char *)0;
1018 
1019 // Supply default keytab location if not specified
1020 //
1021  if (!ktServer) ktServer = XrdSecsssKT::genFN();
1022 
1023 // Set the delta time used to expire credentials
1024 //
1025  deltaTime = lifeTime;
1026 
1027 // Create a keytab object (only one for the server)
1028 //
1029  if (!(ktObject = new XrdSecsssKT(erp, ktServer, XrdSecsssKT::isServer,
1030  rfrTime)))
1031  {Fatal(erp, "Load_Server", ENOMEM, "Unable to create keytab object.");
1032  return (char *)0;
1033  }
1034  if (erp->getErrInfo()) return (char *)0;
1035  ktFixed = true;
1036  CLDBG("Server keytab='" <<ktServer <<"'");
1037 
1038 // Construct client parameter <enccode>.+<lifetime>:<keytab>
1039 // Note: The plus preceding the <lifetime> indicates that we are a V2 server.
1040 // V1 clients will simply ignore this and treat us as a V1 server.
1041 //
1042  sprintf(buff, "%c.+%s%d:%s", CryptObj->Type(),ask4Creds,lifeTime,ktClient);
1043  CLDBG("client parms='" <<buff <<"'");
1044  return strdup(buff);
1045 }
1046 
1047 /******************************************************************************/
1048 /* m y C l o c k */
1049 /******************************************************************************/
1050 
1051 int XrdSecProtocolsss::myClock()
1052 {
1053  static const time_t baseTime = 1222183880;
1054 
1055  return static_cast<int>(time(0)-baseTime);
1056 }
1057 
1058 /******************************************************************************/
1059 /* s e t I D */
1060 /******************************************************************************/
1061 
1062 char *XrdSecProtocolsss::setID(char *id, char **idP)
1063 {
1064  if (id)
1065  {int n = strlen(id);
1066  strcpy(*idP, id); id = *idP; *idP = *idP + n + 1;
1067  }
1068  return id;
1069 }
1070 
1071 /******************************************************************************/
1072 /* s e t I P */
1073 /******************************************************************************/
1074 
1075 void XrdSecProtocolsss::setIP(XrdNetAddrInfo &endPoint)
1076 {
1077  if (!endPoint.Format(urIP, sizeof(urIP), XrdNetAddrInfo::fmtAdv6)) *urIP=0;
1078  if (!endPoint.Format(urIQ, sizeof(urIQ), XrdNetAddrInfo::fmtAdv6,
1079  XrdNetAddrInfo::old6Map4)) *urIQ=0;
1080  Entity.addrInfo = epAddr = &endPoint;
1081 }
1082 
1083 /******************************************************************************/
1084 /* X r d S e c P r o t o c o l s s s I n i t */
1085 /******************************************************************************/
1086 
1087 extern "C"
1088 {
1089 char *XrdSecProtocolsssInit(const char mode,
1090  const char *parms,
1091  XrdOucErrInfo *erp)
1092 {
1093 
1094 // Set debug option
1095 //
1096  if (getenv("XrdSecDEBUG")) sssDEBUG = true;
1097 
1098 // Perform load-time initialization
1099 //
1100  return (mode == 'c' ? XrdSecProtocolsss::Load_Client(erp, parms)
1101  : XrdSecProtocolsss::Load_Server(erp, parms));
1102 }
1103 }
1104 
1105 /******************************************************************************/
1106 /* X r d S e c P r o t o c o l s s s O b j e c t */
1107 /******************************************************************************/
1108 
1110 
1111 extern "C"
1112 {
1114  const char *hostname,
1115  XrdNetAddrInfo &endPoint,
1116  const char *parms,
1117  XrdOucErrInfo *erp)
1118 {
1119  XrdSecProtocolsss *prot;
1120  int Ok;
1121 
1122 // Get a new protocol object
1123 //
1124  if (!(prot = new XrdSecProtocolsss(endPoint.Name(hostname), endPoint)))
1125  XrdSecProtocolsss::Fatal(erp, "sss_Object", ENOMEM,
1126  "Secsss: Insufficient memory for protocol.");
1127  else {Ok = (mode == 'c' ? prot->Init_Client(erp, parms)
1128  : prot->Init_Server(erp, parms));
1129 
1130  if (!Ok) {prot->Delete(); prot = 0;}
1131  }
1132 
1133 // All done
1134 //
1135  return (XrdSecProtocol *)prot;
1136 }
1137 }
int stat(const char *path, struct stat *buf)
#define XrdSecPROTOIDSIZE
Definition: XrdSecEntity.hh:47
XrdSecBuffer XrdSecCredentials
#define XrdsssPROTOIDENT
#define CLDBG(x)
XrdVERSIONINFO(XrdSecProtocolsssObject, secsss)
XrdSecProtocol * XrdSecProtocolsssObject(const char mode, const char *hostname, XrdNetAddrInfo &endPoint, const char *parms, XrdOucErrInfo *erp)
char * XrdSecProtocolsssInit(const char mode, const char *parms, XrdOucErrInfo *erp)
static const int XrdSecsssRR_Data_HdrLen
Definition: XrdSecsssRR.hh:77
int emsg(int rc, char *msg)
const char * XrdSysE2T(int errcode)
Definition: XrdSysE2T.cc:104
if(Avsz)
size_t strlcpy(char *dst, const char *src, size_t sz)
virtual int Encrypt(const char *key, int keyLen, const char *src, int srcLen, char *dst, int dstLen)=0
virtual int Overhead()
virtual int Decrypt(const char *key, int keyLen, const char *src, int srcLen, char *dst, int dstLen)=0
virtual char Type()
static XrdCryptoLite * Create(int &rc, const char *Name, const char Type='\0')
static const int old6Map4
Use deprecated IPV6 mapped format.
int Format(char *bAddr, int bLen, fmtUse fmtType=fmtAuto, int fmtOpts=0)
const char * Name(const char *eName=0, const char **eText=0)
static char * MyHostName(const char *eName="*unknown*", const char **eText=0)
Definition: XrdNetUtils.cc:667
static int IPFormat(const struct sockaddr *sAddr, char *bP, int bL, int opts=0)
Definition: XrdNetUtils.cc:584
static const int oldFmt
Definition: XrdNetUtils.hh:256
char * Get(const char *varname)
Definition: XrdOucEnv.hh:69
int setErrInfo(int code, const char *emsg)
XrdOucEnv * getEnv()
static int Unpack(char **buff, const char *bend, char **data, int &dlen)
Definition: XrdOucPup.cc:250
static int Pack(struct iovec **, const char *, unsigned short &buff)
Definition: XrdOucPup.cc:52
char * GetToken(char **rest=0, int lowcase=0)
static bool getGID(const char *gName, gid_t &gID)
Definition: XrdOucUtils.cc:514
static bool getUID(const char *uName, uid_t &uID, gid_t *gID=0)
Definition: XrdOucUtils.cc:530
bool Add(XrdSecAttr &attr)
char * vorg
Entity's virtual organization(s)
Definition: XrdSecEntity.hh:71
const char * pident
Trace identifier (originator)
Definition: XrdSecEntity.hh:82
int credslen
Length of the 'creds' data.
Definition: XrdSecEntity.hh:78
XrdNetAddrInfo * addrInfo
Entity's connection details.
Definition: XrdSecEntity.hh:80
XrdSecEntityAttr * eaAPI
non-const API to attributes
Definition: XrdSecEntity.hh:92
const char * tident
Trace identifier always preset.
Definition: XrdSecEntity.hh:81
char prot[XrdSecPROTOIDSIZE]
Auth protocol used (e.g. krb5)
Definition: XrdSecEntity.hh:67
char * caps
Entity's capabilities.
Definition: XrdSecEntity.hh:74
char * creds
Raw entity credentials or cert.
Definition: XrdSecEntity.hh:77
gid_t gid
Unix gid or 0 if none.
Definition: XrdSecEntity.hh:87
char * grps
Entity's group name(s)
Definition: XrdSecEntity.hh:73
uid_t uid
Unix uid or 0 if none.
Definition: XrdSecEntity.hh:86
char * name
Entity's name.
Definition: XrdSecEntity.hh:69
char * role
Entity's role(s)
Definition: XrdSecEntity.hh:72
char * endorsements
Protocol specific endorsements.
Definition: XrdSecEntity.hh:75
char * host
Entity's host name dnr dependent.
Definition: XrdSecEntity.hh:70
XrdSecEntity Entity
static void setHostName(const char *hnP)
static const int addExtra
Add v2 data.
Definition: XrdSecsssEnt.hh:77
static const int addCreds
Add v2 data plus creds.
Definition: XrdSecsssEnt.hh:78
int RR_Data(char *&dP, const char *hostIP, int dataOpts)
static const int anyUSR
Definition: XrdSecsssKT.hh:67
struct XrdSecsssKT::ktEnt::ktData Data
static const int noIPCK
Definition: XrdSecsssKT.hh:70
static const int anyGRP
Definition: XrdSecsssKT.hh:68
static const int allUSR
Definition: XrdSecsssKT.hh:66
static const int usrGRP
Definition: XrdSecsssKT.hh:69
static const int NameSZ
Definition: XrdSecsssKT.hh:49
int Same(const char *path)
Definition: XrdSecsssKT.hh:109
static char * genFN()
Definition: XrdSecsssKT.cc:249
int getKey(ktEnt &ktEql, bool andKeyID=false)
Definition: XrdSecsssKT.cc:207
static void genKey(char *Buff, int blen)
Definition: XrdSecsssKT.cc:268
Generic structure to pass security information back and forth.
char * buffer
Pointer to the buffer.
int size
Size of the buffer or length of data in the buffer.
static int eMsg(const char *epn, int rc, const char *txt1, const char *txt2=0, const char *txt3=0, const char *txt4=0)
static char * Load_Client(XrdOucErrInfo *erp, const char *Parms)
int Init_Server(XrdOucErrInfo *erp, const char *Parms)
XrdSecCredentials * getCredentials(XrdSecParameters *parms=0, XrdOucErrInfo *einfo=0)
static char * Load_Server(XrdOucErrInfo *erp, const char *Parms)
int Authenticate(XrdSecCredentials *cred, XrdSecParameters **parms, XrdOucErrInfo *einfo=0)
static int Fatal(XrdOucErrInfo *erP, const char *epn, int rc, const char *etxt)
void Delete()
Delete the protocol object. DO NOT use C++ delete() on this object.
int Init_Client(XrdOucErrInfo *erp, const char *Parms)
static const char SndLID
Definition: XrdSecsssRR.hh:72
static const char UseData
Definition: XrdSecsssRR.hh:71
char Data[XrdSecsssRR_Data::MinDSz+16]
Definition: XrdSecsssRR.hh:113
static const char theHost
Definition: XrdSecsssRR.hh:106
static const char theUser
Definition: XrdSecsssRR.hh:101
static const char theAKey
Definition: XrdSecsssRR.hh:99
static const char theCaps
Definition: XrdSecsssRR.hh:103
char Data[DataSz]
Definition: XrdSecsssRR.hh:85
static const char theAuth
Definition: XrdSecsssRR.hh:97
static const char theRole
Definition: XrdSecsssRR.hh:91
static const char theName
Definition: XrdSecsssRR.hh:89
static const char theLgid
Definition: XrdSecsssRR.hh:105
static const char theGrps
Definition: XrdSecsssRR.hh:92
static const char theRand
Definition: XrdSecsssRR.hh:95
static const char theEndo
Definition: XrdSecsssRR.hh:93
static const char theAVal
Definition: XrdSecsssRR.hh:100
static const char theVorg
Definition: XrdSecsssRR.hh:90
static const char theGrup
Definition: XrdSecsssRR.hh:102
static const char theTID
Definition: XrdSecsssRR.hh:98
static const int MaxDSz
Definition: XrdSecsssRR.hh:82
static const char theCred
Definition: XrdSecsssRR.hh:94
char keyName[XrdSecsssKT::ktEnt::NameSZ]
Definition: XrdSecsssRR.hh:59
long long KeyID
Definition: XrdSecsssRR.hh:49
static const char etBFish32
Definition: XrdSecsssRR.hh:47