aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Server
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Server/Base/ServerUtils.cs4
-rw-r--r--OpenSim/Server/Handlers/Friends/FriendServerConnector.cs6
-rw-r--r--OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs48
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs71
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs323
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs280
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs205
7 files changed, 930 insertions, 7 deletions
diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs
index f4472c7..6743a2e 100644
--- a/OpenSim/Server/Base/ServerUtils.cs
+++ b/OpenSim/Server/Base/ServerUtils.cs
@@ -65,6 +65,10 @@ namespace OpenSim.Server.Base
65 /// <returns></returns> 65 /// <returns></returns>
66 public static T LoadPlugin<T>(string dllName, Object[] args) where T:class 66 public static T LoadPlugin<T>(string dllName, Object[] args) where T:class
67 { 67 {
68 // This is good to debug configuration problems
69 //if (dllName == string.Empty)
70 // Util.PrintCallStack();
71
68 string[] parts = dllName.Split(new char[] {':'}); 72 string[] parts = dllName.Split(new char[] {':'});
69 73
70 dllName = parts[0]; 74 dllName = parts[0];
diff --git a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
index 074f869..5784bdf 100644
--- a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
+++ b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
@@ -46,14 +46,14 @@ namespace OpenSim.Server.Handlers.Friends
46 if (serverConfig == null) 46 if (serverConfig == null)
47 throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); 47 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
48 48
49 string gridService = serverConfig.GetString("LocalServiceModule", 49 string theService = serverConfig.GetString("LocalServiceModule",
50 String.Empty); 50 String.Empty);
51 51
52 if (gridService == String.Empty) 52 if (theService == String.Empty)
53 throw new Exception("No LocalServiceModule in config file"); 53 throw new Exception("No LocalServiceModule in config file");
54 54
55 Object[] args = new Object[] { config }; 55 Object[] args = new Object[] { config };
56 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(gridService, args); 56 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
57 57
58 server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService)); 58 server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService));
59 } 59 }
diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
index b168bb3..9969086 100644
--- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
@@ -82,12 +82,18 @@ namespace OpenSim.Server.Handlers.Friends
82 case "getfriends": 82 case "getfriends":
83 return GetFriends(request); 83 return GetFriends(request);
84 84
85 case "getfriends_string":
86 return GetFriendsString(request);
87
85 case "storefriend": 88 case "storefriend":
86 return StoreFriend(request); 89 return StoreFriend(request);
87 90
88 case "deletefriend": 91 case "deletefriend":
89 return DeleteFriend(request); 92 return DeleteFriend(request);
90 93
94 case "deletefriend_string":
95 return DeleteFriendString(request);
96
91 } 97 }
92 m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); 98 m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
93 } 99 }
@@ -111,7 +117,25 @@ namespace OpenSim.Server.Handlers.Friends
111 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends"); 117 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
112 118
113 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); 119 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
114 //m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count); 120
121 return PackageFriends(finfos);
122 }
123
124 byte[] GetFriendsString(Dictionary<string, object> request)
125 {
126 string principalID = string.Empty;
127 if (request.ContainsKey("PRINCIPALID"))
128 principalID = request["PRINCIPALID"].ToString();
129 else
130 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
131
132 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
133
134 return PackageFriends(finfos);
135 }
136
137 private byte[] PackageFriends(FriendInfo[] finfos)
138 {
115 139
116 Dictionary<string, object> result = new Dictionary<string, object>(); 140 Dictionary<string, object> result = new Dictionary<string, object>();
117 if ((finfos == null) || ((finfos != null) && (finfos.Length == 0))) 141 if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))
@@ -138,7 +162,7 @@ namespace OpenSim.Server.Handlers.Friends
138 { 162 {
139 FriendInfo friend = new FriendInfo(request); 163 FriendInfo friend = new FriendInfo(request);
140 164
141 bool success = m_FriendsService.StoreFriend(friend.PrincipalID, friend.Friend, friend.MyFlags); 165 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, friend.MyFlags);
142 166
143 if (success) 167 if (success)
144 return SuccessResult(); 168 return SuccessResult();
@@ -163,7 +187,25 @@ namespace OpenSim.Server.Handlers.Friends
163 else 187 else
164 return FailureResult(); 188 return FailureResult();
165 } 189 }
166 190
191 byte[] DeleteFriendString(Dictionary<string, object> request)
192 {
193 string principalID = string.Empty;
194 if (request.ContainsKey("PRINCIPALID"))
195 principalID = request["PRINCIPALID"].ToString();
196 else
197 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to delete friend");
198 string friend = string.Empty;
199 if (request.ContainsKey("FRIEND"))
200 friend = request["FRIEND"].ToString();
201
202 bool success = m_FriendsService.Delete(principalID, friend);
203 if (success)
204 return SuccessResult();
205 else
206 return FailureResult();
207 }
208
167 #endregion 209 #endregion
168 210
169 #region Misc 211 #region Misc
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
new file mode 100644
index 0000000..82a7220
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
@@ -0,0 +1,71 @@
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 Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34
35namespace OpenSim.Server.Handlers.Hypergrid
36{
37 public class HGFriendsServerConnector : ServiceConnector
38 {
39 private IFriendsService m_FriendsService;
40 private IUserAgentService m_UserAgentService;
41 private string m_ConfigName = "HGFriendsService";
42
43 public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) :
44 base(config, server, configName)
45 {
46 if (configName != string.Empty)
47 m_ConfigName = configName;
48
49 IConfig serverConfig = config.Configs[m_ConfigName];
50 if (serverConfig == null)
51 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
52
53 string theService = serverConfig.GetString("LocalServiceModule",
54 String.Empty);
55
56 if (theService == String.Empty)
57 throw new Exception("No LocalServiceModule in config file");
58
59 Object[] args = new Object[] { config };
60 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
61
62 theService = serverConfig.GetString("UserAgentService", string.Empty);
63 if (theService == String.Empty)
64 throw new Exception("No UserAgentService in " + m_ConfigName);
65
66 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(theService, args);
67
68 server.AddStreamHandler(new HGFriendsServerPostHandler(m_FriendsService, m_UserAgentService));
69 }
70 }
71}
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
new file mode 100644
index 0000000..841811e
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
@@ -0,0 +1,323 @@
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 Nini.Config;
29using log4net;
30using System;
31using System.Reflection;
32using System.IO;
33using System.Net;
34using System.Text;
35using System.Text.RegularExpressions;
36using System.Xml;
37using System.Xml.Serialization;
38using System.Collections.Generic;
39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces;
41using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
42using OpenSim.Framework;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenMetaverse;
45
46namespace OpenSim.Server.Handlers.Hypergrid
47{
48 public class HGFriendsServerPostHandler : BaseStreamHandler
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private IFriendsService m_FriendsService;
53 private IUserAgentService m_UserAgentService;
54
55 public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) :
56 base("POST", "/hgfriends")
57 {
58 m_FriendsService = service;
59 m_UserAgentService = uservice;
60 m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On");
61 }
62
63 public override byte[] Handle(string path, Stream requestData,
64 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
65 {
66 StreamReader sr = new StreamReader(requestData);
67 string body = sr.ReadToEnd();
68 sr.Close();
69 body = body.Trim();
70
71 //m_log.DebugFormat("[XXX]: query String: {0}", body);
72
73 try
74 {
75 Dictionary<string, object> request =
76 ServerUtils.ParseQueryString(body);
77
78 if (!request.ContainsKey("METHOD"))
79 return FailureResult();
80
81 string method = request["METHOD"].ToString();
82
83 switch (method)
84 {
85 case "getfriendperms":
86 return GetFriendPerms(request);
87
88 case "newfriendship":
89 return NewFriendship(request);
90
91 case "deletefriendship":
92 return DeleteFriendship(request);
93 }
94 m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
95 }
96 catch (Exception e)
97 {
98 m_log.DebugFormat("[HGFRIENDS HANDLER]: Exception {0}", e);
99 }
100
101 return FailureResult();
102
103 }
104
105 #region Method-specific handlers
106
107 byte[] GetFriendPerms(Dictionary<string, object> request)
108 {
109 if (!VerifyServiceKey(request))
110 return FailureResult();
111
112 UUID principalID = UUID.Zero;
113 if (request.ContainsKey("PRINCIPALID"))
114 UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID);
115 else
116 {
117 m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friend perms");
118 return FailureResult();
119 }
120
121 UUID friendID = UUID.Zero;
122 if (request.ContainsKey("FRIENDID"))
123 UUID.TryParse(request["FRIENDID"].ToString(), out friendID);
124 else
125 {
126 m_log.WarnFormat("[HGFRIENDS HANDLER]: no friendID in request to get friend perms");
127 return FailureResult();
128 }
129
130 string perms = "0";
131 FriendInfo[] friendsInfo = m_FriendsService.GetFriends(principalID);
132 foreach (FriendInfo finfo in friendsInfo)
133 {
134 if (finfo.Friend.StartsWith(friendID.ToString()))
135 return SuccessResult(finfo.TheirFlags.ToString());
136 }
137
138 return FailureResult("Friend not found");
139 }
140
141 byte[] NewFriendship(Dictionary<string, object> request)
142 {
143 m_log.DebugFormat("[XXX] 1");
144 if (!VerifyServiceKey(request))
145 return FailureResult();
146
147 m_log.DebugFormat("[XXX] 2");
148 // OK, can proceed
149 FriendInfo friend = new FriendInfo(request);
150 UUID friendID;
151 string tmp = string.Empty;
152 m_log.DebugFormat("[XXX] 3");
153 if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
154 return FailureResult();
155
156
157 m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend);
158
159 // If the friendship already exists, return fail
160 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
161 foreach (FriendInfo finfo in finfos)
162 if (finfo.Friend.StartsWith(friendID.ToString()))
163 return FailureResult();
164
165 // the user needs to confirm when he gets home
166 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
167
168 if (success)
169 return SuccessResult();
170 else
171 return FailureResult();
172 }
173
174 byte[] DeleteFriendship(Dictionary<string, object> request)
175 {
176 FriendInfo friend = new FriendInfo(request);
177 string secret = string.Empty;
178 if (request.ContainsKey("SECRET"))
179 secret = request["SECRET"].ToString();
180
181 if (secret == string.Empty)
182 return FailureResult();
183
184 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
185 foreach (FriendInfo finfo in finfos)
186 {
187 // We check the secret here
188 if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
189 {
190 m_log.DebugFormat("[HGFRIENDS HANDLER]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
191 m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
192 m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
193
194 return SuccessResult();
195 }
196 }
197
198 return FailureResult();
199 }
200
201 #endregion
202
203 #region Misc
204
205 private bool VerifyServiceKey(Dictionary<string, object> request)
206 {
207 if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID"))
208 {
209 m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
210 return false;
211 }
212
213 string serviceKey = request["KEY"].ToString();
214 string sessionStr = request["SESSIONID"].ToString();
215 UUID sessionID;
216 UUID.TryParse(sessionStr, out sessionID);
217
218 if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
219 {
220 m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
221 return false;
222 }
223
224 m_log.DebugFormat("[XXX] Verification ok");
225 return true;
226 }
227
228 private byte[] SuccessResult()
229 {
230 XmlDocument doc = new XmlDocument();
231
232 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
233 "", "");
234
235 doc.AppendChild(xmlnode);
236
237 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
238 "");
239
240 doc.AppendChild(rootElement);
241
242 XmlElement result = doc.CreateElement("", "Result", "");
243 result.AppendChild(doc.CreateTextNode("Success"));
244
245 rootElement.AppendChild(result);
246
247 return DocToBytes(doc);
248 }
249
250 private byte[] SuccessResult(string value)
251 {
252 XmlDocument doc = new XmlDocument();
253
254 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
255 "", "");
256
257 doc.AppendChild(xmlnode);
258
259 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
260 "");
261
262 doc.AppendChild(rootElement);
263
264 XmlElement result = doc.CreateElement("", "Result", "");
265 result.AppendChild(doc.CreateTextNode("Success"));
266
267 rootElement.AppendChild(result);
268
269 XmlElement message = doc.CreateElement("", "Value", "");
270 message.AppendChild(doc.CreateTextNode(value));
271
272 rootElement.AppendChild(message);
273
274 return DocToBytes(doc);
275 }
276
277
278 private byte[] FailureResult()
279 {
280 return FailureResult(String.Empty);
281 }
282
283 private byte[] FailureResult(string msg)
284 {
285 XmlDocument doc = new XmlDocument();
286
287 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
288 "", "");
289
290 doc.AppendChild(xmlnode);
291
292 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
293 "");
294
295 doc.AppendChild(rootElement);
296
297 XmlElement result = doc.CreateElement("", "Result", "");
298 result.AppendChild(doc.CreateTextNode("Failure"));
299
300 rootElement.AppendChild(result);
301
302 XmlElement message = doc.CreateElement("", "Message", "");
303 message.AppendChild(doc.CreateTextNode(msg));
304
305 rootElement.AppendChild(message);
306
307 return DocToBytes(doc);
308 }
309
310 private byte[] DocToBytes(XmlDocument doc)
311 {
312 MemoryStream ms = new MemoryStream();
313 XmlTextWriter xw = new XmlTextWriter(ms, null);
314 xw.Formatting = Formatting.Indented;
315 doc.WriteTo(xw);
316 xw.Flush();
317
318 return ms.ToArray();
319 }
320
321 #endregion
322 }
323}
diff --git a/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs
new file mode 100644
index 0000000..138313a
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/InstantMessageServerConnector.cs
@@ -0,0 +1,280 @@
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 Nini.Config;
35using OpenSim.Framework;
36using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces;
38using OpenSim.Framework.Servers.HttpServer;
39using OpenSim.Server.Handlers.Base;
40using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41
42using log4net;
43using Nwc.XmlRpc;
44using OpenMetaverse;
45
46namespace OpenSim.Server.Handlers.Hypergrid
47{
48 public class InstantMessageServerConnector : ServiceConnector
49 {
50 private static readonly ILog m_log =
51 LogManager.GetLogger(
52 MethodBase.GetCurrentMethod().DeclaringType);
53
54 private IInstantMessage m_IMService;
55
56 public InstantMessageServerConnector(IConfigSource config, IHttpServer server) :
57 this(config, server, null)
58 {
59 }
60
61 public InstantMessageServerConnector(IConfigSource config, IHttpServer server, IInstantMessageSimConnector simConnector) :
62 base(config, server, String.Empty)
63 {
64 IConfig gridConfig = config.Configs["HGInstantMessageService"];
65 if (gridConfig != null)
66 {
67 string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
68
69 Object[] args = new Object[] { config, simConnector };
70 m_IMService = ServerUtils.LoadPlugin<IInstantMessage>(serviceDll, args);
71 }
72 if (m_IMService == null)
73 throw new Exception("InstantMessage server connector cannot proceed because of missing service");
74
75 MainServer.Instance.AddXmlRPCHandler("grid_instant_message", ProcessInstantMessage, false);
76
77 }
78
79 public IInstantMessage GetService()
80 {
81 return m_IMService;
82 }
83
84 protected virtual XmlRpcResponse ProcessInstantMessage(XmlRpcRequest request, IPEndPoint remoteClient)
85 {
86 bool successful = false;
87
88 try
89 {
90 // various rational defaults
91 UUID fromAgentID = UUID.Zero;
92 UUID toAgentID = UUID.Zero;
93 UUID imSessionID = UUID.Zero;
94 uint timestamp = 0;
95 string fromAgentName = "";
96 string message = "";
97 byte dialog = (byte)0;
98 bool fromGroup = false;
99 byte offline = (byte)0;
100 uint ParentEstateID = 0;
101 Vector3 Position = Vector3.Zero;
102 UUID RegionID = UUID.Zero;
103 byte[] binaryBucket = new byte[0];
104
105 float pos_x = 0;
106 float pos_y = 0;
107 float pos_z = 0;
108 //m_log.Info("Processing IM");
109
110
111 Hashtable requestData = (Hashtable)request.Params[0];
112 // Check if it's got all the data
113 if (requestData.ContainsKey("from_agent_id")
114 && requestData.ContainsKey("to_agent_id") && requestData.ContainsKey("im_session_id")
115 && requestData.ContainsKey("timestamp") && requestData.ContainsKey("from_agent_name")
116 && requestData.ContainsKey("message") && requestData.ContainsKey("dialog")
117 && requestData.ContainsKey("from_group")
118 && requestData.ContainsKey("offline") && requestData.ContainsKey("parent_estate_id")
119 && requestData.ContainsKey("position_x") && requestData.ContainsKey("position_y")
120 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
121 && requestData.ContainsKey("binary_bucket"))
122 {
123 // Do the easy way of validating the UUIDs
124 UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
125 UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
126 UUID.TryParse((string)requestData["im_session_id"], out imSessionID);
127 UUID.TryParse((string)requestData["region_id"], out RegionID);
128
129 try
130 {
131 timestamp = (uint)Convert.ToInt32((string)requestData["timestamp"]);
132 }
133 catch (ArgumentException)
134 {
135 }
136 catch (FormatException)
137 {
138 }
139 catch (OverflowException)
140 {
141 }
142
143 fromAgentName = (string)requestData["from_agent_name"];
144 message = (string)requestData["message"];
145 if (message == null)
146 message = string.Empty;
147
148 // Bytes don't transfer well over XMLRPC, so, we Base64 Encode them.
149 string requestData1 = (string)requestData["dialog"];
150 if (string.IsNullOrEmpty(requestData1))
151 {
152 dialog = 0;
153 }
154 else
155 {
156 byte[] dialogdata = Convert.FromBase64String(requestData1);
157 dialog = dialogdata[0];
158 }
159
160 if ((string)requestData["from_group"] == "TRUE")
161 fromGroup = true;
162
163 string requestData2 = (string)requestData["offline"];
164 if (String.IsNullOrEmpty(requestData2))
165 {
166 offline = 0;
167 }
168 else
169 {
170 byte[] offlinedata = Convert.FromBase64String(requestData2);
171 offline = offlinedata[0];
172 }
173
174 try
175 {
176 ParentEstateID = (uint)Convert.ToInt32((string)requestData["parent_estate_id"]);
177 }
178 catch (ArgumentException)
179 {
180 }
181 catch (FormatException)
182 {
183 }
184 catch (OverflowException)
185 {
186 }
187
188 try
189 {
190 pos_x = (uint)Convert.ToInt32((string)requestData["position_x"]);
191 }
192 catch (ArgumentException)
193 {
194 }
195 catch (FormatException)
196 {
197 }
198 catch (OverflowException)
199 {
200 }
201 try
202 {
203 pos_y = (uint)Convert.ToInt32((string)requestData["position_y"]);
204 }
205 catch (ArgumentException)
206 {
207 }
208 catch (FormatException)
209 {
210 }
211 catch (OverflowException)
212 {
213 }
214 try
215 {
216 pos_z = (uint)Convert.ToInt32((string)requestData["position_z"]);
217 }
218 catch (ArgumentException)
219 {
220 }
221 catch (FormatException)
222 {
223 }
224 catch (OverflowException)
225 {
226 }
227
228 Position = new Vector3(pos_x, pos_y, pos_z);
229
230 string requestData3 = (string)requestData["binary_bucket"];
231 if (string.IsNullOrEmpty(requestData3))
232 {
233 binaryBucket = new byte[0];
234 }
235 else
236 {
237 binaryBucket = Convert.FromBase64String(requestData3);
238 }
239
240 // Create a New GridInstantMessageObject the the data
241 GridInstantMessage gim = new GridInstantMessage();
242 gim.fromAgentID = fromAgentID.Guid;
243 gim.fromAgentName = fromAgentName;
244 gim.fromGroup = fromGroup;
245 gim.imSessionID = imSessionID.Guid;
246 gim.RegionID = UUID.Zero.Guid; // RegionID.Guid;
247 gim.timestamp = timestamp;
248 gim.toAgentID = toAgentID.Guid;
249 gim.message = message;
250 gim.dialog = dialog;
251 gim.offline = offline;
252 gim.ParentEstateID = ParentEstateID;
253 gim.Position = Position;
254 gim.binaryBucket = binaryBucket;
255
256 successful = m_IMService.IncomingInstantMessage(gim);
257
258 }
259 }
260 catch (Exception e)
261 {
262 m_log.Error("[INSTANT MESSAGE]: Caught unexpected exception:", e);
263 successful = false;
264 }
265
266 //Send response back to region calling if it was successful
267 // calling region uses this to know when to look up a user's location again.
268 XmlRpcResponse resp = new XmlRpcResponse();
269 Hashtable respdata = new Hashtable();
270 if (successful)
271 respdata["success"] = "TRUE";
272 else
273 respdata["success"] = "FALSE";
274 resp.Value = respdata;
275
276 return resp;
277 }
278
279 }
280}
diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
index 0e8ce80..eb184a5 100644
--- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
@@ -52,15 +52,24 @@ namespace OpenSim.Server.Handlers.Hypergrid
52// MethodBase.GetCurrentMethod().DeclaringType); 52// MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 private IUserAgentService m_HomeUsersService; 54 private IUserAgentService m_HomeUsersService;
55 private string[] m_AuthorizedCallers;
56
57 private bool m_VerifyCallers = false;
55 58
56 public UserAgentServerConnector(IConfigSource config, IHttpServer server) : 59 public UserAgentServerConnector(IConfigSource config, IHttpServer server) :
60 this(config, server, null)
61 {
62 }
63
64 public UserAgentServerConnector(IConfigSource config, IHttpServer server, IFriendsSimConnector friendsConnector) :
57 base(config, server, String.Empty) 65 base(config, server, String.Empty)
58 { 66 {
59 IConfig gridConfig = config.Configs["UserAgentService"]; 67 IConfig gridConfig = config.Configs["UserAgentService"];
60 if (gridConfig != null) 68 if (gridConfig != null)
61 { 69 {
62 string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty); 70 string serviceDll = gridConfig.GetString("LocalServiceModule", string.Empty);
63 Object[] args = new Object[] { config }; 71
72 Object[] args = new Object[] { config, friendsConnector };
64 m_HomeUsersService = ServerUtils.LoadPlugin<IUserAgentService>(serviceDll, args); 73 m_HomeUsersService = ServerUtils.LoadPlugin<IUserAgentService>(serviceDll, args);
65 } 74 }
66 if (m_HomeUsersService == null) 75 if (m_HomeUsersService == null)
@@ -69,12 +78,24 @@ namespace OpenSim.Server.Handlers.Hypergrid
69 string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1"); 78 string loginServerIP = gridConfig.GetString("LoginServerIP", "127.0.0.1");
70 bool proxy = gridConfig.GetBoolean("HasProxy", false); 79 bool proxy = gridConfig.GetBoolean("HasProxy", false);
71 80
81 m_VerifyCallers = gridConfig.GetBoolean("VerifyCallers", false);
82 string csv = gridConfig.GetString("AuthorizedCallers", "127.0.0.1");
83 csv = csv.Replace(" ", "");
84 m_AuthorizedCallers = csv.Split(',');
85
72 server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false); 86 server.AddXmlRPCHandler("agent_is_coming_home", AgentIsComingHome, false);
73 server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false); 87 server.AddXmlRPCHandler("get_home_region", GetHomeRegion, false);
74 server.AddXmlRPCHandler("verify_agent", VerifyAgent, false); 88 server.AddXmlRPCHandler("verify_agent", VerifyAgent, false);
75 server.AddXmlRPCHandler("verify_client", VerifyClient, false); 89 server.AddXmlRPCHandler("verify_client", VerifyClient, false);
76 server.AddXmlRPCHandler("logout_agent", LogoutAgent, false); 90 server.AddXmlRPCHandler("logout_agent", LogoutAgent, false);
77 91
92 server.AddXmlRPCHandler("status_notification", StatusNotification, false);
93 server.AddXmlRPCHandler("get_online_friends", GetOnlineFriends, false);
94 server.AddXmlRPCHandler("get_server_urls", GetServerURLs, false);
95
96 server.AddXmlRPCHandler("locate_user", LocateUser, false);
97 server.AddXmlRPCHandler("get_uui", GetUUI, false);
98
78 server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); 99 server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler);
79 } 100 }
80 101
@@ -194,5 +215,187 @@ namespace OpenSim.Server.Handlers.Hypergrid
194 215
195 } 216 }
196 217
218 public XmlRpcResponse StatusNotification(XmlRpcRequest request, IPEndPoint remoteClient)
219 {
220 Hashtable hash = new Hashtable();
221 hash["result"] = "false";
222
223 Hashtable requestData = (Hashtable)request.Params[0];
224 //string host = (string)requestData["host"];
225 //string portstr = (string)requestData["port"];
226 if (requestData.ContainsKey("userID") && requestData.ContainsKey("online"))
227 {
228 string userID_str = (string)requestData["userID"];
229 UUID userID = UUID.Zero;
230 UUID.TryParse(userID_str, out userID);
231 List<string> ids = new List<string>();
232 foreach (object key in requestData.Keys)
233 {
234 if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null)
235 ids.Add(requestData[key].ToString());
236 }
237 bool online = false;
238 bool.TryParse(requestData["online"].ToString(), out online);
239
240 hash["result"] = "true";
241
242 // let's spawn a thread for this, because it may take a long time...
243 Util.FireAndForget(delegate { m_HomeUsersService.StatusNotification(ids, userID, online); });
244 }
245
246 XmlRpcResponse response = new XmlRpcResponse();
247 response.Value = hash;
248 return response;
249
250 }
251
252 public XmlRpcResponse GetOnlineFriends(XmlRpcRequest request, IPEndPoint remoteClient)
253 {
254 Hashtable hash = new Hashtable();
255
256 Hashtable requestData = (Hashtable)request.Params[0];
257 //string host = (string)requestData["host"];
258 //string portstr = (string)requestData["port"];
259 if (requestData.ContainsKey("userID"))
260 {
261 string userID_str = (string)requestData["userID"];
262 UUID userID = UUID.Zero;
263 UUID.TryParse(userID_str, out userID);
264 List<string> ids = new List<string>();
265 foreach (object key in requestData.Keys)
266 {
267 if (key is string && ((string)key).StartsWith("friend_") && requestData[key] != null)
268 ids.Add(requestData[key].ToString());
269 }
270
271 List<UUID> online = m_HomeUsersService.GetOnlineFriends(userID, ids);
272 if (online.Count > 0)
273 {
274 int i = 0;
275 foreach (UUID id in online)
276 {
277 hash["friend_" + i.ToString()] = id.ToString();
278 i++;
279 }
280 }
281 else
282 hash["result"] = "No Friends Online";
283 }
284
285 XmlRpcResponse response = new XmlRpcResponse();
286 response.Value = hash;
287 return response;
288
289 }
290
291 public XmlRpcResponse GetServerURLs(XmlRpcRequest request, IPEndPoint remoteClient)
292 {
293 Hashtable hash = new Hashtable();
294
295 Hashtable requestData = (Hashtable)request.Params[0];
296 //string host = (string)requestData["host"];
297 //string portstr = (string)requestData["port"];
298 if (requestData.ContainsKey("userID"))
299 {
300 string userID_str = (string)requestData["userID"];
301 UUID userID = UUID.Zero;
302 UUID.TryParse(userID_str, out userID);
303
304 Dictionary<string, object> serverURLs = m_HomeUsersService.GetServerURLs(userID);
305 if (serverURLs.Count > 0)
306 {
307 foreach (KeyValuePair<string, object> kvp in serverURLs)
308 hash["SRV_" + kvp.Key] = kvp.Value.ToString();
309 }
310 else
311 hash["result"] = "No Service URLs";
312 }
313
314 XmlRpcResponse response = new XmlRpcResponse();
315 response.Value = hash;
316 return response;
317
318 }
319
320 /// <summary>
321 /// Locates the user.
322 /// This is a sensitive operation, only authorized IP addresses can perform it.
323 /// </summary>
324 /// <param name="request"></param>
325 /// <param name="remoteClient"></param>
326 /// <returns></returns>
327 public XmlRpcResponse LocateUser(XmlRpcRequest request, IPEndPoint remoteClient)
328 {
329 Hashtable hash = new Hashtable();
330
331 bool authorized = true;
332 if (m_VerifyCallers)
333 {
334 authorized = false;
335 foreach (string s in m_AuthorizedCallers)
336 if (s == remoteClient.Address.ToString())
337 {
338 authorized = true;
339 break;
340 }
341 }
342
343 if (authorized)
344 {
345 Hashtable requestData = (Hashtable)request.Params[0];
346 //string host = (string)requestData["host"];
347 //string portstr = (string)requestData["port"];
348 if (requestData.ContainsKey("userID"))
349 {
350 string userID_str = (string)requestData["userID"];
351 UUID userID = UUID.Zero;
352 UUID.TryParse(userID_str, out userID);
353
354 string url = m_HomeUsersService.LocateUser(userID);
355 if (url != string.Empty)
356 hash["URL"] = url;
357 }
358 }
359
360 XmlRpcResponse response = new XmlRpcResponse();
361 response.Value = hash;
362 return response;
363
364 }
365
366 /// <summary>
367 /// Locates the user.
368 /// This is a sensitive operation, only authorized IP addresses can perform it.
369 /// </summary>
370 /// <param name="request"></param>
371 /// <param name="remoteClient"></param>
372 /// <returns></returns>
373 public XmlRpcResponse GetUUI(XmlRpcRequest request, IPEndPoint remoteClient)
374 {
375 Hashtable hash = new Hashtable();
376
377 Hashtable requestData = (Hashtable)request.Params[0];
378 //string host = (string)requestData["host"];
379 //string portstr = (string)requestData["port"];
380 if (requestData.ContainsKey("userID") && requestData.ContainsKey("targetUserID"))
381 {
382 string userID_str = (string)requestData["userID"];
383 UUID userID = UUID.Zero;
384 UUID.TryParse(userID_str, out userID);
385
386 string tuserID_str = (string)requestData["targetUserID"];
387 UUID targetUserID = UUID.Zero;
388 UUID.TryParse(tuserID_str, out targetUserID);
389 string uui = m_HomeUsersService.GetUUI(userID, targetUserID);
390 if (uui != string.Empty)
391 hash["UUI"] = uui;
392 }
393
394 XmlRpcResponse response = new XmlRpcResponse();
395 response.Value = hash;
396 return response;
397
398 }
399
197 } 400 }
198} 401}