diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp index a2149efd45333b76c51ce65fc3d3e64626318976..52e1079dcdd71c400f4964bf3b104a6c5bb0ba6a 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp +++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp @@ -91,7 +91,7 @@ namespace sfl { if (helloHashEnabled) { // TODO: be careful with that. The hello hash is computed asynchronously. Maybe it's // not even available at that point. - //ca->getLocalSDP()->setZrtpHash(static_cast<AudioZrtpSession *>(_rtpSession)->getHelloHash()); + ca->getLocalSDP()->set_zrtp_hash(static_cast<AudioZrtpSession *>(_rtpSession)->getHelloHash()); _debug("Zrtp hello hash fed to SDP\n"); } break; diff --git a/sflphone-common/src/audio/audiortp/AudioRtpSession.h b/sflphone-common/src/audio/audiortp/AudioRtpSession.h index 2e729ebee584717a79311b9e036210887c0fa2e9..244ba129967196c4ca738dbf2d74a402b52c7015 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioRtpSession.h @@ -36,11 +36,7 @@ #include "managerimpl.h" #include <ccrtp/rtp.h> -//#include <ccrtp/formats.h> -//#include <ccrtp/queuebase.h> -//#include <cc++/thread.h> -#include <cc++/numbers.h> -//#include <cc++/socket.h> +#include <cc++/numbers.h> // ost::Time namespace sfl { diff --git a/sflphone-common/src/audio/audiortp/AudioZrtpSession.h b/sflphone-common/src/audio/audiortp/AudioZrtpSession.h index d552da20cd2464ee399ff1e6ba2edabadbddaeac..2e41e04b45b42086f903e551207563cdd9fdfba7 100644 --- a/sflphone-common/src/audio/audiortp/AudioZrtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioZrtpSession.h @@ -38,13 +38,13 @@ namespace sfl { class AudioZrtpSession : public ost::SymmetricZRTPSession, public AudioRtpSession<AudioZrtpSession> { public: - AudioZrtpSession(ManagerImpl * manager, SIPCall * sipcall, const std::string& zidFilename); private: void initializeZid(void); std::string _zidFilename; }; + } #endif // __AUDIO_ZRTP_SESSION_H__ diff --git a/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.cpp b/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.cpp index 034cdafe83fbbb0468f31fb8feb3cadd8c8c0e55..9cfe6ef15ebdab8a72356580afb6f717ac21d688 100644 --- a/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.cpp +++ b/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.cpp @@ -20,6 +20,9 @@ #include "ZrtpSessionCallback.h" #include "manager.h" #include "global.h" +#include "dbus/dbusmanagerimpl.h" +#include "sip/sipcall.h" +#include "dbus/callmanager.h" #include <cstdlib> #include <string> @@ -31,7 +34,9 @@ using namespace std; namespace sfl { - ZrtpSessionCallback::ZrtpSessionCallback(SIPCall *sipcall): _sipcall(sipcall) + ZrtpSessionCallback::ZrtpSessionCallback(SIPCall *sipcall): + _sipcall(sipcall), + _dbusManager(NULL) { if(_mapInitialized) { @@ -104,34 +109,40 @@ namespace sfl { _mapInitialized = true; + _dbusManager = Manager::instance().getDbusManager(); + if (_dbusManager == NULL) { + throw ZrtpSessionCallbackException(); + } + + } void ZrtpSessionCallback::secureOn(std::string cipher) { _debug("Secure mode is on with cipher %s\n", cipher.c_str()); - //Manager::instance().secureOn(_sipcall->getCallId(), cipher); + _dbusManager->getCallManager()->secureOn(_sipcall->getCallId(), cipher); } void ZrtpSessionCallback::secureOff(void) { _debug("Secure mode is off\n"); - //Manager::instance().secureOff(_sipcall->getCallId()); + _dbusManager->getCallManager()->secureOff(_sipcall->getCallId()); } void ZrtpSessionCallback::showSAS(std::string sas, bool verified) { - _debug("SAS is: %s\n", sas.c_str()); - // Manager::instance().showSAS(_sipcall->getCallId(),sas,verified); + _debug("SAS is: %s\n", sas.c_str()); + _dbusManager->getCallManager()->showSAS(_sipcall->getCallId(), sas, verified); } void ZrtpSessionCallback::zrtpNotSuppOther() { _debug("Callee does not support ZRTP\n"); - //Manager::instance().zrtpNotSuppOther(_sipcall->getCallId()); + _dbusManager->getCallManager()->zrtpNotSuppOther(_sipcall->getCallId()); } void @@ -174,7 +185,7 @@ namespace sfl { void ZrtpSessionCallback::zrtpNegotiationFailed(MessageSeverity severity, int subCode) { - string* msg; + string* msg; if (severity == ZrtpError) { if (subCode < 0) { // received an error packet from peer subCode *= -1; @@ -186,13 +197,13 @@ namespace sfl { msg = _zrtpMap[subCode]; if (msg != NULL) { _debug("%s\n", msg->c_str()); - // Manager::instance().zrtpNegotiationFailed(_sipcall->getCallId(), *msg, "ZRTP"); + _dbusManager->getCallManager()->zrtpNegotiationFailed(_sipcall->getCallId(), *msg, "ZRTP"); } } else { msg = _severeMap[subCode]; _debug("%s\n", msg->c_str()); - // Manager::instance().zrtpNegotiationFailed(_sipcall->getCallId(), *msg, "SEVERE"); + _dbusManager->getCallManager()->zrtpNegotiationFailed(_sipcall->getCallId(), *msg, "SEVERE"); } } @@ -200,7 +211,7 @@ namespace sfl { ZrtpSessionCallback::confirmGoClear() { _debug("Received go clear message. Until confirmation, ZRTP won't send any data\n"); - // Manager::instance().confirmGoClear(_sipcall->getCallId()); + _dbusManager->getCallManager()->zrtpNotSuppOther(_sipcall->getCallId()); } map<int32, std::string*>ZrtpSessionCallback::_infoMap; diff --git a/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.h b/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.h index 49db26150c7dcd79edb799e1ce1ebf9366188824..b354162f3f9743479a66518b0a83754cb26d2c1a 100644 --- a/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.h +++ b/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.h @@ -23,10 +23,22 @@ #include <libzrtpcpp/zrtpccrtp.h> #include <libzrtpcpp/ZrtpQueue.h> #include <libzrtpcpp/ZrtpUserCallback.h> +#include <exception> +#include <map> -#include "sip/sipcall.h" +class SIPCall; +class DBusManagerImpl; namespace sfl { + + class ZrtpSessionCallbackException: public std::exception + { + virtual const char* what() const throw() + { + return "An exception occured while being in a zrtp callback\n"; + } + }; + class ZrtpSessionCallback: public ZrtpUserCallback { public: ZrtpSessionCallback(SIPCall *sipcall); @@ -38,8 +50,11 @@ namespace sfl { void showMessage(GnuZrtpCodes::MessageSeverity sev, int32_t subCode); void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int subCode); void confirmGoClear(); + private: SIPCall* _sipcall; + DBusManagerImpl * _dbusManager; + static std::map<int32, std::string*> _infoMap; static std::map<int32, std::string*> _warningMap; static std::map<int32, std::string*> _severeMap; diff --git a/sflphone-common/src/dbus/callmanager-introspec.xml b/sflphone-common/src/dbus/callmanager-introspec.xml index feabbb1a23739cb9e3a3a67f6871658f866ccbc5..d9917be3492bb8baf60ce4593e24fdac93d5b851 100644 --- a/sflphone-common/src/dbus/callmanager-introspec.xml +++ b/sflphone-common/src/dbus/callmanager-introspec.xml @@ -116,6 +116,36 @@ <signal name="transferFailed"> </signal> + + <!-- ZRTP Methods and Signals --> + <signal name="secureOn"> + <arg type="s" name="callID" direction="out" /> + <arg type="s" name="cipher" direction="out" /> + </signal> + + <signal name="secureOff"> + <arg type="s" name="callID" direction="out" /> + </signal> + + <signal name="confirmGoClear"> + <arg type="s" name="callID" direction="out" /> + </signal> + + <signal name="zrtpNegotiationFailed"> + <arg type="s" name="callID" direction="out" /> + <arg type="s" name="reason" direction="out" /> + <arg type="s" name="severity" direction="out" /> + </signal> + + <signal name="zrtpNotSuppOther"> + <arg type="s" name="callID" direction="out" /> + </signal> + + <signal name="showSAS"> + <arg type="s" name="callID" direction="out" /> + <arg type="s" name="sas" direction="out" /> + <arg type="b" name="verified" direction="out" /> + </signal> <method name="setSASVerified"> <arg type="s" name="callID" direction="in"/> diff --git a/sflphone-common/src/global.h b/sflphone-common/src/global.h index 9192121084a972a2b2bc432b828e4231d035f6fb..72b6451c285d0723b590921cbd5a0a09403fb850 100644 --- a/sflphone-common/src/global.h +++ b/sflphone-common/src/global.h @@ -38,6 +38,7 @@ #define XDG_DATA_HOME (getenv ("XDG_DATA_HOME")) #define XDG_CONFIG_HOME (getenv ("XDG_CONFIG_HOME")) #define XDG_CACHE_HOME (getenv ("XDG_CACHE_HOME")) +#define ZRTP_ZID_FILENAME "sfl.zid" typedef float float32; typedef short int16; diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index 7ced87c662b7f8c126a6acb532484c2f470f40f6..b41523eb78c80b8fb5ba56080eddff9749800274 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -26,6 +26,7 @@ #include "account.h" #include "dbus/callmanager.h" #include "user_cfg.h" +#include "global.h" #include "sip/sipaccount.h" #include "audio/audiolayer.h" #include "audio/alsa/alsalayer.h" @@ -1338,6 +1339,14 @@ ManagerImpl::initConfigFile (bool load_user_value, std::string alternate) // Default values, that will be overwritten by the call to // 'populateFromFile' below. + section = IP2IP_PROFILE; + fill_config_int(SRTP_ENABLE, NO_STR); + fill_config_int(SRTP_KEY_EXCHANGE, YES_STR); + fill_config_int(ZRTP_HELLO_HASH, YES_STR); + fill_config_int(ZRTP_DISPLAY_SAS, YES_STR); + fill_config_int(ZRTP_DISPLAY_SAS_ONCE, NO_STR); + fill_config_int(ZRTP_NOT_SUPP_WARNING, YES_STR); + section = SIGNALISATION; fill_config_int (SYMMETRIC, YES_STR); fill_config_int (PLAY_DTMF, YES_STR); @@ -1346,6 +1355,7 @@ ManagerImpl::initConfigFile (bool load_user_value, std::string alternate) fill_config_int (SEND_DTMF_AS, SIP_INFO_STR); fill_config_int (STUN_ENABLE, DFT_STUN_ENABLE); fill_config_int (STUN_SERVER, DFT_STUN_SERVER); + fill_config_int (ZRTP_ZIDFILE, ZRTP_ZID_FILENAME); section = AUDIO; fill_config_int (ALSA_CARD_ID_IN, ALSA_DFT_CARD); diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h index bfe8d25a7dd643e1a0a89e42c3362eb8c2e61ea4..4f38c18426ddee5239ff6af0f8c91a16e1f81ef5 100644 --- a/sflphone-common/src/managerimpl.h +++ b/sflphone-common/src/managerimpl.h @@ -1163,8 +1163,15 @@ class ManagerImpl { * Unload the account (delete them) */ void unloadAccountMap(); - + public: + + /** + * Return the current DBusManagerImpl + * @return A pointer to the DBusManagerImpl instance + */ + DBusManagerImpl * getDbusManager() { return _dbus; } + /** * Tell if an account exists * @param accountID account ID check diff --git a/sflphone-common/src/sip/sdp.cpp b/sflphone-common/src/sip/sdp.cpp index 24d4368a100d2f400b560d93d39aed372409fa01..d07efce140537f002a349b3dd813b1ef9180d3ba 100644 --- a/sflphone-common/src/sip/sdp.cpp +++ b/sflphone-common/src/sip/sdp.cpp @@ -21,7 +21,7 @@ #include "sdp.h" #include "global.h" #include "manager.h" - +#define ZRTP_VERSION "1.10" static const pj_str_t STR_AUDIO = { (char*) "audio", 5}; static const pj_str_t STR_VIDEO = { (char*) "video", 5}; @@ -33,7 +33,6 @@ static const pj_str_t STR_SDP_NAME = { (char*) "sflphone", 8 }; static const pj_str_t STR_SENDRECV = { (char*) "sendrecv", 8 }; static const pj_str_t STR_RTPMAP = { (char*) "rtpmap", 6 }; - Sdp::Sdp (pj_pool_t *pool) : _local_media_cap() , _session_media (0) @@ -116,10 +115,18 @@ void Sdp::set_media_descriptor_line (sdpMedia *media, pjmedia_sdp_media** p_med) // Add the direction stream attr = (pjmedia_sdp_attr*) pj_pool_zalloc (_pool, sizeof (pjmedia_sdp_attr)); - pj_strdup2 (_pool, &attr->name, media->get_stream_direction_str().c_str()); - med->attr[ med->attr_count++] = attr; + + if(!_zrtp_hello_hash.empty()) { + try { + sdp_add_zrtp_attribute(med,_zrtp_hello_hash); + } catch (...) { + throw; + } + } else { + _debug("No hash specified\n"); + } *p_med = med; } @@ -340,6 +347,32 @@ void Sdp::sdp_add_media_description() } } +void Sdp::sdp_add_zrtp_attribute(pjmedia_sdp_media* media, std::string hash) +{ + pjmedia_sdp_attr *attribute; + char tempbuf[256]; + int len; + + attribute = (pjmedia_sdp_attr*)pj_pool_zalloc( _pool, sizeof(pjmedia_sdp_attr) ); + + attribute->name = pj_strdup3(_pool, "zrtp-hash"); + + /* Format: ":version value" */ + len = pj_ansi_snprintf(tempbuf, sizeof(tempbuf), + "%.*s %.*s", + 4, + ZRTP_VERSION, + hash.size(), + hash.c_str()); + + attribute->value.slen = len; + attribute->value.ptr = (char*) pj_pool_alloc(_pool, attribute->value.slen+1); + pj_memcpy(attribute->value.ptr, tempbuf, attribute->value.slen+1); + + if(pjmedia_sdp_media_add_attr(media, attribute) != PJ_SUCCESS) { + throw sdpException(); + } +} std::string Sdp::media_to_string (void) { diff --git a/sflphone-common/src/sip/sdp.h b/sflphone-common/src/sip/sdp.h index d0673dd25536821ed6905053f62a4d28015a980c..9500fa318539b7185742747d1d6103398cd3c2f8 100644 --- a/sflphone-common/src/sip/sdp.h +++ b/sflphone-common/src/sip/sdp.h @@ -33,6 +33,16 @@ #include "audio/codecs/codecDescriptor.h" #include "sdpmedia.h" +#include <exception> + +class sdpException: public std::exception +{ + virtual const char* what() const throw() + { + return "An sdpException Occured"; + } +}; + class Sdp { public: @@ -80,11 +90,18 @@ class Sdp { * Build the sdp media section * Add rtpmap field if necessary * - * @param media The media to add to SDP + * @param media The media to add to SDP * @param med The structure to receive the media section */ void set_media_descriptor_line( sdpMedia* media, pjmedia_sdp_media** p_med ); + /* Set the zrtp hash that was previously calculated from the hello message in the zrtp layer. + * This hash value is unique at the media level. Therefore, if video support is added, one would + * have to set the correct zrtp-hash value in the corresponding media section. + * @param hash The hello hash of a rtp session. (Only audio at the moment) + */ + inline void set_zrtp_hash(const std::string& hash) { _zrtp_hello_hash = hash; _debug("Zrtp hash set with %s\n", hash.c_str()); } + /* * On building an invite outside a dialog, build the local offer and create the * SDP negociator instance with it. @@ -229,6 +246,8 @@ class Sdp { /** Remote's audio port */ unsigned int _remote_audio_port; + std::string _zrtp_hello_hash; + Sdp(const Sdp&); //No Copy Constructor Sdp& operator=(const Sdp&); //No Assignment Operator @@ -317,8 +336,16 @@ class Sdp { void get_remote_sdp_media_from_offer (const pjmedia_sdp_session* r_sdp, pjmedia_sdp_media** r_media); -//////////////////////////////////////////////////////////////////3 -//////////////////////////////////////////////////////////////////// + /* + * Adds a zrtp-hash attribute to + * the given media section. The hello hash is + * available only after is has been computed + * in the AudioZrtpSession constructor. + * + * @param media The media to add the zrtp-hash attribute to + * @param hash The hash to which the attribute should be set to + */ + void sdp_add_zrtp_attribute(pjmedia_sdp_media* media, std::string hash); };