#include "RConfigure.h"
#include <stdlib.h>
#include "TSecContext.h"
#include "TSocket.h"
#include "TUrl.h"
#include "TROOT.h"
#include "TError.h"
#include "TVirtualMutex.h"
ClassImp(TSecContext)
ClassImp(TSecContextCleanup)
TSecContext::TSecContext(const char *user, const char *host, Int_t meth,
Int_t offset, const char *id,
const char *token, TDatime expdate, void *ctx)
: TObject()
{
R__ASSERT(gROOT);
fContext = ctx;
fCleanup = new TList;
fExpDate = expdate;
if (offset > -1) {
if (fExpDate < TDatime()) {
fExpDate.Set(TDatime().GetDate() + 1, TDatime().GetTime());
}
}
fHost = host;
fID = id;
fMethod = meth;
fMethodName = "";
fOffSet = offset;
fToken = token;
fUser = user;
if (fOffSet > -1) {
R__LOCKGUARD2(gROOTMutex);
gROOT->GetListOfSecContexts()->Add(this);
}
}
TSecContext::TSecContext(const char *url, Int_t meth, Int_t offset,
const char *token, const char *id,
TDatime expdate, void *ctx)
: TObject()
{
R__ASSERT(gROOT);
fContext = ctx;
fCleanup = new TList;
fExpDate = expdate;
if (offset > -1) {
if (fExpDate < TDatime()) {
fExpDate.Set(TDatime().GetDate() + 1, TDatime().GetTime());
}
}
fHost = TUrl(url).GetHost();
fID = id;
fMethod = meth;
fMethodName = "";
fOffSet = offset;
fToken = token;
fUser = TUrl(url).GetUser();
if (fOffSet > -1) {
R__LOCKGUARD2(gROOTMutex);
gROOT->GetListOfSecContexts()->Add(this);
}
}
TSecContext::TSecContext(const TSecContext& sc) :
TObject(sc),
fContext(sc.fContext),
fCleanup(sc.fCleanup),
fExpDate(sc.fExpDate),
fHost(sc.fHost),
fID(sc.fID),
fMethod(sc.fMethod),
fMethodName(sc.fMethodName),
fOffSet(sc.fOffSet),
fToken(sc.fToken),
fUser(sc.fUser)
{
}
TSecContext& TSecContext::operator=(const TSecContext& sc)
{
if(this!=&sc) {
TObject::operator=(sc);
fContext=sc.fContext;
fCleanup=sc.fCleanup;
fExpDate=sc.fExpDate;
fHost=sc.fHost;
fID=sc.fID;
fMethod=sc.fMethod;
fMethodName=sc.fMethodName;
fOffSet=sc.fOffSet;
fToken=sc.fToken;
fUser=sc.fUser;
}
return *this;
}
TSecContext::~TSecContext()
{
Cleanup();
}
void TSecContext::Cleanup()
{
if (IsActive()) {
CleanupSecContext(kTRUE);
DeActivate("R");
TIter nxtl(gROOT->GetListOfSecContexts());
TSecContext *nscl;
while ((nscl = (TSecContext *)nxtl())) {
if (nscl != this && !strcmp(nscl->GetHost(), fHost.Data())) {
nscl->DeActivate("");
}
}
}
if (fCleanup) {
fCleanup->Delete();
delete fCleanup;
fCleanup = 0;
}
}
void TSecContext::DeActivate(Option_t *Opt)
{
Bool_t clean = (strstr(Opt,"C") || strstr(Opt,"c"));
if (clean && fOffSet > -1)
CleanupSecContext(kFALSE);
Bool_t remove = (strstr(Opt,"R") || strstr(Opt,"r"));
if (remove && fOffSet > -1){
R__LOCKGUARD2(gROOTMutex);
gROOT->GetListOfSecContexts()->Remove(this);
}
fOffSet = -1;
fExpDate = kROOTTZERO;
}
void TSecContext::AddForCleanup(Int_t port, Int_t proto, Int_t type)
{
TSecContextCleanup *tscc = new TSecContextCleanup(port, proto, type);
fCleanup->Add(tscc);
}
Bool_t TSecContext::IsA(const char *methname)
{
return Bool_t(!strcmp(methname, GetMethodName()));
}
Bool_t TSecContext::IsActive() const
{
if (fOffSet > -1 && fExpDate > TDatime())
return kTRUE;
return kFALSE;
}
void TSecContext::Print(Option_t *opt) const
{
char aOrd[10] = {0};
char aSpc[10] = {0};
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 (ord > -1) {
snprintf(aOrd,10,"%d)",ord);
Int_t len=strlen(aOrd);
while (len--)
strlcat(aSpc," ",10);
}
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) {
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","+ %s h:%s met:%d (%s) us:'%s'",
aOrd, GetHost(), fMethod, GetMethodName(),
fUser.Data());
Info("PrintEstblshed","+ %s offset:%d id:%s", aSpc, fOffSet, fID.Data());
if (fOffSet > -1)
Info("PrintEstblshed","+ %s expiring: %s",aSpc,fExpDate.AsString());
}
}
const char *TSecContext::AsString(TString &out)
{
if (fOffSet > -1) {
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();
}
Bool_t TSecContext::CleanupSecContext(Bool_t)
{
AbstractMethod("CleanupSecContext");
return kFALSE;
}