]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
ZRTP passthru mode code for phil
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 29 Mar 2012 23:37:10 +0000 (18:37 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 29 Mar 2012 23:37:15 +0000 (18:37 -0500)
src/include/switch_channel.h
src/include/switch_types.h
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/switch_channel.c

index 844013361e25b225172986aab851a392291e8909..d56643445788e1f3d837660221b38d43ecffd8dc 100644 (file)
@@ -403,6 +403,7 @@ SWITCH_DECLARE(void) switch_channel_clear_flag_recursive(switch_channel_t *chann
 SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel, const char *file, const char *func, int line);
 
 SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_channel_t *channel, const char *file, const char *func, int line);
+SWITCH_DECLARE(void) switch_channel_check_zrtp(switch_channel_t *channel);
 
 /*!
   \brief Answer a channel (initiate/acknowledge a successful connection)
index 004b67c727fd51b8f8664cca6c167a30167f6895..87577caae14315777423d1218560493c88f5a48b 100644 (file)
@@ -1208,6 +1208,8 @@ typedef enum {
        CF_VIDEO_REFRESH_REQ,
        CF_SERVICE_AUDIO,
        CF_SERVICE_VIDEO,
+       CF_ZRTP_HASH,
+       CF_ZRTP_PASS,
        /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
        /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
        CF_FLAG_MAX
index 21172b5f90d1b8847d93bae8d55e87c4e98ce8b9..cfcebdab01ee0656764ff9d50a6d6ac233665a57 100644 (file)
@@ -2568,6 +2568,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
                                                }
                                        }
 
+                                       switch_channel_check_zrtp(tech_pvt->channel);
+
                                        if ((status = sofia_glue_tech_choose_port(tech_pvt, 0)) != SWITCH_STATUS_SUCCESS) {
                                                switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
                                                goto end_lock;
index 789bad0da8d2d7a0572821c39637376fd64db499..bedafc2e5ed683873ebb725218c994c00271d85d 100644 (file)
@@ -6270,6 +6270,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                        sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
 
                                        if (match) {
+                                               switch_channel_check_zrtp(channel);
+
                                                if (sofia_glue_tech_choose_port(tech_pvt, 0) == SWITCH_STATUS_SUCCESS) {
                                                        if (sofia_glue_activate_rtp(tech_pvt, 0) == SWITCH_STATUS_SUCCESS) {
                                                                switch_channel_mark_answered(channel);
index b66288ecfb8f48a782268206b6769a4ed1da4ab6..72267d7ea4a6742a05ce83857a0ea0f48ac7bb4b 100644 (file)
@@ -184,7 +184,8 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
        int rate;
        int already_did[128] = { 0 };
        int ptime = 0, noptime = 0;
-       
+       const char *zrtp;
+
        switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP", 
                                        port, secure ? "S" : "");
                                
@@ -343,6 +344,10 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
                switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ptime:%d\n", cur_ptime);
        }
 
+       if ((zrtp = switch_channel_get_variable(tech_pvt->channel, "sdp_zrtp_hash_string"))) {
+               switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=zrtp-hash:%s\n", zrtp); 
+       }
+
        if (sr) {
                switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=%s\n", sr);
        }
@@ -386,6 +391,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
        switch_event_t *map = NULL, *ptmap = NULL;
        const char *b_sdp = NULL;
        int verbose_sdp = 0;
+       const char *zrtp;
 
        sofia_glue_check_dtmf_type(tech_pvt);
 
@@ -539,6 +545,10 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
                        switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=ptime:%d\n", ptime);
                }
 
+               if ((zrtp = switch_channel_get_variable(tech_pvt->channel, "sdp_zrtp_hash_string"))) {
+                       switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=zrtp-hash:%s\n", zrtp); 
+               }
+
                if (sr) {
                        switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=%s\n", sr);
                }
@@ -3552,6 +3562,14 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
                switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, tech_pvt->remote_sdp_audio_ip);
                switch_channel_set_variable(tech_pvt->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
 
+
+               if (switch_channel_test_flag(tech_pvt->channel, CF_ZRTP_PASS)) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_INFO, "Activating ZRTP PROXY MODE\n");
+                       sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
+                       switch_rtp_udptl_mode(tech_pvt->rtp_session);
+               }
+
+
        video:
 
                sofia_glue_check_video_codecs(tech_pvt);
@@ -4657,12 +4675,13 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
 
                                if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) {
                                        switch_channel_set_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port", attr->a_value);
-                               }
-
-                               if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
+                               } else if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
                                        ptime = atoi(attr->a_value);
                                } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) {
                                        maxptime = atoi(attr->a_value);
+                               } else if (!strcasecmp(attr->a_name, "zrtp-hash") && attr->a_value) {
+                                       switch_channel_set_variable(tech_pvt->channel, "sdp_zrtp_hash_string", attr->a_value);
+                                       switch_channel_set_flag(tech_pvt->channel, CF_ZRTP_HASH);
                                } else if (!got_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) {
                                        int crypto_tag;
 
index 2e6ccf7ffddc318a4afeff8e752446ccecf9442c..58f72e504d8419157146d894b9a4c579a42cbc64 100644 (file)
@@ -2918,6 +2918,58 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi
        return SWITCH_STATUS_FALSE;
 }
 
+SWITCH_DECLARE(void) switch_channel_check_zrtp(switch_channel_t *channel)
+{
+
+       if (switch_channel_test_flag(channel, CF_ZRTP_HASH) && !switch_channel_test_flag(channel, CF_ZRTP_PASS)) {
+               switch_core_session_t *other_session;
+               switch_channel_t *other_channel;
+               int doit = 1;
+               
+               if (switch_core_session_get_partner(channel->session, &other_session) == SWITCH_STATUS_SUCCESS) {
+                       other_channel = switch_core_session_get_channel(other_session);
+
+                       if (switch_channel_test_flag(other_channel, CF_ZRTP_HASH) && !switch_channel_test_flag(other_channel, CF_ZRTP_PASS)) {
+                               
+                               switch_channel_set_flag(channel, CF_ZRTP_PASS);
+                               switch_channel_set_flag(other_channel, CF_ZRTP_PASS);
+                       
+                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_INFO, 
+                                                                 "%s Activating ZRTP passthru mode.\n", switch_channel_get_name(channel));
+       
+                               switch_channel_set_variable(channel, "zrtp_secure_media", "false");
+                               switch_channel_set_variable(other_channel, "zrtp_secure_media", "false");
+                               doit = 0;
+                       }
+
+                       switch_core_session_rwunlock(other_session);
+               }
+
+               if (doit) {
+                       switch_channel_set_variable(channel, "zrtp_secure_media", "true");
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(channel->session), SWITCH_LOG_INFO, 
+                                                         "%s ZRTP not negotiated on both sides, Activating ZRTP man-in-the-middle mode.\n", switch_channel_get_name(channel));
+
+                       switch_channel_clear_flag(channel, CF_ZRTP_PASS);
+                       switch_channel_clear_flag(channel, CF_ZRTP_HASH);
+
+                       if (switch_core_session_get_partner(channel->session, &other_session) == SWITCH_STATUS_SUCCESS) {
+                               other_channel = switch_core_session_get_channel(other_session);  
+
+                               switch_channel_set_variable(other_channel, "zrtp_secure_media", "true");
+                               switch_channel_clear_flag(other_channel, CF_ZRTP_PASS);
+                               switch_channel_clear_flag(other_channel, CF_ZRTP_HASH);
+                               
+                               switch_core_session_rwunlock(other_session);
+                       }
+
+               }
+       }
+}
+
+
+
+
 SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_channel_t *channel, const char *file, const char *func, int line)
 {
        switch_event_t *event;
@@ -2927,6 +2979,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_pre_answered(switch_
                const char *uuid;
                switch_core_session_t *other_session;
 
+               switch_channel_check_zrtp(channel);
                switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Pre-Answer %s!\n", channel->name);
                switch_channel_set_flag(channel, CF_EARLY_MEDIA);
                switch_channel_set_callstate(channel, CCS_EARLY);
@@ -3186,6 +3239,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan
                switch_mutex_unlock(channel->profile_mutex);
        }
 
+       switch_channel_check_zrtp(channel);
        switch_channel_set_flag(channel, CF_ANSWERED);
        switch_channel_set_callstate(channel, CCS_ACTIVE);
 
@@ -3265,6 +3319,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *
                return SWITCH_STATUS_SUCCESS;
        }
        
+
        msg.message_id = SWITCH_MESSAGE_INDICATE_ANSWER;
        msg.from = channel->name;
        status = switch_core_session_perform_receive_message(channel->session, &msg, file, func, line);