Line data Source code
1 : /*
2 : * Copyright (C) 2004-2026 Savoir-faire Linux Inc.
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 : */
17 : #pragma once
18 :
19 : #include "account_manager.h"
20 : #include "jamidht/auth_channel_handler.h"
21 :
22 : #include <dhtnet/multiplexed_socket.h>
23 : #include <memory>
24 :
25 : namespace jami {
26 :
27 : // used for status codes on DeviceAuthStateChanged
28 : enum class DeviceAuthState : uint8_t {
29 : INIT = 0,
30 : TOKEN_AVAILABLE = 1,
31 : CONNECTING = 2,
32 : AUTHENTICATING = 3,
33 : IN_PROGRESS = 4,
34 : DONE = 5,
35 : };
36 :
37 : class ArchiveAccountManager : public AccountManager
38 : {
39 : public:
40 : using OnExportConfig = std::function<std::map<std::string, std::string>()>;
41 : using OnSyncData = std::function<void(DeviceSync&&)>;
42 :
43 793 : ArchiveAccountManager(const std::string& accountId,
44 : const std::filesystem::path& path,
45 : OnExportConfig&& onExportConfig,
46 : OnSyncData&& onSyncData,
47 : std::string archivePath,
48 : const std::string& nameServer)
49 793 : : AccountManager(accountId, path, nameServer)
50 793 : , onExportConfig_(std::move(onExportConfig))
51 793 : , onSyncData_(std::move(onSyncData))
52 1586 : , archivePath_(std::move(archivePath))
53 793 : {}
54 :
55 : struct ArchiveAccountCredentials : AccountCredentials
56 : {
57 : in_port_t dhtPort;
58 : std::vector<std::string> dhtBootstrap;
59 : dht::crypto::Identity updateIdentity;
60 : };
61 :
62 : void initAuthentication(std::string deviceName,
63 : std::unique_ptr<AccountCredentials> credentials,
64 : AuthSuccessCallback onSuccess,
65 : AuthFailureCallback onFailure,
66 : const OnChangeCallback& onChange) override;
67 :
68 : bool changePassword(const std::string& password_old, const std::string& password_new) override;
69 : virtual std::vector<uint8_t> getPasswordKey(const std::string& /*password*/) override;
70 :
71 : void syncDevices() override;
72 :
73 : int32_t addDevice(const std::string& uri, std::string_view auth_scheme, AuthChannelHandler*) override;
74 : bool cancelAddDevice(uint32_t token) override;
75 : bool confirmAddDevice(uint32_t token) override;
76 :
77 : bool revokeDevice(const std::string& device,
78 : std::string_view scheme,
79 : const std::string& password,
80 : RevokeDeviceCallback) override;
81 : bool exportArchive(const std::string& destinationPath, std::string_view scheme, const std::string& password);
82 : bool isPasswordValid(const std::string& password) override;
83 :
84 : bool provideAccountAuthentication(const std::string& credentialsFromUser, const std::string& scheme);
85 :
86 : void registerName(const std::string& name,
87 : std::string_view scheme,
88 : const std::string& password,
89 : RegistrationCallback cb) override;
90 :
91 : /**
92 : * Change the validity of a certificate. If hash is empty, update all certificates
93 : */
94 : bool setValidity(std::string_view scheme,
95 : const std::string& password,
96 : dht::crypto::Identity& device,
97 : const dht::InfoHash& id,
98 : int64_t validity);
99 :
100 : // for linking devices
101 : void onAuthReady(const std::string& deviceId, std::shared_ptr<dhtnet::ChannelSocket> channel);
102 :
103 : private:
104 : struct DeviceContextBase;
105 : struct AddDeviceContext;
106 : struct LinkDeviceContext;
107 : struct AuthContext
108 : {
109 : std::mutex mutex;
110 : std::string accountId;
111 : uint32_t token;
112 : PrivateKey key;
113 : CertRequest request;
114 : std::string deviceName;
115 : std::unique_ptr<ArchiveAccountCredentials> credentials;
116 : std::shared_ptr<LinkDeviceContext> linkDevCtx; // New device
117 : std::unique_ptr<AddDeviceContext> addDeviceCtx; // Source device
118 : AuthSuccessCallback onSuccess;
119 : AuthFailureCallback onFailure;
120 : std::unique_ptr<asio::steady_timer> timeout;
121 : bool canceled {false};
122 : };
123 : struct AuthMsg;
124 : struct DeviceAuthInfo;
125 : std::shared_ptr<AuthContext> authCtx_;
126 :
127 : void createAccount(AuthContext& ctx);
128 :
129 : std::pair<std::string, std::shared_ptr<dht::Value>> makeReceipt(const dht::crypto::Identity& id,
130 : const dht::crypto::Certificate& device,
131 : const std::string& ethAccount);
132 : void updateArchive(AccountArchive& content /*, const ContactList& syncData*/) const;
133 : void saveArchive(AccountArchive& content, std::string_view scheme, const std::string& pwd);
134 : AccountArchive readArchive(std::string_view scheme, const std::string& password) const;
135 : static std::pair<std::vector<uint8_t>, dht::InfoHash> computeKeys(const std::string& password,
136 : const std::string& pin,
137 : bool previous = false);
138 : bool updateCertificates(AccountArchive& archive, dht::crypto::Identity& device);
139 : static bool needsMigration(const std::string& accountId, const dht::crypto::Identity& id);
140 :
141 : void loadFromFile(AuthContext& ctx);
142 : void loadFromLocalArchive(AuthContext& ctx);
143 :
144 : // for linking devices
145 : void startLoadArchiveFromDevice(const std::shared_ptr<AuthContext>& ctx);
146 :
147 : bool doAddDevice(std::string_view scheme,
148 : const std::shared_ptr<AuthContext>& ctx,
149 : std::shared_ptr<dhtnet::ChannelSocket> channel);
150 :
151 : void onArchiveLoaded(AuthContext& ctx, AccountArchive&& a, bool isLinkDevProtocol);
152 :
153 797 : inline std::weak_ptr<ArchiveAccountManager> weak()
154 : {
155 797 : return std::static_pointer_cast<ArchiveAccountManager>(shared_from_this());
156 : }
157 :
158 : OnExportConfig onExportConfig_;
159 : OnSyncData onSyncData_;
160 : std::string archivePath_;
161 : };
162 :
163 : } // namespace jami
|