LCOV - code coverage report
Current view: top level - foo/src/sip - sipaccount_config.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 157 200 78.5 %
Date: 2026-04-01 09:29:43 Functions: 8 11 72.7 %

          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 "sipaccount_config.h"
      18             : #include "account_schema.h"
      19             : #include "config/yamlparser.h"
      20             : 
      21             : extern "C" {
      22             : #include <pjlib-util/md5.h>
      23             : 
      24             : #include <cstddef>
      25             : }
      26             : 
      27             : namespace jami {
      28             : 
      29             : namespace Conf {
      30             : constexpr const char* ID_KEY = "id";
      31             : constexpr const char* USERNAME_KEY = "username";
      32             : constexpr const char* BIND_ADDRESS_KEY = "bindAddress";
      33             : constexpr const char* PORT_KEY = "port";
      34             : constexpr const char* PUBLISH_PORT_KEY = "publishPort";
      35             : constexpr const char* SERVICE_ROUTE_KEY = "serviceRoute";
      36             : constexpr const char* ALLOW_IP_AUTO_REWRITE = "allowIPAutoRewrite";
      37             : constexpr const char* PRESENCE_PUBLISH_SUPPORTED_KEY = "presencePublishSupported";
      38             : constexpr const char* PRESENCE_SUBSCRIBE_SUPPORTED_KEY = "presenceSubscribeSupported";
      39             : constexpr const char* PRESENCE_MODULE_ENABLED_KEY = "presenceModuleEnabled";
      40             : constexpr const char* KEEP_ALIVE_ENABLED = "keepAliveEnabled";
      41             : 
      42             : constexpr const char* const TLS_KEY = "tls";
      43             : constexpr const char* CERTIFICATE_KEY = "certificate";
      44             : constexpr const char* CALIST_KEY = "calist";
      45             : constexpr const char* TLS_PORT_KEY = "tlsPort";
      46             : constexpr const char* CIPHERS_KEY = "ciphers";
      47             : constexpr const char* TLS_ENABLE_KEY = "enable";
      48             : constexpr const char* METHOD_KEY = "method";
      49             : constexpr const char* TIMEOUT_KEY = "timeout";
      50             : constexpr const char* TLS_PASSWORD_KEY = "password";
      51             : constexpr const char* PRIVATE_KEY_KEY = "privateKey";
      52             : constexpr const char* REQUIRE_CERTIF_KEY = "requireCertif";
      53             : constexpr const char* SERVER_KEY = "server";
      54             : constexpr const char* VERIFY_CLIENT_KEY = "verifyClient";
      55             : constexpr const char* VERIFY_SERVER_KEY = "verifyServer";
      56             : constexpr const char* DISABLE_SECURE_DLG_CHECK = "disableSecureDlgCheck";
      57             : 
      58             : constexpr const char* STUN_ENABLED_KEY = "stunEnabled";
      59             : constexpr const char* STUN_SERVER_KEY = "stunServer";
      60             : constexpr const char* CRED_KEY = "credential";
      61             : constexpr const char* SRTP_KEY = "srtp";
      62             : constexpr const char* KEY_EXCHANGE_KEY = "keyExchange";
      63             : } // namespace Conf
      64             : 
      65             : static const SipAccountConfig DEFAULT_CONFIG {};
      66             : static constexpr unsigned MIN_REGISTRATION_TIME = 60; // seconds
      67             : 
      68             : using yaml_utils::parseValueOptional;
      69             : using yaml_utils::parseVectorMap;
      70             : 
      71             : void
      72         181 : SipAccountConfig::serialize(YAML::Emitter& out) const
      73             : {
      74         181 :     out << YAML::BeginMap;
      75         181 :     out << YAML::Key << Conf::ID_KEY << YAML::Value << id;
      76         181 :     SipAccountBaseConfig::serializeDiff(out, DEFAULT_CONFIG);
      77             : 
      78         181 :     out << YAML::Key << Conf::BIND_ADDRESS_KEY << YAML::Value << bindAddress;
      79         181 :     out << YAML::Key << Conf::PORT_KEY << YAML::Value << localPort;
      80         181 :     out << YAML::Key << Conf::PUBLISH_PORT_KEY << YAML::Value << publishedPort;
      81             : 
      82         181 :     out << YAML::Key << Conf::USERNAME_KEY << YAML::Value << username;
      83             : 
      84             :     // each credential is a map, and we can have multiple credentials
      85         181 :     out << YAML::Key << Conf::CRED_KEY << YAML::Value << getCredentials();
      86             : 
      87         181 :     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         181 :     out << YAML::Key << Conf::CONFIG_ACCOUNT_REGISTRATION_EXPIRE << YAML::Value << registrationExpire;
      93         181 :     out << YAML::Key << Conf::SERVICE_ROUTE_KEY << YAML::Value << serviceRoute;
      94         181 :     out << YAML::Key << Conf::ALLOW_IP_AUTO_REWRITE << YAML::Value << allowIPAutoRewrite;
      95         181 :     out << YAML::Key << Conf::STUN_ENABLED_KEY << YAML::Value << stunEnabled;
      96         181 :     out << YAML::Key << Conf::STUN_SERVER_KEY << YAML::Value << stunServer;
      97             : 
      98             :     // tls submap
      99         181 :     out << YAML::Key << Conf::TLS_KEY << YAML::Value << YAML::BeginMap;
     100         181 :     out << YAML::Key << Conf::CALIST_KEY << YAML::Value << tlsCaListFile;
     101         181 :     out << YAML::Key << Conf::CERTIFICATE_KEY << YAML::Value << tlsCertificateFile;
     102         181 :     out << YAML::Key << Conf::TLS_PASSWORD_KEY << YAML::Value << tlsPassword;
     103         181 :     out << YAML::Key << Conf::PRIVATE_KEY_KEY << YAML::Value << tlsPrivateKeyFile;
     104         181 :     out << YAML::Key << Conf::TLS_ENABLE_KEY << YAML::Value << tlsEnable;
     105         181 :     out << YAML::Key << Conf::TLS_PORT_KEY << YAML::Value << tlsListenerPort;
     106         181 :     out << YAML::Key << Conf::VERIFY_CLIENT_KEY << YAML::Value << tlsVerifyClient;
     107         181 :     out << YAML::Key << Conf::VERIFY_SERVER_KEY << YAML::Value << tlsVerifyServer;
     108         181 :     out << YAML::Key << Conf::REQUIRE_CERTIF_KEY << YAML::Value << tlsRequireClientCertificate;
     109         181 :     out << YAML::Key << Conf::DISABLE_SECURE_DLG_CHECK << YAML::Value << tlsDisableSecureDlgCheck;
     110         181 :     out << YAML::Key << Conf::TIMEOUT_KEY << YAML::Value << tlsNegotiationTimeout;
     111         181 :     out << YAML::Key << Conf::CIPHERS_KEY << YAML::Value << tlsCiphers;
     112         181 :     out << YAML::Key << Conf::METHOD_KEY << YAML::Value << tlsMethod;
     113         181 :     out << YAML::Key << Conf::SERVER_KEY << YAML::Value << tlsServerName;
     114         181 :     out << YAML::EndMap;
     115             : 
     116             :     // srtp submap
     117         181 :     out << YAML::Key << Conf::SRTP_KEY << YAML::Value << YAML::BeginMap;
     118         181 :     out << YAML::Key << Conf::KEY_EXCHANGE_KEY << YAML::Value << sip_utils::getKeyExchangeName(srtpKeyExchange);
     119         181 :     out << YAML::EndMap;
     120             : 
     121         181 :     out << YAML::EndMap;
     122         181 : }
     123             : 
     124             : void
     125           0 : SipAccountConfig::unserialize(const YAML::Node& node)
     126             : {
     127           0 :     SipAccountBaseConfig::unserialize(node);
     128           0 :     parseValueOptional(node, Conf::USERNAME_KEY, username);
     129           0 :     parseValueOptional(node, Conf::BIND_ADDRESS_KEY, bindAddress);
     130           0 :     parseValueOptional(node, Conf::PORT_KEY, localPort);
     131           0 :     parseValueOptional(node, Conf::PUBLISH_PORT_KEY, publishedPort);
     132           0 :     parseValueOptional(node, Conf::CONFIG_ACCOUNT_REGISTRATION_EXPIRE, registrationExpire);
     133           0 :     registrationExpire = std::max(MIN_REGISTRATION_TIME, registrationExpire);
     134           0 :     parseValueOptional(node, Conf::KEEP_ALIVE_ENABLED, registrationRefreshEnabled);
     135           0 :     parseValueOptional(node, Conf::SERVICE_ROUTE_KEY, serviceRoute);
     136           0 :     parseValueOptional(node, Conf::ALLOW_IP_AUTO_REWRITE, allowIPAutoRewrite);
     137             : 
     138           0 :     parseValueOptional(node, Conf::PRESENCE_MODULE_ENABLED_KEY, presenceEnabled);
     139           0 :     parseValueOptional(node, Conf::PRESENCE_PUBLISH_SUPPORTED_KEY, publishSupported);
     140           0 :     parseValueOptional(node, Conf::PRESENCE_SUBSCRIBE_SUPPORTED_KEY, subscribeSupported);
     141             : 
     142             :     // ICE - STUN/TURN
     143           0 :     parseValueOptional(node, Conf::STUN_ENABLED_KEY, stunEnabled);
     144           0 :     parseValueOptional(node, Conf::STUN_SERVER_KEY, stunServer);
     145             : 
     146           0 :     const auto& credsNode = node[Conf::CRED_KEY];
     147           0 :     setCredentials(
     148           0 :         parseVectorMap(credsNode,
     149             :                        {Conf::CONFIG_ACCOUNT_REALM, Conf::CONFIG_ACCOUNT_USERNAME, Conf::CONFIG_ACCOUNT_PASSWORD}));
     150             : 
     151             :     // get tls submap
     152             :     try {
     153           0 :         const auto& tlsMap = node[Conf::TLS_KEY];
     154           0 :         parseValueOptional(tlsMap, Conf::CERTIFICATE_KEY, tlsCertificateFile);
     155           0 :         parseValueOptional(tlsMap, Conf::CALIST_KEY, tlsCaListFile);
     156           0 :         parseValueOptional(tlsMap, Conf::TLS_PASSWORD_KEY, tlsPassword);
     157           0 :         parseValueOptional(tlsMap, Conf::PRIVATE_KEY_KEY, tlsPrivateKeyFile);
     158           0 :         parseValueOptional(tlsMap, Conf::TLS_ENABLE_KEY, tlsEnable);
     159           0 :         parseValueOptional(tlsMap, Conf::TLS_PORT_KEY, tlsListenerPort);
     160           0 :         parseValueOptional(tlsMap, Conf::CIPHERS_KEY, tlsCiphers);
     161           0 :         parseValueOptional(tlsMap, Conf::METHOD_KEY, tlsMethod);
     162           0 :         parseValueOptional(tlsMap, Conf::SERVER_KEY, tlsServerName);
     163           0 :         parseValueOptional(tlsMap, Conf::REQUIRE_CERTIF_KEY, tlsRequireClientCertificate);
     164           0 :         parseValueOptional(tlsMap, Conf::VERIFY_CLIENT_KEY, tlsVerifyClient);
     165           0 :         parseValueOptional(tlsMap, Conf::VERIFY_SERVER_KEY, tlsVerifyServer);
     166           0 :         parseValueOptional(tlsMap, Conf::DISABLE_SECURE_DLG_CHECK, tlsDisableSecureDlgCheck);
     167           0 :         parseValueOptional(tlsMap, Conf::TIMEOUT_KEY, tlsNegotiationTimeout);
     168           0 :     } catch (const std::exception& e) {
     169           0 :         JAMI_WARNING("Couldn't parse TLS map: {}", e.what());
     170           0 :     }
     171             : 
     172             :     // get srtp submap
     173           0 :     const auto& srtpMap = node[Conf::SRTP_KEY];
     174           0 :     std::string tmpKey;
     175           0 :     parseValueOptional(srtpMap, Conf::KEY_EXCHANGE_KEY, tmpKey);
     176           0 :     srtpKeyExchange = sip_utils::getKeyExchangeProtocol(tmpKey);
     177           0 : }
     178             : 
     179             : std::map<std::string, std::string>
     180          91 : SipAccountConfig::toMap() const
     181             : {
     182          91 :     auto a = SipAccountBaseConfig::toMap();
     183             :     // general sip settings
     184          91 :     a.emplace(Conf::CONFIG_ACCOUNT_USERNAME, username);
     185          91 :     a.emplace(Conf::CONFIG_LOCAL_PORT, std::to_string(localPort));
     186          91 :     a.emplace(Conf::CONFIG_ACCOUNT_DTMF_TYPE, dtmfType);
     187          91 :     a.emplace(Conf::CONFIG_LOCAL_INTERFACE, interface);
     188          91 :     a.emplace(Conf::CONFIG_PUBLISHED_PORT, std::to_string(publishedPort));
     189          91 :     a.emplace(Conf::CONFIG_PUBLISHED_SAMEAS_LOCAL, publishedSameasLocal ? TRUE_STR : FALSE_STR);
     190          91 :     a.emplace(Conf::CONFIG_PUBLISHED_ADDRESS, publishedIp);
     191          91 :     a.emplace(Conf::CONFIG_STUN_ENABLE, stunEnabled ? TRUE_STR : FALSE_STR);
     192          91 :     a.emplace(Conf::CONFIG_STUN_SERVER, stunServer);
     193          91 :     a.emplace(Conf::CONFIG_BIND_ADDRESS, bindAddress);
     194          91 :     a.emplace(Conf::CONFIG_ACCOUNT_ROUTESET, serviceRoute);
     195          91 :     a.emplace(Conf::CONFIG_ACCOUNT_IP_AUTO_REWRITE, allowIPAutoRewrite ? TRUE_STR : FALSE_STR);
     196          91 :     a.emplace(Conf::CONFIG_PRESENCE_ENABLED, presenceEnabled ? TRUE_STR : FALSE_STR);
     197          91 :     a.emplace(Conf::CONFIG_KEEP_ALIVE_ENABLED, registrationRefreshEnabled ? TRUE_STR : FALSE_STR);
     198          91 :     a.emplace(Conf::CONFIG_ACCOUNT_REGISTRATION_EXPIRE, std::to_string(registrationExpire));
     199             : 
     200          91 :     std::string password {};
     201          91 :     if (not credentials.empty()) {
     202          68 :         for (const auto& cred : credentials)
     203          68 :             if (cred.username == username) {
     204          68 :                 password = cred.password;
     205          68 :                 break;
     206             :             }
     207             :     }
     208          91 :     a.emplace(Conf::CONFIG_ACCOUNT_PASSWORD, std::move(password));
     209             : 
     210             :     // srtp settings
     211          91 :     a.emplace(Conf::CONFIG_SRTP_KEY_EXCHANGE, sip_utils::getKeyExchangeName(srtpKeyExchange));
     212          91 :     a.emplace(Conf::CONFIG_TLS_ENABLE, tlsEnable ? TRUE_STR : FALSE_STR);
     213          91 :     a.emplace(Conf::CONFIG_TLS_LISTENER_PORT, std::to_string(tlsListenerPort));
     214          91 :     a.emplace(Conf::CONFIG_TLS_CA_LIST_FILE, tlsCaListFile);
     215          91 :     a.emplace(Conf::CONFIG_TLS_CERTIFICATE_FILE, tlsCertificateFile);
     216          91 :     a.emplace(Conf::CONFIG_TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile);
     217          91 :     a.emplace(Conf::CONFIG_TLS_PASSWORD, tlsPassword);
     218          91 :     a.emplace(Conf::CONFIG_TLS_METHOD, tlsMethod);
     219          91 :     a.emplace(Conf::CONFIG_TLS_CIPHERS, tlsCiphers);
     220          91 :     a.emplace(Conf::CONFIG_TLS_SERVER_NAME, tlsServerName);
     221          91 :     a.emplace(Conf::CONFIG_TLS_VERIFY_SERVER, tlsVerifyServer ? TRUE_STR : FALSE_STR);
     222          91 :     a.emplace(Conf::CONFIG_TLS_VERIFY_CLIENT, tlsVerifyClient ? TRUE_STR : FALSE_STR);
     223          91 :     a.emplace(Conf::CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE, tlsRequireClientCertificate ? TRUE_STR : FALSE_STR);
     224          91 :     a.emplace(Conf::CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC, std::to_string(tlsNegotiationTimeout));
     225          91 :     a.emplace(Conf::CONFIG_TLS_DISABLE_SECURE_DLG_CHECK, tlsDisableSecureDlgCheck ? TRUE_STR : FALSE_STR);
     226         182 :     return a;
     227          91 : }
     228             : 
     229             : void
     230          24 : SipAccountConfig::fromMap(const std::map<std::string, std::string>& details)
     231             : {
     232          24 :     SipAccountBaseConfig::fromMap(details);
     233             : 
     234             :     // general sip settings
     235          24 :     parseString(details, Conf::CONFIG_ACCOUNT_USERNAME, username);
     236          24 :     parseInt(details, Conf::CONFIG_LOCAL_PORT, localPort);
     237          24 :     parseString(details, Conf::CONFIG_BIND_ADDRESS, bindAddress);
     238          24 :     parseString(details, Conf::CONFIG_ACCOUNT_ROUTESET, serviceRoute);
     239          24 :     parseBool(details, Conf::CONFIG_ACCOUNT_IP_AUTO_REWRITE, allowIPAutoRewrite);
     240          24 :     parseString(details, Conf::CONFIG_LOCAL_INTERFACE, interface);
     241          24 :     parseBool(details, Conf::CONFIG_PUBLISHED_SAMEAS_LOCAL, publishedSameasLocal);
     242          24 :     parseString(details, Conf::CONFIG_PUBLISHED_ADDRESS, publishedIp);
     243          24 :     parseInt(details, Conf::CONFIG_PUBLISHED_PORT, publishedPort);
     244          24 :     parseBool(details, Conf::CONFIG_PRESENCE_ENABLED, presenceEnabled);
     245          24 :     parseString(details, Conf::CONFIG_ACCOUNT_DTMF_TYPE, dtmfType);
     246          24 :     parseBool(details, Conf::CONFIG_KEEP_ALIVE_ENABLED, registrationRefreshEnabled);
     247          24 :     parseInt(details, Conf::CONFIG_ACCOUNT_REGISTRATION_EXPIRE, registrationExpire);
     248             : 
     249             :     // srtp settings
     250          24 :     auto iter = details.find(Conf::CONFIG_SRTP_KEY_EXCHANGE);
     251          24 :     if (iter != details.end())
     252          24 :         srtpKeyExchange = sip_utils::getKeyExchangeProtocol(iter->second);
     253             : 
     254          24 :     if (credentials.empty()) { // credentials not set, construct 1 entry
     255          24 :         JAMI_WARN("No credentials set, inferring them...");
     256          24 :         std::map<std::string, std::string> map;
     257          24 :         map[Conf::CONFIG_ACCOUNT_USERNAME] = username;
     258          24 :         parseString(details, Conf::CONFIG_ACCOUNT_PASSWORD, map[Conf::CONFIG_ACCOUNT_PASSWORD]);
     259          24 :         map[Conf::CONFIG_ACCOUNT_REALM] = "*";
     260          48 :         setCredentials({map});
     261          24 :     }
     262             : 
     263             :     // ICE - STUN
     264          24 :     parseBool(details, Conf::CONFIG_STUN_ENABLE, stunEnabled);
     265          24 :     parseString(details, Conf::CONFIG_STUN_SERVER, stunServer);
     266             : 
     267             :     // TLS
     268          24 :     parseBool(details, Conf::CONFIG_TLS_ENABLE, tlsEnable);
     269          24 :     parseInt(details, Conf::CONFIG_TLS_LISTENER_PORT, tlsListenerPort);
     270          24 :     parsePath(details, Conf::CONFIG_TLS_CA_LIST_FILE, tlsCaListFile, path);
     271          24 :     parsePath(details, Conf::CONFIG_TLS_CERTIFICATE_FILE, tlsCertificateFile, path);
     272          24 :     parsePath(details, Conf::CONFIG_TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile, path);
     273          24 :     parseString(details, Conf::CONFIG_TLS_PASSWORD, tlsPassword);
     274          24 :     parseString(details, Conf::CONFIG_TLS_METHOD, tlsMethod);
     275          24 :     parseString(details, Conf::CONFIG_TLS_CIPHERS, tlsCiphers);
     276          24 :     parseString(details, Conf::CONFIG_TLS_SERVER_NAME, tlsServerName);
     277          24 :     parseBool(details, Conf::CONFIG_TLS_VERIFY_SERVER, tlsVerifyServer);
     278          24 :     parseBool(details, Conf::CONFIG_TLS_VERIFY_CLIENT, tlsVerifyClient);
     279          24 :     parseBool(details, Conf::CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE, tlsRequireClientCertificate);
     280          24 :     parseBool(details, Conf::CONFIG_TLS_DISABLE_SECURE_DLG_CHECK, tlsDisableSecureDlgCheck);
     281          24 :     parseInt(details, Conf::CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC, tlsNegotiationTimeout);
     282          24 : }
     283             : 
     284          24 : SipAccountConfig::Credentials::Credentials(const std::map<std::string, std::string>& cred)
     285             : {
     286          24 :     auto itrealm = cred.find(Conf::CONFIG_ACCOUNT_REALM);
     287          24 :     auto user = cred.find(Conf::CONFIG_ACCOUNT_USERNAME);
     288          24 :     auto passw = cred.find(Conf::CONFIG_ACCOUNT_PASSWORD);
     289          24 :     realm = itrealm != cred.end() ? itrealm->second : "";
     290          24 :     username = user != cred.end() ? user->second : "";
     291          24 :     password = passw != cred.end() ? passw->second : "";
     292          24 :     computePasswordHash();
     293          24 : }
     294             : 
     295             : std::map<std::string, std::string>
     296         181 : SipAccountConfig::Credentials::toMap() const
     297             : {
     298         181 :     return {{Conf::CONFIG_ACCOUNT_REALM, realm},
     299         181 :             {Conf::CONFIG_ACCOUNT_USERNAME, username},
     300         724 :             {Conf::CONFIG_ACCOUNT_PASSWORD, password}};
     301             : }
     302             : 
     303             : void
     304          24 : SipAccountConfig::Credentials::computePasswordHash()
     305             : {
     306             :     pj_md5_context pms;
     307             : 
     308             :     /* Compute md5 hash = MD5(username ":" realm ":" password) */
     309          24 :     pj_md5_init(&pms);
     310          24 :     pj_md5_update(&pms, (const uint8_t*) username.data(), username.length());
     311          24 :     pj_md5_update(&pms, (const uint8_t*) ":", 1);
     312          24 :     pj_md5_update(&pms, (const uint8_t*) realm.data(), realm.length());
     313          24 :     pj_md5_update(&pms, (const uint8_t*) ":", 1);
     314          24 :     pj_md5_update(&pms, (const uint8_t*) password.data(), password.length());
     315             : 
     316             :     unsigned char digest[16];
     317          24 :     pj_md5_final(&pms, digest);
     318             : 
     319             :     char hash[32];
     320             : 
     321         408 :     for (int i = 0; i < 16; ++i)
     322         384 :         pj_val_to_hex_digit(digest[i], &hash[static_cast<ptrdiff_t>(2 * i)]);
     323             : 
     324          24 :     password_h = {hash, 32};
     325          24 : }
     326             : 
     327             : std::vector<std::map<std::string, std::string>>
     328         181 : SipAccountConfig::getCredentials() const
     329             : {
     330         181 :     std::vector<std::map<std::string, std::string>> ret;
     331         181 :     ret.reserve(credentials.size());
     332         362 :     for (const auto& c : credentials) {
     333         181 :         ret.emplace_back(c.toMap());
     334             :     }
     335         181 :     return ret;
     336           0 : }
     337             : 
     338             : void
     339          24 : SipAccountConfig::setCredentials(const std::vector<std::map<std::string, std::string>>& creds)
     340             : {
     341          24 :     credentials.clear();
     342          24 :     credentials.reserve(creds.size());
     343          48 :     for (const auto& cred : creds)
     344          24 :         credentials.emplace_back(cred);
     345          24 : }
     346             : 
     347             : } // namespace jami

Generated by: LCOV version 1.14