Commit 4c899b1e authored by Adrien Béraud's avatar Adrien Béraud Committed by Sébastien Blin

jamiaccount: add manager configuration property

Change-Id: I32136e7381b2f3f73f206a83d573822c6b291291
parent 75b134cf
......@@ -719,7 +719,9 @@
<ClCompile Include="..\src\im\message_engine.cpp" />
<ClCompile Include="..\src\ip_utils.cpp" />
<ClCompile Include="..\src\jamidht\account_manager.cpp" />
<ClCompile Include="..\src\jamidht\archive_account_manager.cpp" />
<ClCompile Include="..\src\jamidht\contact_list.cpp" />
<ClCompile Include="..\src\jamidht\server_account_manager.cpp" />
<ClCompile Include="..\src\logger.cpp" />
<ClCompile Include="..\src\manager.cpp" />
<ClCompile Include="..\src\media\audio\audiobuffer.cpp" />
......@@ -879,8 +881,10 @@
<ClInclude Include="..\src\im\message_engine.h" />
<ClInclude Include="..\src\ip_utils.h" />
<ClInclude Include="..\src\jamidht\account_manager.h" />
<ClInclude Include="..\src\jamidht\archive_account_manager.h" />
<ClInclude Include="..\src\jamidht\contact_list.h" />
<ClInclude Include="..\src\jamidht\jami_contact.h" />
<ClInclude Include="..\src\jamidht\server_account_manager.h" />
<ClInclude Include="..\src\logger.h" />
<ClInclude Include="..\src\manager.h" />
<ClInclude Include="..\src\map_utils.h" />
......
......@@ -427,6 +427,12 @@
<ClCompile Include="..\src\jamidht\contact_list.cpp">
<Filter>Source Files\jamidht</Filter>
</ClCompile>
<ClCompile Include="..\src\jamidht\archive_account_manager.cpp">
<Filter>Source Files\jamidht</Filter>
</ClCompile>
<ClCompile Include="..\src\jamidht\server_account_manager.cpp">
<Filter>Source Files\jamidht</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\account.h">
......@@ -882,6 +888,12 @@
<ClInclude Include="..\src\jamidht\jami_contact.h">
<Filter>Source Files\jamidht</Filter>
</ClInclude>
<ClInclude Include="..\src\jamidht\archive_account_manager.h">
<Filter>Source Files\jamidht</Filter>
</ClInclude>
<ClInclude Include="..\src\jamidht\server_account_manager.h">
<Filter>Source Files\jamidht</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\src\jamidht\eth\libdevcore\Makefile.am">
......
......@@ -145,6 +145,7 @@ constexpr static const char PROXY_PUSH_TOKEN [] = "Account.proxyPushToken
constexpr static const char DHT_PEER_DISCOVERY [] = "Account.peerDiscovery";
constexpr static const char ACCOUNT_PEER_DISCOVERY [] = "Account.accountDiscovery";
constexpr static const char ACCOUNT_PUBLISH [] = "Account.accountPublish";
constexpr static const char MANAGER_URI [] = "Account.managerUri";
namespace Audio {
......
......@@ -23,7 +23,11 @@ libringacc_la_SOURCES = \
contact_list.h \
contact_list.cpp \
account_manager.h \
account_manager.cpp
account_manager.cpp \
archive_account_manager.h \
archive_account_manager.cpp \
server_account_manager.h \
server_account_manager.cpp
if RINGNS
libringacc_la_SOURCES += \
......
This diff is collapsed.
......@@ -50,29 +50,45 @@ struct AccountInfo {
std::string ethAccount;
};
template <typename To, typename From>
std::unique_ptr<To>
dynamic_unique_cast(std::unique_ptr<From>&& p) {
if (auto cast = dynamic_cast<To*>(p.get())) {
std::unique_ptr<To> result(cast);
p.release();
return result;
}
return {};
}
class AccountManager {
public:
using AsyncUser = std::function<void(AccountManager&)>;
using OnAsync = std::function<void(AsyncUser&&)>;
using OnChangeCallback = ContactList::OnChangeCallback;
using OnExportConfig = std::function<std::map<std::string, std::string>()>;
using clock = std::chrono::system_clock;
using time_point = clock::time_point;
AccountManager(
const std::string& path,
OnAsync&& onAsync,
OnExportConfig&& onExportConfig,
std::shared_ptr<dht::DhtRunner> dht)
: path_(path), onAsync_(std::move(onAsync)), onExportConfig_(std::move(onExportConfig)), dht_(std::move(dht)) {};
std::shared_ptr<dht::DhtRunner> dht,
const std::string& nameServer)
: path_(path)
, onAsync_(std::move(onAsync))
, dht_(std::move(dht))
, nameDir_(NameDirectory::instance(nameServer)) {};
virtual ~AccountManager() = default;
constexpr static const char* const DHT_TYPE_NS = "cx.ring";
// Auth
enum class AuthError {
UNKNOWN,
INVALID_ARGUMENTS,
SERVER_ERROR,
NETWORK
};
......@@ -183,101 +199,23 @@ public:
tls::TrustStore::PermissionStatus getCertificateStatus(const std::string& cert_id) const;
bool isAllowed(const crypto::Certificate& crt, bool allowPublic);
static std::shared_ptr<dht::Value> parseAnnounce(const std::string& announceBase64, const std::string& accountId, const std::string& deviceId);
// Name resolver
#if HAVE_RINGNS
using LookupCallback = NameDirectory::LookupCallback;
using RegistrationCallback = NameDirectory::RegistrationCallback;
virtual void lookupName(const std::string& name, LookupCallback cb) = 0;
virtual void lookupAddress(const std::string& address, LookupCallback cb) = 0;
virtual void lookupName(const std::string& name, LookupCallback cb);
virtual void lookupAddress(const std::string& address, LookupCallback cb);
virtual void registerName(const std::string& password, const std::string& name, RegistrationCallback cb) = 0;
#endif
protected:
std::string path_;
OnAsync onAsync_;
OnExportConfig onExportConfig_;
OnChangeCallback onChange_;
std::unique_ptr<AccountInfo> info_;
std::shared_ptr<dht::DhtRunner> dht_;
};
class ArchiveAccountManager : public AccountManager {
public:
ArchiveAccountManager(
const std::string& path,
std::shared_ptr<dht::DhtRunner> dht,
OnAsync&& onAsync,
OnExportConfig&& onExportConfig,
std::string archivePath,
const std::string& nameServer)
: AccountManager(path, std::move(onAsync), std::move(onExportConfig), std::move(dht)), archivePath_(std::move(archivePath)), nameDir_(NameDirectory::instance(nameServer)) {};
struct ArchiveAccountCredentials : AccountCredentials {
std::string archivePath;
in_port_t dhtPort;
std::vector<std::string> dhtBootstrap;
dht::crypto::Identity updateIdentity;
};
void initAuthentication(
CertRequest request,
std::unique_ptr<AccountCredentials> credentials,
AuthSuccessCallback onSuccess,
AuthFailureCallback onFailure,
OnChangeCallback onChange) override;
void startSync() override;
bool changePassword(const std::string& password_old, const std::string& password_new) override;
void syncDevices() override;
void onSyncData(DeviceSync&& device);
bool findCertificate(const dht::InfoHash& h, std::function<void(const std::shared_ptr<dht::crypto::Certificate>&)>&& cb = {}) override;
void addDevice(const std::string& password, AddDeviceCallback) override;
bool revokeDevice(const std::string& password, const std::string& device, RevokeDeviceCallback) override;
bool exportArchive(const std::string& destinationPath, const std::string& password);
#if HAVE_RINGNS
void lookupName(const std::string& name, LookupCallback cb) override;
void lookupAddress(const std::string& address, LookupCallback cb) override;
void registerName(const std::string& password, const std::string& name, RegistrationCallback cb) override;
#endif
private:
struct DhtLoadContext;
struct AuthContext {
CertRequest request;
//std::unique_ptr<dht::crypto::CertificateRequest> request;
std::unique_ptr<ArchiveAccountCredentials> credentials;
std::unique_ptr<DhtLoadContext> dhtContext;
AuthSuccessCallback onSuccess;
AuthFailureCallback onFailure;
};
void createAccount(const std::shared_ptr<AuthContext>& ctx);
std::pair<std::string, std::shared_ptr<dht::Value>> makeReceipt(const dht::crypto::Identity& id, const dht::crypto::Certificate& device, const std::string& ethAccount);
void updateArchive(AccountArchive& content/*, const ContactList& syncData*/) const;
void saveArchive(AccountArchive& content, const std::string& pwd);
AccountArchive readArchive(const std::string& pwd) const;
static std::pair<std::vector<uint8_t>, dht::InfoHash> computeKeys(const std::string& password, const std::string& pin, bool previous=false);
bool updateCertificates(AccountArchive& archive, dht::crypto::Identity& device);
static bool needsMigration(const dht::crypto::Identity& id);
void loadFromFile(const std::shared_ptr<AuthContext>& ctx);
void loadFromDHT(const std::shared_ptr<AuthContext>& ctx);
void onArchiveLoaded(AuthContext& ctx, AccountArchive&& a);
std::string archivePath_;
std::reference_wrapper<NameDirectory> nameDir_;
};
class ServerAccountManager : public AccountManager {
};
}
This diff is collapsed.
/*
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "account_manager.h"
namespace jami {
class ArchiveAccountManager : public AccountManager {
public:
using OnExportConfig = std::function<std::map<std::string, std::string>()>;
ArchiveAccountManager(
const std::string& path,
std::shared_ptr<dht::DhtRunner> dht,
OnAsync&& onAsync,
OnExportConfig&& onExportConfig,
std::string archivePath,
const std::string& nameServer)
: AccountManager(path, std::move(onAsync), std::move(dht), nameServer)
, onExportConfig_(std::move(onExportConfig))
, archivePath_(std::move(archivePath))
{};
struct ArchiveAccountCredentials : AccountCredentials {
std::string archivePath;
in_port_t dhtPort;
std::vector<std::string> dhtBootstrap;
dht::crypto::Identity updateIdentity;
};
void initAuthentication(
CertRequest request,
std::unique_ptr<AccountCredentials> credentials,
AuthSuccessCallback onSuccess,
AuthFailureCallback onFailure,
OnChangeCallback onChange) override;
void startSync() override;
bool changePassword(const std::string& password_old, const std::string& password_new) override;
void syncDevices() override;
void onSyncData(DeviceSync&& device);
bool findCertificate(const dht::InfoHash& h, std::function<void(const std::shared_ptr<dht::crypto::Certificate>&)>&& cb = {}) override;
void addDevice(const std::string& password, AddDeviceCallback) override;
bool revokeDevice(const std::string& password, const std::string& device, RevokeDeviceCallback) override;
bool exportArchive(const std::string& destinationPath, const std::string& password);
#if HAVE_RINGNS
/*void lookupName(const std::string& name, LookupCallback cb) override;
void lookupAddress(const std::string& address, LookupCallback cb) override;*/
void registerName(const std::string& password, const std::string& name, RegistrationCallback cb) override;
#endif
private:
struct DhtLoadContext;
struct AuthContext {
CertRequest request;
//std::unique_ptr<dht::crypto::CertificateRequest> request;
std::unique_ptr<ArchiveAccountCredentials> credentials;
std::unique_ptr<DhtLoadContext> dhtContext;
AuthSuccessCallback onSuccess;
AuthFailureCallback onFailure;
};
void createAccount(const std::shared_ptr<AuthContext>& ctx);
std::pair<std::string, std::shared_ptr<dht::Value>> makeReceipt(const dht::crypto::Identity& id, const dht::crypto::Certificate& device, const std::string& ethAccount);
void updateArchive(AccountArchive& content/*, const ContactList& syncData*/) const;
void saveArchive(AccountArchive& content, const std::string& pwd);
AccountArchive readArchive(const std::string& pwd) const;
static std::pair<std::vector<uint8_t>, dht::InfoHash> computeKeys(const std::string& password, const std::string& pin, bool previous=false);
bool updateCertificates(AccountArchive& archive, dht::crypto::Identity& device);
static bool needsMigration(const dht::crypto::Identity& id);
void loadFromFile(const std::shared_ptr<AuthContext>& ctx);
void loadFromDHT(const std::shared_ptr<AuthContext>& ctx);
void onArchiveLoaded(AuthContext& ctx, AccountArchive&& a);
OnExportConfig onExportConfig_;
std::string archivePath_;
};
}
\ No newline at end of file
......@@ -347,6 +347,28 @@ ContactList::saveKnownDevices() const
msgpack::pack(file, devices);
}
void
ContactList::foundAccountDevice(const dht::InfoHash& device, const std::string& name, const time_point& updated)
{
// insert device
auto it = knownDevices_.emplace(device, KnownDevice{{}, name, updated});
if (it.second) {
JAMI_DBG("[Contacts] Found account device: %s %s", name.c_str(),
device.toString().c_str());
saveKnownDevices();
callbacks_.devicesChanged();
} else {
// update device name
if (not name.empty() and it.first->second.name != name) {
JAMI_DBG("[Contacts] updating device name: %s %s", name.c_str(),
device.toString().c_str());
it.first->second.name = name;
saveKnownDevices();
callbacks_.devicesChanged();
}
}
}
bool
ContactList::foundAccountDevice(const std::shared_ptr<dht::crypto::Certificate>& crt, const std::string& name, const time_point& updated)
{
......@@ -354,8 +376,9 @@ ContactList::foundAccountDevice(const std::shared_ptr<dht::crypto::Certificate>&
return false;
// match certificate chain
if (not accountTrust_.verify(*crt)) {
JAMI_WARN("[Contacts] Found invalid account device: %s", crt->getId().toString().c_str());
auto verifyResult = accountTrust_.verify(*crt);
if (not verifyResult) {
JAMI_WARN("[Contacts] Found invalid account device: %s: %s", crt->getId().toString().c_str(), verifyResult.toString().c_str());
return false;
}
......
......@@ -93,6 +93,7 @@ public:
/* Devices */
const std::map<dht::InfoHash, KnownDevice>& getKnownDevices() const { return knownDevices_; }
void foundAccountDevice(const dht::InfoHash& device, const std::string& name = {}, const time_point& last_sync = time_point::min());
bool foundAccountDevice(const std::shared_ptr<dht::crypto::Certificate>& crt, const std::string& name = {}, const time_point& last_sync = time_point::min());
bool removeAccountDevice(const dht::InfoHash& device);
void setAccountDeviceName(const dht::InfoHash& device, const std::string& name);
......
This diff is collapsed.
......@@ -85,7 +85,6 @@ public:
constexpr static const in_port_t DHT_DEFAULT_PORT = 4222;
constexpr static const char* const DHT_DEFAULT_BOOTSTRAP = "bootstrap.jami.net";
constexpr static const char* const DHT_DEFAULT_PROXY = "dhtproxy.jami.net:[80-100]";
constexpr static const char* const DHT_TYPE_NS = "cx.ring";
/* constexpr */ static const std::pair<uint16_t, uint16_t> DHT_PORT_RANGE;
......@@ -633,6 +632,8 @@ private:
*/
std::string receivedParameter_ {};
std::string managerUri_ {};
/**
* Optional: "rport" parameter from VIA header
*/
......
......@@ -55,7 +55,8 @@ public:
alreadyTaken,
error,
incompleteRequest,
signatureVerificationFailed
signatureVerificationFailed,
unsupported
};
using LookupCallback = std::function<void(const std::string& result, Response response)>;
......
This diff is collapsed.
/*
* Copyright (C) 2014-2019 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "account_manager.h"
namespace jami {
class ServerAccountManager : public AccountManager {
public:
ServerAccountManager(
const std::string& path,
std::shared_ptr<dht::DhtRunner> dht,
OnAsync&& onAsync,
const std::string& managerHostname,
const std::string& nameServer);
struct ServerAccountCredentials : AccountCredentials {
std::string username;
std::shared_ptr<dht::crypto::Certificate> ca;
};
void initAuthentication(
CertRequest request,
std::unique_ptr<AccountCredentials> credentials,
AuthSuccessCallback onSuccess,
AuthFailureCallback onFailure,
OnChangeCallback onChange) override;
bool changePassword(const std::string& password_old, const std::string& password_new) {
return false;
}
void syncDevices();
bool findCertificate(const dht::InfoHash& h, std::function<void(const std::shared_ptr<dht::crypto::Certificate>&)>&& cb = {}) {
return false;
}
/*
void lookupName(const std::string& name, LookupCallback cb) {
}
void lookupAddress(const std::string& address, LookupCallback cb) {
}*/
void registerName(const std::string& password, const std::string& name, RegistrationCallback cb);
private:
struct AuthContext {
CertRequest request;
//std::unique_ptr<dht::crypto::CertificateRequest> request;
std::unique_ptr<ServerAccountCredentials> credentials;
//std::unique_ptr<DhtLoadContext> dhtContext;
AuthSuccessCallback onSuccess;
AuthFailureCallback onFailure;
};
const std::string managerHostname_;
std::shared_ptr<dht::Logger> logger_;
std::map<unsigned int /*id*/, std::shared_ptr<dht::http::Request>> requests_;
std::unique_ptr<ServerAccountCredentials> creds_;
};
}
\ No newline at end of file
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