From a1fc15cbbb8f407df06097877c9392e621e3ce4b Mon Sep 17 00:00:00 2001
From: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
Date: Fri, 24 Jul 2015 11:53:44 -0400
Subject: [PATCH] ice: add TURN static credential support

This patch add static credential support in YAML config file and
with client throught account details.

Issue: #78102
Change-Id: I1727305fda7049e67838b34acc10ba26ad0eab9f
---
 src/account_schema.h       |  3 +++
 src/ice_transport.cpp      | 10 ++++++++--
 src/ice_transport.h        | 13 ++++++++-----
 src/sip/sipaccountbase.cpp | 26 ++++++++++++++++++++++----
 src/sip/sipaccountbase.h   |  8 +++++++-
 5 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/src/account_schema.h b/src/account_schema.h
index 3d4ae21532..5a1bfd4d40 100644
--- a/src/account_schema.h
+++ b/src/account_schema.h
@@ -82,6 +82,9 @@ static const char *const CONFIG_STUN_SERVER                     = "STUN.server";
 static const char *const CONFIG_STUN_ENABLE                     = "STUN.enable";
 static const char *const CONFIG_TURN_SERVER                     = "TURN.server";
 static const char *const CONFIG_TURN_ENABLE                     = "TURN.enable";
+static const char *const CONFIG_TURN_SERVER_UNAME               = "TURN.username";
+static const char *const CONFIG_TURN_SERVER_PWD                 = "TURN.password";
+static const char *const CONFIG_TURN_SERVER_REALM               = "TURN.realm";
 
 // SRTP specific parameters
 static const char *const CONFIG_SRTP_ENABLE                     = "SRTP.enable";
diff --git a/src/ice_transport.cpp b/src/ice_transport.cpp
index d054b22c5e..54ec083765 100644
--- a/src/ice_transport.cpp
+++ b/src/ice_transport.cpp
@@ -150,8 +150,14 @@ IceTransport::IceTransport(const char* name, int component_count, bool master,
             config_.turn.port = PJ_STUN_PORT;
         }
 
-        // No authorization yet
-        //config_.turn.auth_cred.type = PJ_STUN_AUTH_STATIC;
+        // Authorization (only static plain password supported yet)
+        if (not options.turnServerPwd.empty()) {
+            config_.turn.auth_cred.type = PJ_STUN_AUTH_CRED_STATIC;
+            config_.turn.auth_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN;
+            pj_cstr(&config_.turn.auth_cred.data.static_cred.realm, options.turnServerRealm.c_str());
+            pj_cstr(&config_.turn.auth_cred.data.static_cred.username, options.turnServerUserName.c_str());
+            pj_cstr(&config_.turn.auth_cred.data.static_cred.data, options.turnServerPwd.c_str());
+        }
 
         // Only UDP yet
         config_.turn.conn_type = PJ_TURN_TP_UDP;
diff --git a/src/ice_transport.h b/src/ice_transport.h
index c11d070e02..2aa66a6900 100644
--- a/src/ice_transport.h
+++ b/src/ice_transport.h
@@ -60,11 +60,14 @@ using IceRecvCb = std::function<ssize_t(unsigned char* buf, size_t len)>;
 using IceCandidate = pj_ice_sess_cand;
 
 struct IceTransportOptions {
-        bool upnpEnable {false};
-        IceTransportCompleteCb onInitDone {};
-        IceTransportCompleteCb onNegoDone {};
-        std::string stunServer {};
-        std::string turnServer {};
+    bool upnpEnable {false};
+    IceTransportCompleteCb onInitDone {};
+    IceTransportCompleteCb onNegoDone {};
+    std::string stunServer {};
+    std::string turnServer {};
+    std::string turnServerUserName {};  //!< credential username
+    std::string turnServerPwd {};       //!< credential password
+    std::string turnServerRealm {};     //!< non-empty for long-term credential
 };
 
 class IceTransport {
diff --git a/src/sip/sipaccountbase.cpp b/src/sip/sipaccountbase.cpp
index 09c122d102..744bfb6bb2 100644
--- a/src/sip/sipaccountbase.cpp
+++ b/src/sip/sipaccountbase.cpp
@@ -121,6 +121,9 @@ void SIPAccountBase::serialize(YAML::Emitter &out)
     out << YAML::Key << Conf::STUN_SERVER_KEY << YAML::Value << stunServer_;
     out << YAML::Key << Conf::TURN_ENABLED_KEY << YAML::Value << turnEnabled_;
     out << YAML::Key << Conf::TURN_SERVER_KEY << YAML::Value << turnServer_;
+    out << YAML::Key << Conf::TURN_SERVER_UNAME_KEY << YAML::Value << turnServerUserName_;
+    out << YAML::Key << Conf::TURN_SERVER_PWD_KEY << YAML::Value << turnServerPwd_;
+    out << YAML::Key << Conf::TURN_SERVER_REALM_KEY << YAML::Value << turnServerRealm_;
 }
 
 void SIPAccountBase::serializeTls(YAML::Emitter &out)
