diff options
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 146 | ||||
-rw-r--r-- | OpenSim/Region/Application/OpenSimBase.cs | 2 | ||||
-rw-r--r-- | bin/OpenSimDefaults.ini | 8 |
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; | |||
43 | using Nwc.XmlRpc; | 43 | using Nwc.XmlRpc; |
44 | using OpenMetaverse.StructuredData; | 44 | using OpenMetaverse.StructuredData; |
45 | using CoolHTTPListener = HttpServer.HttpListener; | 45 | using CoolHTTPListener = HttpServer.HttpListener; |
46 | using HttpListener=System.Net.HttpListener; | 46 | using HttpListener = System.Net.HttpListener; |
47 | using LogPrio=HttpServer.LogPrio; | 47 | using LogPrio = HttpServer.LogPrio; |
48 | using OpenSim.Framework.Monitoring; | 48 | using OpenSim.Framework.Monitoring; |
49 | using System.IO.Compression; | 49 | using System.IO.Compression; |
50 | using System.Security.Cryptography; | ||
50 | 51 | ||
51 | namespace OpenSim.Framework.Servers.HttpServer | 52 | namespace 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 |