diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 8326828dce..4523105b10 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -85,6 +85,7 @@ SWITCH_DECLARE(switch_status)switch_rtp_create(switch_rtp **new_rtp_session, uint32_t packet_size, uint32_t ms_per_packet, switch_rtp_flag_t flags, + char *crypto_key, const char **err, switch_memory_pool *pool); @@ -111,6 +112,7 @@ SWITCH_DECLARE(switch_rtp *)switch_rtp_new(char *rx_host, uint32_t packet_size, uint32_t ms_per_packet, switch_rtp_flag_t flags, + char *crypto_key, const char **err, switch_memory_pool *pool); diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index ea66d9dde6..201db84095 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -1290,6 +1290,7 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi tech_pvt->read_codec.implementation->encoded_bytes_per_frame, tech_pvt->read_codec.implementation->microseconds_per_frame, 0, + NULL, &err, switch_core_session_get_pool(tech_pvt->session)))) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "RTP ERROR %s\n", err); switch_channel_hangup(channel); diff --git a/src/mod/endpoints/mod_exosip/mod_exosip.c b/src/mod/endpoints/mod_exosip/mod_exosip.c index 0d568aefa4..598da364ee 100644 --- a/src/mod/endpoints/mod_exosip/mod_exosip.c +++ b/src/mod/endpoints/mod_exosip/mod_exosip.c @@ -89,6 +89,7 @@ static struct { int codec_ms; int dtmf_duration; unsigned int flags; + char *crypto_key; } globals; struct private_object { @@ -137,6 +138,7 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan) SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_extip, globals.extip) SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ip, globals.ip) SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string) +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_crypto_key, globals.crypto_key) static switch_status exosip_on_init(switch_core_session *session); static switch_status exosip_on_hangup(switch_core_session *session); @@ -482,6 +484,7 @@ static switch_status activate_rtp(struct private_object *tech_pvt) tech_pvt->read_codec.implementation->encoded_bytes_per_frame, ms, 0, + globals.crypto_key, &err, switch_core_session_get_pool(tech_pvt->session)); if (tech_pvt->rtp_session) { @@ -1572,6 +1575,8 @@ static int config_exosip(int reload) set_global_ip(val); } else if (!strcmp(var, "dialplan")) { set_global_dialplan(val); + } else if (!strcmp(var, "crypto_key")) { + set_global_crypto_key(val); } else if (!strcmp(var, "codec_prefs")) { set_global_codec_string(val); globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index f6846d13e1..c4fe85ccd4 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -44,6 +44,8 @@ #define RTP_START_PORT 16384 #define RTP_END_PORT 32768 #define SWITCH_RTP_CNG_PAYLOAD 13 +#define MAX_KEY_LEN 64 +#define MASTER_KEY_LEN 30 static switch_port_t NEXT_PORT = RTP_START_PORT; static switch_mutex_t *port_lock = NULL; @@ -244,6 +246,7 @@ SWITCH_DECLARE(switch_status) switch_rtp_create(switch_rtp **new_rtp_session, uint32_t packet_size, uint32_t ms_per_packet, switch_rtp_flag_t flags, + char *crypto_key, const char **err, switch_memory_pool *pool) { @@ -269,27 +272,60 @@ SWITCH_DECLARE(switch_status) switch_rtp_create(switch_rtp **new_rtp_session, /* for from address on recvfrom calls */ switch_sockaddr_info_get(&rtp_session->from_addr, NULL, SWITCH_UNSPEC, 0, 0, rtp_session->pool); + memset(&policy, 0, sizeof(policy)); + if (crypto_key) { + int len; + crypto_policy_set_rtp_default(&policy.rtp); + crypto_policy_set_rtcp_default(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = ssrc; + policy.key = (uint8_t *) key; + policy.next = NULL; + policy.rtp.sec_serv = sec_serv_conf_and_auth; + policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */ - - - policy.key = (uint8_t *)key; - policy.ssrc.type = ssrc_specific; - policy.ssrc.value = ssrc; - policy.rtp.cipher_type = NULL_CIPHER; - policy.rtp.cipher_key_len = 0; - policy.rtp.auth_type = NULL_AUTH; - policy.rtp.auth_key_len = 0; - policy.rtp.auth_tag_len = 0; - policy.rtp.sec_serv = sec_serv_none; - policy.rtcp.cipher_type = NULL_CIPHER; - policy.rtcp.cipher_key_len = 0; - policy.rtcp.auth_type = NULL_AUTH; - policy.rtcp.auth_key_len = 0; - policy.rtcp.auth_tag_len = 0; - policy.rtcp.sec_serv = sec_serv_none; - policy.next = NULL; - + /* + * read key from hexadecimal on command line into an octet string + */ + len = hex_string_to_octet_string(key, crypto_key, MASTER_KEY_LEN*2); + + /* check that hex string is the right length */ + if (len < MASTER_KEY_LEN*2) { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, + "error: too few digits in key/salt " + "(should be %d hexadecimal digits, found %d)\n", + MASTER_KEY_LEN*2, len); + return SWITCH_STATUS_FALSE; + } + if (strlen(crypto_key) > MASTER_KEY_LEN*2) { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, + "error: too many digits in key/salt " + "(should be %d hexadecimal digits, found %u)\n", + MASTER_KEY_LEN*2, (unsigned)strlen(crypto_key)); + return SWITCH_STATUS_FALSE; + } + + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "set master key/salt to %s/", octet_string_hex_string(key, 16)); + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s\n", octet_string_hex_string(key+16, 14)); + } else { + policy.key = (uint8_t *)key; + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = ssrc; + policy.rtp.cipher_type = NULL_CIPHER; + policy.rtp.cipher_key_len = 0; + policy.rtp.auth_type = NULL_AUTH; + policy.rtp.auth_key_len = 0; + policy.rtp.auth_tag_len = 0; + policy.rtp.sec_serv = sec_serv_none; + policy.rtcp.cipher_type = NULL_CIPHER; + policy.rtcp.cipher_key_len = 0; + policy.rtcp.auth_type = NULL_AUTH; + policy.rtcp.auth_key_len = 0; + policy.rtcp.auth_tag_len = 0; + policy.rtcp.sec_serv = sec_serv_none; + policy.next = NULL; + } rtp_session->send_msg.header.ssrc = htonl(ssrc); rtp_session->send_msg.header.ts = 0; rtp_session->send_msg.header.seq = (uint16_t) rand(); @@ -331,12 +367,13 @@ SWITCH_DECLARE(switch_rtp *)switch_rtp_new(char *rx_host, uint32_t packet_size, uint32_t ms_per_packet, switch_rtp_flag_t flags, + char *crypto_key, const char **err, switch_memory_pool *pool) { switch_rtp *rtp_session; - if (switch_rtp_create(&rtp_session, payload, packet_size, ms_per_packet, flags, err, pool) != SWITCH_STATUS_SUCCESS) { + if (switch_rtp_create(&rtp_session, payload, packet_size, ms_per_packet, flags, crypto_key, err, pool) != SWITCH_STATUS_SUCCESS) { return NULL; }