diff --git a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
index e7f7aa897..44b10fab9 100644
--- a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
+++ b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
@@ -21,7 +21,7 @@
Get all parameters of the specified account.
-
+
The account ID
@@ -75,7 +75,7 @@
-
+
The account ID
@@ -99,7 +99,7 @@
Account settings are written to the configuration file when ring properly quits.
After calling this method, the core will emit the signal accountDetailsChanged with the updated data. The client must subscribe to this signal and use it to update its internal data structure.
-
+
@@ -111,7 +111,7 @@
Set if this account is currently enabled (can be used).
It is only a runtime proprety with no impact on the "enabled" state of the account.
-
+
The account ID
@@ -124,7 +124,7 @@
-
+
@@ -132,7 +132,7 @@
-
+
@@ -162,7 +162,7 @@
Export account on the DHT using the given password and generated PIN (returned through exportOnRingEnded signal).
-
+
@@ -174,14 +174,24 @@
-
+
Copy the account archive to the path provided in argument.
-
+
+
+
+ The password scheme. Accepted values:
+
+ - (empty string): no encryption.
+ - password: plain-text password string.
+ - key: base64-encoded binary key.
+
+
+
@@ -195,7 +205,7 @@
Notify clients when the exportOnRing operation ended.
-
+
@@ -215,15 +225,18 @@
+
Revoke device attached to the given Ring account, and publish the new revocation list.
-
-
-
+
+
+
+
+
True if the operation was performed successfully.
@@ -234,7 +247,7 @@
Notify clients when the revokeDevice operation ended.
-
+
@@ -254,7 +267,7 @@
Notify clients when a newly created account's profile is available for storage.
-
+
@@ -266,7 +279,7 @@
Notify clients when a new device linked to this account is found.
-
+
@@ -280,7 +293,7 @@
Gets list of known devices for this account.
-
+
@@ -294,7 +307,7 @@
Change the account archive password.
-
+
@@ -311,11 +324,11 @@
Performs name lookup for the specified account (if any) or using the default nameserver.
-
+
The account to use. If empty, use the default nameserver.
- The name server URI to use, considered only if accountID is empty.
+ The name server URI to use, considered only if accountId is empty.
@@ -329,11 +342,11 @@
Performs address lookup for the specified account (if any) or using the default nameserver.
-
+
The account to use. If empty, use the default nameserver.
- The name server URI to use, considered only if accountID is empty.
+ The name server URI to use, considered only if accountId is empty.
@@ -352,7 +365,7 @@
Notify clients when a new registered address-name mapping is known.
If status is not success (0), requested field (name or address) is left empty.
-
+
@@ -375,18 +388,17 @@
Performs name registration with RingNS protocol for the specified account.
-
-
-
-
- Ring account main password.
-
+
Name to register. Must be lower-case ASCII, digits or "-" or "_".
+
+
+
+
True if the operation was initialized successfully. nameRegistrationEnded will be trigered on completion.
@@ -398,7 +410,7 @@
Notify clients when the registerName operation ended.
-
+
@@ -423,7 +435,7 @@
Performs name registration with RingNS protocol for the specified account.
-
+
@@ -440,7 +452,7 @@
Notify clients when the registerName operation ended.
-
+
@@ -503,7 +515,7 @@
Send account registration (REGISTER) to the registrar.
Register the account if enable=true, unregister if enable=false.
-
+
The account ID
@@ -517,7 +529,7 @@
-
+
@@ -536,7 +548,7 @@
-
+
@@ -546,7 +558,7 @@
-
+
@@ -554,7 +566,7 @@
-
+
@@ -583,7 +595,7 @@
Notify clients that a new text message has been received at the account level.
-
+
@@ -595,7 +607,7 @@
Notify clients that a sent text message status have changed
-
+
@@ -629,7 +641,7 @@
Notify clients that a vCard has been received
-
+
@@ -881,7 +893,7 @@
-
+
@@ -890,7 +902,7 @@
-
+
@@ -899,7 +911,7 @@
-
+
@@ -907,7 +919,7 @@
-
+
@@ -1082,7 +1094,7 @@
-
+
The account ID
@@ -1096,7 +1108,7 @@
-
+
@@ -1111,7 +1123,7 @@
-
+
The account ID
@@ -1152,7 +1164,7 @@
Returns a list of supported encryption ciphers used to encrypt SIP messages. The list depends on the TLS library being used.
Only registered SIP accounts currently support setting custom ciphers. This method returns an empty list if TLS support is disabled in either pjproject or Jami.
-
+
A SIP account id, other account IDs will be rejected.
@@ -1448,7 +1460,7 @@
-
+
@@ -1463,7 +1475,7 @@
-
+
@@ -1476,7 +1488,7 @@
-
+
@@ -1492,7 +1504,7 @@
Notify clients that a new contact request has been received.
-
+
@@ -1506,7 +1518,7 @@
-
+
@@ -1516,7 +1528,7 @@
-
+
@@ -1524,7 +1536,7 @@
-
+
@@ -1538,7 +1550,7 @@
-
+
@@ -1552,7 +1564,7 @@
-
+
@@ -1567,7 +1579,7 @@
Notify clients that a new contact has been added.
-
+
@@ -1580,7 +1592,7 @@
Notify clients that a new contact has been removed.
-
+
@@ -1917,7 +1929,7 @@
Notify clients that a media parameter changed.
-
+
An account id.
@@ -1939,7 +1951,7 @@
Notify clients when migration is ended.
-
+
An account id.
@@ -2382,14 +2394,14 @@
-
+
-
+
@@ -2397,23 +2409,23 @@
-
+
-
+
-
+
-
+
diff --git a/bin/dbus/dbusconfigurationmanager.hpp b/bin/dbus/dbusconfigurationmanager.hpp
index 638d08fad..da0e343d3 100644
--- a/bin/dbus/dbusconfigurationmanager.hpp
+++ b/bin/dbus/dbusconfigurationmanager.hpp
@@ -99,19 +99,21 @@ public:
auto
exportToFile(const std::string& accountID,
const std::string& destinationPath,
+ const std::string& scheme,
const std::string& password)
- -> decltype(libjami::exportToFile(accountID, destinationPath, password))
+ -> decltype(libjami::exportToFile(accountID, destinationPath, scheme, password))
{
- return libjami::exportToFile(accountID, destinationPath, password);
+ return libjami::exportToFile(accountID, destinationPath, scheme, password);
}
auto
revokeDevice(const std::string& accountID,
- const std::string& password,
- const std::string& device)
- -> decltype(libjami::revokeDevice(accountID, password, device))
+ const std::string& device,
+ const std::string& scheme,
+ const std::string& password)
+ -> decltype(libjami::revokeDevice(accountID, device, scheme, password))
{
- return libjami::revokeDevice(accountID, password, device);
+ return libjami::revokeDevice(accountID, device, scheme, password);
}
auto
@@ -150,11 +152,12 @@ public:
auto
registerName(const std::string& account,
- const std::string& password,
- const std::string& name)
- -> decltype(libjami::registerName(account, password, name))
+ const std::string& name,
+ const std::string& scheme,
+ const std::string& password)
+ -> decltype(libjami::registerName(account, name, scheme, password))
{
- return libjami::registerName(account, password, name);
+ return libjami::registerName(account, name, scheme, password);
}
auto
diff --git a/bin/jni/configurationmanager.i b/bin/jni/configurationmanager.i
index 4f5477546..06a396c29 100644
--- a/bin/jni/configurationmanager.i
+++ b/bin/jni/configurationmanager.i
@@ -84,48 +84,48 @@ struct Message
uint64_t received;
};
-std::map getAccountDetails(const std::string& accountID);
-std::map getVolatileAccountDetails(const std::string& accountID);
-void setAccountDetails(const std::string& accountID, const std::map& details);
-void setAccountActive(const std::string& accountID, bool active);
+std::map getAccountDetails(const std::string& accountId);
+std::map getVolatileAccountDetails(const std::string& accountId);
+void setAccountDetails(const std::string& accountId, const std::map& details);
+void setAccountActive(const std::string& accountId, bool active);
std::map getAccountTemplate(const std::string& accountType);
void monitor(bool continuous);
std::vector> getConnectionList(const std::string& accountId, const std::string& conversationId);
std::vector> getChannelList(const std::string& accountId, const std::string& connectionId);
std::string addAccount(const std::map& details);
-void removeAccount(const std::string& accountID);
+void removeAccount(const std::string& accountId);
std::vector getAccountList();
-void sendRegister(const std::string& accountID, bool enable);
+void sendRegister(const std::string& accountId, bool enable);
void registerAllAccounts(void);
-uint64_t sendAccountTextMessage(const std::string& accountID, const std::string& to, const std::map& message, const int32_t& flag);
-std::vector getLastMessages(const std::string& accountID, uint64_t base_timestamp);
+uint64_t sendAccountTextMessage(const std::string& accountId, const std::string& to, const std::map& message, const int32_t& flag);
+std::vector getLastMessages(const std::string& accountId, uint64_t base_timestamp);
int getMessageStatus(uint64_t id);
-int getMessageStatus(const std::string& accountID, uint64_t id);
-bool cancelMessage(const std::string& accountID, uint64_t id);
-void setIsComposing(const std::string& accountID, const std::string& conversationUri, bool isWriting);
-bool setMessageDisplayed(const std::string& accountID, const std::string& conversationUri, const std::string& messageId, int status);
-bool changeAccountPassword(const std::string& accountID, const std::string& password_old, const std::string& password_new);
+int getMessageStatus(const std::string& accountId, uint64_t id);
+bool cancelMessage(const std::string& accountId, uint64_t id);
+void setIsComposing(const std::string& accountId, const std::string& conversationUri, bool isWriting);
+bool setMessageDisplayed(const std::string& accountId, const std::string& conversationUri, const std::string& messageId, int status);
+bool changeAccountPassword(const std::string& accountId, const std::string& password_old, const std::string& password_new);
bool isPasswordValid(const std::string& accountId, const std::string& password);
std::vector getPasswordKey(const std::string& accountId, const std::string& password);
bool lookupName(const std::string& account, const std::string& nameserver, const std::string& name);
bool lookupAddress(const std::string& account, const std::string& nameserver, const std::string& address);
-bool registerName(const std::string& account, const std::string& password, const std::string& name);
+bool registerName(const std::string& account, const std::string& name, const std::string& scheme, const std::string& password);
bool searchUser(const std::string& account, const std::string& query);
std::vector getCodecList();
std::vector getSupportedTlsMethod();
-std::vector getSupportedCiphers(const std::string& accountID);
-std::map getCodecDetails(const std::string& accountID, const unsigned& codecId);
-bool setCodecDetails(const std::string& accountID, const unsigned& codecId, const std::map& details);
-std::vector getActiveCodecList(const std::string& accountID);
-bool exportOnRing(const std::string& accountID, const std::string& password);
-bool exportToFile(const std::string& accountID, const std::string& destinationPath, const std::string& password);
+std::vector getSupportedCiphers(const std::string& accountId);
+std::map getCodecDetails(const std::string& accountId, const unsigned& codecId);
+bool setCodecDetails(const std::string& accountId, const unsigned& codecId, const std::map& details);
+std::vector getActiveCodecList(const std::string& accountId);
+bool exportOnRing(const std::string& accountId, const std::string& password);
+bool exportToFile(const std::string& accountId, const std::string& destinationPath, const std::string& scheme, const std::string& password);
-std::map getKnownRingDevices(const std::string& accountID);
-bool revokeDevice(const std::string& accountID, const std::string& password, const std::string& deviceID);
+std::map getKnownRingDevices(const std::string& accountId);
+bool revokeDevice(const std::string& accountId, const std::string& deviceId, const std::string& scheme, const std::string& password);
-void setActiveCodecList(const std::string& accountID, const std::vector& list);
+void setActiveCodecList(const std::string& accountId, const std::vector& list);
std::vector> getActiveCalls(const std::string& accountId, const std::string& convId);
std::vector getAudioPluginList();
@@ -175,8 +175,8 @@ int32_t getRingingTimeout();
void setAccountsOrder(const std::string& order);
-std::vector > getCredentials(const std::string& accountID);
-void setCredentials(const std::string& accountID, const std::vector >& details);
+std::vector > getCredentials(const std::string& accountId);
+void setCredentials(const std::string& accountId, const std::vector >& details);
std::string getAddrFromInterfaceName(const std::string& interface);
@@ -235,12 +235,12 @@ void pushNotificationReceived(const std::string& from, const std::map getDefaultModerators(const std::string& accountID);
-void enableLocalModerators(const std::string& accountID, bool isModEnabled);
-bool isLocalModeratorsEnabled(const std::string& accountID);
-void setAllModerators(const std::string& accountID, bool allModerators);
-bool isAllModerators(const std::string& accountID);
+void setDefaultModerator(const std::string& accountId, const std::string& peerURI, bool state);
+std::vector getDefaultModerators(const std::string& accountId);
+void enableLocalModerators(const std::string& accountId, bool isModEnabled);
+bool isLocalModeratorsEnabled(const std::string& accountId);
+void setAllModerators(const std::string& accountId, bool allModerators);
+bool isAllModerators(const std::string& accountId);
}
diff --git a/configure.ac b/configure.ac
index 5c7467037..cdea5ff1c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ dnl Jami - configure.ac
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
-AC_INIT([Jami Daemon],[14.0.0],[jami@gnu.org],[jami])
+AC_INIT([Jami Daemon],[15.0.0],[jami@gnu.org],[jami])
dnl Clear the implicit flags that default to '-g -O2', otherwise they
dnl take precedence over the values we set via the
diff --git a/src/client/configurationmanager.cpp b/src/client/configurationmanager.cpp
index aac0c13ce..38d48e957 100644
--- a/src/client/configurationmanager.cpp
+++ b/src/client/configurationmanager.cpp
@@ -345,20 +345,21 @@ exportOnRing(const std::string& accountId, const std::string& password)
bool
exportToFile(const std::string& accountId,
- const std::string& destinationPath,
- const std::string& password)
+ const std::string& destinationPath,
+ const std::string& scheme,
+ const std::string& password)
{
if (const auto account = jami::Manager::instance().getAccount(accountId)) {
- return account->exportArchive(destinationPath, password);
+ return account->exportArchive(destinationPath, scheme, password);
}
return false;
}
bool
-revokeDevice(const std::string& accountId, const std::string& password, const std::string& deviceID)
+revokeDevice(const std::string& accountId, const std::string& deviceId, const std::string& scheme, const std::string& password)
{
if (const auto account = jami::Manager::instance().getAccount(accountId)) {
- return account->revokeDevice(password, deviceID);
+ return account->revokeDevice(deviceId, scheme, password);
}
return false;
}
@@ -1046,11 +1047,11 @@ searchUser(const std::string& account, const std::string& query)
}
bool
-registerName(const std::string& account, const std::string& password, const std::string& name)
+registerName(const std::string& account, const std::string& name, const std::string& scheme, const std::string& password)
{
#if HAVE_RINGNS
if (auto acc = jami::Manager::instance().getAccount(account)) {
- acc->registerName(password, name);
+ acc->registerName(name, scheme, password);
return true;
}
#endif
diff --git a/src/fileutils.cpp b/src/fileutils.cpp
index 0bd77baab..8f9fb4b88 100644
--- a/src/fileutils.cpp
+++ b/src/fileutils.cpp
@@ -22,6 +22,8 @@
#include "fileutils.h"
#include "archiver.h"
#include "compiler_intrinsics.h"
+#include "base64.h"
+
#include
#ifdef __APPLE__
@@ -302,10 +304,10 @@ loadCacheTextFile(const std::filesystem::path& path, std::chrono::system_clock::
return loadTextFile(path);
}
-std::vector
-readArchive(const std::filesystem::path& path, const std::string& pwd)
+ArchiveStorageData
+readArchive(const std::filesystem::path& path, std::string_view scheme, const std::string& pwd)
{
- JAMI_LOG("Reading archive from {}", path);
+ JAMI_LOG("Reading archive from {} with scheme '{}'", path, scheme);
auto isUnencryptedGzip = [](const std::vector& data) {
// NOTE: some webserver modify gzip files and this can end with a gunzip in a gunzip
@@ -325,45 +327,69 @@ readArchive(const std::filesystem::path& path, const std::string& pwd)
}
};
- std::vector data;
+ ArchiveStorageData ret;
+
// Read file
try {
- data = dhtnet::fileutils::loadFile(path);
+ ret.data = dhtnet::fileutils::loadFile(path);
} catch (const std::exception& e) {
JAMI_ERR("Error loading archive: %s", e.what());
throw e;
}
- if (isUnencryptedGzip(data)) {
+ if (isUnencryptedGzip(ret.data)) {
if (!pwd.empty())
JAMI_WARNING("A gunzip in a gunzip is detected. A webserver may have a bad config");
- decompress(data);
+ decompress(ret.data);
}
if (!pwd.empty()) {
// Decrypt
- try {
- data = dht::crypto::aesDecrypt(data, pwd);
- } catch (const std::exception& e) {
- JAMI_ERROR("Error decrypting archive: {}", e.what());
- throw e;
+ if (scheme == ARCHIVE_AUTH_SCHEME_KEY) {
+ try {
+ ret.salt = dht::crypto::aesGetSalt(ret.data);
+ ret.data = dht::crypto::aesDecrypt(dht::crypto::aesGetEncrypted(ret.data), base64::decode(pwd));
+ } catch (const std::exception& e) {
+ JAMI_ERROR("Error decrypting archive: {}", e.what());
+ throw e;
+ }
+ } else if (scheme == ARCHIVE_AUTH_SCHEME_PASSWORD) {
+ try {
+ ret.salt = dht::crypto::aesGetSalt(ret.data);
+ ret.data = dht::crypto::aesDecrypt(ret.data, pwd);
+ } catch (const std::exception& e) {
+ JAMI_ERROR("Error decrypting archive: {}", e.what());
+ throw e;
+ }
}
- decompress(data);
- } else if (isUnencryptedGzip(data)) {
+ decompress(ret.data);
+ } else if (isUnencryptedGzip(ret.data)) {
JAMI_WARNING("A gunzip in a gunzip is detected. A webserver may have a bad config");
- decompress(data);
+ decompress(ret.data);
}
- return data;
+ return ret;
}
void
writeArchive(const std::string& archive_str,
const std::filesystem::path& path,
- const std::string& password)
+ std::string_view scheme,
+ const std::string& password,
+ const std::vector& password_salt)
{
JAMI_LOG("Writing archive to {}", path);
- if (not password.empty()) {
+ if (scheme == ARCHIVE_AUTH_SCHEME_KEY) {
+ // Encrypt using provided key
+ try {
+ auto key = base64::decode(password);
+ auto newArchive = dht::crypto::aesEncrypt(archiver::compress(archive_str), key);
+ saveFile(path, dht::crypto::aesBuildEncrypted(newArchive, password_salt));
+ } catch (const std::runtime_error& ex) {
+ JAMI_ERROR("Export failed: {}", ex.what());
+ return;
+ }
+ } else if (scheme == ARCHIVE_AUTH_SCHEME_PASSWORD and not password.empty()) {
// Encrypt using provided password
try {
saveFile(path, dht::crypto::aesEncrypt(archiver::compress(archive_str), password));
diff --git a/src/fileutils.h b/src/fileutils.h
index a9b7c3877..56ad8e1c2 100644
--- a/src/fileutils.h
+++ b/src/fileutils.h
@@ -17,6 +17,8 @@
#pragma once
#include "jami/def.h"
+#include
+
#include
#include
#include
@@ -24,8 +26,7 @@
#include
#include
#include
-
-#include
+#include
#ifndef _WIN32
#include // mode_t
@@ -42,6 +43,8 @@
namespace jami {
namespace fileutils {
+using namespace std::literals;
+
std::filesystem::path get_home_dir();
std::filesystem::path get_config_dir(const char* pkg);
std::filesystem::path get_data_dir(const char* pkg);
@@ -100,10 +103,20 @@ std::vector loadCacheFile(const std::filesystem::path& path,
std::chrono::system_clock::duration maxAge);
std::string loadCacheTextFile(const std::filesystem::path& path, std::chrono::system_clock::duration maxAge);
-std::vector readArchive(const std::filesystem::path& path, const std::string& password = {});
+static constexpr auto ARCHIVE_AUTH_SCHEME_NONE = ""sv;
+static constexpr auto ARCHIVE_AUTH_SCHEME_PASSWORD = "password"sv;
+static constexpr auto ARCHIVE_AUTH_SCHEME_KEY = "key"sv;
+
+struct ArchiveStorageData {
+ std::vector data;
+ std::vector salt;
+};
+ArchiveStorageData readArchive(const std::filesystem::path& path, std::string_view scheme, const std::string& pwd);
+
void writeArchive(const std::string& data,
const std::filesystem::path& path,
- const std::string& password = {});
+ std::string_view scheme,
+ const std::string& password = {}, const std::vector& password_salt = {});
int64_t size(const std::filesystem::path& path);
diff --git a/src/jami/account_const.h b/src/jami/account_const.h
index 7b530d60c..066abe5a9 100644
--- a/src/jami/account_const.h
+++ b/src/jami/account_const.h
@@ -132,6 +132,7 @@ constexpr static const char HAS_CUSTOM_USER_AGENT[] = "Account.hasCustomUserAgen
constexpr static const char ALLOW_CERT_FROM_HISTORY[] = "Account.allowCertFromHistory";
constexpr static const char ALLOW_CERT_FROM_CONTACT[] = "Account.allowCertFromContact";
constexpr static const char ALLOW_CERT_FROM_TRUSTED[] = "Account.allowCertFromTrusted";
+constexpr static const char ARCHIVE_PASSWORD_SCHEME[] = "Account.archivePasswordScheme";
constexpr static const char ARCHIVE_PASSWORD[] = "Account.archivePassword";
constexpr static const char ARCHIVE_HAS_PASSWORD[] = "Account.archiveHasPassword";
constexpr static const char ARCHIVE_PATH[] = "Account.archivePath";
diff --git a/src/jami/configurationmanager_interface.h b/src/jami/configurationmanager_interface.h
index 4fa74f576..0efd20144 100644
--- a/src/jami/configurationmanager_interface.h
+++ b/src/jami/configurationmanager_interface.h
@@ -53,36 +53,38 @@ struct LIBJAMI_PUBLIC Message
uint64_t received;
};
-LIBJAMI_PUBLIC std::map getAccountDetails(const std::string& accountID);
+LIBJAMI_PUBLIC std::map getAccountDetails(const std::string& accountId);
LIBJAMI_PUBLIC std::map getVolatileAccountDetails(
- const std::string& accountID);
-LIBJAMI_PUBLIC void setAccountDetails(const std::string& accountID,
+ const std::string& accountId);
+LIBJAMI_PUBLIC void setAccountDetails(const std::string& accountId,
const std::map& details);
-LIBJAMI_PUBLIC void setAccountActive(const std::string& accountID,
+LIBJAMI_PUBLIC void setAccountActive(const std::string& accountId,
bool active,
bool shutdownConnections = false);
LIBJAMI_PUBLIC std::map getAccountTemplate(const std::string& accountType);
LIBJAMI_PUBLIC std::string addAccount(const std::map& details,
- const std::string& accountID = {});
+ const std::string& accountId = {});
LIBJAMI_PUBLIC void monitor(bool continuous);
LIBJAMI_PUBLIC std::vector> getConnectionList(
const std::string& accountId, const std::string& conversationId);
LIBJAMI_PUBLIC std::vector> getChannelList(
const std::string& accountId, const std::string& connectionId);
-LIBJAMI_PUBLIC bool exportOnRing(const std::string& accountID, const std::string& password);
-LIBJAMI_PUBLIC bool exportToFile(const std::string& accountID,
+LIBJAMI_PUBLIC bool exportOnRing(const std::string& accountId, const std::string& password);
+LIBJAMI_PUBLIC bool exportToFile(const std::string& accountId,
const std::string& destinationPath,
+ const std::string& scheme = {},
const std::string& password = {});
-LIBJAMI_PUBLIC bool revokeDevice(const std::string& accountID,
- const std::string& password,
- const std::string& deviceID);
-LIBJAMI_PUBLIC std::map getKnownRingDevices(const std::string& accountID);
-LIBJAMI_PUBLIC bool changeAccountPassword(const std::string& accountID,
+LIBJAMI_PUBLIC bool revokeDevice(const std::string& accountId,
+ const std::string& deviceId,
+ const std::string& scheme = {},
+ const std::string& password = {});
+LIBJAMI_PUBLIC std::map getKnownRingDevices(const std::string& accountId);
+LIBJAMI_PUBLIC bool changeAccountPassword(const std::string& accountId,
const std::string& password_old,
const std::string& password_new);
-LIBJAMI_PUBLIC bool isPasswordValid(const std::string& accountID, const std::string& password);
-LIBJAMI_PUBLIC std::vector getPasswordKey(const std::string& accountID, const std::string& password);
+LIBJAMI_PUBLIC bool isPasswordValid(const std::string& accountId, const std::string& password);
+LIBJAMI_PUBLIC std::vector getPasswordKey(const std::string& accountId, const std::string& password);
LIBJAMI_PUBLIC bool lookupName(const std::string& account,
const std::string& nameserver,
@@ -91,43 +93,44 @@ LIBJAMI_PUBLIC bool lookupAddress(const std::string& account,
const std::string& nameserver,
const std::string& address);
LIBJAMI_PUBLIC bool registerName(const std::string& account,
- const std::string& password,
- const std::string& name);
+ const std::string& name,
+ const std::string& scheme = {},
+ const std::string& password = {});
LIBJAMI_PUBLIC bool searchUser(const std::string& account, const std::string& query);
-LIBJAMI_PUBLIC void removeAccount(const std::string& accountID);
+LIBJAMI_PUBLIC void removeAccount(const std::string& accountId);
LIBJAMI_PUBLIC std::vector getAccountList();
-LIBJAMI_PUBLIC void sendRegister(const std::string& accountID, bool enable);
+LIBJAMI_PUBLIC void sendRegister(const std::string& accountId, bool enable);
LIBJAMI_PUBLIC void registerAllAccounts(void);
-LIBJAMI_PUBLIC uint64_t sendAccountTextMessage(const std::string& accountID,
+LIBJAMI_PUBLIC uint64_t sendAccountTextMessage(const std::string& accountId,
const std::string& to,
const std::map& payloads,
int32_t flags);
-LIBJAMI_PUBLIC bool cancelMessage(const std::string& accountID, uint64_t message);
-LIBJAMI_PUBLIC std::vector getLastMessages(const std::string& accountID,
+LIBJAMI_PUBLIC bool cancelMessage(const std::string& accountId, uint64_t message);
+LIBJAMI_PUBLIC std::vector getLastMessages(const std::string& accountId,
const uint64_t& base_timestamp);
-LIBJAMI_PUBLIC std::map getNearbyPeers(const std::string& accountID);
+LIBJAMI_PUBLIC std::map getNearbyPeers(const std::string& accountId);
LIBJAMI_PUBLIC int getMessageStatus(uint64_t id);
-LIBJAMI_PUBLIC int getMessageStatus(const std::string& accountID, uint64_t id);
-LIBJAMI_PUBLIC void setIsComposing(const std::string& accountID,
+LIBJAMI_PUBLIC int getMessageStatus(const std::string& accountId, uint64_t id);
+LIBJAMI_PUBLIC void setIsComposing(const std::string& accountId,
const std::string& conversationUri,
bool isWriting);
-LIBJAMI_PUBLIC bool setMessageDisplayed(const std::string& accountID,
+LIBJAMI_PUBLIC bool setMessageDisplayed(const std::string& accountId,
const std::string& conversationUri,
const std::string& messageId,
int status);
LIBJAMI_PUBLIC std::vector getCodecList();
LIBJAMI_PUBLIC std::vector getSupportedTlsMethod();
-LIBJAMI_PUBLIC std::vector getSupportedCiphers(const std::string& accountID);
-LIBJAMI_PUBLIC std::map getCodecDetails(const std::string& accountID,
+LIBJAMI_PUBLIC std::vector getSupportedCiphers(const std::string& accountId);
+LIBJAMI_PUBLIC std::map getCodecDetails(const std::string& accountId,
const unsigned& codecId);
-LIBJAMI_PUBLIC bool setCodecDetails(const std::string& accountID,
+LIBJAMI_PUBLIC bool setCodecDetails(const std::string& accountId,
const unsigned& codecId,
const std::map& details);
-LIBJAMI_PUBLIC std::vector getActiveCodecList(const std::string& accountID);
+LIBJAMI_PUBLIC std::vector getActiveCodecList(const std::string& accountId);
-LIBJAMI_PUBLIC void setActiveCodecList(const std::string& accountID,
+LIBJAMI_PUBLIC void setActiveCodecList(const std::string& accountId,
const std::vector& list);
LIBJAMI_PUBLIC std::vector getAudioPluginList();
@@ -180,8 +183,8 @@ LIBJAMI_PUBLIC int32_t getRingingTimeout();
LIBJAMI_PUBLIC void setAccountsOrder(const std::string& order);
LIBJAMI_PUBLIC std::vector> getCredentials(
- const std::string& accountID);
-LIBJAMI_PUBLIC void setCredentials(const std::string& accountID,
+ const std::string& accountId);
+LIBJAMI_PUBLIC void setCredentials(const std::string& accountId,
const std::vector>& details);
LIBJAMI_PUBLIC std::string getAddrFromInterfaceName(const std::string& iface);
@@ -293,34 +296,34 @@ LIBJAMI_PUBLIC void setAudioMeterState(const std::string& id, bool state);
/**
* Add/remove default moderator for conferences
*/
-LIBJAMI_PUBLIC void setDefaultModerator(const std::string& accountID,
+LIBJAMI_PUBLIC void setDefaultModerator(const std::string& accountId,
const std::string& peerURI,
bool state);
/**
* Get default moderators for an account
*/
-LIBJAMI_PUBLIC std::vector getDefaultModerators(const std::string& accountID);
+LIBJAMI_PUBLIC std::vector getDefaultModerators(const std::string& accountId);
/**
* Enable/disable local moderators for conferences
*/
-LIBJAMI_PUBLIC void enableLocalModerators(const std::string& accountID, bool isModEnabled);
+LIBJAMI_PUBLIC void enableLocalModerators(const std::string& accountId, bool isModEnabled);
/**
* Get local moderators state
*/
-LIBJAMI_PUBLIC bool isLocalModeratorsEnabled(const std::string& accountID);
+LIBJAMI_PUBLIC bool isLocalModeratorsEnabled(const std::string& accountId);
/**
* Enable/disable all moderators for conferences
*/
-LIBJAMI_PUBLIC void setAllModerators(const std::string& accountID, bool allModerators);
+LIBJAMI_PUBLIC void setAllModerators(const std::string& accountId, bool allModerators);
/**
* Get all moderators state
*/
-LIBJAMI_PUBLIC bool isAllModerators(const std::string& accountID);
+LIBJAMI_PUBLIC bool isAllModerators(const std::string& accountId);
struct LIBJAMI_PUBLIC AudioSignal
{
diff --git a/src/jamidht/account_manager.h b/src/jamidht/account_manager.h
index f00865d77..ff4731ada 100644
--- a/src/jamidht/account_manager.h
+++ b/src/jamidht/account_manager.h
@@ -105,6 +105,7 @@ public:
{
std::string scheme;
std::string uri;
+ std::string password_scheme;
std::string password;
virtual ~AccountCredentials() {};
};
@@ -162,8 +163,9 @@ public:
using RevokeDeviceCallback = std::function;
virtual void addDevice(const std::string& /*password*/, AddDeviceCallback) {};
- virtual bool revokeDevice(const std::string& /*password*/,
- const std::string& /*device*/,
+ virtual bool revokeDevice(const std::string& /*device*/,
+ std::string_view /*scheme*/,
+ const std::string& /*password*/,
RevokeDeviceCallback)
{
return false;
@@ -260,8 +262,9 @@ public:
LookupCallback cb);
virtual void lookupAddress(const std::string& address, LookupCallback cb);
virtual bool searchUser(const std::string& /*query*/, SearchCallback /*cb*/) { return false; }
- virtual void registerName(const std::string& password,
- const std::string& name,
+ virtual void registerName(const std::string& name,
+ std::string_view scheme,
+ const std::string& password,
RegistrationCallback cb)
= 0;
diff --git a/src/jamidht/accountarchive.cpp b/src/jamidht/accountarchive.cpp
index 39419cdc7..7efefd85e 100644
--- a/src/jamidht/accountarchive.cpp
+++ b/src/jamidht/accountarchive.cpp
@@ -27,10 +27,12 @@
namespace jami {
void
-AccountArchive::deserialize(const std::vector& dat)
+AccountArchive::deserialize(const std::vector& dat, const std::vector& salt)
{
JAMI_DEBUG("Loading account archive ({:d} bytes)", dat.size());
+ password_salt = salt;
+
// Decode string
auto* char_data = reinterpret_cast(&dat[0]);
std::string err;
diff --git a/src/jamidht/accountarchive.h b/src/jamidht/accountarchive.h
index 222174d01..c80175976 100644
--- a/src/jamidht/accountarchive.h
+++ b/src/jamidht/accountarchive.h
@@ -57,26 +57,28 @@ struct AccountArchive
/** Account configuration */
std::map config;
+ /** Salt for the archive encryption password. */
+ std::vector password_salt;
+
AccountArchive() = default;
- AccountArchive(const std::vector& data) { deserialize(data); }
- AccountArchive(const std::filesystem::path& path, const std::string& password) { load(path, password); }
+ AccountArchive(const std::vector& data, const std::vector& password_salt = {}) { deserialize(data, password_salt); }
+ AccountArchive(const std::filesystem::path& path, std::string_view scheme, const std::string& pwd) { load(path, scheme, pwd); }
/** Serialize structured archive data to memory. */
std::string serialize() const;
/** Deserialize archive from memory. */
- void deserialize(const std::vector& data);
+ void deserialize(const std::vector& data, const std::vector& salt);
/** Load archive from file, optionally encrypted with provided password. */
- void load(const std::filesystem::path& path, const std::string& password = {})
- {
- deserialize(fileutils::readArchive(path, password));
+ void load(const std::filesystem::path& path, std::string_view scheme, const std::string& pwd) {
+ auto data = fileutils::readArchive(path, scheme, pwd);
+ deserialize(data.data, data.salt);
}
/** Save archive to file, optionally encrypted with provided password. */
- void save(const std::filesystem::path& path, const std::string& password = {}) const
- {
- fileutils::writeArchive(serialize(), path, password);
+ void save(const std::filesystem::path& path, std::string_view scheme, const std::string& password) const {
+ fileutils::writeArchive(serialize(), path, scheme, password, password_salt);
}
};
diff --git a/src/jamidht/archive_account_manager.cpp b/src/jamidht/archive_account_manager.cpp
index 53e588c4b..1c589cdda 100644
--- a/src/jamidht/archive_account_manager.cpp
+++ b/src/jamidht/archive_account_manager.cpp
@@ -161,12 +161,12 @@ ArchiveAccountManager::updateCertificates(AccountArchive& archive, dht::crypto::
}
bool
-ArchiveAccountManager::setValidity(const std::string& password,
+ArchiveAccountManager::setValidity(std::string_view scheme, const std::string& password,
dht::crypto::Identity& device,
const dht::InfoHash& id,
int64_t validity)
{
- auto archive = readArchive(password);
+ auto archive = readArchive(scheme, password);
// We need the CA key to resign certificates
if (not archive.id.first or not *archive.id.first or not archive.id.second or not archive.ca_key
or not *archive.ca_key)
@@ -201,7 +201,7 @@ ArchiveAccountManager::setValidity(const std::string& password,
}
if (updated) {
- archive.save(fileutils::getFullPath(path_, archivePath_), password);
+ archive.save(fileutils::getFullPath(path_, archivePath_), scheme, password);
}
if (updated or not id or device.second->getId() == id) {
@@ -241,7 +241,7 @@ ArchiveAccountManager::loadFromFile(AuthContext& ctx)
JAMI_WARN("[Auth] loading archive from: %s", ctx.credentials->uri.c_str());
AccountArchive archive;
try {
- archive = AccountArchive(ctx.credentials->uri, ctx.credentials->password);
+ archive = AccountArchive(ctx.credentials->uri, ctx.credentials->password_scheme, ctx.credentials->password);
} catch (const std::exception& ex) {
JAMI_WARN("[Auth] can't read file: %s", ex.what());
ctx.onFailure(AuthError::INVALID_ARGUMENTS, ex.what());
@@ -350,7 +350,7 @@ ArchiveAccountManager::migrateAccount(AuthContext& ctx)
JAMI_WARN("[Auth] account migration needed");
AccountArchive archive;
try {
- archive = readArchive(ctx.credentials->password);
+ archive = readArchive(ctx.credentials->password_scheme, ctx.credentials->password);
} catch (...) {
JAMI_DBG("[Auth] Can't load archive");
ctx.onFailure(AuthError::INVALID_ARGUMENTS, "");
@@ -374,7 +374,7 @@ ArchiveAccountManager::onArchiveLoaded(AuthContext& ctx,
auto ethAccount = dev::KeyPair(dev::Secret(a.eth_key)).address().hex();
dhtnet::fileutils::check_dir(path_, 0700);
- a.save(fileutils::getFullPath(path_, archivePath_), ctx.credentials ? ctx.credentials->password : "");
+ a.save(fileutils::getFullPath(path_, archivePath_), ctx.credentials ? ctx.credentials->password_scheme : "", ctx.credentials ? ctx.credentials->password : "");
if (not a.id.second->isCA()) {
JAMI_ERR("[Auth] trying to sign a certificate with a non-CA.");
@@ -568,10 +568,10 @@ ArchiveAccountManager::startSync(const OnNewDeviceCb& cb, const OnDeviceAnnounce
}
AccountArchive
-ArchiveAccountManager::readArchive(const std::string& pwd) const
+ArchiveAccountManager::readArchive(std::string_view scheme, const std::string& pwd) const
{
JAMI_DBG("[Auth] reading account archive");
- return AccountArchive(fileutils::getFullPath(path_, archivePath_), pwd);
+ return AccountArchive(fileutils::getFullPath(path_, archivePath_), scheme, pwd);
}
void
@@ -625,13 +625,13 @@ ArchiveAccountManager::updateArchive(AccountArchive& archive) const
}
void
-ArchiveAccountManager::saveArchive(AccountArchive& archive, const std::string& pwd)
+ArchiveAccountManager::saveArchive(AccountArchive& archive, std::string_view scheme, const std::string& pwd)
{
try {
updateArchive(archive);
if (archivePath_.empty())
archivePath_ = "export.gz";
- archive.save(fileutils::getFullPath(path_, archivePath_), pwd);
+ archive.save(fileutils::getFullPath(path_, archivePath_), scheme, pwd);
} catch (const std::runtime_error& ex) {
JAMI_ERR("[Auth] Can't export archive: %s", ex.what());
return;
@@ -644,7 +644,8 @@ ArchiveAccountManager::changePassword(const std::string& password_old,
{
try {
auto path = fileutils::getFullPath(path_, archivePath_);
- AccountArchive(path, password_old).save(path, password_new);
+ AccountArchive(path, fileutils::ARCHIVE_AUTH_SCHEME_PASSWORD, password_old)
+ .save(path, fileutils::ARCHIVE_AUTH_SCHEME_PASSWORD, password_new);
return true;
} catch (const std::exception&) {
return false;
@@ -693,7 +694,7 @@ ArchiveAccountManager::addDevice(const std::string& password, AddDeviceCallback
try {
JAMI_DBG("[Auth] exporting account");
- a = this_->readArchive(password);
+ a = this_->readArchive("password", password);
// Generate random PIN
pin_str = generatePIN();
@@ -731,15 +732,15 @@ ArchiveAccountManager::addDevice(const std::string& password, AddDeviceCallback
}
bool
-ArchiveAccountManager::revokeDevice(
+ArchiveAccountManager::revokeDevice(const std::string& device,
+ std::string_view scheme,
const std::string& password,
- const std::string& device,
RevokeDeviceCallback cb)
{
auto fa = dht::ThreadPool::computation().getShared(
- [this, password] { return readArchive(password); });
+ [this, scheme=std::string(scheme), password] { return readArchive(scheme, password); });
findCertificate(DeviceId(device),
- [fa = std::move(fa), password, device, cb, w=weak_from_this()](
+ [fa = std::move(fa), scheme=std::string(scheme), password, device, cb, w=weak_from_this()](
const std::shared_ptr& crt) mutable {
if (not crt) {
cb(RevokeDeviceResult::ERROR_NETWORK);
@@ -768,7 +769,7 @@ ArchiveAccountManager::revokeDevice(
auto h = a.id.second->getId();
this_->dht_->put(h, a.revoked, dht::DoneCallback {}, {}, true);
- this_->saveArchive(a, password);
+ this_->saveArchive(a, scheme, password);
this_->info_->contacts->removeAccountDevice(crt->getLongId());
cb(RevokeDeviceResult::SUCCESS);
this_->syncDevices();
@@ -777,22 +778,19 @@ ArchiveAccountManager::revokeDevice(
}
bool
-ArchiveAccountManager::exportArchive(const std::string& destinationPath, const std::string& password)
+ArchiveAccountManager::exportArchive(const std::string& destinationPath, std::string_view scheme, const std::string& password)
{
try {
// Save contacts if possible before exporting
- AccountArchive archive = readArchive(password);
+ AccountArchive archive = readArchive(scheme, password);
updateArchive(archive);
- archive.save(fileutils::getFullPath(path_, archivePath_), password);
+ auto archivePath = fileutils::getFullPath(path_, archivePath_);
+ archive.save(archivePath, scheme, password);
// Export the file
- auto sourcePath = fileutils::getFullPath(path_, archivePath_);
- std::ifstream src(sourcePath, std::ios::in | std::ios::binary);
- if (!src)
- return false;
- std::ofstream dst(destinationPath, std::ios::out | std::ios::binary);
- dst << src.rdbuf();
- return true;
+ std::error_code ec;
+ std::filesystem::copy_file(archivePath, destinationPath, std::filesystem::copy_options::overwrite_existing, ec);
+ return !ec;
} catch (const std::runtime_error& ex) {
JAMI_ERR("[Auth] Can't export archive: %s", ex.what());
return false;
@@ -806,7 +804,7 @@ bool
ArchiveAccountManager::isPasswordValid(const std::string& password)
{
try {
- readArchive(password);
+ readArchive(fileutils::ARCHIVE_AUTH_SCHEME_PASSWORD, password);
return true;
} catch (...) {
return false;
@@ -815,8 +813,9 @@ ArchiveAccountManager::isPasswordValid(const std::string& password)
#if HAVE_RINGNS
void
-ArchiveAccountManager::registerName(const std::string& password,
- const std::string& name,
+ArchiveAccountManager::registerName(const std::string& name,
+ std::string_view scheme,
+ const std::string& password,
RegistrationCallback cb)
{
std::string signedName;
@@ -827,7 +826,7 @@ ArchiveAccountManager::registerName(const std::string& password,
std::string ethAccount;
try {
- auto archive = readArchive(password);
+ auto archive = readArchive(scheme, password);
auto privateKey = archive.id.first;
const auto& pk = privateKey->getPublicKey();
publickey = pk.toString();
diff --git a/src/jamidht/archive_account_manager.h b/src/jamidht/archive_account_manager.h
index 03874a970..d993a2948 100644
--- a/src/jamidht/archive_account_manager.h
+++ b/src/jamidht/archive_account_manager.h
@@ -57,25 +57,24 @@ public:
void syncDevices() override;
void addDevice(const std::string& password, AddDeviceCallback) override;
- bool revokeDevice(
- const std::string& password,
- const std::string& device,
+ bool revokeDevice(const std::string& device,
+ std::string_view scheme, const std::string& password,
RevokeDeviceCallback) override;
- bool exportArchive(const std::string& destinationPath, const std::string& password);
+ bool exportArchive(const std::string& destinationPath, std::string_view scheme, const std::string& password);
bool isPasswordValid(const std::string& password) override;
#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,
+ void registerName(const std::string& name,
+ std::string_view scheme, const std::string& password,
RegistrationCallback cb) override;
#endif
/**
* Change the validity of a certificate. If hash is empty, update all certificates
*/
- bool setValidity(const std::string& password,
+ bool setValidity(std::string_view scheme, const std::string& password,
dht::crypto::Identity& device,
const dht::InfoHash& id,
int64_t validity);
@@ -102,8 +101,8 @@ private:
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;
+ void saveArchive(AccountArchive& content, std::string_view scheme, const std::string& pwd);
+ AccountArchive readArchive(std::string_view scheme, const std::string& password) const;
static std::pair, dht::InfoHash> computeKeys(const std::string& password,
const std::string& pin,
bool previous = false);
diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp
index 6cdcda323..0f7d1651b 100644
--- a/src/jamidht/jamiaccount.cpp
+++ b/src/jamidht/jamiaccount.cpp
@@ -931,7 +931,7 @@ JamiAccount::loadConfig()
getAccountID().c_str(),
e.what());
}
- loadAccount(config().archive_password, config().archive_pin, config().archive_path);
+ loadAccount(config().archive_password_scheme, config().archive_password, config().archive_pin, config().archive_path);
}
bool
@@ -999,19 +999,19 @@ JamiAccount::addDevice(const std::string& password)
}
bool
-JamiAccount::exportArchive(const std::string& destinationPath, const std::string& password)
+JamiAccount::exportArchive(const std::string& destinationPath, std::string_view scheme, const std::string& password)
{
if (auto manager = dynamic_cast(accountManager_.get())) {
- return manager->exportArchive(destinationPath, password);
+ return manager->exportArchive(destinationPath, scheme, password);
}
return false;
}
bool
-JamiAccount::setValidity(const std::string& pwd, const dht::InfoHash& id, int64_t validity)
+JamiAccount::setValidity(std::string_view scheme, const std::string& pwd, const dht::InfoHash& id, int64_t validity)
{
if (auto manager = dynamic_cast(accountManager_.get())) {
- if (manager->setValidity(pwd, id_, id, validity)) {
+ if (manager->setValidity(scheme, pwd, id_, id, validity)) {
saveIdentity(id_, idPath_, DEVICE_ID_PATH);
return true;
}
@@ -1062,12 +1062,12 @@ JamiAccount::isValidAccountDevice(const dht::crypto::Certificate& cert) const
}
bool
-JamiAccount::revokeDevice(const std::string& password, const std::string& device)
+JamiAccount::revokeDevice(const std::string& device, std::string_view scheme, const std::string& password)
{
if (not accountManager_)
return false;
return accountManager_
- ->revokeDevice(password, device, [this, device](AccountManager::RevokeDeviceResult result) {
+ ->revokeDevice(device, scheme, password, [this, device](AccountManager::RevokeDeviceResult result) {
emitSignal(getAccountID(),
device,
static_cast(
@@ -1091,7 +1091,8 @@ JamiAccount::saveIdentity(const dht::crypto::Identity id,
// must be called while configurationMutex_ is locked
void
-JamiAccount::loadAccount(const std::string& archive_password,
+JamiAccount::loadAccount(const std::string& archive_password_scheme,
+ const std::string& archive_password,
const std::string& archive_pin,
const std::string& archive_path)
{
@@ -1283,6 +1284,10 @@ JamiAccount::loadAccount(const std::string& archive_password,
}
creds->password = archive_password;
bool hasPassword = !archive_password.empty();
+ if (hasPassword && archive_password_scheme.empty())
+ creds->password_scheme = fileutils::ARCHIVE_AUTH_SCHEME_PASSWORD;
+ else
+ creds->password_scheme = archive_password_scheme;
accountManager_->initAuthentication(
getAccountID(),
@@ -1297,7 +1302,7 @@ JamiAccount::loadAccount(const std::string& archive_password,
if (not sthis) return;
JAMI_LOG("[Account {}] Auth success!", getAccountID());
- dhtnet::fileutils::check_dir(idPath_.c_str(), 0700);
+ dhtnet::fileutils::check_dir(idPath_, 0700);
auto id = info.identity;
editConfig([&](JamiAccountConfig& conf) {
@@ -1420,13 +1425,13 @@ JamiAccount::lookupAddress(const std::string& addr)
}
void
-JamiAccount::registerName(const std::string& password, const std::string& name)
+JamiAccount::registerName(const std::string& name, const std::string& scheme, const std::string& password)
{
std::lock_guard lock(configurationMutex_);
if (accountManager_)
accountManager_->registerName(
- password,
name,
+ scheme, password,
[acc = getAccountID(), name, w = weak()](NameDirectory::RegistrationResponse response) {
int res
= (response == NameDirectory::RegistrationResponse::success)
diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h
index 1b0ab9520..c5e94770d 100644
--- a/src/jamidht/jamiaccount.h
+++ b/src/jamidht/jamiaccount.h
@@ -344,8 +344,8 @@ public:
* doesn't have a password
* @return if the archive was exported
*/
- bool exportArchive(const std::string& destinationPath, const std::string& password = {});
- bool revokeDevice(const std::string& password, const std::string& device);
+ bool exportArchive(const std::string& destinationPath, std::string_view scheme = {}, const std::string& password = {});
+ bool revokeDevice(const std::string& device, std::string_view scheme, const std::string& password = {});
std::map getKnownDevices() const;
bool isPasswordValid(const std::string& password);
@@ -361,7 +361,7 @@ public:
#if HAVE_RINGNS
void lookupName(const std::string& name);
void lookupAddress(const std::string& address);
- void registerName(const std::string& password, const std::string& name);
+ void registerName(const std::string& name, const std::string& scheme, const std::string& password);
#endif
bool searchUser(const std::string& nameQuery);
@@ -550,7 +550,7 @@ public:
* @param validity New validity
* @note forceReloadAccount may be necessary to retrigger the migration
*/
- bool setValidity(const std::string& pwd, const dht::InfoHash& id, int64_t validity);
+ bool setValidity(std::string_view scheme, const std::string& pwd, const dht::InfoHash& id, int64_t validity);
/**
* Try to reload the account to force the identity to be updated
*/
@@ -666,10 +666,9 @@ private:
void forEachPendingCall(const DeviceId& deviceId,
const std::function&)>& cb);
- void loadAccountFromFile(const std::string& archive_path, const std::string& archive_password);
void loadAccountFromDHT(const std::string& archive_password, const std::string& archive_pin);
- void loadAccountFromArchive(AccountArchive&& archive, const std::string& archive_password);
- void loadAccount(const std::string& archive_password = {},
+ void loadAccount(const std::string& archive_password_scheme = {},
+ const std::string& archive_password = {},
const std::string& archive_pin = {},
const std::string& archive_path = {});
diff --git a/src/jamidht/jamiaccount_config.cpp b/src/jamidht/jamiaccount_config.cpp
index 039e9f407..ba37e2691 100644
--- a/src/jamidht/jamiaccount_config.cpp
+++ b/src/jamidht/jamiaccount_config.cpp
@@ -200,6 +200,7 @@ JamiAccountConfig::fromMap(const std::map& details)
// parseString(details, libjami::Account::ConfProperties::USERNAME, username);
parseString(details, libjami::Account::ConfProperties::ARCHIVE_PASSWORD, archive_password);
+ parseString(details, libjami::Account::ConfProperties::ARCHIVE_PASSWORD_SCHEME, archive_password_scheme);
parseString(details, libjami::Account::ConfProperties::ARCHIVE_PIN, archive_pin);
std::transform(archive_pin.begin(), archive_pin.end(), archive_pin.begin(), ::toupper);
parseString(details, libjami::Account::ConfProperties::ARCHIVE_PATH, archive_path);
diff --git a/src/jamidht/jamiaccount_config.h b/src/jamidht/jamiaccount_config.h
index e50d01314..edac4b199 100644
--- a/src/jamidht/jamiaccount_config.h
+++ b/src/jamidht/jamiaccount_config.h
@@ -68,6 +68,7 @@ struct JamiAccountConfig : public SipAccountBaseConfig {
std::string archivePath {"archive.gz"};
bool archiveHasPassword {true};
// not saved, only used client->daemon
+ std::string archive_password_scheme;
std::string archive_password;
std::string archive_pin;
std::string archive_path;
diff --git a/src/jamidht/server_account_manager.cpp b/src/jamidht/server_account_manager.cpp
index 056d24a6d..2f67deaa6 100644
--- a/src/jamidht/server_account_manager.cpp
+++ b/src/jamidht/server_account_manager.cpp
@@ -19,6 +19,7 @@
#include "server_account_manager.h"
#include "base64.h"
#include "jami/account_const.h"
+#include "fileutils.h"
#include
#include
@@ -578,11 +579,11 @@ ServerAccountManager::syncBlueprintConfig(SyncBlueprintCallback onSuccess)
}
bool
-ServerAccountManager::revokeDevice(const std::string& password,
- const std::string& device,
+ServerAccountManager::revokeDevice(const std::string& device,
+ std::string_view scheme, const std::string& password,
RevokeDeviceCallback cb)
{
- if (not info_) {
+ if (not info_ || scheme != fileutils::ARCHIVE_AUTH_SCHEME_PASSWORD) {
if (cb)
cb(RevokeDeviceResult::ERROR_CREDENTIALS);
return false;
@@ -618,7 +619,7 @@ ServerAccountManager::revokeDevice(const std::string& password,
}
void
-ServerAccountManager::registerName(const std::string&, const std::string&, RegistrationCallback cb)
+ServerAccountManager::registerName(const std::string&, std::string_view scheme, const std::string&, RegistrationCallback cb)
{
cb(NameDirectory::RegistrationResponse::unsupported);
}
diff --git a/src/jamidht/server_account_manager.h b/src/jamidht/server_account_manager.h
index e0fcd9867..d357d2b08 100644
--- a/src/jamidht/server_account_manager.h
+++ b/src/jamidht/server_account_manager.h
@@ -59,13 +59,13 @@ public:
void syncBlueprintConfig(SyncBlueprintCallback onSuccess);
- bool revokeDevice(const std::string& password,
- const std::string& device,
+ bool revokeDevice(const std::string& device,
+ std::string_view scheme, const std::string& password,
RevokeDeviceCallback cb) override;
bool searchUser(const std::string& query, SearchCallback cb) override;
- void registerName(const std::string& password,
- const std::string& name,
+ void registerName(const std::string& name,
+ std::string_view scheme, const std::string& password,
RegistrationCallback cb) override;
private:
diff --git a/test/unitTest/account_archive/account_archive.cpp b/test/unitTest/account_archive/account_archive.cpp
index 8345629af..10db06c05 100644
--- a/test/unitTest/account_archive/account_archive.cpp
+++ b/test/unitTest/account_archive/account_archive.cpp
@@ -149,7 +149,7 @@ AccountArchiveTest::testExportImportPassword()
{
auto bobAccount = Manager::instance().getAccount(bobId);
- CPPUNIT_ASSERT(bobAccount->exportArchive("test.gz", "test"));
+ CPPUNIT_ASSERT(bobAccount->exportArchive("test.gz", "password", "test"));
std::map details = libjami::getAccountTemplate("RING");
details[ConfProperties::ARCHIVE_PATH] = "test.gz";
@@ -168,7 +168,7 @@ AccountArchiveTest::testExportImportPasswordDoubleGunzip()
{
auto bobAccount = Manager::instance().getAccount(bobId);
- CPPUNIT_ASSERT(bobAccount->exportArchive("test.gz", "test"));
+ CPPUNIT_ASSERT(bobAccount->exportArchive("test.gz", "password", "test"));
auto dat = fileutils::loadFile("test.gz");
archiver::compressGzip(dat, "test.gz");
diff --git a/test/unitTest/account_archive/migration.cpp b/test/unitTest/account_archive/migration.cpp
index 66efefb81..dd139808d 100644
--- a/test/unitTest/account_archive/migration.cpp
+++ b/test/unitTest/account_archive/migration.cpp
@@ -112,7 +112,7 @@ MigrationTest::testLoadExpiredAccount()
auto accountExpiration = archive.id.second->getExpiration();
// Update validity
- CPPUNIT_ASSERT(aliceAccount->setValidity("", {}, 9));
+ CPPUNIT_ASSERT(aliceAccount->setValidity("", "", {}, 9));
archive = AccountArchive(archivePath, "");
deviceCert = dht::crypto::Certificate(fileutils::loadFile(devicePath));
auto newDeviceExpiration = deviceCert.getExpiration();
@@ -295,7 +295,7 @@ MigrationTest::testExpiredDeviceInSwarm()
CPPUNIT_ASSERT(cv.wait_for(lk, 10s, [&]() { return aliceRegistering; }));
auto aliceDevice = std::string(aliceAccount->currentDeviceId());
- CPPUNIT_ASSERT(aliceAccount->setValidity("", {}, 90));
+ CPPUNIT_ASSERT(aliceAccount->setValidity("", "", {}, 90));
auto now = std::chrono::system_clock::now();
aliceRegistered = false;
aliceAccount->forceReloadAccount();
diff --git a/test/unitTest/namedirectory/namedirectory.cpp b/test/unitTest/namedirectory/namedirectory.cpp
index 301f7ba47..c6e00c496 100644
--- a/test/unitTest/namedirectory/namedirectory.cpp
+++ b/test/unitTest/namedirectory/namedirectory.cpp
@@ -196,7 +196,7 @@ NameDirectoryTest::testRegisterName()
cv.notify_one();
}));
libjami::registerSignalHandlers(confHandlers);
- CPPUNIT_ASSERT(libjami::registerName(aliceId, "", "foo"));
+ CPPUNIT_ASSERT(libjami::registerName(aliceId, "", "password", "foo"));
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&] { return nameRegistered; }));
}
diff --git a/test/unitTest/revoke/revoke.cpp b/test/unitTest/revoke/revoke.cpp
index 81a97fff9..5d20150d4 100644
--- a/test/unitTest/revoke/revoke.cpp
+++ b/test/unitTest/revoke/revoke.cpp
@@ -118,7 +118,7 @@ RevokeTest::testRevokeDevice()
auto alice2Account = Manager::instance().getAccount(alice2Id);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&] { return knownChanged; }));
alice2Device = std::string(alice2Account->currentDeviceId());
- aliceAccount->revokeDevice("", alice2Device);
+ aliceAccount->revokeDevice(alice2Device);
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&] { return deviceRevoked; }));
std::remove("test.gz");
@@ -143,7 +143,7 @@ RevokeTest::testRevokeInvalidDevice()
cv.notify_one();
}));
libjami::registerSignalHandlers(confHandlers);
- aliceAccount->revokeDevice("", "foo");
+ aliceAccount->revokeDevice("foo");
CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&] { return revokeFailed; }));
}