From 5f9a193b439d7939da4491005cc17e4a4b3bb647 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Sep 2009 16:04:36 +0100 Subject: [PATCH 1/6] Reorder prebuild and remove one unneeded backward reference --- prebuild.xml | 58 ++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/prebuild.xml b/prebuild.xml index fdd2c17d90..ecb0b62b6b 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -371,7 +371,6 @@ - @@ -1105,6 +1104,35 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + @@ -1382,34 +1410,6 @@ - - - - ../../../bin/ - - - - - ../../../bin/ - - - - ../../../bin/ - - - - - - - - - - - - - - - From 97ebdd4607a3d6aa312adb07292b13ae2b120929 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Sep 2009 16:57:15 +0100 Subject: [PATCH 2/6] Adding Xml serialization of Dictionary where object is either another Dictionary or a value that is convertible to a string. --- OpenSim/Server/Base/ServerUtils.cs | 72 ++++++++++++++++++++++++++++++ prebuild.xml | 1 + 2 files changed, 73 insertions(+) diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index 0a36bbee14..ae7ec0f44c 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -183,5 +183,77 @@ namespace OpenSim.Server.Base return result; } + + public static string BuildQueryString(Dictionary data) + { + string qstring = String.Empty; + + foreach(KeyValuePair kvp in data) + { + string part; + if (kvp.Value != String.Empty) + { + part = System.Web.HttpUtility.UrlEncode(kvp.Key) + + "=" + System.Web.HttpUtility.UrlEncode(kvp.Value); + } + else + { + part = System.Web.HttpUtility.UrlEncode(kvp.Key); + } + + if (qstring != String.Empty) + qstring += "&"; + + qstring += part; + } + + return qstring; + } + + public static string BuildXmlResponse(Dictionary data) + { + XmlDocument doc = new XmlDocument(); + + XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, + "", ""); + + doc.AppendChild(xmlnode); + + XmlElement rootElement = doc.CreateElement("", "ServerResponse", + ""); + + doc.AppendChild(rootElement); + + BuildXmlData(rootElement, data); + + return doc.InnerXml; + } + + private static void BuildXmlData(XmlElement parent, Dictionary data) + { + foreach (KeyValuePair kvp in data) + { + XmlElement elem = parent.OwnerDocument.CreateElement("", + kvp.Key, ""); + + if (kvp.Value is Dictionary) + { + XmlAttribute type = parent.OwnerDocument.CreateAttribute("", + "type", ""); + type.Value = "List"; + + elem.Attributes.Append(type); + + BuildXmlData(elem, (Dictionary)kvp.Value); + } + else + { + elem.AppendChild(parent.OwnerDocument.CreateTextNode( + kvp.Value.ToString())); + } + + parent.AppendChild(elem); + } + } } } diff --git a/prebuild.xml b/prebuild.xml index ecb0b62b6b..2265b099e3 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1213,6 +1213,7 @@ + From 2d9d25b367cd6a33747d2b647abfe57ede97e805 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Sep 2009 17:33:57 +0100 Subject: [PATCH 3/6] Add the skeleton of the authentication connector and the forms data requester --- .../SynchronousRestFormsRequester.cs | 95 ++++++++++++++++++ .../AuthenticationServiceConnector.cs | 99 +++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs create mode 100644 OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs new file mode 100644 index 0000000000..0f0c79020a --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -0,0 +1,95 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Net; +using System.Text; +using System.Xml; +using System.Xml.Serialization; + +namespace OpenSim.Framework.Servers.HttpServer +{ + public class SynchronousRestFormsRequester + { + /// + /// Perform a synchronous REST request. + /// + /// + /// + /// + /// + /// + /// Thrown if we encounter a network issue while posting + /// the request. You'll want to make sure you deal with this as they're not uncommon + public static string MakeRequest(string verb, string requestUrl, string obj) + { + WebRequest request = WebRequest.Create(requestUrl); + request.Method = verb; + + if ((verb == "POST") || (verb == "PUT")) + { + request.ContentType = "text/www-form-urlencoded"; + + MemoryStream buffer = new MemoryStream(); + + using (StreamWriter writer = new StreamWriter(buffer)) + { + writer.WriteLine(obj); + writer.Flush(); + } + + int length = (int) buffer.Length; + request.ContentLength = length; + + Stream requestStream = request.GetRequestStream(); + requestStream.Write(buffer.ToArray(), 0, length); + } + + string respstring = String.Empty; + + try + { + using (WebResponse resp = request.GetResponse()) + { + if (resp.ContentLength > 0) + { + using (StreamReader reader = new StreamReader(resp.GetResponseStream())) + { + respstring = reader.ReadToEnd(); + } + } + } + } + catch (System.InvalidOperationException) + { + // This is what happens when there is invalid XML + } + return respstring; + } + } +} diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs new file mode 100644 index 0000000000..053d27c8da --- /dev/null +++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs @@ -0,0 +1,99 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class AuthenticationServicesConnector : IAuthenticationService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public AuthenticationServicesConnector() + { + } + + public AuthenticationServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/'); + } + + public AuthenticationServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig assetConfig = source.Configs["AuthenticationService"]; + if (assetConfig == null) + { + m_log.Error("[USER CONNECTOR]: AuthenticationService missing from OpanSim.ini"); + throw new Exception("Authentication connector init error"); + } + + string serviceURI = assetConfig.GetString("AuthenticationServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[USER CONNECTOR]: No Server URI named in section AuthenticationService"); + throw new Exception("Authentication connector init error"); + } + m_ServerURI = serviceURI; + } + + public string Authenticate(UUID principalID, string password, int lifetime) + { + return String.Empty; + } + + public bool Verify(UUID principalID, string token, int lifetime) + { + return false; + } + + public bool Release(UUID principalID, string token) + { + return false; + } + } +} From 2f624800d37bae36cecf1bff191b646d59d86746 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Sep 2009 18:06:25 +0100 Subject: [PATCH 4/6] Adding the deserializer for server form/xml replies --- OpenSim/Server/Base/ServerUtils.cs | 42 +++++++++++++++++++ .../AuthenticationServerPostHandler.cs | 6 +-- .../AuthenticationServiceConnector.cs | 12 ++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index ae7ec0f44c..6c2b3ed031 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -255,5 +255,47 @@ namespace OpenSim.Server.Base parent.AppendChild(elem); } } + + public static Dictionary ParseXmlResponse(string data) + { + Dictionary ret = new Dictionary(); + + XmlDocument doc = new XmlDocument(); + + doc.LoadXml(data); + + XmlNodeList rootL = doc.GetElementsByTagName("ServerResponse"); + + if (rootL.Count != 1) + return ret; + + XmlNode rootNode = rootL[0]; + + ret = ParseElement(rootNode); + + return ret; + } + + private static Dictionary ParseElement(XmlNode element) + { + Dictionary ret = new Dictionary(); + + XmlNodeList partL = element.ChildNodes; + + foreach (XmlNode part in partL) + { + XmlNode type = part.Attributes.GetNamedItem("Type"); + if (type == null || type.Value != "List") + { + ret[part.Name] = part.InnerText; + } + else + { + ret[part.Name] = ParseElement(part); + } + } + + return ret; + } } } diff --git a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs index 6cf7d56ec2..490a13a30f 100644 --- a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs @@ -157,7 +157,7 @@ namespace OpenSim.Server.Handlers.Authentication doc.AppendChild(xmlnode); - XmlElement rootElement = doc.CreateElement("", "Authentication", + XmlElement rootElement = doc.CreateElement("", "ServerResponse", ""); doc.AppendChild(rootElement); @@ -179,7 +179,7 @@ namespace OpenSim.Server.Handlers.Authentication doc.AppendChild(xmlnode); - XmlElement rootElement = doc.CreateElement("", "Authentication", + XmlElement rootElement = doc.CreateElement("", "ServerResponse", ""); doc.AppendChild(rootElement); @@ -201,7 +201,7 @@ namespace OpenSim.Server.Handlers.Authentication doc.AppendChild(xmlnode); - XmlElement rootElement = doc.CreateElement("", "Authentication", + XmlElement rootElement = doc.CreateElement("", "ServerResponse", ""); doc.AppendChild(rootElement); diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs index 053d27c8da..35f96a19a3 100644 --- a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs @@ -35,6 +35,7 @@ using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; using OpenMetaverse; namespace OpenSim.Services.Connectors @@ -83,6 +84,17 @@ namespace OpenSim.Services.Connectors public string Authenticate(UUID principalID, string password, int lifetime) { + Dictionary sendData = new Dictionary(); + sendData["LIFETIME"] = lifetime.ToString(); + sendData["PRINCIPAL"] = principalID.ToString(); + sendData["PASSWORD"] = password; + + sendData["METHOD"] = "authenticate"; + + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/auth/plain", + ServerUtils.BuildQueryString(sendData)); + return String.Empty; } From 0c364ee2853f5d33df67e4a340734dfe7c6c2398 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Sep 2009 18:14:22 +0100 Subject: [PATCH 5/6] Complete the first authenticator method --- .../Authentication/AuthenticationServiceConnector.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs index 35f96a19a3..258b9b14d0 100644 --- a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs @@ -95,7 +95,13 @@ namespace OpenSim.Services.Connectors m_ServerURI + "/auth/plain", ServerUtils.BuildQueryString(sendData)); - return String.Empty; + Dictionary replyData = ServerUtils.ParseXmlResponse( + reply); + + if (replyData["Result"].ToString() != "Success") + return String.Empty; + + return replyData["Token"].ToString(); } public bool Verify(UUID principalID, string token, int lifetime) From f6410882a5bb3ac53e7a0434c3dcc4ecd1de8457 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Sep 2009 18:18:47 +0100 Subject: [PATCH 6/6] Finish the (untested) authentication connector --- .../AuthenticationServiceConnector.cs | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs index 258b9b14d0..50e817e064 100644 --- a/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServiceConnector.cs @@ -106,12 +106,45 @@ namespace OpenSim.Services.Connectors public bool Verify(UUID principalID, string token, int lifetime) { - return false; + Dictionary sendData = new Dictionary(); + sendData["LIFETIME"] = lifetime.ToString(); + sendData["PRINCIPAL"] = principalID.ToString(); + sendData["TOKEN"] = token; + + sendData["METHOD"] = "verify"; + + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/auth/plain", + ServerUtils.BuildQueryString(sendData)); + + Dictionary replyData = ServerUtils.ParseXmlResponse( + reply); + + if (replyData["Result"].ToString() != "Success") + return false; + + return true; } public bool Release(UUID principalID, string token) { - return false; + Dictionary sendData = new Dictionary(); + sendData["PRINCIPAL"] = principalID.ToString(); + sendData["TOKEN"] = token; + + sendData["METHOD"] = "release"; + + string reply = SynchronousRestFormsRequester.MakeRequest("POST", + m_ServerURI + "/auth/plain", + ServerUtils.BuildQueryString(sendData)); + + Dictionary replyData = ServerUtils.ParseXmlResponse( + reply); + + if (replyData["Result"].ToString() != "Success") + return false; + + return true; } } }