aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra
diff options
context:
space:
mode:
authorMcCabe Maxsted2011-04-19 14:49:18 -0700
committerMcCabe Maxsted2011-04-19 14:49:18 -0700
commita0902a050cc713f742990a09d2a610d4c135b7c7 (patch)
treec4a2c89cd48d6e50908959deed5318c6cd4fbaf5 /linden/indra
parentFixed usernames default setting to '.' when logging into second life for the ... (diff)
downloadmeta-impy-a0902a050cc713f742990a09d2a610d4c135b7c7.zip
meta-impy-a0902a050cc713f742990a09d2a610d4c135b7c7.tar.gz
meta-impy-a0902a050cc713f742990a09d2a610d4c135b7c7.tar.bz2
meta-impy-a0902a050cc713f742990a09d2a610d4c135b7c7.tar.xz
Remember name and password based on grid. This is far from optimal, but will work for the time being.
* UI needs to be made clear on what's going on with user's passwords * 'Remember password' checkbox now works on login (but is unclear) * Stored passwords are MD5s in grid_info.xml * Fixed vivox license appearing on other grids rather than specifically on second life login when voice is enabled * Small fix for username entry after logout * Sadly, storing password in the mac keychain needs to be reimplemented now
Diffstat (limited to 'linden/indra')
-rw-r--r--linden/indra/llcommon/llstring.cpp34
-rw-r--r--linden/indra/llcommon/llstring.h2
-rw-r--r--linden/indra/newview/app_settings/settings.xml33
-rw-r--r--linden/indra/newview/floatergridmanager.cpp63
-rw-r--r--linden/indra/newview/floatergridmanager.h8
-rw-r--r--linden/indra/newview/hippogridmanager.cpp96
-rw-r--r--linden/indra/newview/hippogridmanager.h6
-rw-r--r--linden/indra/newview/llagent.cpp3
-rw-r--r--linden/indra/newview/llappviewer.cpp20
-rw-r--r--linden/indra/newview/llfloaterchat.cpp3
-rw-r--r--linden/indra/newview/llloginhandler.cpp20
-rw-r--r--linden/indra/newview/llpanellogin.cpp56
-rw-r--r--linden/indra/newview/llpanellogin.h5
-rw-r--r--linden/indra/newview/llprefsim.cpp4
-rw-r--r--linden/indra/newview/llstartup.cpp242
-rw-r--r--linden/indra/newview/llstartup.h9
16 files changed, 254 insertions, 350 deletions
diff --git a/linden/indra/llcommon/llstring.cpp b/linden/indra/llcommon/llstring.cpp
index 0f72d5e..cd5a9f2 100644
--- a/linden/indra/llcommon/llstring.cpp
+++ b/linden/indra/llcommon/llstring.cpp
@@ -596,6 +596,40 @@ std::string utf8str_removeCRLF(const std::string& utf8str)
596 return out; 596 return out;
597} 597}
598 598
599bool is_hex_string(U8* str, S32 len)
600{
601 bool rv = true;
602 U8* c = str;
603 while(rv && len--)
604 {
605 switch(*c)
606 {
607 case '0':
608 case '1':
609 case '2':
610 case '3':
611 case '4':
612 case '5':
613 case '6':
614 case '7':
615 case '8':
616 case '9':
617 case 'a':
618 case 'b':
619 case 'c':
620 case 'd':
621 case 'e':
622 case 'f':
623 ++c;
624 break;
625 default:
626 rv = false;
627 break;
628 }
629 }
630 return rv;
631}
632
599#if LL_WINDOWS 633#if LL_WINDOWS
600// documentation moved to header. Phoenix 2007-11-27 634// documentation moved to header. Phoenix 2007-11-27
601namespace snprintf_hack 635namespace snprintf_hack
diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h
index 61767ac..a592e2c 100644
--- a/linden/indra/llcommon/llstring.h
+++ b/linden/indra/llcommon/llstring.h
@@ -456,6 +456,8 @@ LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str);
456 456
457LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); 457LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str);
458 458
459LL_COMMON_API bool is_hex_string(U8* str, S32 len);
460
459 461
460#if LL_WINDOWS 462#if LL_WINDOWS
461/* @name Windows string helpers 463/* @name Windows string helpers
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml
index c8ad381..79519fa 100644
--- a/linden/indra/newview/app_settings/settings.xml
+++ b/linden/indra/newview/app_settings/settings.xml
@@ -5865,17 +5865,6 @@
5865 <key>Value</key> 5865 <key>Value</key>
5866 <integer>1</integer> 5866 <integer>1</integer>
5867 </map> 5867 </map>
5868 <key>FirstName</key>
5869 <map>
5870 <key>Comment</key>
5871 <string>Login first name</string>
5872 <key>Persist</key>
5873 <integer>1</integer>
5874 <key>Type</key>
5875 <string>String</string>
5876 <key>Value</key>
5877 <string />
5878 </map>
5879 <key>FirstPersonAvatarVisible</key> 5868 <key>FirstPersonAvatarVisible</key>
5880 <map> 5869 <map>
5881 <key>Comment</key> 5870 <key>Comment</key>
@@ -7776,17 +7765,6 @@
7776 <key>Value</key> 7765 <key>Value</key>
7777 <string>find_all_panel</string> 7766 <string>find_all_panel</string>
7778 </map> 7767 </map>
7779 <key>LastName</key>
7780 <map>
7781 <key>Comment</key>
7782 <string>Login last name</string>
7783 <key>Persist</key>
7784 <integer>1</integer>
7785 <key>Type</key>
7786 <string>String</string>
7787 <key>Value</key>
7788 <string />
7789 </map>
7790 <key>LastPrefTab</key> 7768 <key>LastPrefTab</key>
7791 <map> 7769 <map>
7792 <key>Comment</key> 7770 <key>Comment</key>
@@ -8161,17 +8139,6 @@
8161 <key>Value</key> 8139 <key>Value</key>
8162 <integer>1</integer> 8140 <integer>1</integer>
8163 </map> 8141 </map>
8164 <key>Marker</key>
8165 <map>
8166 <key>Comment</key>
8167 <string>[NOT USED]</string>
8168 <key>Persist</key>
8169 <integer>1</integer>
8170 <key>Type</key>
8171 <string>String</string>
8172 <key>Value</key>
8173 <string />
8174 </map>
8175 <key>MaxDragDistance</key> 8142 <key>MaxDragDistance</key>
8176 <map> 8143 <map>
8177 <key>Comment</key> 8144 <key>Comment</key>
diff --git a/linden/indra/newview/floatergridmanager.cpp b/linden/indra/newview/floatergridmanager.cpp
index ad6ea05..257c210 100644
--- a/linden/indra/newview/floatergridmanager.cpp
+++ b/linden/indra/newview/floatergridmanager.cpp
@@ -47,13 +47,11 @@
47#include "llpanellogin.h" 47#include "llpanellogin.h"
48 48
49const std::string PASSWORD_FILLER = "123456789!123456"; 49const std::string PASSWORD_FILLER = "123456789!123456";
50//bool FloaterGridManager::sIsInitialLogin;
51 50
52FloaterGridManager::FloaterGridManager(const LLSD& key) 51FloaterGridManager::FloaterGridManager(const LLSD& key)
53 : 52 :
54 mState(GRID_STATE_NORMAL), 53 mState(GRID_STATE_NORMAL),
55 mCurGrid(""), 54 mCurGrid("")
56 mMungedPassword("")
57{ 55{
58 llinfos << "Opening grid manager" << llendl; 56 llinfos << "Opening grid manager" << llendl;
59 57
@@ -250,7 +248,15 @@ void FloaterGridManager::refreshGrids()
250 FloaterGridManager::getInstance()->getChild<LLLineEditor>("first_name")->setText(gridInfo->getFirstName()); 248 FloaterGridManager::getInstance()->getChild<LLLineEditor>("first_name")->setText(gridInfo->getFirstName());
251 FloaterGridManager::getInstance()->getChild<LLLineEditor>("last_name")->setText(gridInfo->getLastName()); 249 FloaterGridManager::getInstance()->getChild<LLLineEditor>("last_name")->setText(gridInfo->getLastName());
252 FloaterGridManager::getInstance()->getChild<LLLineEditor>("username")->setText(gridInfo->getUsername()); 250 FloaterGridManager::getInstance()->getChild<LLLineEditor>("username")->setText(gridInfo->getUsername());
253 FloaterGridManager::getInstance()->getChild<LLLineEditor>("avatar_password")->setText(gridInfo->getAvatarPassword()); 251
252 if (gridInfo->getPassword().empty())
253 {
254 FloaterGridManager::getInstance()->getChild<LLLineEditor>("avatar_password")->setText(LLStringExplicit(""));
255 }
256 else
257 {
258 FloaterGridManager::getInstance()->getChild<LLLineEditor>("avatar_password")->setText(PASSWORD_FILLER);
259 }
254 260
255 FloaterGridManager::getInstance()->getChild<LLLineEditor>("first_name")->setVisible(!gridInfo->isUsernameCompat()); 261 FloaterGridManager::getInstance()->getChild<LLLineEditor>("first_name")->setVisible(!gridInfo->isUsernameCompat());
256 FloaterGridManager::getInstance()->getChild<LLTextBox>("first_name_text")->setVisible(!gridInfo->isUsernameCompat()); 262 FloaterGridManager::getInstance()->getChild<LLTextBox>("first_name_text")->setVisible(!gridInfo->isUsernameCompat());
@@ -353,15 +359,13 @@ void FloaterGridManager::applyChanges()
353 359
354 // don't allow users to set their password as PASSWORD_FILLER 360 // don't allow users to set their password as PASSWORD_FILLER
355 // would be nice to get grid-specific rules on password formatting, too 361 // would be nice to get grid-specific rules on password formatting, too
356 // passwords are remembered by default 362 // passwords are remembered by default when entered in the grid manager (good default?)
357 std::string password_new = childGetValue("avatar_password").asString(); 363 std::string password_new = childGetValue("avatar_password").asString();
358 std::string password_old = grid->getAvatarPassword(); // initialized to "" 364 std::string password_old = grid->getPassword(); // initialized to ""
359 if (!password_new.empty() && password_new != PASSWORD_FILLER && password_new != password_old) 365 if (password_new != PASSWORD_FILLER && password_new != password_old)
360 { 366 {
361 // store account authentication data 367 // store account authentication data
362 std::string hashed_password; 368 grid->setPassword(password_new);
363 hashPassword(password_new, hashed_password);
364 grid->setAvatarPassword(hashed_password);
365 } 369 }
366 370
367 FloaterGridManager::getInstance()->getChild<LLScrollListCtrl>("grid_selector")->setEnabled(true); 371 FloaterGridManager::getInstance()->getChild<LLScrollListCtrl>("grid_selector")->setEnabled(true);
@@ -380,11 +384,11 @@ void FloaterGridManager::applyChanges()
380 // should this be settable? 384 // should this be settable?
381 if (grid->isUsernameCompat()) 385 if (grid->isUsernameCompat())
382 { 386 {
383 LLPanelLogin::setFields(grid->getUsername(), grid->getAvatarPassword()); 387 LLPanelLogin::setFields(grid->getUsername(), grid->getPassword());
384 } 388 }
385 else 389 else
386 { 390 {
387 LLPanelLogin::setFields(grid->getFirstName(), grid->getLastName(), grid->getAvatarPassword()); 391 LLPanelLogin::setFields(grid->getFirstName(), grid->getLastName(), grid->getPassword());
388 } 392 }
389 393
390 if (FloaterGridDefault::instanceVisible()) 394 if (FloaterGridDefault::instanceVisible())
@@ -540,6 +544,8 @@ void FloaterGridManager::apply()
540 544
541 gHippoGridManager->saveFile(); 545 gHippoGridManager->saveFile();
542 LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel()); 546 LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel());
547 LLPanelLogin::loadLoginForm();
548 LLPanelLogin::loadLoginPage();
543} 549}
544 550
545// static 551// static
@@ -697,36 +703,3 @@ BOOL FloaterGridManager::isGridComboDirty()
697// LLComboBox* combo = FloaterGridManager::getInstance()->getChild<LLComboBox>("start_location_combo"); 703// LLComboBox* combo = FloaterGridManager::getInstance()->getChild<LLComboBox>("start_location_combo");
698// location = combo->getValue().asString(); 704// location = combo->getValue().asString();
699//} 705//}
700
701std::string& FloaterGridManager::getPassword()
702{
703 return mMungedPassword;
704}
705
706void FloaterGridManager::setPassword(std::string &password)
707{
708 mMungedPassword = password;
709}
710
711bool FloaterGridManager::isSamePassword(std::string &password)
712{
713 return mMungedPassword == password;
714}
715
716void FloaterGridManager::hashPassword(const std::string& password, std::string& hashedPassword)
717{
718 // Max "actual" password length is 16 characters.
719 // Hex digests are always 32 characters.
720 if (password.length() == 32)
721 {
722 hashedPassword = password;
723 }
724 else
725 {
726 // this is a normal text password
727 LLMD5 pass((unsigned char *)password.c_str());
728 char munged_password[MD5HEX_STR_SIZE];
729 pass.hex_digest(munged_password);
730 hashedPassword = munged_password;
731 }
732}
diff --git a/linden/indra/newview/floatergridmanager.h b/linden/indra/newview/floatergridmanager.h
index b93a430..985a905 100644
--- a/linden/indra/newview/floatergridmanager.h
+++ b/linden/indra/newview/floatergridmanager.h
@@ -50,19 +50,12 @@ public:
50 50
51 void refresh(); 51 void refresh();
52 52
53 // new-style login methods
54 virtual std::string& getPassword();
55 virtual void setPassword(std::string &password);
56 virtual bool isSamePassword(std::string &password);
57
58 // clears either the loginuri fetched info or all the info in the grid manager 53 // clears either the loginuri fetched info or all the info in the grid manager
59 void clearGridInfo(bool clear_all); 54 void clearGridInfo(bool clear_all);
60 55
61 //static void getLocation(std::string &location); 56 //static void getLocation(std::string &location);
62 //void refreshLocation(bool force_visible) 57 //void refreshLocation(bool force_visible)
63 static BOOL isGridComboDirty(); 58 static BOOL isGridComboDirty();
64 //static void addServer(const std::string& server, S32 domain_name);
65 static void hashPassword(const std::string& password, std::string& hashedPassword);
66 59
67private: 60private:
68 61
@@ -75,7 +68,6 @@ private:
75 68
76 void setGridState(EGridState state) { mState = state; } 69 void setGridState(EGridState state) { mState = state; }
77 EGridState getGridState() { return mState; } 70 EGridState getGridState() { return mState; }
78 std::string mMungedPassword;
79 EGridState mState; 71 EGridState mState;
80 std::string mCurGrid; 72 std::string mCurGrid;
81 73
diff --git a/linden/indra/newview/hippogridmanager.cpp b/linden/indra/newview/hippogridmanager.cpp
index 8277361..78539f8 100644
--- a/linden/indra/newview/hippogridmanager.cpp
+++ b/linden/indra/newview/hippogridmanager.cpp
@@ -41,10 +41,14 @@
41#include <llerror.h> 41#include <llerror.h>
42#include <llfile.h> 42#include <llfile.h>
43#include <llhttpclient.h> 43#include <llhttpclient.h>
44#include "llmd5.h"
44#include <llsdserialize.h> 45#include <llsdserialize.h>
46
45#include "lltrans.h" 47#include "lltrans.h"
46#include "llviewercontrol.h" 48#include "llviewercontrol.h"
49#include "llviewernetwork.h" // gMacAddress
47#include "llweb.h" 50#include "llweb.h"
51#include "llxorcipher.h" // saved password, MAC address
48 52
49#include "hipporestrequest.h" 53#include "hipporestrequest.h"
50 54
@@ -82,7 +86,7 @@ HippoGridInfo::HippoGridInfo(const std::string& gridNick) :
82 mSearchURL(LLStringUtil::null), 86 mSearchURL(LLStringUtil::null),
83 mFirstName(LLStringUtil::null), 87 mFirstName(LLStringUtil::null),
84 mLastName(LLStringUtil::null), 88 mLastName(LLStringUtil::null),
85 mAvatarPassword(LLStringUtil::null), 89 mPasswordAvatar(LLStringUtil::null),
86 mXmlState(XML_VOID), 90 mXmlState(XML_VOID),
87 mVoiceConnector("SLVoice"), 91 mVoiceConnector("SLVoice"),
88 mRenderCompat(true), 92 mRenderCompat(true),
@@ -401,6 +405,92 @@ void HippoGridInfo::formatFee(std::string &fee, S32 cost, bool showFree) const
401} 405}
402 406
403 407
408void HippoGridInfo::setPassword(const std::string& unhashed_password)
409{
410 if (unhashed_password.empty())
411 {
412 mPasswordAvatar = "";
413 return;
414 }
415
416 if (unhashed_password == mPasswordAvatar)
417 {
418 return;
419 }
420
421 std::string hashed_password("");
422
423 // Max "actual" password length is 16 characters.
424 // Hex digests are always 32 characters.
425 if (unhashed_password.length() == 32)
426 {
427 hashed_password = unhashed_password;
428 }
429 else
430 {
431 // this is a user-entered plaintext password
432 LLMD5 pass((unsigned char *)unhashed_password.c_str());
433 char munged_password[MD5HEX_STR_SIZE];
434 pass.hex_digest(munged_password);
435 hashed_password = munged_password;
436 }
437
438 // need to fix the bug in this
439 /*
440
441 // Encipher with MAC address
442 const S32 HASHED_LENGTH = 32;
443 U8 buffer[HASHED_LENGTH+1];
444
445 LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1);
446
447 LLXORCipher cipher(gMACAddress, 6);
448 cipher.encrypt(buffer, HASHED_LENGTH);
449
450 mPasswordAvatar.assign((char*)buffer);
451 */
452 mPasswordAvatar.assign(hashed_password);
453}
454
455
456std::string HippoGridInfo::getPassword() const
457{
458 // need to fix the bug in this
459 /*
460 if (mPasswordAvatar.empty() || mPasswordAvatar.length() == 32)
461 {
462 return mPasswordAvatar;
463 }
464
465 std::string hashed_password("");
466
467 // UUID is 16 bytes, written into ASCII is 32 characters
468 // without trailing \0
469 const S32 HASHED_LENGTH = 32;
470 U8 buffer[HASHED_LENGTH+1];
471
472 LLStringUtil::copy((char*)buffer, mPasswordAvatar.c_str(), HASHED_LENGTH+1);
473
474 // Decipher with MAC address
475 LLXORCipher cipher(gMACAddress, 6);
476 cipher.decrypt(buffer, HASHED_LENGTH);
477
478 buffer[HASHED_LENGTH] = '\0';
479
480 // Check to see if the mac address generated a bad hashed
481 // password. It should be a hex-string or else the mac adress has
482 // changed. This is a security feature to make sure that if you
483 // get someone's grid_info.xml file, you cannot hack their account.
484 if (is_hex_string(buffer, HASHED_LENGTH))
485 {
486 hashed_password.assign((char*)buffer);
487 }
488
489 return hashed_password;
490 */
491 return mPasswordAvatar;
492}
493
404// ******************************************************************** 494// ********************************************************************
405// Static Helpers 495// Static Helpers
406 496
@@ -800,7 +890,7 @@ void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer)
800 if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]); 890 if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]);
801 if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]); 891 if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]);
802 if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]); 892 if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]);
803 if (gridMap.has("avatarpassword")) grid->setAvatarPassword(gridMap["avatarpassword"]); 893 if (gridMap.has("avatarpassword")) grid->setPassword(gridMap["avatarpassword"]);
804 if (gridMap.has("username")) grid->setUsername(gridMap["username"]); 894 if (gridMap.has("username")) grid->setUsername(gridMap["username"]);
805 if (gridMap.has("username_compat")) grid->setUsernameCompat(gridMap["username_compat"]); 895 if (gridMap.has("username_compat")) grid->setUsernameCompat(gridMap["username_compat"]);
806 if (newGrid) addGrid(grid); 896 if (newGrid) addGrid(grid);
@@ -836,7 +926,7 @@ void HippoGridManager::saveFile()
836 gridInfo[i]["password"] = grid->getPasswordURL(); 926 gridInfo[i]["password"] = grid->getPasswordURL();
837 gridInfo[i]["firstname"] = grid->getFirstName(); 927 gridInfo[i]["firstname"] = grid->getFirstName();
838 gridInfo[i]["lastname"] = grid->getLastName(); 928 gridInfo[i]["lastname"] = grid->getLastName();
839 gridInfo[i]["avatarpassword"] = grid->getAvatarPassword(); 929 gridInfo[i]["avatarpassword"] = grid->getPassword();
840 930
841 gridInfo[i]["search"] = grid->getSearchURL(); 931 gridInfo[i]["search"] = grid->getSearchURL();
842 gridInfo[i]["render_compat"] = grid->isRenderCompat(); 932 gridInfo[i]["render_compat"] = grid->isRenderCompat();
diff --git a/linden/indra/newview/hippogridmanager.h b/linden/indra/newview/hippogridmanager.h
index f1b0a8e..c983c9d 100644
--- a/linden/indra/newview/hippogridmanager.h
+++ b/linden/indra/newview/hippogridmanager.h
@@ -88,7 +88,7 @@ public:
88 const std::string& getFirstName() const { return mFirstName; } 88 const std::string& getFirstName() const { return mFirstName; }
89 const std::string& getLastName() const { return mLastName; } 89 const std::string& getLastName() const { return mLastName; }
90 const std::string& getUsername() const { return mUsername; } 90 const std::string& getUsername() const { return mUsername; }
91 const std::string& getAvatarPassword() const { return mAvatarPassword; } 91 std::string getPassword() const;
92 const std::string& getVoiceConnector() const { return mVoiceConnector; } 92 const std::string& getVoiceConnector() const { return mVoiceConnector; }
93 S32 getMaxAgentGroups() const { return mMaxAgentGroups; } 93 S32 getMaxAgentGroups() const { return mMaxAgentGroups; }
94 const std::string& getCurrencySymbol() const { return mCurrencySymbol; } 94 const std::string& getCurrencySymbol() const { return mCurrencySymbol; }
@@ -114,7 +114,7 @@ public:
114 void setMaxAgentGroups(S32 max) { mMaxAgentGroups = max; } 114 void setMaxAgentGroups(S32 max) { mMaxAgentGroups = max; }
115 void setFirstName(const std::string& firstName) { mFirstName = firstName; } 115 void setFirstName(const std::string& firstName) { mFirstName = firstName; }
116 void setLastName(const std::string& lastName) { mLastName = lastName; } 116 void setLastName(const std::string& lastName) { mLastName = lastName; }
117 void setAvatarPassword(const std::string& avatarPassword) { mAvatarPassword = avatarPassword; } 117 void setPassword(const std::string& unhashed_password);
118 void setVoiceConnector(const std::string& vc) { mVoiceConnector = vc; } 118 void setVoiceConnector(const std::string& vc) { mVoiceConnector = vc; }
119 void setCurrencySymbol(const std::string& sym) { mCurrencySymbol = sym.substr(0, 3); } 119 void setCurrencySymbol(const std::string& sym) { mCurrencySymbol = sym.substr(0, 3); }
120 void setRealCurrencySymbol(const std::string& sym) { mRealCurrencySymbol = sym.substr(0, 3); } 120 void setRealCurrencySymbol(const std::string& sym) { mRealCurrencySymbol = sym.substr(0, 3); }
@@ -145,7 +145,7 @@ private:
145 std::string mVoiceConnector; 145 std::string mVoiceConnector;
146 std::string mFirstName; 146 std::string mFirstName;
147 std::string mLastName; 147 std::string mLastName;
148 std::string mAvatarPassword; 148 std::string mPasswordAvatar;
149 bool mRenderCompat; 149 bool mRenderCompat;
150 S32 mMaxAgentGroups; 150 S32 mMaxAgentGroups;
151 151
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp
index 88ec2ca..44a71da 100644
--- a/linden/indra/newview/llagent.cpp
+++ b/linden/indra/newview/llagent.cpp
@@ -56,6 +56,7 @@
56#include "llsdutil.h" 56#include "llsdutil.h"
57//#include "vmath.h" 57//#include "vmath.h"
58 58
59#include "hippogridmanager.h"
59#include "imageids.h" 60#include "imageids.h"
60#include "llbox.h" 61#include "llbox.h"
61#include "llbutton.h" 62#include "llbutton.h"
@@ -5590,7 +5591,7 @@ void LLAgent::getName(std::string& name)
5590 } 5591 }
5591 else 5592 else
5592 { 5593 {
5593 name = gSavedSettings.getString("FirstName") + " " + gSavedSettings.getString("LastName"); 5594 name = gHippoGridManager->getCurrentGrid()->getFirstName() + " " + gHippoGridManager->getCurrentGrid()->getLastName();
5594 } 5595 }
5595} 5596}
5596 5597
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp
index cbec717..0bb5759 100644
--- a/linden/indra/newview/llappviewer.cpp
+++ b/linden/indra/newview/llappviewer.cpp
@@ -1267,6 +1267,19 @@ bool LLAppViewer::cleanup()
1267 1267
1268 LLCalc::cleanUp(); 1268 LLCalc::cleanUp();
1269 1269
1270 // Quitting with "Remember Password" turned off should always stomp your
1271 // saved password, whether or not you successfully logged in. JC
1272 if (!gSavedSettings.getBOOL("RememberPassword"))
1273 {
1274 gHippoGridManager->getConnectedGrid()->setPassword("");
1275
1276 // kill old password.dat file if it exists. We do this to keep setting compatibility with older versions -- MC
1277 std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "password.dat");
1278 LLFile::remove(filepath);
1279 }
1280
1281 gHippoGridManager->saveFile();
1282
1270 delete gHippoGridManager; 1283 delete gHippoGridManager;
1271 gHippoGridManager = NULL; 1284 gHippoGridManager = NULL;
1272 1285
@@ -1418,13 +1431,6 @@ bool LLAppViewer::cleanup()
1418 // 1431 //
1419 LLVFile::cleanupClass(); 1432 LLVFile::cleanupClass();
1420 llinfos << "VFS cleaned up" << llendflush; 1433 llinfos << "VFS cleaned up" << llendflush;
1421
1422 // Quitting with "Remember Password" turned off should always stomp your
1423 // saved password, whether or not you successfully logged in. JC
1424 if (!gSavedSettings.getBOOL("RememberPassword"))
1425 {
1426 LLStartUp::deletePasswordFromDisk();
1427 }
1428 1434
1429 // Store the time of our current logoff 1435 // Store the time of our current logoff
1430 gSavedPerAccountSettings.setU32("LastLogoff", time_corrected()); 1436 gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp
index 79dddaa..f3d71d7 100644
--- a/linden/indra/newview/llfloaterchat.cpp
+++ b/linden/indra/newview/llfloaterchat.cpp
@@ -49,6 +49,7 @@
49#include "message.h" 49#include "message.h"
50 50
51// project include 51// project include
52#include "hippogridmanager.h"
52#include "llagent.h" 53#include "llagent.h"
53#include "llbutton.h" 54#include "llbutton.h"
54#include "llcheckboxctrl.h" 55#include "llcheckboxctrl.h"
@@ -475,7 +476,7 @@ BOOL checkStringInText(const std::string &text_line, std::string textToMatch)
475 476
476BOOL LLFloaterChat::isOwnNameInText(const std::string &text_line) 477BOOL LLFloaterChat::isOwnNameInText(const std::string &text_line)
477{ 478{
478 if (checkStringInText(text_line, gSavedSettings.getString("FirstName"))) 479 if (checkStringInText(text_line, gHippoGridManager->getConnectedGrid()->getFirstName()))
479 return TRUE; 480 return TRUE;
480 481
481 for (int i=1; i<=3; i++) 482 for (int i=1; i<=3; i++)
diff --git a/linden/indra/newview/llloginhandler.cpp b/linden/indra/newview/llloginhandler.cpp
index c35ba04..988ef2f 100644
--- a/linden/indra/newview/llloginhandler.cpp
+++ b/linden/indra/newview/llloginhandler.cpp
@@ -131,23 +131,29 @@ bool LLLoginHandler::handle(const LLSD& tokens,
131 131
132 if (password.substr(0,3) != "$1$") 132 if (password.substr(0,3) != "$1$")
133 { 133 {
134 LLMD5 pass((unsigned char*)password.c_str()); 134 // grids we try in order: loginhandler "grid", LastConnectedGrid, grid manager
135 char md5pass[33]; /* Flawfinder: ignore */ 135 // icky that we do this here and in LLStartUp
136 pass.hex_digest(md5pass); 136 std::string grid_nick = query_map["grid"].asString();
137 std::string hashed_password = ll_safe_string(md5pass, 32); 137 if (grid_nick.empty()) grid_nick = gSavedSettings.getString("LastConnectedGrid");
138 LLStartUp::savePasswordToDisk(hashed_password); 138 if (grid_nick.empty()) grid_nick = gHippoGridManager->getCurrentGridNick();
139 HippoGridInfo* grid = gHippoGridManager->getGrid(grid_nick);
140 if (grid) grid->setPassword(password);
139 } 141 }
140 } 142 }
141 143
142 144
143 if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page 145 if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP) //on splash page
144 { 146 {
145 // if we ever support saving names based on grid, we'll have to support saving usernames too -- MC
146 LLPanelLogin::loadLoginForm(); 147 LLPanelLogin::loadLoginForm();
147 148
148 if (!mFirstName.empty() || !mLastName.empty()) 149 if (!mFirstName.empty() || !mLastName.empty())
149 { 150 {
150 // Fill in the name, and maybe the password 151 // Fill in the name, and the password if we can
152 if (password.empty())
153 {
154 password = gHippoGridManager->getCurrentGrid()->getPassword();
155 }
156
151 if (gHippoGridManager && gHippoGridManager->getCurrentGrid()->isUsernameCompat()) 157 if (gHippoGridManager && gHippoGridManager->getCurrentGrid()->isUsernameCompat())
152 { 158 {
153 if (mLastName == "resident" || mLastName == "Resident") 159 if (mLastName == "resident" || mLastName == "Resident")
diff --git a/linden/indra/newview/llpanellogin.cpp b/linden/indra/newview/llpanellogin.cpp
index 7b05794..fd9d077 100644
--- a/linden/indra/newview/llpanellogin.cpp
+++ b/linden/indra/newview/llpanellogin.cpp
@@ -91,6 +91,7 @@
91 91
92const S32 BLACK_BORDER_HEIGHT = 160; 92const S32 BLACK_BORDER_HEIGHT = 160;
93const S32 MAX_PASSWORD = 16; 93const S32 MAX_PASSWORD = 16;
94const std::string PASSWORD_FILLER = "123456789!123456";
94 95
95LLPanelLogin *LLPanelLogin::sInstance = NULL; 96LLPanelLogin *LLPanelLogin::sInstance = NULL;
96BOOL LLPanelLogin::sCapslockDidNotification = FALSE; 97BOOL LLPanelLogin::sCapslockDidNotification = FALSE;
@@ -174,7 +175,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
174 mLogoImage(), 175 mLogoImage(),
175 mCallback(callback), 176 mCallback(callback),
176 mCallbackData(cb_data), 177 mCallbackData(cb_data),
177 mHtmlAvailable( TRUE ) 178 mHtmlAvailable( TRUE ),
179 mActualPassword("")
178{ 180{
179 setFocusRoot(TRUE); 181 setFocusRoot(TRUE);
180 182
@@ -212,7 +214,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
212 childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace); 214 childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
213 childSetPrevalidate("username_edit", LLLineEditor::prevalidatePrintableSpace); 215 childSetPrevalidate("username_edit", LLLineEditor::prevalidatePrintableSpace);
214 216
215 childSetCommitCallback("password_edit", mungePassword); 217 childSetCommitCallback("password_edit", onPasswordChanged, this);
216 childSetKeystrokeCallback("password_edit", onPassKey, this); 218 childSetKeystrokeCallback("password_edit", onPassKey, this);
217 childSetUserData("password_edit", this); 219 childSetUserData("password_edit", this);
218 220
@@ -355,22 +357,6 @@ void LLPanelLogin::setSiteIsAlive( bool alive )
355 } 357 }
356} 358}
357 359
358void LLPanelLogin::mungePassword(LLUICtrl* caller, void* user_data)
359{
360 LLPanelLogin* self = (LLPanelLogin*)user_data;
361 LLLineEditor* editor = (LLLineEditor*)caller;
362 std::string password = editor->getText();
363
364 // Re-md5 if we've changed at all
365 if (password != self->mIncomingPassword)
366 {
367 LLMD5 pass((unsigned char *)password.c_str());
368 char munged_password[MD5HEX_STR_SIZE];
369 pass.hex_digest(munged_password);
370 self->mMungedPassword = munged_password;
371 }
372}
373
374LLPanelLogin::~LLPanelLogin() 360LLPanelLogin::~LLPanelLogin()
375{ 361{
376 LLPanelLogin::sInstance = NULL; 362 LLPanelLogin::sInstance = NULL;
@@ -596,6 +582,8 @@ void LLPanelLogin::setFields(const std::string& firstname,
596// static 582// static
597void LLPanelLogin::setPassword(const std::string& password) 583void LLPanelLogin::setPassword(const std::string& password)
598{ 584{
585 // we check for sInstance before getting here
586
599 // Max "actual" password length is 16 characters. 587 // Max "actual" password length is 16 characters.
600 // Hex digests are always 32 characters. 588 // Hex digests are always 32 characters.
601 if (password.length() == 32) 589 if (password.length() == 32)
@@ -604,21 +592,16 @@ void LLPanelLogin::setPassword(const std::string& password)
604 // We don't actually use the password input field, 592 // We don't actually use the password input field,
605 // fill it with MAX_PASSWORD characters so we get a 593 // fill it with MAX_PASSWORD characters so we get a
606 // nice row of asterixes. 594 // nice row of asterixes.
607 const std::string filler("123456789!123456"); 595 sInstance->childSetText("password_edit", PASSWORD_FILLER);
608 sInstance->childSetText("password_edit", filler);
609 sInstance->mIncomingPassword = filler;
610 sInstance->mMungedPassword = password;
611 } 596 }
612 else 597 else
613 { 598 {
614 // this is a normal text password 599 // this is a normal text password
615 sInstance->childSetText("password_edit", password); 600 sInstance->childSetText("password_edit", password);
616 sInstance->mIncomingPassword = password;
617 LLMD5 pass((unsigned char *)password.c_str());
618 char munged_password[MD5HEX_STR_SIZE];
619 pass.hex_digest(munged_password);
620 sInstance->mMungedPassword = munged_password;
621 } 601 }
602
603 // munging happens in the grid manager now
604 sInstance->mActualPassword = password;
622} 605}
623 606
624 607
@@ -714,7 +697,8 @@ void LLPanelLogin::getFields(std::string *firstname,
714 LLStringUtil::trim(*lastname); 697 LLStringUtil::trim(*lastname);
715 } 698 }
716 699
717 *password = sInstance->mMungedPassword; 700 // sent to us from LLStartUp. Saved only on an actual connect
701 *password = sInstance->mActualPassword;
718} 702}
719 703
720// static 704// static
@@ -893,7 +877,7 @@ void LLPanelLogin::loadLoginForm()
893 lastname_l->setText(lastname_s); 877 lastname_l->setText(lastname_s);
894 } 878 }
895 879
896 setPassword(gHippoGridManager->getCurrentGrid()->getAvatarPassword()); 880 setPassword(gHippoGridManager->getCurrentGrid()->getPassword());
897} 881}
898 882
899 883
@@ -1224,6 +1208,20 @@ void LLPanelLogin::onClickNewAccount(void*)
1224 } 1208 }
1225} 1209}
1226 1210
1211// static
1212void LLPanelLogin::onPasswordChanged(LLUICtrl* caller, void* user_data)
1213{
1214 LLPanelLogin* self = (LLPanelLogin*)user_data;
1215 LLLineEditor* editor = (LLLineEditor*)caller;
1216 std::string password = editor->getText();
1217
1218 // update if we've changed at all
1219 // is there a good way to let users know we can't let them use PASSWORD_FILLER?
1220 if (password != self->mActualPassword && password != PASSWORD_FILLER)
1221 {
1222 self->mActualPassword = password;
1223 }
1224}
1227 1225
1228// *NOTE: This function is dead as of 2008 August. I left it here in case 1226// *NOTE: This function is dead as of 2008 August. I left it here in case
1229// we suddenly decide to put the Quit button back. JC 1227// we suddenly decide to put the Quit button back. JC
diff --git a/linden/indra/newview/llpanellogin.h b/linden/indra/newview/llpanellogin.h
index 947aea6..645999c 100644
--- a/linden/indra/newview/llpanellogin.h
+++ b/linden/indra/newview/llpanellogin.h
@@ -83,7 +83,6 @@ public:
83 static void refreshLoginPage(); 83 static void refreshLoginPage();
84 static void giveFocus(); 84 static void giveFocus();
85 static void setAlwaysRefresh(bool refresh); 85 static void setAlwaysRefresh(bool refresh);
86 static void mungePassword(LLUICtrl* caller, void* user_data);
87 86
88 // inherited from LLViewerMediaObserver 87 // inherited from LLViewerMediaObserver
89 /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); 88 /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
@@ -98,6 +97,7 @@ private:
98 static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response); 97 static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response);
99 static void onClickQuit(void*); 98 static void onClickQuit(void*);
100 static void onClickVersion(void*); 99 static void onClickVersion(void*);
100 static void onPasswordChanged(LLUICtrl* caller, void* user_data);
101 static void onClickForgotPassword(void*); 101 static void onClickForgotPassword(void*);
102 static void onPassKey(LLLineEditor* caller, void* user_data); 102 static void onPassKey(LLLineEditor* caller, void* user_data);
103 static void onSelectServer(LLUICtrl*, void*); 103 static void onSelectServer(LLUICtrl*, void*);
@@ -120,8 +120,7 @@ private:
120 void (*mCallback)(S32 option, void *userdata); 120 void (*mCallback)(S32 option, void *userdata);
121 void* mCallbackData; 121 void* mCallbackData;
122 122
123 std::string mIncomingPassword; 123 std::string mActualPassword;
124 std::string mMungedPassword;
125 124
126 static LLPanelLogin* sInstance; 125 static LLPanelLogin* sInstance;
127 static BOOL sCapslockDidNotification; 126 static BOOL sCapslockDidNotification;
diff --git a/linden/indra/newview/llprefsim.cpp b/linden/indra/newview/llprefsim.cpp
index 5ac2bb2..33d9701 100644
--- a/linden/indra/newview/llprefsim.cpp
+++ b/linden/indra/newview/llprefsim.cpp
@@ -179,12 +179,12 @@ void LLPrefsIMImpl::apply()
179 if (gSavedSettings.getBOOL("UseLegacyChatLogsFolder")) 179 if (gSavedSettings.getBOOL("UseLegacyChatLogsFolder"))
180 { 180 {
181 gDirUtilp->setPerAccountChatLogsDir(LLStringUtil::null, 181 gDirUtilp->setPerAccountChatLogsDir(LLStringUtil::null,
182 gSavedSettings.getString("FirstName"), gSavedSettings.getString("LastName") ); 182 gHippoGridManager->getCurrentGrid()->getFirstName(), gHippoGridManager->getCurrentGrid()->getLastName() );
183 } 183 }
184 else 184 else
185 { 185 {
186 gDirUtilp->setPerAccountChatLogsDir(gHippoGridManager->getCurrentGridNick(), 186 gDirUtilp->setPerAccountChatLogsDir(gHippoGridManager->getCurrentGridNick(),
187 gSavedSettings.getString("FirstName"), gSavedSettings.getString("LastName") ); 187 gHippoGridManager->getCurrentGrid()->getFirstName(), gHippoGridManager->getCurrentGrid()->getLastName() );
188 } 188 }
189 LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); 189 LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
190 } 190 }
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index 4028cad..e29dc5a 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -76,7 +76,6 @@
76#include "llstring.h" 76#include "llstring.h"
77#include "lluserrelations.h" 77#include "lluserrelations.h"
78#include "llvfs.h" 78#include "llvfs.h"
79#include "llxorcipher.h" // saved password, MAC address
80#include "message.h" 79#include "message.h"
81#include "v3math.h" 80#include "v3math.h"
82 81
@@ -262,7 +261,6 @@ bool LLStartUp::sLoginFailed = false;
262 261
263void login_show(); 262void login_show();
264void login_callback(S32 option, void* userdata); 263void login_callback(S32 option, void* userdata);
265bool is_hex_string(U8* str, S32 len);
266void show_first_run_dialog(); 264void show_first_run_dialog();
267bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); 265bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);
268void set_startup_status(const F32 frac, const std::string& string, const std::string& msg); 266void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
@@ -750,12 +748,13 @@ bool idle_startup()
750#endif 748#endif
751 gSavedSettings.setBOOL("AutoLogin", TRUE); 749 gSavedSettings.setBOOL("AutoLogin", TRUE);
752 } 750 }
753 else if (gSavedSettings.getBOOL("AutoLogin")) 751 else if (gSavedSettings.getBOOL("AutoLogin") && gHippoGridManager)
754 { 752 {
755 firstname = gSavedSettings.getString("FirstName"); 753 // at this point, getCurrentGrid is the last logged in grid. Should we create a new entry for this? -- MC
756 lastname = gSavedSettings.getString("LastName"); 754 firstname = gHippoGridManager->getCurrentGrid()->getFirstName();
757 password = LLStartUp::loadPasswordFromDisk(); 755 lastname = gHippoGridManager->getCurrentGrid()->getLastName();
758 gSavedSettings.setBOOL("RememberPassword", TRUE); 756 password = gHippoGridManager->getCurrentGrid()->getPassword();
757 gSavedSettings.setBOOL("RememberPassword", TRUE); // why do we do this, anyway? -- MC
759 758
760#ifdef USE_VIEWER_AUTH 759#ifdef USE_VIEWER_AUTH
761 show_connect_box = true; 760 show_connect_box = true;
@@ -766,9 +765,7 @@ bool idle_startup()
766 else 765 else
767 { 766 {
768 // if not automatically logging in, display login dialog 767 // if not automatically logging in, display login dialog
769 firstname = gSavedSettings.getString("FirstName"); 768 // name and password are now handled in STATE_LOGIN_SHOW when the login screen's shown -- MC
770 lastname = gSavedSettings.getString("LastName");
771 password = LLStartUp::loadPasswordFromDisk();
772 show_connect_box = true; 769 show_connect_box = true;
773 } 770 }
774 771
@@ -826,17 +823,19 @@ bool idle_startup()
826 823
827 // connect dialog is already shown, so fill in the names associated with the grid 824 // connect dialog is already shown, so fill in the names associated with the grid
828 // note how we always remember avatar names, but don't necessarily have to 825 // note how we always remember avatar names, but don't necessarily have to
829 // icky how usernames get bolted on here as a kind of hack -- MC 826 // icky how all this gets bolted on here as a kind of hack -- MC
830 if (gHippoGridManager) 827 if (gHippoGridManager)
831 { 828 {
832 firstname = gHippoGridManager->getCurrentGrid()->getFirstName(); 829 firstname = gHippoGridManager->getCurrentGrid()->getFirstName();
833 lastname = gHippoGridManager->getCurrentGrid()->getLastName(); 830 lastname = gHippoGridManager->getCurrentGrid()->getLastName();
834 // RememberPassword toggles this being saved 831 // RememberPassword toggles this being saved
835 password = gHippoGridManager->getCurrentGrid()->getAvatarPassword(); 832 password = gHippoGridManager->getCurrentGrid()->getPassword();
836 833
834 // empty in case we used logout
837 if (gHippoGridManager->getCurrentGrid()->isUsernameCompat()) 835 if (gHippoGridManager->getCurrentGrid()->isUsernameCompat())
838 { 836 {
839 if (lastname == "resident" || lastname == "Resident") 837 if ((lastname == "resident" || lastname == "Resident") ||
838 (firstname.empty() && lastname.empty()))
840 { 839 {
841 LLPanelLogin::setFields(firstname, password); 840 LLPanelLogin::setFields(firstname, password);
842 } 841 }
@@ -998,8 +997,8 @@ bool idle_startup()
998 997
999 if (!firstname.empty() && !lastname.empty()) 998 if (!firstname.empty() && !lastname.empty())
1000 { 999 {
1001 gSavedSettings.setString("FirstName", firstname); 1000 gHippoGridManager->getCurrentGrid()->setFirstName(firstname);
1002 gSavedSettings.setString("LastName", lastname); 1001 gHippoGridManager->getCurrentGrid()->setLastName(lastname);
1003 1002
1004 //LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << " " << password << LL_ENDL; 1003 //LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << " " << password << LL_ENDL;
1005 gDebugInfo["LoginName"] = firstname + " " + lastname; 1004 gDebugInfo["LoginName"] = firstname + " " + lastname;
@@ -1162,7 +1161,9 @@ bool idle_startup()
1162 // color init must be after saved settings loaded 1161 // color init must be after saved settings loaded
1163 init_colors(); 1162 init_colors();
1164 1163
1165 if (gSavedSettings.getBOOL("VivoxLicenseAccepted") || gHippoGridManager->getConnectedGrid()->isSecondLife()) 1164 if (!gSavedSettings.getBOOL("EnableVoiceChat") ||
1165 (gSavedSettings.getBOOL("EnableVoiceChat") && gSavedSettings.getBOOL("VivoxLicenseAccepted")) ||
1166 !gHippoGridManager->getConnectedGrid()->isSecondLife())
1166 { 1167 {
1167 // skipping over STATE_LOGIN_VOICE_LICENSE since we don't need it 1168 // skipping over STATE_LOGIN_VOICE_LICENSE since we don't need it
1168 // skipping over STATE_UPDATE_CHECK because that just waits for input 1169 // skipping over STATE_UPDATE_CHECK because that just waits for input
@@ -1306,6 +1307,21 @@ bool idle_startup()
1306 } 1307 }
1307 } 1308 }
1308 1309
1310 // We hash a temporary password for login auth. The actual stored password
1311 // is in the grid manager, and is XORed with the mac address -- MC
1312 std::string hashed_password("");
1313 if (password.length() == 32)
1314 {
1315 hashed_password = password;
1316 }
1317 else if (!password.empty())
1318 {
1319 LLMD5 pass((unsigned char *)password.c_str());
1320 char munged_password[MD5HEX_STR_SIZE];
1321 pass.hex_digest(munged_password);
1322 hashed_password = munged_password;
1323 }
1324
1309 // TODO if statement here to use web_login_key 1325 // TODO if statement here to use web_login_key
1310 if(web_login_key.isNull()){ 1326 if(web_login_key.isNull()){
1311 sAuthUriNum = llclamp(sAuthUriNum, 0, (S32)sAuthUris.size()-1); 1327 sAuthUriNum = llclamp(sAuthUriNum, 0, (S32)sAuthUris.size()-1);
@@ -1314,7 +1330,7 @@ bool idle_startup()
1314 auth_method, 1330 auth_method,
1315 firstname, 1331 firstname,
1316 lastname, 1332 lastname,
1317 password, 1333 hashed_password,
1318 //web_login_key, 1334 //web_login_key,
1319 start.str(), 1335 start.str(),
1320 gSkipOptionalUpdate, 1336 gSkipOptionalUpdate,
@@ -1573,10 +1589,8 @@ bool idle_startup()
1573 1589
1574 if(successful_login) 1590 if(successful_login)
1575 { 1591 {
1576 { 1592 std::string current_grid = gHippoGridManager->getConnectedGrid()->getGridNick();
1577 std::string current_grid = gHippoGridManager->getConnectedGrid()->getGridNick(); 1593 gSavedSettings.setString("LastConnectedGrid", current_grid);
1578 gSavedSettings.setString("LastConnectedGrid", current_grid);
1579 }
1580 1594
1581 std::string text; 1595 std::string text;
1582 text = LLUserAuth::getInstance()->getResponse("udp_blacklist"); 1596 text = LLUserAuth::getInstance()->getResponse("udp_blacklist");
@@ -1608,19 +1622,23 @@ bool idle_startup()
1608 } 1622 }
1609 text = LLUserAuth::getInstance()->getResponse("last_name"); 1623 text = LLUserAuth::getInstance()->getResponse("last_name");
1610 if(!text.empty()) lastname.assign(text); 1624 if(!text.empty()) lastname.assign(text);
1611 gSavedSettings.setString("FirstName", firstname); 1625
1612 gSavedSettings.setString("LastName", lastname); 1626 gHippoGridManager->getConnectedGrid()->setFirstName(firstname);
1627 gHippoGridManager->getConnectedGrid()->setLastName(lastname);
1613 1628
1614 if (gSavedSettings.getBOOL("RememberPassword")) 1629 if (gSavedSettings.getBOOL("RememberPassword"))
1615 { 1630 {
1616 // Successful login means the password is valid, so save it. 1631 // Successful login means the password is valid, so save it.
1617 LLStartUp::savePasswordToDisk(password); 1632 // formerly LLStartUp::savePasswordToDisk(password);
1633 // this needs to happen after gMACAddress is set -- MC
1634 gHippoGridManager->getConnectedGrid()->setPassword(password);
1618 } 1635 }
1619 else 1636 else
1620 { 1637 {
1621 // Don't leave password from previous session sitting around 1638 // Don't leave password from previous session sitting around
1622 // during this login session. 1639 // during this login session.
1623 LLStartUp::deletePasswordFromDisk(); 1640 // formerly LLStartUp::deletePasswordFromDisk(); -- MC
1641 gHippoGridManager->getConnectedGrid()->setPassword("");
1624 } 1642 }
1625 1643
1626 // this is their actual ability to access content 1644 // this is their actual ability to access content
@@ -3084,180 +3102,6 @@ void login_callback(S32 option, void *userdata)
3084} 3102}
3085 3103
3086 3104
3087// static
3088std::string LLStartUp::loadPasswordFromDisk()
3089{
3090 // Only load password if we also intend to save it (otherwise the user
3091 // wonders what we're doing behind his back). JC
3092 BOOL remember_password = gSavedSettings.getBOOL("RememberPassword");
3093 if (!remember_password)
3094 {
3095 return std::string("");
3096 }
3097
3098 std::string hashed_password("");
3099
3100 // Look for legacy "marker" password from settings.ini
3101 hashed_password = gSavedSettings.getString("Marker");
3102 if (!hashed_password.empty())
3103 {
3104 // Stomp the Marker entry.
3105 gSavedSettings.setString("Marker", "");
3106
3107 // Return that password.
3108 return hashed_password;
3109 }
3110
3111 // UUID is 16 bytes, written into ASCII is 32 characters
3112 // without trailing \0
3113 const S32 HASHED_LENGTH = 32;
3114
3115 std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
3116 "password.dat");
3117 LLFILE* fp = LLFile::fopen(filepath, "rb"); /* Flawfinder: ignore */
3118 if (!fp)
3119 {
3120#if LL_DARWIN
3121 UInt32 passwordLength;
3122 char *passwordData;
3123 OSStatus stat = SecKeychainFindGenericPassword(NULL, 10, "Imprudence", 0, NULL, &passwordLength, (void**)&passwordData, NULL);
3124 if (stat == noErr)
3125 {
3126 if (passwordLength == HASHED_LENGTH)
3127 hashed_password.assign(passwordData, HASHED_LENGTH);
3128 SecKeychainItemFreeContent(NULL, passwordData);
3129 }
3130#endif
3131 return hashed_password;
3132 }
3133
3134 U8 buffer[HASHED_LENGTH+1];
3135
3136 if (1 != fread(buffer, HASHED_LENGTH, 1, fp))
3137 {
3138 return hashed_password;
3139 }
3140
3141 fclose(fp);
3142
3143 // Decipher with MAC address
3144 LLXORCipher cipher(gMACAddress, 6);
3145 cipher.decrypt(buffer, HASHED_LENGTH);
3146
3147 buffer[HASHED_LENGTH] = '\0';
3148
3149 // Check to see if the mac address generated a bad hashed
3150 // password. It should be a hex-string or else the mac adress has
3151 // changed. This is a security feature to make sure that if you
3152 // get someone's password.dat file, you cannot hack their account.
3153 if(is_hex_string(buffer, HASHED_LENGTH))
3154 {
3155 hashed_password.assign((char*)buffer);
3156 }
3157#if LL_DARWIN
3158 // we're migrating to the keychain
3159 LLFile::remove(filepath);
3160#endif
3161
3162 return hashed_password;
3163}
3164
3165
3166// static
3167void LLStartUp::savePasswordToDisk(const std::string& hashed_password)
3168{
3169#if LL_DARWIN
3170 SecKeychainItemRef keychainItem;
3171 OSStatus status = SecKeychainFindGenericPassword(NULL, 10, "Imprudence", 0, NULL, NULL, NULL, &keychainItem);
3172 if (status == noErr)
3173 {
3174 SecKeychainItemModifyAttributesAndData(keychainItem, NULL, hashed_password.length(), hashed_password.c_str());
3175 CFRelease(keychainItem);
3176 }
3177 else
3178 {
3179 SecKeychainAddGenericPassword(NULL, 10, "Imprudence", 0, NULL, hashed_password.length(), hashed_password.c_str(), NULL);
3180 }
3181#else
3182 std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
3183 "password.dat");
3184 LLFILE* fp = LLFile::fopen(filepath, "wb"); /* Flawfinder: ignore */
3185 if (!fp)
3186 {
3187 return;
3188 }
3189
3190 // Encipher with MAC address
3191 const S32 HASHED_LENGTH = 32;
3192 U8 buffer[HASHED_LENGTH+1];
3193
3194 LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1);
3195
3196 LLXORCipher cipher(gMACAddress, 6);
3197 cipher.encrypt(buffer, HASHED_LENGTH);
3198
3199 if (fwrite(buffer, HASHED_LENGTH, 1, fp) != 1)
3200 {
3201 LL_WARNS("AppInit") << "Short write" << LL_ENDL;
3202 }
3203
3204 fclose(fp);
3205#endif
3206}
3207
3208
3209// static
3210void LLStartUp::deletePasswordFromDisk()
3211{
3212#if LL_DARWIN
3213 SecKeychainItemRef keychainItem;
3214 OSStatus status = SecKeychainFindGenericPassword(NULL, 10, "Imprudence", 0, NULL, NULL, NULL, &keychainItem);
3215 if (status == noErr)
3216 {
3217 SecKeychainItemDelete(keychainItem);
3218 CFRelease(keychainItem);
3219 }
3220#endif
3221 std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
3222 "password.dat");
3223 LLFile::remove(filepath);
3224}
3225
3226
3227bool is_hex_string(U8* str, S32 len)
3228{
3229 bool rv = true;
3230 U8* c = str;
3231 while(rv && len--)
3232 {
3233 switch(*c)
3234 {
3235 case '0':
3236 case '1':
3237 case '2':
3238 case '3':
3239 case '4':
3240 case '5':
3241 case '6':
3242 case '7':
3243 case '8':
3244 case '9':
3245 case 'a':
3246 case 'b':
3247 case 'c':
3248 case 'd':
3249 case 'e':
3250 case 'f':
3251 ++c;
3252 break;
3253 default:
3254 rv = false;
3255 break;
3256 }
3257 }
3258 return rv;
3259}
3260
3261void show_first_run_dialog() 3105void show_first_run_dialog()
3262{ 3106{
3263 LLNotifications::instance().add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback); 3107 LLNotifications::instance().add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback);
diff --git a/linden/indra/newview/llstartup.h b/linden/indra/newview/llstartup.h
index 6dc3946..5960817 100644
--- a/linden/indra/newview/llstartup.h
+++ b/linden/indra/newview/llstartup.h
@@ -106,15 +106,6 @@ public:
106 // gender_name is either "male" or "female" 106 // gender_name is either "male" or "female"
107 static void loadInitialOutfit( const std::string& outfit_folder_name, 107 static void loadInitialOutfit( const std::string& outfit_folder_name,
108 const std::string& gender_name ); 108 const std::string& gender_name );
109
110 // Load MD5 of user's password from local disk file.
111 static std::string loadPasswordFromDisk();
112
113 // Record MD5 of user's password for subsequent login.
114 static void savePasswordToDisk(const std::string& hashed_password);
115
116 // Delete the saved password local disk file.
117 static void deletePasswordFromDisk();
118 109
119 static bool dispatchURL(); 110 static bool dispatchURL();
120 // if we have a SLURL or sim string ("Ahern/123/45") that started 111 // if we have a SLURL or sim string ("Ahern/123/45") that started