mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-07 22:02:12 +08:00
p2p device link: cleanup
Change-Id: I8625be46bcde0c2f69f75cb341a11da7def7e0d0
This commit is contained in:
@ -40,6 +40,8 @@ namespace jami {
|
||||
|
||||
const constexpr auto EXPORT_KEY_RENEWAL_TIME = std::chrono::minutes(20);
|
||||
constexpr auto AUTH_URI_SCHEME = "jami-auth://"sv;
|
||||
constexpr auto CHANNEL_SCHEME = "auth:"sv;
|
||||
constexpr auto OP_TIMEOUT = 5min;
|
||||
|
||||
void
|
||||
ArchiveAccountManager::initAuthentication(PrivateKey key,
|
||||
@ -73,8 +75,8 @@ ArchiveAccountManager::initAuthentication(PrivateKey key,
|
||||
return;
|
||||
}
|
||||
|
||||
dht::ThreadPool::computation().run([ctx = std::move(ctx), wthis = weak_from_this()] {
|
||||
auto this_ = std::static_pointer_cast<ArchiveAccountManager>(wthis.lock());
|
||||
dht::ThreadPool::computation().run([ctx = std::move(ctx), wthis = weak()] {
|
||||
auto this_ = wthis.lock();
|
||||
if (not this_)
|
||||
return;
|
||||
try {
|
||||
@ -315,16 +317,15 @@ toString(AuthDecodingState state)
|
||||
}
|
||||
}
|
||||
|
||||
struct ArchiveAccountManager::PayloadKey
|
||||
{
|
||||
static constexpr auto passwordCorrect = "passwordCorrect"sv;
|
||||
static constexpr auto canRetry = "canRetry"sv;
|
||||
static constexpr auto archiveTransferredWithoutFailure = "archiveTransferredWithoutFailure"sv;
|
||||
static constexpr auto accData = "accData"sv;
|
||||
static constexpr auto authScheme = "authScheme"sv;
|
||||
static constexpr auto password = "password"sv;
|
||||
static constexpr auto stateMsg = "stateMsg"sv;
|
||||
};
|
||||
namespace PayloadKey {
|
||||
static constexpr auto passwordCorrect = "passwordCorrect"sv;
|
||||
static constexpr auto canRetry = "canRetry"sv;
|
||||
static constexpr auto archiveTransferredWithoutFailure = "archiveTransferredWithoutFailure"sv;
|
||||
static constexpr auto accData = "accData"sv;
|
||||
static constexpr auto authScheme = "authScheme"sv;
|
||||
static constexpr auto password = "password"sv;
|
||||
static constexpr auto stateMsg = "stateMsg"sv;
|
||||
}
|
||||
|
||||
struct ArchiveAccountManager::AuthMsg
|
||||
{
|
||||
@ -332,8 +333,7 @@ struct ArchiveAccountManager::AuthMsg
|
||||
std::map<std::string, std::string> payload;
|
||||
MSGPACK_DEFINE_MAP(schemeId, payload)
|
||||
|
||||
void set(std::string_view key, std::string_view value)
|
||||
{
|
||||
void set(std::string_view key, std::string_view value) {
|
||||
payload.emplace(std::string(key), std::string(value));
|
||||
}
|
||||
|
||||
@ -343,8 +343,7 @@ struct ArchiveAccountManager::AuthMsg
|
||||
|
||||
void logMsg() { JAMI_DEBUG("[LinkDevice]\nLinkDevice::logMsg:\n{}", formatMsg()); }
|
||||
|
||||
std::string formatMsg()
|
||||
{
|
||||
std::string formatMsg() {
|
||||
std::string logStr = "=========\n";
|
||||
logStr += fmt::format("scheme: {}\n", schemeId);
|
||||
for (const auto& [msgKey, msgVal] : payload) {
|
||||
@ -353,6 +352,12 @@ struct ArchiveAccountManager::AuthMsg
|
||||
logStr += "=========";
|
||||
return logStr;
|
||||
}
|
||||
|
||||
static AuthMsg timeout() {
|
||||
AuthMsg timeoutMsg;
|
||||
timeoutMsg.set(PayloadKey::stateMsg, toString(AuthDecodingState::TIMEOUT));
|
||||
return timeoutMsg;
|
||||
}
|
||||
};
|
||||
|
||||
struct ArchiveAccountManager::DeviceAuthInfo : public std::map<std::string, std::string>
|
||||
@ -362,7 +367,6 @@ struct ArchiveAccountManager::DeviceAuthInfo : public std::map<std::string, std:
|
||||
static constexpr auto error = "error"sv;
|
||||
static constexpr auto auth_scheme = "auth_scheme"sv;
|
||||
static constexpr auto peer_id = "peer_id"sv;
|
||||
static constexpr auto peer_device_id = "peer_device_id"sv;
|
||||
static constexpr auto auth_error = "auth_error"sv;
|
||||
static constexpr auto peer_address = "peer_address"sv;
|
||||
|
||||
@ -375,9 +379,11 @@ struct ArchiveAccountManager::DeviceAuthInfo : public std::map<std::string, std:
|
||||
DeviceAuthInfo(const Map& map)
|
||||
: Map(map)
|
||||
{}
|
||||
DeviceAuthInfo(Map&& map)
|
||||
: Map(std::move(map))
|
||||
{}
|
||||
|
||||
void set(std::string_view key, std::string_view value)
|
||||
{
|
||||
void set(std::string_view key, std::string_view value) {
|
||||
emplace(std::string(key), std::string(value));
|
||||
}
|
||||
|
||||
@ -424,18 +430,11 @@ struct ArchiveAccountManager::DeviceContextBase
|
||||
|
||||
constexpr std::string_view formattedAuthState() const { return toString(state); }
|
||||
|
||||
AuthMsg createTimeoutMsg() const
|
||||
{
|
||||
AuthMsg timeoutMsg;
|
||||
timeoutMsg.set(PayloadKey::stateMsg, std::string(toString(AuthDecodingState::TIMEOUT)));
|
||||
return timeoutMsg;
|
||||
}
|
||||
|
||||
bool handleTimeoutMessage(const AuthMsg& msg)
|
||||
{
|
||||
auto stateMsgIt = msg.find(PayloadKey::stateMsg);
|
||||
if (stateMsgIt != msg.payload.end()) {
|
||||
if (stateMsgIt->second == std::string(toString(AuthDecodingState::TIMEOUT))) {
|
||||
if (stateMsgIt->second == toString(AuthDecodingState::TIMEOUT)) {
|
||||
this->state = AuthDecodingState::TIMEOUT;
|
||||
return true;
|
||||
}
|
||||
@ -447,7 +446,7 @@ struct ArchiveAccountManager::DeviceContextBase
|
||||
{
|
||||
auto stateMsgIt = msg.find(PayloadKey::stateMsg);
|
||||
if (stateMsgIt != msg.payload.end()) {
|
||||
if (stateMsgIt->second == std::string(toString(AuthDecodingState::CANCELED))) {
|
||||
if (stateMsgIt->second == toString(AuthDecodingState::CANCELED)) {
|
||||
this->state = AuthDecodingState::CANCELED;
|
||||
return true;
|
||||
}
|
||||
@ -515,7 +514,7 @@ struct ArchiveAccountManager::AddDeviceContext : public DeviceContextBase
|
||||
AuthMsg createCanceledMsg() const
|
||||
{
|
||||
AuthMsg timeoutMsg;
|
||||
timeoutMsg.set(PayloadKey::stateMsg, std::string(toString(AuthDecodingState::CANCELED)));
|
||||
timeoutMsg.set(PayloadKey::stateMsg, toString(AuthDecodingState::CANCELED));
|
||||
return timeoutMsg;
|
||||
}
|
||||
};
|
||||
@ -645,7 +644,6 @@ ArchiveAccountManager::startLoadArchiveFromDevice(const std::shared_ptr<AuthCont
|
||||
ctx->linkDevCtx->tempConnMgr.onChannelRequest(
|
||||
[wthis, ctx](const std::shared_ptr<dht::crypto::Certificate>& cert,
|
||||
const std::string& name) {
|
||||
constexpr auto CHANNEL_SCHEME = "auth:"sv;
|
||||
std::string_view url(name);
|
||||
if (!starts_with(url, CHANNEL_SCHEME)) {
|
||||
JAMI_WARNING(
|
||||
@ -677,7 +675,7 @@ ArchiveAccountManager::startLoadArchiveFromDevice(const std::shared_ptr<AuthCont
|
||||
ctx->linkDevCtx->channel = socket;
|
||||
|
||||
ctx->timeout = std::make_unique<asio::steady_timer>(*Manager::instance().ioContext());
|
||||
ctx->timeout->expires_from_now(5min);
|
||||
ctx->timeout->expires_from_now(OP_TIMEOUT);
|
||||
ctx->timeout->async_wait([c = std::weak_ptr(ctx), socket](const std::error_code& ec) {
|
||||
if (ec) {
|
||||
return;
|
||||
@ -688,9 +686,8 @@ ArchiveAccountManager::startLoadArchiveFromDevice(const std::shared_ptr<AuthCont
|
||||
JAMI_WARNING("[LinkDevice] timeout: {}", socket->name());
|
||||
|
||||
// Create and send timeout message
|
||||
auto timeoutMsg = ctx->linkDevCtx->createTimeoutMsg();
|
||||
msgpack::sbuffer buffer(UINT16_MAX);
|
||||
msgpack::pack(buffer, timeoutMsg);
|
||||
msgpack::pack(buffer, AuthMsg::timeout());
|
||||
std::error_code ec;
|
||||
socket->write(reinterpret_cast<const unsigned char*>(buffer.data()),
|
||||
buffer.size(),
|
||||
@ -764,7 +761,7 @@ ArchiveAccountManager::startLoadArchiveFromDevice(const std::shared_ptr<AuthCont
|
||||
return len;
|
||||
}
|
||||
AuthMsg toSend;
|
||||
bool shouldShutDown = false;
|
||||
bool shouldShutdown = false;
|
||||
auto accDataIt = toRecv.find(PayloadKey::accData);
|
||||
bool shouldLoadArchive = accDataIt != toRecv.payload.end();
|
||||
|
||||
@ -821,7 +818,7 @@ ArchiveAccountManager::startLoadArchiveFromDevice(const std::shared_ptr<AuthCont
|
||||
// at this point we suppose to have archive. If not, export failed.
|
||||
// Update state and signal will be handeled onShutdown
|
||||
ctx->linkDevCtx->state = AuthDecodingState::ERR;
|
||||
shouldShutDown = true;
|
||||
shouldShutdown = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -848,10 +845,10 @@ ArchiveAccountManager::startLoadArchiveFromDevice(const std::shared_ptr<AuthCont
|
||||
ctx->linkDevCtx->archiveTransferredWithoutFailure = false;
|
||||
JAMI_WARNING("[LinkDevice] NEW: Error reading archive.");
|
||||
}
|
||||
shouldShutDown = true;
|
||||
shouldShutdown = true;
|
||||
}
|
||||
|
||||
if (shouldShutDown) {
|
||||
if (shouldShutdown) {
|
||||
ctx->linkDevCtx->channel->shutdown();
|
||||
}
|
||||
|
||||
@ -915,22 +912,24 @@ ArchiveAccountManager::addDevice(const std::string& uriProvided,
|
||||
|
||||
channelHandler->connect(
|
||||
dht::InfoHash(peerTempAcc),
|
||||
fmt::format("auth:{}", peerCodeS),
|
||||
[this, auth_scheme, ctx](std::shared_ptr<dhtnet::ChannelSocket> socket,
|
||||
fmt::format("{}{}", CHANNEL_SCHEME, peerCodeS),
|
||||
[wthis = weak(), auth_scheme, ctx, accountId=accountId_](std::shared_ptr<dhtnet::ChannelSocket> socket,
|
||||
const dht::InfoHash& infoHash) {
|
||||
if (!socket) {
|
||||
auto this_ = wthis.lock();
|
||||
if (!socket || !this_) {
|
||||
JAMI_WARNING(
|
||||
"[LinkDevice] Invalid socket event while AccountManager connecting.");
|
||||
authCtx_.reset();
|
||||
if (this_)
|
||||
this_->authCtx_.reset();
|
||||
emitSignal<libjami::ConfigurationSignal::AddDeviceStateChanged>(
|
||||
accountId_,
|
||||
accountId,
|
||||
ctx->token,
|
||||
static_cast<uint8_t>(DeviceAuthState::DONE),
|
||||
DeviceAuthInfo::createError(DeviceAuthInfo::Error::NETWORK));
|
||||
} else {
|
||||
if (!doAddDevice(auth_scheme, ctx, socket))
|
||||
if (!this_->doAddDevice(auth_scheme, ctx, socket))
|
||||
emitSignal<libjami::ConfigurationSignal::AddDeviceStateChanged>(
|
||||
accountId_,
|
||||
accountId,
|
||||
ctx->token,
|
||||
static_cast<uint8_t>(DeviceAuthState::DONE),
|
||||
DeviceAuthInfo::createError(DeviceAuthInfo::Error::UNKNOWN));
|
||||
@ -964,9 +963,9 @@ ArchiveAccountManager::doAddDevice(std::string_view scheme,
|
||||
ctx->addDeviceCtx->state = AuthDecodingState::HANDSHAKE;
|
||||
|
||||
ctx->timeout = std::make_unique<asio::steady_timer>(*Manager::instance().ioContext());
|
||||
ctx->timeout->expires_from_now(5min);
|
||||
ctx->timeout->expires_from_now(OP_TIMEOUT);
|
||||
ctx->timeout->async_wait(
|
||||
[wthis = weak_from_this(), wctx = std::weak_ptr(ctx)](const std::error_code& ec) {
|
||||
[wthis = weak(), wctx = std::weak_ptr(ctx)](const std::error_code& ec) {
|
||||
if (ec) {
|
||||
return;
|
||||
}
|
||||
@ -977,9 +976,8 @@ ArchiveAccountManager::doAddDevice(std::string_view scheme,
|
||||
JAMI_WARNING("[LinkDevice] Timeout for addDevice.");
|
||||
|
||||
// Create and send timeout message
|
||||
auto timeoutMsg = ctx->linkDevCtx->createTimeoutMsg();
|
||||
msgpack::sbuffer buffer(UINT16_MAX);
|
||||
msgpack::pack(buffer, timeoutMsg);
|
||||
msgpack::pack(buffer, AuthMsg::timeout());
|
||||
std::error_code ec;
|
||||
ctx->addDeviceCtx->channel->write(reinterpret_cast<const unsigned char*>(
|
||||
buffer.data()),
|
||||
@ -1085,7 +1083,7 @@ ArchiveAccountManager::doAddDevice(std::string_view scheme,
|
||||
}
|
||||
AuthMsg toSend;
|
||||
bool shouldSendMsg = false;
|
||||
bool shouldShutDown = false;
|
||||
bool shouldShutdown = false;
|
||||
bool shouldSendArchive = false;
|
||||
|
||||
// we expect to be receiving credentials in this state and we know the archive is encrypted
|
||||
@ -1095,51 +1093,42 @@ ArchiveAccountManager::doAddDevice(std::string_view scheme,
|
||||
JAMI_DEBUG("[LinkDevice] EXPORTING: addDevice: setOnRecv: verifying sent "
|
||||
"credentials from NEW");
|
||||
shouldSendMsg = true;
|
||||
// check if the password is valid... if so then send the unencrypyted archive data
|
||||
// over the tls channel as a compressed file this will involve (EXPORTING:) unzip,
|
||||
// unencrypt, send, (NEW:) recv, encrypt w new salt, compress, write to system file
|
||||
// (ONLY DO EXPORTING HERE) check if password is valid
|
||||
const auto& passwordIt = toRecv.find(PayloadKey::password);
|
||||
|
||||
bool passValid = this_->isPasswordValid(toRecv.at(PayloadKey::password));
|
||||
JAMI_DEBUG("[LinkDevice] EXPORTING: {} password received for authentication.",
|
||||
passValid ? "Valid" : "Invalid");
|
||||
if (passValid) {
|
||||
if (passwordIt != toRecv.payload.end()) {
|
||||
// try and decompress archive for xfer
|
||||
shouldSendArchive = true;
|
||||
try {
|
||||
JAMI_DEBUG("[LinkDevice] Injecting account archive into outbound message.");
|
||||
|
||||
ctx->addDeviceCtx->accData
|
||||
= this_
|
||||
->readArchive(fileutils::ARCHIVE_AUTH_SCHEME_PASSWORD,
|
||||
toRecv.at(PayloadKey::password))
|
||||
passwordIt->second)
|
||||
.serialize();
|
||||
|
||||
JAMI_DEBUG("[LinkDevice] Injected account archive into outbound message.\n{}",
|
||||
ctx->addDeviceCtx->accData);
|
||||
shouldSendArchive = true;
|
||||
JAMI_DEBUG("[LinkDevice] Sending account archive.");
|
||||
} catch (...) {
|
||||
ctx->addDeviceCtx->state = AuthDecodingState::ERR;
|
||||
JAMI_DEBUG("[LinkDevice] Finished reading archive: FAILURE");
|
||||
shouldSendArchive = false;
|
||||
}
|
||||
shouldShutDown = true;
|
||||
} else { // pass is not valid
|
||||
}
|
||||
if (!shouldSendArchive) {
|
||||
// pass is not valid
|
||||
if (ctx->addDeviceCtx->numTries < ctx->addDeviceCtx->maxTries) {
|
||||
// can retry auth
|
||||
ctx->addDeviceCtx->numTries++;
|
||||
JAMI_DEBUG("[LinkDevice] Incorrect password was submitted to this server... "
|
||||
"allowing a retry. {}",
|
||||
ctx->addDeviceCtx->numTries);
|
||||
JAMI_DEBUG("[LinkDevice] Incorrect password received. "
|
||||
"Attempt {} out of {}.",
|
||||
ctx->addDeviceCtx->numTries,
|
||||
ctx->addDeviceCtx->maxTries);
|
||||
toSend.set(PayloadKey::passwordCorrect, "false");
|
||||
toSend.set(PayloadKey::canRetry, "true");
|
||||
} else {
|
||||
// cannot retry auth
|
||||
JAMI_DEBUG("[LinkDevice] Incorrect password was submitted to this server... "
|
||||
"NOT allowing a retry because threshold already reached!");
|
||||
JAMI_WARNING("[LinkDevice] Incorrect password received, maximum attempts reached.");
|
||||
toSend.set(PayloadKey::canRetry, "false");
|
||||
ctx->addDeviceCtx->state = AuthDecodingState::AUTH_ERROR;
|
||||
shouldShutDown = true;
|
||||
shouldShutdown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1152,7 +1141,7 @@ ArchiveAccountManager::doAddDevice(std::string_view scheme,
|
||||
ctx->token,
|
||||
static_cast<uint8_t>(DeviceAuthState::IN_PROGRESS),
|
||||
DeviceAuthInfo {});
|
||||
shouldShutDown = true;
|
||||
shouldShutdown = true;
|
||||
shouldSendMsg = true;
|
||||
ctx->addDeviceCtx->archiveTransferredWithoutFailure = true;
|
||||
try {
|
||||
@ -1177,7 +1166,7 @@ ArchiveAccountManager::doAddDevice(std::string_view scheme,
|
||||
ec);
|
||||
}
|
||||
|
||||
if (shouldShutDown) {
|
||||
if (shouldShutdown) {
|
||||
ctx->addDeviceCtx->channel->shutdown();
|
||||
}
|
||||
|
||||
@ -1278,7 +1267,7 @@ ArchiveAccountManager::loadFromDHT(const std::shared_ptr<AuthContext>& ctx)
|
||||
}
|
||||
};
|
||||
|
||||
auto search = [ctx, searchEnded, w = weak_from_this()](bool previous) {
|
||||
auto search = [ctx, searchEnded, w = weak()](bool previous) {
|
||||
std::vector<uint8_t> key;
|
||||
dht::InfoHash loc;
|
||||
auto& s = previous ? ctx->dhtContext->stateOld : ctx->dhtContext->stateNew;
|
||||
@ -1310,8 +1299,7 @@ ArchiveAccountManager::loadFromDHT(const std::shared_ptr<AuthContext>& ctx)
|
||||
[ctx, decrypted = std::move(decrypted), w] {
|
||||
try {
|
||||
auto archive = AccountArchive(decrypted);
|
||||
if (auto sthis = std::static_pointer_cast<ArchiveAccountManager>(
|
||||
w.lock())) {
|
||||
if (auto sthis = w.lock()) {
|
||||
if (ctx->dhtContext) {
|
||||
ctx->dhtContext->dht.join();
|
||||
ctx->dhtContext.reset();
|
||||
@ -1705,13 +1693,13 @@ ArchiveAccountManager::revokeDevice(const std::string& device,
|
||||
password,
|
||||
device,
|
||||
cb,
|
||||
w = weak_from_this()](
|
||||
w = weak()](
|
||||
const std::shared_ptr<dht::crypto::Certificate>& crt) mutable {
|
||||
if (not crt) {
|
||||
cb(RevokeDeviceResult::ERROR_NETWORK);
|
||||
return;
|
||||
}
|
||||
auto this_ = std::static_pointer_cast<ArchiveAccountManager>(w.lock());
|
||||
auto this_ = w.lock();
|
||||
if (not this_)
|
||||
return;
|
||||
this_->info_->contacts->foundAccountDevice(crt);
|
||||
|
@ -87,14 +87,10 @@ public:
|
||||
const std::string& password);
|
||||
bool isPasswordValid(const std::string& password) override;
|
||||
|
||||
// link device: NEW: for authenticating exporting account to another device but can be used for
|
||||
// any sort of authentication in the future
|
||||
bool provideAccountAuthentication(const std::string& credentialsFromUser,
|
||||
const std::string& scheme);
|
||||
|
||||
#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& name,
|
||||
std::string_view scheme,
|
||||
const std::string& password,
|
||||
@ -138,7 +134,6 @@ private:
|
||||
struct DecodingContext;
|
||||
struct AuthMsg;
|
||||
struct DeviceAuthInfo;
|
||||
struct PayloadKey;
|
||||
std::shared_ptr<AuthContext> authCtx_;
|
||||
|
||||
void createAccount(AuthContext& ctx);
|
||||
|
Reference in New Issue
Block a user