Commit 5917951d authored by pierre-luc's avatar pierre-luc

[#812] TLS integration within sipvoiplink and pjsip. Also, configure.ac

was changed in order to be able to compile against pjsip with TLS enabled.
parent fd7daae2
......@@ -195,6 +195,11 @@ AC_SUBST(CCEXT2_CFLAGS)
AC_SUBST(CCRTP_LIBS)
AC_SUBST(CCRTP_CFLAGS)
dnl Check for OpenSSL to link against pjsip and provide SIPS TLS support
PKG_CHECK_MODULES([libssl], libssl, , AC_MSG_ERROR([libssl is required]))
AC_SUBST(libssl_CFLAGS)
AC_SUBST(libssl_LIBS)
dnl Check for libzrtpcpp, a ccRTP extension providing zrtp key exchange
LIBZRTPCPP_MIN_VERSION=1.3.0
PKG_CHECK_MODULES(ZRTPCPP, libzrtpcpp >= ${LIBZRTPCPP_MIN_VERSION})
......
......@@ -23,7 +23,7 @@ PJSIP_LIBS= \
-lpjsip-ua-sfl-$(target) \
-lpjmedia-codec-sfl-$(target) \
-lpjlib-util-sfl-$(target) \
-lpj-sfl-$(target)
-lpj-sfl-$(target)
SIP_CFLAGS=-I$(src)/libs/pjproject-$(PJSIP_VERSION)/pjsip/include \
-I$(src)/libs/pjproject-$(PJSIP_VERSION)/pjlib/include \
......
......@@ -19,7 +19,8 @@ sflphoned_SOURCES = \
sflphoned_CXXFLAGS = \
-DPREFIX=\"$(prefix)\" -DPROGSHAREDIR=\"${datadir}/sflphone\" \
@ZRTPCPP_CFLAGS@
@ZRTPCPP_CFLAGS@ \
@libssl_CFLAGS@
# Add here the dynamic libraries sflphoned should be linked against
......@@ -32,7 +33,8 @@ sflphoned_LDADD = \
@CCRTP_LIBS@ \
@ALSA_LIBS@ \
@PULSEAUDIO_LIBS@ \
@SAMPLERATE_LIBS@
@SAMPLERATE_LIBS@ \
@libssl_LIBS@
# sflphoned_LDFLAGS= -pg -luuid
sflphoned_LDFLAGS= -luuid
......
......@@ -86,6 +86,7 @@ typedef enum RegistrationState {
#define ZRTP_DISPLAY_SAS_ONCE "ZRTP.displaySasOnce"
#define TLS_ENABLE "TLS.enable"
#define TLS_PORT "TLS.port"
#define TLS_CA_LIST_FILE "TLS.certificateListFile"
#define TLS_CERTIFICATE_FILE "TLS.certificateFile"
#define TLS_PRIVATE_KEY_FILE "TLS.privateKeyFile"
......
......@@ -47,7 +47,7 @@ ConfigurationManager::getTlsSettingsDefault (void)
_debug ("ConfigurationManager::getTlsDefaultSettings\n");
std::map<std::string, std::string> tlsSettingsDefault;
tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_PORT, DEFAULT_SIP_TLS_PORT));
tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_CA_LIST_FILE, ""));
tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, ""));
tlsSettingsDefault.insert(std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, ""));
......@@ -128,7 +128,9 @@ ConfigurationManager::getTlsSettings(const std::string& section)
{
std::map<std::string, std::string> tlsSettings;
tlsSettings.insert(std::pair<std::string, std::string>
(TLS_ENABLE, Manager::instance().getConfigString(section, TLS_ENABLE)));
(TLS_ENABLE, Manager::instance().getConfigString(section, TLS_ENABLE)));
tlsSettings.insert(std::pair<std::string, std::string>
(TLS_PORT, Manager::instance().getConfigString(section, TLS_PORT)));
tlsSettings.insert(std::pair<std::string, std::string>
(TLS_CA_LIST_FILE, Manager::instance().getConfigString(section, TLS_CA_LIST_FILE)));
tlsSettings.insert(std::pair<std::string, std::string>
......@@ -166,7 +168,12 @@ ConfigurationManager::setTlsSettings(const std::string& section, const std::map<
if (it != details.end()) {
Manager::instance().setConfig(section, TLS_ENABLE, it->second);
}
it = map_cpy.find(TLS_PORT);
if (it != details.end()) {
Manager::instance().setConfig(section, TLS_PORT, it->second);
}
it = map_cpy.find(TLS_CA_LIST_FILE);
if (it != details.end()) {
Manager::instance().setConfig(section, TLS_CA_LIST_FILE, it->second);
......
......@@ -137,6 +137,7 @@ static const SOUND_FORMAT INT32 = 0x8;
#define UNUSED __attribute__((__unused__))
#define DEFAULT_SIP_PORT 5060
#define DEFAULT_SIP_TLS_PORT "5061"
#define HOOK_DEFAULT_SIP_FIELD "X-sflphone-url"
#define HOOK_DEFAULT_URL_COMMAND "x-www-browser"
......
......@@ -1343,6 +1343,7 @@ ManagerImpl::initConfigFile (bool load_user_value, std::string alternate)
_config.addDefaultValue(std::pair<std::string, std::string> (ZRTP_DISPLAY_SAS_ONCE, FALSE_STR), IP2IP_PROFILE);
_config.addDefaultValue(std::pair<std::string, std::string> (ZRTP_NOT_SUPP_WARNING, TRUE_STR), IP2IP_PROFILE);
_config.addDefaultValue(std::pair<std::string, std::string> (TLS_ENABLE, FALSE_STR), IP2IP_PROFILE);
_config.addDefaultValue(std::pair<std::string, std::string> (TLS_PORT, DEFAULT_SIP_TLS_PORT), IP2IP_PROFILE);
_config.addDefaultValue(std::pair<std::string, std::string> (TLS_CA_LIST_FILE, EMPTY_FIELD), IP2IP_PROFILE);
_config.addDefaultValue(std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, EMPTY_FIELD), IP2IP_PROFILE);
_config.addDefaultValue(std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, EMPTY_FIELD), IP2IP_PROFILE);
......@@ -2556,6 +2557,7 @@ std::map< std::string, std::string > ManagerImpl::getAccountDetails (const Accou
a.insert(std::pair<std::string, std::string> (ZRTP_NOT_SUPP_WARNING, getConfigString(accountID, ZRTP_NOT_SUPP_WARNING)));
a.insert(std::pair<std::string, std::string> (TLS_ENABLE, Manager::instance().getConfigString(accountID, TLS_ENABLE)));
a.insert(std::pair<std::string, std::string> (TLS_PORT, Manager::instance().getConfigString(accountID, TLS_PORT)));
a.insert(std::pair<std::string, std::string> (TLS_CA_LIST_FILE, Manager::instance().getConfigString(accountID, TLS_CA_LIST_FILE)));
a.insert(std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, Manager::instance().getConfigString(accountID, TLS_CERTIFICATE_FILE)));
a.insert(std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, Manager::instance().getConfigString(accountID, TLS_PRIVATE_KEY_FILE)));
......@@ -2736,6 +2738,7 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma
std::string srtpKeyExchange;
std::string tlsEnable;
std::string tlsPort;
std::string tlsCaListFile;
std::string tlsCertificateFile;
std::string tlsPrivateKeyFile;
......@@ -2765,6 +2768,7 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma
if((iter = map_cpy.find(CONFIG_ACCOUNT_REGISTRATION_EXPIRE)) != map_cpy.end()) { registrationExpire = iter->second; }
if((iter = map_cpy.find(TLS_ENABLE)) != map_cpy.end()) { tlsEnable = iter->second; }
if((iter = map_cpy.find(TLS_PORT)) != map_cpy.end()) { tlsPort = iter->second; }
if((iter = map_cpy.find(TLS_CA_LIST_FILE)) != map_cpy.end()) { tlsCaListFile = iter->second; }
if((iter = map_cpy.find(TLS_CERTIFICATE_FILE)) != map_cpy.end()) { tlsCertificateFile = iter->second; }
if((iter = map_cpy.find(TLS_PRIVATE_KEY_FILE)) != map_cpy.end()) { tlsPrivateKeyFile = iter->second; }
......@@ -2787,7 +2791,8 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma
setConfig(accountID, ZRTP_HELLO_HASH, zrtpHelloHash);
setConfig(accountID, SRTP_KEY_EXCHANGE, srtpKeyExchange);
setConfig(accountID, TLS_ENABLE, tlsEnable);
setConfig(accountID, TLS_ENABLE, tlsEnable);
setConfig(accountID, TLS_ENABLE, tlsPort);
setConfig(accountID, TLS_CA_LIST_FILE, tlsCaListFile);
setConfig(accountID, TLS_CERTIFICATE_FILE, tlsCertificateFile);
setConfig(accountID, TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile);
......
......@@ -2,6 +2,7 @@
* Copyright (C) 2006-2009 Savoir-Faire Linux inc.
*
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -29,6 +30,9 @@ SIPAccount::SIPAccount (const AccountID& accountID)
, _bRegister (false)
, _contact ("")
, _resolveOnce (false)
, _tlsSetting (NULL)
, _tlsEnabled (false)
, _tlsPort (0)
{
/* SIPVoIPlink is used as a singleton, because we want to have only one link for all the SIP accounts created */
/* So instead of creating a new instance, we just fetch the static instance, or create one if it is not yet */
......@@ -48,7 +52,7 @@ SIPAccount::~SIPAccount()
/* Delete accounts-related information */
_regc = NULL;
free(_cred);
_cred = NULL;
free(_tlsSetting);
}
int SIPAccount::registerVoIPLink()
......@@ -132,6 +136,13 @@ int SIPAccount::registerVoIPLink()
_registrationExpire = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE);
}
/* Init TLS settings if the user wants to use TLS */
_tlsEnabled = Manager::instance().getConfigBool(_accountID, TLS_ENABLE);
if (_tlsEnabled) {
_tlsPort = (pj_uint16_t) Manager::instance().getConfigInt(_accountID, TLS_PORT);
initTlsConfiguration();
}
/* Start registration */
status = _link->sendRegister (_accountID);
......@@ -152,6 +163,62 @@ int SIPAccount::unregisterVoIPLink()
}
pjsip_ssl_method SIPAccount::sslMethodStringToPjEnum(const std::string& method)
{
if (method == "Default") { return PJSIP_SSL_UNSPECIFIED_METHOD; }
if (method == "TLSv1") { return PJSIP_TLSV1_METHOD; }
if (method == "SSLv2") { return PJSIP_SSLV2_METHOD; }
if (method == "SSLv3") { return PJSIP_SSLV3_METHOD; }
if (method == "SSLv23") { return PJSIP_SSLV23_METHOD; }
return PJSIP_SSL_UNSPECIFIED_METHOD;
}
void SIPAccount::initTlsConfiguration(void)
{
/*
* Initialize structure to zero
*/
_tlsSetting = (pjsip_tls_setting *) malloc(sizeof(pjsip_tls_setting));
assert(_tlsSetting);
pjsip_tls_setting_default(_tlsSetting);
std::string tlsCaListFile = Manager::instance().getConfigString(_accountID, TLS_CA_LIST_FILE);
std::string tlsCertificateFile = Manager::instance().getConfigString(_accountID, TLS_CERTIFICATE_FILE);
std::string tlsPrivateKeyFile = Manager::instance().getConfigString(_accountID, TLS_PRIVATE_KEY_FILE);
std::string tlsPassword = Manager::instance().getConfigString(_accountID, TLS_PASSWORD);
std::string tlsMethod = Manager::instance().getConfigString(_accountID, TLS_METHOD);
std::string tlsCiphers = Manager::instance().getConfigString(_accountID, TLS_CIPHERS);
std::string tlsServerName = Manager::instance().getConfigString(_accountID, TLS_SERVER_NAME);
bool tlsVerifyServer = Manager::instance().getConfigBool(_accountID, TLS_VERIFY_SERVER);
bool tlsVerifyClient = Manager::instance().getConfigBool(_accountID, TLS_VERIFY_CLIENT);
bool tlsRequireClientCertificate = Manager::instance().getConfigBool(_accountID, TLS_REQUIRE_CLIENT_CERTIFICATE);
std::string tlsNegotiationTimeoutSec = Manager::instance().getConfigString(_accountID, TLS_NEGOTIATION_TIMEOUT_SEC);
std::string tlsNegotiationTimeoutMsec = Manager::instance().getConfigString(_accountID, TLS_NEGOTIATION_TIMEOUT_MSEC);
pj_cstr(&_tlsSetting->ca_list_file, tlsCaListFile.c_str());
pj_cstr(&_tlsSetting->cert_file, tlsCertificateFile.c_str());
pj_cstr(&_tlsSetting->privkey_file, tlsPrivateKeyFile.c_str());
pj_cstr(&_tlsSetting->password, tlsPassword.c_str());
_tlsSetting->method = sslMethodStringToPjEnum(tlsMethod);
pj_cstr(&_tlsSetting->ciphers, tlsCiphers.c_str());
pj_cstr(&_tlsSetting->server_name, tlsServerName.c_str());
_tlsSetting->verify_server = (tlsVerifyServer == true) ? PJ_TRUE: PJ_FALSE;
_tlsSetting->verify_client = (tlsVerifyClient == true) ? PJ_TRUE: PJ_FALSE;
_tlsSetting->require_client_cert = (tlsRequireClientCertificate == true) ? PJ_TRUE: PJ_FALSE;
_tlsSetting->timeout.sec = atol(tlsNegotiationTimeoutSec.c_str());
_tlsSetting->timeout.msec = atol(tlsNegotiationTimeoutMsec.c_str());
}
void SIPAccount::loadConfig()
{
// Account generic
......
......@@ -25,6 +25,7 @@
#include "account.h"
#include "sipvoiplink.h"
#include "pjsip/sip_transport_tls.h"
class SIPVoIPLink;
......@@ -94,8 +95,24 @@ class SIPAccount : public Account
bool isRegister() {return _bRegister;}
void setRegister(bool result) {_bRegister = result;}
inline pjsip_tls_setting * getTlsSetting(void) { return _tlsSetting; }
inline bool isTlsEnabled(void) { return _tlsEnabled; }
inline pj_uint16_t getTlsPort(void) { return _tlsPort; }
private:
/* Maps a string description of the SSL method
* to the corresponding enum value in pjsip_ssl_method.
* @param method The string representation
* @return pjsip_ssl_method The corresponding value in the enum
*/
pjsip_ssl_method sslMethodStringToPjEnum(const std::string& method);
/*
* Initializes tls settings from configuration file.
*
*/
void initTlsConfiguration(void);
/**
* Credential information
*/
......@@ -106,6 +123,19 @@ class SIPAccount : public Account
*/
pjsip_regc *_regc;
/**
* The TLS settings, if tls is chosen as
* a sip transport.
*/
pjsip_tls_setting * _tlsSetting;
/**
* A flag telling if tls is enabled or not.
*/
bool _tlsEnabled;
pj_uint16_t _tlsPort;
/**
* To check if the account is registered
*/
......
......@@ -3,7 +3,8 @@
*
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Yun Liu <yun.liu@savoirfairelinux.com>
*
* Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
......@@ -29,6 +30,7 @@
#include "sip/sdp.h"
#include "pjsip/sip_endpoint.h"
#include "pjsip/sip_transport_tls.h"
#include <netinet/in.h>
#include <arpa/nameser.h>
......@@ -1778,7 +1780,6 @@ int SIPVoIPLink::createUDPServer (void)
pj_strdup2 (_pool, &a_name.host, tmpIP);
a_name.port = (pj_uint16_t) _localExternPort;
status = pjsip_udp_transport_start (_endpt, &bound_addr, &a_name, 1, NULL);
if (status != PJ_SUCCESS) {
......@@ -1788,12 +1789,57 @@ int SIPVoIPLink::createUDPServer (void)
_debug ("UserAgent: UDP server listening on port %d\n", _localExternPort);
}
_debug ("Transport initialized successfully! \n");
return PJ_SUCCESS;
}
int SIPVoIPLink::createTLSServer(AccountID id)
{
pjsip_tpfactory *tls;
pj_sockaddr_in local_addr;
pjsip_host_port a_name;
pj_status_t status;
/* Grab the tls settings, populated
* from configuration file.
*/
SIPAccount * account = NULL;
account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount(id));
if (account == NULL) {
_debug("Account is null. Returning");
return !PJ_SUCCESS;
}
/**
* Init local address.
* IP interface address is not specified,
* so socket will be bound to PJ_INADDR_ANY.
* If user specified port is an empty string
* of if is equal to 0, then the port will
* be chosen automatically by the OS.
*/
pj_sockaddr_in_init(&local_addr, 0, 0);
pj_uint16_t localTlsPort = account->getTlsPort();
if (localTlsPort != 0) {
local_addr.sin_port = pj_htons(localTlsPort);
}
/* Init published name */
pj_bzero(&a_name, sizeof(pjsip_host_port));
pj_cstr(&a_name.host, _localExternAddress.c_str());
a_name.port = (pj_uint16_t) _localExternPort;
pjsip_tls_setting * tls_setting = account->getTlsSetting();
status = pjsip_tls_transport_start(_endpt, tls_setting, &local_addr, &a_name, 1, &tls);
if (status != PJ_SUCCESS) {
_debug("Error creating SIP TLS listener (%d)\n", status);
}
return PJ_SUCCESS;
}
bool SIPVoIPLink::loadSIPLocalIP()
{
......
......@@ -362,6 +362,9 @@ class SIPVoIPLink : public VoIPLink
/** Create SIP UDP Listener */
int createUDPServer();
/** Create SIP TLS Listener */
int createTLSServer(AccountID id);
bool loadSIPLocalIP();
std::string getLocalIP() {return _localExternAddress;}
......
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