aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Communications')
-rw-r--r--OpenSim/Framework/Communications/Clients/AuthClient.cs151
-rw-r--r--OpenSim/Framework/Communications/Clients/GridClient.cs389
-rw-r--r--OpenSim/Framework/Communications/Clients/InventoryClient.cs79
-rw-r--r--OpenSim/Framework/Communications/Clients/RegionClient.cs755
-rw-r--r--OpenSim/Framework/Communications/Services/HGLoginAuthService.cs339
-rw-r--r--OpenSim/Framework/Communications/Services/LoginResponse.cs823
-rw-r--r--OpenSim/Framework/Communications/Services/LoginService.cs1243
7 files changed, 0 insertions, 3779 deletions
diff --git a/OpenSim/Framework/Communications/Clients/AuthClient.cs b/OpenSim/Framework/Communications/Clients/AuthClient.cs
deleted file mode 100644
index adae637..0000000
--- a/OpenSim/Framework/Communications/Clients/AuthClient.cs
+++ /dev/null
@@ -1,151 +0,0 @@
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using Nwc.XmlRpc;
32using OpenMetaverse;
33
34namespace OpenSim.Framework.Communications.Clients
35{
36 public class AuthClient
37 {
38 public static string GetNewKey(string authurl, UUID userID, UUID authToken)
39 {
40 //Hashtable keyParams = new Hashtable();
41 //keyParams["user_id"] = userID;
42 //keyParams["auth_token"] = authKey;
43
44 List<string> SendParams = new List<string>();
45 SendParams.Add(userID.ToString());
46 SendParams.Add(authToken.ToString());
47
48 XmlRpcRequest request = new XmlRpcRequest("hg_new_auth_key", SendParams);
49 XmlRpcResponse reply;
50 try
51 {
52 reply = request.Send(authurl, 6000);
53 }
54 catch (Exception e)
55 {
56 System.Console.WriteLine("[HGrid]: Failed to get new key. Reason: " + e.Message);
57 return string.Empty;
58 }
59
60 if (!reply.IsFault)
61 {
62 string newKey = string.Empty;
63 if (reply.Value != null)
64 newKey = (string)reply.Value;
65
66 return newKey;
67 }
68 else
69 {
70 System.Console.WriteLine("[HGrid]: XmlRpc request to get auth key failed with message {0}" + reply.FaultString + ", code " + reply.FaultCode);
71 return string.Empty;
72 }
73
74 }
75
76 public static bool VerifyKey(string authurl, UUID userID, string authKey)
77 {
78 List<string> SendParams = new List<string>();
79 SendParams.Add(userID.ToString());
80 SendParams.Add(authKey);
81
82 System.Console.WriteLine("[HGrid]: Verifying user key with authority " + authurl);
83
84 XmlRpcRequest request = new XmlRpcRequest("hg_verify_auth_key", SendParams);
85 XmlRpcResponse reply;
86 try
87 {
88 reply = request.Send(authurl, 10000);
89 }
90 catch (Exception e)
91 {
92 System.Console.WriteLine("[HGrid]: Failed to verify key. Reason: " + e.Message);
93 return false;
94 }
95
96 if (reply != null)
97 {
98 if (!reply.IsFault)
99 {
100 bool success = false;
101 if (reply.Value != null)
102 success = (bool)reply.Value;
103
104 return success;
105 }
106 else
107 {
108 System.Console.WriteLine("[HGrid]: XmlRpc request to verify key failed with message {0}" + reply.FaultString + ", code " + reply.FaultCode);
109 return false;
110 }
111 }
112 else
113 {
114 System.Console.WriteLine("[HGrid]: XmlRpc request to verify key returned null reply");
115 return false;
116 }
117 }
118
119 public static bool VerifySession(string authurl, UUID userID, UUID sessionID)
120 {
121 Hashtable requestData = new Hashtable();
122 requestData["avatar_uuid"] = userID.ToString();
123 requestData["session_id"] = sessionID.ToString();
124 ArrayList SendParams = new ArrayList();
125 SendParams.Add(requestData);
126 XmlRpcRequest UserReq = new XmlRpcRequest("check_auth_session", SendParams);
127 XmlRpcResponse UserResp = null;
128 try
129 {
130 UserResp = UserReq.Send(authurl, 3000);
131 }
132 catch (Exception e)
133 {
134 System.Console.WriteLine("[Session Auth]: VerifySession XmlRpc: " + e.Message);
135 return false;
136 }
137
138 Hashtable responseData = (Hashtable)UserResp.Value;
139 if (responseData != null && responseData.ContainsKey("auth_session") && responseData["auth_session"] != null && responseData["auth_session"].ToString() == "TRUE")
140 {
141 //System.Console.WriteLine("[Authorization]: userserver reported authorized session for user " + userID);
142 return true;
143 }
144 else
145 {
146 //System.Console.WriteLine("[Authorization]: userserver reported unauthorized session for user " + userID);
147 return false;
148 }
149 }
150 }
151}
diff --git a/OpenSim/Framework/Communications/Clients/GridClient.cs b/OpenSim/Framework/Communications/Clients/GridClient.cs
deleted file mode 100644
index 0198d75..0000000
--- a/OpenSim/Framework/Communications/Clients/GridClient.cs
+++ /dev/null
@@ -1,389 +0,0 @@
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33
34using log4net;
35using OpenMetaverse;
36using Nwc.XmlRpc;
37
38namespace OpenSim.Framework.Communications.Clients
39{
40 public class GridClient
41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 public bool RegisterRegion(
45 string gridServerURL, string sendKey, string receiveKey, RegionInfo regionInfo, out bool forcefulBanLines)
46 {
47 m_log.InfoFormat(
48 "[GRID CLIENT]: Registering region {0} with grid at {1}", regionInfo.RegionName, gridServerURL);
49
50 forcefulBanLines = true;
51
52 Hashtable GridParams = new Hashtable();
53 // Login / Authentication
54
55 GridParams["authkey"] = sendKey;
56 GridParams["recvkey"] = receiveKey;
57 GridParams["UUID"] = regionInfo.RegionID.ToString();
58 GridParams["sim_ip"] = regionInfo.ExternalHostName;
59 GridParams["sim_port"] = regionInfo.InternalEndPoint.Port.ToString();
60 GridParams["region_locx"] = regionInfo.RegionLocX.ToString();
61 GridParams["region_locy"] = regionInfo.RegionLocY.ToString();
62 GridParams["sim_name"] = regionInfo.RegionName;
63 GridParams["http_port"] = regionInfo.HttpPort.ToString();
64 GridParams["remoting_port"] = ConfigSettings.DefaultRegionRemotingPort.ToString();
65 GridParams["map-image-id"] = regionInfo.RegionSettings.TerrainImageID.ToString();
66 GridParams["originUUID"] = regionInfo.originRegionID.ToString();
67 GridParams["server_uri"] = regionInfo.ServerURI;
68 GridParams["region_secret"] = regionInfo.regionSecret;
69 GridParams["major_interface_version"] = VersionInfo.MajorInterfaceVersion.ToString();
70
71 GridParams["master_avatar_uuid"] = regionInfo.EstateSettings.EstateOwner.ToString();
72
73 // Package into an XMLRPC Request
74 ArrayList SendParams = new ArrayList();
75 SendParams.Add(GridParams);
76
77 // Send Request
78 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_login", SendParams);
79 XmlRpcResponse GridResp;
80
81 try
82 {
83 // The timeout should always be significantly larger than the timeout for the grid server to request
84 // the initial status of the region before confirming registration.
85 GridResp = GridReq.Send(gridServerURL, 90000);
86 }
87 catch (Exception e)
88 {
89 Exception e2
90 = new Exception(
91 String.Format(
92 "Unable to register region with grid at {0}. Grid service not running?",
93 gridServerURL),
94 e);
95
96 throw e2;
97 }
98
99 Hashtable GridRespData = (Hashtable)GridResp.Value;
100 // Hashtable griddatahash = GridRespData;
101
102 // Process Response
103 if (GridRespData.ContainsKey("error"))
104 {
105 string errorstring = (string)GridRespData["error"];
106
107 Exception e = new Exception(
108 String.Format("Unable to connect to grid at {0}: {1}", gridServerURL, errorstring));
109
110 throw e;
111 }
112 else
113 {
114 // m_knownRegions = RequestNeighbours(regionInfo.RegionLocX, regionInfo.RegionLocY);
115 if (GridRespData.ContainsKey("allow_forceful_banlines"))
116 {
117 if ((string)GridRespData["allow_forceful_banlines"] != "TRUE")
118 {
119 forcefulBanLines = false;
120 }
121 }
122
123 }
124 return true;
125 }
126
127 public bool DeregisterRegion(string gridServerURL, string sendKey, string receiveKey, RegionInfo regionInfo, out string errorMsg)
128 {
129 errorMsg = "";
130 Hashtable GridParams = new Hashtable();
131
132 GridParams["UUID"] = regionInfo.RegionID.ToString();
133
134 // Package into an XMLRPC Request
135 ArrayList SendParams = new ArrayList();
136 SendParams.Add(GridParams);
137
138 // Send Request
139 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_after_region_moved", SendParams);
140 XmlRpcResponse GridResp = null;
141
142 try
143 {
144 GridResp = GridReq.Send(gridServerURL, 10000);
145 }
146 catch (Exception e)
147 {
148 Exception e2
149 = new Exception(
150 String.Format(
151 "Unable to deregister region with grid at {0}. Grid service not running?",
152 gridServerURL),
153 e);
154
155 throw e2;
156 }
157
158 Hashtable GridRespData = (Hashtable)GridResp.Value;
159
160 // Hashtable griddatahash = GridRespData;
161
162 // Process Response
163 if (GridRespData != null && GridRespData.ContainsKey("error"))
164 {
165 errorMsg = (string)GridRespData["error"];
166 return false;
167 }
168
169 return true;
170 }
171
172 public bool RequestNeighborInfo(
173 string gridServerURL, string sendKey, string receiveKey, UUID regionUUID,
174 out RegionInfo regionInfo, out string errorMsg)
175 {
176 // didn't find it so far, we have to go the long way
177 regionInfo = null;
178 errorMsg = string.Empty;
179 Hashtable requestData = new Hashtable();
180 requestData["region_UUID"] = regionUUID.ToString();
181 requestData["authkey"] = sendKey;
182 ArrayList SendParams = new ArrayList();
183 SendParams.Add(requestData);
184 XmlRpcRequest gridReq = new XmlRpcRequest("simulator_data_request", SendParams);
185 XmlRpcResponse gridResp = null;
186
187 try
188 {
189 gridResp = gridReq.Send(gridServerURL, 3000);
190 }
191 catch (Exception e)
192 {
193 errorMsg = e.Message;
194 return false;
195 }
196
197 Hashtable responseData = (Hashtable)gridResp.Value;
198
199 if (responseData.ContainsKey("error"))
200 {
201 errorMsg = (string)responseData["error"];
202 return false; ;
203 }
204
205 regionInfo = BuildRegionInfo(responseData, String.Empty);
206
207 return true;
208 }
209
210 public bool RequestNeighborInfo(
211 string gridServerURL, string sendKey, string receiveKey, ulong regionHandle,
212 out RegionInfo regionInfo, out string errorMsg)
213 {
214 // didn't find it so far, we have to go the long way
215 regionInfo = null;
216 errorMsg = string.Empty;
217
218 try
219 {
220 Hashtable requestData = new Hashtable();
221 requestData["region_handle"] = regionHandle.ToString();
222 requestData["authkey"] = sendKey;
223 ArrayList SendParams = new ArrayList();
224 SendParams.Add(requestData);
225 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams);
226 XmlRpcResponse GridResp = GridReq.Send(gridServerURL, 3000);
227
228 Hashtable responseData = (Hashtable)GridResp.Value;
229
230 if (responseData.ContainsKey("error"))
231 {
232 errorMsg = (string)responseData["error"];
233 return false;
234 }
235
236 uint regX = Convert.ToUInt32((string)responseData["region_locx"]);
237 uint regY = Convert.ToUInt32((string)responseData["region_locy"]);
238 string externalHostName = (string)responseData["sim_ip"];
239 uint simPort = Convert.ToUInt32(responseData["sim_port"]);
240 string regionName = (string)responseData["region_name"];
241 UUID regionID = new UUID((string)responseData["region_UUID"]);
242 uint remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]);
243
244 uint httpPort = 9000;
245 if (responseData.ContainsKey("http_port"))
246 {
247 httpPort = Convert.ToUInt32((string)responseData["http_port"]);
248 }
249
250 // Ok, so this is definitively the wrong place to do this, way too hard coded, but it doesn't seem we GET this info?
251
252 string simURI = "http://" + externalHostName + ":" + simPort;
253
254 // string externalUri = (string) responseData["sim_uri"];
255
256 //IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int) port);
257 regionInfo = RegionInfo.Create(regionID, regionName, regX, regY, externalHostName, httpPort, simPort, remotingPort, simURI);
258 }
259 catch (Exception e)
260 {
261 errorMsg = e.Message;
262 return false;
263 }
264
265 return true;
266 }
267
268 public bool RequestClosestRegion(
269 string gridServerURL, string sendKey, string receiveKey, string regionName,
270 out RegionInfo regionInfo, out string errorMsg)
271 {
272 regionInfo = null;
273 errorMsg = string.Empty;
274 try
275 {
276 Hashtable requestData = new Hashtable();
277 requestData["region_name_search"] = regionName;
278 requestData["authkey"] = sendKey;
279 ArrayList SendParams = new ArrayList();
280 SendParams.Add(requestData);
281 XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams);
282 XmlRpcResponse GridResp = GridReq.Send(gridServerURL, 3000);
283
284 Hashtable responseData = (Hashtable)GridResp.Value;
285
286 if (responseData.ContainsKey("error"))
287 {
288 errorMsg = (string)responseData["error"];
289 return false;
290 }
291
292 regionInfo = BuildRegionInfo(responseData, "");
293
294 }
295 catch (Exception e)
296 {
297 errorMsg = e.Message;
298 return false;
299 }
300 return true;
301 }
302
303 /// <summary>
304 /// Performs a XML-RPC query against the grid server returning mapblock information in the specified coordinates
305 /// </summary>
306 /// <remarks>REDUNDANT - OGS1 is to be phased out in favour of OGS2</remarks>
307 /// <param name="minX">Minimum X value</param>
308 /// <param name="minY">Minimum Y value</param>
309 /// <param name="maxX">Maximum X value</param>
310 /// <param name="maxY">Maximum Y value</param>
311 /// <returns>Hashtable of hashtables containing map data elements</returns>
312 public bool MapBlockQuery(
313 string gridServerURL, int minX, int minY, int maxX, int maxY, out Hashtable respData, out string errorMsg)
314 {
315 respData = new Hashtable();
316 errorMsg = string.Empty;
317
318 Hashtable param = new Hashtable();
319 param["xmin"] = minX;
320 param["ymin"] = minY;
321 param["xmax"] = maxX;
322 param["ymax"] = maxY;
323 IList parameters = new ArrayList();
324 parameters.Add(param);
325
326 try
327 {
328 XmlRpcRequest req = new XmlRpcRequest("map_block", parameters);
329 XmlRpcResponse resp = req.Send(gridServerURL, 10000);
330 respData = (Hashtable)resp.Value;
331 return true;
332 }
333 catch (Exception e)
334 {
335 errorMsg = e.Message;
336 return false;
337 }
338 }
339
340 public bool SearchRegionByName(string gridServerURL, IList parameters, out Hashtable respData, out string errorMsg)
341 {
342 respData = null;
343 errorMsg = string.Empty;
344 try
345 {
346 XmlRpcRequest request = new XmlRpcRequest("search_for_region_by_name", parameters);
347 XmlRpcResponse resp = request.Send(gridServerURL, 10000);
348 respData = (Hashtable)resp.Value;
349 if (respData != null && respData.Contains("faultCode"))
350 {
351 errorMsg = (string)respData["faultString"];
352 return false;
353 }
354
355 return true;
356 }
357 catch (Exception e)
358 {
359 errorMsg = e.Message;
360 return false;
361 }
362 }
363
364 public RegionInfo BuildRegionInfo(Hashtable responseData, string prefix)
365 {
366 uint regX = Convert.ToUInt32((string)responseData[prefix + "region_locx"]);
367 uint regY = Convert.ToUInt32((string)responseData[prefix + "region_locy"]);
368 string internalIpStr = (string)responseData[prefix + "sim_ip"];
369 uint port = Convert.ToUInt32(responseData[prefix + "sim_port"]);
370
371 IPEndPoint neighbourInternalEndPoint = new IPEndPoint(Util.GetHostFromDNS(internalIpStr), (int)port);
372
373 RegionInfo regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr);
374 regionInfo.RemotingPort = Convert.ToUInt32((string)responseData[prefix + "remoting_port"]);
375 regionInfo.RemotingAddress = internalIpStr;
376
377 if (responseData.ContainsKey(prefix + "http_port"))
378 {
379 regionInfo.HttpPort = Convert.ToUInt32((string)responseData[prefix + "http_port"]);
380 }
381
382 regionInfo.RegionID = new UUID((string)responseData[prefix + "region_UUID"]);
383 regionInfo.RegionName = (string)responseData[prefix + "region_name"];
384
385 regionInfo.RegionSettings.TerrainImageID = new UUID((string)responseData[prefix + "map_UUID"]);
386 return regionInfo;
387 }
388 }
389}
diff --git a/OpenSim/Framework/Communications/Clients/InventoryClient.cs b/OpenSim/Framework/Communications/Clients/InventoryClient.cs
deleted file mode 100644
index e4f5e2a..0000000
--- a/OpenSim/Framework/Communications/Clients/InventoryClient.cs
+++ /dev/null
@@ -1,79 +0,0 @@
1/**
2 * Copyright (c), Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using OpenSim.Framework.Servers;
31using OpenSim.Framework.Servers.HttpServer;
32
33using OpenMetaverse;
34
35namespace OpenSim.Framework.Communications.Clients
36{
37 public class InventoryClient
38 {
39 private string ServerURL;
40
41 public InventoryClient(string url)
42 {
43 ServerURL = url;
44 }
45
46 public void GetInventoryItemAsync(InventoryItemBase item, ReturnResponse<InventoryItemBase> callBack)
47 {
48 System.Console.WriteLine("[HGrid] GetInventory from " + ServerURL);
49 try
50 {
51 RestSessionObjectPosterResponse<InventoryItemBase, InventoryItemBase> requester
52 = new RestSessionObjectPosterResponse<InventoryItemBase, InventoryItemBase>();
53 requester.ResponseCallback = callBack;
54
55 requester.BeginPostObject(ServerURL + "/GetItem/", item, string.Empty, string.Empty);
56 }
57 catch (Exception e)
58 {
59 System.Console.WriteLine("[HGrid]: Exception posting to inventory: " + e);
60 }
61 }
62
63 public InventoryItemBase GetInventoryItem(InventoryItemBase item)
64 {
65 System.Console.WriteLine("[HGrid] GetInventory " + item.ID + " from " + ServerURL);
66 try
67 {
68 item = SynchronousRestSessionObjectPoster<Guid, InventoryItemBase>.BeginPostObject("POST", ServerURL + "/GetItem/", item.ID.Guid, "", "");
69 return item;
70 }
71 catch (Exception e)
72 {
73 System.Console.WriteLine("[HGrid]: Exception posting to inventory: " + e);
74 }
75 return null;
76 }
77
78 }
79}
diff --git a/OpenSim/Framework/Communications/Clients/RegionClient.cs b/OpenSim/Framework/Communications/Clients/RegionClient.cs
deleted file mode 100644
index ee7dec8..0000000
--- a/OpenSim/Framework/Communications/Clients/RegionClient.cs
+++ /dev/null
@@ -1,755 +0,0 @@
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
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using System.Text;
34
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37
38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39
40using log4net;
41
42namespace OpenSim.Framework.Communications.Clients
43{
44 public class RegionClient
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 public bool DoCreateChildAgentCall(GridRegion region, AgentCircuitData aCircuit, string authKey, uint teleportFlags, out string reason)
49 {
50 reason = String.Empty;
51
52 // Eventually, we want to use a caps url instead of the agentID
53 string uri = string.Empty;
54 try
55 {
56 uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + aCircuit.AgentID + "/";
57 }
58 catch (Exception e)
59 {
60 m_log.Debug("[REST COMMS]: Unable to resolve external endpoint on agent create. Reason: " + e.Message);
61 reason = e.Message;
62 return false;
63 }
64
65 //Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri);
66
67 HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri);
68 AgentCreateRequest.Method = "POST";
69 AgentCreateRequest.ContentType = "application/json";
70 AgentCreateRequest.Timeout = 10000;
71 //AgentCreateRequest.KeepAlive = false;
72 AgentCreateRequest.Headers.Add("Authorization", authKey);
73
74 // Fill it in
75 OSDMap args = null;
76 try
77 {
78 args = aCircuit.PackAgentCircuitData();
79 }
80 catch (Exception e)
81 {
82 m_log.Debug("[REST COMMS]: PackAgentCircuitData failed with exception: " + e.Message);
83 }
84 // Add the regionhandle of the destination region
85 ulong regionHandle = GetRegionHandle(region.RegionHandle);
86 args["destination_handle"] = OSD.FromString(regionHandle.ToString());
87 args["teleport_flags"] = OSD.FromString(teleportFlags.ToString());
88
89 string strBuffer = "";
90 byte[] buffer = new byte[1];
91 try
92 {
93 strBuffer = OSDParser.SerializeJsonString(args);
94 Encoding str = Util.UTF8;
95 buffer = str.GetBytes(strBuffer);
96
97 }
98 catch (Exception e)
99 {
100 m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
101 // ignore. buffer will be empty, caller should check.
102 }
103
104 Stream os = null;
105 try
106 { // send the Post
107 AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send
108 os = AgentCreateRequest.GetRequestStream();
109 os.Write(buffer, 0, strBuffer.Length); //Send it
110 //m_log.InfoFormat("[REST COMMS]: Posted CreateChildAgent request to remote sim {0}", uri);
111 }
112 //catch (WebException ex)
113 catch
114 {
115 //m_log.InfoFormat("[REST COMMS]: Bad send on ChildAgentUpdate {0}", ex.Message);
116 reason = "cannot contact remote region";
117 return false;
118 }
119 finally
120 {
121 if (os != null)
122 os.Close();
123 }
124
125 // Let's wait for the response
126 //m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall");
127
128 WebResponse webResponse = null;
129 StreamReader sr = null;
130 try
131 {
132 webResponse = AgentCreateRequest.GetResponse();
133 if (webResponse == null)
134 {
135 m_log.Info("[REST COMMS]: Null reply on DoCreateChildAgentCall post");
136 }
137 else
138 {
139
140 sr = new StreamReader(webResponse.GetResponseStream());
141 string response = sr.ReadToEnd().Trim();
142 m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", response);
143
144 if (!String.IsNullOrEmpty(response))
145 {
146 try
147 {
148 // we assume we got an OSDMap back
149 OSDMap r = GetOSDMap(response);
150 bool success = r["success"].AsBoolean();
151 reason = r["reason"].AsString();
152 return success;
153 }
154 catch (NullReferenceException e)
155 {
156 m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
157
158 // check for old style response
159 if (response.ToLower().StartsWith("true"))
160 return true;
161
162 return false;
163 }
164 }
165 }
166 }
167 catch (WebException ex)
168 {
169 m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
170 // ignore, really
171 }
172 finally
173 {
174 if (sr != null)
175 sr.Close();
176 }
177
178 return true;
179
180 }
181
182 public bool DoChildAgentUpdateCall(GridRegion region, IAgentData cAgentData)
183 {
184 // Eventually, we want to use a caps url instead of the agentID
185 string uri = string.Empty;
186 try
187 {
188 uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + cAgentData.AgentID + "/";
189 }
190 catch (Exception e)
191 {
192 m_log.Debug("[REST COMMS]: Unable to resolve external endpoint on agent update. Reason: " + e.Message);
193 return false;
194 }
195 //Console.WriteLine(" >>> DoChildAgentUpdateCall <<< " + uri);
196
197 HttpWebRequest ChildUpdateRequest = (HttpWebRequest)WebRequest.Create(uri);
198 ChildUpdateRequest.Method = "PUT";
199 ChildUpdateRequest.ContentType = "application/json";
200 ChildUpdateRequest.Timeout = 10000;
201 //ChildUpdateRequest.KeepAlive = false;
202
203 // Fill it in
204 OSDMap args = null;
205 try
206 {
207 args = cAgentData.Pack();
208 }
209 catch (Exception e)
210 {
211 m_log.Debug("[REST COMMS]: PackUpdateMessage failed with exception: " + e.Message);
212 }
213 // Add the regionhandle of the destination region
214 ulong regionHandle = GetRegionHandle(region.RegionHandle);
215 args["destination_handle"] = OSD.FromString(regionHandle.ToString());
216
217 string strBuffer = "";
218 byte[] buffer = new byte[1];
219 try
220 {
221 strBuffer = OSDParser.SerializeJsonString(args);
222 Encoding str = Util.UTF8;
223 buffer = str.GetBytes(strBuffer);
224
225 }
226 catch (Exception e)
227 {
228 m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of ChildUpdate: {0}", e.Message);
229 // ignore. buffer will be empty, caller should check.
230 }
231
232 Stream os = null;
233 try
234 { // send the Post
235 ChildUpdateRequest.ContentLength = buffer.Length; //Count bytes to send
236 os = ChildUpdateRequest.GetRequestStream();
237 os.Write(buffer, 0, strBuffer.Length); //Send it
238 //m_log.InfoFormat("[REST COMMS]: Posted ChildAgentUpdate request to remote sim {0}", uri);
239 }
240 //catch (WebException ex)
241 catch
242 {
243 //m_log.InfoFormat("[REST COMMS]: Bad send on ChildAgentUpdate {0}", ex.Message);
244
245 return false;
246 }
247 finally
248 {
249 if (os != null)
250 os.Close();
251 }
252
253 // Let's wait for the response
254 //m_log.Info("[REST COMMS]: Waiting for a reply after ChildAgentUpdate");
255
256 WebResponse webResponse = null;
257 StreamReader sr = null;
258 try
259 {
260 webResponse = ChildUpdateRequest.GetResponse();
261 if (webResponse == null)
262 {
263 m_log.Info("[REST COMMS]: Null reply on ChilAgentUpdate post");
264 }
265
266 sr = new StreamReader(webResponse.GetResponseStream());
267 //reply = sr.ReadToEnd().Trim();
268 sr.ReadToEnd().Trim();
269 sr.Close();
270 //m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply);
271
272 }
273 catch (WebException ex)
274 {
275 m_log.InfoFormat("[REST COMMS]: exception on reply of ChilAgentUpdate {0}", ex.Message);
276 // ignore, really
277 }
278 finally
279 {
280 if (sr != null)
281 sr.Close();
282 }
283
284 return true;
285 }
286
287 public bool DoRetrieveRootAgentCall(GridRegion region, UUID id, out IAgentData agent)
288 {
289 agent = null;
290 // Eventually, we want to use a caps url instead of the agentID
291 string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + id + "/" + region.RegionHandle.ToString() + "/";
292 //Console.WriteLine(" >>> DoRetrieveRootAgentCall <<< " + uri);
293
294 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
295 request.Method = "GET";
296 request.Timeout = 10000;
297 //request.Headers.Add("authorization", ""); // coming soon
298
299 HttpWebResponse webResponse = null;
300 string reply = string.Empty;
301 StreamReader sr = null;
302 try
303 {
304 webResponse = (HttpWebResponse)request.GetResponse();
305 if (webResponse == null)
306 {
307 m_log.Info("[REST COMMS]: Null reply on agent get ");
308 }
309
310 sr = new StreamReader(webResponse.GetResponseStream());
311 reply = sr.ReadToEnd().Trim();
312
313 //Console.WriteLine("[REST COMMS]: ChilAgentUpdate reply was " + reply);
314
315 }
316 catch (WebException ex)
317 {
318 m_log.InfoFormat("[REST COMMS]: exception on reply of agent get {0}", ex.Message);
319 // ignore, really
320 return false;
321 }
322 finally
323 {
324 if (sr != null)
325 sr.Close();
326 }
327
328 if (webResponse.StatusCode == HttpStatusCode.OK)
329 {
330 // we know it's jason
331 OSDMap args = GetOSDMap(reply);
332 if (args == null)
333 {
334 //Console.WriteLine("[REST COMMS]: Error getting OSDMap from reply");
335 return false;
336 }
337
338 agent = new CompleteAgentData();
339 agent.Unpack(args);
340 return true;
341 }
342
343 //Console.WriteLine("[REST COMMS]: DoRetrieveRootAgentCall returned status " + webResponse.StatusCode);
344 return false;
345 }
346
347 public bool DoReleaseAgentCall(ulong regionHandle, UUID id, string uri)
348 {
349 //m_log.Debug(" >>> DoReleaseAgentCall <<< " + uri);
350
351 WebRequest request = WebRequest.Create(uri);
352 request.Method = "DELETE";
353 request.Timeout = 10000;
354
355 StreamReader sr = null;
356 try
357 {
358 WebResponse webResponse = request.GetResponse();
359 if (webResponse == null)
360 {
361 m_log.Info("[REST COMMS]: Null reply on agent delete ");
362 }
363
364 sr = new StreamReader(webResponse.GetResponseStream());
365 //reply = sr.ReadToEnd().Trim();
366 sr.ReadToEnd().Trim();
367 sr.Close();
368 //m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply);
369
370 }
371 catch (WebException ex)
372 {
373 m_log.InfoFormat("[REST COMMS]: exception on reply of agent delete {0}", ex.Message);
374 // ignore, really
375 }
376 finally
377 {
378 if (sr != null)
379 sr.Close();
380 }
381
382 return true;
383 }
384
385
386 public bool DoCloseAgentCall(GridRegion region, UUID id)
387 {
388 string uri = string.Empty;
389 try
390 {
391 uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/agent/" + id + "/" + region.RegionHandle.ToString() + "/";
392 }
393 catch (Exception e)
394 {
395 m_log.Debug("[REST COMMS]: Unable to resolve external endpoint on agent close. Reason: " + e.Message);
396 return false;
397 }
398
399 //Console.WriteLine(" >>> DoCloseAgentCall <<< " + uri);
400
401 WebRequest request = WebRequest.Create(uri);
402 request.Method = "DELETE";
403 request.Timeout = 10000;
404
405 StreamReader sr = null;
406 try
407 {
408 WebResponse webResponse = request.GetResponse();
409 if (webResponse == null)
410 {
411 m_log.Info("[REST COMMS]: Null reply on agent delete ");
412 }
413
414 sr = new StreamReader(webResponse.GetResponseStream());
415 //reply = sr.ReadToEnd().Trim();
416 sr.ReadToEnd().Trim();
417 sr.Close();
418 //m_log.InfoFormat("[REST COMMS]: ChilAgentUpdate reply was {0} ", reply);
419
420 }
421 catch (WebException ex)
422 {
423 m_log.InfoFormat("[REST COMMS]: exception on reply of agent delete {0}", ex.Message);
424 // ignore, really
425 }
426 finally
427 {
428 if (sr != null)
429 sr.Close();
430 }
431
432 return true;
433 }
434
435 public bool DoCreateObjectCall(GridRegion region, ISceneObject sog, string sogXml2, bool allowScriptCrossing)
436 {
437 ulong regionHandle = GetRegionHandle(region.RegionHandle);
438 string uri
439 = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort
440 + "/object/" + sog.UUID + "/" + regionHandle.ToString() + "/";
441 //m_log.Debug(" >>> DoCreateChildAgentCall <<< " + uri);
442
443 WebRequest ObjectCreateRequest = WebRequest.Create(uri);
444 ObjectCreateRequest.Method = "POST";
445 ObjectCreateRequest.ContentType = "application/json";
446 ObjectCreateRequest.Timeout = 10000;
447
448 OSDMap args = new OSDMap(2);
449 args["sog"] = OSD.FromString(sogXml2);
450 args["extra"] = OSD.FromString(sog.ExtraToXmlString());
451 if (allowScriptCrossing)
452 {
453 string state = sog.GetStateSnapshot();
454 if (state.Length > 0)
455 args["state"] = OSD.FromString(state);
456 }
457
458 string strBuffer = "";
459 byte[] buffer = new byte[1];
460 try
461 {
462 strBuffer = OSDParser.SerializeJsonString(args);
463 Encoding str = Util.UTF8;
464 buffer = str.GetBytes(strBuffer);
465
466 }
467 catch (Exception e)
468 {
469 m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message);
470 // ignore. buffer will be empty, caller should check.
471 }
472
473 Stream os = null;
474 try
475 { // send the Post
476 ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send
477 os = ObjectCreateRequest.GetRequestStream();
478 os.Write(buffer, 0, strBuffer.Length); //Send it
479 m_log.InfoFormat("[REST COMMS]: Posted ChildAgentUpdate request to remote sim {0}", uri);
480 }
481 //catch (WebException ex)
482 catch
483 {
484 // m_log.InfoFormat("[REST COMMS]: Bad send on CreateObject {0}", ex.Message);
485
486 return false;
487 }
488 finally
489 {
490 if (os != null)
491 os.Close();
492 }
493
494 // Let's wait for the response
495 //m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall");
496
497 StreamReader sr = null;
498 try
499 {
500 WebResponse webResponse = ObjectCreateRequest.GetResponse();
501 if (webResponse == null)
502 {
503 m_log.Info("[REST COMMS]: Null reply on DoCreateObjectCall post");
504 }
505
506 sr = new StreamReader(webResponse.GetResponseStream());
507 //reply = sr.ReadToEnd().Trim();
508 sr.ReadToEnd().Trim();
509 //m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", reply);
510
511 }
512 catch (WebException ex)
513 {
514 m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateObjectCall {0}", ex.Message);
515 // ignore, really
516 }
517 finally
518 {
519 if (sr != null)
520 sr.Close();
521 }
522
523 return true;
524
525 }
526
527 public bool DoCreateObjectCall(GridRegion region, UUID userID, UUID itemID)
528 {
529 ulong regionHandle = GetRegionHandle(region.RegionHandle);
530 string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/object/" + UUID.Zero + "/" + regionHandle.ToString() + "/";
531 //m_log.Debug(" >>> DoCreateChildAgentCall <<< " + uri);
532
533 WebRequest ObjectCreateRequest = WebRequest.Create(uri);
534 ObjectCreateRequest.Method = "PUT";
535 ObjectCreateRequest.ContentType = "application/json";
536 ObjectCreateRequest.Timeout = 10000;
537
538 OSDMap args = new OSDMap(2);
539 args["userid"] = OSD.FromUUID(userID);
540 args["itemid"] = OSD.FromUUID(itemID);
541
542 string strBuffer = "";
543 byte[] buffer = new byte[1];
544 try
545 {
546 strBuffer = OSDParser.SerializeJsonString(args);
547 Encoding str = Util.UTF8;
548 buffer = str.GetBytes(strBuffer);
549
550 }
551 catch (Exception e)
552 {
553 m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message);
554 // ignore. buffer will be empty, caller should check.
555 }
556
557 Stream os = null;
558 try
559 { // send the Post
560 ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send
561 os = ObjectCreateRequest.GetRequestStream();
562 os.Write(buffer, 0, strBuffer.Length); //Send it
563 //m_log.InfoFormat("[REST COMMS]: Posted CreateObject request to remote sim {0}", uri);
564 }
565 //catch (WebException ex)
566 catch
567 {
568 // m_log.InfoFormat("[REST COMMS]: Bad send on CreateObject {0}", ex.Message);
569
570 return false;
571 }
572 finally
573 {
574 if (os != null)
575 os.Close();
576 }
577
578 // Let's wait for the response
579 //m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall");
580
581 StreamReader sr = null;
582 try
583 {
584 WebResponse webResponse = ObjectCreateRequest.GetResponse();
585 if (webResponse == null)
586 {
587 m_log.Info("[REST COMMS]: Null reply on DoCreateObjectCall post");
588 }
589
590 sr = new StreamReader(webResponse.GetResponseStream());
591 sr.ReadToEnd().Trim();
592 sr.ReadToEnd().Trim();
593
594 //m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", reply);
595
596 }
597 catch (WebException ex)
598 {
599 m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateObjectCall {0}", ex.Message);
600 // ignore, really
601 }
602 finally
603 {
604 if (sr != null)
605 sr.Close();
606 }
607
608 return true;
609
610 }
611
612 public bool DoHelloNeighbourCall(RegionInfo region, RegionInfo thisRegion)
613 {
614 string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/region/" + thisRegion.RegionID + "/";
615 //m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri);
616
617 WebRequest HelloNeighbourRequest = WebRequest.Create(uri);
618 HelloNeighbourRequest.Method = "POST";
619 HelloNeighbourRequest.ContentType = "application/json";
620 HelloNeighbourRequest.Timeout = 10000;
621
622 // Fill it in
623 OSDMap args = null;
624 try
625 {
626 args = thisRegion.PackRegionInfoData();
627 }
628 catch (Exception e)
629 {
630 m_log.Debug("[REST COMMS]: PackRegionInfoData failed with exception: " + e.Message);
631 }
632 // Add the regionhandle of the destination region
633 ulong regionHandle = GetRegionHandle(region.RegionHandle);
634 args["destination_handle"] = OSD.FromString(regionHandle.ToString());
635
636 string strBuffer = "";
637 byte[] buffer = new byte[1];
638 try
639 {
640 strBuffer = OSDParser.SerializeJsonString(args);
641 Encoding str = Util.UTF8;
642 buffer = str.GetBytes(strBuffer);
643
644 }
645 catch (Exception e)
646 {
647 m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of HelloNeighbour: {0}", e.Message);
648 // ignore. buffer will be empty, caller should check.
649 }
650
651 Stream os = null;
652 try
653 { // send the Post
654 HelloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send
655 os = HelloNeighbourRequest.GetRequestStream();
656 os.Write(buffer, 0, strBuffer.Length); //Send it
657 //m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri);
658 }
659 //catch (WebException ex)
660 catch
661 {
662 //m_log.InfoFormat("[REST COMMS]: Bad send on HelloNeighbour {0}", ex.Message);
663
664 return false;
665 }
666 finally
667 {
668 if (os != null)
669 os.Close();
670 }
671 // Let's wait for the response
672 //m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall");
673
674 StreamReader sr = null;
675 try
676 {
677 WebResponse webResponse = HelloNeighbourRequest.GetResponse();
678 if (webResponse == null)
679 {
680 m_log.Info("[REST COMMS]: Null reply on DoHelloNeighbourCall post");
681 }
682
683 sr = new StreamReader(webResponse.GetResponseStream());
684 //reply = sr.ReadToEnd().Trim();
685 sr.ReadToEnd().Trim();
686 //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply);
687
688 }
689 catch (WebException ex)
690 {
691 m_log.InfoFormat("[REST COMMS]: exception on reply of DoHelloNeighbourCall {0}", ex.Message);
692 // ignore, really
693 }
694 finally
695 {
696 if (sr != null)
697 sr.Close();
698 }
699
700 return true;
701
702 }
703
704 #region Hyperlinks
705
706 public virtual ulong GetRegionHandle(ulong handle)
707 {
708 return handle;
709 }
710
711 public virtual bool IsHyperlink(ulong handle)
712 {
713 return false;
714 }
715
716 public virtual void SendUserInformation(GridRegion regInfo, AgentCircuitData aCircuit)
717 {
718 }
719
720 public virtual void AdjustUserInformation(AgentCircuitData aCircuit)
721 {
722 }
723
724 #endregion /* Hyperlinks */
725
726 public static OSDMap GetOSDMap(string data)
727 {
728 OSDMap args = null;
729 try
730 {
731 OSD buffer;
732 // We should pay attention to the content-type, but let's assume we know it's Json
733 buffer = OSDParser.DeserializeJson(data);
734 if (buffer.Type == OSDType.Map)
735 {
736 args = (OSDMap)buffer;
737 return args;
738 }
739 else
740 {
741 // uh?
742 System.Console.WriteLine("[REST COMMS]: Got OSD of type " + buffer.Type.ToString());
743 return null;
744 }
745 }
746 catch (Exception ex)
747 {
748 System.Console.WriteLine("[REST COMMS]: exception on parse of REST message " + ex.Message);
749 return null;
750 }
751 }
752
753
754 }
755}
diff --git a/OpenSim/Framework/Communications/Services/HGLoginAuthService.cs b/OpenSim/Framework/Communications/Services/HGLoginAuthService.cs
deleted file mode 100644
index d3f813e..0000000
--- a/OpenSim/Framework/Communications/Services/HGLoginAuthService.cs
+++ /dev/null
@@ -1,339 +0,0 @@
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33using System.Text.RegularExpressions;
34using OpenSim.Framework;
35using OpenSim.Framework.Communications.Cache;
36using OpenSim.Framework.Capabilities;
37using OpenSim.Framework.Servers;
38
39using OpenMetaverse;
40
41using log4net;
42using Nini.Config;
43using Nwc.XmlRpc;
44
45namespace OpenSim.Framework.Communications.Services
46{
47 public class HGLoginAuthService : LoginService
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 protected NetworkServersInfo m_serversInfo;
52 protected bool m_authUsers = false;
53
54 /// <summary>
55 /// Used by the login service to make requests to the inventory service.
56 /// </summary>
57 protected IInterServiceInventoryServices m_interServiceInventoryService;
58
59 /// <summary>
60 /// Used to make requests to the local regions.
61 /// </summary>
62 protected ILoginServiceToRegionsConnector m_regionsConnector;
63
64 public HGLoginAuthService(
65 UserManagerBase userManager, string welcomeMess,
66 IInterServiceInventoryServices interServiceInventoryService,
67 NetworkServersInfo serversInfo,
68 bool authenticate, LibraryRootFolder libraryRootFolder, ILoginServiceToRegionsConnector regionsConnector)
69 : base(userManager, libraryRootFolder, welcomeMess)
70 {
71 this.m_serversInfo = serversInfo;
72 if (m_serversInfo != null)
73 {
74 m_defaultHomeX = this.m_serversInfo.DefaultHomeLocX;
75 m_defaultHomeY = this.m_serversInfo.DefaultHomeLocY;
76 }
77 m_authUsers = authenticate;
78
79 m_interServiceInventoryService = interServiceInventoryService;
80 m_regionsConnector = regionsConnector;
81 m_interInventoryService = interServiceInventoryService;
82 }
83
84 public void SetServersInfo(NetworkServersInfo sinfo)
85 {
86 m_serversInfo = sinfo;
87 }
88
89 public override XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request, IPEndPoint remoteClient)
90 {
91 m_log.Info("[HGLOGIN]: HGLogin called " + request.MethodName);
92 XmlRpcResponse response = base.XmlRpcLoginMethod(request, remoteClient);
93 Hashtable responseData = (Hashtable)response.Value;
94
95 responseData["grid_service"] = m_serversInfo.GridURL;
96 responseData["grid_service_send_key"] = m_serversInfo.GridSendKey;
97 responseData["inventory_service"] = m_serversInfo.InventoryURL;
98 responseData["asset_service"] = m_serversInfo.AssetURL;
99 responseData["asset_service_send_key"] = m_serversInfo.AssetSendKey;
100 int x = (Int32)responseData["region_x"];
101 int y = (Int32)responseData["region_y"];
102 uint ux = (uint)(x / Constants.RegionSize);
103 uint uy = (uint)(y / Constants.RegionSize);
104 ulong regionHandle = Util.UIntsToLong(ux, uy);
105 responseData["region_handle"] = regionHandle.ToString();
106
107 // Let's remove the seed cap from the login
108 //responseData.Remove("seed_capability");
109
110 // Let's add the appearance
111 UUID userID = UUID.Zero;
112 UUID.TryParse((string)responseData["agent_id"], out userID);
113 AvatarAppearance appearance = m_userManager.GetUserAppearance(userID);
114 if (appearance == null)
115 {
116 m_log.WarnFormat("[INTER]: Appearance not found for {0}. Creating default.", userID);
117 appearance = new AvatarAppearance();
118 }
119
120 responseData["appearance"] = appearance.ToHashTable();
121
122 // Let's also send the auth token
123 UUID token = UUID.Random();
124 responseData["auth_token"] = token.ToString();
125 UserProfileData userProfile = m_userManager.GetUserProfile(userID);
126 if (userProfile != null)
127 {
128 userProfile.WebLoginKey = token;
129 m_userManager.CommitAgent(ref userProfile);
130 }
131 m_log.Warn("[HGLOGIN]: Auth token: " + token);
132
133
134 return response;
135 }
136
137 public XmlRpcResponse XmlRpcGenerateKeyMethod(XmlRpcRequest request, IPEndPoint remoteClient)
138 {
139 // Verify the key of who's calling
140 UUID userID = UUID.Zero;
141 UUID authKey = UUID.Zero;
142 UUID.TryParse((string)request.Params[0], out userID);
143 UUID.TryParse((string)request.Params[1], out authKey);
144
145 m_log.InfoFormat("[HGLOGIN] HGGenerateKey called with authToken ", authKey);
146 string newKey = string.Empty;
147
148 if (!(m_userManager is IAuthentication))
149 {
150 m_log.Debug("[HGLOGIN]: UserManager is not IAuthentication service. Returning empty key.");
151 }
152 else
153 {
154 newKey = ((IAuthentication)m_userManager).GetNewKey(m_serversInfo.UserURL, userID, authKey);
155 }
156
157 XmlRpcResponse response = new XmlRpcResponse();
158 response.Value = (string) newKey;
159 return response;
160 }
161
162 public XmlRpcResponse XmlRpcVerifyKeyMethod(XmlRpcRequest request, IPEndPoint remoteClient)
163 {
164 bool success = false;
165
166 if (request.Params.Count >= 2)
167 {
168 // Verify the key of who's calling
169 UUID userID = UUID.Zero;
170 string authKey = string.Empty;
171 if (UUID.TryParse((string)request.Params[0], out userID))
172 {
173 authKey = (string)request.Params[1];
174
175 m_log.InfoFormat("[HGLOGIN] HGVerifyKey called with key {0}", authKey);
176
177 if (!(m_userManager is IAuthentication))
178 {
179 m_log.Debug("[HGLOGIN]: UserManager is not IAuthentication service. Denying.");
180 }
181 else
182 {
183 success = ((IAuthentication)m_userManager).VerifyKey(userID, authKey);
184 }
185 }
186 }
187
188 m_log.DebugFormat("[HGLOGIN]: Response to VerifyKey is {0}", success);
189 XmlRpcResponse response = new XmlRpcResponse();
190 response.Value = success;
191 return response;
192 }
193
194 public override UserProfileData GetTheUser(string firstname, string lastname)
195 {
196 UserProfileData profile = m_userManager.GetUserProfile(firstname, lastname);
197 if (profile != null)
198 {
199 return profile;
200 }
201
202 if (!m_authUsers)
203 {
204 //no current user account so make one
205 m_log.Info("[LOGIN]: No user account found so creating a new one.");
206
207 m_userManager.AddUser(firstname, lastname, "test", "", m_defaultHomeX, m_defaultHomeY);
208
209 return m_userManager.GetUserProfile(firstname, lastname);
210 }
211
212 return null;
213 }
214
215 public override bool AuthenticateUser(UserProfileData profile, string password)
216 {
217 if (!m_authUsers)
218 {
219 //for now we will accept any password in sandbox mode
220 m_log.Info("[LOGIN]: Authorising user (no actual password check)");
221
222 return true;
223 }
224 else
225 {
226 m_log.Info(
227 "[LOGIN]: Authenticating " + profile.FirstName + " " + profile.SurName);
228
229 if (!password.StartsWith("$1$"))
230 password = "$1$" + Util.Md5Hash(password);
231
232 password = password.Remove(0, 3); //remove $1$
233
234 string s = Util.Md5Hash(password + ":" + profile.PasswordSalt);
235
236 bool loginresult = (profile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
237 || profile.PasswordHash.Equals(password, StringComparison.InvariantCulture));
238 return loginresult;
239 }
240 }
241
242 protected override RegionInfo RequestClosestRegion(string region)
243 {
244 return m_regionsConnector.RequestClosestRegion(region);
245 }
246
247 protected override RegionInfo GetRegionInfo(ulong homeRegionHandle)
248 {
249 return m_regionsConnector.RequestNeighbourInfo(homeRegionHandle);
250 }
251
252 protected override RegionInfo GetRegionInfo(UUID homeRegionId)
253 {
254 return m_regionsConnector.RequestNeighbourInfo(homeRegionId);
255 }
256
257 /// <summary>
258 /// Not really informing the region. Just filling out the response fields related to the region.
259 /// </summary>
260 /// <param name="sim"></param>
261 /// <param name="user"></param>
262 /// <param name="response"></param>
263 /// <returns>true if the region was successfully contacted, false otherwise</returns>
264 protected override bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint remoteClient)
265 {
266 IPEndPoint endPoint = regionInfo.ExternalEndPoint;
267 response.SimAddress = endPoint.Address.ToString();
268 response.SimPort = (uint)endPoint.Port;
269 response.RegionX = regionInfo.RegionLocX;
270 response.RegionY = regionInfo.RegionLocY;
271 response.SimHttpPort = regionInfo.HttpPort;
272
273 string capsPath = CapsUtil.GetRandomCapsObjectPath();
274 string capsSeedPath = CapsUtil.GetCapsSeedPath(capsPath);
275
276 // Don't use the following! It Fails for logging into any region not on the same port as the http server!
277 // Kept here so it doesn't happen again!
278 // response.SeedCapability = regionInfo.ServerURI + capsSeedPath;
279
280 string seedcap = "http://";
281
282 if (m_serversInfo.HttpUsesSSL)
283 {
284 // For NAT
285 string host = NetworkUtil.GetHostFor(remoteClient.Address, m_serversInfo.HttpSSLCN);
286
287 seedcap = "https://" + host + ":" + m_serversInfo.httpSSLPort + capsSeedPath;
288 }
289 else
290 {
291 // For NAT
292 string host = NetworkUtil.GetHostFor(remoteClient.Address, regionInfo.ExternalHostName);
293
294 seedcap = "http://" + host + ":" + m_serversInfo.HttpListenerPort + capsSeedPath;
295 }
296
297 response.SeedCapability = seedcap;
298
299 // Notify the target of an incoming user
300 m_log.InfoFormat(
301 "[LOGIN]: Telling {0} @ {1},{2} ({3}) to prepare for client connection",
302 regionInfo.RegionName, response.RegionX, response.RegionY, regionInfo.ServerURI);
303
304 // Update agent with target sim
305 user.CurrentAgent.Region = regionInfo.RegionID;
306 user.CurrentAgent.Handle = regionInfo.RegionHandle;
307
308 return true;
309 }
310
311 public override void LogOffUser(UserProfileData theUser, string message)
312 {
313 RegionInfo SimInfo;
314 try
315 {
316 SimInfo = this.m_regionsConnector.RequestNeighbourInfo(theUser.CurrentAgent.Handle);
317
318 if (SimInfo == null)
319 {
320 m_log.Error("[LOCAL LOGIN]: Region user was in isn't currently logged in");
321 return;
322 }
323 }
324 catch (Exception)
325 {
326 m_log.Error("[LOCAL LOGIN]: Unable to look up region to log user off");
327 return;
328 }
329
330 m_regionsConnector.LogOffUserFromGrid(SimInfo.RegionHandle, theUser.ID, theUser.CurrentAgent.SecureSessionID, "Logging you off");
331 }
332
333 protected override bool AllowLoginWithoutInventory()
334 {
335 return true;
336 }
337
338 }
339}
diff --git a/OpenSim/Framework/Communications/Services/LoginResponse.cs b/OpenSim/Framework/Communications/Services/LoginResponse.cs
deleted file mode 100644
index ec5f428..0000000
--- a/OpenSim/Framework/Communications/Services/LoginResponse.cs
+++ /dev/null
@@ -1,823 +0,0 @@
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nwc.XmlRpc;
34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
36
37namespace OpenSim.Framework.Communications.Services
38{
39 /// <summary>
40 /// A temp class to handle login response.
41 /// Should make use of UserProfileManager where possible.
42 /// </summary>
43 public class LoginResponse
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 private Hashtable loginFlagsHash;
48 private Hashtable globalTexturesHash;
49 private Hashtable loginError;
50 private Hashtable uiConfigHash;
51
52 private ArrayList loginFlags;
53 private ArrayList globalTextures;
54 private ArrayList eventCategories;
55 private ArrayList uiConfig;
56 private ArrayList classifiedCategories;
57 private ArrayList inventoryRoot;
58 private ArrayList initialOutfit;
59 private ArrayList agentInventory;
60 private ArrayList inventoryLibraryOwner;
61 private ArrayList inventoryLibRoot;
62 private ArrayList inventoryLibrary;
63 private ArrayList activeGestures;
64
65 private UserInfo userProfile;
66
67 private UUID agentID;
68 private UUID sessionID;
69 private UUID secureSessionID;
70
71 // Login Flags
72 private string dst;
73 private string stipendSinceLogin;
74 private string gendered;
75 private string everLoggedIn;
76 private string login;
77 private uint simPort;
78 private uint simHttpPort;
79 private string simAddress;
80 private string agentAccess;
81 private string agentAccessMax;
82 private Int32 circuitCode;
83 private uint regionX;
84 private uint regionY;
85
86 // Login
87 private string firstname;
88 private string lastname;
89
90 // Global Textures
91 private string sunTexture;
92 private string cloudTexture;
93 private string moonTexture;
94
95 // Error Flags
96 private string errorReason;
97 private string errorMessage;
98
99 // Response
100 private XmlRpcResponse xmlRpcResponse;
101 // private XmlRpcResponse defaultXmlRpcResponse;
102
103 private string welcomeMessage;
104 private string startLocation;
105 private string allowFirstLife;
106 private string home;
107 private string seedCapability;
108 private string lookAt;
109
110 private BuddyList m_buddyList = null;
111
112 public LoginResponse()
113 {
114 loginFlags = new ArrayList();
115 globalTextures = new ArrayList();
116 eventCategories = new ArrayList();
117 uiConfig = new ArrayList();
118 classifiedCategories = new ArrayList();
119
120 loginError = new Hashtable();
121 uiConfigHash = new Hashtable();
122
123 // defaultXmlRpcResponse = new XmlRpcResponse();
124 userProfile = new UserInfo();
125 inventoryRoot = new ArrayList();
126 initialOutfit = new ArrayList();
127 agentInventory = new ArrayList();
128 inventoryLibrary = new ArrayList();
129 inventoryLibraryOwner = new ArrayList();
130 activeGestures = new ArrayList();
131
132 xmlRpcResponse = new XmlRpcResponse();
133 // defaultXmlRpcResponse = new XmlRpcResponse();
134
135 SetDefaultValues();
136 }
137
138 private void SetDefaultValues()
139 {
140 DST = TimeZone.CurrentTimeZone.IsDaylightSavingTime(DateTime.Now) ? "Y" : "N";
141 StipendSinceLogin = "N";
142 Gendered = "Y";
143 EverLoggedIn = "Y";
144 login = "false";
145 firstname = "Test";
146 lastname = "User";
147 agentAccess = "M";
148 agentAccessMax = "A";
149 startLocation = "last";
150 allowFirstLife = "Y";
151
152 SunTexture = "cce0f112-878f-4586-a2e2-a8f104bba271";
153 CloudTexture = "dc4b9f0b-d008-45c6-96a4-01dd947ac621";
154 MoonTexture = "ec4b9f0b-d008-45c6-96a4-01dd947ac621";
155
156 ErrorMessage = "You have entered an invalid name/password combination. Check Caps/lock.";
157 ErrorReason = "key";
158 welcomeMessage = "Welcome to OpenSim!";
159 seedCapability = String.Empty;
160 home = "{'region_handle':[r" + (1000*Constants.RegionSize).ToString() + ",r" + (1000*Constants.RegionSize).ToString() + "], 'position':[r" +
161 userProfile.homepos.X.ToString() + ",r" + userProfile.homepos.Y.ToString() + ",r" +
162 userProfile.homepos.Z.ToString() + "], 'look_at':[r" + userProfile.homelookat.X.ToString() + ",r" +
163 userProfile.homelookat.Y.ToString() + ",r" + userProfile.homelookat.Z.ToString() + "]}";
164 lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]";
165 RegionX = (uint) 255232;
166 RegionY = (uint) 254976;
167
168 // Classifieds;
169 AddClassifiedCategory((Int32) 1, "Shopping");
170 AddClassifiedCategory((Int32) 2, "Land Rental");
171 AddClassifiedCategory((Int32) 3, "Property Rental");
172 AddClassifiedCategory((Int32) 4, "Special Attraction");
173 AddClassifiedCategory((Int32) 5, "New Products");
174 AddClassifiedCategory((Int32) 6, "Employment");
175 AddClassifiedCategory((Int32) 7, "Wanted");
176 AddClassifiedCategory((Int32) 8, "Service");
177 AddClassifiedCategory((Int32) 9, "Personal");
178
179 SessionID = UUID.Random();
180 SecureSessionID = UUID.Random();
181 AgentID = UUID.Random();
182
183 Hashtable InitialOutfitHash = new Hashtable();
184 InitialOutfitHash["folder_name"] = "Nightclub Female";
185 InitialOutfitHash["gender"] = "female";
186 initialOutfit.Add(InitialOutfitHash);
187 }
188
189 #region Login Failure Methods
190
191 public XmlRpcResponse GenerateFailureResponse(string reason, string message, string login)
192 {
193 // Overwrite any default values;
194 xmlRpcResponse = new XmlRpcResponse();
195
196 // Ensure Login Failed message/reason;
197 ErrorMessage = message;
198 ErrorReason = reason;
199
200 loginError["reason"] = ErrorReason;
201 loginError["message"] = ErrorMessage;
202 loginError["login"] = login;
203 xmlRpcResponse.Value = loginError;
204 return (xmlRpcResponse);
205 }
206
207 public OSD GenerateFailureResponseLLSD(string reason, string message, string login)
208 {
209 OSDMap map = new OSDMap();
210
211 // Ensure Login Failed message/reason;
212 ErrorMessage = message;
213 ErrorReason = reason;
214
215 map["reason"] = OSD.FromString(ErrorReason);
216 map["message"] = OSD.FromString(ErrorMessage);
217 map["login"] = OSD.FromString(login);
218
219 return map;
220 }
221
222 public XmlRpcResponse CreateFailedResponse()
223 {
224 return (CreateLoginFailedResponse());
225 }
226
227 public OSD CreateFailedResponseLLSD()
228 {
229 return CreateLoginFailedResponseLLSD();
230 }
231
232 public XmlRpcResponse CreateLoginFailedResponse()
233 {
234 return
235 (GenerateFailureResponse("key",
236 "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.",
237 "false"));
238 }
239
240 public OSD CreateLoginFailedResponseLLSD()
241 {
242 return GenerateFailureResponseLLSD(
243 "key",
244 "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.",
245 "false");
246 }
247
248 /// <summary>
249 /// Response to indicate that login failed because the agent's inventory was not available.
250 /// </summary>
251 /// <returns></returns>
252 public XmlRpcResponse CreateLoginInventoryFailedResponse()
253 {
254 return GenerateFailureResponse(
255 "key",
256 "The avatar inventory service is not responding. Please notify your login region operator.",
257 "false");
258 }
259
260 public XmlRpcResponse CreateAlreadyLoggedInResponse()
261 {
262 return
263 (GenerateFailureResponse("presence",
264 "You appear to be already logged in. " +
265 "If this is not the case please wait for your session to timeout. " +
266 "If this takes longer than a few minutes please contact the grid owner. " +
267 "Please wait 5 minutes if you are going to connect to a region nearby to the region you were at previously.",
268 "false"));
269 }
270
271 public OSD CreateAlreadyLoggedInResponseLLSD()
272 {
273 return GenerateFailureResponseLLSD(
274 "presence",
275 "You appear to be already logged in. " +
276 "If this is not the case please wait for your session to timeout. " +
277 "If this takes longer than a few minutes please contact the grid owner",
278 "false");
279 }
280
281 public XmlRpcResponse CreateLoginBlockedResponse()
282 {
283 return
284 (GenerateFailureResponse("presence",
285 "Logins are currently restricted. Please try again later",
286 "false"));
287 }
288
289 public OSD CreateLoginBlockedResponseLLSD()
290 {
291 return GenerateFailureResponseLLSD(
292 "presence",
293 "Logins are currently restricted. Please try again later",
294 "false");
295 }
296
297 public XmlRpcResponse CreateDeadRegionResponse()
298 {
299 return
300 (GenerateFailureResponse("key",
301 "The region you are attempting to log into is not responding. Please select another region and try again.",
302 "false"));
303 }
304
305 public OSD CreateDeadRegionResponseLLSD()
306 {
307 return GenerateFailureResponseLLSD(
308 "key",
309 "The region you are attempting to log into is not responding. Please select another region and try again.",
310 "false");
311 }
312
313 public XmlRpcResponse CreateGridErrorResponse()
314 {
315 return
316 (GenerateFailureResponse("key",
317 "Error connecting to grid. Could not percieve credentials from login XML.",
318 "false"));
319 }
320
321 public OSD CreateGridErrorResponseLLSD()
322 {
323 return GenerateFailureResponseLLSD(
324 "key",
325 "Error connecting to grid. Could not perceive credentials from login XML.",
326 "false");
327 }
328
329 #endregion
330
331 public virtual XmlRpcResponse ToXmlRpcResponse()
332 {
333 try
334 {
335 Hashtable responseData = new Hashtable();
336
337 loginFlagsHash = new Hashtable();
338 loginFlagsHash["daylight_savings"] = DST;
339 loginFlagsHash["stipend_since_login"] = StipendSinceLogin;
340 loginFlagsHash["gendered"] = Gendered;
341 loginFlagsHash["ever_logged_in"] = EverLoggedIn;
342 loginFlags.Add(loginFlagsHash);
343
344 responseData["first_name"] = Firstname;
345 responseData["last_name"] = Lastname;
346 responseData["agent_access"] = agentAccess;
347 responseData["agent_access_max"] = agentAccessMax;
348
349 globalTexturesHash = new Hashtable();
350 globalTexturesHash["sun_texture_id"] = SunTexture;
351 globalTexturesHash["cloud_texture_id"] = CloudTexture;
352 globalTexturesHash["moon_texture_id"] = MoonTexture;
353 globalTextures.Add(globalTexturesHash);
354 // this.eventCategories.Add(this.eventCategoriesHash);
355
356 AddToUIConfig("allow_first_life", allowFirstLife);
357 uiConfig.Add(uiConfigHash);
358
359 responseData["sim_port"] = (Int32) SimPort;
360 responseData["sim_ip"] = SimAddress;
361 responseData["http_port"] = (Int32)SimHttpPort;
362
363 responseData["agent_id"] = AgentID.ToString();
364 responseData["session_id"] = SessionID.ToString();
365 responseData["secure_session_id"] = SecureSessionID.ToString();
366 responseData["circuit_code"] = CircuitCode;
367 responseData["seconds_since_epoch"] = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
368 responseData["login-flags"] = loginFlags;
369 responseData["global-textures"] = globalTextures;
370 responseData["seed_capability"] = seedCapability;
371
372 responseData["event_categories"] = eventCategories;
373 responseData["event_notifications"] = new ArrayList(); // todo
374 responseData["classified_categories"] = classifiedCategories;
375 responseData["ui-config"] = uiConfig;
376
377 if (agentInventory != null)
378 {
379 responseData["inventory-skeleton"] = agentInventory;
380 responseData["inventory-root"] = inventoryRoot;
381 }
382 responseData["inventory-skel-lib"] = inventoryLibrary;
383 responseData["inventory-lib-root"] = inventoryLibRoot;
384 responseData["gestures"] = activeGestures;
385 responseData["inventory-lib-owner"] = inventoryLibraryOwner;
386 responseData["initial-outfit"] = initialOutfit;
387 responseData["start_location"] = startLocation;
388 responseData["seed_capability"] = seedCapability;
389 responseData["home"] = home;
390 responseData["look_at"] = lookAt;
391 responseData["message"] = welcomeMessage;
392 responseData["region_x"] = (Int32)(RegionX * Constants.RegionSize);
393 responseData["region_y"] = (Int32)(RegionY * Constants.RegionSize);
394
395 if (m_buddyList != null)
396 {
397 responseData["buddy-list"] = m_buddyList.ToArray();
398 }
399
400 responseData["login"] = "true";
401 xmlRpcResponse.Value = responseData;
402
403 return (xmlRpcResponse);
404 }
405 catch (Exception e)
406 {
407 m_log.Warn("[CLIENT]: LoginResponse: Error creating XML-RPC Response: " + e.Message);
408
409 return (GenerateFailureResponse("Internal Error", "Error generating Login Response", "false"));
410 }
411 }
412
413 public OSD ToLLSDResponse()
414 {
415 try
416 {
417 OSDMap map = new OSDMap();
418
419 map["first_name"] = OSD.FromString(Firstname);
420 map["last_name"] = OSD.FromString(Lastname);
421 map["agent_access"] = OSD.FromString(agentAccess);
422 map["agent_access_max"] = OSD.FromString(agentAccessMax);
423
424 map["sim_port"] = OSD.FromInteger(SimPort);
425 map["sim_ip"] = OSD.FromString(SimAddress);
426
427 map["agent_id"] = OSD.FromUUID(AgentID);
428 map["session_id"] = OSD.FromUUID(SessionID);
429 map["secure_session_id"] = OSD.FromUUID(SecureSessionID);
430 map["circuit_code"] = OSD.FromInteger(CircuitCode);
431 map["seconds_since_epoch"] = OSD.FromInteger((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds);
432
433 #region Login Flags
434
435 OSDMap loginFlagsLLSD = new OSDMap();
436 loginFlagsLLSD["daylight_savings"] = OSD.FromString(DST);
437 loginFlagsLLSD["stipend_since_login"] = OSD.FromString(StipendSinceLogin);
438 loginFlagsLLSD["gendered"] = OSD.FromString(Gendered);
439 loginFlagsLLSD["ever_logged_in"] = OSD.FromString(EverLoggedIn);
440 map["login-flags"] = WrapOSDMap(loginFlagsLLSD);
441
442 #endregion Login Flags
443
444 #region Global Textures
445
446 OSDMap globalTexturesLLSD = new OSDMap();
447 globalTexturesLLSD["sun_texture_id"] = OSD.FromString(SunTexture);
448 globalTexturesLLSD["cloud_texture_id"] = OSD.FromString(CloudTexture);
449 globalTexturesLLSD["moon_texture_id"] = OSD.FromString(MoonTexture);
450
451 map["global-textures"] = WrapOSDMap(globalTexturesLLSD);
452
453 #endregion Global Textures
454
455 map["seed_capability"] = OSD.FromString(seedCapability);
456
457 map["event_categories"] = ArrayListToOSDArray(eventCategories);
458 //map["event_notifications"] = new OSDArray(); // todo
459 map["classified_categories"] = ArrayListToOSDArray(classifiedCategories);
460
461 #region UI Config
462
463 OSDMap uiConfigLLSD = new OSDMap();
464 uiConfigLLSD["allow_first_life"] = OSD.FromString(allowFirstLife);
465 map["ui-config"] = WrapOSDMap(uiConfigLLSD);
466
467 #endregion UI Config
468
469 #region Inventory
470
471 map["inventory-skeleton"] = ArrayListToOSDArray(agentInventory);
472
473 map["inventory-skel-lib"] = ArrayListToOSDArray(inventoryLibrary);
474 map["inventory-root"] = ArrayListToOSDArray(inventoryRoot); ;
475 map["inventory-lib-root"] = ArrayListToOSDArray(inventoryLibRoot);
476 map["inventory-lib-owner"] = ArrayListToOSDArray(inventoryLibraryOwner);
477
478 #endregion Inventory
479
480 map["gestures"] = ArrayListToOSDArray(activeGestures);
481
482 map["initial-outfit"] = ArrayListToOSDArray(initialOutfit);
483 map["start_location"] = OSD.FromString(startLocation);
484
485 map["seed_capability"] = OSD.FromString(seedCapability);
486 map["home"] = OSD.FromString(home);
487 map["look_at"] = OSD.FromString(lookAt);
488 map["message"] = OSD.FromString(welcomeMessage);
489 map["region_x"] = OSD.FromInteger(RegionX * Constants.RegionSize);
490 map["region_y"] = OSD.FromInteger(RegionY * Constants.RegionSize);
491
492 if (m_buddyList != null)
493 {
494 map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray());
495 }
496
497 map["login"] = OSD.FromString("true");
498
499 return map;
500 }
501 catch (Exception e)
502 {
503 m_log.Warn("[CLIENT]: LoginResponse: Error creating LLSD Response: " + e.Message);
504
505 return GenerateFailureResponseLLSD("Internal Error", "Error generating Login Response", "false");
506 }
507 }
508
509 public OSDArray ArrayListToOSDArray(ArrayList arrlst)
510 {
511 OSDArray llsdBack = new OSDArray();
512 foreach (Hashtable ht in arrlst)
513 {
514 OSDMap mp = new OSDMap();
515 foreach (DictionaryEntry deHt in ht)
516 {
517 mp.Add((string)deHt.Key, OSDString.FromObject(deHt.Value));
518 }
519 llsdBack.Add(mp);
520 }
521 return llsdBack;
522 }
523
524 private static OSDArray WrapOSDMap(OSDMap wrapMe)
525 {
526 OSDArray array = new OSDArray();
527 array.Add(wrapMe);
528 return array;
529 }
530
531 public void SetEventCategories(string category, string value)
532 {
533 // this.eventCategoriesHash[category] = value;
534 //TODO
535 }
536
537 public void AddToUIConfig(string itemName, string item)
538 {
539 uiConfigHash[itemName] = item;
540 }
541
542 public void AddClassifiedCategory(Int32 ID, string categoryName)
543 {
544 Hashtable hash = new Hashtable();
545 hash["category_name"] = categoryName;
546 hash["category_id"] = ID;
547 classifiedCategories.Add(hash);
548 // this.classifiedCategoriesHash.Clear();
549 }
550
551 #region Properties
552
553 public string Login
554 {
555 get { return login; }
556 set { login = value; }
557 }
558
559 public string DST
560 {
561 get { return dst; }
562 set { dst = value; }
563 }
564
565 public string StipendSinceLogin
566 {
567 get { return stipendSinceLogin; }
568 set { stipendSinceLogin = value; }
569 }
570
571 public string Gendered
572 {
573 get { return gendered; }
574 set { gendered = value; }
575 }
576
577 public string EverLoggedIn
578 {
579 get { return everLoggedIn; }
580 set { everLoggedIn = value; }
581 }
582
583 public uint SimPort
584 {
585 get { return simPort; }
586 set { simPort = value; }
587 }
588
589 public uint SimHttpPort
590 {
591 get { return simHttpPort; }
592 set { simHttpPort = value; }
593 }
594
595 public string SimAddress
596 {
597 get { return simAddress; }
598 set { simAddress = value; }
599 }
600
601 public UUID AgentID
602 {
603 get { return agentID; }
604 set { agentID = value; }
605 }
606
607 public UUID SessionID
608 {
609 get { return sessionID; }
610 set { sessionID = value; }
611 }
612
613 public UUID SecureSessionID
614 {
615 get { return secureSessionID; }
616 set { secureSessionID = value; }
617 }
618
619 public Int32 CircuitCode
620 {
621 get { return circuitCode; }
622 set { circuitCode = value; }
623 }
624
625 public uint RegionX
626 {
627 get { return regionX; }
628 set { regionX = value; }
629 }
630
631 public uint RegionY
632 {
633 get { return regionY; }
634 set { regionY = value; }
635 }
636
637 public string SunTexture
638 {
639 get { return sunTexture; }
640 set { sunTexture = value; }
641 }
642
643 public string CloudTexture
644 {
645 get { return cloudTexture; }
646 set { cloudTexture = value; }
647 }
648
649 public string MoonTexture
650 {
651 get { return moonTexture; }
652 set { moonTexture = value; }
653 }
654
655 public string Firstname
656 {
657 get { return firstname; }
658 set { firstname = value; }
659 }
660
661 public string Lastname
662 {
663 get { return lastname; }
664 set { lastname = value; }
665 }
666
667 public string AgentAccess
668 {
669 get { return agentAccess; }
670 set { agentAccess = value; }
671 }
672
673 public string AgentAccessMax
674 {
675 get { return agentAccessMax; }
676 set { agentAccessMax = value; }
677 }
678
679 public string StartLocation
680 {
681 get { return startLocation; }
682 set { startLocation = value; }
683 }
684
685 public string LookAt
686 {
687 get { return lookAt; }
688 set { lookAt = value; }
689 }
690
691 public string SeedCapability
692 {
693 get { return seedCapability; }
694 set { seedCapability = value; }
695 }
696
697 public string ErrorReason
698 {
699 get { return errorReason; }
700 set { errorReason = value; }
701 }
702
703 public string ErrorMessage
704 {
705 get { return errorMessage; }
706 set { errorMessage = value; }
707 }
708
709 public ArrayList InventoryRoot
710 {
711 get { return inventoryRoot; }
712 set { inventoryRoot = value; }
713 }
714
715 public ArrayList InventorySkeleton
716 {
717 get { return agentInventory; }
718 set { agentInventory = value; }
719 }
720
721 public ArrayList InventoryLibrary
722 {
723 get { return inventoryLibrary; }
724 set { inventoryLibrary = value; }
725 }
726
727 public ArrayList InventoryLibraryOwner
728 {
729 get { return inventoryLibraryOwner; }
730 set { inventoryLibraryOwner = value; }
731 }
732
733 public ArrayList InventoryLibRoot
734 {
735 get { return inventoryLibRoot; }
736 set { inventoryLibRoot = value; }
737 }
738
739 public ArrayList ActiveGestures
740 {
741 get { return activeGestures; }
742 set { activeGestures = value; }
743 }
744
745 public string Home
746 {
747 get { return home; }
748 set { home = value; }
749 }
750
751 public string Message
752 {
753 get { return welcomeMessage; }
754 set { welcomeMessage = value; }
755 }
756
757 public BuddyList BuddList
758 {
759 get { return m_buddyList; }
760 set { m_buddyList = value; }
761 }
762
763 #endregion
764
765 public class UserInfo
766 {
767 public string firstname;
768 public string lastname;
769 public ulong homeregionhandle;
770 public Vector3 homepos;
771 public Vector3 homelookat;
772 }
773
774 public class BuddyList
775 {
776 public List<BuddyInfo> Buddies = new List<BuddyInfo>();
777
778 public void AddNewBuddy(BuddyInfo buddy)
779 {
780 if (!Buddies.Contains(buddy))
781 {
782 Buddies.Add(buddy);
783 }
784 }
785
786 public ArrayList ToArray()
787 {
788 ArrayList buddyArray = new ArrayList();
789 foreach (BuddyInfo buddy in Buddies)
790 {
791 buddyArray.Add(buddy.ToHashTable());
792 }
793 return buddyArray;
794 }
795
796 public class BuddyInfo
797 {
798 public int BuddyRightsHave = 1;
799 public int BuddyRightsGiven = 1;
800 public UUID BuddyID;
801
802 public BuddyInfo(string buddyID)
803 {
804 BuddyID = new UUID(buddyID);
805 }
806
807 public BuddyInfo(UUID buddyID)
808 {
809 BuddyID = buddyID;
810 }
811
812 public Hashtable ToHashTable()
813 {
814 Hashtable hTable = new Hashtable();
815 hTable["buddy_rights_has"] = BuddyRightsHave;
816 hTable["buddy_rights_given"] = BuddyRightsGiven;
817 hTable["buddy_id"] = BuddyID.ToString();
818 return hTable;
819 }
820 }
821 }
822 }
823}
diff --git a/OpenSim/Framework/Communications/Services/LoginService.cs b/OpenSim/Framework/Communications/Services/LoginService.cs
deleted file mode 100644
index 57ca704..0000000
--- a/OpenSim/Framework/Communications/Services/LoginService.cs
+++ /dev/null
@@ -1,1243 +0,0 @@
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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using System.Net;
33using System.Reflection;
34using System.Text.RegularExpressions;
35using System.Threading;
36using System.Web;
37using log4net;
38using Nwc.XmlRpc;
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenSim.Framework;
42using OpenSim.Framework.Communications.Cache;
43using OpenSim.Framework.Statistics;
44using OpenSim.Services.Interfaces;
45
46namespace OpenSim.Framework.Communications.Services
47{
48 public abstract class LoginService
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 protected string m_welcomeMessage = "Welcome to OpenSim";
53 protected int m_minLoginLevel = 0;
54 protected UserManagerBase m_userManager = null;
55 protected Mutex m_loginMutex = new Mutex(false);
56
57 /// <summary>
58 /// Used during login to send the skeleton of the OpenSim Library to the client.
59 /// </summary>
60 protected LibraryRootFolder m_libraryRootFolder;
61
62 protected uint m_defaultHomeX;
63 protected uint m_defaultHomeY;
64
65 protected bool m_warn_already_logged = true;
66
67 /// <summary>
68 /// Used by the login service to make requests to the inventory service.
69 /// </summary>
70 protected IInterServiceInventoryServices m_interInventoryService;
71 // Hack
72 protected IInventoryService m_InventoryService;
73
74 /// <summary>
75 /// Constructor
76 /// </summary>
77 /// <param name="userManager"></param>
78 /// <param name="libraryRootFolder"></param>
79 /// <param name="welcomeMess"></param>
80 public LoginService(UserManagerBase userManager, LibraryRootFolder libraryRootFolder,
81 string welcomeMess)
82 {
83 m_userManager = userManager;
84 m_libraryRootFolder = libraryRootFolder;
85
86 if (welcomeMess != String.Empty)
87 {
88 m_welcomeMessage = welcomeMess;
89 }
90 }
91
92 /// <summary>
93 /// If the user is already logged in, try to notify the region that the user they've got is dead.
94 /// </summary>
95 /// <param name="theUser"></param>
96 public virtual void LogOffUser(UserProfileData theUser, string message)
97 {
98 }
99
100 /// <summary>
101 /// Called when we receive the client's initial XMLRPC login_to_simulator request message
102 /// </summary>
103 /// <param name="request">The XMLRPC request</param>
104 /// <returns>The response to send</returns>
105 public virtual XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request, IPEndPoint remoteClient)
106 {
107 // Temporary fix
108 m_loginMutex.WaitOne();
109
110 try
111 {
112 //CFK: CustomizeResponse contains sufficient strings to alleviate the need for this.
113 //CKF: m_log.Info("[LOGIN]: Attempting login now...");
114 XmlRpcResponse response = new XmlRpcResponse();
115 Hashtable requestData = (Hashtable)request.Params[0];
116
117 SniffLoginKey((Uri)request.Params[2], requestData);
118
119 bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") &&
120 (requestData.Contains("passwd") || requestData.Contains("web_login_key")));
121
122 string startLocationRequest = "last";
123
124 UserProfileData userProfile;
125 LoginResponse logResponse = new LoginResponse();
126
127 string firstname;
128 string lastname;
129
130 if (GoodXML)
131 {
132 if (requestData.Contains("start"))
133 {
134 startLocationRequest = (string)requestData["start"];
135 }
136
137 firstname = (string)requestData["first"];
138 lastname = (string)requestData["last"];
139
140 m_log.InfoFormat(
141 "[LOGIN BEGIN]: XMLRPC Received login request message from user '{0}' '{1}'",
142 firstname, lastname);
143
144 string clientVersion = "Unknown";
145
146 if (requestData.Contains("version"))
147 {
148 clientVersion = (string)requestData["version"];
149 }
150
151 m_log.DebugFormat(
152 "[LOGIN]: XMLRPC Client is {0}, start location is {1}", clientVersion, startLocationRequest);
153
154 if (!TryAuthenticateXmlRpcLogin(request, firstname, lastname, out userProfile))
155 {
156 return logResponse.CreateLoginFailedResponse();
157 }
158 }
159 else
160 {
161 m_log.Info(
162 "[LOGIN END]: XMLRPC login_to_simulator login message did not contain all the required data");
163
164 return logResponse.CreateGridErrorResponse();
165 }
166
167 if (userProfile.GodLevel < m_minLoginLevel)
168 {
169 return logResponse.CreateLoginBlockedResponse();
170 }
171 else
172 {
173 // If we already have a session...
174 if (userProfile.CurrentAgent != null && userProfile.CurrentAgent.AgentOnline)
175 {
176 //TODO: The following statements can cause trouble:
177 // If agentOnline could not turn from true back to false normally
178 // because of some problem, for instance, the crashment of server or client,
179 // the user cannot log in any longer.
180 userProfile.CurrentAgent.AgentOnline = false;
181
182 m_userManager.CommitAgent(ref userProfile);
183
184 // try to tell the region that their user is dead.
185 LogOffUser(userProfile, " XMLRPC You were logged off because you logged in from another location");
186
187 if (m_warn_already_logged)
188 {
189 // This is behavior for for grid, reject login
190 m_log.InfoFormat(
191 "[LOGIN END]: XMLRPC Notifying user {0} {1} that they are already logged in",
192 firstname, lastname);
193
194 return logResponse.CreateAlreadyLoggedInResponse();
195 }
196 else
197 {
198 // This is behavior for standalone (silent logout of last hung session)
199 m_log.InfoFormat(
200 "[LOGIN]: XMLRPC User {0} {1} is already logged in, not notifying user, kicking old presence and starting new login.",
201 firstname, lastname);
202 }
203 }
204
205 // Otherwise...
206 // Create a new agent session
207
208 // XXYY we don't need this
209 //m_userManager.ResetAttachments(userProfile.ID);
210
211 CreateAgent(userProfile, request);
212
213 // We need to commit the agent right here, even though the userProfile info is not complete
214 // at this point. There is another commit further down.
215 // This is for the new sessionID to be stored so that the region can check it for session authentication.
216 // CustomiseResponse->PrepareLoginToRegion
217 CommitAgent(ref userProfile);
218
219 try
220 {
221 UUID agentID = userProfile.ID;
222 InventoryData inventData = null;
223
224 try
225 {
226 inventData = GetInventorySkeleton(agentID);
227 }
228 catch (Exception e)
229 {
230 m_log.ErrorFormat(
231 "[LOGIN END]: Error retrieving inventory skeleton of agent {0} - {1}",
232 agentID, e);
233
234 // Let's not panic
235 if (!AllowLoginWithoutInventory())
236 return logResponse.CreateLoginInventoryFailedResponse();
237 }
238
239 if (inventData != null)
240 {
241 ArrayList AgentInventoryArray = inventData.InventoryArray;
242
243 Hashtable InventoryRootHash = new Hashtable();
244 InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
245 ArrayList InventoryRoot = new ArrayList();
246 InventoryRoot.Add(InventoryRootHash);
247
248 logResponse.InventoryRoot = InventoryRoot;
249 logResponse.InventorySkeleton = AgentInventoryArray;
250 }
251
252 // Inventory Library Section
253 Hashtable InventoryLibRootHash = new Hashtable();
254 InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
255 ArrayList InventoryLibRoot = new ArrayList();
256 InventoryLibRoot.Add(InventoryLibRootHash);
257
258 logResponse.InventoryLibRoot = InventoryLibRoot;
259 logResponse.InventoryLibraryOwner = GetLibraryOwner();
260 logResponse.InventoryLibrary = GetInventoryLibrary();
261
262 logResponse.CircuitCode = Util.RandomClass.Next();
263 logResponse.Lastname = userProfile.SurName;
264 logResponse.Firstname = userProfile.FirstName;
265 logResponse.AgentID = agentID;
266 logResponse.SessionID = userProfile.CurrentAgent.SessionID;
267 logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID;
268 logResponse.Message = GetMessage();
269 logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID));
270 logResponse.StartLocation = startLocationRequest;
271
272 if (CustomiseResponse(logResponse, userProfile, startLocationRequest, remoteClient))
273 {
274 userProfile.LastLogin = userProfile.CurrentAgent.LoginTime;
275 CommitAgent(ref userProfile);
276
277 // If we reach this point, then the login has successfully logged onto the grid
278 if (StatsManager.UserStats != null)
279 StatsManager.UserStats.AddSuccessfulLogin();
280
281 m_log.DebugFormat(
282 "[LOGIN END]: XMLRPC Authentication of user {0} {1} successful. Sending response to client.",
283 firstname, lastname);
284
285 return logResponse.ToXmlRpcResponse();
286 }
287 else
288 {
289 m_log.ErrorFormat("[LOGIN END]: XMLRPC informing user {0} {1} that login failed due to an unavailable region", firstname, lastname);
290 return logResponse.CreateDeadRegionResponse();
291 }
292 }
293 catch (Exception e)
294 {
295 m_log.Error("[LOGIN END]: XMLRPC Login failed, " + e);
296 m_log.Error(e.StackTrace);
297 }
298 }
299
300 m_log.Info("[LOGIN END]: XMLRPC Login failed. Sending back blank XMLRPC response");
301 return response;
302 }
303 finally
304 {
305 m_loginMutex.ReleaseMutex();
306 }
307 }
308
309 protected virtual bool TryAuthenticateXmlRpcLogin(
310 XmlRpcRequest request, string firstname, string lastname, out UserProfileData userProfile)
311 {
312 Hashtable requestData = (Hashtable)request.Params[0];
313
314 userProfile = GetTheUser(firstname, lastname);
315 if (userProfile == null)
316 {
317 m_log.Debug("[LOGIN END]: XMLRPC Could not find a profile for " + firstname + " " + lastname);
318 return false;
319 }
320 else
321 {
322 if (requestData.Contains("passwd"))
323 {
324 string passwd = (string)requestData["passwd"];
325 bool authenticated = AuthenticateUser(userProfile, passwd);
326
327 if (!authenticated)
328 m_log.DebugFormat("[LOGIN END]: XMLRPC User {0} {1} failed password authentication",
329 firstname, lastname);
330
331 return authenticated;
332 }
333
334 if (requestData.Contains("web_login_key"))
335 {
336 try
337 {
338 UUID webloginkey = new UUID((string)requestData["web_login_key"]);
339 bool authenticated = AuthenticateUser(userProfile, webloginkey);
340
341 if (!authenticated)
342 m_log.DebugFormat("[LOGIN END]: XMLRPC User {0} {1} failed web login key authentication",
343 firstname, lastname);
344
345 return authenticated;
346 }
347 catch (Exception e)
348 {
349 m_log.DebugFormat(
350 "[LOGIN END]: XMLRPC Bad web_login_key: {0} for user {1} {2}, exception {3}",
351 requestData["web_login_key"], firstname, lastname, e);
352
353 return false;
354 }
355 }
356
357 m_log.DebugFormat(
358 "[LOGIN END]: XMLRPC login request for {0} {1} contained neither a password nor a web login key",
359 firstname, lastname);
360 }
361
362 return false;
363 }
364
365 protected virtual bool TryAuthenticateLLSDLogin(string firstname, string lastname, string passwd, out UserProfileData userProfile)
366 {
367 bool GoodLogin = false;
368 userProfile = GetTheUser(firstname, lastname);
369 if (userProfile == null)
370 {
371 m_log.Info("[LOGIN]: LLSD Could not find a profile for " + firstname + " " + lastname);
372
373 return false;
374 }
375
376 GoodLogin = AuthenticateUser(userProfile, passwd);
377 return GoodLogin;
378 }
379
380 /// <summary>
381 /// Called when we receive the client's initial LLSD login_to_simulator request message
382 /// </summary>
383 /// <param name="request">The LLSD request</param>
384 /// <returns>The response to send</returns>
385 public OSD LLSDLoginMethod(OSD request, IPEndPoint remoteClient)
386 {
387 // Temporary fix
388 m_loginMutex.WaitOne();
389
390 try
391 {
392 // bool GoodLogin = false;
393
394 string startLocationRequest = "last";
395
396 UserProfileData userProfile = null;
397 LoginResponse logResponse = new LoginResponse();
398
399 if (request.Type == OSDType.Map)
400 {
401 OSDMap map = (OSDMap)request;
402
403 if (map.ContainsKey("first") && map.ContainsKey("last") && map.ContainsKey("passwd"))
404 {
405 string firstname = map["first"].AsString();
406 string lastname = map["last"].AsString();
407 string passwd = map["passwd"].AsString();
408
409 if (map.ContainsKey("start"))
410 {
411 m_log.Info("[LOGIN]: LLSD StartLocation Requested: " + map["start"].AsString());
412 startLocationRequest = map["start"].AsString();
413 }
414 m_log.Info("[LOGIN]: LLSD Login Requested for: '" + firstname + "' '" + lastname + "' / " + passwd);
415
416 if (!TryAuthenticateLLSDLogin(firstname, lastname, passwd, out userProfile))
417 {
418 return logResponse.CreateLoginFailedResponseLLSD();
419 }
420 }
421 else
422 return logResponse.CreateLoginFailedResponseLLSD();
423 }
424 else
425 return logResponse.CreateLoginFailedResponseLLSD();
426
427
428 if (userProfile.GodLevel < m_minLoginLevel)
429 {
430 return logResponse.CreateLoginBlockedResponseLLSD();
431 }
432 else
433 {
434 // If we already have a session...
435 if (userProfile.CurrentAgent != null && userProfile.CurrentAgent.AgentOnline)
436 {
437 userProfile.CurrentAgent.AgentOnline = false;
438
439 m_userManager.CommitAgent(ref userProfile);
440 // try to tell the region that their user is dead.
441 LogOffUser(userProfile, " LLSD You were logged off because you logged in from another location");
442
443 if (m_warn_already_logged)
444 {
445 // This is behavior for for grid, reject login
446 m_log.InfoFormat(
447 "[LOGIN END]: LLSD Notifying user {0} {1} that they are already logged in",
448 userProfile.FirstName, userProfile.SurName);
449
450 userProfile.CurrentAgent = null;
451 return logResponse.CreateAlreadyLoggedInResponseLLSD();
452 }
453 else
454 {
455 // This is behavior for standalone (silent logout of last hung session)
456 m_log.InfoFormat(
457 "[LOGIN]: LLSD User {0} {1} is already logged in, not notifying user, kicking old presence and starting new login.",
458 userProfile.FirstName, userProfile.SurName);
459 }
460 }
461
462 // Otherwise...
463 // Create a new agent session
464
465 // XXYY We don't need this
466 //m_userManager.ResetAttachments(userProfile.ID);
467
468 CreateAgent(userProfile, request);
469
470 // We need to commit the agent right here, even though the userProfile info is not complete
471 // at this point. There is another commit further down.
472 // This is for the new sessionID to be stored so that the region can check it for session authentication.
473 // CustomiseResponse->PrepareLoginToRegion
474 CommitAgent(ref userProfile);
475
476 try
477 {
478 UUID agentID = userProfile.ID;
479
480 //InventoryData inventData = GetInventorySkeleton(agentID);
481 InventoryData inventData = null;
482
483 try
484 {
485 inventData = GetInventorySkeleton(agentID);
486 }
487 catch (Exception e)
488 {
489 m_log.ErrorFormat(
490 "[LOGIN END]: LLSD Error retrieving inventory skeleton of agent {0}, {1} - {2}",
491 agentID, e.GetType(), e.Message);
492
493 return logResponse.CreateLoginFailedResponseLLSD();// .CreateLoginInventoryFailedResponseLLSD ();
494 }
495
496
497 ArrayList AgentInventoryArray = inventData.InventoryArray;
498
499 Hashtable InventoryRootHash = new Hashtable();
500 InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
501 ArrayList InventoryRoot = new ArrayList();
502 InventoryRoot.Add(InventoryRootHash);
503
504
505 // Inventory Library Section
506 Hashtable InventoryLibRootHash = new Hashtable();
507 InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
508 ArrayList InventoryLibRoot = new ArrayList();
509 InventoryLibRoot.Add(InventoryLibRootHash);
510
511 logResponse.InventoryLibRoot = InventoryLibRoot;
512 logResponse.InventoryLibraryOwner = GetLibraryOwner();
513 logResponse.InventoryRoot = InventoryRoot;
514 logResponse.InventorySkeleton = AgentInventoryArray;
515 logResponse.InventoryLibrary = GetInventoryLibrary();
516
517 logResponse.CircuitCode = (Int32)Util.RandomClass.Next();
518 logResponse.Lastname = userProfile.SurName;
519 logResponse.Firstname = userProfile.FirstName;
520 logResponse.AgentID = agentID;
521 logResponse.SessionID = userProfile.CurrentAgent.SessionID;
522 logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID;
523 logResponse.Message = GetMessage();
524 logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID));
525 logResponse.StartLocation = startLocationRequest;
526
527 try
528 {
529 CustomiseResponse(logResponse, userProfile, startLocationRequest, remoteClient);
530 }
531 catch (Exception ex)
532 {
533 m_log.Info("[LOGIN]: LLSD " + ex.ToString());
534 return logResponse.CreateDeadRegionResponseLLSD();
535 }
536
537 userProfile.LastLogin = userProfile.CurrentAgent.LoginTime;
538 CommitAgent(ref userProfile);
539
540 // If we reach this point, then the login has successfully logged onto the grid
541 if (StatsManager.UserStats != null)
542 StatsManager.UserStats.AddSuccessfulLogin();
543
544 m_log.DebugFormat(
545 "[LOGIN END]: LLSD Authentication of user {0} {1} successful. Sending response to client.",
546 userProfile.FirstName, userProfile.SurName);
547
548 return logResponse.ToLLSDResponse();
549 }
550 catch (Exception ex)
551 {
552 m_log.Info("[LOGIN]: LLSD " + ex.ToString());
553 return logResponse.CreateFailedResponseLLSD();
554 }
555 }
556 }
557 finally
558 {
559 m_loginMutex.ReleaseMutex();
560 }
561 }
562
563 public Hashtable ProcessHTMLLogin(Hashtable keysvals)
564 {
565 // Matches all unspecified characters
566 // Currently specified,; lowercase letters, upper case letters, numbers, underline
567 // period, space, parens, and dash.
568
569 Regex wfcut = new Regex("[^a-zA-Z0-9_\\.\\$ \\(\\)\\-]");
570
571 Hashtable returnactions = new Hashtable();
572 int statuscode = 200;
573
574 string firstname = String.Empty;
575 string lastname = String.Empty;
576 string location = String.Empty;
577 string region = String.Empty;
578 string grid = String.Empty;
579 string channel = String.Empty;
580 string version = String.Empty;
581 string lang = String.Empty;
582 string password = String.Empty;
583 string errormessages = String.Empty;
584
585 // the client requires the HTML form field be named 'username'
586 // however, the data it sends when it loads the first time is 'firstname'
587 // another one of those little nuances.
588
589 if (keysvals.Contains("firstname"))
590 firstname = wfcut.Replace((string)keysvals["firstname"], String.Empty, 99999);
591
592 if (keysvals.Contains("username"))
593 firstname = wfcut.Replace((string)keysvals["username"], String.Empty, 99999);
594
595 if (keysvals.Contains("lastname"))
596 lastname = wfcut.Replace((string)keysvals["lastname"], String.Empty, 99999);
597
598 if (keysvals.Contains("location"))
599 location = wfcut.Replace((string)keysvals["location"], String.Empty, 99999);
600
601 if (keysvals.Contains("region"))
602 region = wfcut.Replace((string)keysvals["region"], String.Empty, 99999);
603
604 if (keysvals.Contains("grid"))
605 grid = wfcut.Replace((string)keysvals["grid"], String.Empty, 99999);
606
607 if (keysvals.Contains("channel"))
608 channel = wfcut.Replace((string)keysvals["channel"], String.Empty, 99999);
609
610 if (keysvals.Contains("version"))
611 version = wfcut.Replace((string)keysvals["version"], String.Empty, 99999);
612
613 if (keysvals.Contains("lang"))
614 lang = wfcut.Replace((string)keysvals["lang"], String.Empty, 99999);
615
616 if (keysvals.Contains("password"))
617 password = wfcut.Replace((string)keysvals["password"], String.Empty, 99999);
618
619 // load our login form.
620 string loginform = GetLoginForm(firstname, lastname, location, region, grid, channel, version, lang, password, errormessages);
621
622 if (keysvals.ContainsKey("show_login_form"))
623 {
624 UserProfileData user = GetTheUser(firstname, lastname);
625 bool goodweblogin = false;
626
627 if (user != null)
628 goodweblogin = AuthenticateUser(user, password);
629
630 if (goodweblogin)
631 {
632 UUID webloginkey = UUID.Random();
633 m_userManager.StoreWebLoginKey(user.ID, webloginkey);
634 //statuscode = 301;
635
636 // string redirectURL = "about:blank?redirect-http-hack=" +
637 // HttpUtility.UrlEncode("secondlife:///app/login?first_name=" + firstname + "&last_name=" +
638 // lastname +
639 // "&location=" + location + "&grid=Other&web_login_key=" + webloginkey.ToString());
640 //m_log.Info("[WEB]: R:" + redirectURL);
641 returnactions["int_response_code"] = statuscode;
642 //returnactions["str_redirect_location"] = redirectURL;
643 //returnactions["str_response_string"] = "<HTML><BODY>GoodLogin</BODY></HTML>";
644 returnactions["str_response_string"] = webloginkey.ToString();
645 }
646 else
647 {
648 errormessages = "The Username and password supplied did not match our records. Check your caps lock and try again";
649
650 loginform = GetLoginForm(firstname, lastname, location, region, grid, channel, version, lang, password, errormessages);
651 returnactions["int_response_code"] = statuscode;
652 returnactions["str_response_string"] = loginform;
653 }
654 }
655 else
656 {
657 returnactions["int_response_code"] = statuscode;
658 returnactions["str_response_string"] = loginform;
659 }
660 return returnactions;
661 }
662
663 public string GetLoginForm(string firstname, string lastname, string location, string region,
664 string grid, string channel, string version, string lang,
665 string password, string errormessages)
666 {
667 // inject our values in the form at the markers
668
669 string loginform = String.Empty;
670 string file = Path.Combine(Util.configDir(), "http_loginform.html");
671 if (!File.Exists(file))
672 {
673 loginform = GetDefaultLoginForm();
674 }
675 else
676 {
677 StreamReader sr = File.OpenText(file);
678 loginform = sr.ReadToEnd();
679 sr.Close();
680 }
681
682 loginform = loginform.Replace("[$firstname]", firstname);
683 loginform = loginform.Replace("[$lastname]", lastname);
684 loginform = loginform.Replace("[$location]", location);
685 loginform = loginform.Replace("[$region]", region);
686 loginform = loginform.Replace("[$grid]", grid);
687 loginform = loginform.Replace("[$channel]", channel);
688 loginform = loginform.Replace("[$version]", version);
689 loginform = loginform.Replace("[$lang]", lang);
690 loginform = loginform.Replace("[$password]", password);
691 loginform = loginform.Replace("[$errors]", errormessages);
692
693 return loginform;
694 }
695
696 public string GetDefaultLoginForm()
697 {
698 string responseString =
699 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
700 responseString += "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
701 responseString += "<head>";
702 responseString += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
703 responseString += "<meta http-equiv=\"cache-control\" content=\"no-cache\">";
704 responseString += "<meta http-equiv=\"Pragma\" content=\"no-cache\">";
705 responseString += "<title>OpenSim Login</title>";
706 responseString += "<body><br />";
707 responseString += "<div id=\"login_box\">";
708
709 responseString += "<form action=\"/go.cgi\" method=\"GET\" id=\"login-form\">";
710
711 responseString += "<div id=\"message\">[$errors]</div>";
712 responseString += "<fieldset id=\"firstname\">";
713 responseString += "<legend>First Name:</legend>";
714 responseString += "<input type=\"text\" id=\"firstname_input\" size=\"15\" maxlength=\"100\" name=\"username\" value=\"[$firstname]\" />";
715 responseString += "</fieldset>";
716 responseString += "<fieldset id=\"lastname\">";
717 responseString += "<legend>Last Name:</legend>";
718 responseString += "<input type=\"text\" size=\"15\" maxlength=\"100\" name=\"lastname\" value=\"[$lastname]\" />";
719 responseString += "</fieldset>";
720 responseString += "<fieldset id=\"password\">";
721 responseString += "<legend>Password:</legend>";
722 responseString += "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";
723 responseString += "<tr>";
724 responseString += "<td colspan=\"2\"><input type=\"password\" size=\"15\" maxlength=\"100\" name=\"password\" value=\"[$password]\" /></td>";
725 responseString += "</tr>";
726 responseString += "<tr>";
727 responseString += "<td valign=\"middle\"><input type=\"checkbox\" name=\"remember_password\" id=\"remember_password\" [$remember_password] style=\"margin-left:0px;\"/></td>";
728 responseString += "<td><label for=\"remember_password\">Remember password</label></td>";
729 responseString += "</tr>";
730 responseString += "</table>";
731 responseString += "</fieldset>";
732 responseString += "<input type=\"hidden\" name=\"show_login_form\" value=\"FALSE\" />";
733 responseString += "<input type=\"hidden\" name=\"method\" value=\"login\" />";
734 responseString += "<input type=\"hidden\" id=\"grid\" name=\"grid\" value=\"[$grid]\" />";
735 responseString += "<input type=\"hidden\" id=\"region\" name=\"region\" value=\"[$region]\" />";
736 responseString += "<input type=\"hidden\" id=\"location\" name=\"location\" value=\"[$location]\" />";
737 responseString += "<input type=\"hidden\" id=\"channel\" name=\"channel\" value=\"[$channel]\" />";
738 responseString += "<input type=\"hidden\" id=\"version\" name=\"version\" value=\"[$version]\" />";
739 responseString += "<input type=\"hidden\" id=\"lang\" name=\"lang\" value=\"[$lang]\" />";
740 responseString += "<div id=\"submitbtn\">";
741 responseString += "<input class=\"input_over\" type=\"submit\" value=\"Connect\" />";
742 responseString += "</div>";
743 responseString += "<div id=\"connecting\" style=\"visibility:hidden\"> Connecting...</div>";
744
745 responseString += "<div id=\"helplinks\"><!---";
746 responseString += "<a href=\"#join now link\" target=\"_blank\"></a> | ";
747 responseString += "<a href=\"#forgot password link\" target=\"_blank\"></a>";
748 responseString += "---></div>";
749
750 responseString += "<div id=\"channelinfo\"> [$channel] | [$version]=[$lang]</div>";
751 responseString += "</form>";
752 responseString += "<script language=\"JavaScript\">";
753 responseString += "document.getElementById('firstname_input').focus();";
754 responseString += "</script>";
755 responseString += "</div>";
756 responseString += "</div>";
757 responseString += "</body>";
758 responseString += "</html>";
759
760 return responseString;
761 }
762
763 /// <summary>
764 /// Saves a target agent to the database
765 /// </summary>
766 /// <param name="profile">The users profile</param>
767 /// <returns>Successful?</returns>
768 public bool CommitAgent(ref UserProfileData profile)
769 {
770 return m_userManager.CommitAgent(ref profile);
771 }
772
773 /// <summary>
774 /// Checks a user against it's password hash
775 /// </summary>
776 /// <param name="profile">The users profile</param>
777 /// <param name="password">The supplied password</param>
778 /// <returns>Authenticated?</returns>
779 public virtual bool AuthenticateUser(UserProfileData profile, string password)
780 {
781 bool passwordSuccess = false;
782 //m_log.InfoFormat("[LOGIN]: Authenticating {0} {1} ({2})", profile.FirstName, profile.SurName, profile.ID);
783
784 // Web Login method seems to also occasionally send the hashed password itself
785
786 // we do this to get our hash in a form that the server password code can consume
787 // when the web-login-form submits the password in the clear (supposed to be over SSL!)
788 if (!password.StartsWith("$1$"))
789 password = "$1$" + Util.Md5Hash(password);
790
791 password = password.Remove(0, 3); //remove $1$
792
793 string s = Util.Md5Hash(password + ":" + profile.PasswordSalt);
794 // Testing...
795 //m_log.Info("[LOGIN]: SubHash:" + s + " userprofile:" + profile.passwordHash);
796 //m_log.Info("[LOGIN]: userprofile:" + profile.passwordHash + " SubCT:" + password);
797
798 passwordSuccess = (profile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
799 || profile.PasswordHash.Equals(password, StringComparison.InvariantCulture));
800
801 return passwordSuccess;
802 }
803
804 public virtual bool AuthenticateUser(UserProfileData profile, UUID webloginkey)
805 {
806 bool passwordSuccess = false;
807 m_log.InfoFormat("[LOGIN]: Authenticating {0} {1} ({2})", profile.FirstName, profile.SurName, profile.ID);
808
809 // Match web login key unless it's the default weblogin key UUID.Zero
810 passwordSuccess = ((profile.WebLoginKey == webloginkey) && profile.WebLoginKey != UUID.Zero);
811
812 return passwordSuccess;
813 }
814
815 /// <summary>
816 ///
817 /// </summary>
818 /// <param name="profile"></param>
819 /// <param name="request"></param>
820 public void CreateAgent(UserProfileData profile, XmlRpcRequest request)
821 {
822 m_userManager.CreateAgent(profile, request);
823 }
824
825 public void CreateAgent(UserProfileData profile, OSD request)
826 {
827 m_userManager.CreateAgent(profile, request);
828 }
829
830 /// <summary>
831 ///
832 /// </summary>
833 /// <param name="firstname"></param>
834 /// <param name="lastname"></param>
835 /// <returns></returns>
836 public virtual UserProfileData GetTheUser(string firstname, string lastname)
837 {
838 return m_userManager.GetUserProfile(firstname, lastname);
839 }
840
841 /// <summary>
842 ///
843 /// </summary>
844 /// <returns></returns>
845 public virtual string GetMessage()
846 {
847 return m_welcomeMessage;
848 }
849
850 private static LoginResponse.BuddyList ConvertFriendListItem(List<FriendListItem> LFL)
851 {
852 LoginResponse.BuddyList buddylistreturn = new LoginResponse.BuddyList();
853 foreach (FriendListItem fl in LFL)
854 {
855 LoginResponse.BuddyList.BuddyInfo buddyitem = new LoginResponse.BuddyList.BuddyInfo(fl.Friend);
856 buddyitem.BuddyID = fl.Friend;
857 buddyitem.BuddyRightsHave = (int)fl.FriendListOwnerPerms;
858 buddyitem.BuddyRightsGiven = (int)fl.FriendPerms;
859 buddylistreturn.AddNewBuddy(buddyitem);
860 }
861 return buddylistreturn;
862 }
863
864 /// <summary>
865 /// Converts the inventory library skeleton into the form required by the rpc request.
866 /// </summary>
867 /// <returns></returns>
868 protected virtual ArrayList GetInventoryLibrary()
869 {
870 Dictionary<UUID, InventoryFolderImpl> rootFolders
871 = m_libraryRootFolder.RequestSelfAndDescendentFolders();
872 ArrayList folderHashes = new ArrayList();
873
874 foreach (InventoryFolderBase folder in rootFolders.Values)
875 {
876 Hashtable TempHash = new Hashtable();
877 TempHash["name"] = folder.Name;
878 TempHash["parent_id"] = folder.ParentID.ToString();
879 TempHash["version"] = (Int32)folder.Version;
880 TempHash["type_default"] = (Int32)folder.Type;
881 TempHash["folder_id"] = folder.ID.ToString();
882 folderHashes.Add(TempHash);
883 }
884
885 return folderHashes;
886 }
887
888 /// <summary>
889 ///
890 /// </summary>
891 /// <returns></returns>
892 protected virtual ArrayList GetLibraryOwner()
893 {
894 //for now create random inventory library owner
895 Hashtable TempHash = new Hashtable();
896 TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000";
897 ArrayList inventoryLibOwner = new ArrayList();
898 inventoryLibOwner.Add(TempHash);
899 return inventoryLibOwner;
900 }
901
902 public class InventoryData
903 {
904 public ArrayList InventoryArray = null;
905 public UUID RootFolderID = UUID.Zero;
906
907 public InventoryData(ArrayList invList, UUID rootID)
908 {
909 InventoryArray = invList;
910 RootFolderID = rootID;
911 }
912 }
913
914 protected void SniffLoginKey(Uri uri, Hashtable requestData)
915 {
916 string uri_str = uri.ToString();
917 string[] parts = uri_str.Split(new char[] { '=' });
918 if (parts.Length > 1)
919 {
920 string web_login_key = parts[1];
921 requestData.Add("web_login_key", web_login_key);
922 m_log.InfoFormat("[LOGIN]: Login with web_login_key {0}", web_login_key);
923 }
924 }
925
926 /// <summary>
927 /// Customises the login response and fills in missing values. This method also tells the login region to
928 /// expect a client connection.
929 /// </summary>
930 /// <param name="response">The existing response</param>
931 /// <param name="theUser">The user profile</param>
932 /// <param name="startLocationRequest">The requested start location</param>
933 /// <returns>true on success, false if the region was not successfully told to expect a user connection</returns>
934 public bool CustomiseResponse(LoginResponse response, UserProfileData theUser, string startLocationRequest, IPEndPoint client)
935 {
936 // add active gestures to login-response
937 AddActiveGestures(response, theUser);
938
939 // HomeLocation
940 RegionInfo homeInfo = null;
941
942 // use the homeRegionID if it is stored already. If not, use the regionHandle as before
943 UUID homeRegionId = theUser.HomeRegionID;
944 ulong homeRegionHandle = theUser.HomeRegion;
945 if (homeRegionId != UUID.Zero)
946 {
947 homeInfo = GetRegionInfo(homeRegionId);
948 }
949 else
950 {
951 homeInfo = GetRegionInfo(homeRegionHandle);
952 }
953
954 if (homeInfo != null)
955 {
956 response.Home =
957 string.Format(
958 "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
959 (homeInfo.RegionLocX * Constants.RegionSize),
960 (homeInfo.RegionLocY * Constants.RegionSize),
961 theUser.HomeLocation.X, theUser.HomeLocation.Y, theUser.HomeLocation.Z,
962 theUser.HomeLookAt.X, theUser.HomeLookAt.Y, theUser.HomeLookAt.Z);
963 }
964 else
965 {
966 m_log.InfoFormat("not found the region at {0} {1}", theUser.HomeRegionX, theUser.HomeRegionY);
967 // Emergency mode: Home-region isn't available, so we can't request the region info.
968 // Use the stored home regionHandle instead.
969 // NOTE: If the home-region moves, this will be wrong until the users update their user-profile again
970 ulong regionX = homeRegionHandle >> 32;
971 ulong regionY = homeRegionHandle & 0xffffffff;
972 response.Home =
973 string.Format(
974 "{{'region_handle':[r{0},r{1}], 'position':[r{2},r{3},r{4}], 'look_at':[r{5},r{6},r{7}]}}",
975 regionX, regionY,
976 theUser.HomeLocation.X, theUser.HomeLocation.Y, theUser.HomeLocation.Z,
977 theUser.HomeLookAt.X, theUser.HomeLookAt.Y, theUser.HomeLookAt.Z);
978
979 m_log.InfoFormat("[LOGIN] Home region of user {0} {1} is not available; using computed region position {2} {3}",
980 theUser.FirstName, theUser.SurName,
981 regionX, regionY);
982 }
983
984 // StartLocation
985 RegionInfo regionInfo = null;
986 if (startLocationRequest == "home")
987 {
988 regionInfo = homeInfo;
989 theUser.CurrentAgent.Position = theUser.HomeLocation;
990 response.LookAt = String.Format("[r{0},r{1},r{2}]", theUser.HomeLookAt.X.ToString(),
991 theUser.HomeLookAt.Y.ToString(), theUser.HomeLookAt.Z.ToString());
992 }
993 else if (startLocationRequest == "last")
994 {
995 UUID lastRegion = theUser.CurrentAgent.Region;
996 regionInfo = GetRegionInfo(lastRegion);
997 response.LookAt = String.Format("[r{0},r{1},r{2}]", theUser.CurrentAgent.LookAt.X.ToString(),
998 theUser.CurrentAgent.LookAt.Y.ToString(), theUser.CurrentAgent.LookAt.Z.ToString());
999 }
1000 else
1001 {
1002 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$");
1003 Match uriMatch = reURI.Match(startLocationRequest);
1004 if (uriMatch == null)
1005 {
1006 m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, but can't process it", startLocationRequest);
1007 }
1008 else
1009 {
1010 string region = uriMatch.Groups["region"].ToString();
1011 regionInfo = RequestClosestRegion(region);
1012 if (regionInfo == null)
1013 {
1014 m_log.InfoFormat("[LOGIN]: Got Custom Login URL {0}, can't locate region {1}", startLocationRequest, region);
1015 }
1016 else
1017 {
1018 theUser.CurrentAgent.Position = new Vector3(float.Parse(uriMatch.Groups["x"].Value),
1019 float.Parse(uriMatch.Groups["y"].Value), float.Parse(uriMatch.Groups["z"].Value));
1020 }
1021 }
1022 response.LookAt = "[r0,r1,r0]";
1023 // can be: last, home, safe, url
1024 response.StartLocation = "url";
1025 }
1026
1027 if ((regionInfo != null) && (PrepareLoginToRegion(regionInfo, theUser, response, client)))
1028 {
1029 return true;
1030 }
1031
1032 // Get the default region handle
1033 ulong defaultHandle = Utils.UIntsToLong(m_defaultHomeX * Constants.RegionSize, m_defaultHomeY * Constants.RegionSize);
1034
1035 // If we haven't already tried the default region, reset regionInfo
1036 if (regionInfo != null && defaultHandle != regionInfo.RegionHandle)
1037 regionInfo = null;
1038
1039 if (regionInfo == null)
1040 {
1041 m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead");
1042 regionInfo = GetRegionInfo(defaultHandle);
1043 }
1044
1045 if (regionInfo == null)
1046 {
1047 m_log.ErrorFormat("[LOGIN]: Sending user to any region");
1048 regionInfo = RequestClosestRegion(String.Empty);
1049 }
1050
1051 theUser.CurrentAgent.Position = new Vector3(128f, 128f, 0f);
1052 response.StartLocation = "safe";
1053
1054 return PrepareLoginToRegion(regionInfo, theUser, response, client);
1055 }
1056
1057 protected abstract RegionInfo RequestClosestRegion(string region);
1058 protected abstract RegionInfo GetRegionInfo(ulong homeRegionHandle);
1059 protected abstract RegionInfo GetRegionInfo(UUID homeRegionId);
1060
1061 /// <summary>
1062 /// Prepare a login to the given region. This involves both telling the region to expect a connection
1063 /// and appropriately customising the response to the user.
1064 /// </summary>
1065 /// <param name="sim"></param>
1066 /// <param name="user"></param>
1067 /// <param name="response"></param>
1068 /// <param name="remoteClient"></param>
1069 /// <returns>true if the region was successfully contacted, false otherwise</returns>
1070 protected abstract bool PrepareLoginToRegion(
1071 RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint client);
1072
1073 /// <summary>
1074 /// Add active gestures of the user to the login response.
1075 /// </summary>
1076 /// <param name="response">
1077 /// A <see cref="LoginResponse"/>
1078 /// </param>
1079 /// <param name="theUser">
1080 /// A <see cref="UserProfileData"/>
1081 /// </param>
1082 protected void AddActiveGestures(LoginResponse response, UserProfileData theUser)
1083 {
1084 List<InventoryItemBase> gestures = null;
1085 try
1086 {
1087 if (m_InventoryService != null)
1088 gestures = m_InventoryService.GetActiveGestures(theUser.ID);
1089 else
1090 gestures = m_interInventoryService.GetActiveGestures(theUser.ID);
1091 }
1092 catch (Exception e)
1093 {
1094 m_log.Debug("[LOGIN]: Unable to retrieve active gestures from inventory server. Reason: " + e.Message);
1095 }
1096 //m_log.DebugFormat("[LOGIN]: AddActiveGestures, found {0}", gestures == null ? 0 : gestures.Count);
1097 ArrayList list = new ArrayList();
1098 if (gestures != null)
1099 {
1100 foreach (InventoryItemBase gesture in gestures)
1101 {
1102 Hashtable item = new Hashtable();
1103 item["item_id"] = gesture.ID.ToString();
1104 item["asset_id"] = gesture.AssetID.ToString();
1105 list.Add(item);
1106 }
1107 }
1108 response.ActiveGestures = list;
1109 }
1110
1111 /// <summary>
1112 /// Get the initial login inventory skeleton (in other words, the folder structure) for the given user.
1113 /// </summary>
1114 /// <param name="userID"></param>
1115 /// <returns></returns>
1116 /// <exception cref='System.Exception'>This will be thrown if there is a problem with the inventory service</exception>
1117 protected InventoryData GetInventorySkeleton(UUID userID)
1118 {
1119 List<InventoryFolderBase> folders = null;
1120 if (m_InventoryService != null)
1121 {
1122 folders = m_InventoryService.GetInventorySkeleton(userID);
1123 }
1124 else
1125 {
1126 folders = m_interInventoryService.GetInventorySkeleton(userID);
1127 }
1128
1129 // If we have user auth but no inventory folders for some reason, create a new set of folders.
1130 if (folders == null || folders.Count == 0)
1131 {
1132 m_log.InfoFormat(
1133 "[LOGIN]: A root inventory folder for user {0} was not found. Requesting creation.", userID);
1134
1135 // Although the create user function creates a new agent inventory along with a new user profile, some
1136 // tools are creating the user profile directly in the database without creating the inventory. At
1137 // this time we'll accomodate them by lazily creating the user inventory now if it doesn't already
1138 // exist.
1139 if (m_interInventoryService != null)
1140 {
1141 if (!m_interInventoryService.CreateNewUserInventory(userID))
1142 {
1143 throw new Exception(
1144 String.Format(
1145 "The inventory creation request for user {0} did not succeed."
1146 + " Please contact your inventory service provider for more information.",
1147 userID));
1148 }
1149 }
1150 else if ((m_InventoryService != null) && !m_InventoryService.CreateUserInventory(userID))
1151 {
1152 throw new Exception(
1153 String.Format(
1154 "The inventory creation request for user {0} did not succeed."
1155 + " Please contact your inventory service provider for more information.",
1156 userID));
1157 }
1158
1159
1160 m_log.InfoFormat("[LOGIN]: A new inventory skeleton was successfully created for user {0}", userID);
1161
1162 if (m_InventoryService != null)
1163 folders = m_InventoryService.GetInventorySkeleton(userID);
1164 else
1165 folders = m_interInventoryService.GetInventorySkeleton(userID);
1166
1167 if (folders == null || folders.Count == 0)
1168 {
1169 throw new Exception(
1170 String.Format(
1171 "A root inventory folder for user {0} could not be retrieved from the inventory service",
1172 userID));
1173 }
1174 }
1175
1176 UUID rootID = UUID.Zero;
1177 ArrayList AgentInventoryArray = new ArrayList();
1178 Hashtable TempHash;
1179 foreach (InventoryFolderBase InvFolder in folders)
1180 {
1181 if (InvFolder.ParentID == UUID.Zero)
1182 {
1183 rootID = InvFolder.ID;
1184 }
1185 TempHash = new Hashtable();
1186 TempHash["name"] = InvFolder.Name;
1187 TempHash["parent_id"] = InvFolder.ParentID.ToString();
1188 TempHash["version"] = (Int32)InvFolder.Version;
1189 TempHash["type_default"] = (Int32)InvFolder.Type;
1190 TempHash["folder_id"] = InvFolder.ID.ToString();
1191 AgentInventoryArray.Add(TempHash);
1192 }
1193
1194 return new InventoryData(AgentInventoryArray, rootID);
1195 }
1196
1197 protected virtual bool AllowLoginWithoutInventory()
1198 {
1199 return false;
1200 }
1201
1202 public XmlRpcResponse XmlRPCCheckAuthSession(XmlRpcRequest request, IPEndPoint remoteClient)
1203 {
1204 XmlRpcResponse response = new XmlRpcResponse();
1205 Hashtable requestData = (Hashtable)request.Params[0];
1206
1207 string authed = "FALSE";
1208 if (requestData.Contains("avatar_uuid") && requestData.Contains("session_id"))
1209 {
1210 UUID guess_aid;
1211 UUID guess_sid;
1212
1213 UUID.TryParse((string)requestData["avatar_uuid"], out guess_aid);
1214 if (guess_aid == UUID.Zero)
1215 {
1216 return Util.CreateUnknownUserErrorResponse();
1217 }
1218
1219 UUID.TryParse((string)requestData["session_id"], out guess_sid);
1220 if (guess_sid == UUID.Zero)
1221 {
1222 return Util.CreateUnknownUserErrorResponse();
1223 }
1224
1225 if (m_userManager.VerifySession(guess_aid, guess_sid))
1226 {
1227 authed = "TRUE";
1228 m_log.InfoFormat("[UserManager]: CheckAuthSession TRUE for user {0}", guess_aid);
1229 }
1230 else
1231 {
1232 m_log.InfoFormat("[UserManager]: CheckAuthSession FALSE");
1233 return Util.CreateUnknownUserErrorResponse();
1234 }
1235 }
1236
1237 Hashtable responseData = new Hashtable();
1238 responseData["auth_session"] = authed;
1239 response.Value = responseData;
1240 return response;
1241 }
1242 }
1243} \ No newline at end of file