aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/MSSQL/MSSQLGridData.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/MSSQL/MSSQLGridData.cs')
-rw-r--r--OpenSim/Data/MSSQL/MSSQLGridData.cs366
1 files changed, 366 insertions, 0 deletions
diff --git a/OpenSim/Data/MSSQL/MSSQLGridData.cs b/OpenSim/Data/MSSQL/MSSQLGridData.cs
new file mode 100644
index 0000000..9bd8acc
--- /dev/null
+++ b/OpenSim/Data/MSSQL/MSSQLGridData.cs
@@ -0,0 +1,366 @@
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 OpenSim 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.Data;
31using System.Security.Cryptography;
32using System.Text;
33using libsecondlife;
34using OpenSim.Framework.Console;
35
36namespace OpenSim.Framework.Data.MSSQL
37{
38 /// <summary>
39 /// A grid data interface for Microsoft SQL Server
40 /// </summary>
41 public class MSSQLGridData : GridDataBase
42 {
43 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
44
45 /// <summary>
46 /// Database manager
47 /// </summary>
48 private MSSQLManager database;
49
50 private string m_regionsTableName;
51
52 /// <summary>
53 /// Initialises the Grid Interface
54 /// </summary>
55 override public void Initialise()
56 {
57 IniFile iniFile = new IniFile("mssql_connection.ini");
58
59 string settingDataSource = iniFile.ParseFileReadValue("data_source");
60 string settingInitialCatalog = iniFile.ParseFileReadValue("initial_catalog");
61 string settingPersistSecurityInfo = iniFile.ParseFileReadValue("persist_security_info");
62 string settingUserId = iniFile.ParseFileReadValue("user_id");
63 string settingPassword = iniFile.ParseFileReadValue("password");
64
65 m_regionsTableName = iniFile.ParseFileReadValue("regionstablename");
66 if (m_regionsTableName == null)
67 {
68 m_regionsTableName = "regions";
69 }
70
71 database =
72 new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
73 settingPassword);
74
75 TestTables();
76 }
77
78 private void TestTables()
79 {
80 IDbCommand cmd = database.Query("SELECT TOP 1 * FROM "+m_regionsTableName, new Dictionary<string, string>());
81
82 try
83 {
84 cmd.ExecuteNonQuery();
85 cmd.Dispose();
86 }
87 catch (Exception)
88 {
89 m_log.Info("[DATASTORE]: MSSQL Database doesn't exist... creating");
90 database.ExecuteResourceSql("Mssql-regions.sql");
91 }
92 }
93
94 /// <summary>
95 /// Shuts down the grid interface
96 /// </summary>
97 override public void Close()
98 {
99 database.Close();
100 }
101
102 /// <summary>
103 /// Returns the storage system name
104 /// </summary>
105 /// <returns>A string containing the storage system name</returns>
106 override public string getName()
107 {
108 return "Sql OpenGridData";
109 }
110
111 /// <summary>
112 /// Returns the storage system version
113 /// </summary>
114 /// <returns>A string containing the storage system version</returns>
115 override public string getVersion()
116 {
117 return "0.1";
118 }
119
120 /// <summary>
121 /// Returns a list of regions within the specified ranges
122 /// </summary>
123 /// <param name="a">minimum X coordinate</param>
124 /// <param name="b">minimum Y coordinate</param>
125 /// <param name="c">maximum X coordinate</param>
126 /// <param name="d">maximum Y coordinate</param>
127 /// <returns>An array of region profiles</returns>
128 override public RegionProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d)
129 {
130 return null;
131 }
132
133 /// <summary>
134 /// Returns a sim profile from its location
135 /// </summary>
136 /// <param name="handle">Region location handle</param>
137 /// <returns>Sim profile</returns>
138 override public RegionProfileData GetProfileByHandle(ulong handle)
139 {
140 IDataReader reader = null;
141 try
142 {
143 Dictionary<string, string> param = new Dictionary<string, string>();
144 param["handle"] = handle.ToString();
145 IDbCommand result = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE regionHandle = @handle", param);
146 reader = result.ExecuteReader();
147
148 RegionProfileData row = database.getRegionRow(reader);
149 reader.Close();
150 result.Dispose();
151
152 return row;
153 }
154 catch (Exception)
155 {
156 if (reader != null)
157 {
158 reader.Close();
159 }
160 }
161 return null;
162 }
163
164 /// <summary>
165 /// Returns a sim profile from its UUID
166 /// </summary>
167 /// <param name="uuid">The region UUID</param>
168 /// <returns>The sim profile</returns>
169 override public RegionProfileData GetProfileByLLUUID(LLUUID uuid)
170 {
171 Dictionary<string, string> param = new Dictionary<string, string>();
172 param["uuid"] = uuid.ToString();
173 IDbCommand result = database.Query("SELECT * FROM " + m_regionsTableName + " WHERE uuid = @uuid", param);
174 IDataReader reader = result.ExecuteReader();
175
176 RegionProfileData row = database.getRegionRow(reader);
177 reader.Close();
178 result.Dispose();
179
180 return row;
181 }
182
183 /// <summary>
184 /// Returns a sim profile from it's Region name string
185 /// </summary>
186 /// <param name="uuid">The region name search query</param>
187 /// <returns>The sim profile</returns>
188 override public RegionProfileData GetProfileByString(string regionName)
189 {
190 if (regionName.Length > 2)
191 {
192 try
193 {
194 lock (database)
195 {
196 Dictionary<string, string> param = new Dictionary<string, string>();
197 // Add % because this is a like query.
198 param["?regionName"] = regionName + "%";
199 // Order by statement will return shorter matches first. Only returns one record or no record.
200 IDbCommand result = database.Query("SELECT top 1 * FROM " + m_regionsTableName + " WHERE regionName like ?regionName order by regionName", param);
201 IDataReader reader = result.ExecuteReader();
202
203 RegionProfileData row = database.getRegionRow(reader);
204 reader.Close();
205 result.Dispose();
206
207 return row;
208 }
209 }
210 catch (Exception e)
211 {
212 database.Reconnect();
213 m_log.Error(e.ToString());
214 return null;
215 }
216 }
217 else
218 {
219 m_log.Error("[DATABASE]: Searched for a Region Name shorter then 3 characters");
220 return null;
221 }
222 }
223
224 /// <summary>
225 /// Adds a new specified region to the database
226 /// </summary>
227 /// <param name="profile">The profile to add</param>
228 /// <returns>A dataresponse enum indicating success</returns>
229 override public DataResponse AddProfile(RegionProfileData profile)
230 {
231 try
232 {
233 if (GetProfileByLLUUID(profile.UUID) != null)
234 {
235 return DataResponse.RESPONSE_OK;
236 }
237 }
238 catch (Exception)
239 {
240 System.Console.WriteLine("No regions found. Create new one.");
241 }
242
243 if (insertRegionRow(profile))
244 {
245 return DataResponse.RESPONSE_OK;
246 }
247 else
248 {
249 return DataResponse.RESPONSE_ERROR;
250 }
251 }
252
253 /// <summary>
254 /// Creates a new region in the database
255 /// </summary>
256 /// <param name="profile">The region profile to insert</param>
257 /// <returns>Successful?</returns>
258 public bool insertRegionRow(RegionProfileData profile)
259 {
260 //Insert new region
261 string sql =
262 "INSERT INTO " + m_regionsTableName + " ([regionHandle], [regionName], [uuid], [regionRecvKey], [regionSecret], [regionSendKey], [regionDataURI], ";
263 sql +=
264 "[serverIP], [serverPort], [serverURI], [locX], [locY], [locZ], [eastOverrideHandle], [westOverrideHandle], [southOverrideHandle], [northOverrideHandle], [regionAssetURI], [regionAssetRecvKey], ";
265 sql +=
266 "[regionAssetSendKey], [regionUserURI], [regionUserRecvKey], [regionUserSendKey], [regionMapTexture], [serverHttpPort], [serverRemotingPort], [owner_uuid]) VALUES ";
267
268 sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, ";
269 sql +=
270 "@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, ";
271 sql +=
272 "@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey, @regionMapTexture, @serverHttpPort, @serverRemotingPort, @owner_uuid);";
273
274 Dictionary<string, string> parameters = new Dictionary<string, string>();
275
276 parameters["regionHandle"] = profile.regionHandle.ToString();
277 parameters["regionName"] = profile.regionName;
278 parameters["uuid"] = profile.UUID.ToString();
279 parameters["regionRecvKey"] = profile.regionRecvKey;
280 parameters["regionSecret"] = profile.regionSecret;
281 parameters["regionSendKey"] = profile.regionSendKey;
282 parameters["regionDataURI"] = profile.regionDataURI;
283 parameters["serverIP"] = profile.serverIP;
284 parameters["serverPort"] = profile.serverPort.ToString();
285 parameters["serverURI"] = profile.serverURI;
286 parameters["locX"] = profile.regionLocX.ToString();
287 parameters["locY"] = profile.regionLocY.ToString();
288 parameters["locZ"] = profile.regionLocZ.ToString();
289 parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString();
290 parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString();
291 parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString();
292 parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString();
293 parameters["regionAssetURI"] = profile.regionAssetURI;
294 parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey;
295 parameters["regionAssetSendKey"] = profile.regionAssetSendKey;
296 parameters["regionUserURI"] = profile.regionUserURI;
297 parameters["regionUserRecvKey"] = profile.regionUserRecvKey;
298 parameters["regionUserSendKey"] = profile.regionUserSendKey;
299 parameters["regionMapTexture"] = profile.regionMapTextureID.ToString();
300 parameters["serverHttpPort"] = profile.httpPort.ToString();
301 parameters["serverRemotingPort"] = profile.remotingPort.ToString();
302 parameters["owner_uuid"] = profile.owner_uuid.ToString();
303
304 bool returnval = false;
305
306 try
307 {
308 IDbCommand result = database.Query(sql, parameters);
309
310 if (result.ExecuteNonQuery() == 1)
311 returnval = true;
312
313 result.Dispose();
314 }
315 catch (Exception e)
316 {
317 m_log.Error("MSSQLManager : " + e.ToString());
318 }
319
320 return returnval;
321 }
322
323 /// <summary>
324 /// DEPRECATED. Attempts to authenticate a region by comparing a shared secret.
325 /// </summary>
326 /// <param name="uuid">The UUID of the challenger</param>
327 /// <param name="handle">The attempted regionHandle of the challenger</param>
328 /// <param name="authkey">The secret</param>
329 /// <returns>Whether the secret and regionhandle match the database entry for UUID</returns>
330 override public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey)
331 {
332 bool throwHissyFit = false; // Should be true by 1.0
333
334 if (throwHissyFit)
335 throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential.");
336
337 RegionProfileData data = GetProfileByLLUUID(uuid);
338
339 return (handle == data.regionHandle && authkey == data.regionSecret);
340 }
341
342 /// <summary>
343 /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region
344 /// </summary>
345 /// <remarks>This requires a security audit.</remarks>
346 /// <param name="uuid"></param>
347 /// <param name="handle"></param>
348 /// <param name="authhash"></param>
349 /// <param name="challenge"></param>
350 /// <returns></returns>
351 public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge)
352 {
353 SHA512Managed HashProvider = new SHA512Managed();
354 ASCIIEncoding TextProvider = new ASCIIEncoding();
355
356 byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge);
357 byte[] hash = HashProvider.ComputeHash(stream);
358 return false;
359 }
360
361 override public ReservationData GetReservationAtPoint(uint x, uint y)
362 {
363 return null;
364 }
365 }
366}