Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 12340) +++ channels/chan_sip.c (arbetskopia) @@ -115,8 +115,12 @@ #define SRTP_MASTERSALT_LEN (SRTP_MASTER_LEN - SRTP_MASTERKEY_LEN) #define SRTP_MASTER_LEN64 ((SRTP_MASTER_LEN * 8 + 5) / 6 + 1) +/* SRTP flags */ +#define SRTP_ENCR_OPTIONAL 1 /* SRTP encryption optional */ + /*! \brief structure for secure RTP audio */ struct sip_srtp { + unsigned int flags; char *a_crypto; unsigned char local_key[SRTP_MASTER_LEN]; char local_key64[SRTP_MASTER_LEN64]; @@ -2147,6 +2151,11 @@ if (!ast_srtp_is_registered()) return -1; + if (ast_test_flag(p, SIP_OUTGOING) && !srtp) { + ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n"); + return -1; + } + /* Crypto already accepted */ if (srtp && srtp->a_crypto) return -1; @@ -2284,6 +2293,11 @@ ast_log(LOG_WARNING, "SIP SRTP sdes setup failed\n"); return -1; } + + if (!strcasecmp(ast_var_value(current), "optional")) { + ast_set_flag(p->srtp, SRTP_ENCR_OPTIONAL); + } + } } @@ -4708,6 +4722,7 @@ int debug; const char *protocol = NULL; struct sip_srtp *srtp = p->srtp; + const char a_encr_optional[] = "a=encryption:optional\r\n"; debug = sip_debug_test_pvt(p); @@ -4765,7 +4780,7 @@ } } - if (a_crypto) { + if (a_crypto && !ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) { protocol = "SAVP"; } else { protocol = "AVP"; @@ -4864,8 +4879,12 @@ if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */ len += strlen(m_video) + strlen(a_video); - if (a_crypto) + if (a_crypto) { len += strlen(a_crypto); + if (ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) { + len += strlen(a_encr_optional); + } + } add_header(resp, "Content-Type", "application/sdp"); add_header_contentLength(resp, len); @@ -4876,8 +4895,12 @@ add_line(resp, t); add_line(resp, m_audio); add_line(resp, a_audio); - if (a_crypto) + if (a_crypto) { add_line(resp, a_crypto); + if (ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) { + add_line(resp, a_encr_optional); + } + } if ((p->vrtp) && (!ast_test_flag(p, SIP_NOVIDEO)) && (capability & VIDEO_CODEC_MASK)) { /* only if video response is appropriate */ add_line(resp, m_video); add_line(resp, a_video);