aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/hippogridmanager.cpp
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-03-11 04:31:18 +1000
committerDavid Walter Seikel2012-03-11 04:31:18 +1000
commitf2715ed85d43b7c7fa4f86e3c3b4118c4cd5ce4d (patch)
tree09b03f9c806b034090c5e9bafa96faeee0f936b0 /linden/indra/newview/hippogridmanager.cpp
parentJust adding a TODO. (diff)
downloadmeta-impy-f2715ed85d43b7c7fa4f86e3c3b4118c4cd5ce4d.zip
meta-impy-f2715ed85d43b7c7fa4f86e3c3b4118c4cd5ce4d.tar.gz
meta-impy-f2715ed85d43b7c7fa4f86e3c3b4118c4cd5ce4d.tar.bz2
meta-impy-f2715ed85d43b7c7fa4f86e3c3b4118c4cd5ce4d.tar.xz
Fix http://redmine.kokuaviewer.org/issues/1126 and as a bonus, now using blowfish to encrypt passwords.
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/hippogridmanager.cpp177
1 files changed, 131 insertions, 46 deletions
diff --git a/linden/indra/newview/hippogridmanager.cpp b/linden/indra/newview/hippogridmanager.cpp
index 1dfb9ac..11b144e 100644
--- a/linden/indra/newview/hippogridmanager.cpp
+++ b/linden/indra/newview/hippogridmanager.cpp
@@ -49,6 +49,7 @@
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#include <boost/algorithm/string.hpp> 55#include <boost/algorithm/string.hpp>
@@ -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),
@@ -423,12 +425,115 @@ void HippoGridInfo::formatFee(std::string &fee, S32 cost, bool showFree) const
423 } 425 }
424} 426}
425 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}
426 528
427void HippoGridInfo::setPassword(const std::string& unhashed_password) 529void HippoGridInfo::setPassword(const std::string& unhashed_password)
428{ 530{
531 int i;
532
429 if (unhashed_password.empty()) 533 if (unhashed_password.empty())
430 { 534 {
431 mPasswordAvatar = ""; 535 mPasswordAvatar = "";
536 mEncryptedPassword = "";
432 return; 537 return;
433 } 538 }
434 539
@@ -454,59 +559,38 @@ void HippoGridInfo::setPassword(const std::string& unhashed_password)
454 hashed_password = munged_password; 559 hashed_password = munged_password;
455 } 560 }
456 561
457 // need to fix the bug in this 562 // Encrypt it for storing in the grids file.
458 /*
459
460 // Encipher with MAC address 563 // Encipher with MAC address
461 const S32 HASHED_LENGTH = 32; 564 char out[HASHED_LENGTH * 2 + 1];
462 U8 buffer[HASHED_LENGTH+1];
463
464 LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1);
465 565
466 LLXORCipher cipher(gMACAddress, 6); 566/* indra/llmessage/llmail.cpp says "blowfish-not-supported-on-windows", but we shall see.
467 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();
468 576
469 mPasswordAvatar.assign((char*)buffer); 577 cipher.encrypt(password, HASHED_LENGTH, encrypted, HASHED_LENGTH);
470 */ 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);
471 mPasswordAvatar.assign(hashed_password); 584 mPasswordAvatar.assign(hashed_password);
472} 585}
473 586
587std::string HippoGridInfo::getEncryptedPassword() const
588{
589 return mEncryptedPassword;
590}
474 591
475std::string HippoGridInfo::getPassword() const 592std::string HippoGridInfo::getPassword() const
476{ 593{
477 // need to fix the bug in this
478 /*
479 if (mPasswordAvatar.empty() || mPasswordAvatar.length() == 32)
480 {
481 return mPasswordAvatar;
482 }
483
484 std::string hashed_password("");
485
486 // UUID is 16 bytes, written into ASCII is 32 characters
487 // without trailing \0
488 const S32 HASHED_LENGTH = 32;
489 U8 buffer[HASHED_LENGTH+1];
490
491 LLStringUtil::copy((char*)buffer, mPasswordAvatar.c_str(), HASHED_LENGTH+1);
492
493 // Decipher with MAC address
494 LLXORCipher cipher(gMACAddress, 6);
495 cipher.decrypt(buffer, HASHED_LENGTH);
496
497 buffer[HASHED_LENGTH] = '\0';
498
499 // Check to see if the mac address generated a bad hashed
500 // password. It should be a hex-string or else the mac adress has
501 // changed. This is a security feature to make sure that if you
502 // get someone's grid_info.xml file, you cannot hack their account.
503 if (is_hex_string(buffer, HASHED_LENGTH))
504 {
505 hashed_password.assign((char*)buffer);
506 }
507
508 return hashed_password;
509 */
510 return mPasswordAvatar; 594 return mPasswordAvatar;
511} 595}
512 596
@@ -909,7 +993,9 @@ void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer)
909 if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]); 993 if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]);
910 if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]); 994 if (gridMap.has("firstname")) grid->setFirstName(gridMap["firstname"]);
911 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.
912 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"]);
913 if (gridMap.has("username")) grid->setUsername(gridMap["username"]); 999 if (gridMap.has("username")) grid->setUsername(gridMap["username"]);
914 if (gridMap.has("username_compat")) grid->setUsernameCompat(gridMap["username_compat"]); 1000 if (gridMap.has("username_compat")) grid->setUsernameCompat(gridMap["username_compat"]);
915 if (newGrid) addGrid(grid); 1001 if (newGrid) addGrid(grid);
@@ -945,8 +1031,7 @@ void HippoGridManager::saveFile()
945 gridInfo[i]["password"] = grid->getPasswordURL(); 1031 gridInfo[i]["password"] = grid->getPasswordURL();
946 gridInfo[i]["firstname"] = grid->getFirstName(); 1032 gridInfo[i]["firstname"] = grid->getFirstName();
947 gridInfo[i]["lastname"] = grid->getLastName(); 1033 gridInfo[i]["lastname"] = grid->getLastName();
948 gridInfo[i]["avatarpassword"] = grid->getPassword(); 1034 gridInfo[i]["encryptedpassword"] = grid->getEncryptedPassword();
949
950 gridInfo[i]["search"] = grid->getSearchURL(); 1035 gridInfo[i]["search"] = grid->getSearchURL();
951 gridInfo[i]["render_compat"] = grid->isRenderCompat(); 1036 gridInfo[i]["render_compat"] = grid->isRenderCompat();
952 1037