From dbbbec48dfbc51f30953d8a46f4fc8f192bd277c Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sun, 14 Sep 2008 18:39:17 +0000 Subject: * 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 --- OpenSim/Framework/NetworkServersInfo.cs | 7 ++ OpenSim/Framework/Servers/BaseHttpServer.cs | 129 +++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 2 deletions(-) (limited to 'OpenSim/Framework') diff --git a/OpenSim/Framework/NetworkServersInfo.cs b/OpenSim/Framework/NetworkServersInfo.cs index 43ec11e..9f3014d 100644 --- a/OpenSim/Framework/NetworkServersInfo.cs +++ b/OpenSim/Framework/NetworkServersInfo.cs @@ -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 = diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs index 181eb92..6cf6744 100644 --- a/OpenSim/Framework/Servers/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs @@ -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 m_agentHandlers = new Dictionary(); 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); + } + + } + + /// /// Add a stream handler to the http server. If the handler already exists, then nothing happens. /// @@ -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 + "?"); } } -- cgit v1.1