diff options
author | UbitUmarov | 2016-10-09 01:01:52 +0100 |
---|---|---|
committer | UbitUmarov | 2016-10-09 01:01:52 +0100 |
commit | 5b946405a09a4ec89e0d7664fabbf5015c7c62e8 (patch) | |
tree | c1d29ec42bd4bf546e1a51eea00863dcac1fee12 /OpenSim/Framework | |
parent | Merge branch 'master' into httptests (diff) | |
download | opensim-SC-5b946405a09a4ec89e0d7664fabbf5015c7c62e8.zip opensim-SC-5b946405a09a4ec89e0d7664fabbf5015c7c62e8.tar.gz opensim-SC-5b946405a09a4ec89e0d7664fabbf5015c7c62e8.tar.bz2 opensim-SC-5b946405a09a4ec89e0d7664fabbf5015c7c62e8.tar.xz |
changes to regions ssl suport: verify if hostnames are validate by the selected cert, make clear that for now all regions need to have the same ExternalHostName if using sll (due to other code that needs to be changed later)
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 146 |
1 files changed, 135 insertions, 11 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> |