aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Communications/LoginService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Communications/LoginService.cs')
-rw-r--r--OpenSim/Framework/Communications/LoginService.cs148
1 files changed, 134 insertions, 14 deletions
diff --git a/OpenSim/Framework/Communications/LoginService.cs b/OpenSim/Framework/Communications/LoginService.cs
index f0a0a0b..04b8501 100644
--- a/OpenSim/Framework/Communications/LoginService.cs
+++ b/OpenSim/Framework/Communications/LoginService.cs
@@ -30,6 +30,7 @@ using System;
30using System.Collections; 30using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.IO; 32using System.IO;
33using System.Text.RegularExpressions;
33using System.Threading; 34using System.Threading;
34using libsecondlife; 35using libsecondlife;
35using libsecondlife.StructuredData; 36using libsecondlife.StructuredData;
@@ -359,21 +360,103 @@ namespace OpenSim.Framework.UserManagement
359 360
360 public Hashtable ProcessHTMLLogin(Hashtable keysvals) 361 public Hashtable ProcessHTMLLogin(Hashtable keysvals)
361 { 362 {
363
364 // Matches all unspecified characters
365 // Currently specified,; lowercase letters, upper case letters, numbers, underline
366 // period, space, parens, and dash.
367
368 Regex wfcut = new Regex("[^a-zA-Z0-9_\\.\\$ \\(\\)\\-]");
369
362 Hashtable returnactions = new Hashtable(); 370 Hashtable returnactions = new Hashtable();
363 int statuscode = 200; 371 int statuscode = 200;
364 372
365 returnactions["int_response_code"] = statuscode; 373 string firstname = "";
366 returnactions["str_response_string"] = GetDefaultLoginForm(); 374 string lastname = "";
375 string location = "";
376 string region ="";
377 string grid = "";
378 string channel = "";
379 string version = "";
380 string lang = "";
381 string password = "";
382 string errormessages = "";
383
384 // the client requires the HTML form field be named 'username'
385 // however, the data it sends when it loads the first time is 'firstname'
386 // another one of those little nuances.
387
388
389 if (keysvals.Contains("firstname"))
390 firstname = wfcut.Replace((string)keysvals["firstname"],"",99999);
391 if (keysvals.Contains("username"))
392 firstname = wfcut.Replace((string)keysvals["username"],"",99999);
393
394 if (keysvals.Contains("lastname"))
395 lastname = wfcut.Replace((string)keysvals["lastname"],"",99999);
396
397 if (keysvals.Contains("location"))
398 location = wfcut.Replace((string)keysvals["location"],"",99999);
399
400 if (keysvals.Contains("region"))
401 region = wfcut.Replace((string)keysvals["region"],"",99999);
402
403 if (keysvals.Contains("grid"))
404 grid = wfcut.Replace((string)keysvals["grid"],"",99999);
405
406 if (keysvals.Contains("channel"))
407 channel = wfcut.Replace((string)keysvals["channel"],"",99999);
408
409 if (keysvals.Contains("version"))
410 version = wfcut.Replace((string)keysvals["version"],"",99999);
411
412 if (keysvals.Contains("lang"))
413 lang = wfcut.Replace((string)keysvals["lang"],"",99999);
414
415 if (keysvals.Contains("password"))
416 password = wfcut.Replace((string)keysvals["password"], "", 99999);
417
418
419 // load our login form.
420 string loginform = GetLoginForm(firstname,lastname,location,region,grid,channel,version,lang,password,errormessages);
367 421
368 if (keysvals.ContainsKey("show_login_form")) 422 if (keysvals.ContainsKey("show_login_form"))
369 { 423 {
370 if ((string)keysvals["show_login_form"] == "TRUE") 424 if ((string)keysvals["show_login_form"] == "TRUE")
371 { 425 {
372 426 returnactions["int_response_code"] = statuscode;
427 returnactions["str_response_string"] = loginform;
373 } 428 }
374 else 429 else
375 { 430 {
431 UserProfileData user = GetTheUser(firstname, lastname);
432 bool goodweblogin = false;
376 433
434 if (user != null)
435 goodweblogin = AuthenticateUser(user, password);
436
437 if (goodweblogin)
438 {
439 LLUUID webloginkey = LLUUID.Random();
440 m_userManager.StoreWebLoginKey(user.UUID, webloginkey);
441 statuscode = 301;
442
443 string redirectURL = "secondlife:///app/login?first_name=" + firstname + "&last_name=" +
444 lastname +
445 "&location=" + location + "&grid=Other&web_login_key=" + webloginkey.ToString();
446
447 returnactions["int_response_code"] = statuscode;
448 returnactions["str_redirect_location"] = redirectURL;
449 returnactions["str_response_string"] = "<HTML><BODY>GoodLogin</BODY></HTML>";
450 }
451 else
452 {
453 errormessages = "The Username and password supplied did not match our records. Check your caps lock and try again";
454
455 loginform = GetLoginForm(firstname, lastname, location, region, grid, channel, version, lang, password, errormessages);
456 returnactions["int_response_code"] = statuscode;
457 returnactions["str_response_string"] = loginform;
458
459 }
377 460
378 } 461 }
379 462
@@ -382,16 +465,36 @@ namespace OpenSim.Framework.UserManagement
382 465
383 } 466 }
384 467
385 public string GetLoginForm() 468 public string GetLoginForm(string firstname, string lastname, string location, string region,
469 string grid, string channel, string version, string lang,
470 string password, string errormessages)
386 { 471 {
472 // inject our values in the form at the markers
473
474 string loginform="";
387 string file = Path.Combine(Util.configDir(), "http_loginform.html"); 475 string file = Path.Combine(Util.configDir(), "http_loginform.html");
388 if (!File.Exists(file)) 476 if (!File.Exists(file))
389 return GetDefaultLoginForm(); 477 {
390 478 loginform = GetDefaultLoginForm();
391 StreamReader sr = File.OpenText(file); 479 }
392 string result = sr.ReadToEnd(); 480 else
393 sr.Close(); 481 {
394 return result; 482 StreamReader sr = File.OpenText(file);
483 loginform = sr.ReadToEnd();
484 sr.Close();
485 }
486
487 loginform = loginform.Replace("[$firstname]", firstname);
488 loginform = loginform.Replace("[$lastname]", lastname);
489 loginform = loginform.Replace("[$location]", location);
490 loginform = loginform.Replace("[$region]", region);
491 loginform = loginform.Replace("[$grid]", grid);
492 loginform = loginform.Replace("[$channel]", channel);
493 loginform = loginform.Replace("[$version]", version);
494 loginform = loginform.Replace("[$lang]", lang);
495 loginform = loginform.Replace("[$password]", password);
496 loginform = loginform.Replace("[$errors]", errormessages);
497 return loginform;
395 } 498 }
396 499
397 public string GetDefaultLoginForm() 500 public string GetDefaultLoginForm()
@@ -405,7 +508,7 @@ namespace OpenSim.Framework.UserManagement
405 responseString = responseString + "<meta http-equiv=\"cache-control\" content=\"no-cache\">"; 508 responseString = responseString + "<meta http-equiv=\"cache-control\" content=\"no-cache\">";
406 responseString = responseString + "<meta http-equiv=\"Pragma\" content=\"no-cache\">"; 509 responseString = responseString + "<meta http-equiv=\"Pragma\" content=\"no-cache\">";
407 responseString = responseString + "<title>Second Life Login</title>"; 510 responseString = responseString + "<title>Second Life Login</title>";
408 responseString = responseString + "<body>"; 511 responseString = responseString + "<body><br />";
409 responseString = responseString + "<div id=\"login_box\">"; 512 responseString = responseString + "<div id=\"login_box\">";
410 513
411 responseString = responseString + "<form action=\"/\" method=\"GET\" id=\"login-form\">"; 514 responseString = responseString + "<form action=\"/\" method=\"GET\" id=\"login-form\">";
@@ -434,6 +537,11 @@ namespace OpenSim.Framework.UserManagement
434 responseString = responseString + "<input type=\"hidden\" name=\"show_login_form\" value=\"FALSE\" />"; 537 responseString = responseString + "<input type=\"hidden\" name=\"show_login_form\" value=\"FALSE\" />";
435 responseString = responseString + "<input type=\"hidden\" name=\"method\" value=\"login\" />"; 538 responseString = responseString + "<input type=\"hidden\" name=\"method\" value=\"login\" />";
436 responseString = responseString + "<input type=\"hidden\" id=\"grid\" name=\"grid\" value=\"[$grid]\" />"; 539 responseString = responseString + "<input type=\"hidden\" id=\"grid\" name=\"grid\" value=\"[$grid]\" />";
540 responseString = responseString + "<input type=\"hidden\" id=\"region\" name=\"region\" value=\"[$region]\" />";
541 responseString = responseString + "<input type=\"hidden\" id=\"location\" name=\"location\" value=\"[$location]\" />";
542 responseString = responseString + "<input type=\"hidden\" id=\"channel\" name=\"channel\" value=\"[$channel]\" />";
543 responseString = responseString + "<input type=\"hidden\" id=\"version\" name=\"version\" value=\"[$version]\" />";
544 responseString = responseString + "<input type=\"hidden\" id=\"lang\" name=\"lang\" value=\"[$lang]\" />";
437 responseString = responseString + "<div id=\"submitbtn\">"; 545 responseString = responseString + "<div id=\"submitbtn\">";
438 responseString = responseString + "<input class=\"input_over\" type=\"submit\" value=\"Connect\" />"; 546 responseString = responseString + "<input class=\"input_over\" type=\"submit\" value=\"Connect\" />";
439 responseString = responseString + "</div>"; 547 responseString = responseString + "</div>";
@@ -444,7 +552,7 @@ namespace OpenSim.Framework.UserManagement
444 responseString = responseString + "<a href=\"http://www.secondlife.com/account/request.php\" target=\"_blank\">Forgot password?</a>"; 552 responseString = responseString + "<a href=\"http://www.secondlife.com/account/request.php\" target=\"_blank\">Forgot password?</a>";
445 responseString = responseString + "</div>"; 553 responseString = responseString + "</div>";
446 554
447 responseString = responseString + "<div id=\"channelinfo\"> [$clientchannelinfo] | [$clientversion]=[$clientlanguage]</div>"; 555 responseString = responseString + "<div id=\"channelinfo\"> [$channel] | [$version]=[$lang]</div>";
448 responseString = responseString + "</form>"; 556 responseString = responseString + "</form>";
449 responseString = responseString + "<script language=\"JavaScript\">"; 557 responseString = responseString + "<script language=\"JavaScript\">";
450 responseString = responseString + "document.getElementById('firstname_input').focus();"; 558 responseString = responseString + "document.getElementById('firstname_input').focus();";
@@ -480,14 +588,26 @@ namespace OpenSim.Framework.UserManagement
480 "LOGIN", "Authenticating {0} {1} ({2})", profile.username, profile.surname, profile.UUID); 588 "LOGIN", "Authenticating {0} {1} ({2})", profile.username, profile.surname, profile.UUID);
481 589
482 // Web Login method seems to also occasionally send the hashed password itself 590 // Web Login method seems to also occasionally send the hashed password itself
483
484 591
592
593 // we do this to get our hash in a form that the server password code can consume
594 // when the web-login-form submits the password in the clear (supposed to be over SSL!)
595 if (!password.StartsWith("$1$"))
596 password = "$1$" + Util.Md5Hash(password);
597
598
599
485 password = password.Remove(0, 3); //remove $1$ 600 password = password.Remove(0, 3); //remove $1$
601
602
486 603
487 string s = Util.Md5Hash(password + ":" + profile.passwordSalt); 604 string s = Util.Md5Hash(password + ":" + profile.passwordSalt);
605 // Testing...
606 //MainLog.Instance.Verbose("LOGIN", "SubHash:" + s + " userprofile:" + profile.passwordHash);
607 //MainLog.Instance.Verbose("LOGIN", "userprofile:" + profile.passwordHash + " SubCT:" + password);
488 608
489 passwordSuccess = (profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase) 609 passwordSuccess = (profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
490 || profile.passwordHash.Equals(password.ToString(),StringComparison.InvariantCultureIgnoreCase)); 610 || profile.passwordHash.Equals(password,StringComparison.InvariantCultureIgnoreCase));
491 611
492 return passwordSuccess; 612 return passwordSuccess;
493 } 613 }