@@ -170,6 +173,9 @@ void SIPAccountBase::unserialize(const YAML::Node &node)
         parseValue(node, Conf::STUN_SERVER_KEY, stunServer_);
         parseValue(node, Conf::TURN_ENABLED_KEY, turnEnabled_);
         parseValue(node, Conf::TURN_SERVER_KEY, turnServer_);
+        parseValue(node, Conf::TURN_SERVER_UNAME_KEY, turnServerUserName_);
+        parseValue(node, Conf::TURN_SERVER_PWD_KEY, turnServerPwd_);
+        parseValue(node, Conf::TURN_SERVER_REALM_KEY, turnServerRealm_);
     }
 }
 
@@ -206,11 +212,16 @@ void SIPAccountBase::setAccountDetails(const std::map<std::string, std::string>
     parseString(details, Conf::CONFIG_TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile_);
     parseString(details, Conf::CONFIG_TLS_PASSWORD, tlsPassword_);
 
-    // ICE - STUN/TURN
-    parseString(details, Conf::CONFIG_STUN_SERVER, stunServer_);
+    // ICE - STUN
     parseBool(details, Conf::CONFIG_STUN_ENABLE, stunEnabled_);
-    parseString(details, Conf::CONFIG_TURN_SERVER, turnServer_);
+    parseString(details, Conf::CONFIG_STUN_SERVER, stunServer_);
+
+    // ICE - TURN
     parseBool(details, Conf::CONFIG_TURN_ENABLE, turnEnabled_);
+    parseString(details, Conf::CONFIG_TURN_SERVER, turnServer_);
+    parseString(details, Conf::CONFIG_TURN_SERVER_UNAME, turnServerUserName_);
+    parseString(details, Conf::CONFIG_TURN_SERVER_PWD, turnServerPwd_);
+    parseString(details, Conf::CONFIG_TURN_SERVER_REALM, turnServerRealm_);
 }
 
 std::map<std::string, std::string>
@@ -234,6 +245,9 @@ SIPAccountBase::getAccountDetails() const
     a.emplace(Conf::CONFIG_STUN_SERVER, stunServer_);
     a.emplace(Conf::CONFIG_TURN_ENABLE, turnEnabled_ ? TRUE_STR : FALSE_STR);
     a.emplace(Conf::CONFIG_TURN_SERVER, turnServer_);
+    a.emplace(Conf::CONFIG_TURN_SERVER_UNAME, turnServerUserName_);
+    a.emplace(Conf::CONFIG_TURN_SERVER_PWD, turnServerPwd_);
+    a.emplace(Conf::CONFIG_TURN_SERVER_REALM, turnServerRealm_);
 
     a.emplace(Conf::CONFIG_TLS_CA_LIST_FILE,        tlsCaListFile_);
     a.emplace(Conf::CONFIG_TLS_CERTIFICATE_FILE,    tlsCertificateFile_);
@@ -323,8 +337,12 @@ SIPAccountBase::getIceOptions() const noexcept
     auto opts = Account::getIceOptions();
     if (stunEnabled_)
         opts.stunServer = stunServer_;
-    if (turnEnabled_)
+    if (turnEnabled_) {
         opts.turnServer = turnServer_;
+        opts.turnServerUserName = turnServerUserName_;
+        opts.turnServerPwd = turnServerPwd_;
+        opts.turnServerRealm = turnServerRealm_;
+    }
     return opts;
 }
 
diff --git a/src/sip/sipaccountbase.h b/src/sip/sipaccountbase.h
index 6728a3c9c1..e4e4fd1f8a 100644
--- a/src/sip/sipaccountbase.h
+++ b/src/sip/sipaccountbase.h
@@ -88,6 +88,9 @@ namespace Conf {
     const char *const STUN_SERVER_KEY = "stunServer";
     const char *const TURN_ENABLED_KEY = "turnEnabled";
     const char *const TURN_SERVER_KEY = "turnServer";
+    const char *const TURN_SERVER_UNAME_KEY = "turnServerUserName";
+    const char *const TURN_SERVER_PWD_KEY = "turnServerPassword";
+    const char *const TURN_SERVER_REALM_KEY = "turnServerRealm";
     const char *const CRED_KEY = "credential";
     const char *const AUDIO_PORT_MIN_KEY = "audioPortMin";
     const char *const AUDIO_PORT_MAX_KEY = "audioPortMax";
@@ -312,7 +315,10 @@ protected:
      * The TURN server hostname (optional), used to provide the public IP address in case the softphone
      * stay behind a NAT.
      */
-    std::string turnServer_ {};
+    std::string turnServer_;
+    std::string turnServerUserName_;
+    std::string turnServerPwd_;
+    std::string turnServerRealm_;
 
     std::string tlsCaListFile_;
     std::string tlsCertificateFile_;
-- 
GitLab