Partial rewrite of client IP verification. Not completely finished yet, and untested. Committing to move to my other computer.

0.7.0.2-release
Diva Canto 2010-08-19 18:55:30 -07:00
parent 59ce2c3227
commit 05373de9df
8 changed files with 167 additions and 47 deletions

View File

@ -83,7 +83,9 @@ namespace OpenSim.Framework
/// <summary>Finished, Sim Changed</summary> /// <summary>Finished, Sim Changed</summary>
FinishedViaNewSim = 1 << 28, FinishedViaNewSim = 1 << 28,
/// <summary>Finished, Same Sim</summary> /// <summary>Finished, Same Sim</summary>
FinishedViaSameSim = 1 << 29 FinishedViaSameSim = 1 << 29,
/// <summary>Agent coming into the grid from another grid</summary>
ViaHGLogin = 1 << 30
} }
} }

View File

@ -178,6 +178,8 @@ namespace OpenSim.Server.Handlers.Simulation
resp["reason"] = OSD.FromString(reason); resp["reason"] = OSD.FromString(reason);
resp["success"] = OSD.FromBoolean(result); resp["success"] = OSD.FromBoolean(result);
// Let's also send out the IP address of the caller back to the caller (HG 1.5)
resp["your_ip"] = OSD.FromString(GetCallerIP(request));
// TODO: add reason if not String.Empty? // TODO: add reason if not String.Empty?
responsedata["int_response_code"] = HttpStatusCode.OK; responsedata["int_response_code"] = HttpStatusCode.OK;
@ -352,6 +354,24 @@ namespace OpenSim.Server.Handlers.Simulation
{ {
m_SimulationService.ReleaseAgent(regionID, id, ""); m_SimulationService.ReleaseAgent(regionID, id, "");
} }
private string GetCallerIP(Hashtable req)
{
if (req.ContainsKey("headers"))
{
try
{
Hashtable headers = (Hashtable)req["headers"];
if (headers.ContainsKey("remote_addr") && headers["remote_addr"] != null)
return headers["remote_addr"].ToString();
}
catch (Exception e)
{
m_log.WarnFormat("[AGENT HANDLER]: exception in GetCallerIP: {0}", e.Message);
}
}
return string.Empty;
}
} }
} }

View File

@ -38,6 +38,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Imaging; using OpenMetaverse.Imaging;
using OpenMetaverse.StructuredData;
using Nwc.XmlRpc; using Nwc.XmlRpc;
using log4net; using log4net;
@ -268,5 +269,48 @@ namespace OpenSim.Services.Connectors.Hypergrid
return null; return null;
} }
public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string myipaddress, out string reason)
{
HttpWebRequest AgentCreateRequest = null;
myipaddress = String.Empty;
reason = String.Empty;
if (SendRequest(destination, aCircuit, flags, out reason, out AgentCreateRequest))
{
string response = GetResponse(AgentCreateRequest, out reason);
bool success = true;
UnpackResponse(response, out success, out reason, out myipaddress);
return success;
}
return false;
}
protected void UnpackResponse(string response, out bool result, out string reason, out string ipaddress)
{
result = true;
reason = string.Empty;
ipaddress = string.Empty;
if (!String.IsNullOrEmpty(response))
{
try
{
// we assume we got an OSDMap back
OSDMap r = Util.GetOSDMap(response);
result = r["success"].AsBoolean();
reason = r["reason"].AsString();
ipaddress = r["your_ip"].AsString();
}
catch (NullReferenceException e)
{
m_log.InfoFormat("[GATEKEEPER SERVICE CONNECTOR]: exception on UnpackResponse of DoCreateChildAgentCall {0}", e.Message);
reason = "Internal error";
result = false;
}
}
}
} }
} }

View File

