diff options
author | David Walter Seikel | 2014-02-03 15:23:22 +1000 |
---|---|---|
committer | David Walter Seikel | 2014-02-03 15:23:22 +1000 |
commit | d056a17f05a1f90708f554651475e116a2ddbd68 (patch) | |
tree | 07fa4f1cca2a25548b8d2d6b4752b07d8efbd2ff /linden/indra/newview/hippogridmanager.cpp | |
parent | Updating tree and volume LOD. These go to eleven. (diff) | |
parent | Fix up OTR prefs to not crash. (diff) | |
download | meta-impy-next.zip meta-impy-next.tar.gz meta-impy-next.tar.bz2 meta-impy-next.tar.xz |
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/hippogridmanager.cpp | 198 |
1 files changed, 151 insertions, 47 deletions
diff --git a/linden/indra/newview/hippogridmanager.cpp b/linden/indra/newview/hippogridmanager.cpp index 4c46d3e..11b144e 100644 --- a/linden/indra/newview/hippogridmanager.cpp +++ b/linden/indra/newview/hippogridmanager.cpp | |||
@@ -49,9 +49,10 @@ | |||
49 | #include "llviewernetwork.h" // gMacAddress | 49 | #include "llviewernetwork.h" // gMacAddress |
50 | #include "llweb.h" | 50 | #include "llweb.h" |
51 | #include "llxorcipher.h" // saved password, MAC address | 51 | #include "llxorcipher.h" // saved password, MAC address |
52 | #include "llblowfishcipher.h" | ||
52 | 53 | ||
53 | #include "hipporestrequest.h" | 54 | #include "hipporestrequest.h" |
54 | 55 | #include <boost/algorithm/string.hpp> | |
55 | 56 | ||
56 | // ******************************************************************** | 57 | // ******************************************************************** |
57 | // Global Variables | 58 | // Global Variables |
@@ -87,6 +88,7 @@ HippoGridInfo::HippoGridInfo(const std::string& gridNick) : | |||
87 | mFirstName(LLStringUtil::null), | 88 | mFirstName(LLStringUtil::null), |
88 | mLastName(LLStringUtil::null), | 89 | mLastName(LLStringUtil::null), |
89 | mPasswordAvatar(LLStringUtil::null), | 90 | mPasswordAvatar(LLStringUtil::null), |
91 | mEncryptedPassword(LLStringUtil::null), | ||
90 | mXmlState(XML_VOID), | 92 | mXmlState(XML_VOID), |
91 | mVoiceConnector("SLVoice"), | 93 | mVoiceConnector("SLVoice"), |
92 | mRenderCompat(false), | 94 | mRenderCompat(false), |
@@ -101,9 +103,27 @@ HippoGridInfo::HippoGridInfo(const std::string& gridNick) : | |||
101 | mGridNick = sanitizeGridNick(nick); | 103 | mGridNick = sanitizeGridNick(nick); |
102 | } | 104 | } |
103 | 105 | ||
106 | // Check if this really is a SecondLife grid, to prevent cheating. | ||
107 | void HippoGridInfo::checkLoginURIforSecondLifeness() | ||
108 | { | ||
109 | LLURI loginURI(mLoginURI); | ||
110 | std::string host = loginURI.hostName(); | ||
111 | size_t found; | ||
112 | |||
113 | boost::algorithm::to_lower(host); | ||
114 | |||
115 | found = host.rfind("lindenlab.com"); | ||
116 | if ((found + 13) == host.size()) | ||
117 | mPlatform = PLATFORM_SECONDLIFE; | ||
118 | found = host.rfind("secondlife.com"); | ||
119 | if ((found + 14) == host.size()) | ||
120 | mPlatform = PLATFORM_SECONDLIFE; | ||
121 | } | ||
122 | |||
104 | void HippoGridInfo::setPlatform(Platform platform) | 123 | void HippoGridInfo::setPlatform(Platform platform) |
105 | { | 124 | { |
106 | mPlatform = platform; | 125 | mPlatform = platform; |
126 | checkLoginURIforSecondLifeness(); | ||
107 | if (mPlatform == PLATFORM_SECONDLIFE) | 127 | if (mPlatform == PLATFORM_SECONDLIFE) |
108 | { | 128 | { |
109 | mCurrencySymbol = "L$"; | 129 | mCurrencySymbol = "L$"; |
@@ -136,6 +156,7 @@ void HippoGridInfo::setLoginURI(const std::string& loginURI) | |||
136 | { | 156 | { |
137 | std::string uri = loginURI; | 157 | std::string uri = loginURI; |
138 | mLoginURI = sanitizeURI(uri); | 158 | mLoginURI = sanitizeURI(uri); |
159 | checkLoginURIforSecondLifeness(); | ||
139 | } | 160 | } |
140 | 161 | ||
141 | void HippoGridInfo::setHelperURI(const std::string& helperURI) | 162 | void HippoGridInfo::setHelperURI(const std::string& helperURI) |
@@ -404,12 +425,115 @@ void HippoGridInfo::formatFee(std::string &fee, S32 cost, bool showFree) const | |||
404 | } | 425 | } |
405 | } | 426 | } |
406 | 427 | ||
428 | const S32 HASHED_LENGTH = 32; | ||
429 | |||
430 | void HippoGridInfo::setEncryptedPassword(const std::string& encrypted_password) | ||
431 | { | ||
432 | int i; | ||
433 | LLBlowfishCipher cipher(gMACAddress, 6); | ||
434 | size_t encrypted_size = cipher.requiredEncryptionSpace(HASHED_LENGTH); | ||
435 | |||
436 | if (encrypted_password.empty()) | ||
437 | { | ||
438 | // Check if we have a password hash to encrypt. | ||
439 | if (mPasswordAvatar.empty()) | ||
440 | mEncryptedPassword = ""; | ||
441 | else | ||
442 | { | ||
443 | // In theory, this is used to convert old style Imprudence 1.4 beta 2 and earlier passwords. | ||
444 | // Encipher with MAC address | ||
445 | char out[HASHED_LENGTH * 2 + 1]; | ||
446 | |||
447 | /* indra/llmessage/llmail.cpp says "blowfish-not-supported-on-windows", but we shall see. | ||
448 | #if LL_WINDOWS | ||
449 | LLXORCipher cipherX(gMACAddress, 6); | ||
450 | cipherX.encrypt(mPasswordAvatar.c_str(), HASHED_LENGTH); | ||
451 | #else | ||
452 | */ | ||
453 | U8* encrypted = new U8[encrypted_size]; | ||
454 | U8* password = (U8 *) mPasswordAvatar.c_str(); | ||
455 | |||
456 | cipher.encrypt(password, HASHED_LENGTH, encrypted, HASHED_LENGTH); | ||
457 | for (i = 0; i < HASHED_LENGTH; i++) | ||
458 | { | ||
459 | sprintf(out + i * 2, "%02x", encrypted[i]); | ||
460 | } | ||
461 | out[HASHED_LENGTH * 2]='\0'; | ||
462 | mEncryptedPassword.assign(out); | ||
463 | } | ||
464 | |||
465 | return; | ||
466 | } | ||
467 | |||
468 | if (encrypted_password == mEncryptedPassword) | ||
469 | { | ||
470 | return; | ||
471 | } | ||
472 | |||
473 | // Max "actual" password length is 16 characters. | ||
474 | // Hex digests are always 32 characters. | ||
475 | // Encrypted passwords stored as hex digits are 64 characters. | ||
476 | if (encrypted_password.length() == (HASHED_LENGTH * 2)) | ||
477 | { | ||
478 | // This is actually encrypted, as found in the grids file. | ||
479 | mEncryptedPassword.assign(encrypted_password); | ||
480 | } | ||
481 | else | ||
482 | { | ||
483 | // Should never happen, this is only called from the file reading bit. | ||
484 | llwarns << "Encrypted password corrupted." << llendl; | ||
485 | return; | ||
486 | } | ||
487 | |||
488 | std::string hashed_password(""); | ||
489 | |||
490 | // Decrypt it for the password hash. | ||
491 | // Decipher with MAC address | ||
492 | U8 buffer[HASHED_LENGTH + 1]; | ||
493 | char in[HASHED_LENGTH * 2 + 1]; | ||
494 | |||
495 | LLStringUtil::copy(in, mEncryptedPassword.c_str(), HASHED_LENGTH * 2 + 1); | ||
496 | /* indra/llmessage/llmail.cpp says "blowfish-not-supported-on-windows", but we shall see. | ||
497 | #if LL_WINDOWS | ||
498 | for (i = 0; i < HASHED_LENGTH; i++) | ||
499 | { | ||
500 | sscanf(in + i * 2, "%2hhx", &buffer[i]); | ||
501 | } | ||
502 | // Note that an XOR "cipher" is a lousy one when the secret is repeated several times like it is here. | ||
503 | LLXORCipher cipher(gMACAddress, 6); | ||
504 | cipher.decrypt(buffer, HASHED_LENGTH); | ||
505 | #else | ||
506 | */ | ||
507 | U8* encrypted = new U8[encrypted_size]; | ||
508 | for (i = 0; i < HASHED_LENGTH; i++) | ||
509 | { | ||
510 | sscanf(in + i * 2, "%2hhx", &encrypted[i]); | ||
511 | } | ||
512 | // Not sure why, but this prints a warning saying it failed, even though it works. Which does not matter that much, we don't use the return value anyway. | ||
513 | cipher.decrypt(encrypted, HASHED_LENGTH, buffer, HASHED_LENGTH); | ||
514 | buffer[HASHED_LENGTH] = '\0'; | ||
515 | |||
516 | // Check to see if the mac address generated a bad hashed | ||
517 | // password. It should be a hex-string or else the mac adress has | ||
518 | // changed. This is a security feature to make sure that if you | ||
519 | // get someone's grid_info.xml file, you cannot hack their account. | ||
520 | // This is a lousy way to check. | ||
521 | if (is_hex_string(buffer, HASHED_LENGTH)) | ||
522 | { | ||
523 | hashed_password.assign((char*)buffer); | ||
524 | } | ||
525 | |||
526 | mPasswordAvatar.assign(hashed_password); | ||
527 | } | ||
407 | 528 | ||
408 | void HippoGridInfo::setPassword(const std::string& unhashed_password) | 529 | void HippoGridInfo::setPassword(const std::string& unhashed_password) |
409 | { | 530 | { |
531 | int i; | ||
532 | |||
410 | if (unhashed_password.empty()) | 533 | if (unhashed_password.empty()) |
411 | { | 534 | { |
412 | mPasswordAvatar = ""; | 535 | mPasswordAvatar = ""; |
536 | mEncryptedPassword = ""; | ||
413 | return; | 537 | return; |
414 | } | 538 | } |
415 | 539 | ||
@@ -435,59 +559,38 @@ void HippoGridInfo::setPassword(const std::string& unhashed_password) | |||
435 | hashed_password = munged_password; | 559 | hashed_password = munged_password; |
436 | } | 560 | } |
437 | 561 | ||
438 | // need to fix the bug in this | 562 | // Encrypt it for storing in the grids file. |
439 | /* | ||
440 | |||
441 | // Encipher with MAC address | 563 | // Encipher with MAC address |
442 | const S32 HASHED_LENGTH = 32; | 564 | char out[HASHED_LENGTH * 2 + 1]; |
443 | U8 buffer[HASHED_LENGTH+1]; | ||
444 | |||
445 | LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1); | ||
446 | 565 | ||
447 | LLXORCipher cipher(gMACAddress, 6); | 566 | /* indra/llmessage/llmail.cpp says "blowfish-not-supported-on-windows", but we shall see. |
448 | cipher.encrypt(buffer, HASHED_LENGTH); | 567 | #if LL_WINDOWS |
568 | LLXORCipher cipherX(gMACAddress, 6); | ||
569 | cipherX.encrypt(hashed_password.c_str(), HASHED_LENGTH); | ||
570 | #else | ||
571 | */ | ||
572 | LLBlowfishCipher cipher(gMACAddress, 6); | ||
573 | size_t encrypted_size = cipher.requiredEncryptionSpace(HASHED_LENGTH); | ||
574 | U8* encrypted = new U8[encrypted_size]; | ||
575 | U8* password = (U8 *) hashed_password.c_str(); | ||
449 | 576 | ||
450 | mPasswordAvatar.assign((char*)buffer); | 577 | cipher.encrypt(password, HASHED_LENGTH, encrypted, HASHED_LENGTH); |
451 | */ | 578 | for (i = 0; i < HASHED_LENGTH; i++) |
579 | { | ||
580 | sprintf(out + i * 2, "%02x", encrypted[i]); | ||
581 | } | ||
582 | out[HASHED_LENGTH * 2]='\0'; | ||
583 | mEncryptedPassword.assign(out); | ||
452 | mPasswordAvatar.assign(hashed_password); | 584 | mPasswordAvatar.assign(hashed_password); |
453 | } | 585 | } |
454 | 586 | ||
587 | std::string HippoGridInfo::getEncryptedPassword() const | ||
588 | { | ||
589 | return mEncryptedPassword; | ||
590 | } | ||
455 | 591 | ||
456 | std::string HippoGridInfo::getPassword() const | 592 | std::string HippoGridInfo::getPassword() const |
457 | { | 593 | { |
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; | 594 | return mPasswordAvatar; |
492 | } | 595 | } |
493 | 596 | ||
@@ -890,7 +993,9 @@ void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer) | |||
890 | if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]); | 993 | if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]); |
891 | if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]); | 994 | if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]); |
892 | if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]); | 995 | if (gridMap.has("lastname")) grid->setLastName(gridMap["lastname"]); |
996 | // Reading this one coz there are some old files in the wild that have it, but not encryptedpassword. | ||
893 | if (gridMap.has("avatarpassword")) grid->setPassword(gridMap["avatarpassword"]); | 997 | if (gridMap.has("avatarpassword")) grid->setPassword(gridMap["avatarpassword"]); |
998 | if (gridMap.has("encryptedpassword")) grid->setEncryptedPassword(gridMap["encryptedpassword"]); | ||
894 | if (gridMap.has("username")) grid->setUsername(gridMap["username"]); | 999 | if (gridMap.has("username")) grid->setUsername(gridMap["username"]); |
895 | if (gridMap.has("username_compat")) grid->setUsernameCompat(gridMap["username_compat"]); | 1000 | if (gridMap.has("username_compat")) grid->setUsernameCompat(gridMap["username_compat"]); |
896 | if (newGrid) addGrid(grid); | 1001 | if (newGrid) addGrid(grid); |
@@ -926,8 +1031,7 @@ void HippoGridManager::saveFile() | |||
926 | gridInfo[i]["password"] = grid->getPasswordURL(); | 1031 | gridInfo[i]["password"] = grid->getPasswordURL(); |
927 | gridInfo[i]["firstname"] = grid->getFirstName(); | 1032 | gridInfo[i]["firstname"] = grid->getFirstName(); |
928 | gridInfo[i]["lastname"] = grid->getLastName(); | 1033 | gridInfo[i]["lastname"] = grid->getLastName(); |
929 | gridInfo[i]["avatarpassword"] = grid->getPassword(); | 1034 | gridInfo[i]["encryptedpassword"] = grid->getEncryptedPassword(); |
930 | |||
931 | gridInfo[i]["search"] = grid->getSearchURL(); | 1035 | gridInfo[i]["search"] = grid->getSearchURL(); |
932 | gridInfo[i]["render_compat"] = grid->isRenderCompat(); | 1036 | gridInfo[i]["render_compat"] = grid->isRenderCompat(); |
933 | 1037 | ||