aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/GridServers
diff options
context:
space:
mode:
Diffstat (limited to 'src/GridServers')
-rw-r--r--src/GridServers/LoginServer.cs322
1 files changed, 322 insertions, 0 deletions
diff --git a/src/GridServers/LoginServer.cs b/src/GridServers/LoginServer.cs
new file mode 100644
index 0000000..da982e7
--- /dev/null
+++ b/src/GridServers/LoginServer.cs
@@ -0,0 +1,322 @@
1/*
2* Copyright (c) OpenSim project, http://sim.opensecondlife.org/
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are met:
6* * Redistributions of source code must retain the above copyright
7* notice, this list of conditions and the following disclaimer.
8* * Redistributions in binary form must reproduce the above copyright
9* notice, this list of conditions and the following disclaimer in the
10* documentation and/or other materials provided with the distribution.
11* * Neither the name of the <organization> nor the
12* names of its contributors may be used to endorse or promote products
13* derived from this software without specific prior written permission.
14*
15* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
16* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
19* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*
26*/
27
28using Nwc.XmlRpc;
29using System;
30using System.IO;
31using System.Net;
32using System.Net.Sockets;
33using System.Text;
34using System.Text.RegularExpressions;
35using System.Threading;
36using System.Collections;
37using System.Security.Cryptography;
38using System.Xml;
39using libsecondlife;
40using OpenSim;
41
42namespace OpenSim.GridServers
43{
44
45 /// <summary>
46 /// When running in local (default) mode , handles client logins.
47 /// </summary>
48 public class LoginServer
49 {
50 public LoginServer(IGridServer gridServer)
51 {
52 _gridServer = gridServer;
53 }
54 private Login _login;
55 private IGridServer _gridServer;
56 private ushort _loginPort = 8080;
57 public IPAddress clientAddress = IPAddress.Loopback;
58 public IPAddress remoteAddress = IPAddress.Any;
59 private Socket loginServer;
60 private Random RandomClass = new Random();
61 private int NumClients;
62 private string _defaultResponse;
63
64 private string _mpasswd;
65 private bool _needPasswd=false;
66
67 // InitializeLogin: initialize the login
68 private void InitializeLogin() {
69 loginServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
70 loginServer.Bind(new IPEndPoint(remoteAddress, _loginPort));
71 loginServer.Listen(1);
72
73 this._needPasswd=false;
74 //read in default response string
75 StreamReader SR;
76 string lines;
77 SR=File.OpenText("new-login.dat");
78
79 //lines=SR.ReadLine();
80
81 while(!SR.EndOfStream)
82 {
83 lines = SR.ReadLine();
84 _defaultResponse += lines;
85 //lines = SR.ReadLine();
86 }
87 SR.Close();
88 this._mpasswd = EncodePassword("testpass");
89 }
90
91 public void Startup()
92 {
93 this.InitializeLogin();
94 Thread runLoginProxy = new Thread(new ThreadStart(RunLogin));
95 runLoginProxy.IsBackground = true;
96 runLoginProxy.Start();
97 }
98
99 private void RunLogin()
100 {
101 Console.WriteLine("Starting Login Server");
102 try
103 {
104 for (;;)
105 {
106 Socket client = loginServer.Accept();
107 IPEndPoint clientEndPoint = (IPEndPoint)client.RemoteEndPoint;
108
109
110 NetworkStream networkStream = new NetworkStream(client);
111 StreamReader networkReader = new StreamReader(networkStream);
112 StreamWriter networkWriter = new StreamWriter(networkStream);
113
114 try
115 {
116 LoginRequest(networkReader, networkWriter);
117 }
118 catch (Exception e)
119 {
120 Console.WriteLine(e.Message);
121 }
122
123 networkWriter.Close();
124 networkReader.Close();
125 networkStream.Close();
126
127 client.Close();
128
129 // send any packets queued for injection
130
131 }
132 }
133 catch (Exception e)
134 {
135 Console.WriteLine(e.Message);
136 Console.WriteLine(e.StackTrace);
137 }
138 }
139
140 // ProxyLogin: proxy a login request
141 private void LoginRequest(StreamReader reader, StreamWriter writer)
142 {
143 lock(this)
144 {
145 string line;
146 int contentLength = 0;
147 // read HTTP header
148 do
149 {
150 // read one line of the header
151 line = reader.ReadLine();
152
153 // check for premature EOF
154 if (line == null)
155 throw new Exception("EOF in client HTTP header");
156
157 // look for Content-Length
158 Match match = (new Regex(@"Content-Length: (\d+)$")).Match(line);
159 if (match.Success)
160 contentLength = Convert.ToInt32(match.Groups[1].Captures[0].ToString());
161 } while (line != "");
162
163 // read the HTTP body into a buffer
164 char[] content = new char[contentLength];
165 reader.Read(content, 0, contentLength);
166
167 XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(new String(content));
168 if(request.MethodName == "login_to_simulator")
169 {
170 Hashtable requestData = (Hashtable)request.Params[0];
171 string first;
172 string last;
173 string passwd;
174 LLUUID Agent;
175 LLUUID Session;
176
177 //get login name
178 if(requestData.Contains("first"))
179 {
180 first = (string)requestData["first"];
181 }
182 else
183 {
184 first = "test";
185 }
186
187 if(requestData.Contains("last"))
188 {
189 last = (string)requestData["last"];
190 }
191 else
192 {
193 last = "User"+NumClients.ToString();
194 }
195
196 if(requestData.Contains("passwd"))
197 {
198 passwd = (string)requestData["passwd"];
199 }
200 else
201 {
202 passwd = "notfound";
203 }
204
205 if( !Authenticate(first, last, passwd))
206 {
207 // Fail miserably
208 writer.WriteLine("HTTP/1.0 403 Authentication Forbidden");
209 writer.WriteLine();
210 return;
211 }
212 NumClients++;
213
214 //create a agent and session LLUUID
215 Agent = GetAgentId( first, last );
216 int SessionRand = this.RandomClass.Next(1,999);
217 Session = new LLUUID("aaaabbbb-0200-"+SessionRand.ToString("0000")+"-8664-58f53e442797");
218
219
220 XmlRpcResponse response =(XmlRpcResponse)(new XmlRpcResponseDeserializer()).Deserialize(this._defaultResponse);
221 Hashtable responseData = (Hashtable)response.Value;
222
223 responseData["sim_port"] = OpenSim_Main.cfg.IPListenPort;
224 responseData["sim_ip"] = OpenSim_Main.cfg.IPListenAddr;
225 responseData["agent_id"] = Agent.ToStringHyphenated();
226 responseData["session_id"] = Session.ToStringHyphenated();
227 ArrayList InventoryList = (ArrayList) responseData["inventory-skeleton"];
228 Hashtable Inventory1 = (Hashtable)InventoryList[0];
229 Hashtable Inventory2 = (Hashtable)InventoryList[1];
230 LLUUID BaseFolderID = LLUUID.Random();
231 LLUUID InventoryFolderID = LLUUID.Random();
232 Inventory2["name"] = "Base";
233 Inventory2["folder_id"] = BaseFolderID.ToStringHyphenated();
234 Inventory2["type_default"] =6;
235 Inventory1["folder_id"] = InventoryFolderID.ToStringHyphenated();
236
237 ArrayList InventoryRoot = (ArrayList) responseData["inventory-root"];
238 Hashtable Inventoryroot = (Hashtable)InventoryRoot[0];
239 Inventoryroot["folder_id"] = InventoryFolderID.ToStringHyphenated();
240
241 CustomiseLoginResponse( responseData, first, last );
242
243 this._login = new Login();
244 //copy data to login object
245 _login.First = first;
246 _login.Last = last;
247 _login.Agent = Agent;
248 _login.Session = Session;
249 _login.BaseFolder = BaseFolderID;
250 _login.InventoryFolder = InventoryFolderID;
251
252 //working on local computer so lets add to the gridserver's list of sessions
253 this._gridServer.AddNewSession(_login);
254
255 // forward the XML-RPC response to the client
256 writer.WriteLine("HTTP/1.0 200 OK");
257 writer.WriteLine("Content-type: text/xml");
258 writer.WriteLine();
259
260 XmlTextWriter responseWriter = new XmlTextWriter(writer);
261 XmlRpcResponseSerializer.Singleton.Serialize(responseWriter, response);
262 responseWriter.Close();
263 }
264 else
265 {
266 writer.WriteLine("HTTP/1.0 403 Authentication Forbidden");
267 writer.WriteLine();
268 }
269 }
270 }
271
272 protected virtual void CustomiseLoginResponse( Hashtable responseData, string first, string last )
273 {
274 }
275
276 protected virtual LLUUID GetAgentId(string firstName, string lastName)
277 {
278 LLUUID Agent;
279 int AgentRand = this.RandomClass.Next(1,9999);
280 Agent = new LLUUID("99998888-0100-"+AgentRand.ToString("0000")+"-8ec1-0b1d5cd6aead");
281 return Agent;
282 }
283
284 protected virtual bool Authenticate(string first, string last, string passwd)
285 {
286 if(this._needPasswd)
287 {
288 //every user needs the password to login
289 string encodedPass = passwd.Remove(0,3); //remove $1$
290 if(encodedPass == this._mpasswd)
291 {
292 return true;
293 }
294 else
295 {
296 return false;
297 }
298 }
299 else
300 {
301 //do not need password to login
302 return true;
303 }
304 }
305
306 private static string EncodePassword(string passwd)
307 {
308 Byte[] originalBytes;
309 Byte[] encodedBytes;
310 MD5 md5;
311
312 md5 = new MD5CryptoServiceProvider();
313 originalBytes = ASCIIEncoding.Default.GetBytes(passwd);
314 encodedBytes = md5.ComputeHash(originalBytes);
315
316 return Regex.Replace(BitConverter.ToString(encodedBytes), "-", "").ToLower();
317 }
318
319 }
320
321
322}