@ -73,6 +73,13 @@ namespace OpenSim.Services.Connectors.Hypergrid
{ {
} }
public bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint ipaddress, out string reason)
{
// not available over remote calls
reason = "Method not available over remote calls";
return false;
}
public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason) public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason)
{ {
reason = String.Empty; reason = String.Empty;

View File

@ -77,8 +77,26 @@ namespace OpenSim.Services.Connectors.Simulation
public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason) public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason)
{ {
HttpWebRequest AgentCreateRequest = null;
reason = String.Empty; reason = String.Empty;
if (SendRequest(destination, aCircuit, flags, out reason, out AgentCreateRequest))
{
string response = GetResponse(AgentCreateRequest, out reason);
bool success = true;
UnpackResponse(response, out success, out reason);
return success;
}
return false;
}
protected bool SendRequest(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason, out HttpWebRequest AgentCreateRequest)
{
reason = String.Empty;
AgentCreateRequest = null;
if (destination == null) if (destination == null)
{ {
reason = "Destination is null"; reason = "Destination is null";
@ -101,7 +119,7 @@ namespace OpenSim.Services.Connectors.Simulation
//Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri); //Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri);
HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri); AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
AgentCreateRequest.Method = "POST"; AgentCreateRequest.Method = "POST";
AgentCreateRequest.ContentType = "application/json"; AgentCreateRequest.ContentType = "application/json";
AgentCreateRequest.Timeout = 10000; AgentCreateRequest.Timeout = 10000;
@ -150,11 +168,18 @@ namespace OpenSim.Services.Connectors.Simulation
os.Close(); os.Close();
} }
return true;
}
protected string GetResponse(HttpWebRequest AgentCreateRequest, out string reason)
{
// Let's wait for the response // Let's wait for the response
//m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall"); //m_log.Info("[REMOTE SIMULATION CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
reason = string.Empty;
WebResponse webResponse = null; WebResponse webResponse = null;
StreamReader sr = null; StreamReader sr = null;
string response = string.Empty;
try try
{ {
webResponse = AgentCreateRequest.GetResponse(); webResponse = AgentCreateRequest.GetResponse();
@ -166,37 +191,15 @@ namespace OpenSim.Services.Connectors.Simulation
{ {
sr = new StreamReader(webResponse.GetResponseStream()); sr = new StreamReader(webResponse.GetResponseStream());
string response = sr.ReadToEnd().Trim(); response = sr.ReadToEnd().Trim();
m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response); m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response);
if (!String.IsNullOrEmpty(response))
{
try
{
// we assume we got an OSDMap back
OSDMap r = Util.GetOSDMap(response);
bool success = r["success"].AsBoolean();
reason = r["reason"].AsString();
return success;
}
catch (NullReferenceException e)
{
m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
// check for old style response
if (response.ToLower().StartsWith("true"))
return true;
return false;
}
}
} }
} }
catch (WebException ex) catch (WebException ex)
{ {
m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message); m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
reason = "Destination did not reply"; reason = "Destination did not reply";
return false; return string.Empty;
} }
finally finally
{ {
@ -204,7 +207,33 @@ namespace OpenSim.Services.Connectors.Simulation
sr.Close(); sr.Close();
} }
return true; return response;
}
protected void UnpackResponse(string response, out bool result, out string reason)
{
result = true;
reason = string.Empty;
if (!String.IsNullOrEmpty(response))
{
try
{
// we assume we got an OSDMap back
OSDMap r = Util.GetOSDMap(response);
result = r["success"].AsBoolean();
reason = r["reason"].AsString();
}
catch (NullReferenceException e)
{
m_log.InfoFormat("[REMOTE SIMULATION CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
// check for old style response
if (response.ToLower().StartsWith("true"))
result = true;
result = false;
}
}
} }
protected virtual OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion destination, uint flags) protected virtual OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion destination, uint flags)

View File

