Index: build_tools/menuselect-deps.in =================================================================== --- build_tools/menuselect-deps.in (revision 34342) +++ build_tools/menuselect-deps.in (arbetskopia) @@ -26,3 +26,4 @@ LIBGSM=@PBX_LIBgsm@ IKSEMEL=@PBX_LIBIKSEMEL@ IXJUSER=@PBX_IXJUSER@ +LIBSRTP=@PBX_LIBSRTP@ Index: utils.c =================================================================== --- utils.c (revision 34342) +++ utils.c (arbetskopia) @@ -358,7 +358,7 @@ byte |= *(src++); bits += 8; cntin++; - if ((bits == 24) && (cnt + 4 < max)) { + if ((bits == 24) && (cnt + 4 <= max)) { *dst++ = base64[(byte >> 18) & 0x3f]; *dst++ = base64[(byte >> 12) & 0x3f]; *dst++ = base64[(byte >> 6) & 0x3f]; @@ -374,7 +374,7 @@ col = 0; } } - if (bits && (cnt + 4 < max)) { + if (bits && (cnt + 4 <= max)) { /* Add one last character for the remaining bits, padding the rest with 0 */ byte <<= 24 - bits; Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 34342) +++ channels/chan_sip.c (arbetskopia) @@ -168,8 +168,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]; @@ -2676,7 +2680,6 @@ } else if (!strcasecmp(ast_var_name(current),"SIPTRANSFER_REPLACES")) { /* We're replacing a call. */ p->options->replaces = ast_var_value(current); -<<<<<<< .working } else if (!strncasecmp(ast_var_name(current), "SIP_SRTP_SDES", strlen("SIP_SRTP_SDES"))) { if (!ast_srtp_is_registered()) { ast_log(LOG_WARNING, "SIP_SRTP_SDES set but SRTP is not available\n"); @@ -2688,13 +2691,16 @@ 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); + } + } -======= } else if (!strcasecmp(ast_var_name(current),"T38CALL")) { p->t38.state = T38_LOCAL_DIRECT; if (option_debug) ast_log(LOG_DEBUG,"T38State change to %d on channel %s\n", p->t38.state, ast->name); ->>>>>>> .merge-right.r34043 } } @@ -4552,9 +4558,9 @@ while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') { int x; int audio = FALSE; - len = -1; char protocol[5] = ""; + len = -1; numberofmediastreams++; if (p->vrtp) @@ -4753,15 +4759,11 @@ ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype); if (p->vrtp) ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype); + } - if (secure_audio && !(p->srtp && p->srtp->a_crypto)) { - ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n"); - return -2; - } - if (secure_video && !(p->srtp && p->srtp->a_crypto)) { - ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n"); - return -2; - } + if (secure_audio && !(p->srtp && p->srtp->a_crypto)) { + ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n"); + return -2; } if (udptlportno != -1) { @@ -4881,6 +4883,11 @@ ast_log(LOG_DEBUG, "T38 state changed to %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : ""); } + if (secure_video && !(p->srtp && p->srtp->a_crypto)) { + ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n"); + return -2; + } + /* Now gather all of the codecs that we are asked for: */ ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability); ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability); @@ -5813,6 +5820,7 @@ struct sip_srtp *srtp = p->srtp; int needvideo = FALSE; int debug = sip_debug_test_pvt(p); + const char a_encr_optional[] = "a=encryption:optional\r\n"; m_video[0] = '\0'; /* Reset the video media string if it's not needed */ @@ -5881,13 +5889,13 @@ } } - if (a_crypto) { + if (a_crypto && !ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) { protocol = "SAVP"; } else { protocol = "AVP"; } - + /* Ok, we need video. Let's add what we need for video and set codecs. Video is handled differently than audio since we can not transcode. */ @@ -6036,8 +6044,12 @@ if (needvideo) /* only if video response is appropriate */ len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold); - 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); @@ -6050,8 +6062,12 @@ add_line(resp, stime); add_line(resp, m_audio); add_line(resp, a_audio); - if (a_crypto) - len += strlen(a_crypto); + if (a_crypto) { + add_line(resp, a_crypto); + if (ast_test_flag(srtp, SRTP_ENCR_OPTIONAL)) { + add_line(resp, a_encr_optional); + } + } add_line(resp, hold); if (needvideo) { /* only if video response is appropriate */ add_line(resp, m_video); @@ -16479,6 +16495,11 @@ if (!ast_srtp_is_registered()) return -1; + if (ast_test_flag(&p->flags[0], 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; Index: configure.ac =================================================================== --- configure.ac (revision 34342) +++ configure.ac (arbetskopia) @@ -213,6 +213,7 @@ AST_EXT_LIB([tinfo], [tgetent], [], [TINFO], [Term Info]) AST_EXT_LIB([vorbis], [vorbis_info_init], [vorbis/codec.h], [VORBIS], [Vorbis], [-lm -lvorbisenc]) AST_EXT_LIB([z], [compress], [zlib.h], [ZLIB], [zlib]) +AST_EXT_LIB([srtp], [srtp_init], [srtp/srtp.h], [SRTP], [libSRTP]) EDITLINE_LIBS="" if test "x$TERMCAP_LIB" != "x" ; then Index: include/asterisk/rtp.h =================================================================== --- include/asterisk/rtp.h (revision 34342) +++ include/asterisk/rtp.h (arbetskopia) @@ -133,6 +133,7 @@ }; +/*! * \brief Get the amount of space required to hold an RTP session * \return number of bytes required */ Index: include/asterisk/aes.h =================================================================== --- include/asterisk/aes.h (revision 34342) +++ include/asterisk/aes.h (arbetskopia) @@ -115,6 +115,8 @@ #ifdef AES_ENCRYPT +#define aes_encrypt ast_aes_encrypt + typedef struct { aes_32t ks[KS_LENGTH]; } aes_encrypt_ctx; @@ -140,6 +142,8 @@ #ifdef AES_DECRYPT +#define aes_decrypt ast_aes_decrypt + typedef struct { aes_32t ks[KS_LENGTH]; } aes_decrypt_ctx; Index: rtp.c =================================================================== --- rtp.c (revision 34342) +++ rtp.c (arbetskopia) @@ -1174,7 +1174,7 @@ len = sizeof(sin); /* Cache where the header will go */ - res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, + res = rtp_recvfrom(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, 0, (struct sockaddr *)&sin, &len); rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET); @@ -2771,8 +2771,8 @@ if (p0->srtp || p1->srtp) { ast_log(LOG_NOTICE, "Cannot native bridge in SRTP.\n"); - ast_mutex_unlock(&c0->lock); - ast_mutex_unlock(&c1->lock); + ast_channel_unlock(c0); + ast_channel_unlock(c1); return AST_BRIDGE_FAILED_NOWARN; } Index: makeopts.in =================================================================== --- makeopts.in (revision 34342) +++ makeopts.in (arbetskopia) @@ -123,3 +123,6 @@ RADIUSCLIENT_LIB=@RADIUSCLIENT_LIB@ RADIUSCLIENT_INCLUDE=@RADIUSCLIENT_INCLUDE@ + +SRTP_LIB=@SRTP_LIB@ +SRTP_INCLUDE=@SRTP_INCLUDE@ Index: configure =================================================================== Index: res/res_srtp.c =================================================================== --- res/res_srtp.c (revision 0) +++ res/res_srtp.c (arbetskopia) @@ -42,9 +42,12 @@ in clear text, making it easy to eavesdrop. */ -#include #include "asterisk.h" +ASTERISK_FILE_VERSION(__FILE__, "$Revision: $") + +#include + #include "asterisk/lock.h" #include "asterisk/module.h" #include "asterisk/options.h" @@ -67,10 +70,7 @@ static int g_initialized = 0; /* Exported functions */ -int load_module(void); -int unload_module(void); int usecount(void); -char *description(void); /* SRTP functions */ static int res_srtp_create(struct ast_srtp **srtp, @@ -540,12 +540,13 @@ * Exported functions */ -int load_module(void) +static int load_module(void *mod) { + __mod_desc = mod; return res_srtp_init(); } -int unload_module(void) +static int unload_module(void *mod) { return ast_rtp_unregister_srtp(&srtp_res, &policy_res); } @@ -555,12 +556,14 @@ return 1; } -char *description(void) +static const char *description(void) { return (char *)desc; } -char *key() +static const char *key(void) { return ASTERISK_GPL_KEY; } + +STD_MOD(MOD_0 | NO_UNLOAD, NULL, NULL, NULL); Index: res/Makefile =================================================================== --- res/Makefile (revision 34342) +++ res/Makefile (arbetskopia) @@ -104,6 +104,9 @@ res_config_pgsql.o: res_config_pgsql.c $(CC) -c -o $@ $(CFLAGS) $(PGSQL_INCLUDE) $< +res_srtp.so: res_srtp.o + $(CC) $(SOLINK) -o $@ $(CFLAGS) $(SRTP_INCLUDE) $< $(SRTP_LIB) + ifneq ($(wildcard .depend),) include .depend endif