mirror of
https://github.com/opensim/opensim.git
synced 2026-08-06 09:16:28 +08:00
* This update makes configuring SSL a little easier on Windows XP. It also makes it possible to run a HTTPS server on the region. It also has a junk Certification authority for test purposes.
* There are still a lot of things that are hard coded to use http. They need to be fixed. * Also includes directions * A standard junk PEM file to append to app_settings/CA.pem in the client so SSL will work
This commit is contained in:
@@ -49,6 +49,9 @@ namespace OpenSim.Framework
|
||||
public string UserRecvKey = String.Empty;
|
||||
public string UserSendKey = String.Empty;
|
||||
public string UserURL = String.Empty;
|
||||
public bool HttpUsesSSL = false;
|
||||
public string HttpSSLCN = "";
|
||||
public uint httpSSLPort = 9001;
|
||||
|
||||
|
||||
public NetworkServersInfo()
|
||||
@@ -78,6 +81,10 @@ namespace OpenSim.Framework
|
||||
|
||||
HttpListenerPort =
|
||||
(uint) config.Configs["Network"].GetInt("http_listener_port", (int) DefaultHttpListenerPort);
|
||||
httpSSLPort =
|
||||
(uint)config.Configs["Network"].GetInt("http_listener_sslport", ((int)DefaultHttpListenerPort+1));
|
||||
HttpUsesSSL = config.Configs["Network"].GetBoolean("http_listener_ssl", false);
|
||||
HttpSSLCN = config.Configs["Network"].GetString("http_listener_cn", "");
|
||||
RemotingListenerPort =
|
||||
(uint) config.Configs["Network"].GetInt("remoting_listener_port", (int) RemotingListenerPort);
|
||||
GridURL =
|
||||
|
||||
@@ -26,12 +26,14 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
@@ -39,6 +41,7 @@ using OpenMetaverse.StructuredData;
|
||||
using log4net;
|
||||
using Nwc.XmlRpc;
|
||||
|
||||
|
||||
namespace OpenSim.Framework.Servers
|
||||
{
|
||||
public class BaseHttpServer
|
||||
@@ -55,9 +58,14 @@ namespace OpenSim.Framework.Servers
|
||||
protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>();
|
||||
|
||||
protected uint m_port;
|
||||
protected uint m_sslport;
|
||||
protected bool m_ssl = false;
|
||||
protected bool m_firstcaps = true;
|
||||
|
||||
public uint SSLPort
|
||||
{
|
||||
get { return m_sslport; }
|
||||
}
|
||||
public uint Port
|
||||
{
|
||||
get { return m_port; }
|
||||
@@ -72,8 +80,124 @@ namespace OpenSim.Framework.Servers
|
||||
{
|
||||
m_ssl = ssl;
|
||||
m_port = port;
|
||||
|
||||
}
|
||||
|
||||
public BaseHttpServer(uint port, bool ssl, uint sslport, string CN)
|
||||
{
|
||||
m_ssl = ssl;
|
||||
m_port = port;
|
||||
if (m_ssl)
|
||||
{
|
||||
bool result = SetupSsl((int)sslport, CN);
|
||||
m_sslport = sslport;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public bool SetupSsl(int port, string CN)
|
||||
{
|
||||
string searchCN = Environment.MachineName.ToUpper();
|
||||
|
||||
if (CN.Length > 0)
|
||||
searchCN = CN.ToUpper();
|
||||
|
||||
Type t = Type.GetType("Mono.Runtime");
|
||||
if (t != null)
|
||||
{
|
||||
// TODO Mono User Friendly HTTPS setup
|
||||
// if this doesn't exist, then mono people can still manually use httpcfg
|
||||
}
|
||||
else
|
||||
{
|
||||
// Windows.
|
||||
// Search through the store for a certificate with a Common name specified in OpenSim.ini.
|
||||
// We need to find it's hash so we can pass it to httpcfg
|
||||
X509Store store = new X509Store(StoreLocation.LocalMachine);
|
||||
//Use the first cert to configure Ssl
|
||||
store.Open(OpenFlags.ReadOnly);
|
||||
//Assumption is we have certs. If not then this call will fail :(
|
||||
try
|
||||
{
|
||||
bool found = false;
|
||||
//X509Certificate2.CreateFromCertFile("testCert.cer");
|
||||
|
||||
foreach (X509Certificate2 cert in store.Certificates)
|
||||
{
|
||||
String certHash = cert.GetCertHashString();
|
||||
//Only install certs issued for the machine and has the name as the machine name
|
||||
if (cert.Subject.ToUpper().IndexOf(searchCN) >= 0)
|
||||
{
|
||||
string httpcfgparams = String.Format("set ssl -i 0.0.0.0:{1} -c \"MY\" -h {0}", certHash, port);
|
||||
try
|
||||
{
|
||||
found = true;
|
||||
|
||||
ExecuteHttpcfgCommand(httpcfgparams);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[HTTPS]: Automatic HTTPS setup failed. Do you have httpcfg.exe in your path? If not, you can download it in the windowsXP Service Pack 2 Support Tools, here: http://www.microsoft.com/downloads/details.aspx?FamilyID=49ae8576-9bb9-4126-9761-ba8011fabf38&displaylang=en. When you get it installed type, httpcfg {0}", httpcfgparams);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
m_log.WarnFormat("[HTTPS]: We didn't find a certificate that matched the common name {0}. Automatic HTTPS setup failed, you may have certificate errors. To fix this, make sure you generate a certificate request(CSR) using OpenSSL or the IIS snap-in with the common name you specified in opensim.ini. Then get it signed by a certification authority or sign it yourself with OpenSSL and the junkCA. Finally, be sure to import the cert to the 'MY' store(StoreLocation.LocalMachine)", searchCN);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[HTTPS]: We didn't any certificates in your LocalMachine certificate store. Automatic HTTPS setup failed, you may have certificate errors. To fix this, make sure you generate a certificate request(CSR) using OpenSSL or the IIS snap-inwith the common name you specified in opensim.ini. Then get it signed by a certification authority or sign it yourself with OpenSSL and the junkCA. Finally, be sure to import the cert to the 'MY' store(StoreLocation.LocalMachine). The configured common name is {0}", searchCN);
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (store != null)
|
||||
{
|
||||
store.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ExecuteHttpcfgCommand(string p)
|
||||
{
|
||||
|
||||
string file = "httpcfg";
|
||||
|
||||
ProcessStartInfo info = new ProcessStartInfo(file, p);
|
||||
// Redirect output so we can read it.
|
||||
info.RedirectStandardOutput = true;
|
||||
// To redirect, we must not use shell execute.
|
||||
info.UseShellExecute = false;
|
||||
|
||||
// Create and execute the process.
|
||||
Process httpcfgprocess = Process.Start(info);
|
||||
httpcfgprocess.Start();
|
||||
string result = httpcfgprocess.StandardOutput.ReadToEnd();
|
||||
if (result.Contains("HttpSetServiceConfiguration completed with"))
|
||||
{
|
||||
//success
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//fail
|
||||
m_log.WarnFormat("[HTTPS]:Error binding certificate with the requested port. Message:{0}", result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add a stream handler to the http server. If the handler already exists, then nothing happens.
|
||||
/// </summary>
|
||||
@@ -907,7 +1031,8 @@ namespace OpenSim.Framework.Servers
|
||||
}
|
||||
else
|
||||
{
|
||||
m_httpListener.Prefixes.Add("https://+:" + m_port + "/");
|
||||
m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/");
|
||||
m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
|
||||
}
|
||||
m_httpListener.Start();
|
||||
|
||||
@@ -921,7 +1046,7 @@ namespace OpenSim.Framework.Servers
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Warn("[HTTPD]: Error - " + e.Message);
|
||||
m_log.Warn("Tip: Do you have permission to listen on port " + m_port + "?");
|
||||
m_log.Warn("Tip: Do you have permission to listen on port " + m_port + "," + m_sslport + "?");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,12 @@ namespace OpenSim.Region.ClientStack
|
||||
|
||||
Initialize();
|
||||
|
||||
m_httpServer = new BaseHttpServer(m_httpServerPort);
|
||||
m_httpServer = new BaseHttpServer(m_httpServerPort,m_networkServersInfo.HttpUsesSSL,m_networkServersInfo.httpSSLPort, m_networkServersInfo.HttpSSLCN);
|
||||
if (m_networkServersInfo.HttpUsesSSL && (m_networkServersInfo.HttpListenerPort == m_networkServersInfo.httpSSLPort))
|
||||
{
|
||||
m_log.Error("[HTTP]: HTTP Server config failed. HTTP Server and HTTPS server must be on different ports");
|
||||
}
|
||||
|
||||
|
||||
m_log.Info("[REGION]: Starting HTTP server");
|
||||
|
||||
|
||||
@@ -86,6 +86,9 @@ namespace OpenSim.Region.Environment.Modules.InterGrid
|
||||
private Dictionary<UUID, OGPState> m_OGPState = new Dictionary<UUID, OGPState>();
|
||||
private string LastNameSuffix = "_EXTERNAL";
|
||||
private string FirstNamePrefix = "";
|
||||
private string httpsCN = "";
|
||||
private bool httpSSL = false;
|
||||
private uint httpsslport = 0;
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
@@ -93,6 +96,7 @@ namespace OpenSim.Region.Environment.Modules.InterGrid
|
||||
{
|
||||
bool enabled = false;
|
||||
IConfig cfg = null;
|
||||
IConfig httpcfg = null;
|
||||
try
|
||||
{
|
||||
cfg = config.Configs["OpenGridProtocol"];
|
||||
@@ -100,6 +104,16 @@ namespace OpenSim.Region.Environment.Modules.InterGrid
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
httpcfg = config.Configs["Network"];
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (cfg != null)
|
||||
{
|
||||
enabled = cfg.GetBoolean("ogp_enabled", false);
|
||||
@@ -139,6 +153,20 @@ namespace OpenSim.Region.Environment.Modules.InterGrid
|
||||
}
|
||||
}
|
||||
}
|
||||
lock (m_scene)
|
||||
{
|
||||
if (m_scene.Count == 1)
|
||||
{
|
||||
if (httpcfg != null)
|
||||
{
|
||||
httpSSL = httpcfg.GetBoolean("http_listener_ssl", false);
|
||||
httpsCN = httpcfg.GetString("http_listener_cn", scene.RegionInfo.ExternalHostName);
|
||||
if (httpsCN.Length == 0)
|
||||
httpsCN = scene.RegionInfo.ExternalHostName;
|
||||
httpsslport = (uint)httpcfg.GetInt("http_listener_sslport",((int)scene.RegionInfo.HttpPort + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Of interest to this module potentially
|
||||
//scene.EventManager.OnNewClient += OnNewClient;
|
||||
//scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage;
|
||||
@@ -371,14 +399,35 @@ namespace OpenSim.Region.Environment.Modules.InterGrid
|
||||
// Get a reference to the user's cap so we can pull out the Caps Object Path
|
||||
OpenSim.Framework.Communications.Capabilities.Caps userCap = homeScene.GetCapsHandlerForUser(agentData.AgentID);
|
||||
|
||||
string rezHttpProtocol = "http://";
|
||||
string regionCapsHttpProtocol = "http://";
|
||||
string httpaddr = reg.ExternalHostName;
|
||||
string urlport = reg.HttpPort.ToString();
|
||||
|
||||
|
||||
if (httpSSL)
|
||||
{
|
||||
rezHttpProtocol = "https://";
|
||||
|
||||
urlport = httpsslport.ToString();
|
||||
|
||||
if (httpsCN.Length > 0)
|
||||
httpaddr = httpsCN;
|
||||
}
|
||||
|
||||
|
||||
// Be warned that the two following lines assume http not
|
||||
// https since region caps are not implemented in https currently
|
||||
|
||||
// DEPRECIATED
|
||||
responseMap["seed_capability"] = LLSD.FromString("http://" + reg.ExternalHostName + ":" + reg.HttpPort + "/CAPS/" + userCap.CapsObjectPath + "0000/");
|
||||
responseMap["seed_capability"] = LLSD.FromString(regionCapsHttpProtocol + httpaddr + ":" + reg.HttpPort + "/CAPS/" + userCap.CapsObjectPath + "0000/");
|
||||
|
||||
// REPLACEMENT
|
||||
responseMap["region_seed_capability"] = LLSD.FromString("http://" + reg.ExternalHostName + ":" + reg.HttpPort + "/CAPS/" + userCap.CapsObjectPath + "0000/");
|
||||
responseMap["region_seed_capability"] = LLSD.FromString(regionCapsHttpProtocol + httpaddr + ":" + reg.HttpPort + "/CAPS/" + userCap.CapsObjectPath + "0000/");
|
||||
|
||||
|
||||
responseMap["rez_avatar/rez"] = LLSD.FromString("http://" + reg.ExternalHostName + ":" + reg.HttpPort + rezAvatarPath);
|
||||
responseMap["rez_avatar/derez"] = LLSD.FromString("http://" + reg.ExternalHostName + ":" + reg.HttpPort + derezAvatarPath);
|
||||
responseMap["rez_avatar/rez"] = LLSD.FromString(rezHttpProtocol + httpaddr + ":" + urlport + rezAvatarPath);
|
||||
responseMap["rez_avatar/derez"] = LLSD.FromString(rezHttpProtocol + httpaddr + ":" + urlport + derezAvatarPath);
|
||||
|
||||
// Add the user to the list of CAPS that are outstanding.
|
||||
// well allow the caps hosts in this dictionary
|
||||
|
||||
Reference in New Issue
Block a user