This source file includes following definitions.
- ParseSignons
- ReadAndParseSignons
#include "chrome/utility/importer/nss_decryptor.h"
#include <string>
#include <vector>
#include "base/base64.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/common/password_form.h"
#include "sql/connection.h"
#include "sql/statement.h"
#if defined(USE_NSS)
#include <pk11pub.h>
#include <pk11sdr.h>
#endif
base::string16 NSSDecryptor::Decrypt(const std::string& crypt) const {
if (!is_nss_initialized_)
return base::string16();
std::string plain;
if (crypt[0] != '~') {
std::string decoded_data;
base::Base64Decode(crypt, &decoded_data);
PK11SlotInfo* slot = GetKeySlotForDB();
SECStatus result = PK11_Authenticate(slot, PR_TRUE, NULL);
if (result != SECSuccess) {
FreeSlot(slot);
return base::string16();
}
SECItem request;
request.data = reinterpret_cast<unsigned char*>(
const_cast<char*>(decoded_data.data()));
request.len = static_cast<unsigned int>(decoded_data.size());
SECItem reply;
reply.data = NULL;
reply.len = 0;
#if defined(USE_NSS)
result = PK11SDR_DecryptWithSlot(slot, &request, &reply, NULL);
#else
result = PK11SDR_Decrypt(&request, &reply, NULL);
#endif
if (result == SECSuccess)
plain.assign(reinterpret_cast<char*>(reply.data), reply.len);
SECITEM_FreeItem(&reply, PR_FALSE);
FreeSlot(slot);
} else {
base::Base64Decode(crypt.substr(1), &plain);
}
return base::UTF8ToUTF16(plain);
}
void NSSDecryptor::ParseSignons(
const std::string& content,
std::vector<autofill::PasswordForm>* forms) {
forms->clear();
std::vector<std::string> lines;
base::SplitString(content, '\n', &lines);
if (lines.empty())
return;
int version;
if (lines[0] == "#2c")
version = 1;
else if (lines[0] == "#2d")
version = 2;
else if (lines[0] == "#2e")
version = 3;
else
return;
GURL::Replacements rep;
rep.ClearQuery();
rep.ClearRef();
rep.ClearUsername();
rep.ClearPassword();
size_t i;
for (i = 1; i < lines.size() && lines[i].compare(".") != 0; ++i) {
autofill::PasswordForm form;
form.origin = GURL(lines[i]).ReplaceComponents(rep);
form.signon_realm = form.origin.GetOrigin().spec();
form.blacklisted_by_user = true;
forms->push_back(form);
}
++i;
while (i < lines.size()) {
size_t begin = i;
size_t end = i + 1;
while (end < lines.size() && lines[end].compare(".") != 0)
++end;
i = end + 1;
if (end - begin < 5)
continue;
autofill::PasswordForm form;
GURL url;
std::string realm;
const char kRealmBracketBegin[] = " (";
const char kRealmBracketEnd[] = ")";
if (lines[begin].find(kRealmBracketBegin) != std::string::npos) {
if (lines[begin].find("://") == std::string::npos)
lines[begin] = "http://" + lines[begin];
size_t start = lines[begin].find(kRealmBracketBegin);
url = GURL(lines[begin].substr(0, start));
start += std::string(kRealmBracketBegin).size();
size_t end = lines[begin].rfind(kRealmBracketEnd);
realm = lines[begin].substr(start, end - start);
} else {
url = GURL(lines[begin]);
}
if (!url.is_valid())
continue;
form.origin = url.ReplaceComponents(rep);
form.signon_realm = form.origin.GetOrigin().spec();
if (!realm.empty())
form.signon_realm += realm;
form.ssl_valid = form.origin.SchemeIsSecure();
++begin;
while (begin + 4 < end) {
form.username_element = base::UTF8ToUTF16(lines[begin++]);
form.username_value = Decrypt(lines[begin++]);
if (lines[begin].at(0) == '*') {
form.password_element = base::UTF8ToUTF16(lines[begin++].substr(1));
form.password_value = Decrypt(lines[begin++]);
} else {
break;
}
if (version >= 2) {
if (begin < end)
form.action = GURL(lines[begin]).ReplaceComponents(rep);
++begin;
}
if (version == 3) {
++begin;
}
forms->push_back(form);
}
}
}
bool NSSDecryptor::ReadAndParseSignons(const base::FilePath& sqlite_file,
std::vector<autofill::PasswordForm>* forms) {
sql::Connection db;
if (!db.Open(sqlite_file))
return false;
const char* query = "SELECT hostname FROM moz_disabledHosts";
sql::Statement s(db.GetUniqueStatement(query));
if (!s.is_valid())
return false;
GURL::Replacements rep;
rep.ClearQuery();
rep.ClearRef();
rep.ClearUsername();
rep.ClearPassword();
while (s.Step()) {
autofill::PasswordForm form;
form.origin = GURL(s.ColumnString(0)).ReplaceComponents(rep);
form.signon_realm = form.origin.GetOrigin().spec();
form.blacklisted_by_user = true;
forms->push_back(form);
}
const char* query2 = "SELECT hostname, httpRealm, formSubmitURL, "
"usernameField, passwordField, encryptedUsername, "
"encryptedPassword FROM moz_logins";
sql::Statement s2(db.GetUniqueStatement(query2));
if (!s2.is_valid())
return false;
while (s2.Step()) {
GURL url;
std::string realm(s2.ColumnString(1));
if (!realm.empty()) {
std::string host(s2.ColumnString(0));
if (host.find("://") == std::string::npos)
host = "http://" + host;
url = GURL(host);
} else {
url = GURL(s2.ColumnString(0));
}
if (!url.is_valid())
continue;
autofill::PasswordForm form;
form.origin = url.ReplaceComponents(rep);
form.signon_realm = form.origin.GetOrigin().spec();
if (!realm.empty())
form.signon_realm += realm;
form.ssl_valid = form.origin.SchemeIsSecure();
form.username_element = s2.ColumnString16(3);
form.username_value = Decrypt(s2.ColumnString(5));
form.password_element = s2.ColumnString16(4);
form.password_value = Decrypt(s2.ColumnString(6));
form.action = GURL(s2.ColumnString(2)).ReplaceComponents(rep);
forms->push_back(form);
}
return true;
}