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 : #include "jamiaccount_config.h"
18 : #include "account_const.h"
19 : #include "account_schema.h"
20 : #include "configkeys.h"
21 : #include "fileutils.h"
22 : #include "config/account_config_utils.h"
23 :
24 : namespace jami {
25 :
26 : namespace Conf {
27 : constexpr const char* const TLS_KEY = "tls";
28 : constexpr const char* CERTIFICATE_KEY = "certificate";
29 : constexpr const char* CALIST_KEY = "calist";
30 : const char* const TLS_PASSWORD_KEY = "password";
31 : const char* const PRIVATE_KEY_KEY = "privateKey";
32 : } // namespace Conf
33 :
34 : static const JamiAccountConfig DEFAULT_CONFIG {};
35 :
36 : void
37 3358 : JamiAccountConfig::serialize(YAML::Emitter& out) const
38 : {
39 3358 : out << YAML::BeginMap;
40 3358 : SipAccountBaseConfig::serializeDiff(out, DEFAULT_CONFIG);
41 3358 : SERIALIZE_CONFIG(Conf::DHT_PORT_KEY, dhtPort);
42 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::DHT::PUBLIC_IN_CALLS, allowPublicIncoming);
43 3358 : SERIALIZE_CONFIG(Conf::DHT_ALLOW_PEERS_FROM_HISTORY, allowPeersFromHistory);
44 3358 : SERIALIZE_CONFIG(Conf::DHT_ALLOW_PEERS_FROM_CONTACT, allowPeersFromContact);
45 3358 : SERIALIZE_CONFIG(Conf::DHT_ALLOW_PEERS_FROM_TRUSTED, allowPeersFromTrusted);
46 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::DHT_PEER_DISCOVERY, dhtPeerDiscovery);
47 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::ACCOUNT_PEER_DISCOVERY, accountPeerDiscovery);
48 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::ACCOUNT_PUBLISH, accountPublish);
49 3358 : SERIALIZE_CONFIG(Conf::PROXY_ENABLED_KEY, proxyEnabled);
50 3358 : SERIALIZE_CONFIG(Conf::PROXY_SERVER_KEY, proxyServer);
51 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::PROXY_LIST_ENABLED, proxyListEnabled);
52 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::DHT_PROXY_LIST_URL, proxyListUrl);
53 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::DHT_PROXY_SERVER_ENABLED, dhtProxyServerEnabled);
54 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::DHT_PROXY_SERVER_PORT, dhtProxyServerPort);
55 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::Nameserver::URI, nameServer);
56 3358 : SERIALIZE_CONFIG(libjami::Account::VolatileProperties::REGISTERED_NAME, registeredName);
57 3358 : SERIALIZE_PATH(libjami::Account::ConfProperties::ARCHIVE_PATH, archivePath);
58 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::ARCHIVE_HAS_PASSWORD, archiveHasPassword);
59 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::DEVICE_NAME, deviceName);
60 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::MANAGER_URI, managerUri);
61 3358 : SERIALIZE_CONFIG(libjami::Account::ConfProperties::MANAGER_USERNAME, managerUsername);
62 :
63 3358 : out << YAML::Key << Conf::RING_ACCOUNT_RECEIPT << YAML::Value << receipt;
64 3358 : if (receiptSignature.size() > 0)
65 : out << YAML::Key << Conf::RING_ACCOUNT_RECEIPT_SIG << YAML::Value
66 1149 : << YAML::Binary(receiptSignature.data(), receiptSignature.size());
67 :
68 : // tls submap
69 3358 : out << YAML::Key << Conf::TLS_KEY << YAML::Value << YAML::BeginMap;
70 3358 : SERIALIZE_PATH(Conf::CALIST_KEY, tlsCaListFile);
71 3358 : SERIALIZE_PATH(Conf::CERTIFICATE_KEY, tlsCertificateFile);
72 3358 : SERIALIZE_CONFIG(Conf::TLS_PASSWORD_KEY, tlsPassword);
73 3358 : SERIALIZE_PATH(Conf::PRIVATE_KEY_KEY, tlsPrivateKeyFile);
74 3358 : out << YAML::EndMap;
75 :
76 3358 : out << YAML::EndMap;
77 3358 : }
78 :
79 : void
80 0 : JamiAccountConfig::unserialize(const YAML::Node& node)
81 : {
82 : using yaml_utils::parseValueOptional;
83 : using yaml_utils::parsePathOptional;
84 0 : SipAccountBaseConfig::unserialize(node);
85 :
86 : // get tls submap
87 : try {
88 0 : const auto& tlsMap = node[Conf::TLS_KEY];
89 0 : parsePathOptional(tlsMap, Conf::CERTIFICATE_KEY, tlsCertificateFile, path);
90 0 : parsePathOptional(tlsMap, Conf::CALIST_KEY, tlsCaListFile, path);
91 0 : parseValueOptional(tlsMap, Conf::TLS_PASSWORD_KEY, tlsPassword);
92 0 : parsePathOptional(tlsMap, Conf::PRIVATE_KEY_KEY, tlsPrivateKeyFile, path);
93 0 : } catch (...) {
94 0 : }
95 0 : parseValueOptional(node, Conf::DHT_PORT_KEY, dhtPort);
96 0 : parseValueOptional(node, Conf::DHT_ALLOW_PEERS_FROM_HISTORY, allowPeersFromHistory);
97 0 : parseValueOptional(node, Conf::DHT_ALLOW_PEERS_FROM_CONTACT, allowPeersFromContact);
98 0 : parseValueOptional(node, Conf::DHT_ALLOW_PEERS_FROM_TRUSTED, allowPeersFromTrusted);
99 :
100 0 : parseValueOptional(node, Conf::PROXY_ENABLED_KEY, proxyEnabled);
101 0 : parseValueOptional(node, Conf::PROXY_SERVER_KEY, proxyServer);
102 0 : parseValueOptional(node, libjami::Account::ConfProperties::DHT_PROXY_LIST_URL, proxyListUrl);
103 0 : parseValueOptional(node, libjami::Account::ConfProperties::PROXY_LIST_ENABLED, proxyListEnabled);
104 :
105 0 : parseValueOptional(node, libjami::Account::ConfProperties::DHT_PROXY_SERVER_ENABLED, dhtProxyServerEnabled);
106 0 : parseValueOptional(node, libjami::Account::ConfProperties::DHT_PROXY_SERVER_PORT, dhtProxyServerPort);
107 :
108 0 : parseValueOptional(node, libjami::Account::ConfProperties::DEVICE_NAME, deviceName);
109 0 : parseValueOptional(node, libjami::Account::ConfProperties::MANAGER_URI, managerUri);
110 0 : parseValueOptional(node, libjami::Account::ConfProperties::MANAGER_USERNAME, managerUsername);
111 :
112 0 : parsePathOptional(node, libjami::Account::ConfProperties::ARCHIVE_PATH, archivePath, path);
113 0 : parseValueOptional(node, libjami::Account::ConfProperties::ARCHIVE_HAS_PASSWORD, archiveHasPassword);
114 :
115 : try {
116 0 : parseValueOptional(node, Conf::RING_ACCOUNT_RECEIPT, receipt);
117 0 : auto receipt_sig = node[Conf::RING_ACCOUNT_RECEIPT_SIG].as<YAML::Binary>();
118 0 : receiptSignature = {receipt_sig.data(), receipt_sig.data() + receipt_sig.size()};
119 0 : } catch (const std::exception& e) {
120 0 : JAMI_WARNING("Unable to read receipt: {}", e.what());
121 0 : }
122 :
123 0 : parseValueOptional(node, libjami::Account::ConfProperties::DHT_PEER_DISCOVERY, dhtPeerDiscovery);
124 0 : parseValueOptional(node, libjami::Account::ConfProperties::ACCOUNT_PEER_DISCOVERY, accountPeerDiscovery);
125 0 : parseValueOptional(node, libjami::Account::ConfProperties::ACCOUNT_PUBLISH, accountPublish);
126 0 : parseValueOptional(node, libjami::Account::ConfProperties::Nameserver::URI, nameServer);
127 0 : parseValueOptional(node, libjami::Account::VolatileProperties::REGISTERED_NAME, registeredName);
128 : // Whether to accept incoming calls from unknown peers. Read the legacy YAML
129 : // key first, then the canonical one so the latter takes precedence when both
130 : // are present (migration from configs that stored both).
131 0 : parseValueOptional(node, Conf::DHT_PUBLIC_IN_CALLS, allowPublicIncoming);
132 0 : parseValueOptional(node, libjami::Account::ConfProperties::DHT::PUBLIC_IN_CALLS, allowPublicIncoming);
133 0 : }
134 :
135 : std::map<std::string, std::string>
136 705 : JamiAccountConfig::toMap() const
137 : {
138 705 : std::map<std::string, std::string> a = SipAccountBaseConfig::toMap();
139 705 : a.emplace(Conf::CONFIG_DHT_PORT, std::to_string(dhtPort));
140 705 : a.emplace(Conf::CONFIG_DHT_PUBLIC_IN_CALLS, allowPublicIncoming ? TRUE_STR : FALSE_STR);
141 705 : a.emplace(libjami::Account::ConfProperties::DHT_PEER_DISCOVERY, dhtPeerDiscovery ? TRUE_STR : FALSE_STR);
142 705 : a.emplace(libjami::Account::ConfProperties::ACCOUNT_PEER_DISCOVERY, accountPeerDiscovery ? TRUE_STR : FALSE_STR);
143 705 : a.emplace(libjami::Account::ConfProperties::ACCOUNT_PUBLISH, accountPublish ? TRUE_STR : FALSE_STR);
144 705 : a.emplace(libjami::Account::ConfProperties::DEVICE_NAME, deviceName);
145 705 : a.emplace(libjami::Account::ConfProperties::Presence::SUPPORT_SUBSCRIBE, TRUE_STR);
146 705 : if (not archivePath.empty() or not managerUri.empty())
147 705 : a.emplace(libjami::Account::ConfProperties::ARCHIVE_HAS_PASSWORD, archiveHasPassword ? TRUE_STR : FALSE_STR);
148 :
149 705 : a.emplace(Conf::CONFIG_TLS_CA_LIST_FILE, fileutils::getFullPath(path, tlsCaListFile).string());
150 705 : a.emplace(Conf::CONFIG_TLS_CERTIFICATE_FILE, fileutils::getFullPath(path, tlsCertificateFile).string());
151 705 : a.emplace(Conf::CONFIG_TLS_PRIVATE_KEY_FILE, fileutils::getFullPath(path, tlsPrivateKeyFile).string());
152 705 : a.emplace(Conf::CONFIG_TLS_PASSWORD, tlsPassword);
153 705 : a.emplace(libjami::Account::ConfProperties::ALLOW_CERT_FROM_HISTORY, allowPeersFromHistory ? TRUE_STR : FALSE_STR);
154 705 : a.emplace(libjami::Account::ConfProperties::ALLOW_CERT_FROM_CONTACT, allowPeersFromContact ? TRUE_STR : FALSE_STR);
155 : // Emit the trusted-peers flag under both the canonical DHT.AllowFromTrusted
156 : // key and the legacy Account.allowCertFromTrusted key for old-client compat.
157 705 : a.emplace(libjami::Account::ConfProperties::ALLOW_CERT_FROM_TRUSTED, allowPeersFromTrusted ? TRUE_STR : FALSE_STR);
158 705 : a.emplace(libjami::Account::ConfProperties::DHT::ALLOW_FROM_TRUSTED, allowPeersFromTrusted ? TRUE_STR : FALSE_STR);
159 705 : a.emplace(libjami::Account::ConfProperties::PROXY_ENABLED, proxyEnabled ? TRUE_STR : FALSE_STR);
160 705 : a.emplace(libjami::Account::ConfProperties::PROXY_LIST_ENABLED, proxyListEnabled ? TRUE_STR : FALSE_STR);
161 705 : a.emplace(libjami::Account::ConfProperties::PROXY_SERVER, proxyServer);
162 705 : a.emplace(libjami::Account::ConfProperties::DHT_PROXY_LIST_URL, proxyListUrl);
163 :
164 705 : a.emplace(libjami::Account::ConfProperties::DHT_PROXY_SERVER_ENABLED, dhtProxyServerEnabled ? TRUE_STR : FALSE_STR);
165 705 : a.emplace(libjami::Account::ConfProperties::DHT_PROXY_SERVER_PORT, std::to_string(dhtProxyServerPort));
166 :
167 705 : a.emplace(libjami::Account::ConfProperties::MANAGER_URI, managerUri);
168 705 : a.emplace(libjami::Account::ConfProperties::MANAGER_USERNAME, managerUsername);
169 705 : a.emplace(libjami::Account::ConfProperties::Nameserver::URI, nameServer);
170 705 : return a;
171 0 : }
172 :
173 : void
174 2046 : JamiAccountConfig::fromMap(const std::map<std::string, std::string>& details)
175 : {
176 2046 : SipAccountBaseConfig::fromMap(details);
177 : // TLS
178 2046 : parsePath(details, Conf::CONFIG_TLS_CA_LIST_FILE, tlsCaListFile, path);
179 2046 : parsePath(details, Conf::CONFIG_TLS_CERTIFICATE_FILE, tlsCertificateFile, path);
180 2046 : parsePath(details, Conf::CONFIG_TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile, path);
181 2046 : parseString(details, Conf::CONFIG_TLS_PASSWORD, tlsPassword);
182 :
183 2046 : if (hostname.empty())
184 0 : hostname = DHT_DEFAULT_BOOTSTRAP;
185 2046 : parseString(details, libjami::Account::ConfProperties::BOOTSTRAP_LIST_URL, bootstrapListUrl);
186 2046 : parseInt(details, Conf::CONFIG_DHT_PORT, dhtPort);
187 2046 : parseBool(details, Conf::CONFIG_DHT_PUBLIC_IN_CALLS, allowPublicIncoming);
188 2046 : parseBool(details, libjami::Account::ConfProperties::DHT_PEER_DISCOVERY, dhtPeerDiscovery);
189 2046 : parseBool(details, libjami::Account::ConfProperties::ACCOUNT_PEER_DISCOVERY, accountPeerDiscovery);
190 2046 : parseBool(details, libjami::Account::ConfProperties::ACCOUNT_PUBLISH, accountPublish);
191 2046 : parseBool(details, libjami::Account::ConfProperties::ALLOW_CERT_FROM_HISTORY, allowPeersFromHistory);
192 2046 : parseBool(details, libjami::Account::ConfProperties::ALLOW_CERT_FROM_CONTACT, allowPeersFromContact);
193 : // DHT.AllowFromTrusted is the canonical key; parse the legacy
194 : // Account.allowCertFromTrusted first so the canonical one wins when present.
195 2046 : parseBool(details, libjami::Account::ConfProperties::ALLOW_CERT_FROM_TRUSTED, allowPeersFromTrusted);
196 2046 : parseBool(details, libjami::Account::ConfProperties::DHT::ALLOW_FROM_TRUSTED, allowPeersFromTrusted);
197 :
198 2046 : parseString(details, libjami::Account::ConfProperties::MANAGER_URI, managerUri);
199 2046 : parseString(details, libjami::Account::ConfProperties::MANAGER_USERNAME, managerUsername);
200 : // parseString(details, libjami::Account::ConfProperties::USERNAME, username);
201 :
202 2046 : parseString(details, libjami::Account::ConfProperties::ARCHIVE_PASSWORD, credentials.archive_password);
203 2046 : parseString(details, libjami::Account::ConfProperties::ARCHIVE_PASSWORD_SCHEME, credentials.archive_password_scheme);
204 2046 : parseString(details, libjami::Account::ConfProperties::ARCHIVE_PATH, credentials.archive_path);
205 2046 : parseString(details, libjami::Account::ConfProperties::DEVICE_NAME, deviceName);
206 2046 : parseString(details, libjami::Account::ConfProperties::ARCHIVE_URL, archive_url);
207 :
208 2046 : auto oldProxyServer = proxyServer, oldProxyServerList = proxyListUrl;
209 2046 : parseString(details, libjami::Account::ConfProperties::DHT_PROXY_LIST_URL, proxyListUrl);
210 2046 : parseBool(details, libjami::Account::ConfProperties::PROXY_ENABLED, proxyEnabled);
211 2046 : parseBool(details, libjami::Account::ConfProperties::PROXY_LIST_ENABLED, proxyListEnabled);
212 2046 : parseString(details, libjami::Account::ConfProperties::PROXY_SERVER, proxyServer);
213 :
214 2046 : parseBool(details, libjami::Account::ConfProperties::DHT_PROXY_SERVER_ENABLED, dhtProxyServerEnabled);
215 2046 : parseInt(details, libjami::Account::ConfProperties::DHT_PROXY_SERVER_PORT, dhtProxyServerPort);
216 :
217 2046 : parseString(details, libjami::Account::ConfProperties::UI_CUSTOMIZATION, uiCustomization);
218 2046 : if (not managerUri.empty() and managerUri.rfind("http", 0) != 0) {
219 0 : managerUri = "https://" + managerUri;
220 : }
221 :
222 2046 : parseString(details, libjami::Account::ConfProperties::Nameserver::URI, nameServer);
223 2046 : }
224 :
225 : } // namespace jami
|