@ -131,10 +131,11 @@ namespace OpenSim.Services.HypergridService
return home; return home;
} }
public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason) public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason)
{ {
m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} to grid {2}", m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}",
agentCircuit.firstname, agentCircuit.lastname, gatekeeper.ExternalHostName +":"+ gatekeeper.HttpPort); agentCircuit.firstname, agentCircuit.lastname, ((clientIP == null) ? "(stored IP)" : clientIP.ToString()),
gatekeeper.ExternalHostName +":"+ gatekeeper.HttpPort);
// Take the IP address + port of the gatekeeper (reg) plus the info of finalDestination // Take the IP address + port of the gatekeeper (reg) plus the info of finalDestination
GridRegion region = new GridRegion(gatekeeper); GridRegion region = new GridRegion(gatekeeper);
@ -149,11 +150,12 @@ namespace OpenSim.Services.HypergridService
//bool success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason); //bool success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason);
bool success = false; bool success = false;
string myExternalIP = string.Empty;
string gridName = "http://" + gatekeeper.ExternalHostName + ":" + gatekeeper.HttpPort; string gridName = "http://" + gatekeeper.ExternalHostName + ":" + gatekeeper.HttpPort;
if (m_GridName == gridName) if (m_GridName == gridName)
success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason);
else else
success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out reason); success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason);
if (!success) if (!success)
{ {
@ -167,15 +169,25 @@ namespace OpenSim.Services.HypergridService
return false; return false;
} }
// else set the IP addresses associated with this client
if (clientIP != null)
m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.ToString();
m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP;
return true; return true;
} }
public void SetClientToken(UUID sessionID, string token) public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason)
{
reason = string.Empty;
return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, null, out reason);
}
private void SetClientIP(UUID sessionID, string ip)
{ {
if (m_TravelingAgents.ContainsKey(sessionID)) if (m_TravelingAgents.ContainsKey(sessionID))
{ {
m_log.DebugFormat("[USER AGENT SERVICE]: Setting token {0} for session {1}", token, sessionID); m_log.DebugFormat("[USER AGENT SERVICE]: Setting IP {0} for session {1}", ip, sessionID);
m_TravelingAgents[sessionID].ClientToken = token; m_TravelingAgents[sessionID].ClientIPAddress = ip;
} }
} }
@ -196,7 +208,7 @@ namespace OpenSim.Services.HypergridService
travel.GridExternalName = "http://" + region.ExternalHostName + ":" + region.HttpPort; travel.GridExternalName = "http://" + region.ExternalHostName + ":" + region.HttpPort;
travel.ServiceToken = agentCircuit.ServiceSessionID; travel.ServiceToken = agentCircuit.ServiceSessionID;
if (old != null) if (old != null)
travel.ClientToken = old.ClientToken; travel.ClientIPAddress = old.ClientIPAddress;
return old; return old;
} }
@ -233,15 +245,22 @@ namespace OpenSim.Services.HypergridService
return travel.GridExternalName == thisGridExternalName; return travel.GridExternalName == thisGridExternalName;
} }
public bool VerifyClient(UUID sessionID, string token) public bool VerifyClient(UUID sessionID, string reportedIP)
{ {
if (m_BypassClientVerification) if (m_BypassClientVerification)
return true; return true;
m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with token {1}", sessionID, token); m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.",
sessionID, reportedIP);
if (m_TravelingAgents.ContainsKey(sessionID)) if (m_TravelingAgents.ContainsKey(sessionID))
return m_TravelingAgents[sessionID].ClientToken == token; {
m_log.DebugFormat("[USER AGENT SERVICE]: Comparing with login IP {0} and MyIP {1}",
m_TravelingAgents[sessionID].ClientIPAddress, m_TravelingAgents[sessionID].MyIpAddress);
return m_TravelingAgents[sessionID].ClientIPAddress == reportedIP ||
m_TravelingAgents[sessionID].MyIpAddress == reportedIP; // NATed
}
return false; return false;
} }
@ -266,7 +285,8 @@ namespace OpenSim.Services.HypergridService
public UUID UserID; public UUID UserID;
public string GridExternalName = string.Empty; public string GridExternalName = string.Empty;
public string ServiceToken = string.Empty; public string ServiceToken = string.Empty;
public string ClientToken = string.Empty; public string ClientIPAddress = string.Empty; // as seen from this user agent service
public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper
} }
} }

View File

@ -48,13 +48,15 @@ namespace OpenSim.Services.Interfaces
/// </summary> /// </summary>
public interface IUserAgentService public interface IUserAgentService
{ {
// called by login service only
bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason);
// called by simulators
bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason); bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason);
void SetClientToken(UUID sessionID, string token);
void LogoutAgent(UUID userID, UUID sessionID); void LogoutAgent(UUID userID, UUID sessionID);
GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
bool AgentIsComingHome(UUID sessionID, string thisGridExternalName); bool AgentIsComingHome(UUID sessionID, string thisGridExternalName);
bool VerifyAgent(UUID sessionID, string token); bool VerifyAgent(UUID sessionID, string token);
bool VerifyClient(UUID sessionID, string token); bool VerifyClient(UUID sessionID, string reportedIP);
} }
} }

View File

@ -754,12 +754,8 @@ namespace OpenSim.Services.LLLoginService
private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, IPEndPoint clientIP, out string reason) private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, IPEndPoint clientIP, out string reason)
{ {
m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName); m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName);
if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, out reason)) if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, clientIP, out reason))
{
IPAddress addr = NetworkUtil.GetExternalIPOf(clientIP.Address);
m_UserAgentService.SetClientToken(aCircuit.SessionID, addr.ToString() /* clientIP.Address.ToString() */);
return true; return true;
}
return false; return false;
} }