Commit ac3bf29a authored by Emmanuel Lepage Vallee's avatar Emmanuel Lepage Vallee Committed by Guillaume Roguez

tls: Expose supported ciphers through the API

Refs #56702

Change-Id: I00694aca0849a82f56edaaf52643ef58a8b4b21d
parent 61bc0db0
......@@ -612,6 +612,26 @@
</arg>
</method>
<method name="getSupportedCiphers" tp:name-for-bindings="getSupportedCiphers">
<tp:added version="2.0.0"/>
<tp:docstring>
Returns a list of supported encryption ciphers used to encrypt SIP messages. The list depends on the TLS library being used.
Only registered SIP accounts currently support setting custom ciphers. This method returns an empty list if TLS support is disabled in either pjproject or Ring.
</tp:docstring>
<arg type="s" name="accountID" direction="in">
<tp:docstring>
A SIP account id, other account IDs will be rejected.
</tp:docstring>
</arg>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/>
<arg type="as" name="list" direction="out">
<tp:docstring>
A list of randomly sorted cipher names. The order may or may
not be significant depending on the SSL library being used.
</tp:docstring>
</arg>
</method>
<method name="getTlsSettingsDefault" tp:name-for-bindings="getTlsSettingsDefault">
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringString"/>
<arg type="a{ss}" name="details" direction="out">
......
......@@ -97,6 +97,11 @@ std::vector< std::string > DBusConfigurationManager::getSupportedTlsMethod()
return ring_config_get_supported_tls_method();
}
std::vector< std::string > DBusConfigurationManager::getSupportedCiphers(const std::string& accountID)
{
return ring_config_get_supported_ciphers(accountID);
}
std::vector< std::string > DBusConfigurationManager::getAudioCodecDetails(const int32_t& payload)
{
return ring_config_get_audio_codec_details(payload);
......
......@@ -77,6 +77,7 @@ class DBusConfigurationManager :
void sendRegister(const std::string& accoundID, const bool& enable);
void registerAllAccounts(void);
std::map< std::string, std::string > getTlsSettingsDefault();
std::vector< std::string > getSupportedCiphers(const std::string& accountID);
std::vector< int32_t > getAudioCodecList();
std::vector< std::string > getSupportedTlsMethod();
std::vector< std::string > getAudioCodecDetails(const int32_t& payload);
......
......@@ -207,9 +207,9 @@ std::string ConfigurationManager::addAccount(const std::map<std::string, std::st
return Manager::instance().addAccount(details);
}
void ConfigurationManager::removeAccount(const std::string& accoundID)
void ConfigurationManager::removeAccount(const std::string& accountID)
{
return Manager::instance().removeAccount(accoundID);
return Manager::instance().removeAccount(accountID);
}
std::vector<std::string> ConfigurationManager::getAccountList()
......@@ -241,6 +241,22 @@ std::vector<std::string> ConfigurationManager::getSupportedTlsMethod()
return method;
}
std::vector<std::string> ConfigurationManager::getSupportedCiphers(const std::string& accountID) const
{
#if HAVE_TLS
const auto sipaccount = Manager::instance().getAccount<SIPAccount>(accountID);
if (sipaccount) {
return sipaccount->getSupportedCiphers();
} else {
RING_ERR("SIP account %s doesn't exist", accountID.c_str());
#else
{
#endif
return {};
}
}
std::vector<std::string> ConfigurationManager::getAudioCodecDetails(int32_t payload)
{
std::vector<std::string> result(Manager::instance().audioCodecFactory.getCodecSpecifications(payload));
......
......@@ -67,6 +67,7 @@ class ConfigurationManager
std::vector< int32_t > getAudioCodecList();
std::vector< std::string > getSupportedTlsMethod();
std::vector< std::string > getSupportedCiphers(const std::string& accountID) const;
std::vector< std::string > getAudioCodecDetails(int32_t payload);
std::vector< int32_t > getActiveAudioCodecList(const std::string& accountID);
......
......@@ -205,6 +205,7 @@ void ring_config_register_all_accounts(void);
std::map<std::string, std::string> ring_config_get_tls_default_settings(void);
std::vector<int> ring_config_get_audio_codec_list(void);
std::vector<std::string> ring_config_get_supported_tls_method(void);
std::vector<std::string> ring_config_get_supported_ciphers(const std::string& account_id);
std::vector<std::string> ring_config_get_audio_codec_details(int payload);
std::vector<int> ring_config_get_active_audio_codec_list(const std::string& account_id);
void ring_config_set_active_audio_codec_list(const std::vector<std::string>& list, const std::string& account_id);
......
......@@ -395,6 +395,11 @@ std::vector<std::string> ring_config_get_supported_tls_method(void)
return getConfigurationManager()->getSupportedTlsMethod();
}
std::vector<std::string> ring_config_get_supported_ciphers(const std::string& account_id)
{
return getConfigurationManager()->getSupportedCiphers(account_id);
}
std::vector<std::string> ring_config_get_audio_codec_details(int payload)
{
return getConfigurationManager()->getAudioCodecDetails(payload);
......
......@@ -121,6 +121,7 @@ SIPAccount::SIPAccount(const std::string& accountID, bool presenceEnabled)
, serviceRoute_()
, cred_()
, tlsSetting_()
, ciphers_(100)
, tlsCaListFile_()
, tlsCertificateFile_()
, tlsPrivateKeyFile_()
......@@ -1501,6 +1502,30 @@ SIPAccount::getHostPortFromSTUN(pj_pool_t *pool)
return result;
}
const std::vector<std::string>&
SIPAccount::getSupportedCiphers() const
{
//Currently, both OpenSSL and GNUTLS implementations are static
//reloading this for each account is unnecessary
static std::vector<std::string> availCiphers {};
// LIMITATION Assume the size might change, if there aren't any ciphers,
// this will cause the cache to be repopulated at each call for nothing.
if (availCiphers.empty()) {
unsigned cipherNum = 256;
CipherArray avail_ciphers(cipherNum);
if (pj_ssl_cipher_get_availables(&avail_ciphers.front(), &cipherNum) != PJ_SUCCESS)
RING_ERR("Could not determine cipher list on this system");
// filter-out 0 ciphers
std::copy_if(avail_ciphers.begin(), avail_ciphers.end(),
availCiphers.begin(),
[](pj_ssl_cipher& item){ return item > 0; });
}
return availCiphers;
}
void SIPAccount::keepAliveRegistrationCb(UNUSED pj_timer_heap_t *th, pj_timer_entry *te)
{
SIPAccount *sipAccount = static_cast<SIPAccount *>(te->user_data);
......
......@@ -315,6 +315,8 @@ class SIPAccount : public SIPAccountBase {
return stunServerName_;
}
const std::vector<std::string>& getSupportedCiphers() const;
/**
* @return pj_uint8_t structure, filled from the configuration
* file, that can be used directly by PJSIP to initialize
......@@ -614,7 +616,7 @@ class SIPAccount : public SIPAccountBase {
/**
* Allocate a vector to be used by pjsip to store the supported ciphers on this system.
*/
CipherArray ciphers_ {};
CipherArray ciphers_;
/**
* Determine if STUN public address resolution is required to register this account. In this case a
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment