Files
SingularityViewer/indra/newview/llsavedlogins.cpp
Hazim Gazov 62c1bd007f Revert "some stuff"
This reverts commit 5d993e35c4.
2010-08-01 04:54:14 +00:00

275 lines
7.3 KiB
C++

/**
* @file llsavedlogins.cpp
* @brief Manages a list of previous successful logins
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llsavedlogins.h"
#include "llxorcipher.h"
#include "llsdserialize.h"
//---------------------------------------------------------------------------
// LLSavedLoginEntry methods
//---------------------------------------------------------------------------
LLSavedLoginEntry::LLSavedLoginEntry(const LLSD& entry_data)
{
if (entry_data.isUndefined() || !entry_data.isMap())
{
throw std::invalid_argument("Cannot create a null login entry.");
}
if (!entry_data.has("firstname"))
{
throw std::invalid_argument("Missing firstname key.");
}
if (!entry_data.has("lastname"))
{
throw std::invalid_argument("Missing lastname key.");
}
if (!entry_data.has("grid"))
{
throw std::invalid_argument("Missing grid key.");
}
if (!entry_data.has("password"))
{
throw std::invalid_argument("Missing password key.");
}
if (!entry_data.get("grid").isInteger())
{
throw std::invalid_argument("grid key is not integer.");
}
if (!entry_data.get("firstname").isString())
{
throw std::invalid_argument("firstname key is not string.");
}
if (!entry_data.get("lastname").isString())
{
throw std::invalid_argument("lastname key is not string.");
}
if (!(entry_data.get("password").isUndefined() || entry_data.get("password").isBinary()))
{
throw std::invalid_argument("password key is neither blank nor binary.");
}
mEntry = entry_data;
}
LLSavedLoginEntry::LLSavedLoginEntry(const EGridInfo grid,
const std::string& firstname,
const std::string& lastname,
const std::string& password)
{
mEntry.clear();
mEntry.insert("grid", LLSD(grid));
mEntry.insert("firstname", LLSD(firstname));
mEntry.insert("lastname", LLSD(lastname));
setPassword(password);
}
const std::string LLSavedLoginEntry::getGridName() const
{
std::string gridname = "";
if (mEntry.has("griduri") && mEntry.get("griduri").isURI())
{
gridname = mEntry.get("griduri").asURI().hostName();
LLStringUtil::toLower(gridname);
}
else if (mEntry.has("grid"))
{
LLViewerLogin* login_data = LLViewerLogin::getInstance();
gridname = login_data->getKnownGridLabel(static_cast<EGridInfo>(mEntry.get("grid").asInteger()));
}
return gridname;
}
LLSD LLSavedLoginEntry::asLLSD() const
{
return mEntry;
}
const std::string LLSavedLoginEntry::getDisplayString() const
{
std::ostringstream etitle;
etitle << getFirstName() << " " << getLastName() << " (" << getGridName() << ")";
return etitle.str();
}
const std::string LLSavedLoginEntry::getPassword() const
{
return (mEntry.has("password") ? decryptPassword(mEntry.get("password")) : std::string());
}
void LLSavedLoginEntry::setPassword(const std::string& value)
{
mEntry.insert("password", encryptPassword(value));
}
const std::string LLSavedLoginEntry::decryptPassword(const LLSD& pwdata)
{
std::string pw = "";
if (pwdata.isBinary() && pwdata.asBinary().size() == PASSWORD_HASH_LENGTH+1)
{
LLSD::Binary buffer = pwdata.asBinary();
LLXORCipher cipher(gMACAddress, 6);
cipher.decrypt(&buffer[0], PASSWORD_HASH_LENGTH);
buffer[PASSWORD_HASH_LENGTH] = '\0';
if (LLStringOps::isHexString(std::string(reinterpret_cast<const char*>(&buffer[0]), PASSWORD_HASH_LENGTH)))
{
pw.assign(reinterpret_cast<char*>(&buffer[0]));
}
}
return pw;
}
const LLSD LLSavedLoginEntry::encryptPassword(const std::string& password)
{
LLSD pwdata;
if (password.size() == PASSWORD_HASH_LENGTH && LLStringOps::isHexString(password))
{
LLSD::Binary buffer(PASSWORD_HASH_LENGTH+1);
LLStringUtil::copy(reinterpret_cast<char*>(&buffer[0]), password.c_str(), PASSWORD_HASH_LENGTH+1);
buffer[PASSWORD_HASH_LENGTH] = '\0';
LLXORCipher cipher(gMACAddress, 6);
cipher.encrypt(&buffer[0], PASSWORD_HASH_LENGTH);
pwdata.assign(buffer);
}
return pwdata;
}
//---------------------------------------------------------------------------
// LLSavedLogins methods
//---------------------------------------------------------------------------
LLSavedLogins::LLSavedLogins()
{
}
LLSavedLogins::LLSavedLogins(const LLSD& history_data)
{
if (!history_data.isArray()) throw std::invalid_argument("Invalid history data.");
for (LLSD::array_const_iterator i = history_data.beginArray();
i != history_data.endArray(); ++i)
{
// Put the last used grids first.
if (!i->isUndefined()) mEntries.push_front(LLSavedLoginEntry(*i));
}
}
LLSD LLSavedLogins::asLLSD() const
{
LLSD output;
for (LLSavedLoginsList::const_iterator i = mEntries.begin();
i != mEntries.end(); ++i)
{
output.insert(0, i->asLLSD());
}
return output;
}
void LLSavedLogins::addEntry(const LLSavedLoginEntry& entry)
{
mEntries.push_back(entry);
}
void LLSavedLogins::deleteEntry(const EGridInfo grid,
const std::string& firstname,
const std::string& lastname,
const std::string& griduri)
{
for (LLSavedLoginsList::iterator i = mEntries.begin();
i != mEntries.end();)
{
if (i->getFirstName() == firstname &&
i->getGrid() == grid &&
i->getLastName() == lastname &&
(grid != GRID_INFO_OTHER || i->getGridURI().asString() == griduri))
{
i = mEntries.erase(i);
}
else
{
++i;
}
}
}
LLSavedLogins LLSavedLogins::loadFile(const std::string& filepath)
{
LLSavedLogins hist;
LLSD data;
llifstream file(filepath);
if (file.is_open())
{
llinfos << "Loading login history file at " << filepath << llendl;
LLSDSerialize::fromXML(data, file);
}
if (data.isUndefined())
{
llinfos << "Login History File \"" << filepath << "\" is missing, "
"ill-formed, or simply undefined; not loading the file." << llendl;
}
else
{
try
{
hist = LLSavedLogins(data);
}
catch(std::invalid_argument& error)
{
llwarns << "Login History File \"" << filepath << "\" is ill-formed (" <<
error.what() << "); not loading the file." << llendl;
}
}
return hist;
}
bool LLSavedLogins::saveFile(const LLSavedLogins& history, const std::string& filepath)
{
llofstream out(filepath);
if (!out.good())
{
llwarns << "Unable to open \"" << filepath << "\" for output." << llendl;
return false;
}
LLSDSerialize::toPrettyXML(history.asLLSD(), out);
out.close();
return true;
}