Commit 8cdc7c66 authored by Adrien Béraud's avatar Adrien Béraud Committed by Guillaume Roguez

srtp: fix SRTP streams handling

Refs #68180

Change-Id: I09d41357124486085ca46fc0149fca273e1b739f
Signed-off-by: Guillaume Roguez's avatarGuillaume Roguez <guillaume.roguez@savoirfairelinux.com>
parent d8439d29
......@@ -125,6 +125,12 @@ void VideoRtpSession::start()
socketPair_.reset(
new SocketPair(getRemoteRtpUri().c_str(), receive_.addr.getPort())
);
if (send_.crypto and receive_.crypto) {
socketPair_->createSRTP(receive_.crypto.getCryptoSuite().c_str(),
receive_.crypto.getSrtpKeyInfo().c_str(),
send_.crypto.getCryptoSuite().c_str(),
send_.crypto.getSrtpKeyInfo().c_str());
}
} catch (const std::runtime_error &e) {
RING_ERR("Socket creation failed on port %d: %s", receive_.addr.getPort(), e.what());
return;
......@@ -154,7 +160,19 @@ void VideoRtpSession::start(std::unique_ptr<IceSocket> rtp_sock,
return;
}
socketPair_.reset(new SocketPair(std::move(rtp_sock), std::move(rtcp_sock)));
try {
socketPair_.reset(new SocketPair(std::move(rtp_sock),
std::move(rtcp_sock)));
if (send_.crypto and receive_.crypto) {
socketPair_->createSRTP(receive_.crypto.getCryptoSuite().c_str(),
receive_.crypto.getSrtpKeyInfo().c_str(),
send_.crypto.getCryptoSuite().c_str(),
send_.crypto.getSrtpKeyInfo().c_str());
}
} catch (const std::runtime_error &e) {
RING_ERR("Socket creation failed");
return;
}
startSender();
startReceiver();
......
......@@ -238,10 +238,6 @@ class RingAccount : public SIPAccountBase {
return true;
}
virtual bool getSrtpEnabled() const {
return true;
}
virtual sip_utils::KeyExchangeProtocol getSrtpKeyExchange() const {
return sip_utils::KeyExchangeProtocol::SDES;
}
......
......@@ -654,9 +654,9 @@ Sdp::getMediaSlots(const pjmedia_sdp_session* session, bool remote) const
break;
}
if (remote) {
if (not remote) {
descr.receiving_sdp = getFilteredSdp(session, i, descr.payload_type);
RING_WARN("Filtered SDP for remote media #%u :\n%s", i, descr.receiving_sdp.c_str());
RING_WARN("Filtered SDP for local media #%u :\n%s", i, descr.receiving_sdp.c_str());
}
// get crypto info
......
......@@ -49,6 +49,14 @@ namespace ring {namespace sip_utils {
enum class KeyExchangeProtocol { NONE, SDES, ZRTP };
constexpr const char* getKeyExchangeName(KeyExchangeProtocol kx) {
return kx == KeyExchangeProtocol::SDES ? "sdes" : (
kx == KeyExchangeProtocol::ZRTP ? "zrtp" : "");
}
constexpr KeyExchangeProtocol getKeyExchangeProtocol(const char* name) {
return !strcmp("sdes", name) ? KeyExchangeProtocol::SDES : KeyExchangeProtocol::NONE;
}
/**
* Helper function to parser header from incoming sip messages
* @return Header from SIP message
......
......@@ -83,7 +83,6 @@ using yaml_utils::parseVectorMap;
static const int MIN_REGISTRATION_TIME = 60;
static const int DEFAULT_REGISTRATION_TIME = 3600;
static const char *const VALID_TLS_METHODS[] = {"Default", "TLSv1", "SSLv3", "SSLv23"};
static const char *const VALID_SRTP_KEY_EXCHANGES[] = {"", "sdes", "zrtp"};
constexpr const char * const SIPAccount::ACCOUNT_TYPE;
......@@ -223,6 +222,7 @@ SIPAccount::newOutgoingCall(const std::string& toUrl)
call->initIceTransport(true);
call->setIPToIP(isIP2IP());
call->setSecure(isTlsEnabled());
call->setPeerNumber(toUri);
call->initRecFilename(to);
......@@ -459,8 +459,7 @@ void SIPAccount::serialize(YAML::Emitter &out)
// srtp submap
out << YAML::Key << Conf::SRTP_KEY << YAML::Value << YAML::BeginMap;
out << YAML::Key << Conf::SRTP_ENABLE_KEY << YAML::Value << srtpEnabled_;
out << YAML::Key << Conf::KEY_EXCHANGE_KEY << YAML::Value << srtpKeyExchange_;
out << YAML::Key << Conf::KEY_EXCHANGE_KEY << YAML::Value << sip_utils::getKeyExchangeName(srtpKeyExchange_);
out << YAML::Key << Conf::RTP_FALLBACK_KEY << YAML::Value << srtpFallback_;
out << YAML::EndMap;
......@@ -564,11 +563,9 @@ void SIPAccount::unserialize(const YAML::Node &node)
// get srtp submap
const auto &srtpMap = node[Conf::SRTP_KEY];
parseValue(srtpMap, Conf::SRTP_ENABLE_KEY, srtpEnabled_);
std::string tmpKey;
parseValue(srtpMap, Conf::KEY_EXCHANGE_KEY, tmpKey);
validate(srtpKeyExchange_, tmpKey, VALID_SRTP_KEY_EXCHANGES);
srtpKeyExchange_ = sip_utils::getKeyExchangeProtocol(tmpKey.c_str());
parseValue(srtpMap, Conf::RTP_FALLBACK_KEY, srtpFallback_);
}
......@@ -629,11 +626,10 @@ void SIPAccount::setAccountDetails(const std::map<std::string, std::string> &det
parseString(details, Conf::CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC, tlsNegotiationTimeoutSec_);
// srtp settings
parseBool(details, Conf::CONFIG_SRTP_ENABLE, srtpEnabled_);
parseBool(details, Conf::CONFIG_SRTP_RTP_FALLBACK, srtpFallback_);
iter = details.find(Conf::CONFIG_SRTP_KEY_EXCHANGE);
if (iter != details.end())
validate(srtpKeyExchange_, iter->second, VALID_SRTP_KEY_EXCHANGES);
srtpKeyExchange_ = sip_utils::getKeyExchangeProtocol(iter->second.c_str());
if (credentials_.empty()) { // credentials not set, construct 1 entry
RING_WARN("No credentials set, inferring them...");
......@@ -722,8 +718,8 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
a[Conf::CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE] = tlsRequireClientCertificate_ ? TRUE_STR : FALSE_STR;
a[Conf::CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC] = tlsNegotiationTimeoutSec_;
a[Conf::CONFIG_SRTP_KEY_EXCHANGE] = srtpKeyExchange_;
a[Conf::CONFIG_SRTP_ENABLE] = srtpEnabled_ ? TRUE_STR : FALSE_STR;
a[Conf::CONFIG_SRTP_KEY_EXCHANGE] = sip_utils::getKeyExchangeName(srtpKeyExchange_);
a[Conf::CONFIG_SRTP_ENABLE] = isSrtpEnabled() ? TRUE_STR : FALSE_STR;
a[Conf::CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? TRUE_STR : FALSE_STR;
a[Conf::CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? TRUE_STR : FALSE_STR;
......@@ -1734,8 +1730,8 @@ std::map<std::string, std::string> SIPAccount::getIp2IpDetails() const
{
assert(isIP2IP());
std::map<std::string, std::string> ip2ipAccountDetails;
ip2ipAccountDetails[Conf::CONFIG_SRTP_KEY_EXCHANGE] = srtpKeyExchange_;
ip2ipAccountDetails[Conf::CONFIG_SRTP_ENABLE] = srtpEnabled_ ? TRUE_STR : FALSE_STR;
ip2ipAccountDetails[Conf::CONFIG_SRTP_KEY_EXCHANGE] = sip_utils::getKeyExchangeName(srtpKeyExchange_);
ip2ipAccountDetails[Conf::CONFIG_SRTP_ENABLE] = isSrtpEnabled() ? TRUE_STR : FALSE_STR;
ip2ipAccountDetails[Conf::CONFIG_SRTP_RTP_FALLBACK] = srtpFallback_ ? TRUE_STR : FALSE_STR;
ip2ipAccountDetails[Conf::CONFIG_ZRTP_DISPLAY_SAS] = zrtpDisplaySas_ ? TRUE_STR : FALSE_STR;
ip2ipAccountDetails[Conf::CONFIG_ZRTP_HELLO_HASH] = zrtpHelloHash_ ? TRUE_STR : FALSE_STR;
......
......@@ -382,14 +382,8 @@ class SIPAccount : public SIPAccountBase {
return tlsEnable_;
}
virtual bool getSrtpEnabled() const {
return srtpEnabled_;
}
virtual sip_utils::KeyExchangeProtocol getSrtpKeyExchange() const {
return srtpKeyExchange_ == "srtp"
? sip_utils::KeyExchangeProtocol::SDES
: sip_utils::KeyExchangeProtocol::NONE;
return srtpKeyExchange_;
}
virtual bool getSrtpFallback() const {
......@@ -532,6 +526,10 @@ class SIPAccount : public SIPAccountBase {
bool hostnameMatch(const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
bool proxyMatch(const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
bool isSrtpEnabled() const {
return srtpKeyExchange_ != sip_utils::KeyExchangeProtocol::NONE;
}
/**
* Callback called by the transport layer when the registration
* transport state changes.
......@@ -673,16 +671,10 @@ class SIPAccount : public SIPAccountBase {
std::string tlsNegotiationTimeoutSec_;
/**
* Determine if SRTP is enabled for this account, SRTP and ZRTP are mutually exclusive
* This only determine if the media channel is secured. One could only enable TLS
* with no secured media channel.
*/
bool srtpEnabled_ {false};
/**
* Specifies the type of key exchange usd for SRTP (sdes/zrtp)
* Specifies the type of key exchange used for SRTP (sdes/zrtp), if any.
* This only determine if the media channel is secured.
*/
std::string srtpKeyExchange_ {""};
sip_utils::KeyExchangeProtocol srtpKeyExchange_ {sip_utils::KeyExchangeProtocol::NONE};
/**
* Determine if the softphone should fallback on non secured media channel if SRTP negotiation fails.
......
......@@ -232,10 +232,6 @@ public:
publishedPort_ = port;
}
virtual bool getSrtpEnabled() const {
return false;
}
virtual sip_utils::KeyExchangeProtocol getSrtpKeyExchange() const = 0;
virtual bool getSrtpFallback() const = 0;
......
......@@ -772,31 +772,6 @@ SIPCall::startAllMedia()
continue;
}
auto accountAudioCodec = std::static_pointer_cast<AccountAudioCodecInfo>(local.codec);
RING_DBG("########## UPDATE MEDIA ############");
RING_DBG("[LOCAL][codec:%s][enabled:%s][holding:%s]"
, local.codec->systemCodecInfo.to_string().c_str()
, local.enabled ? "true" : "false"
, local.holding ? "true" : "false"
);
RING_DBG("[LOCAL][Audioformat] [sampleRate%d][nbChanels:%d]"
, accountAudioCodec->audioformat.sample_rate
, accountAudioCodec->audioformat.nb_channels
);
RING_DBG("[LOCAL] SDP: \n %s", local.receiving_sdp.c_str());
accountAudioCodec = std::static_pointer_cast<AccountAudioCodecInfo>(remote.codec);
RING_DBG("[REMOTE][codec:%s][enabled:%s][holding:%s]"
, remote.codec->systemCodecInfo.to_string().c_str()
, remote.enabled ? "true" : "false"
, remote.holding ? "true" : "false"
);
RING_DBG("[REMOTE][Audioformat] [sampleRate%d][nbChanels:%d]"
, accountAudioCodec->audioformat.sample_rate
, accountAudioCodec->audioformat.nb_channels
);
RING_DBG("[REMOTE] SDP: \n %s", remote.receiving_sdp.c_str());
RING_DBG("####################################");
#ifdef RING_VIDEO
if (local.type == MEDIA_VIDEO) {
if (videoInput_.empty())
......@@ -804,7 +779,7 @@ SIPCall::startAllMedia()
videortp_.switchInput(videoInput_);
}
#endif
rtp->updateMedia(local, remote);
rtp->updateMedia(remote, local);
if (isIceRunning()) {
rtp->start(newIceSocket(ice_comp_id + 0),
newIceSocket(ice_comp_id + 1));
......
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