Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TSecContext.cxx
Go to the documentation of this file.
1 // @(#)root/net:$Id$
2 // Author: G. Ganis 19/03/2003
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TSecContext //
15 // //
16 // Contains details about an established security context //
17 // Used by THostAuth //
18 // //
19 //////////////////////////////////////////////////////////////////////////
20 
21 #include "RConfigure.h"
22 
23 #include <stdlib.h>
24 
25 #include "TSecContext.h"
26 #include "TSocket.h"
27 #include "TUrl.h"
28 #include "TROOT.h"
29 #include "TError.h"
30 #include "TVirtualMutex.h"
31 
32 ClassImp(TSecContext);
33 ClassImp(TSecContextCleanup);
34 
35 const TDatime kROOTTZERO = 788914800;
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Ctor for SecContext object.
39 
40 TSecContext::TSecContext(const char *user, const char *host, Int_t meth,
41  Int_t offset, const char *id,
42  const char *token, TDatime expdate, void *ctx)
43  : TObject()
44 {
45  R__ASSERT(gROOT);
46 
47  fContext = ctx;
48  fCleanup = new TList;
49  fExpDate = expdate;
50  if (offset > -1) {
51  if (fExpDate < TDatime()) {
52  // This means expdate was not initialized
53  // We set it to default, ie 1 day from now
54  fExpDate.Set(TDatime().GetDate() + 1, TDatime().GetTime());
55  }
56  }
57  fHost = host;
58  fID = id;
59  fMethod = meth;
60  fMethodName = "";
61  fOffSet = offset;
62  fToken = token;
63  fUser = user;
64 
65  // Keep official list updated with active TSecContexts
66  if (fOffSet > -1) {
67  R__LOCKGUARD(gROOTMutex);
68  gROOT->GetListOfSecContexts()->Add(this);
69  }
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Ctor for SecContext object.
74 /// User and host from url = user@host .
75 
76 TSecContext::TSecContext(const char *url, Int_t meth, Int_t offset,
77  const char *token, const char *id,
78  TDatime expdate, void *ctx)
79  : TObject()
80 {
81  R__ASSERT(gROOT);
82 
83  fContext = ctx;
84  fCleanup = new TList;
85  fExpDate = expdate;
86  if (offset > -1) {
87  if (fExpDate < TDatime()) {
88  // This means expdate was not initialized
89  // We set it to default, ie 1 day from now
90  fExpDate.Set(TDatime().GetDate() + 1, TDatime().GetTime());
91  }
92  }
93  fHost = TUrl(url).GetHost();
94  fID = id;
95  fMethod = meth;
96  fMethodName = "";
97  fOffSet = offset;
98  fToken = token;
99  fUser = TUrl(url).GetUser();
100 
101  // Keep official list updated with active TSecContexts
102  if (fOffSet > -1) {
103  R__LOCKGUARD(gROOTMutex);
104  gROOT->GetListOfSecContexts()->Add(this);
105  }
106 }
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 ///copy constructor
110 
111 TSecContext::TSecContext(const TSecContext& sc) :
112  TObject(sc),
113  fContext(sc.fContext),
114  fCleanup(sc.fCleanup),
115  fExpDate(sc.fExpDate),
116  fHost(sc.fHost),
117  fID(sc.fID),
118  fMethod(sc.fMethod),
119  fMethodName(sc.fMethodName),
120  fOffSet(sc.fOffSet),
121  fToken(sc.fToken),
122  fUser(sc.fUser)
123 {
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 ///assignement operator
128 
129 TSecContext& TSecContext::operator=(const TSecContext& sc)
130 {
131  if(this!=&sc) {
132  TObject::operator=(sc);
133  fContext=sc.fContext;
134  fCleanup=sc.fCleanup;
135  fExpDate=sc.fExpDate;
136  fHost=sc.fHost;
137  fID=sc.fID;
138  fMethod=sc.fMethod;
139  fMethodName=sc.fMethodName;
140  fOffSet=sc.fOffSet;
141  fToken=sc.fToken;
142  fUser=sc.fUser;
143  }
144  return *this;
145 }
146 
147 ////////////////////////////////////////////////////////////////////////////////
148 /// Dtor: delete (deActivate, local/remote cleanup, list removal)
149 /// all what is still active
150 
151 TSecContext::~TSecContext()
152 {
153  Cleanup();
154 }
155 ////////////////////////////////////////////////////////////////////////////////
156 /// Cleanup what is still active
157 
158 void TSecContext::Cleanup()
159 {
160  if (IsActive()) {
161  CleanupSecContext(kTRUE);
162  DeActivate("R");
163  // All have been remotely Deactivated
164  TIter nxtl(gROOT->GetListOfSecContexts());
165  TSecContext *nscl;
166  while ((nscl = (TSecContext *)nxtl())) {
167  if (nscl != this && !strcmp(nscl->GetHost(), fHost.Data())) {
168  // Need to set ofs=-1 to avoid sending another
169  // cleanup request
170  nscl->DeActivate("");
171  }
172  }
173  }
174 
175  // Delete the cleanup list
176  if (fCleanup) {
177  fCleanup->Delete();
178  delete fCleanup;
179  fCleanup = 0;
180  }
181 }
182 
183 ////////////////////////////////////////////////////////////////////////////////
184 /// Set OffSet to -1 and expiring Date to default
185 /// Remove from the list
186 /// If Opt contains "C" or "c", ask for remote cleanup
187 /// If Opt contains "R" or "r", remove from the list
188 /// Default Opt="CR"
189 
190 void TSecContext::DeActivate(Option_t *Opt)
191 {
192  // Ask remote cleanup of this context
193  Bool_t clean = (strstr(Opt,"C") || strstr(Opt,"c"));
194  if (clean && fOffSet > -1)
195  CleanupSecContext(kFALSE);
196 
197  Bool_t remove = (strstr(Opt,"R") || strstr(Opt,"r"));
198  if (remove && fOffSet > -1){
199  R__LOCKGUARD(gROOTMutex);
200  // Remove from the global list
201  gROOT->GetListOfSecContexts()->Remove(this);
202  }
203 
204  // Set inactive
205  fOffSet = -1;
206  fExpDate = kROOTTZERO;
207 }
208 
209 ////////////////////////////////////////////////////////////////////////////////
210 /// Create a new TSecContextCleanup
211 /// Internally is added to the list
212 
213 void TSecContext::AddForCleanup(Int_t port, Int_t proto, Int_t type)
214 {
215  TSecContextCleanup *tscc = new TSecContextCleanup(port, proto, type);
216  fCleanup->Add(tscc);
217 
218 }
219 
220 ////////////////////////////////////////////////////////////////////////////////
221 /// Checks if this security context is for method named 'methname'
222 /// Case sensitive.
223 
224 Bool_t TSecContext::IsA(const char *methname)
225 {
226  return Bool_t(!strcmp(methname, GetMethodName()));
227 }
228 
229 ////////////////////////////////////////////////////////////////////////////////
230 /// Check remote OffSet and expiring Date
231 
232 Bool_t TSecContext::IsActive() const
233 {
234  if (fOffSet > -1 && fExpDate > TDatime())
235  return kTRUE;
236  // Invalid
237  return kFALSE;
238 }
239 
240 ////////////////////////////////////////////////////////////////////////////////
241 /// If opt is "F" (default) print object content.
242 /// If opt is "<number>" print in special form for calls within THostAuth
243 /// with cardinality <number>
244 /// If opt is "S" prints short in-line form for calls within TFTP,
245 /// TSlave, TProof ...
246 
247 void TSecContext::Print(Option_t *opt) const
248 {
249  char aOrd[16] = {0};
250  char aSpc[16] = {0};
251 
252  // Check if option is numeric
253  Int_t ord = -1, i = 0;
254  for (; i < (Int_t)strlen(opt); i++) {
255  if (opt[i] < 48 || opt[i] > 57) {
256  ord = -2;
257  break;
258  }
259  }
260  // If numeric get the cardinality and prepare the strings
261  if (ord == -1)
262  ord = atoi(opt);
263 
264  // If asked to print ordinal number, preapre the string
265  if (ord > -1) {
266  snprintf(aOrd, sizeof(aOrd), "%d)", ord);
267  // and take care of alignment
268  Int_t len=strlen(aOrd);
269  while (len--)
270  strlcat(aSpc, " ", sizeof(aSpc));
271  }
272 
273  if (!strncasecmp(opt,"F",1)) {
274  Info("Print",
275  "+------------------------------------------------------+");
276  Info("Print",
277  "+ Host:%s Method:%d (%s) User:'%s'",
278  GetHost(), fMethod, GetMethodName(),
279  fUser.Data());
280  Info("Print",
281  "+ OffSet:%d, id:%s", fOffSet, fID.Data());
282  if (fOffSet > -1)
283  Info("Print",
284  "+ Expiration time: %s",fExpDate.AsString());
285  Info("Print",
286  "+------------------------------------------------------+");
287  } else if (!strncasecmp(opt,"S",1)) {
288  if (fOffSet > -1) {
289  Printf("Security context: Method: %d (%s) expiring on %s",
290  fMethod, GetMethodName(),
291  fExpDate.AsString());
292  } else {
293  Printf("Security context: Method: %d (%s) not reusable",
294  fMethod, GetMethodName());
295  }
296  } else {
297  // special printing form for THostAuth
298  Info("PrintEstblshed","+ %s h:%s met:%d (%s) us:'%s'",
299  aOrd, GetHost(), fMethod, GetMethodName(),
300  fUser.Data());
301  Info("PrintEstblshed","+ %s offset:%d id:%s", aSpc, fOffSet, fID.Data());
302  if (fOffSet > -1)
303  Info("PrintEstblshed","+ %s expiring: %s",aSpc,fExpDate.AsString());
304  }
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 /// Returns short string with relevant information about this
309 /// security context
310 
311 const char *TSecContext::AsString(TString &out)
312 {
313  if (fOffSet > -1) {
314  char expdate[32];
315  out = Form("Method: %d (%s) expiring on %s",
316  fMethod, GetMethodName(), fExpDate.AsString(expdate));
317  } else {
318  if (fOffSet == -1)
319  out = Form("Method: %d (%s) not reusable", fMethod, GetMethodName());
320  else if (fOffSet == -3)
321  out = Form("Method: %d (%s) authorized by /etc/hosts.equiv or $HOME/.rhosts",
322  fMethod, GetMethodName());
323  else if (fOffSet == -4)
324  out = Form("No authentication required remotely");
325  }
326  return out.Data();
327 }
328 
329 ////////////////////////////////////////////////////////////////////////////////
330 /// Ask remote client to cleanup security context 'ctx'
331 /// If 'all', all sec context with the same host as ctx
332 /// are cleaned.
333 
334 Bool_t TSecContext::CleanupSecContext(Bool_t)
335 {
336  AbstractMethod("CleanupSecContext");
337  return kFALSE;
338 }