#include "TAuthenticate.h"
#include "TEnv.h"
#include "TError.h"
#include "THostAuth.h"
#include "TRootAuth.h"
#include "TRootSecContext.h"
#include "TSocket.h"
#include "TSystem.h"
#include "TUrl.h"
TSecContext *TRootAuth::Authenticate(TSocket *s, const char *host,
const char *user, Option_t *opts)
{
TSecContext *ctx = 0;
Int_t rc = 0;
Int_t rproto = s->GetRemoteProtocol() % 1000;
if (s->GetServType() == (Int_t)TSocket::kROOTD) {
if (rproto > 6 && rproto < 10) {
s->Send(Form("%d", TSocket::GetClientProtocol()), kROOTD_PROTOCOL2);
Int_t kind = 0;
if (s->Recv(rproto, kind) < 0) {
Error("Authenticate", "receiving remote protocol");
return ctx;
}
s->SetRemoteProtocol(rproto);
}
}
Bool_t isPROOF = (s->GetServType() == (Int_t)TSocket::kPROOFD);
Bool_t isMASTER = kFALSE;
if (isPROOF) {
isMASTER = kTRUE;
TString opt(TUrl(s->GetUrl()).GetOptions());
if (!strncasecmp(opt.Data()+1, "C", 1)) {
isMASTER = kFALSE;
}
}
Bool_t isPROOFserv = (opts[0] == 'P') ? kTRUE : kFALSE;
TString proto = TUrl(s->GetUrl()).GetProtocol();
if (proto == "") {
proto = "root";
} else if (proto.Contains("sockd") || proto.Contains("rootd") ||
proto.Contains("proofd")) {
proto.ReplaceAll("d",1,"",0);
}
proto += Form(":%d",rproto);
TAuthenticate *auth =
new TAuthenticate(s, host, proto, user);
if (isMASTER && !isPROOFserv) {
if (gEnv->GetValue("Proofd.SendSRPPwd",0)) {
Int_t kSRP = TAuthenticate::kSRP;
TString detsSRP(auth->GetHostAuth()->GetDetails(kSRP));
Int_t pos = detsSRP.Index("ru:0");
if (pos > -1) {
detsSRP.ReplaceAll("ru:0",4,"ru:1",4);
auth->GetHostAuth()->SetDetails(kSRP,detsSRP);
} else {
TSubString ss = detsSRP.SubString("ru:no",TString::kIgnoreCase);
if (!ss.IsNull()) {
detsSRP.ReplaceAll(ss.Data(),5,"ru:1",4);
auth->GetHostAuth()->SetDetails(kSRP,detsSRP);
}
}
}
}
if (isPROOFserv) {
if (!(gEnv->GetValue("ProofServ.UseSSH",0)))
auth->GetHostAuth()->RemoveMethod(TAuthenticate::kSSH);
}
if (!auth->Authenticate()) {
if (auth->HasTimedOut() > 0)
Error("Authenticate",
"timeout expired for %s@%s", auth->GetUser(), host);
else
Error("Authenticate",
"authentication failed for %s@%s", auth->GetUser(), host);
if (isPROOF)
s->Send(Form("%d %s", gSystem->GetPid(), host), kROOTD_CLEANUP);
} else {
rc = 1;
ctx = auth->GetSecContext();
s->SetSecContext(ctx);
}
delete auth;
if (rc && isPROOF && rproto > 11) {
Bool_t client = !isPROOFserv;
if (TAuthenticate::ProofAuthSetup(s, client) !=0 ) {
Error("Authenticate", "PROOF: failed to finalize setup");
}
}
return ctx;
}
Int_t TRootAuth::ClientVersion()
{
return TSocket::GetClientProtocol();
}
void TRootAuth::ErrorMsg(const char *where, Int_t ecode)
{
TAuthenticate::AuthError(where, ecode);
}