Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TRootSecContext.cxx
Go to the documentation of this file.
1 // @(#)root/auth:$Id$
2 // Author: G. Ganis 08/07/2005
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2005, 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 // TRootSecContext //
15 // //
16 // Special implementation of TSecContext //
17 // //
18 //////////////////////////////////////////////////////////////////////////
19 
20 #include "RConfigure.h"
21 
22 #include <stdlib.h>
23 
24 #include "TError.h"
25 #include "TRootSecContext.h"
26 #include "TROOT.h"
27 #include "TSocket.h"
28 #include "TUrl.h"
29 #include "TVirtualMutex.h"
30 
31 ClassImp(TRootSecContext);
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 /// Ctor for SecContext object.
35 
36  TRootSecContext::TRootSecContext(const char *user, const char *host, Int_t meth,
37  Int_t offset, const char *id,
38  const char *token, TDatime expdate,
39  void *ctx, Int_t key)
40  : TSecContext(user, host, meth, offset, id, token, expdate, ctx)
41 {
42  R__ASSERT(gROOT);
43 
44  fRSAKey = key;
45  fMethodName = TAuthenticate::GetAuthMethod(fMethod);
46 }
47 
48 ////////////////////////////////////////////////////////////////////////////////
49 /// Ctor for SecContext object.
50 /// User and host from url = user@host .
51 
52 TRootSecContext::TRootSecContext(const char *url, Int_t meth, Int_t offset,
53  const char *id, const char *token,
54  TDatime expdate, void *ctx, Int_t key)
55  : TSecContext(url, meth, offset, id, token, expdate, ctx)
56 {
57  R__ASSERT(gROOT);
58 
59  fRSAKey = key;
60  fMethodName = TAuthenticate::GetAuthMethod(fMethod);
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// Dtor: delete (deActivate, local/remote cleanup, list removal)
65 /// all what is still active
66 
67 TRootSecContext::~TRootSecContext()
68 {
69  TSecContext::Cleanup();
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Set OffSet to -1 and expiring Date to default
74 /// Remove from the list
75 /// If Opt contains "C" or "c", ask for remote cleanup
76 /// If Opt contains "R" or "r", remove from the list
77 /// Default Opt="CR"
78 
79 void TRootSecContext::DeActivate(Option_t *Opt)
80 {
81  // Ask remote cleanup of this context
82  Bool_t clean = (strstr(Opt,"C") || strstr(Opt,"c"));
83  if (clean && fOffSet > -1)
84  CleanupSecContext(kFALSE);
85 
86  // Cleanup TPwdCtx object fro UsrPwd
87  if (fMethod == TAuthenticate::kClear)
88  if (fContext) {
89  delete (TPwdCtx *)fContext;
90  fContext = 0;
91  }
92 
93  Bool_t remove = (strstr(Opt,"R") || strstr(Opt,"r"));
94  if (remove && fOffSet > -1){
95  R__LOCKGUARD(gROOTMutex);
96  // Remove from the global list
97  gROOT->GetListOfSecContexts()->Remove(this);
98  // Remove also from local lists in THostAuth objects
99  TAuthenticate::RemoveSecContext(this);
100  }
101 
102  // Set inactive
103  fOffSet = -1;
104  fExpDate = kROOTTZERO;
105 
106 }
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// Ask remote client to cleanup security context 'ctx'
110 /// If 'all', all sec context with the same host as ctx
111 /// are cleaned.
112 
113 Bool_t TRootSecContext::CleanupSecContext(Bool_t all)
114 {
115  Bool_t cleaned = kFALSE;
116 
117  // Nothing to do if inactive ...
118  if (!IsActive())
119  return kTRUE;
120 
121  // Contact remote services that used this context,
122  // starting from the last ...
123  TIter last(fCleanup,kIterBackward);
124  TSecContextCleanup *nscc = 0;
125  while ((nscc = (TSecContextCleanup *)last()) && !cleaned) {
126 
127  // First check if remote daemon supports cleaning
128  Int_t srvtyp = nscc->GetType();
129  Int_t rproto = nscc->GetProtocol();
130  Int_t level = 2;
131  if ((srvtyp == TSocket::kROOTD && rproto < 10) ||
132  (srvtyp == TSocket::kPROOFD && rproto < 9))
133  level = 1;
134  if ((srvtyp == TSocket::kROOTD && rproto < 8) ||
135  (srvtyp == TSocket::kPROOFD && rproto < 7))
136  level = 0;
137  if (level) {
138  Int_t port = nscc->GetPort();
139 
140  TSocket *news = new TSocket(fHost.Data(),port,-1);
141 
142  if (news && news->IsValid()) {
143  if (srvtyp == TSocket::kPROOFD) {
144  news->SetOption(kNoDelay, 1);
145  news->Send("cleaning request");
146  } else
147  news->SetOption(kNoDelay, 0);
148 
149  // Backward compatibility: send socket size
150  if (srvtyp == TSocket::kROOTD && level == 1)
151  news->Send((Int_t)0, (Int_t)0);
152 
153  if (all || level == 1) {
154  news->Send(Form("%d",TAuthenticate::fgProcessID), kROOTD_CLEANUP);
155  cleaned = kTRUE;
156  } else {
157  news->Send(Form("%d %d %d %s", TAuthenticate::fgProcessID, fMethod,
158  fOffSet, fUser.Data()), kROOTD_CLEANUP);
159  if (TAuthenticate::SecureSend(news, 1, fRSAKey,
160  (char *)(fToken.Data())) == -1) {
161  Info("CleanupSecContext", "problems secure-sending token");
162  } else {
163  cleaned = kTRUE;
164  }
165  }
166  if (cleaned && gDebug > 2) {
167  char srvname[3][10] = {"sockd", "rootd", "proofd"};
168  Info("CleanupSecContext",
169  "remote %s notified for cleanup (%s,%d)",
170  srvname[srvtyp],fHost.Data(),port);
171  }
172  }
173  SafeDelete(news);
174  }
175  }
176 
177  if (!cleaned)
178  if (gDebug > 2)
179  Info("CleanupSecContext",
180  "unable to open valid socket for cleanup for %s", fHost.Data());
181 
182  return cleaned;
183 }
184 
185 ////////////////////////////////////////////////////////////////////////////////
186 /// If opt is "F" (default) print object content.
187 /// If opt is "<number>" print in special form for calls within THostAuth
188 /// with cardinality <number>
189 /// If opt is "S" prints short in-line form for calls within TFTP,
190 /// TSlave, TProof ...
191 
192 void TRootSecContext::Print(Option_t *opt) const
193 {
194  // Check if option is numeric
195  Int_t ord = -1, i = 0;
196  for (; i < (Int_t)strlen(opt); i++) {
197  if (opt[i] < 48 || opt[i] > 57) {
198  ord = -2;
199  break;
200  }
201  }
202  // If numeric get the cardinality and prepare the strings
203  if (ord == -1)
204  ord = atoi(opt);
205 
206  if (!strncasecmp(opt,"F",1)) {
207  Info("Print",
208  "+------------------------------------------------------+");
209  Info("Print",
210  "+ Host:%s Method:%d (%s) User:'%s'",
211  GetHost(), fMethod, GetMethodName(),
212  fUser.Data());
213  Info("Print",
214  "+ OffSet:%d Id: '%s'", fOffSet, fID.Data());
215  if (fOffSet > -1)
216  Info("Print",
217  "+ Expiration time: %s",fExpDate.AsString());
218  Info("Print",
219  "+------------------------------------------------------+");
220  } else if (!strncasecmp(opt,"S",1)) {
221  if (fOffSet > -1) {
222  if (fID.BeginsWith("AFS"))
223  Printf("Security context: Method: AFS, not reusable");
224  else
225  Printf("Security context: Method: %d (%s) expiring on %s",
226  fMethod, GetMethodName(),
227  fExpDate.AsString());
228  } else {
229  Printf("Security context: Method: %d (%s) not reusable",
230  fMethod, GetMethodName());
231  }
232  } else {
233  // special printing form for THostAuth
234  Info("PrintEstblshed","+ %d \t h:%s met:%d (%s) us:'%s'",
235  ord, GetHost(), fMethod, GetMethodName(),
236  fUser.Data());
237  Info("PrintEstblshed","+ \t offset:%d id: '%s'", fOffSet, fID.Data());
238  if (fOffSet > -1)
239  Info("PrintEstblshed","+ \t expiring: %s",fExpDate.AsString());
240  }
241 }
242 
243 ////////////////////////////////////////////////////////////////////////////////
244 /// Returns short string with relevant information about this
245 /// security context
246 
247 const char *TRootSecContext::AsString(TString &out)
248 {
249  if (fOffSet > -1) {
250  if (fID.BeginsWith("AFS"))
251  out = Form("Method: AFS, not reusable");
252  else {
253  char expdate[32];
254  out = Form("Method: %d (%s) expiring on %s",
255  fMethod, GetMethodName(), fExpDate.AsString(expdate));
256  }
257  } else {
258  if (fOffSet == -1)
259  out = Form("Method: %d (%s) not reusable", fMethod, GetMethodName());
260  else if (fOffSet == -3)
261  out = Form("Method: %d (%s) authorized by /etc/hosts.equiv or $HOME/.rhosts",
262  fMethod, GetMethodName());
263  else if (fOffSet == -4)
264  out = Form("No authentication required remotely");
265  }
266  return out.Data();
267 }