OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
AuthenticationServerPostHandler.cs
Go to the documentation of this file.
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 Nini.Config;
29 using log4net;
30 using System;
31 using System.Reflection;
32 using System.IO;
33 using System.Net;
34 using System.Text;
35 using System.Text.RegularExpressions;
36 using System.Xml;
37 using System.Xml.Serialization;
38 using System.Collections.Generic;
39 using OpenSim.Server.Base;
40 using OpenSim.Services.Interfaces;
41 using OpenSim.Framework;
42 using OpenSim.Framework.ServiceAuth;
43 using OpenSim.Framework.Servers.HttpServer;
44 using OpenMetaverse;
45 
46 namespace OpenSim.Server.Handlers.Authentication
47 {
49  {
50  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 
52  private IAuthenticationService m_AuthenticationService;
53 
54  private bool m_AllowGetAuthInfo = false;
55  private bool m_AllowSetAuthInfo = false;
56  private bool m_AllowSetPassword = false;
57 
59  this(service, null, null) {}
60 
62  base("POST", "/auth", auth)
63  {
64  m_AuthenticationService = service;
65 
66  if (config != null)
67  {
68  m_AllowGetAuthInfo = config.GetBoolean("AllowGetAuthInfo", m_AllowGetAuthInfo);
69  m_AllowSetAuthInfo = config.GetBoolean("AllowSetAuthInfo", m_AllowSetAuthInfo);
70  m_AllowSetPassword = config.GetBoolean("AllowSetPassword", m_AllowSetPassword);
71  }
72  }
73 
74  protected override byte[] ProcessRequest(string path, Stream request,
75  IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
76  {
77 // m_log.Error("[XXX]: Authenticating...");
78  string[] p = SplitParams(path);
79 
80  if (p.Length > 0)
81  {
82  switch (p[0])
83  {
84  case "plain":
85  StreamReader sr = new StreamReader(request);
86  string body = sr.ReadToEnd();
87  sr.Close();
88 
89  return DoPlainMethods(body);
90  case "crypt":
91  byte[] buffer = new byte[request.Length];
92  long length = request.Length;
93  if (length > 16384)
94  length = 16384;
95  request.Read(buffer, 0, (int)length);
96 
97  return DoEncryptedMethods(buffer);
98  }
99  }
100  return new byte[0];
101  }
102 
103  private byte[] DoPlainMethods(string body)
104  {
105  Dictionary<string, object> request =
106  ServerUtils.ParseQueryString(body);
107 
108  int lifetime = 30;
109 
110  if (request.ContainsKey("LIFETIME"))
111  {
112  lifetime = Convert.ToInt32(request["LIFETIME"].ToString());
113  if (lifetime > 30)
114  lifetime = 30;
115  }
116 
117  if (!request.ContainsKey("METHOD"))
118  return FailureResult();
119  if (!request.ContainsKey("PRINCIPAL"))
120  return FailureResult();
121 
122  string method = request["METHOD"].ToString();
123 
124  UUID principalID;
125  string token;
126 
127  if (!UUID.TryParse(request["PRINCIPAL"].ToString(), out principalID))
128  return FailureResult();
129 
130  switch (method)
131  {
132  case "authenticate":
133  if (!request.ContainsKey("PASSWORD"))
134  return FailureResult();
135 
136  token = m_AuthenticationService.Authenticate(principalID, request["PASSWORD"].ToString(), lifetime);
137 
138  if (token != String.Empty)
139  return SuccessResult(token);
140  return FailureResult();
141 
142  case "setpassword":
143  if (!m_AllowSetPassword)
144  return FailureResult();
145 
146  if (!request.ContainsKey("PASSWORD"))
147  return FailureResult();
148 
149  if (m_AuthenticationService.SetPassword(principalID, request["PASSWORD"].ToString()))
150  return SuccessResult();
151  else
152  return FailureResult();
153 
154  case "verify":
155  if (!request.ContainsKey("TOKEN"))
156  return FailureResult();
157 
158  if (m_AuthenticationService.Verify(principalID, request["TOKEN"].ToString(), lifetime))
159  return SuccessResult();
160 
161  return FailureResult();
162 
163  case "release":
164  if (!request.ContainsKey("TOKEN"))
165  return FailureResult();
166 
167  if (m_AuthenticationService.Release(principalID, request["TOKEN"].ToString()))
168  return SuccessResult();
169 
170  return FailureResult();
171 
172  case "getauthinfo":
173  if (m_AllowGetAuthInfo)
174  return GetAuthInfo(principalID);
175 
176  break;
177 
178  case "setauthinfo":
179  if (m_AllowSetAuthInfo)
180  return SetAuthInfo(principalID, request);
181 
182  break;
183  }
184 
185  return FailureResult();
186  }
187 
188  private byte[] DoEncryptedMethods(byte[] ciphertext)
189  {
190  return new byte[0];
191  }
192 
193  private byte[] SuccessResult()
194  {
195  XmlDocument doc = new XmlDocument();
196 
197  XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
198  "", "");
199 
200  doc.AppendChild(xmlnode);
201 
202  XmlElement rootElement = doc.CreateElement("", "ServerResponse",
203  "");
204 
205  doc.AppendChild(rootElement);
206 
207  XmlElement result = doc.CreateElement("", "Result", "");
208  result.AppendChild(doc.CreateTextNode("Success"));
209 
210  rootElement.AppendChild(result);
211 
212  return Util.DocToBytes(doc);
213  }
214 
215  byte[] GetAuthInfo(UUID principalID)
216  {
217  AuthInfo info = m_AuthenticationService.GetAuthInfo(principalID);
218 
219  if (info != null)
220  {
221  Dictionary<string, object> result = new Dictionary<string, object>();
222  result["result"] = info.ToKeyValuePairs();
223 
224  return ResultToBytes(result);
225  }
226  else
227  {
228  return FailureResult();
229  }
230  }
231 
232  byte[] SetAuthInfo(UUID principalID, Dictionary<string, object> request)
233  {
234  AuthInfo existingInfo = m_AuthenticationService.GetAuthInfo(principalID);
235 
236  if (existingInfo == null)
237  return FailureResult();
238 
239  if (request.ContainsKey("AccountType"))
240  existingInfo.AccountType = request["AccountType"].ToString();
241 
242  if (request.ContainsKey("PasswordHash"))
243  existingInfo.PasswordHash = request["PasswordHash"].ToString();
244 
245  if (request.ContainsKey("PasswordSalt"))
246  existingInfo.PasswordSalt = request["PasswordSalt"].ToString();
247 
248  if (request.ContainsKey("WebLoginKey"))
249  existingInfo.WebLoginKey = request["WebLoginKey"].ToString();
250 
251  if (!m_AuthenticationService.SetAuthInfo(existingInfo))
252  {
253  m_log.ErrorFormat(
254  "[AUTHENTICATION SERVER POST HANDLER]: Authentication info store failed for account {0} {1} {2}",
255  existingInfo.PrincipalID);
256 
257  return FailureResult();
258  }
259 
260  return SuccessResult();
261  }
262 
263  private byte[] FailureResult()
264  {
265  XmlDocument doc = new XmlDocument();
266 
267  XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
268  "", "");
269 
270  doc.AppendChild(xmlnode);
271 
272  XmlElement rootElement = doc.CreateElement("", "ServerResponse",
273  "");
274 
275  doc.AppendChild(rootElement);
276 
277  XmlElement result = doc.CreateElement("", "Result", "");
278  result.AppendChild(doc.CreateTextNode("Failure"));
279 
280  rootElement.AppendChild(result);
281 
282  return Util.DocToBytes(doc);
283  }
284 
285  private byte[] SuccessResult(string token)
286  {
287  XmlDocument doc = new XmlDocument();
288 
289  XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
290  "", "");
291 
292  doc.AppendChild(xmlnode);
293 
294  XmlElement rootElement = doc.CreateElement("", "ServerResponse",
295  "");
296 
297  doc.AppendChild(rootElement);
298 
299  XmlElement result = doc.CreateElement("", "Result", "");
300  result.AppendChild(doc.CreateTextNode("Success"));
301 
302  rootElement.AppendChild(result);
303 
304  XmlElement t = doc.CreateElement("", "Token", "");
305  t.AppendChild(doc.CreateTextNode(token));
306 
307  rootElement.AppendChild(t);
308 
309  return Util.DocToBytes(doc);
310  }
311 
312  private byte[] ResultToBytes(Dictionary<string, object> result)
313  {
314  string xmlString = ServerUtils.BuildXmlResponse(result);
315  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
316  }
317  }
318 }
AuthenticationServerPostHandler(IAuthenticationService service, IConfig config, IServiceAuth auth)
override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
AuthenticationServerPostHandler(IAuthenticationService service)