Commit ad63b452 authored by Adrien Béraud's avatar Adrien Béraud

ringaccount: improve loading logic

* setup trust store when creating device
* fix createAccount, migrateAccount to use loaded id
  since identity_ is not set anymore
* useIdentity: loadIdentity will now fail when migration is needed,
  adapt logic. Recursively call loadIdentity when migration has ended.

Change-Id: Ie4f993fdd13fac894679b96a20fc5eacff5817c3
Tuleap: #1457
parent a6e3ed73
...@@ -750,6 +750,8 @@ RingAccount::createRingDevice(const dht::crypto::Identity& id) ...@@ -750,6 +750,8 @@ RingAccount::createRingDevice(const dht::crypto::Identity& id)
std::tie(tlsPrivateKeyFile_, tlsCertificateFile_) = saveIdentity(dev_id, idPath_, "ring_device"); std::tie(tlsPrivateKeyFile_, tlsCertificateFile_) = saveIdentity(dev_id, idPath_, "ring_device");
tlsPassword_ = {}; tlsPassword_ = {};
identity_ = dev_id; identity_ = dev_id;
accountTrust_ = tls::TrustStore{};
accountTrust_.setCertificateStatus(id.second, tls::TrustStore::PermissionStatus::ALLOWED, false);
ringDeviceId_ = dev_id.first->getPublicKey().getId().toString(); ringDeviceId_ = dev_id.first->getPublicKey().getId().toString();
ringDeviceName_ = ip_utils::getHostname(); ringDeviceName_ = ip_utils::getHostname();
if (ringDeviceName_.empty()) if (ringDeviceName_.empty())
...@@ -1300,12 +1302,12 @@ RingAccount::loadAccountFromDHT(const std::string& archive_password, const std:: ...@@ -1300,12 +1302,12 @@ RingAccount::loadAccountFromDHT(const std::string& archive_password, const std::
} }
void void
RingAccount::createAccount(const std::string& archive_password) RingAccount::createAccount(const std::string& archive_password, dht::crypto::Identity&& migrate)
{ {
RING_WARN("Creating new Ring account"); RING_WARN("Creating new Ring account");
setRegistrationState(RegistrationState::INITIALIZING); setRegistrationState(RegistrationState::INITIALIZING);
auto sthis = std::static_pointer_cast<RingAccount>(shared_from_this()); auto sthis = std::static_pointer_cast<RingAccount>(shared_from_this());
ThreadPool::instance().run([sthis,archive_password](){ ThreadPool::instance().run([sthis,archive_password,migrate]() mutable {
ArchiveContent a; ArchiveContent a;
auto& this_ = *sthis; auto& this_ = *sthis;
...@@ -1313,13 +1315,13 @@ RingAccount::createAccount(const std::string& archive_password) ...@@ -1313,13 +1315,13 @@ RingAccount::createAccount(const std::string& archive_password)
auto future_keypair = ThreadPool::instance().get<dev::KeyPair>(std::bind(&dev::KeyPair::create)); auto future_keypair = ThreadPool::instance().get<dev::KeyPair>(std::bind(&dev::KeyPair::create));
try { try {
if (this_.identity_.first and this_.identity_.second) { if (migrate.first and migrate.second) {
RING_WARN("Converting certificate from old ring account"); RING_WARN("Converting certificate from old ring account");
a.id = std::move(this_.identity_); a.id = std::move(migrate);
try { try {
a.ca_key = std::make_shared<dht::crypto::PrivateKey>(fileutils::loadFile("ca.key", this_.idPath_)); a.ca_key = std::make_shared<dht::crypto::PrivateKey>(fileutils::loadFile("ca.key", this_.idPath_));
} catch (...) {} } catch (...) {}
updateCertificates(a, this_.identity_); updateCertificates(a, migrate);
} else { } else {
auto ca = dht::crypto::generateIdentity("Ring CA"); auto ca = dht::crypto::generateIdentity("Ring CA");
if (!ca.first || !ca.second) { if (!ca.first || !ca.second) {
...@@ -1414,7 +1416,7 @@ RingAccount::updateCertificates(ArchiveContent& archive, dht::crypto::Identity& ...@@ -1414,7 +1416,7 @@ RingAccount::updateCertificates(ArchiveContent& archive, dht::crypto::Identity&
} }
void void
RingAccount::migrateAccount(const std::string& pwd) RingAccount::migrateAccount(const std::string& pwd, dht::crypto::Identity& device)
{ {
ArchiveContent archive; ArchiveContent archive;
try { try {
...@@ -1424,8 +1426,8 @@ RingAccount::migrateAccount(const std::string& pwd) ...@@ -1424,8 +1426,8 @@ RingAccount::migrateAccount(const std::string& pwd)
return; return;
} }
if (updateCertificates(archive, identity_)) { if (updateCertificates(archive, device)) {
std::tie(tlsPrivateKeyFile_, tlsCertificateFile_) = saveIdentity(identity_, idPath_, "ring_device"); std::tie(tlsPrivateKeyFile_, tlsCertificateFile_) = saveIdentity(device, idPath_, "ring_device");
saveArchive(archive, pwd); saveArchive(archive, pwd);
setRegistrationState(RegistrationState::UNREGISTERED); setRegistrationState(RegistrationState::UNREGISTERED);
Migration::setState(accountID_, Migration::State::SUCCESS); Migration::setState(accountID_, Migration::State::SUCCESS);
...@@ -1442,32 +1444,23 @@ RingAccount::loadAccount(const std::string& archive_password, const std::string& ...@@ -1442,32 +1444,23 @@ RingAccount::loadAccount(const std::string& archive_password, const std::string&
RING_DBG("[Account %s] loading Ring account", getAccountID().c_str()); RING_DBG("[Account %s] loading Ring account", getAccountID().c_str());
try { try {
auto id = loadIdentity(tlsCertificateFile_, tlsPrivateKeyFile_, tlsPassword_); auto id = loadIdentity(tlsCertificateFile_, tlsPrivateKeyFile_, tlsPassword_);
bool hasValidId = useIdentity(id); bool hasArchive = not archivePath_.empty()
bool needMigration = hasValidId and needsMigration(id); and fileutils::isFile(fileutils::getFullPath(idPath_, archivePath_));
bool hasArchive = not archivePath_.empty() \ if (useIdentity(id)) {
and fileutils::isFile(fileutils::getFullPath(idPath_, archivePath_)); // normal loading path
if (hasValidId) {
loadKnownDevices(); loadKnownDevices();
loadContacts(); loadContacts();
loadTrustRequests(); loadTrustRequests();
if (not needMigration) { if (not hasArchive)
if (not hasArchive) RING_WARN("[Account %s] account archive not found, won't be able to add new devices", getAccountID().c_str());
RING_WARN("[Account %s] account archive not found, won't be able to add new devices", getAccountID().c_str()); } else if (hasArchive) {
// normal account loading path
return;
} else
RING_WARN("[Account %s] account certificates need to be updated", getAccountID().c_str());
}
if (hasArchive) {
if (archive_password.empty()) { if (archive_password.empty()) {
RING_WARN("[Account %s] password needed to read archive", getAccountID().c_str()); RING_WARN("[Account %s] password needed to read archive", getAccountID().c_str());
setRegistrationState(RegistrationState::ERROR_NEED_MIGRATION); setRegistrationState(RegistrationState::ERROR_NEED_MIGRATION);
} else { } else {
if (needMigration) { if (needsMigration(id)) {
RING_WARN("[Account %s] account certificate needs update", getAccountID().c_str()); RING_WARN("[Account %s] account certificate needs update", getAccountID().c_str());
migrateAccount(archive_password); migrateAccount(archive_password, id);
} else { } else {
RING_WARN("[Account %s] archive present but no valid receipt: creating new device", getAccountID().c_str()); RING_WARN("[Account %s] archive present but no valid receipt: creating new device", getAccountID().c_str());
try { try {
...@@ -1477,21 +1470,23 @@ RingAccount::loadAccount(const std::string& archive_password, const std::string& ...@@ -1477,21 +1470,23 @@ RingAccount::loadAccount(const std::string& archive_password, const std::string&
return; return;
} }
Migration::setState(accountID_, Migration::State::SUCCESS); Migration::setState(accountID_, Migration::State::SUCCESS);
setRegistrationState(RegistrationState::UNREGISTERED);
} }
Manager::instance().saveConfig(); Manager::instance().saveConfig();
loadAccount();
} }
} else { } else {
// no receipt or archive, creating new account // no receipt or archive, creating new account
if (archive_password.empty()) { if (archive_password.empty()) {
RING_WARN("[Account %s] password needed to create archive", getAccountID().c_str()); RING_WARN("[Account %s] password needed to create archive", getAccountID().c_str());
if (identity_.first) { if (id.first) {
ringAccountId_ = identity_.first->getPublicKey().getId().toString(); ringAccountId_ = id.first->getPublicKey().getId().toString();
username_ = RING_URI_PREFIX+ringAccountId_; username_ = RING_URI_PREFIX+ringAccountId_;
} }
setRegistrationState(RegistrationState::ERROR_NEED_MIGRATION); setRegistrationState(RegistrationState::ERROR_NEED_MIGRATION);
} else { } else {
if (archive_pin.empty()) { if (archive_pin.empty()) {
createAccount(archive_password); createAccount(archive_password, std::move(id));
} else { } else {
loadAccountFromDHT(archive_password, archive_pin); loadAccountFromDHT(archive_password, archive_pin);
} }
...@@ -2356,7 +2351,9 @@ RingAccount::foundAccountDevice(const std::shared_ptr<dht::crypto::Certificate>& ...@@ -2356,7 +2351,9 @@ RingAccount::foundAccountDevice(const std::shared_ptr<dht::crypto::Certificate>&
// insert device // insert device
auto it = knownDevices_.emplace(crt->getId(), KnownDevice{crt, name, updated}); auto it = knownDevices_.emplace(crt->getId(), KnownDevice{crt, name, updated});
if (it.second) { if (it.second) {
RING_WARN("[Account %s] Found known account device: %s", getAccountID().c_str(), crt->getId().toString().c_str()); RING_WARN("[Account %s] Found account device: %s %s", getAccountID().c_str(),
name.c_str(),
crt->getId().toString().c_str());
tls::CertificateStore::instance().pinCertificate(crt); tls::CertificateStore::instance().pinCertificate(crt);
saveKnownDevices(); saveKnownDevices();
emitSignal<DRing::ConfigurationSignal::KnownDevicesChanged>(getAccountID(), getKnownDevices()); emitSignal<DRing::ConfigurationSignal::KnownDevicesChanged>(getAccountID(), getKnownDevices());
......
...@@ -496,10 +496,10 @@ class RingAccount : public SIPAccountBase { ...@@ -496,10 +496,10 @@ class RingAccount : public SIPAccountBase {
std::string makeReceipt(const dht::crypto::Identity& id); std::string makeReceipt(const dht::crypto::Identity& id);
void createRingDevice(const dht::crypto::Identity& id); void createRingDevice(const dht::crypto::Identity& id);
void initRingDevice(const ArchiveContent& a); void initRingDevice(const ArchiveContent& a);
void migrateAccount(const std::string& pwd); void migrateAccount(const std::string& pwd, dht::crypto::Identity& device);
static bool updateCertificates(ArchiveContent& archive, dht::crypto::Identity& device); static bool updateCertificates(ArchiveContent& archive, dht::crypto::Identity& device);
void createAccount(const std::string& archive_password); void createAccount(const std::string& archive_password, dht::crypto::Identity&& migrate);
std::vector<uint8_t> makeArchive(const ArchiveContent& content) const; std::vector<uint8_t> makeArchive(const ArchiveContent& content) const;
void saveArchive(const ArchiveContent& content, const std::string& pwd); void saveArchive(const ArchiveContent& content, const std::string& pwd);
ArchiveContent readArchive(const std::string& pwd) const; ArchiveContent readArchive(const std::string& pwd) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment