aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/hippogridmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/hippogridmanager.cpp')
-rw-r--r--linden/indra/newview/hippogridmanager.cpp198
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.
107void 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
104void HippoGridInfo::setPlatform(Platform platform) 123void 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
141void HippoGridInfo::setHelperURI(const std::string& helperURI) 162void 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
428const S32 HASHED_LENGTH = 32;
429
430void 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
408void HippoGridInfo::setPassword(const std::string& unhashed_password) 529void 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
587std::string HippoGridInfo::getEncryptedPassword() const
588{
589 return mEncryptedPassword;
590}
455 591
456std::string HippoGridInfo::getPassword() const 592std::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