aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authoronefang2019-08-17 07:09:16 +1000
committeronefang2019-08-17 07:09:16 +1000
commitee33dd4b56f7782bbf7798fa3ff8821ff81acd36 (patch)
tree591ed389ce4daf085a2ed79b2e9fc26957c9c476
parentSimple web server gets HTTPS. (diff)
downloadopensim-SC-ee33dd4b56f7782bbf7798fa3ff8821ff81acd36.zip
opensim-SC-ee33dd4b56f7782bbf7798fa3ff8821ff81acd36.tar.gz
opensim-SC-ee33dd4b56f7782bbf7798fa3ff8821ff81acd36.tar.bz2
opensim-SC-ee33dd4b56f7782bbf7798fa3ff8821ff81acd36.tar.xz
VArious additions to account manager.
First and last names merged into one name. Is name two words check, a suprisingly effective spam blocker. Poor mans Bobby Tables protection. Various other input checking. Added account creation confirmation page. Some text and length tweaks.
-rw-r--r--OpenSim/Server/Handlers/Web/WebServerConnector.cs102
1 files changed, 83 insertions, 19 deletions
diff --git a/OpenSim/Server/Handlers/Web/WebServerConnector.cs b/OpenSim/Server/Handlers/Web/WebServerConnector.cs
index 3a8e906..7879e4e 100644
--- a/OpenSim/Server/Handlers/Web/WebServerConnector.cs
+++ b/OpenSim/Server/Handlers/Web/WebServerConnector.cs
@@ -6,6 +6,7 @@ using System.Net;
6using System.Reflection; 6using System.Reflection;
7using System.Security; 7using System.Security;
8using System.Text; 8using System.Text;
9using System.Text.RegularExpressions;
9using log4net; 10using log4net;
10using Nini.Config; 11using Nini.Config;
11using OpenMetaverse; 12using OpenMetaverse;
@@ -131,13 +132,14 @@ namespace OpenSim.Server.Handlers.Web
131 return reply; 132 return reply;
132 } 133 }
133 134
134 m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} type {2} body {3}.", method, reqpath, type, body); 135 m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} contont type {2} body {3}.", method, reqpath, type, body);
135 foreach (DictionaryEntry h in headers) 136 foreach (DictionaryEntry h in headers)
136 m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} header {2} = {3}", method, reqpath, (string) h.Key, (string) h.Value); 137 m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} header {2} = {3}", method, reqpath, (string) h.Key, (string) h.Value);
137 foreach (String q in query) 138 foreach (String q in query)
138 m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} query {2} value {3}", method, reqpath, q, (string) request[q]); 139 m_log.InfoFormat("[WEB SERVICE]: {0} method path {1} query {2} value {3}", method, reqpath, q, (string) request[q]);
139 140
140 reply["int_response_code"] = 200; 141 reply["int_response_code"] = 200;
142// TODO - need to support HEAD method, seems to be what triggers the endles GETs.
141 if ("GET" == method) 143 if ("GET" == method)
142 { 144 {
143 if (File.Exists(path)) 145 if (File.Exists(path))
@@ -211,25 +213,71 @@ namespace OpenSim.Server.Handlers.Web
211 String v = ""; 213 String v = "";
212 if (b.Length > 1) 214 if (b.Length > 1)
213 v = System.Web.HttpUtility.UrlDecode(b[1]); 215 v = System.Web.HttpUtility.UrlDecode(b[1]);
216 if ((0 != String.Compare("password", n)) && (0 != String.Compare("psswrd", n)))
217 {
218 // Poor mans Bobby Tables protection.
219 v = v.Replace("'", "_");
220 v = v.Replace("\"", "_");
221 v = v.Replace(";", "_");
222 v = v.Replace("(", "_");
223 v = v.Replace(")", "_");
224 }
214 fields[n] = v; 225 fields[n] = v;
215 body = body + "<p>" + n + " = " + v + "</p>\n"; 226 body = body + "<p>" + n + " = " + v + "</p>\n";
216 } 227 }
217 228
218 if ("account.html" == file) 229 if ("account.html" == file)
219 { 230 {
231 string doit = fields["doit"].ToString();
220 replyHeaders["Cache-Control"] = "no-cache"; 232 replyHeaders["Cache-Control"] = "no-cache";
221 if ("logout" == fields["doit"].ToString()) 233 if ("logout" == doit)
222 reply["str_response_string"] = loginPage(null, "Logged out."); 234 reply["str_response_string"] = loginPage(null, "Logged out.");
223 else if ("create" == fields["doit"].ToString()) 235 else if (("create" == doit) || ("confirm" == doit))
224 { 236 {
237 Regex rgxName = new Regex("^[a-zA-Z0-9]+$");
238 Regex rgxEmail = new Regex("^.+@.+\\..+$");
239 string[] names = fields["name"].ToString().Split(' ');
225 if ("" == fields["email"].ToString()) 240 if ("" == fields["email"].ToString())
226 reply["str_response_string"] = loginPage(fields, "Please supply an email address when creating an account."); 241 reply["str_response_string"] = loginPage(fields, "Please supply an email address when creating an account.");
242 else if (!rgxEmail.IsMatch(fields["email"].ToString()))
243 reply["str_response_string"] = loginPage(fields, "Please supply a valid email address when creating an account.");
244 else if (!Uri.IsWellFormedUriString("mailto:" + fields["email"].ToString(), System.UriKind.Absolute))
245 reply["str_response_string"] = loginPage(fields, "Please supply a valid email address when creating an account.");
246// TODO - the other test to do here is actually lookup the domain name, looking for any sort of record.
247 else if (2 != names.Length)
248 reply["str_response_string"] = loginPage(fields, "Please supply a two word name when creating an account.");
249 // SL docs say 31 characters each for first and last name. UserAccounts table is varchar(64) each. userinfo has varchar(50) for the combined name.
250 // The userinfo table seems to be obsolete.
251 // Singularity at least limits the total name to 64.
252 // I can't find any limitations on characters allowed, but I only ever see letters and digits used. Case is stored, but not significant.
253 // OpenSims "create user" console command doesn't sanitize it at all, even crashing on some names.
254 else if (31 < names[0].Length)
255 reply["str_response_string"] = loginPage(fields, "First and last names are limited to 31 letters each.");
256 else if (31 < names[1].Length)
257 reply["str_response_string"] = loginPage(fields, "First and last names are limited to 31 letters each.");
258 else if (!rgxName.IsMatch(names[0]))
259 reply["str_response_string"] = loginPage(fields, "First and last names are limited to letters and digits.");
260 else if (!rgxName.IsMatch(names[1]))
261 reply["str_response_string"] = loginPage(fields, "First and last names are limited to letters and digits.");
262// TODO - check and disallow god names, those are done in the console.
227 else 263 else
228 { 264 {
229 reply["str_response_string"] = loggedOnPage(body, fields); 265 if (("create" == doit))
266 reply["str_response_string"] = accountCreationPage(body, fields);
267 else
268 {
269 if (0 != String.Compare(fields["psswrd"].ToString(), fields["password"].ToString()))
270 reply["str_response_string"] = loginPage(fields, "Passwords are not the same.");
271 else
272 reply["str_response_string"] = loggedOnPage(body, fields);
273 }
230 } 274 }
231 } 275 }
232 else if ("list" == fields["doit"].ToString()) 276 else if ("cancel" == doit)
277 {
278 reply["str_response_string"] = loginPage(null, "Cancelled.");
279 }
280 else if ("list" == doit)
233 { 281 {
234 List< Hashtable > rows = m_database.Select("UserAccounts", 282 List< Hashtable > rows = m_database.Select("UserAccounts",
235 "CONCAT(FirstName,' ',LastName) as Name,UserTitle as Title,UserLevel as Level,UserFlags as Flags,PrincipalID as UUID", 283 "CONCAT(FirstName,' ',LastName) as Name,UserTitle as Title,UserLevel as Level,UserFlags as Flags,PrincipalID as UUID",
@@ -268,21 +316,19 @@ namespace OpenSim.Server.Handlers.Web
268 316
269 private string loginPage(Hashtable fields, string message) 317 private string loginPage(Hashtable fields, string message)
270 { 318 {
271 string f = ""; 319 string n = "";
272 string l = "";
273 string e = ""; 320 string e = "";
274 if (null != fields) 321 if (null != fields)
275 { 322 {
276 f = fields["firstName"].ToString(); 323 n = fields["name"].ToString();
277 l = fields["lastName"].ToString();
278 e = fields["email"].ToString(); 324 e = fields["email"].ToString();
279 } 325 }
280 return header(ssi["grid"] + " account") 326 return header(ssi["grid"] + " account")
281 + form("account.html", "", 327 + form("account.html", "",
282 text("text", "first name", "firstName", f, 16, true) 328 text("text", "name", "name", n, 63, true)
283 + text("text", "last name", "lastName", l, 16, true) 329 + text("email", "email", "email", e, 254, false)
284 + text("email", "email", "email", e, 0, false) 330 + text("password", "password", "password", "", 0, true)
285 + text("password", "password", "password", "", 14,true) 331 + "Warning, the limit on password length is set by your viewer, some can't handle longer than 16 characters."
286 + button("create") 332 + button("create")
287 + button("login") 333 + button("login")
288 ) 334 )
@@ -290,17 +336,35 @@ namespace OpenSim.Server.Handlers.Web
290 + footer(); 336 + footer();
291 } 337 }
292 338
339 private string accountCreationPage(string body, Hashtable fields)
340 {
341 return header(ssi["grid"] + " account")
342 + "<h1>Creating " + ssi["grid"] + " account for " + fields["name"].ToString() + "</h1>"
343 + form("account.html", fields["token"].ToString(),
344 hidden("name", fields["name"].ToString())
345 + hidden("psswrd", fields["password"].ToString())
346 + text("email", "An email will be sent to", "email", fields["email"].ToString(), 254, true)
347 + "&nbsp;to validate it, please double check this."
348 + text("password", "Re-enter your password", "password", "", 0, true)
349 + "Warning, the limit on password length is set by your viewer, some can't handle longer than 16 characters."
350 + button("confirm")
351 + button("cancel")
352 )
353 + body
354 + footer();
355 }
356
293 private string loggedOnPage(string body, Hashtable fields) 357 private string loggedOnPage(string body, Hashtable fields)
294 { 358 {
295 return header(ssi["grid"] + " account") 359 return header(ssi["grid"] + " account")
296 + "<h1>" + ssi["grid"] + " account for " + fields["firstName"].ToString() + " " + fields["lastName"].ToString() + "</h1>" 360 + "<h1>" + ssi["grid"] + " account for " + fields["name"].ToString() + "</h1>"
297 + form("account.html", fields["token"].ToString(), 361 + form("account.html", fields["token"].ToString(),
298 hidden("firstName", fields["firstName"].ToString()) 362 hidden("name", fields["name"].ToString())
299 + hidden("lastName", fields["lastName"].ToString())
300// + hidden("UUID", fields["UUID"].ToString()) 363// + hidden("UUID", fields["UUID"].ToString())
301 + text("email", "email", "email", fields["email"].ToString(), 0, false) 364 + text("email", "email", "email", fields["email"].ToString(), 254, true)
302 + text("password", "password", "password", "", 14, false) 365 + text("password", "password", "password", "", 0, false)
303// + text("title", "text", "title", fields["title"].ToString(), 0, false) 366 + "Warning, the limit on password length is set by your viewer, some can't handle longer than 16 characters."
367// + text("title", "text", "title", fields["title"].ToString(), 64, false)
304 + select("type", "type", 368 + select("type", "type",
305 option("", false) 369 option("", false)
306 + option("approved", true) 370 + option("approved", true)