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 792 : 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 792 : : AccountManager(accountId, path, nameServer)
50 792 : , onExportConfig_(std::move(onExportConfig))
51 792 : , onSyncData_(std::move(onSyncData))
52 1584 : , archivePath_(std::move(archivePath))
53 792 : {}
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(PrivateKey request,
63 : std::string deviceName,
64 : std::unique_ptr<AccountCredentials> credentials,
65 : AuthSuccessCallback onSuccess,
66 : AuthFailureCallback onFailure,
67 : const OnChangeCallback& onChange) override;
68 :
69 : bool changePassword(const std::string& password_old, const std::string& password_new) override;
70 : virtual std::vector<uint8_t> getPasswordKey(const std::string& /*password*/) override;
71 :
72 : void syncDevices() override;
73 :
74 : int32_t addDevice(const std::string& uri, std::string_view auth_scheme, AuthChannelHandler*) override;
75 : bool cancelAddDevice(uint32_t token) override;
76 : bool confirmAddDevice(uint32_t token) override;
77 :
78 : bool revokeDevice(const std::string& device,
79 : std::string_view scheme,
80 : const std::string& password,
81 : RevokeDeviceCallback) override;
82 : bool exportArchive(const std::string& destinationPath, std::string_view scheme, const std::string& password);
83 : bool isPasswordValid(const std::string& password) override;
84 :
85 : bool provideAccountAuthentication(const std::string& credentialsFromUser, const std::string& scheme);
86 :
87 : void registerName(const std::string& name,
88 : std::string_view scheme,
89 : const std::string& password,
90 : RegistrationCallback cb) override;
91 :
92 : /**
93 : * Change the validity of a certificate. If hash is empty, update all certificates
94 : */
95 : bool setValidity(std::string_view scheme,
96 : const std::string& password,
97 : dht::crypto::Identity& device,
98 : const dht::InfoHash& id,
99 : int64_t validity);
100 :
101 : // for linking devices
102 : void onAuthReady(const std::string& deviceId, std::shared_ptr<dhtnet::ChannelSocket> channel);
103 :
104 : private:
105 : struct DeviceContextBase;
106 : struct AddDeviceContext;
107 : struct LinkDeviceContext;
108 : struct AuthContext
109 : {
110 : std::mutex mutex;
111 : std::string accountId;
112 : uint32_t token;
113 : PrivateKey key;
114 : CertRequest request;
115 : std::string deviceName;
116 : std::unique_ptr<ArchiveAccountCredentials> credentials;
117 : std::shared_ptr<LinkDeviceContext> linkDevCtx; // New device
118 : std::unique_ptr<AddDeviceContext> addDeviceCtx; // Source device
119 : AuthSuccessCallback onSuccess;
120 : AuthFailureCallback onFailure;
121 : std::unique_ptr<asio::steady_timer> timeout;
122 : bool canceled {false};
123 : };
124 : struct AuthMsg;
125 : struct DeviceAuthInfo;
126 : std::shared_ptr<AuthContext> authCtx_;
127 :
128 : void createAccount(AuthContext& ctx);
129 : void migrateAccount(AuthContext& ctx);
130 :
131 : std::pair<std::string, std::shared_ptr<dht::Value>> makeReceipt(const dht::crypto::Identity& id,
132 : const dht::crypto::Certificate& device,
133 : const std::string& ethAccount);
134 : void updateArchive(AccountArchive& content /*, const ContactList& syncData*/) const;
135 : void saveArchive(AccountArchive& content, std::string_view scheme, const std::string& pwd);
136 : AccountArchive readArchive(std::string_view scheme, const std::string& password) const;
137 : static std::pair<std::vector<uint8_t>, dht::InfoHash> computeKeys(const std::string& password,
138 : const std::string& pin,
139 : bool previous = false);
140 : bool updateCertificates(AccountArchive& archive, dht::crypto::Identity& device);
141 : static bool needsMigration(const std::string& accountId, const dht::crypto::Identity& id);
142 :
143 : void loadFromFile(AuthContext& ctx);
144 :
145 : // for linking devices
146 : void startLoadArchiveFromDevice(const std::shared_ptr<AuthContext>& ctx);
147 :
148 : bool doAddDevice(std::string_view scheme,
149 : const std::shared_ptr<AuthContext>& ctx,
150 : std::shared_ptr<dhtnet::ChannelSocket> channel);
151 :
152 : void onArchiveLoaded(AuthContext& ctx, AccountArchive&& a, bool isLinkDevProtocol);
153 :
154 784 : inline std::weak_ptr<ArchiveAccountManager> weak()
155 : {
156 784 : return std::static_pointer_cast<ArchiveAccountManager>(shared_from_this());
157 : }
158 :
159 : OnExportConfig onExportConfig_;
160 : OnSyncData onSyncData_;
161 : std::string archivePath_;
162 : };
163 :
164 : } // namespace jami
|