diff options
author | Diva Canto | 2009-09-20 08:32:51 -0700 |
---|---|---|
committer | Diva Canto | 2009-09-20 08:32:51 -0700 |
commit | 9027d4b490fcc6e806cb8b49f7d89ed317df0950 (patch) | |
tree | 44dff73fa1bb38ea42aa8f79bb9f2792eab23fb4 /OpenSim | |
parent | Merge branch 'master' of ssh://diva@opensimulator.org/var/git/opensim (diff) | |
parent | Finish the (untested) authentication connector (diff) | |
download | opensim-SC-9027d4b490fcc6e806cb8b49f7d89ed317df0950.zip opensim-SC-9027d4b490fcc6e806cb8b49f7d89ed317df0950.tar.gz opensim-SC-9027d4b490fcc6e806cb8b49f7d89ed317df0950.tar.bz2 opensim-SC-9027d4b490fcc6e806cb8b49f7d89ed317df0950.tar.xz |
Merge branch 'master' of ssh://diva@opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim')
4 files changed, 362 insertions, 3 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs new file mode 100644 index 0000000..0f0c790 --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Net; | ||
31 | using System.Text; | ||
32 | using System.Xml; | ||
33 | using System.Xml.Serialization; | ||
34 | |||
35 | namespace OpenSim.Framework.Servers.HttpServer | ||
36 | { | ||
37 | public class SynchronousRestFormsRequester | ||
38 | { | ||
39 | /// <summary> | ||
40 | /// Perform a synchronous REST request. | ||
41 | /// </summary> | ||
42 | /// <param name="verb"></param> | ||
43 | /// <param name="requestUrl"></param> | ||
44 | /// <param name="obj"> </param> | ||
45 | /// <returns></returns> | ||
46 | /// | ||
47 | /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting | ||
48 | /// the request. You'll want to make sure you deal with this as they're not uncommon</exception> | ||
49 | public static string MakeRequest(string verb, string requestUrl, string obj) | ||
50 | { | ||
51 | WebRequest request = WebRequest.Create(requestUrl); | ||
52 | request.Method = verb; | ||
53 | |||
54 | if ((verb == "POST") || (verb == "PUT")) | ||
55 | { | ||
56 | request.ContentType = "text/www-form-urlencoded"; | ||
57 | |||
58 | MemoryStream buffer = new MemoryStream(); | ||
59 | |||
60 | using (StreamWriter writer = new StreamWriter(buffer)) | ||
61 | { | ||
62 | writer.WriteLine(obj); | ||
63 | writer.Flush(); | ||
64 | } | ||
65 | |||
66 | int length = (int) buffer.Length; | ||
67 | request.ContentLength = length; | ||
68 | |||
69 | Stream requestStream = request.GetRequestStream(); | ||
70 | requestStream.Write(buffer.ToArray(), 0, length); | ||
71 | } | ||
72 | |||
73 | string respstring = String.Empty; | ||
74 | |||
75 | try | ||
76 | { | ||
77 | using (WebResponse resp = request.GetResponse()) | ||
78 | { | ||
79 | if (resp.ContentLength > 0) | ||
80 | { | ||
81 | using (StreamReader reader = new StreamReader(resp.GetResponseStream())) | ||
82 | { | ||
83 | respstring = reader.ReadToEnd(); | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | catch (System.InvalidOperationException) | ||
89 | { | ||
90 | // This is what happens when there is invalid XML | ||
91 | } | ||
92 | return respstring; | ||
93 | } | ||
94 | } | ||
95 | } | ||
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 0a36bbe..6c2b3ed 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs | |||
@@ -183,5 +183,119 @@ namespace OpenSim.Server.Base | |||
183 | 183 | ||
184 | return result; | 184 | return result; |
185 | } | 185 | } |
186 | |||
187 | public static string BuildQueryString(Dictionary<string, string> data) | ||
188 | { | ||
189 | string qstring = String.Empty; | ||
190 | |||
191 | foreach(KeyValuePair<string, string> kvp in data) | ||
192 | { | ||
193 | string part; | ||
194 | if (kvp.Value != String.Empty) | ||
195 | { | ||
196 | part = System.Web.HttpUtility.UrlEncode(kvp.Key) + | ||
197 | "=" + System.Web.HttpUtility.UrlEncode(kvp.Value); | ||
198 | } | ||
199 | else | ||
200 | { | ||
201 | part = System.Web.HttpUtility.UrlEncode(kvp.Key); | ||
202 | } | ||
203 | |||
204 | if (qstring != String.Empty) | ||
205 | qstring += "&"; | ||
206 | |||
207 | qstring += part; | ||
208 | } | ||
209 | |||
210 | return qstring; | ||
211 | } | ||
212 | |||
213 | public static string BuildXmlResponse(Dictionary<string, object> data) | ||
214 | { | ||
215 | XmlDocument doc = new XmlDocument(); | ||
216 | |||
217 | XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, | ||
218 | "", ""); | ||
219 | |||
220 | doc.AppendChild(xmlnode); | ||
221 | |||
222 | XmlElement rootElement = doc.CreateElement("", "ServerResponse", | ||
223 | ""); | ||
224 | |||
225 | doc.AppendChild(rootElement); | ||
226 | |||
227 | BuildXmlData(rootElement, data); | ||
228 | |||
229 | return doc.InnerXml; | ||
230 | } | ||
231 | |||
232 | private static void BuildXmlData(XmlElement parent, Dictionary<string, object> data) | ||
233 | { | ||
234 | foreach (KeyValuePair<string, object> kvp in data) | ||
235 | { | ||
236 | XmlElement elem = parent.OwnerDocument.CreateElement("", | ||
237 | kvp.Key, ""); | ||
238 | |||
239 | if (kvp.Value is Dictionary<string, object>) | ||
240 | { | ||
241 | XmlAttribute type = parent.OwnerDocument.CreateAttribute("", | ||
242 | "type", ""); | ||
243 | type.Value = "List"; | ||
244 | |||
245 | elem.Attributes.Append(type); | ||
246 | |||
247 | BuildXmlData(elem, (Dictionary<string, object>)kvp.Value); | ||
248 | } | ||
249 | else | ||
250 | { | ||
251 | elem.AppendChild(parent.OwnerDocument.CreateTextNode( | ||
252 | kvp.Value.ToString())); | ||
253 | } | ||
254 | |||
255 | parent.AppendChild(elem); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | public static Dictionary<string, object> ParseXmlResponse(string data) | ||
260 | { | ||
261 | Dictionary<string, object> ret = new Dictionary<string, object>(); | ||
262 | |||
263 | XmlDocument doc = new XmlDocument(); | ||
264 | |||
265 | doc.LoadXml(data); | ||
266 | |||
267 | XmlNodeList rootL = doc.GetElementsByTagName("ServerResponse"); | ||
268 | |||
269 | if (rootL.Count != 1) | ||
270 | return ret; | ||
271 | |||
272 | XmlNode rootNode = rootL[0]; | ||
273 | |||
274 | ret = ParseElement(rootNode); | ||
275 | |||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | private static Dictionary<string, object> ParseElement(XmlNode element) | ||
280 | { | ||
281 | Dictionary<string, object> ret = new Dictionary<string, object>(); | ||
282 | |||
283 | XmlNodeList partL = element.ChildNodes; | ||
284 | |||
285 | foreach (XmlNode part in partL) | ||
286 | { | ||
287 | XmlNode type = part.Attributes.GetNamedItem("Type"); | ||
288 | if (type == null || type.Value != "List") | ||
289 | { | ||
290 | ret[part.Name] = part.InnerText; | ||
291 | } | ||
292 | else | ||
293 | { | ||
294 | ret[part.Name] = ParseElement(part); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | return ret; | ||
299 | } | ||
186 | } | 300 | } |
187 | } | 301 | } |
diff --git a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs index 6cf7d56..490a13a 100644 --- a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs | |||
@@ -157,7 +157,7 @@ namespace OpenSim.Server.Handlers.Authentication | |||
157 | 157 | ||
158 | doc.AppendChild(xmlnode); | 158 | doc.AppendChild(xmlnode); |
159 | 159 | ||
160 | XmlElement rootElement = doc.CreateElement("", "Authentication", | 160 | XmlElement rootElement = doc.CreateElement("", "ServerResponse", |
161 | ""); | 161 | ""); |
162 | 162 | ||
163 | doc.AppendChild(rootElement); | 163 | doc.AppendChild(rootElement); |
@@ -179,7 +179,7 @@ namespace OpenSim.Server.Handlers.Authentication | |||
179 | 179 | ||
180 | doc.AppendChild(xmlnode); | 180 | doc.AppendChild(xmlnode); |
181 | 181 | ||
182 | XmlElement rootElement = doc.CreateElement("", "Authentication", | 182 | XmlElement rootElement = doc.CreateElement("", "ServerResponse", |
183 | ""); | 183 | ""); |
184 | 184 | ||
185 | doc.AppendChild(rootElement); | 185 | doc.AppendChild(rootElement); |
@@ -201,7 +201,7 @@ namespace OpenSim.Server.Handlers.Authentication | |||
201 | 201 | ||
202 | doc.AppendChild(xmlnode); | 202 | doc.AppendChild(xmlnode); |
203 | 203 | ||
204 | XmlElement rootElement = doc.CreateElement("", "Authentication", | 204 | XmlElement rootElement = doc.CreateElement("", "ServerResponse", |
205 | ""); | 205 | ""); |
206 | 206 | ||
207 | doc.AppendChild(rootElement); | 207 | doc.AppendChild(rootElement); |
diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs new file mode 100644 index 0000000..50e817e --- /dev/null +++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using log4net; | ||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.IO; | ||
32 | using System.Reflection; | ||
33 | using Nini.Config; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Framework.Communications; | ||
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Services.Interfaces; | ||
38 | using OpenSim.Server.Base; | ||
39 | using OpenMetaverse; | ||
40 | |||
41 | namespace OpenSim.Services.Connectors | ||
42 | { | ||
43 | public class AuthenticationServicesConnector : IAuthenticationService | ||
44 | { | ||
45 | private static readonly ILog m_log = | ||
46 | LogManager.GetLogger( | ||
47 | MethodBase.GetCurrentMethod().DeclaringType); | ||
48 | |||
49 | private string m_ServerURI = String.Empty; | ||
50 | |||
51 | public AuthenticationServicesConnector() | ||
52 | { | ||
53 | } | ||
54 | |||
55 | public AuthenticationServicesConnector(string serverURI) | ||
56 | { | ||
57 | m_ServerURI = serverURI.TrimEnd('/'); | ||
58 | } | ||
59 | |||
60 | public AuthenticationServicesConnector(IConfigSource source) | ||
61 | { | ||
62 | Initialise(source); | ||
63 | } | ||
64 | |||
65 | public virtual void Initialise(IConfigSource source) | ||
66 | { | ||
67 | IConfig assetConfig = source.Configs["AuthenticationService"]; | ||
68 | if (assetConfig == null) | ||
69 | { | ||
70 | m_log.Error("[USER CONNECTOR]: AuthenticationService missing from OpanSim.ini"); | ||
71 | throw new Exception("Authentication connector init error"); | ||
72 | } | ||
73 | |||
74 | string serviceURI = assetConfig.GetString("AuthenticationServerURI", | ||
75 | String.Empty); | ||
76 | |||
77 | if (serviceURI == String.Empty) | ||
78 | { | ||
79 | m_log.Error("[USER CONNECTOR]: No Server URI named in section AuthenticationService"); | ||
80 | throw new Exception("Authentication connector init error"); | ||
81 | } | ||
82 | m_ServerURI = serviceURI; | ||
83 | } | ||
84 | |||
85 | public string Authenticate(UUID principalID, string password, int lifetime) | ||
86 | { | ||
87 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | ||
88 | sendData["LIFETIME"] = lifetime.ToString(); | ||
89 | sendData["PRINCIPAL"] = principalID.ToString(); | ||
90 | sendData["PASSWORD"] = password; | ||
91 | |||
92 | sendData["METHOD"] = "authenticate"; | ||
93 | |||
94 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
95 | m_ServerURI + "/auth/plain", | ||
96 | ServerUtils.BuildQueryString(sendData)); | ||
97 | |||
98 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( | ||
99 | reply); | ||
100 | |||
101 | if (replyData["Result"].ToString() != "Success") | ||
102 | return String.Empty; | ||
103 | |||
104 | return replyData["Token"].ToString(); | ||
105 | } | ||
106 | |||
107 | public bool Verify(UUID principalID, string token, int lifetime) | ||
108 | { | ||
109 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | ||
110 | sendData["LIFETIME"] = lifetime.ToString(); | ||
111 | sendData["PRINCIPAL"] = principalID.ToString(); | ||
112 | sendData["TOKEN"] = token; | ||
113 | |||
114 | sendData["METHOD"] = "verify"; | ||
115 | |||
116 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
117 | m_ServerURI + "/auth/plain", | ||
118 | ServerUtils.BuildQueryString(sendData)); | ||
119 | |||
120 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( | ||
121 | reply); | ||
122 | |||
123 | if (replyData["Result"].ToString() != "Success") | ||
124 | return false; | ||
125 | |||
126 | return true; | ||
127 | } | ||
128 | |||
129 | public bool Release(UUID principalID, string token) | ||
130 | { | ||
131 | Dictionary<string, string> sendData = new Dictionary<string, string>(); | ||
132 | sendData["PRINCIPAL"] = principalID.ToString(); | ||
133 | sendData["TOKEN"] = token; | ||
134 | |||
135 | sendData["METHOD"] = "release"; | ||
136 | |||
137 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
138 | m_ServerURI + "/auth/plain", | ||
139 | ServerUtils.BuildQueryString(sendData)); | ||
140 | |||
141 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( | ||
142 | reply); | ||
143 | |||
144 | if (replyData["Result"].ToString() != "Success") | ||
145 | return false; | ||
146 | |||
147 | return true; | ||
148 | } | ||
149 | } | ||
150 | } | ||