Ring Daemon
Loading...
Searching...
No Matches
sipaccount_config.cpp
Go to the documentation of this file.
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 "sipaccount_config.h"
18#include "account_schema.h"
19#include "config/yamlparser.h"
20
21extern "C" {
22#include <pjlib-util/md5.h>
23
24#include <cstddef>
25}
26
27namespace jami {
28
29namespace Conf {
30constexpr const char* ID_KEY = "id";
31constexpr const char* USERNAME_KEY = "username";
32constexpr const char* BIND_ADDRESS_KEY = "bindAddress";
33constexpr const char* PORT_KEY = "port";
34constexpr const char* PUBLISH_PORT_KEY = "publishPort";
35constexpr const char* SERVICE_ROUTE_KEY = "serviceRoute";
36constexpr const char* ALLOW_IP_AUTO_REWRITE = "allowIPAutoRewrite";
37constexpr const char* PRESENCE_PUBLISH_SUPPORTED_KEY = "presencePublishSupported";
38constexpr const char* PRESENCE_SUBSCRIBE_SUPPORTED_KEY = "presenceSubscribeSupported";
39constexpr const char* PRESENCE_MODULE_ENABLED_KEY = "presenceModuleEnabled";
40constexpr const char* KEEP_ALIVE_ENABLED = "keepAliveEnabled";
41
42constexpr const char* const TLS_KEY = "tls";
43constexpr const char* CERTIFICATE_KEY = "certificate";
44constexpr const char* CALIST_KEY = "calist";
45constexpr const char* TLS_PORT_KEY = "tlsPort";
46constexpr const char* CIPHERS_KEY = "ciphers";
47constexpr const char* TLS_ENABLE_KEY = "enable";
48constexpr const char* METHOD_KEY = "method";
49constexpr const char* TIMEOUT_KEY = "timeout";
50constexpr const char* TLS_PASSWORD_KEY = "password";
51constexpr const char* PRIVATE_KEY_KEY = "privateKey";
52constexpr const char* REQUIRE_CERTIF_KEY = "requireCertif";
53constexpr const char* SERVER_KEY = "server";
54constexpr const char* VERIFY_CLIENT_KEY = "verifyClient";
55constexpr const char* VERIFY_SERVER_KEY = "verifyServer";
56constexpr const char* DISABLE_SECURE_DLG_CHECK = "disableSecureDlgCheck";
57
58constexpr const char* STUN_ENABLED_KEY = "stunEnabled";
59constexpr const char* STUN_SERVER_KEY = "stunServer";
60constexpr const char* CRED_KEY = "credential";
61constexpr const char* SRTP_KEY = "srtp";
62constexpr const char* KEY_EXCHANGE_KEY = "keyExchange";
63} // namespace Conf
64
66static constexpr unsigned MIN_REGISTRATION_TIME = 60; // seconds
67
70
71void
72SipAccountConfig::serialize(YAML::Emitter& out) const
73{
74 out << YAML::BeginMap;
75 out << YAML::Key << Conf::ID_KEY << YAML::Value << id;
77
78 out << YAML::Key << Conf::BIND_ADDRESS_KEY << YAML::Value << bindAddress;
79 out << YAML::Key << Conf::PORT_KEY << YAML::Value << localPort;
80 out << YAML::Key << Conf::PUBLISH_PORT_KEY << YAML::Value << publishedPort;
81
82 out << YAML::Key << Conf::USERNAME_KEY << YAML::Value << username;
83
84 // each credential is a map, and we can have multiple credentials
85 out << YAML::Key << Conf::CRED_KEY << YAML::Value << getCredentials();
86
87 out << YAML::Key << Conf::KEEP_ALIVE_ENABLED << YAML::Value << registrationRefreshEnabled;
88
89 // out << YAML::Key << PRESENCE_MODULE_ENABLED_KEY << YAML::Value
90 // << (presence_ and presence_->isEnabled());
91
92 out << YAML::Key << Conf::CONFIG_ACCOUNT_REGISTRATION_EXPIRE << YAML::Value << registrationExpire;
93 out << YAML::Key << Conf::SERVICE_ROUTE_KEY << YAML::Value << serviceRoute;
94 out << YAML::Key << Conf::ALLOW_IP_AUTO_REWRITE << YAML::Value << allowIPAutoRewrite;
95 out << YAML::Key << Conf::STUN_ENABLED_KEY << YAML::Value << stunEnabled;
96 out << YAML::Key << Conf::STUN_SERVER_KEY << YAML::Value << stunServer;
97
98 // tls submap
99 out << YAML::Key << Conf::TLS_KEY << YAML::Value << YAML::BeginMap;
100 out << YAML::Key << Conf::CALIST_KEY << YAML::Value << tlsCaListFile;
101 out << YAML::Key << Conf::CERTIFICATE_KEY << YAML::Value << tlsCertificateFile;
102 out << YAML::Key << Conf::TLS_PASSWORD_KEY << YAML::Value << tlsPassword;
103 out << YAML::Key << Conf::PRIVATE_KEY_KEY << YAML::Value << tlsPrivateKeyFile;
104 out << YAML::Key << Conf::TLS_ENABLE_KEY << YAML::Value << tlsEnable;
105 out << YAML::Key << Conf::TLS_PORT_KEY << YAML::Value << tlsListenerPort;
106 out << YAML::Key << Conf::VERIFY_CLIENT_KEY << YAML::Value << tlsVerifyClient;
107 out << YAML::Key << Conf::VERIFY_SERVER_KEY << YAML::Value << tlsVerifyServer;
108 out << YAML::Key << Conf::REQUIRE_CERTIF_KEY << YAML::Value << tlsRequireClientCertificate;
109 out << YAML::Key << Conf::DISABLE_SECURE_DLG_CHECK << YAML::Value << tlsDisableSecureDlgCheck;
110 out << YAML::Key << Conf::TIMEOUT_KEY << YAML::Value << tlsNegotiationTimeout;
111 out << YAML::Key << Conf::CIPHERS_KEY << YAML::Value << tlsCiphers;
112 out << YAML::Key << Conf::METHOD_KEY << YAML::Value << tlsMethod;
113 out << YAML::Key << Conf::SERVER_KEY << YAML::Value << tlsServerName;
114 out << YAML::EndMap;
115
116 // srtp submap
117 out << YAML::Key << Conf::SRTP_KEY << YAML::Value << YAML::BeginMap;
119 out << YAML::EndMap;
120
121 out << YAML::EndMap;
122}
123
124void
125SipAccountConfig::unserialize(const YAML::Node& node)
126{
128 parseValueOptional(node, Conf::USERNAME_KEY, username);
129 parseValueOptional(node, Conf::BIND_ADDRESS_KEY, bindAddress);
130 parseValueOptional(node, Conf::PORT_KEY, localPort);
131 parseValueOptional(node, Conf::PUBLISH_PORT_KEY, publishedPort);
134 parseValueOptional(node, Conf::KEEP_ALIVE_ENABLED, registrationRefreshEnabled);
135 parseValueOptional(node, Conf::SERVICE_ROUTE_KEY, serviceRoute);
136 parseValueOptional(node, Conf::ALLOW_IP_AUTO_REWRITE, allowIPAutoRewrite);
137
138 parseValueOptional(node, Conf::PRESENCE_MODULE_ENABLED_KEY, presenceEnabled);
141
142 // ICE - STUN/TURN
143 parseValueOptional(node, Conf::STUN_ENABLED_KEY, stunEnabled);
144 parseValueOptional(node, Conf::STUN_SERVER_KEY, stunServer);
145
146 const auto& credsNode = node[Conf::CRED_KEY];
148 parseVectorMap(credsNode,
150
151 // get tls submap
152 try {
153 const auto& tlsMap = node[Conf::TLS_KEY];
154 parseValueOptional(tlsMap, Conf::CERTIFICATE_KEY, tlsCertificateFile);
155 parseValueOptional(tlsMap, Conf::CALIST_KEY, tlsCaListFile);
156 parseValueOptional(tlsMap, Conf::TLS_PASSWORD_KEY, tlsPassword);
157 parseValueOptional(tlsMap, Conf::PRIVATE_KEY_KEY, tlsPrivateKeyFile);
158 parseValueOptional(tlsMap, Conf::TLS_ENABLE_KEY, tlsEnable);
159 parseValueOptional(tlsMap, Conf::TLS_PORT_KEY, tlsListenerPort);
160 parseValueOptional(tlsMap, Conf::CIPHERS_KEY, tlsCiphers);
161 parseValueOptional(tlsMap, Conf::METHOD_KEY, tlsMethod);
162 parseValueOptional(tlsMap, Conf::SERVER_KEY, tlsServerName);
164 parseValueOptional(tlsMap, Conf::VERIFY_CLIENT_KEY, tlsVerifyClient);
165 parseValueOptional(tlsMap, Conf::VERIFY_SERVER_KEY, tlsVerifyServer);
167 parseValueOptional(tlsMap, Conf::TIMEOUT_KEY, tlsNegotiationTimeout);
168 } catch (const std::exception& e) {
169 JAMI_WARNING("Couldn't parse TLS map: {}", e.what());
170 }
171
172 // get srtp submap
173 const auto& srtpMap = node[Conf::SRTP_KEY];
174 std::string tmpKey;
175 parseValueOptional(srtpMap, Conf::KEY_EXCHANGE_KEY, tmpKey);
177}
178
179std::map<std::string, std::string>
181{
183 // general sip settings
185 a.emplace(Conf::CONFIG_LOCAL_PORT, std::to_string(localPort));
188 a.emplace(Conf::CONFIG_PUBLISHED_PORT, std::to_string(publishedPort));
199
200 std::string password {};
201 if (not credentials.empty()) {
202 for (const auto& cred : credentials)
203 if (cred.username == username) {
204 password = cred.password;
205 break;
206 }
207 }
208 a.emplace(Conf::CONFIG_ACCOUNT_PASSWORD, std::move(password));
209
210 // srtp settings
213 a.emplace(Conf::CONFIG_TLS_LISTENER_PORT, std::to_string(tlsListenerPort));
226 return a;
227}
228
229void
230SipAccountConfig::fromMap(const std::map<std::string, std::string>& details)
231{
233
234 // general sip settings
248
249 // srtp settings
251 if (iter != details.end())
253
254 if (credentials.empty()) { // credentials not set, construct 1 entry
255 JAMI_WARN("No credentials set, inferring them...");
256 std::map<std::string, std::string> map;
260 setCredentials({map});
261 }
262
263 // ICE - STUN
266
267 // TLS
282}
283
284SipAccountConfig::Credentials::Credentials(const std::map<std::string, std::string>& cred)
285{
289 realm = itrealm != cred.end() ? itrealm->second : "";
290 username = user != cred.end() ? user->second : "";
291 password = passw != cred.end() ? passw->second : "";
293}
294
295std::map<std::string, std::string>
302
303void
305{
307
308 /* Compute md5 hash = MD5(username ":" realm ":" password) */
310 pj_md5_update(&pms, (const uint8_t*) username.data(), username.length());
311 pj_md5_update(&pms, (const uint8_t*) ":", 1);
312 pj_md5_update(&pms, (const uint8_t*) realm.data(), realm.length());
313 pj_md5_update(&pms, (const uint8_t*) ":", 1);
314 pj_md5_update(&pms, (const uint8_t*) password.data(), password.length());
315
316 unsigned char digest[16];
318
319 char hash[32];
320
321 for (int i = 0; i < 16; ++i)
322 pj_val_to_hex_digit(digest[i], &hash[static_cast<ptrdiff_t>(2 * i)]);
323
324 password_h = {hash, 32};
325}
326
327std::vector<std::map<std::string, std::string>>
329{
330 std::vector<std::map<std::string, std::string>> ret;
331 ret.reserve(credentials.size());
332 for (const auto& c : credentials) {
333 ret.emplace_back(c.toMap());
334 }
335 return ret;
336}
337
338void
339SipAccountConfig::setCredentials(const std::vector<std::map<std::string, std::string>>& creds)
340{
341 credentials.clear();
342 credentials.reserve(creds.size());
343 for (const auto& cred : creds)
344 credentials.emplace_back(cred);
345}
346
347} // namespace jami
Account specific keys/constants that must be shared in daemon and clients.
#define JAMI_WARN(...)
Definition logger.h:229
#define JAMI_WARNING(formatstr,...)
Definition logger.h:242
constexpr const char * CALIST_KEY
static const char *const CONFIG_SRTP_KEY_EXCHANGE
constexpr const char * STUN_ENABLED_KEY
static const char *const CONFIG_ACCOUNT_USERNAME
const char *const TLS_PASSWORD_KEY
static const char *const CONFIG_ACCOUNT_REALM
static const char *const CONFIG_TLS_VERIFY_CLIENT
static const char *const CONFIG_ACCOUNT_IP_AUTO_REWRITE
constexpr const char * BIND_ADDRESS_KEY
static const char *const CONFIG_PUBLISHED_SAMEAS_LOCAL
static const char *const CONFIG_PRESENCE_ENABLED
static const char *const CONFIG_TLS_DISABLE_SECURE_DLG_CHECK
constexpr const char * CIPHERS_KEY
constexpr const char * PRESENCE_PUBLISH_SUPPORTED_KEY
static const char *const CONFIG_TLS_CIPHERS
constexpr const char * DISABLE_SECURE_DLG_CHECK
constexpr const char * CRED_KEY
static const char *const CONFIG_TLS_SERVER_NAME
static const char *const CONFIG_PUBLISHED_ADDRESS
static const char *const CONFIG_STUN_SERVER
constexpr const char * REQUIRE_CERTIF_KEY
constexpr const char * PUBLISH_PORT_KEY
constexpr const char * VERIFY_SERVER_KEY
static const char *const CONFIG_TLS_ENABLE
constexpr const char * KEEP_ALIVE_ENABLED
constexpr const char * TIMEOUT_KEY
static const char *const CONFIG_TLS_CERTIFICATE_FILE
static const char *const CONFIG_STUN_ENABLE
constexpr const char *const TLS_KEY
static const char *const CONFIG_TLS_PASSWORD
constexpr const char * METHOD_KEY
constexpr const char * ID_KEY
static const char *const CONFIG_TLS_PRIVATE_KEY_FILE
constexpr const char * PORT_KEY
static const char *const CONFIG_TLS_LISTENER_PORT
const char *const PRIVATE_KEY_KEY
constexpr const char * PRESENCE_MODULE_ENABLED_KEY
constexpr const char * TLS_ENABLE_KEY
static const char *const CONFIG_KEEP_ALIVE_ENABLED
static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC
static const char *const CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE
static const char *const CONFIG_ACCOUNT_DTMF_TYPE
constexpr const char * VERIFY_CLIENT_KEY
constexpr const char * CERTIFICATE_KEY
constexpr const char * PRESENCE_SUBSCRIBE_SUPPORTED_KEY
static const char *const CONFIG_TLS_VERIFY_SERVER
constexpr const char * USERNAME_KEY
constexpr const char * TLS_PORT_KEY
static const char *const CONFIG_TLS_CA_LIST_FILE
constexpr const char * KEY_EXCHANGE_KEY
static const char *const CONFIG_LOCAL_PORT
constexpr const char * SERVER_KEY
static const char *const CONFIG_ACCOUNT_PASSWORD
constexpr const char * SERVICE_ROUTE_KEY
constexpr const char * STUN_SERVER_KEY
static const char *const CONFIG_BIND_ADDRESS
static const char *const CONFIG_PUBLISHED_PORT
static const char *const CONFIG_ACCOUNT_ROUTESET
static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE
constexpr const char * SRTP_KEY
constexpr const char * ALLOW_IP_AUTO_REWRITE
static const char *const CONFIG_TLS_METHOD
static const char *const CONFIG_LOCAL_INTERFACE
static KeyExchangeProtocol getKeyExchangeProtocol(std::string_view name)
Definition sip_utils.h:117
static constexpr const char * getKeyExchangeName(KeyExchangeProtocol kx)
Definition sip_utils.h:111
std::vector< std::map< std::string, std::string > > parseVectorMap(const YAML::Node &node, const std::initializer_list< std::string > &keys)
bool parseValueOptional(const YAML::Node &node, const char *key, T &value)
Definition yamlparser.h:38
void parseBool(const std::map< std::string, std::string > &details, const char *key, bool &s)
static constexpr const char TRUE_STR[]
void emitSignal(Args... args)
Definition jami_signal.h:64
void parseInt(const std::map< std::string, std::string > &details, const char *key, T &s)
static constexpr const char FALSE_STR[]
void parseString(const std::map< std::string, std::string > &details, const char *key, std::string &s)
void parsePath(const std::map< std::string, std::string > &details, const char *key, std::string &s, const std::filesystem::path &base)
static const JamiAccountConfig DEFAULT_CONFIG
static constexpr unsigned MIN_REGISTRATION_TIME
const std::filesystem::path path
Path where the configuration file is stored.
const std::string id
Account id.
bool publishedSameasLocal
Flag which determine if localIpAddress_ or publishedIpAddress_ is used in sip headers.
void fromMap(const std::map< std::string, std::string > &) override
void serializeDiff(YAML::Emitter &out, const SipAccountBaseConfig &def) const
void unserialize(const YAML::Node &node) override
std::map< std::string, std::string > toMap() const override
Credentials(const std::string &r, const std::string &u, const std::string &p)
std::map< std::string, std::string > toMap() const
uint16_t publishedPort
Published port, used only if defined by the user.
std::string stunServer
The STUN server hostname (optional), used to provide the public IP address in case the softphone stay...
void unserialize(const YAML::Node &node) override
std::vector< std::map< std::string, std::string > > getCredentials() const
std::string interface
interface name on which this account is bound
bool stunEnabled
Determine if STUN public address resolution is required to register this account.
uint16_t localPort
Local port to whih this account is bound.
unsigned registrationExpire
Network settings.
std::map< std::string, std::string > toMap() const override
uint16_t tlsListenerPort
The TLS listener port.
void setCredentials(const std::vector< std::map< std::string, std::string > > &creds)
void serialize(YAML::Emitter &out) const override
std::string serviceRoute
Input Outbound Proxy Server Address.
std::vector< Credentials > credentials
KeyExchangeProtocol srtpKeyExchange
Specifies the type of key exchange used for SRTP, if any.
std::string bindAddress
Potential ip addresss on which this account is bound.
void fromMap(const std::map< std::string, std::string > &) override