aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
authorDiva Canto2014-05-23 16:19:43 -0700
committerDiva Canto2014-05-23 16:19:43 -0700
commit20f20895cf1444071d5edc42e11a1fb94b1b1079 (patch)
tree0c7547590a89eec47886e0a8646f86ebbf449e63 /OpenSim/Framework
parentMerge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff)
downloadopensim-SC-20f20895cf1444071d5edc42e11a1fb94b1b1079.zip
opensim-SC-20f20895cf1444071d5edc42e11a1fb94b1b1079.tar.gz
opensim-SC-20f20895cf1444071d5edc42e11a1fb94b1b1079.tar.bz2
opensim-SC-20f20895cf1444071d5edc42e11a1fb94b1b1079.tar.xz
Adds optional HTTP Basic Authentication to Robust service connectors.
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/Communications/RestClient.cs29
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs19
-rw-r--r--OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs79
-rw-r--r--OpenSim/Framework/ServiceAuth/IServiceAuth.cs15
-rw-r--r--OpenSim/Framework/ServiceAuth/ServiceAuth.cs23
-rw-r--r--OpenSim/Framework/WebUtil.cs75
6 files changed, 231 insertions, 9 deletions
diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/Communications/RestClient.cs
index e7f0ca8..89e6aa1 100644
--- a/OpenSim/Framework/Communications/RestClient.cs
+++ b/OpenSim/Framework/Communications/RestClient.cs
@@ -35,6 +35,8 @@ using System.Threading;
35using System.Web; 35using System.Web;
36using log4net; 36using log4net;
37 37
38using OpenSim.Framework.ServiceAuth;
39
38namespace OpenSim.Framework.Communications 40namespace OpenSim.Framework.Communications
39{ 41{
40 /// <summary> 42 /// <summary>
@@ -297,7 +299,7 @@ namespace OpenSim.Framework.Communications
297 /// <summary> 299 /// <summary>
298 /// Perform a synchronous request 300 /// Perform a synchronous request
299 /// </summary> 301 /// </summary>
300 public Stream Request() 302 public Stream Request(IServiceAuth auth)
301 { 303 {
302 lock (_lock) 304 lock (_lock)
303 { 305 {
@@ -307,6 +309,8 @@ namespace OpenSim.Framework.Communications
307 _request.Timeout = 200000; 309 _request.Timeout = 200000;
308 _request.Method = RequestMethod; 310 _request.Method = RequestMethod;
309 _asyncException = null; 311 _asyncException = null;
312 if (auth != null)
313 auth.AddAuthorization(_request.Headers);
310 314
311// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); 315// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
312 try 316 try
@@ -358,7 +362,7 @@ namespace OpenSim.Framework.Communications
358 } 362 }
359 } 363 }
360 364
361 public Stream Request(Stream src) 365 public Stream Request(Stream src, IServiceAuth auth)
362 { 366 {
363 _request = (HttpWebRequest) WebRequest.Create(buildUri()); 367 _request = (HttpWebRequest) WebRequest.Create(buildUri());
364 _request.KeepAlive = false; 368 _request.KeepAlive = false;
@@ -367,6 +371,8 @@ namespace OpenSim.Framework.Communications
367 _request.Method = RequestMethod; 371 _request.Method = RequestMethod;
368 _asyncException = null; 372 _asyncException = null;
369 _request.ContentLength = src.Length; 373 _request.ContentLength = src.Length;
374 if (auth != null)
375 auth.AddAuthorization(_request.Headers);
370 376
371 m_log.InfoFormat("[REST]: Request Length {0}", _request.ContentLength); 377 m_log.InfoFormat("[REST]: Request Length {0}", _request.ContentLength);
372 m_log.InfoFormat("[REST]: Sending Web Request {0}", buildUri()); 378 m_log.InfoFormat("[REST]: Sending Web Request {0}", buildUri());
@@ -384,7 +390,22 @@ namespace OpenSim.Framework.Communications
384 length = src.Read(buf, 0, 1024); 390 length = src.Read(buf, 0, 1024);
385 } 391 }
386 392
387 _response = (HttpWebResponse) _request.GetResponse(); 393 try
394 {
395 _response = (HttpWebResponse)_request.GetResponse();
396 }
397 catch (WebException e)
398 {
399 m_log.WarnFormat("[REST]: Request {0} {1} failed with status {2} and message {3}",
400 RequestMethod, _request.RequestUri, e.Status, e.Message);
401 }
402 catch (Exception e)
403 {
404 m_log.WarnFormat(
405 "[REST]: Request {0} {1} failed with exception {2} {3}",
406 RequestMethod, _request.RequestUri, e.Message, e.StackTrace);
407 }
408
388 409
389// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request); 410// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
390 411
@@ -423,7 +444,7 @@ namespace OpenSim.Framework.Communications
423 try 444 try
424 { 445 {
425 // Perform the operation; if sucessful set the result 446 // Perform the operation; if sucessful set the result
426 Stream s = Request(); 447 Stream s = Request(null);
427 ar.SetAsCompleted(s, false); 448 ar.SetAsCompleted(s, false);
428 } 449 }
429 catch (Exception e) 450 catch (Exception e)
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
index 252cc2a..f160734 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
@@ -26,6 +26,8 @@
26 */ 26 */
27 27
28using System.IO; 28using System.IO;
29using System.Net;
30using OpenSim.Framework.ServiceAuth;
29 31
30namespace OpenSim.Framework.Servers.HttpServer 32namespace OpenSim.Framework.Servers.HttpServer
31{ 33{
@@ -37,15 +39,30 @@ namespace OpenSim.Framework.Servers.HttpServer
37 /// </remarks> 39 /// </remarks>
38 public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler 40 public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler
39 { 41 {
40 protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} 42 protected IServiceAuth m_Auth;
43
44 protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) { }
41 45
42 protected BaseStreamHandler(string httpMethod, string path, string name, string description) 46 protected BaseStreamHandler(string httpMethod, string path, string name, string description)
43 : base(httpMethod, path, name, description) {} 47 : base(httpMethod, path, name, description) {}
44 48
49 protected BaseStreamHandler(string httpMethod, string path, IServiceAuth auth)
50 : base(httpMethod, path, null, null)
51 {
52 m_Auth = auth;
53 }
54
45 public virtual byte[] Handle( 55 public virtual byte[] Handle(
46 string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 56 string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
47 { 57 {
48 RequestsReceived++; 58 RequestsReceived++;
59 if (m_Auth != null && !m_Auth.Authenticate(httpRequest.Headers, httpResponse.AddHeader))
60 {
61
62 httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
63 httpResponse.ContentType = "text/plain";
64 return new byte[0];
65 }
49 66
50 byte[] result = ProcessRequest(path, request, httpRequest, httpResponse); 67 byte[] result = ProcessRequest(path, request, httpRequest, httpResponse);
51 68
diff --git a/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs
new file mode 100644
index 0000000..f33a045
--- /dev/null
+++ b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs
@@ -0,0 +1,79 @@
1using System;
2using System.Collections.Generic;
3using System.Collections.Specialized;
4using System.Reflection;
5
6using Nini.Config;
7using log4net;
8
9namespace OpenSim.Framework.ServiceAuth
10{
11 public class BasicHttpAuthentication : IServiceAuth
12 {
13 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
14
15 private string m_Username, m_Password;
16 private string m_CredentialsB64;
17
18 private string remove_me;
19
20 public string Credentials
21 {
22 get { return m_CredentialsB64; }
23 }
24
25 public BasicHttpAuthentication(IConfigSource config, string section)
26 {
27 remove_me = section;
28 m_Username = Util.GetConfigVarFromSections<string>(config, "HttpAuthUsername", new string[] { "Network", section }, string.Empty);
29 m_Password = Util.GetConfigVarFromSections<string>(config, "HttpAuthPassword", new string[] { "Network", section }, string.Empty);
30 string str = m_Username + ":" + m_Password;
31 byte[] encData_byte = Util.UTF8.GetBytes(str);
32
33 m_CredentialsB64 = Convert.ToBase64String(encData_byte);
34 m_log.DebugFormat("[HTTP BASIC AUTH]: {0} {1} [{2}]", m_Username, m_Password, section);
35 }
36
37 public void AddAuthorization(NameValueCollection headers)
38 {
39 //m_log.DebugFormat("[HTTP BASIC AUTH]: Adding authorization for {0}", remove_me);
40 headers["Authorization"] = "Basic " + m_CredentialsB64;
41 }
42
43 public bool Authenticate(string data)
44 {
45 string recovered = Util.Base64ToString(data);
46 if (!String.IsNullOrEmpty(recovered))
47 {
48 string[] parts = recovered.Split(new char[] { ':' });
49 if (parts.Length >= 2)
50 {
51 return m_Username.Equals(parts[0]) && m_Password.Equals(parts[1]);
52 }
53 }
54
55 return false;
56 }
57
58 public bool Authenticate(NameValueCollection requestHeaders, AddHeaderDelegate d)
59 {
60 //m_log.DebugFormat("[HTTP BASIC AUTH]: Authenticate in {0}", remove_me);
61 if (requestHeaders != null)
62 {
63 string value = requestHeaders.Get("Authorization");
64 if (value != null)
65 {
66 value = value.Trim();
67 if (value.StartsWith("Basic "))
68 {
69 value = value.Replace("Basic ", string.Empty);
70 if (Authenticate(value))
71 return true;
72 }
73 }
74 }
75 d("WWW-Authenticate", "Basic realm = \"Asset Server\"");
76 return false;
77 }
78 }
79}
diff --git a/OpenSim/Framework/ServiceAuth/IServiceAuth.cs b/OpenSim/Framework/ServiceAuth/IServiceAuth.cs
new file mode 100644
index 0000000..415dc12
--- /dev/null
+++ b/OpenSim/Framework/ServiceAuth/IServiceAuth.cs
@@ -0,0 +1,15 @@
1using System;
2using System.Collections.Generic;
3using System.Collections.Specialized;
4
5namespace OpenSim.Framework.ServiceAuth
6{
7 public delegate void AddHeaderDelegate(string key, string value);
8
9 public interface IServiceAuth
10 {
11 bool Authenticate(string data);
12 bool Authenticate(NameValueCollection headers, AddHeaderDelegate d);
13 void AddAuthorization(NameValueCollection headers);
14 }
15}
diff --git a/OpenSim/Framework/ServiceAuth/ServiceAuth.cs b/OpenSim/Framework/ServiceAuth/ServiceAuth.cs
new file mode 100644
index 0000000..bc32d90
--- /dev/null
+++ b/OpenSim/Framework/ServiceAuth/ServiceAuth.cs
@@ -0,0 +1,23 @@
1using System;
2using System.Collections.Generic;
3
4using Nini.Config;
5
6namespace OpenSim.Framework.ServiceAuth
7{
8 public class ServiceAuth
9 {
10 public static IServiceAuth Create(IConfigSource config, string section)
11 {
12 string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", section }, "None");
13
14 switch (authType)
15 {
16 case "BasicHttpAuthentication":
17 return new BasicHttpAuthentication(config, section);
18 }
19
20 return null;
21 }
22 }
23}
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index 0970fd1..e614fd5 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -45,6 +45,8 @@ using Nwc.XmlRpc;
45using OpenMetaverse.StructuredData; 45using OpenMetaverse.StructuredData;
46using XMLResponseHelper = OpenSim.Framework.SynchronousRestObjectRequester.XMLResponseHelper; 46using XMLResponseHelper = OpenSim.Framework.SynchronousRestObjectRequester.XMLResponseHelper;
47 47
48using OpenSim.Framework.ServiceAuth;
49
48namespace OpenSim.Framework 50namespace OpenSim.Framework
49{ 51{
50 /// <summary> 52 /// <summary>
@@ -773,6 +775,13 @@ namespace OpenSim.Framework
773 string requestUrl, TRequest obj, Action<TResponse> action, 775 string requestUrl, TRequest obj, Action<TResponse> action,
774 int maxConnections) 776 int maxConnections)
775 { 777 {
778 MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, action, maxConnections, null);
779 }
780
781 public static void MakeRequest<TRequest, TResponse>(string verb,
782 string requestUrl, TRequest obj, Action<TResponse> action,
783 int maxConnections, IServiceAuth auth)
784 {
776 int reqnum = WebUtil.RequestNumber++; 785 int reqnum = WebUtil.RequestNumber++;
777 786
778 if (WebUtil.DebugLevel >= 3) 787 if (WebUtil.DebugLevel >= 3)
@@ -786,6 +795,10 @@ namespace OpenSim.Framework
786 795
787 WebRequest request = WebRequest.Create(requestUrl); 796 WebRequest request = WebRequest.Create(requestUrl);
788 HttpWebRequest ht = (HttpWebRequest)request; 797 HttpWebRequest ht = (HttpWebRequest)request;
798
799 if (auth != null)
800 auth.AddAuthorization(ht.Headers);
801
789 if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections) 802 if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections)
790 ht.ServicePoint.ConnectionLimit = maxConnections; 803 ht.ServicePoint.ConnectionLimit = maxConnections;
791 804
@@ -969,7 +982,7 @@ namespace OpenSim.Framework
969 /// 982 ///
970 /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting 983 /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting
971 /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> 984 /// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
972 public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs) 985 public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs, IServiceAuth auth)
973 { 986 {
974 int reqnum = WebUtil.RequestNumber++; 987 int reqnum = WebUtil.RequestNumber++;
975 988
@@ -984,6 +997,10 @@ namespace OpenSim.Framework
984 request.Method = verb; 997 request.Method = verb;
985 if (timeoutsecs > 0) 998 if (timeoutsecs > 0)
986 request.Timeout = timeoutsecs * 1000; 999 request.Timeout = timeoutsecs * 1000;
1000
1001 if (auth != null)
1002 auth.AddAuthorization(request.Headers);
1003
987 string respstring = String.Empty; 1004 string respstring = String.Empty;
988 1005
989 using (MemoryStream buffer = new MemoryStream()) 1006 using (MemoryStream buffer = new MemoryStream())
@@ -1068,10 +1085,20 @@ namespace OpenSim.Framework
1068 return respstring; 1085 return respstring;
1069 } 1086 }
1070 1087
1088 public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs)
1089 {
1090 return MakeRequest(verb, requestUrl, obj, timeoutsecs, null);
1091 }
1092
1071 public static string MakeRequest(string verb, string requestUrl, string obj) 1093 public static string MakeRequest(string verb, string requestUrl, string obj)
1072 { 1094 {
1073 return MakeRequest(verb, requestUrl, obj, -1); 1095 return MakeRequest(verb, requestUrl, obj, -1);
1074 } 1096 }
1097
1098 public static string MakeRequest(string verb, string requestUrl, string obj, IServiceAuth auth)
1099 {
1100 return MakeRequest(verb, requestUrl, obj, -1, auth);
1101 }
1075 } 1102 }
1076 1103
1077 public class SynchronousRestObjectRequester 1104 public class SynchronousRestObjectRequester
@@ -1094,6 +1121,10 @@ namespace OpenSim.Framework
1094 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, 0); 1121 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, 0);
1095 } 1122 }
1096 1123
1124 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, IServiceAuth auth)
1125 {
1126 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, 0, auth);
1127 }
1097 /// <summary> 1128 /// <summary>
1098 /// Perform a synchronous REST request. 1129 /// Perform a synchronous REST request.
1099 /// </summary> 1130 /// </summary>
@@ -1112,7 +1143,11 @@ namespace OpenSim.Framework
1112 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, pTimeout, 0); 1143 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, pTimeout, 0);
1113 } 1144 }
1114 1145
1115 /// <summary> 1146 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, IServiceAuth auth)
1147 {
1148 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, pTimeout, 0, auth);
1149 }
1150
1116 /// Perform a synchronous REST request. 1151 /// Perform a synchronous REST request.
1117 /// </summary> 1152 /// </summary>
1118 /// <param name="verb"></param> 1153 /// <param name="verb"></param>
@@ -1128,6 +1163,25 @@ namespace OpenSim.Framework
1128 /// </returns> 1163 /// </returns>
1129 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections) 1164 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections)
1130 { 1165 {
1166 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, pTimeout, maxConnections, null);
1167 }
1168
1169 /// <summary>
1170 /// Perform a synchronous REST request.
1171 /// </summary>
1172 /// <param name="verb"></param>
1173 /// <param name="requestUrl"></param>
1174 /// <param name="obj"></param>
1175 /// <param name="pTimeout">
1176 /// Request timeout in milliseconds. Timeout.Infinite indicates no timeout. If 0 is passed then the default HttpWebRequest timeout is used (100 seconds)
1177 /// </param>
1178 /// <param name="maxConnections"></param>
1179 /// <returns>
1180 /// The response. If there was an internal exception or the request timed out,
1181 /// then the default(TResponse) is returned.
1182 /// </returns>
1183 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections, IServiceAuth auth)
1184 {
1131 int reqnum = WebUtil.RequestNumber++; 1185 int reqnum = WebUtil.RequestNumber++;
1132 1186
1133 if (WebUtil.DebugLevel >= 3) 1187 if (WebUtil.DebugLevel >= 3)
@@ -1143,6 +1197,9 @@ namespace OpenSim.Framework
1143 WebRequest request = WebRequest.Create(requestUrl); 1197 WebRequest request = WebRequest.Create(requestUrl);
1144 HttpWebRequest ht = (HttpWebRequest)request; 1198 HttpWebRequest ht = (HttpWebRequest)request;
1145 1199
1200 if (auth != null)
1201 auth.AddAuthorization(ht.Headers);
1202
1146 if (pTimeout != 0) 1203 if (pTimeout != 0)
1147 ht.Timeout = pTimeout; 1204 ht.Timeout = pTimeout;
1148 1205
@@ -1221,8 +1278,18 @@ namespace OpenSim.Framework
1221 { 1278 {
1222 using (HttpWebResponse hwr = (HttpWebResponse)e.Response) 1279 using (HttpWebResponse hwr = (HttpWebResponse)e.Response)
1223 { 1280 {
1224 if (hwr != null && hwr.StatusCode == HttpStatusCode.NotFound) 1281 if (hwr != null)
1225 return deserial; 1282 {
1283 if (hwr.StatusCode == HttpStatusCode.NotFound)
1284 return deserial;
1285 if (hwr.StatusCode == HttpStatusCode.Unauthorized)
1286 {
1287 m_log.Error(string.Format(
1288 "[SynchronousRestObjectRequester]: Web request {0} requires authentication ",
1289 requestUrl));
1290 return deserial;
1291 }
1292 }
1226 else 1293 else
1227 m_log.Error(string.Format( 1294 m_log.Error(string.Format(
1228 "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} ", 1295 "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} ",