diff options
author | McCabe Maxsted | 2011-04-19 14:49:18 -0700 |
---|---|---|
committer | McCabe Maxsted | 2011-04-19 14:49:18 -0700 |
commit | a0902a050cc713f742990a09d2a610d4c135b7c7 (patch) | |
tree | c4a2c89cd48d6e50908959deed5318c6cd4fbaf5 /linden/indra | |
parent | Fixed usernames default setting to '.' when logging into second life for the ... (diff) | |
download | meta-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.cpp | 34 | ||||
-rw-r--r-- | linden/indra/llcommon/llstring.h | 2 | ||||
-rw-r--r-- | linden/indra/newview/app_settings/settings.xml | 33 | ||||
-rw-r--r-- | linden/indra/newview/floatergridmanager.cpp | 63 | ||||
-rw-r--r-- | linden/indra/newview/floatergridmanager.h | 8 | ||||
-rw-r--r-- | linden/indra/newview/hippogridmanager.cpp | 96 | ||||
-rw-r--r-- | linden/indra/newview/hippogridmanager.h | 6 | ||||
-rw-r--r-- | linden/indra/newview/llagent.cpp | 3 | ||||
-rw-r--r-- | linden/indra/newview/llappviewer.cpp | 20 | ||||
-rw-r--r-- | linden/indra/newview/llfloaterchat.cpp | 3 | ||||
-rw-r--r-- | linden/indra/newview/llloginhandler.cpp | 20 | ||||
-rw-r--r-- | linden/indra/newview/llpanellogin.cpp | 56 | ||||
-rw-r--r-- | linden/indra/newview/llpanellogin.h | 5 | ||||
-rw-r--r-- | linden/indra/newview/llprefsim.cpp | 4 | ||||
-rw-r--r-- | linden/indra/newview/llstartup.cpp | 242 | ||||
-rw-r--r-- | linden/indra/newview/llstartup.h | 9 |
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 | ||
599 | bool 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 |
601 | namespace snprintf_hack | 635 | namespace 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 | ||
457 | LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); | 457 | LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); |
458 | 458 | ||
459 | LL_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 | ||
49 | const std::string PASSWORD_FILLER = "123456789!123456"; | 49 | const std::string PASSWORD_FILLER = "123456789!123456"; |
50 | //bool FloaterGridManager::sIsInitialLogin; | ||
51 | 50 | ||
52 | FloaterGridManager::FloaterGridManager(const LLSD& key) | 51 | FloaterGridManager::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 | |||
701 | std::string& FloaterGridManager::getPassword() | ||
702 | { | ||
703 | return mMungedPassword; | ||
704 | } | ||
705 | |||
706 | void FloaterGridManager::setPassword(std::string &password) | ||
707 | { | ||
708 | mMungedPassword = password; | ||
709 | } | ||
710 | |||
711 | bool FloaterGridManager::isSamePassword(std::string &password) | ||
712 | { | ||
713 | return mMungedPassword == password; | ||
714 | } | ||
715 | |||
716 | void 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 | ||
67 | private: | 60 | private: |
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 | ||
408 | void 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 | |||
456 | std::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 | ||
476 | BOOL LLFloaterChat::isOwnNameInText(const std::string &text_line) | 477 | BOOL 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 | ||
92 | const S32 BLACK_BORDER_HEIGHT = 160; | 92 | const S32 BLACK_BORDER_HEIGHT = 160; |
93 | const S32 MAX_PASSWORD = 16; | 93 | const S32 MAX_PASSWORD = 16; |
94 | const std::string PASSWORD_FILLER = "123456789!123456"; | ||
94 | 95 | ||
95 | LLPanelLogin *LLPanelLogin::sInstance = NULL; | 96 | LLPanelLogin *LLPanelLogin::sInstance = NULL; |
96 | BOOL LLPanelLogin::sCapslockDidNotification = FALSE; | 97 | BOOL 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 | ||
358 | void 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 | |||
374 | LLPanelLogin::~LLPanelLogin() | 360 | LLPanelLogin::~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 |
597 | void LLPanelLogin::setPassword(const std::string& password) | 583 | void 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 | ||
1212 | void 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 | ||
263 | void login_show(); | 262 | void login_show(); |
264 | void login_callback(S32 option, void* userdata); | 263 | void login_callback(S32 option, void* userdata); |
265 | bool is_hex_string(U8* str, S32 len); | ||
266 | void show_first_run_dialog(); | 264 | void show_first_run_dialog(); |
267 | bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); | 265 | bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); |
268 | void set_startup_status(const F32 frac, const std::string& string, const std::string& msg); | 266 | void 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 | ||
3088 | std::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 | ||
3167 | void 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 | ||
3210 | void 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 | |||
3227 | bool 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 | |||
3261 | void show_first_run_dialog() | 3105 | void 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 |