#include "RConfigure.h"
#include <stdlib.h>
#include "TError.h"
#include "TRootSecContext.h"
#include "TROOT.h"
#include "TSocket.h"
#include "TUrl.h"
#include "TVirtualMutex.h"
ClassImp(TRootSecContext)
TRootSecContext::TRootSecContext(const char *user, const char *host, Int_t meth,
Int_t offset, const char *id,
const char *token, TDatime expdate,
void *ctx, Int_t key)
: TSecContext(user, host, meth, offset, id, token, expdate, ctx)
{
R__ASSERT(gROOT);
fRSAKey = key;
fMethodName = TAuthenticate::GetAuthMethod(fMethod);
}
TRootSecContext::TRootSecContext(const char *url, Int_t meth, Int_t offset,
const char *id, const char *token,
TDatime expdate, void *ctx, Int_t key)
: TSecContext(url, meth, offset, id, token, expdate, ctx)
{
R__ASSERT(gROOT);
fRSAKey = key;
fMethodName = TAuthenticate::GetAuthMethod(fMethod);
}
TRootSecContext::~TRootSecContext()
{
TSecContext::Cleanup();
}
void TRootSecContext::DeActivate(Option_t *Opt)
{
Bool_t clean = (strstr(Opt,"C") || strstr(Opt,"c"));
if (clean && fOffSet > -1)
CleanupSecContext(kFALSE);
if (fMethod == TAuthenticate::kClear ||
fMethod == TAuthenticate::kSRP)
if (fContext) {
delete (TPwdCtx *)fContext;
fContext = 0;
}
if (fMethod == TAuthenticate::kGlobus && fContext) {
GlobusAuth_t globusAuthHook = TAuthenticate::GetGlobusAuthHook();
if (globusAuthHook != 0) {
TString det("context");
TString us("-1");
(*globusAuthHook)((TAuthenticate *)fContext,us,det);
fContext = 0;
}
}
Bool_t remove = (strstr(Opt,"R") || strstr(Opt,"r"));
if (remove && fOffSet > -1){
R__LOCKGUARD2(gROOTMutex);
gROOT->GetListOfSecContexts()->Remove(this);
TAuthenticate::RemoveSecContext(this);
}
fOffSet = -1;
fExpDate = kROOTTZERO;
}
Bool_t TRootSecContext::CleanupSecContext(Bool_t all)
{
Bool_t cleaned = kFALSE;
if (!IsActive())
return kTRUE;
TIter last(fCleanup,kIterBackward);
TSecContextCleanup *nscc = 0;
while ((nscc = (TSecContextCleanup *)last()) && !cleaned) {
Int_t srvtyp = nscc->GetType();
Int_t rproto = nscc->GetProtocol();
Int_t level = 2;
if ((srvtyp == TSocket::kROOTD && rproto < 10) ||
(srvtyp == TSocket::kPROOFD && rproto < 9))
level = 1;
if ((srvtyp == TSocket::kROOTD && rproto < 8) ||
(srvtyp == TSocket::kPROOFD && rproto < 7))
level = 0;
if (level) {
Int_t port = nscc->GetPort();
TSocket *news = new TSocket(fHost.Data(),port,-1);
if (news && news->IsValid()) {
if (srvtyp == TSocket::kPROOFD) {
news->SetOption(kNoDelay, 1);
news->Send("cleaning request");
} else
news->SetOption(kNoDelay, 0);
if (srvtyp == TSocket::kROOTD && level == 1)
news->Send((Int_t)0, (Int_t)0);
if (all || level == 1) {
news->Send(Form("%d",TAuthenticate::fgProcessID), kROOTD_CLEANUP);
cleaned = kTRUE;
} else {
news->Send(Form("%d %d %d %s", TAuthenticate::fgProcessID, fMethod,
fOffSet, fUser.Data()), kROOTD_CLEANUP);
if (TAuthenticate::SecureSend(news, 1, fRSAKey,
(char *)(fToken.Data())) == -1) {
Info("CleanupSecContext", "problems secure-sending token");
} else {
cleaned = kTRUE;
}
}
if (cleaned && gDebug > 2) {
char srvname[3][10] = {"sockd", "rootd", "proofd"};
Info("CleanupSecContext",
"remote %s notified for cleanup (%s,%d)",
srvname[srvtyp],fHost.Data(),port);
}
}
SafeDelete(news);
}
}
if (!cleaned)
if (gDebug > 2)
Info("CleanupSecContext",
"unable to open valid socket for cleanup for %s", fHost.Data());
return cleaned;
}
void TRootSecContext::Print(Option_t *opt) const
{
Int_t ord = -1, i = 0;
for (; i < (Int_t)strlen(opt); i++) {
if (opt[i] < 48 || opt[i] > 57) {
ord = -2;
break;
}
}
if (ord == -1)
ord = atoi(opt);
if (!strncasecmp(opt,"F",1)) {
Info("Print",
"+------------------------------------------------------+");
Info("Print",
"+ Host:%s Method:%d (%s) User:'%s'",
GetHost(), fMethod, GetMethodName(),
fUser.Data());
Info("Print",
"+ OffSet:%d Id: '%s'", fOffSet, fID.Data());
if (fOffSet > -1)
Info("Print",
"+ Expiration time: %s",fExpDate.AsString());
Info("Print",
"+------------------------------------------------------+");
} else if (!strncasecmp(opt,"S",1)) {
if (fOffSet > -1) {
if (fID.BeginsWith("AFS"))
Printf("Security context: Method: AFS, not reusable");
else
Printf("Security context: Method: %d (%s) expiring on %s",
fMethod, GetMethodName(),
fExpDate.AsString());
} else {
Printf("Security context: Method: %d (%s) not reusable",
fMethod, GetMethodName());
}
} else {
Info("PrintEstblshed","+ %d \t h:%s met:%d (%s) us:'%s'",
ord, GetHost(), fMethod, GetMethodName(),
fUser.Data());
Info("PrintEstblshed","+ \t offset:%d id: '%s'", fOffSet, fID.Data());
if (fOffSet > -1)
Info("PrintEstblshed","+ \t expiring: %s",fExpDate.AsString());
}
}
const char *TRootSecContext::AsString(TString &out)
{
if (fOffSet > -1) {
if (fID.BeginsWith("AFS"))
out = Form("Method: AFS, not reusable");
else {
char expdate[32];
out = Form("Method: %d (%s) expiring on %s",
fMethod, GetMethodName(), fExpDate.AsString(expdate));
}
} else {
if (fOffSet == -1)
out = Form("Method: %d (%s) not reusable", fMethod, GetMethodName());
else if (fOffSet == -3)
out = Form("Method: %d (%s) authorized by /etc/hosts.equiv or $HOME/.rhosts",
fMethod, GetMethodName());
else if (fOffSet == -4)
out = Form("No authentication required remotely");
}
return out.Data();
}