diff options
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs')
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 167 |
1 files changed, 149 insertions, 18 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index e431042..bd8b681 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 | { |
@@ -110,8 +111,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
110 | protected uint m_sslport; | 111 | protected uint m_sslport; |
111 | protected bool m_ssl; | 112 | protected bool m_ssl; |
112 | private X509Certificate2 m_cert; | 113 | private X509Certificate2 m_cert; |
113 | protected bool m_firstcaps = true; | ||
114 | protected string m_SSLCommonName = ""; | 114 | protected string m_SSLCommonName = ""; |
115 | protected List<string> m_certNames = new List<string>(); | ||
116 | protected List<string> m_certIPs = new List<string>(); | ||
117 | protected string m_certCN= ""; | ||
115 | 118 | ||
116 | protected IPAddress m_listenIPAddress = IPAddress.Any; | 119 | protected IPAddress m_listenIPAddress = IPAddress.Any; |
117 | 120 | ||
@@ -148,27 +151,153 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
148 | m_port = port; | 151 | m_port = port; |
149 | } | 152 | } |
150 | 153 | ||
151 | public BaseHttpServer(uint port, bool ssl) : this (port) | 154 | private void load_cert(string CPath, string CPass) |
152 | { | 155 | { |
153 | m_ssl = ssl; | 156 | try |
157 | { | ||
158 | m_cert = new X509Certificate2(CPath, CPass); | ||
159 | X509Extension ext = m_cert.Extensions["2.5.29.17"]; | ||
160 | if(ext != null) | ||
161 | { | ||
162 | AsnEncodedData asndata = new AsnEncodedData(ext.Oid, ext.RawData); | ||
163 | string datastr = asndata.Format(true); | ||
164 | string[] lines = datastr.Split(new char[] {'\n','\r'}); | ||
165 | foreach(string s in lines) | ||
166 | { | ||
167 | if(String.IsNullOrEmpty(s)) | ||
168 | continue; | ||
169 | string[] parts = s.Split(new char[] {'='}); | ||
170 | if(String.IsNullOrEmpty(parts[0])) | ||
171 | continue; | ||
172 | string entryName = parts[0].Replace(" ",""); | ||
173 | if(entryName == "DNSName") | ||
174 | m_certNames.Add(parts[1]); | ||
175 | else if(entryName == "IPAddress") | ||
176 | m_certIPs.Add(parts[1]); | ||
177 | } | ||
178 | } | ||
179 | m_certCN = m_cert.GetNameInfo(X509NameType.SimpleName, false); | ||
180 | } | ||
181 | catch | ||
182 | { | ||
183 | throw new Exception("SSL cert load error"); | ||
184 | } | ||
154 | } | 185 | } |
155 | 186 | ||
156 | public BaseHttpServer(uint port, bool ssl, uint sslport, string CN) : this (port, ssl) | 187 | public BaseHttpServer(uint port, bool ssl, uint sslport, string CN, string CPath, string CPass) |
157 | { | 188 | { |
158 | if (m_ssl) | 189 | m_port = port; |
190 | if (ssl) | ||
159 | { | 191 | { |
192 | if(string.IsNullOrEmpty(CPath)) | ||
193 | throw new Exception("invalid main http server cert path"); | ||
194 | |||
195 | if(Uri.CheckHostName(CN) == UriHostNameType.Unknown) | ||
196 | throw new Exception("invalid main http server CN (ExternalHostName)"); | ||
197 | |||
198 | m_certNames.Clear(); | ||
199 | m_certIPs.Clear(); | ||
200 | m_certCN= ""; | ||
201 | |||
202 | m_ssl = true; | ||
160 | m_sslport = sslport; | 203 | m_sslport = sslport; |
204 | load_cert(CPath, CPass); | ||
205 | |||
206 | if(!CheckSSLCertHost(CN)) | ||
207 | throw new Exception("invalid main http server CN (ExternalHostName)"); | ||
208 | |||
209 | m_SSLCommonName = CN; | ||
210 | |||
211 | if(m_cert.Issuer == m_cert.Subject ) | ||
212 | m_log.Warn("Self signed certificate. Clients need to allow this (some viewers debug option NoVerifySSLcert must be set to true"); | ||
161 | } | 213 | } |
214 | else | ||
215 | m_ssl = false; | ||
162 | } | 216 | } |
163 | 217 | ||
164 | public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) : this (port, ssl) | 218 | public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) |
165 | { | 219 | { |
166 | if (m_ssl) | 220 | m_port = port; |
221 | if (ssl) | ||
167 | { | 222 | { |
168 | m_cert = new X509Certificate2(CPath, CPass); | 223 | load_cert(CPath, CPass); |
224 | if(m_cert.Issuer == m_cert.Subject ) | ||
225 | m_log.Warn("Self signed certificate. Http clients need to allow this"); | ||
226 | m_ssl = true; | ||
227 | m_sslport = port; | ||
228 | } | ||
229 | else | ||
230 | m_ssl = false; | ||
231 | } | ||
232 | |||
233 | static bool MatchDNS (string hostname, string dns) | ||
234 | { | ||
235 | int indx = dns.IndexOf ('*'); | ||
236 | if (indx == -1) | ||
237 | return (String.Compare(hostname, dns, true, CultureInfo.InvariantCulture) == 0); | ||
238 | |||
239 | int dnslen = dns.Length; | ||
240 | dnslen--; | ||
241 | if(indx == dnslen) | ||
242 | return true; // just * ? | ||
243 | |||
244 | if(indx > dnslen - 2) | ||
245 | return false; // 2 short ? | ||
246 | |||
247 | if (dns[indx + 1] != '.') | ||
248 | return false; | ||
249 | |||
250 | int indx2 = dns.IndexOf ('*', indx + 1); | ||
251 | if (indx2 != -1) | ||
252 | return false; // there can only be one; | ||
253 | |||
254 | string end = dns.Substring(indx + 1); | ||
255 | int hostlen = hostname.Length; | ||
256 | int endlen = end.Length; | ||
257 | int length = hostlen - endlen; | ||
258 | if (length <= 0) | ||
259 | return false; | ||
260 | |||
261 | if (String.Compare(hostname, length, end, 0, endlen, true, CultureInfo.InvariantCulture) != 0) | ||
262 | return false; | ||
263 | |||
264 | if (indx == 0) | ||
265 | { | ||
266 | indx2 = hostname.IndexOf ('.'); | ||
267 | return ((indx2 == -1) || (indx2 >= length)); | ||
268 | } | ||
269 | |||
270 | string start = dns.Substring (0, indx); | ||
271 | return (String.Compare (hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0); | ||
272 | } | ||
273 | |||
274 | public bool CheckSSLCertHost(string hostname) | ||
275 | { | ||
276 | UriHostNameType htype = Uri.CheckHostName(hostname); | ||
277 | |||
278 | if(htype == UriHostNameType.Unknown || htype == UriHostNameType.Basic) | ||
279 | return false; | ||
280 | if(htype == UriHostNameType.Dns) | ||
281 | { | ||
282 | foreach(string name in m_certNames) | ||
283 | { | ||
284 | if(MatchDNS(hostname, name)) | ||
285 | return true; | ||
286 | } | ||
287 | if(MatchDNS(hostname, m_certCN)) | ||
288 | return true; | ||
289 | } | ||
290 | else | ||
291 | { | ||
292 | foreach(string ip in m_certIPs) | ||
293 | { | ||
294 | if (String.Compare(hostname, ip, true, CultureInfo.InvariantCulture) != 0) | ||
295 | return true; | ||
296 | } | ||
169 | } | 297 | } |
170 | } | ||
171 | 298 | ||
299 | return false; | ||
300 | } | ||
172 | /// <summary> | 301 | /// <summary> |
173 | /// Add a stream handler to the http server. If the handler already exists, then nothing happens. | 302 | /// Add a stream handler to the http server. If the handler already exists, then nothing happens. |
174 | /// </summary> | 303 | /// </summary> |
@@ -461,7 +590,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
461 | } | 590 | } |
462 | 591 | ||
463 | OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); | 592 | OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); |
464 | resp.ReuseContext = true; | 593 | // resp.ReuseContext = true; |
465 | // resp.ReuseContext = false; | 594 | // resp.ReuseContext = false; |
466 | HandleRequest(req, resp); | 595 | HandleRequest(req, resp); |
467 | 596 | ||
@@ -1804,7 +1933,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1804 | */ | 1933 | */ |
1805 | // disable this things | 1934 | // disable this things |
1806 | response.KeepAlive = false; | 1935 | response.KeepAlive = false; |
1807 | response.ReuseContext = false; | 1936 | // response.ReuseContext = false; |
1808 | 1937 | ||
1809 | // Cross-Origin Resource Sharing with simple requests | 1938 | // Cross-Origin Resource Sharing with simple requests |
1810 | if (responsedata.ContainsKey("access_control_allow_origin")) | 1939 | if (responsedata.ContainsKey("access_control_allow_origin")) |
@@ -1906,7 +2035,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1906 | 2035 | ||
1907 | public void Start() | 2036 | public void Start() |
1908 | { | 2037 | { |
1909 | Start(true); | 2038 | Start(true,true); |
1910 | } | 2039 | } |
1911 | 2040 | ||
1912 | /// <summary> | 2041 | /// <summary> |
@@ -1916,7 +2045,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1916 | /// If true then poll responses are performed asynchronsly. | 2045 | /// If true then poll responses are performed asynchronsly. |
1917 | /// Option exists to allow regression tests to perform processing synchronously. | 2046 | /// Option exists to allow regression tests to perform processing synchronously. |
1918 | /// </param> | 2047 | /// </param> |
1919 | public void Start(bool performPollResponsesAsync) | 2048 | public void Start(bool performPollResponsesAsync, bool runPool) |
1920 | { | 2049 | { |
1921 | m_log.InfoFormat( | 2050 | m_log.InfoFormat( |
1922 | "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); | 2051 | "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); |
@@ -1954,9 +2083,11 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
1954 | m_httpListener2.Start(64); | 2083 | m_httpListener2.Start(64); |
1955 | 2084 | ||
1956 | // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events | 2085 | // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events |
1957 | 2086 | if(runPool) | |
1958 | PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000); | 2087 | { |
1959 | PollServiceRequestManager.Start(); | 2088 | PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000); |
2089 | PollServiceRequestManager.Start(); | ||
2090 | } | ||
1960 | 2091 | ||
1961 | HTTPDRunning = true; | 2092 | HTTPDRunning = true; |
1962 | 2093 | ||