aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs146
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs2
-rw-r--r--bin/OpenSimDefaults.ini8
3 files changed, 141 insertions, 15 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 29a8d3f..af292c6 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -43,10 +43,11 @@ using log4net;
43using Nwc.XmlRpc; 43using Nwc.XmlRpc;
44using OpenMetaverse.StructuredData; 44using OpenMetaverse.StructuredData;
45using CoolHTTPListener = HttpServer.HttpListener; 45using CoolHTTPListener = HttpServer.HttpListener;
46using HttpListener=System.Net.HttpListener; 46using HttpListener = System.Net.HttpListener;
47using LogPrio=HttpServer.LogPrio; 47using LogPrio = HttpServer.LogPrio;
48using OpenSim.Framework.Monitoring; 48using OpenSim.Framework.Monitoring;
49using System.IO.Compression; 49using System.IO.Compression;
50using System.Security.Cryptography;
50 51
51namespace OpenSim.Framework.Servers.HttpServer 52namespace OpenSim.Framework.Servers.HttpServer
52{ 53{
@@ -112,6 +113,9 @@ namespace OpenSim.Framework.Servers.HttpServer
112 private X509Certificate2 m_cert; 113 private X509Certificate2 m_cert;
113 protected bool m_firstcaps = true; 114 protected bool m_firstcaps = true;
114 protected string m_SSLCommonName = ""; 115 protected string m_SSLCommonName = "";
116 protected List<string> m_certNames = new List<string>();
117 protected List<string> m_certIPs = new List<string>();
118 protected string m_certCN= "";
115 119
116 protected IPAddress m_listenIPAddress = IPAddress.Any; 120 protected IPAddress m_listenIPAddress = IPAddress.Any;
117 121
@@ -153,30 +157,150 @@ namespace OpenSim.Framework.Servers.HttpServer
153 m_ssl = ssl; 157 m_ssl = ssl;
154 } 158 }
155 159
156 public BaseHttpServer(uint port, bool ssl, uint sslport, string CN, string CPath, string CPass) : this (port, ssl) 160 private void load_cert(string CPath, string CPass)
157 { 161 {
158 if (m_ssl) 162 try
159 { 163 {
160 if(string.IsNullOrEmpty(CPass)) 164 m_cert = new X509Certificate2(CPath, CPass);
165 X509Extension ext = m_cert.Extensions["2.5.29.17"];
166 if(ext != null)
167 {
168 AsnEncodedData asndata = new AsnEncodedData(ext.Oid, ext.RawData);
169 string datastr = asndata.Format(true);
170 string[] lines = datastr.Split(new char[] {'\n','\r'});
171 foreach(string s in lines)
172 {
173 if(String.IsNullOrEmpty(s))
174 continue;
175 string[] parts = s.Split(new char[] {'='});
176 if(String.IsNullOrEmpty(parts[0]))
177 continue;
178 string entryName = parts[0].Replace(" ","");
179 if(entryName == "DNSName")
180 m_certNames.Add(parts[1]);
181 else if(entryName == "IPAddress")
182 m_certIPs.Add(parts[1]);
183 }
184 }
185 m_certCN = m_cert.GetNameInfo(X509NameType.SimpleName, false);
186 }
187 catch
188 {
189 throw new Exception("SSL cert load error");
190 }
191 }
192
193 public BaseHttpServer(uint port, bool ssl, uint sslport, string CN, string CPath, string CPass)
194 {
195 m_port = port;
196 if (ssl)
197 {
198 if(string.IsNullOrEmpty(CPath))
161 throw new Exception("invalid main http server cert path"); 199 throw new Exception("invalid main http server cert path");
162 200
201 if(Uri.CheckHostName(CN) == UriHostNameType.Unknown)
202 throw new Exception("invalid main http server CN (ExternalHostName)");
203
204 m_certNames.Clear();
205 m_certIPs.Clear();
206 m_certCN= "";
207
208 m_ssl = true;
163 m_sslport = sslport; 209 m_sslport = sslport;
164 m_cert = new X509Certificate2(CPath, CPass); 210 load_cert(CPath, CPass);
165 m_SSLCommonName = m_cert.GetNameInfo(X509NameType.SimpleName,false); 211
166 if(CN != m_SSLCommonName) 212 if(!CheckSSLCertHost(CN))
167 throw new Exception("main http server CN does not match cert CN"); 213 throw new Exception("invalid main http server CN (ExternalHostName)");
214
215 m_SSLCommonName = CN;
216
217 if(m_cert.Issuer == m_cert.Subject )
218 m_log.Warn("Self signed certificate. Clients need to allow this (some viewers debug option NoVerifySSLcert must be set to true");
219
168 220
169 } 221 }
222 else
223 m_ssl = false;
170 } 224 }
171 225
172 public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) : this (port, ssl) 226 public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) : this (port, ssl)
173 { 227 {
174 if (m_ssl) 228 if (m_ssl)
175 { 229 {
176 m_cert = new X509Certificate2(CPath, CPass); 230 load_cert(CPath, CPass);
231 if(m_cert.Issuer == m_cert.Subject )
232 m_log.Warn("Self signed certificate. Http clients need to allow this");
233 }
234 }
235
236 static bool MatchDNS (string hostname, string dns)
237 {
238 int indx = dns.IndexOf ('*');
239 if (indx == -1)
240 return (String.Compare(hostname, dns, true, CultureInfo.InvariantCulture) == 0);
241
242 int dnslen = dns.Length;
243 dnslen--;
244 if(indx == dnslen)
245 return true; // just * ?
246
247 if(indx > dnslen - 2)
248 return false; // 2 short ?
249
250 if (dns[indx + 1] != '.')
251 return false;
252
253 int indx2 = dns.IndexOf ('*', indx + 1);
254 if (indx2 != -1)
255 return false; // there can only be one;
256
257 string end = dns.Substring(indx + 1);
258 int hostlen = hostname.Length;
259 int endlen = end.Length;
260 int length = hostlen - endlen;
261 if (length <= 0)
262 return false;
263
264 if (String.Compare(hostname, length, end, 0, endlen, true, CultureInfo.InvariantCulture) != 0)
265 return false;
266
267 if (indx == 0)
268 {
269 indx2 = hostname.IndexOf ('.');
270 return ((indx2 == -1) || (indx2 >= length));
271 }
272
273 string start = dns.Substring (0, indx);
274 return (String.Compare (hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0);
275 }
276
277 public bool CheckSSLCertHost(string hostname)
278 {
279 UriHostNameType htype = Uri.CheckHostName(hostname);
280
281 if(htype == UriHostNameType.Unknown || htype == UriHostNameType.Basic)
282 return false;
283 if(htype == UriHostNameType.Dns)
284 {
285 foreach(string name in m_certNames)
286 {
287 if(MatchDNS(hostname, name))
288 return true;
289 }
290 if(MatchDNS(hostname, m_certCN))
291 return true;
292 }
293 else
294 {
295 foreach(string ip in m_certIPs)
296 {
297 if (String.Compare(hostname, ip, true, CultureInfo.InvariantCulture) != 0)
298 return true;
299 }
177 } 300 }
178 }
179 301
302 return false;
303 }
180 /// <summary> 304 /// <summary>
181 /// Add a stream handler to the http server. If the handler already exists, then nothing happens. 305 /// Add a stream handler to the http server. If the handler already exists, then nothing happens.
182 /// </summary> 306 /// </summary>
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 62abf8e..90505e1 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -417,7 +417,7 @@ namespace OpenSim
417 regionInfo.HttpPort = m_httpServerPort; 417 regionInfo.HttpPort = m_httpServerPort;
418 if(m_httpServerSSL) 418 if(m_httpServerSSL)
419 { 419 {
420 if(m_networkServersInfo.HttpSSLCN != regionInfo.ExternalHostName) 420 if(!m_httpServer.CheckSSLCertHost(regionInfo.ExternalHostName))
421 throw new Exception("main http cert CN doesn't match region External IP"); 421 throw new Exception("main http cert CN doesn't match region External IP");
422 422
423 regionInfo.ServerURI = "https://" + regionInfo.ExternalHostName + 423 regionInfo.ServerURI = "https://" + regionInfo.ExternalHostName +
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index d1ded36..07e1c48 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -501,10 +501,12 @@
501 console_port = 0 501 console_port = 0
502 502
503 ; ssl config: Experimental! 503 ; ssl config: Experimental!
504 http_listener_ssl = false ; if set to true main server is replaced a ssl one 504 http_listener_ssl = false ; if set to true main server is replaced by a ssl one
505 http_listener_sslport = 9001 ; Use this port for SSL connections 505 http_listener_sslport = 9001 ; Use this port for SSL connections
506 http_listener_cn = "myexternalip" ; // should be the External ip and match the CN on the cert 506 ; currently if using ssl, regions ExternalHostName must the the same and equal to http_listener_cn
507 http_listener_cert_path = "mycert.p12" ; path for the cert file 507 ; this will change is future
508 http_listener_cn = "myRegionsExternalHostName"
509 http_listener_cert_path = "mycert.p12" ; path for the cert file that is valid for the ExternalHostName
508 http_listener_cert_pass = "mycertpass" ; the cert passwork 510 http_listener_cert_pass = "mycertpass" ; the cert passwork
509 511
510 ; HTTPS for "Out of band" management applications such as the remote 512 ; HTTPS for "Out of band" management applications such as the remote