LCOV - code coverage report
Current view: top level - src/sip - sipaccount_config.cpp (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 78.6 % 201 158
Test Date: 2026-06-13 09:18:46 Functions: 76.9 % 13 10

            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           96 :         JAMI_WARNING("No credentials set, inferring them...");
     256           24 :         std::map<std::string, std::string> map;
     257           72 :         map[Conf::CONFIG_ACCOUNT_USERNAME] = username;
     258           48 :         parseString(details, Conf::CONFIG_ACCOUNT_PASSWORD, map[Conf::CONFIG_ACCOUNT_PASSWORD]);
     259           24 :         map[Conf::CONFIG_ACCOUNT_REALM] = "*";
     260           72 :         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           48 : }
     283              : 
     284           24 : SipAccountConfig::Credentials::Credentials(const std::map<std::string, std::string>& cred)
     285              : {
     286           48 :     auto itrealm = cred.find(Conf::CONFIG_ACCOUNT_REALM);
     287           48 :     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          905 :             {Conf::CONFIG_ACCOUNT_PASSWORD, password}};
     301          181 : }
     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 2.0-1