From 0d1acb08ffedb2d80bf1ad5abc38872e96fcef75 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 18 Dec 2012 22:02:19 -0600 Subject: [PATCH] add video srtp --- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 ++ src/mod/endpoints/mod_sofia/sofia_glue.c | 15 +++++++- src/mod/endpoints/mod_sofia/sofia_media.c | 42 +++++++++++++++++++++-- src/switch_core_session.c | 1 + 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index abcfebbcac..6be5927507 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -114,7 +114,9 @@ typedef struct private_object private_object_t; #define SOFIA_REFER_TO_VARIABLE "sip_refer_to" #define SOFIA_SECURE_MEDIA_VARIABLE "sip_secure_media" #define SOFIA_SECURE_MEDIA_CONFIRMED_VARIABLE "sip_secure_media_confirmed" +#define SOFIA_SECURE_VIDEO_CONFIRMED_VARIABLE "sip_secure_video_confirmed" #define SOFIA_HAS_CRYPTO_VARIABLE "sip_has_crypto" +#define SOFIA_HAS_VIDEO_CRYPTO_VARIABLE "sip_has_video_crypto" #define SOFIA_CRYPTO_MANDATORY_VARIABLE "sip_crypto_mandatory" #define FREESWITCH_SUPPORT "update_display,send_info" diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 8db76a09a8..b15a4ce15c 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -188,6 +188,7 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen, int ptime = 0, noptime = 0; const char *local_audio_crypto_key = switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO); + switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP", port, secure ? "S" : ""); @@ -654,12 +655,17 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch } if (sofia_test_flag(tech_pvt, TFLAG_VIDEO)) { + const char *local_video_crypto_key = switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO); + if (!tech_pvt->local_sdp_video_port) { sofia_glue_tech_choose_video_port(tech_pvt, 0); } if ((v_port = tech_pvt->adv_sdp_video_port)) { - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video %d RTP/AVP", v_port); + + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video %d RTP/%sAVP", + v_port, (!zstr(local_video_crypto_key) && switch_channel_test_flag(tech_pvt->channel, CF_SECURE)) ? "S" : ""); + /*****************************/ if (tech_pvt->video_rm_encoding) { @@ -768,6 +774,12 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch } + if (switch_channel_test_flag(tech_pvt->channel, CF_SECURE)) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=crypto:%s\n", local_video_crypto_key); + //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n"); + } + + if (tech_pvt->local_sdp_video_zrtp_hash) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Adding video a=zrtp-hash:%s\n", tech_pvt->local_sdp_video_zrtp_hash); @@ -4090,6 +4102,7 @@ int sofia_recover_callback(switch_core_session_t *session) switch_core_session_get_recovery_crypto_key(session, SWITCH_MEDIA_TYPE_AUDIO, "srtp_remote_audio_crypto_key"); + switch_core_session_get_recovery_crypto_key(session, SWITCH_MEDIA_TYPE_VIDEO, "srtp_remote_video_crypto_key"); if ((tmp = switch_channel_get_variable(channel, "sip_local_sdp_str"))) { tech_pvt->local_sdp_str = switch_core_session_strdup(session, tmp); diff --git a/src/mod/endpoints/mod_sofia/sofia_media.c b/src/mod/endpoints/mod_sofia/sofia_media.c index 5d3704b872..738f27cb12 100644 --- a/src/mod/endpoints/mod_sofia/sofia_media.c +++ b/src/mod/endpoints/mod_sofia/sofia_media.c @@ -326,7 +326,7 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s switch_channel_t *channel = switch_core_session_get_channel(session); const char *val; const char *crypto = NULL; - int got_crypto = 0, got_audio = 0, got_avp = 0, got_savp = 0, got_udptl = 0; + int got_crypto = 0, got_video_crypto = 0, got_audio = 0, got_avp = 0, got_video_avp = 0, got_video_savp = 0, got_savp = 0, got_udptl = 0; int scrooge = 0; sdp_parser_t *parser = NULL; sdp_session_t *sdp; @@ -492,9 +492,17 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s maxptime = dmaxptime; if (m->m_proto == sdp_proto_srtp) { - got_savp++; + if (m->m_type == sdp_media_audio) { + got_savp++; + } else { + got_video_savp++; + } } else if (m->m_proto == sdp_proto_rtp) { - got_avp++; + if (m->m_type == sdp_media_audio) { + got_avp++; + } else { + got_video_avp++; + } } else if (m->m_proto == sdp_proto_udptl) { got_udptl++; } @@ -950,8 +958,34 @@ 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_video_rtcp_port", attr->a_value); + + } else if (!got_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) { + int crypto_tag; + + if (!(tech_pvt->profile->ndlb & SM_NDLB_ALLOW_CRYPTO_IN_AVP) && + !switch_true(switch_channel_get_variable(tech_pvt->channel, "sip_allow_crypto_in_avp"))) { + if (m->m_proto != sdp_proto_srtp) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "a=crypto in RTP/AVP, refer to rfc3711\n"); + match = 0; + goto done; + } + } + + crypto = attr->a_value; + crypto_tag = atoi(crypto); + + got_video_crypto = switch_core_session_check_incoming_crypto(tech_pvt->session, + SOFIA_HAS_VIDEO_CRYPTO_VARIABLE, + SWITCH_MEDIA_TYPE_VIDEO, crypto, crypto_tag); + } } + + if (got_video_crypto && !got_video_avp) { + switch_channel_set_variable(tech_pvt->channel, SOFIA_CRYPTO_MANDATORY_VARIABLE, "true"); + switch_channel_set_variable(tech_pvt->channel, SOFIA_SECURE_MEDIA_VARIABLE, "true"); + } + if (!(rm_encoding = map->rm_encoding)) { rm_encoding = ""; } @@ -1665,6 +1699,8 @@ switch_status_t sofia_media_activate_rtp(private_object_t *tech_pvt) tech_pvt->video_ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session); switch_channel_set_variable_printf(tech_pvt->channel, "rtp_use_video_ssrc", "%u", tech_pvt->ssrc); + switch_core_session_apply_crypto(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO, SOFIA_SECURE_VIDEO_CONFIRMED_VARIABLE); + if ((val = switch_channel_get_variable(tech_pvt->channel, "rtcp_audio_interval_msec")) || (val = tech_pvt->profile->rtcp_audio_interval_msec)) { diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 410ffa711b..dd617fe8d3 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -2025,6 +2025,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_xml(switch_e flags[CF_LAZY_ATTENDED_TRANSFER] = 0; flags[CF_SIGNAL_DATA] = 0; flags[CF_SIMPLIFY] = 0; + flags[CF_SECURE] = 0; if (!(session = switch_core_session_request_uuid(endpoint_interface, direction, SOF_NO_LIMITS, pool, uuid))) {