XRootD
XrdSecsssEnt.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S e c s s s E n t . c c */
4 /* */
5 /* (c) 2020 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 #include "XrdOuc/XrdOucPup.hh"
32 #include "XrdOuc/XrdOucUtils.hh"
33 #include "XrdSec/XrdSecEntity.hh"
37 #include "XrdSecsss/XrdSecsssKT.hh"
39 #include "XrdSecsss/XrdSecsssRR.hh"
40 
41 using namespace XrdSecsssMap;
42 
43 /******************************************************************************/
44 /* L o c a l C l a s s e s */
45 /******************************************************************************/
46 
47 namespace
48 {
49 class copyAttrs : public XrdSecEntityAttrCB
50 {
51 public:
52 
53 XrdSecEntityAttrCB::Action Attr(const char *key, const char *val)
54  {if (!key) return XrdSecEntityAttrCB::Stop;
55  if (calcSz)
56  {bL += strlen(key) + strlen(val) + 8;
57  } else {
59  XrdOucPup::Pack(&bP,key);
61  XrdOucPup::Pack(&bP,val);
62  }
64  }
65 char *bP;
66 int bL;
67 bool calcSz;
68 
69  copyAttrs() : bP(0), bL(0), calcSz(false) {}
70  ~copyAttrs() {}
71 };
72 }
73 
74 /******************************************************************************/
75 /* S t a t i c M e m b e r s */
76 /******************************************************************************/
77 
78 char *XrdSecsssEnt::myHostName = 0;
79 int XrdSecsssEnt::myHostNLen = 0;
80 
81 /******************************************************************************/
82 /* A d d C o n t a c t */
83 /******************************************************************************/
84 
85 void XrdSecsssEnt::AddContact(const std::string &hostID)
86 {
87 // If we are tracking connections then add this one to the set. We use the
88 // fact that a set can only have one instance of a member and ignores dups.
89 //
90  if (conTrack) Contacts.insert(hostID);
91 }
92 
93 /******************************************************************************/
94 /* D e l e t e */
95 /******************************************************************************/
96 
98 {
99 // Invoke the cleanup call back if there is something to clean up
100 //
101  if (conTrack && Contacts.size()) conTrack->Cleanup(Contacts, *eP);
102 
103 // Now we can delete ourselves
104 //
105  delete this;
106 }
107 
108 /******************************************************************************/
109 /* R R _ D a t a */
110 /******************************************************************************/
111 
112 int XrdSecsssEnt::RR_Data(char *&dP, const char *hostIP, int dataOpts)
113 {
114  char *bP;
115  int cpyLen, totLen = XrdSecsssRR_Data_HdrLen;
116  int n = 0;
117 
118 // If we have not yet serialized the data, do so now.
119 //
120  if (!eData && !Serialize()) return 0;
121 
122 // Compute the length we will need for the buffer (it must be exact)
123 //
124  if (dataOpts & v2Client)
125  {cpyLen = tLen;
126  if (dataOpts & addCreds) cpyLen += credLen;
127  } else cpyLen = iLen;
128  totLen += cpyLen;
129 
130 // Add in the hostIP if specified and hostname if available
131 //
132  n = strlen(hostIP) + 4;
133  if (hostIP) totLen += n;
134  totLen += myHostNLen;
135 
136 // Allocate a buffer
137 //
138  if (!(dP = (char *)malloc(totLen))) return 0;
139  bP = dP + XrdSecsssRR_Data_HdrLen;
140 
141 // The first thing in the serialized packet is the host IP
142 //
143  if (hostIP)
144  {*bP++ = XrdSecsssRR_Data::theHost;
145  XrdOucPup::Pack(&bP, hostIP);
146  }
147 
148 // The next thing is to addthe hostname for backward compatibility
149 //
150  if (myHostName)
151  {memcpy(bP, myHostName, myHostNLen); bP += myHostNLen;}
152 
153 // Copy the remaining data
154 //
155  memcpy(bP, eData, cpyLen);
156 
157 // Return length of the whole thing
158 //
159  return totLen;
160 }
161 
162 /******************************************************************************/
163 /* Private: S e r i a l i z e */
164 /******************************************************************************/
165 
166 bool XrdSecsssEnt::Serialize()
167 {
168  copyAttrs theAttr;
169  char *bP, rBuff[XrdSecsssRR_Data::MinDSz], uName[256], gName[256];
170  int n, rLen = 0;
171  bool incCreds = false;
172 
173 // Make sure we have an entity here
174 //
175  if (!eP) return false;
176 
177 // Perform some initialization here
178 //
179  *uName = 0;
180  *gName = 0;
181 
182 // Calculate the length needed for the entity (4 bytes overhead for each item)
183 // These items ae always sent to all servers.
184 //
185  iLen = (eP->name ? strlen(eP->name) + 4 : 0)
186  + (eP->vorg ? strlen(eP->vorg) + 4 : 0)
187  + (eP->role ? strlen(eP->role) + 4 : 0)
188  + (eP->grps ? strlen(eP->grps) + 4 : 0)
189  + (eP->caps ? strlen(eP->caps) + 4 : 0)
190  + (eP->endorsements ? strlen(eP->endorsements) + 4 : 0);
191 
192 // The above is always sent to V1 servers and it can't be too short
193 //
194  n = iLen + XrdSecsssRR_Data_HdrLen;
195  if (n < XrdSecsssRR_Data::MinDSz)
196  {rLen = XrdSecsssRR_Data::MinDSz - n;
197  XrdSecsssKT::genKey(rBuff, rLen);
198  if (!rBuff[0]) rBuff[0] = 0xff;
199  iLen += rLen + 4;
200  }
201 
202 // Now, compute the size of all extra stuff we will be sending. Note that
203 // V1 servers will ignore them but we might exceed their maximum buffer size
204 // if we do, so we never send this information.
205 //
206  tLen = iLen;
207  theAttr.calcSz = true;
208  eP->eaAPI->List(theAttr);
209  theAttr.calcSz = false;
210  tLen += theAttr.bL;
211 
212 // Add in the length authnetication protocol (original)
213 //
214  tLen += strlen(eP->prot) + 4;
215 
216 // Add in the length of the traceID that we will send
217 //
218  if (eP->tident) tLen += strlen(eP->tident) + 4;
219 
220 // If the underlying protocol is not sss then it may replace the username
221 // and group name which determines the uid and gid. Otherwise, those are
222 // extracted from the keyfile by the server. This only applies if a uid
223 // or gid was enetered in the SecEntity object in the first place.
224 //
225  if (*(eP->prot) && strcmp("sss", eP->prot))
226  {if (eP->uid && !XrdOucUtils::UserName( eP->uid, uName, sizeof(uName)))
227  tLen += strlen(uName) + 4;
228  else *uName = 0;
229  if (eP->gid && XrdOucUtils::GroupName(eP->gid, gName, sizeof(gName)))
230  tLen += strlen(gName) + 4;
231  else *gName = 0;
232  }
233 
234 // At the end we attach the credentials if they are not too large. The data
235 // must be at the end because it can optionally be pruned when returned.
236 //
237  if (eP->credslen && eP->credslen <= XrdSecsssRR_Data::MaxCSz)
238  {tLen += eP->credslen + 3;
239  incCreds = true;
240  }
241 
242 // If no identity information, return failure otherwise allocate a struct
243 //
244  if (!tLen || !(eData = (char *)malloc(tLen))) return 0;
245 
246 // Now stick each entry into the iData field
247 //
248  bP = eData;
249  if (eP->name)
250  {*bP++ = XrdSecsssRR_Data::theName; XrdOucPup::Pack(&bP,eP->name);}
251  if (eP->vorg)
252  {*bP++ = XrdSecsssRR_Data::theVorg; XrdOucPup::Pack(&bP,eP->vorg);}
253  if (eP->role)
254  {*bP++ = XrdSecsssRR_Data::theRole; XrdOucPup::Pack(&bP,eP->role);}
255  if (eP->grps)
256  {*bP++ = XrdSecsssRR_Data::theGrps; XrdOucPup::Pack(&bP,eP->grps);}
257  if (eP->caps)
258  {*bP++ = XrdSecsssRR_Data::theCaps; XrdOucPup::Pack(&bP,eP->caps);}
259  if (eP->endorsements)
260  {*bP++ = XrdSecsssRR_Data::theEndo; XrdOucPup::Pack(&bP,eP->endorsements);}
261  if (rLen)
262  {*bP++ = XrdSecsssRR_Data::theRand; XrdOucPup::Pack(&bP, rBuff, rLen);}
263  iLen = bP - eData;
264 
265 // Add the underlying security protocol
266 //
267  if (*(eP->prot))
268  {*bP++ = XrdSecsssRR_Data::theAuth; XrdOucPup::Pack(&bP,eP->prot);}
269 
270 // Add the trace ident
271 //
272  if (eP->tident)
273  {*bP++ = XrdSecsssRR_Data::theTID; XrdOucPup::Pack(&bP,eP->tident);}
274 
275 // Add the user name if present
276 //
277  if (*uName)
278  {*bP++ = XrdSecsssRR_Data::theUser; XrdOucPup::Pack(&bP,uName);}
279 
280 // Add the group name if present
281 //
282  if (*gName)
283  {*bP++ = XrdSecsssRR_Data::theGrup; XrdOucPup::Pack(&bP,gName);}
284 
285 // Add additional attributes. The buffer is gauranteed to be big enough.
286 //
287  if (theAttr.bL > 0)
288  {theAttr.bP = bP;
289  eP->eaAPI->List(theAttr);
290  bP = theAttr.bP;
291  }
292 
293 // Compue total length
294 //
295  tLen = bP - eData;
296 
297 // Attach the credentials if we must
298 //
299  if (incCreds)
300  {*bP++ = XrdSecsssRR_Data::theCred;
301  credLen = XrdOucPup::Pack(&bP, eP->creds, eP->credslen) + 1;
302  } else credLen = 0;
303 
304 // All done
305 //
306  return true;
307 }
308 
309 /******************************************************************************/
310 /* s e t H o s t N a m e */
311 /******************************************************************************/
312 
313 void XrdSecsssEnt::setHostName(const char *hnP)
314 {
315  char *bP;
316  int n = strlen(hnP);
317 
318 // The host name always goes into the serialized data. So, we prepack it here.
319 //
320  if (n)
321  {if (myHostName) free(myHostName);
322  myHostName = bP = (char *)malloc(n+4);
324  myHostNLen = XrdOucPup::Pack(&bP, hnP) + 1;
325  }
326 }
static const int XrdSecsssRR_Data_HdrLen
Definition: XrdSecsssRR.hh:77
static int Pack(struct iovec **, const char *, unsigned short &buff)
Definition: XrdOucPup.cc:52
static int UserName(uid_t uID, char *uName, int uNsz)
static int GroupName(gid_t gID, char *gName, int gNsz)
Definition: XrdOucUtils.cc:596
@ Stop
Stop the iteration.
@ Next
Proceed to the next key-value pair.
virtual void Cleanup(const std::set< std::string > &Contacts, const XrdSecEntity &Entity)=0
void Delete()
Delete this entity object.
Definition: XrdSecsssEnt.cc:97
static void setHostName(const char *hnP)
void AddContact(const std::string &hostID)
Definition: XrdSecsssEnt.cc:85
int RR_Data(char *&dP, const char *hostIP, int dataOpts)
static void genKey(char *Buff, int blen)
Definition: XrdSecsssKT.cc:268
const char * myHostName
XrdSecsssCon * conTrack
Definition: XrdSecsssID.cc:64
static const char theHost
Definition: XrdSecsssRR.hh:106
static const int MaxCSz
Definition: XrdSecsssRR.hh:81
static const char theUser
Definition: XrdSecsssRR.hh:101
static const char theAKey
Definition: XrdSecsssRR.hh:99
static const char theCaps
Definition: XrdSecsssRR.hh:103
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 int MinDSz
Definition: XrdSecsssRR.hh:83
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 char theCred
Definition: XrdSecsssRR.hh:94