[svn-commits] twilson: branch group/v6-new r269012 - in /team/group/v6-new: ./ apps/ build_...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jun 8 11:09:27 CDT 2010


Author: twilson
Date: Tue Jun  8 11:09:20 2010
New Revision: 269012

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=269012
Log:
Merged revisions 268894,268896,268933,268969 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
  r268894 | twilson | 2010-06-08 00:29:08 -0500 (Tue, 08 Jun 2010) | 17 lines
  
  Add SRTP support for Asterisk
  
  After 5 years in mantis and over a year on reviewboard, SRTP support is finally
  being comitted. This includes generic CHANNEL dialplan functions that work for
  getting the status of whether a call has secure media or signaling as defined
  by the underlying channel technology and for setting whether or not a new
  channel being bridged to a calling channel should have secure signaling or
  media. See doc/tex/secure-calls.tex for examples.
  
  Original patch by mikma, updated for trunk and revised by me.
  
  (closes issue #5413)
  Reported by: mikma
  Tested by: twilson, notthematrix, hemanshurpatel
  
  Review: https://reviewboard.asterisk.org/r/191/
........
  r268896 | tilghman | 2010-06-08 01:16:43 -0500 (Tue, 08 Jun 2010) | 2 lines
  
  Fix trunk build on Mac OS X.
........
  r268933 | tilghman | 2010-06-08 01:57:24 -0500 (Tue, 08 Jun 2010) | 2 lines
  
  Release list lock before returning on error.
........
  r268969 | lmadsen | 2010-06-08 09:38:18 -0500 (Tue, 08 Jun 2010) | 7 lines
  
  Fix some doxygen warnings.
  
  (closes issue #17336)
  Reported by: snuffy
  Patches:
        doxygen-fixes1.diff uploaded by snuffy (license 35)
  Tested by: russell
........

Added:
    team/group/v6-new/channels/sip/include/sdp_crypto.h
      - copied unchanged from r268969, trunk/channels/sip/include/sdp_crypto.h
    team/group/v6-new/channels/sip/include/srtp.h
      - copied unchanged from r268969, trunk/channels/sip/include/srtp.h
    team/group/v6-new/channels/sip/sdp_crypto.c
      - copied unchanged from r268969, trunk/channels/sip/sdp_crypto.c
    team/group/v6-new/channels/sip/srtp.c
      - copied unchanged from r268969, trunk/channels/sip/srtp.c
    team/group/v6-new/doc/tex/secure-calls.tex
      - copied unchanged from r268969, trunk/doc/tex/secure-calls.tex
    team/group/v6-new/include/asterisk/res_srtp.h
      - copied unchanged from r268969, trunk/include/asterisk/res_srtp.h
    team/group/v6-new/res/res_srtp.c
      - copied unchanged from r268969, trunk/res/res_srtp.c
    team/group/v6-new/res/res_srtp.exports.in
      - copied unchanged from r268969, trunk/res/res_srtp.exports.in
Modified:
    team/group/v6-new/   (props changed)
    team/group/v6-new/CHANGES
    team/group/v6-new/apps/app_meetme.c
    team/group/v6-new/apps/app_voicemail.c
    team/group/v6-new/build_tools/menuselect-deps.in
    team/group/v6-new/channels/chan_dahdi.c
    team/group/v6-new/channels/chan_iax2.c
    team/group/v6-new/channels/chan_sip.c
    team/group/v6-new/channels/sig_pri.h
    team/group/v6-new/channels/sip/dialplan_functions.c
    team/group/v6-new/channels/sip/include/sip.h
    team/group/v6-new/configure
    team/group/v6-new/configure.ac
    team/group/v6-new/doc/tex/asterisk.tex
    team/group/v6-new/funcs/func_channel.c
    team/group/v6-new/include/asterisk/app.h
    team/group/v6-new/include/asterisk/astmm.h
    team/group/v6-new/include/asterisk/astobj2.h
    team/group/v6-new/include/asterisk/autoconfig.h.in
    team/group/v6-new/include/asterisk/bridging_technology.h
    team/group/v6-new/include/asterisk/calendar.h
    team/group/v6-new/include/asterisk/callerid.h
    team/group/v6-new/include/asterisk/ccss.h
    team/group/v6-new/include/asterisk/channel.h
    team/group/v6-new/include/asterisk/data.h
    team/group/v6-new/include/asterisk/dnsmgr.h
    team/group/v6-new/include/asterisk/doxyref.h
    team/group/v6-new/include/asterisk/event.h
    team/group/v6-new/include/asterisk/features.h
    team/group/v6-new/include/asterisk/frame.h
    team/group/v6-new/include/asterisk/global_datastores.h
    team/group/v6-new/include/asterisk/http.h
    team/group/v6-new/include/asterisk/logger.h
    team/group/v6-new/include/asterisk/manager.h
    team/group/v6-new/include/asterisk/pbx.h
    team/group/v6-new/include/asterisk/rtp_engine.h
    team/group/v6-new/include/asterisk/smdi.h
    team/group/v6-new/include/asterisk/threadstorage.h
    team/group/v6-new/include/asterisk/timing.h
    team/group/v6-new/include/asterisk/xml.h
    team/group/v6-new/main/ast_expr2f.c
    team/group/v6-new/main/asterisk.exports.in
    team/group/v6-new/main/audiohook.c
    team/group/v6-new/main/ccss.c
    team/group/v6-new/main/channel.c
    team/group/v6-new/main/features.c
    team/group/v6-new/main/global_datastores.c
    team/group/v6-new/main/pbx.c
    team/group/v6-new/main/rtp_engine.c
    team/group/v6-new/makeopts.in
    team/group/v6-new/res/res_config_sqlite.c
    team/group/v6-new/res/res_jabber.c
    team/group/v6-new/res/res_rtp_asterisk.c
    team/group/v6-new/utils/extconf.c

Propchange: team/group/v6-new/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/group/v6-new/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jun  8 11:09:20 2010
@@ -1,1 +1,1 @@
-/trunk:1-268863
+/trunk:1-268983

Modified: team/group/v6-new/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/CHANGES?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/CHANGES (original)
+++ team/group/v6-new/CHANGES Tue Jun  8 11:09:20 2010
@@ -59,6 +59,10 @@
  * When dialing SIP peers, a new component may be added to the end of the dialstring
    to indicate that a specific remote IP address or host should be used when dialing
    the particular peer. The dialstring format is SIP/peer/exten/host_or_IP.
+ * SRTP SDES support for encrypting calls to/from Asterisk over SIP. The
+   ability to selectively force bridged channels to also be encrypted is also
+   implemented. Branching in the dialplan can be done based on whether or not
+   a channel has secure media and/or signaling.
  * Added directmediapermit/directmediadeny to limit which peers can send direct media
    to each other
  * Added the 'snom_aoc_enabled' option to turn on support for sending Advice of
@@ -68,6 +72,10 @@
 -----------
  * Added rtsavesysname option into iax.conf to allow the systname to be saved
    on realtime updates.
+ * Added the ability for chan_iax2 to inform the dialplan whether or not
+   encryption is being used. This interoperates with the SIP SRTP implementation
+   so that a secure SIP call can be bridged to a secure IAX call when the
+   dialplan requires bridged channels to be "secure".
 
 MGCP Changes
 ------------
@@ -205,6 +213,11 @@
    prefixing the name of the hash at assignment with the appropriate number of
    underscores, just like variables.
  * GROUP_MATCH_COUNT has been improved to allow regex matching on category
+ * CHANNEL(secure_bridge_signaling) and CHANNEL(secure_bridge_media) to set/get
+   whether or not channels that are bridged to the current channel will be
+   required to have secure signaling and/or media.
+ * CHANNEL(secure_signaling) and CHANNEL(secure_media) to get whether or not
+   the current channel has secure signaling and/or media.
  * For DAHDI/ISDN channels, the CHANNEL() dialplan function now supports the
    "no_media_path" option.
    Returns "0" if there is a B channel associated with the call.

Modified: team/group/v6-new/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/apps/app_meetme.c?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/apps/app_meetme.c (original)
+++ team/group/v6-new/apps/app_meetme.c Tue Jun  8 11:09:20 2010
@@ -944,11 +944,12 @@
  *  when in a conference */
 static int audio_buffers;
 
-/*!  \briefMap 'volume' levels from -5 through +5 into
- *  decibel (dB) settings for channel drivers
+/*! \brief Map 'volume' levels from -5 through +5 into decibel (dB) 
+ *    settings for channel drivers.
+ *
  *  \note these are not a straight linear-to-dB
  *  conversion... the numbers have been modified
- *  to give the user a better level of adjustability
+ *  to give the user a better level of adjustability.
  */
 static const char gain_map[] = {
 	-15,
@@ -5066,7 +5067,7 @@
 
 /*! \brief Choose the highest priority ringing trunk for a station
  * \param station the station
- * \param remove remove the ringing trunk once selected
+ * \param rm remove the ringing trunk once selected
  * \param trunk_ref a place to store the pointer to this stations reference to
  *        the selected trunk
  * \return a pointer to the selected ringing trunk, or NULL if none found

Modified: team/group/v6-new/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/apps/app_voicemail.c?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/apps/app_voicemail.c (original)
+++ team/group/v6-new/apps/app_voicemail.c Tue Jun  8 11:09:20 2010
@@ -1569,6 +1569,9 @@
  * \brief Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
  * \param dest The variable to hold the output generated path expression. This buffer should be of size PATH_MAX.
  * \param len The length of the path string that was written out.
+ * \param context
+ * \param ext 
+ * \param folder 
  * 
  * The path is constructed as 
  * 	VM_SPOOL_DIRcontext/ext/folder
@@ -1584,6 +1587,8 @@
  * \brief Creates a file system path expression for a folder within the voicemail data folder and the appropriate context.
  * \param dest The variable to hold the output generated path expression. This buffer should be of size PATH_MAX.
  * \param len The length of the path string that was written out.
+ * \param dir 
+ * \param num 
  * 
  * The path is constructed as 
  * 	VM_SPOOL_DIRcontext/ext/folder
@@ -4338,15 +4343,18 @@
  * \param msgnum The message index in the mailbox folder.
  * \param context 
  * \param mailbox The voicemail box to read the voicemail to be notified in this email.
+ * \param fromfolder
  * \param cidnum The caller ID number.
  * \param cidname The caller ID name.
  * \param attach the name of the sound file to be attached to the email, if attach_user_voicemail == 1.
+ * \param attach2 
  * \param format The message sound file format. i.e. .wav
  * \param duration The time of the message content, in seconds.
  * \param attach_user_voicemail if 1, the sound file is attached to the email.
  * \param chan
  * \param category
  * \param imap if == 1, indicates the target folder for the email notification to be sent to will be an IMAP mailstore. This causes additional mailbox headers to be set, which would facilitate searching for the email in the destination IMAP folder.
+ * \param flag
  *
  * The email body, and base 64 encoded attachement (if any) are stored to the file identified by *p. This method does not actually send the email.  That is done by invoking the configure 'mailcmd' and piping this generated file into it, or with the sendemail() function.
  */
@@ -5125,6 +5133,7 @@
  * \param recip
  * \param fmt
  * \param dir
+ * \param flag
  *
  * This is only used by file storage based mailboxes.
  *
@@ -6547,11 +6556,12 @@
  * \param vmu
  * \param curdir
  * \param curmsg
- * \param vmfmts
+ * \param vm_fmts
  * \param context
  * \param record_gain
  * \param duration
  * \param vms
+ * \param flag 
  *
  * Presents a prompt for 1 to prepend the current message, 2 to forward the message without prepending, or * to return to the main menu.
  *
@@ -6730,6 +6740,7 @@
  * \param fmt
  * \param cidnum The Caller ID phone number value.
  * \param cidname The Caller ID name value.
+ * \param flag
  *
  * \return zero on success, -1 on error.
  */
@@ -6807,7 +6818,7 @@
 
 /*!
  * \brief Sends a voicemail message to a mailbox recipient.
- * \param ast_channel
+ * \param chan
  * \param context
  * \param vms
  * \param sender
@@ -6816,6 +6827,7 @@
  *             Will be 0 when called to forward an existing message (option 8)
  *             Will be 1 when called to leave a message (option 3->5)
  * \param record_gain 
+ * \param urgent
  *
  * Reads the destination mailbox(es) from keypad input for CID, or if use_directory feature is enabled, the Directory.
  * 

Modified: team/group/v6-new/build_tools/menuselect-deps.in
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/build_tools/menuselect-deps.in?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/build_tools/menuselect-deps.in (original)
+++ team/group/v6-new/build_tools/menuselect-deps.in Tue Jun  8 11:09:20 2010
@@ -51,6 +51,7 @@
 SPEEX_PREPROCESS=@PBX_SPEEX_PREPROCESS@
 SQLITE3=@PBX_SQLITE3@
 SQLITE=@PBX_SQLITE@
+SRTP=@PBX_SRTP@
 SS7=@PBX_SS7@
 OPENSSL=@PBX_OPENSSL@
 SUPPSERV=@PBX_SUPPSERV@

Modified: team/group/v6-new/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/chan_dahdi.c?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/channels/chan_dahdi.c (original)
+++ team/group/v6-new/channels/chan_dahdi.c Tue Jun  8 11:09:20 2010
@@ -9169,7 +9169,7 @@
 
 /*! \brief enable or disable the chan_dahdi Do-Not-Disturb mode for a DAHDI channel
  * \param dahdichan "Physical" DAHDI channel (e.g: DAHDI/5)
- * \param on 1 to enable, 0 to disable, -1 return dnd value
+ * \param flag on 1 to enable, 0 to disable, -1 return dnd value
  *
  * chan_dahdi has a DND (Do Not Disturb) mode for each dahdichan (physical
  * DAHDI channel). Use this to enable or disable it.

Modified: team/group/v6-new/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/chan_iax2.c?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/channels/chan_iax2.c (original)
+++ team/group/v6-new/channels/chan_iax2.c Tue Jun  8 11:09:20 2010
@@ -1171,6 +1171,7 @@
 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
 static int iax2_sendtext(struct ast_channel *c, const char *text);
 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
+static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen);
 static int iax2_transfer(struct ast_channel *c, const char *dest);
 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
@@ -1218,6 +1219,7 @@
 	.write_video = iax2_write,
 	.indicate = iax2_indicate,
 	.setoption = iax2_setoption,
+	.queryoption = iax2_queryoption,
 	.bridge = iax2_bridge,
 	.transfer = iax2_transfer,
 	.fixup = iax2_fixup,
@@ -4907,6 +4909,11 @@
 		ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
 		return -1;
 	}
+	if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
+		ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
+		c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
+		return -1;
+	}
 	if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
 		ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
 		return -1;
@@ -5148,6 +5155,19 @@
 	case AST_OPTION_OPRMODE:
 		errno = EINVAL;
 		return -1;
+	case AST_OPTION_SECURE_SIGNALING:
+	case AST_OPTION_SECURE_MEDIA:
+	{
+		unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
+		ast_mutex_lock(&iaxsl[callno]);
+		if ((*(int *) data)) {
+			ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
+		} else {
+			ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
+		}
+		ast_mutex_unlock(&iaxsl[callno]);
+		return 0;
+	}
 	default:
 	{
 		unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
@@ -5176,6 +5196,23 @@
 		ast_free(h);
 		return res;
 	}
+	}
+}
+
+static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
+{
+	switch (option) {
+	case AST_OPTION_SECURE_SIGNALING:
+	case AST_OPTION_SECURE_MEDIA:
+	{
+		unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
+		ast_mutex_lock(&iaxsl[callno]);
+		*((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
+		ast_mutex_unlock(&iaxsl[callno]);
+		return 0;
+	}
+	default:
+		return -1;
 	}
 }
 
@@ -13626,6 +13663,8 @@
 		ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
 	} else if (!strcasecmp(args, "peername")) {
 		ast_copy_string(buf, pvt->username, buflen);
+	} else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
+		snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
 	} else {
 		res = -1;
 	}

Modified: team/group/v6-new/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/chan_sip.c?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/channels/chan_sip.c (original)
+++ team/group/v6-new/channels/chan_sip.c Tue Jun  8 11:09:20 2010
@@ -267,10 +267,13 @@
 #include "sip/include/config_parser.h"
 #include "sip/include/reqresp_parser.h"
 #include "sip/include/sip_utils.h"
+#include "sip/include/srtp.h"
+#include "sip/include/sdp_crypto.h"
 #include "asterisk/ccss.h"
 #include "asterisk/xml.h"
 #include "sip/include/dialog.h"
 #include "sip/include/dialplan_functions.h"
+
 
 /*** DOCUMENTATION
 	<application name="SIPDtmfMode" language="en_US">
@@ -1568,6 +1571,10 @@
 static int handle_response_register(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno);
 static void handle_response(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno);
 
+/*------ SRTP Support -------- */
+static int setup_srtp(struct sip_srtp **srtp);
+static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a);
+
 /*------ T38 Support --------- */
 static int transmit_response_with_t38_sdp(struct sip_pvt *p, char *msg, struct sip_request *req, int retrans);
 static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
@@ -3920,7 +3927,16 @@
 			res = 0;
 		}
 		break;
+	case AST_OPTION_SECURE_SIGNALING:
+		p->req_secure_signaling = *(unsigned int *) data;
+		res = 0;
+		break;
+	case AST_OPTION_SECURE_MEDIA:
+		ast_set2_flag(&p->flags[1], *(unsigned int *) data, SIP_PAGE2_USE_SRTP);
+		res = 0;
+		break;
 	default:
+		ast_log(LOG_NOTICE, "Unknown option: %d\n", option);
 		break;
 	}
 
@@ -3970,6 +3986,14 @@
 		cp = (char *) data;
 		*cp = p->dsp ? 1 : 0;
 		ast_debug(1, "Reporting digit detection %sabled on %s\n", *cp ? "en" : "dis", chan->name);
+		break;
+	case AST_OPTION_SECURE_SIGNALING:
+		*((unsigned int *) data) = p->req_secure_signaling;
+		res = 0;
+		break;
+	case AST_OPTION_SECURE_MEDIA:
+		*((unsigned int *) data) = ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP) ? 1 : 0;
+		res = 0;
 		break;
 	case AST_OPTION_DEVICE_NAME:
 		if (p && p->outgoing_call) {
@@ -4473,7 +4497,7 @@
 
 /*!
  * \brief Locate device by name or ip address
- *
+ * \param peer, sin, realtime, devstate_only, transport
  * \param which_objects Define which objects should be matched when doing a lookup
  *        by name.  Valid options are FINDUSERS, FINDPEERS, or FINDALLDEVICES.
  *        Note that this option is not used at all when doing a lookup by IP.
@@ -5002,6 +5026,35 @@
 		}
 	}
 
+	/* Check to see if we should try to force encryption */
+	if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) {
+	   ast_log(LOG_WARNING, "Encrypted signaling is required\n");
+	   ast->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
+	   return -1;
+	}
+
+	if (ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
+		if (ast_test_flag(&p->flags[0], SIP_REINVITE)) {
+			ast_debug(1, "Direct media not possible when using SRTP, ignoring canreinvite setting\n");
+			ast_clear_flag(&p->flags[0], SIP_REINVITE);
+		}
+
+		if (p->rtp && !p->srtp && setup_srtp(&p->srtp) < 0) {
+			ast_log(LOG_WARNING, "SRTP audio setup failed\n");
+			return -1;
+		}
+
+		if (p->vrtp && !p->vsrtp && setup_srtp(&p->vsrtp) < 0) {
+			ast_log(LOG_WARNING, "SRTP video setup failed\n");
+			return -1;
+		}
+
+		if (p->trtp && !p->vsrtp && setup_srtp(&p->tsrtp) < 0) {
+			ast_log(LOG_WARNING, "SRTP text setup failed\n");
+			return -1;
+		}
+	}
+
 	res = 0;
 	ast_set_flag(&p->flags[0], SIP_OUTGOING);
 
@@ -5207,6 +5260,21 @@
 	if (p->chanvars) {
 		ast_variables_destroy(p->chanvars);
 		p->chanvars = NULL;
+	}
+
+	if (p->srtp) {
+		sip_srtp_destroy(p->srtp);
+		p->srtp = NULL;
+	}
+
+	if (p->vsrtp) {
+		sip_srtp_destroy(p->vsrtp);
+		p->vsrtp = NULL;
+	}
+
+	if (p->tsrtp) {
+		sip_srtp_destroy(p->tsrtp);
+		p->tsrtp = NULL;
 	}
 
 	if (p->directmediaha) {
@@ -7671,6 +7739,10 @@
 	const char *codecs;
 	int codec;
 
+	/* SRTP */
+	int secure_audio = FALSE;
+	int secure_video = FALSE;
+
 	/* Others */
 	int sendonly = -1;
 	int vsendonly = -1;
@@ -7770,6 +7842,7 @@
 		int video = FALSE;
 		int image = FALSE;
 		int text = FALSE;
+		char protocol[5] = {0,};
 		int x;
 
 		numberofports = 1;
@@ -7780,8 +7853,14 @@
 		nextm = get_sdp_iterate(&next, req, "m");
 
 		/* Search for audio media definition */
-		if ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
-		    (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) {
+		if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
+		    (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) {
+			if (!strcmp(protocol, "SAVP")) {
+				secure_audio = 1;
+			} else if (strcmp(protocol, "AVP")) {
+				ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol);
+				continue;
+			}
 			audio = TRUE;
 			p->offered_media[SDP_AUDIO].offered = TRUE;
 			numberofmediastreams++;
@@ -7801,8 +7880,14 @@
 				ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec);
 			}
 		/* Search for video media definition */
-		} else if ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
-			   (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len >= 0)) {
+		} else if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
+			   (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len >= 0)) {
+			if (!strcmp(protocol, "SAVP")) {
+				secure_video = 1;
+			} else if (strcmp(protocol, "AVP")) {
+				ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol);
+				continue;
+			}
 			video = TRUE;
 			p->novideo = FALSE;
 			p->offered_media[SDP_VIDEO].offered = TRUE;
@@ -7864,8 +7949,6 @@
 		if (numberofports > 1)
 			ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
 		
-
-
 		/* Media stream specific parameters */
 		while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
 			int processed = FALSE;
@@ -7899,12 +7982,16 @@
 				if (audio) {
 					if (process_sdp_a_sendonly(value, &sendonly))
 						processed = TRUE;
+					else if (process_crypto(p, p->rtp, &p->srtp, value))
+						processed = TRUE;
 					else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
 						processed = TRUE;
 				}
 				/* Video specific scanning */
 				else if (video) {
 					if (process_sdp_a_sendonly(value, &vsendonly))
+						processed = TRUE;
+					else if (process_crypto(p, p->vrtp, &p->vsrtp, value))
 						processed = TRUE;
 					else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
 						processed = TRUE;
@@ -7913,6 +8000,8 @@
 				else if (text) {
 					if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
 						processed = TRUE;
+					else if (process_crypto(p, p->trtp, &p->tsrtp, value))
+						processed = TRUE;
 				}
 				/* Image (T.38 FAX) specific scanning */
 				else if (image) {
@@ -7937,19 +8026,47 @@
 		return -1;
 	}
 
-	if (portno == -1 && vportno == -1 && udptlportno == -1  && tportno == -1)
+	if (portno == -1 && vportno == -1 && udptlportno == -1  && tportno == -1) {
 		/* No acceptable offer found in SDP  - we have no ports */
 		/* Do not change RTP or VRTP if this is a re-invite */
+		ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n");
 		return -2;
-
-	if (numberofmediastreams > 3)
+	}
+
+	if (numberofmediastreams > 3) {
 		/* We have too many fax, audio and/or video and/or text media streams, fail this offer */
+		ast_log(LOG_WARNING, "Faling due to too many media streams\n");
 		return -3;
+	}
+
+	if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) {
+		ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
+		return -4;
+	}
+
+	if (!secure_audio && p->srtp) {
+		ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
+		return -4;
+	}
+
+	if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) {
+		ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
+		return -4;
+	}
+
+	if (!p->novideo && !secure_video && p->vsrtp) {
+		ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
+		return -4;
+	}
+
+	if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
+		ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n");
+		return -4;
+	}
 
 	if (udptlportno == -1) {
 		change_t38_state(p, T38_DISABLED);
 	}
-
 
 	/* Now gather all of the codecs that we are asked for: */
 	ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability);
@@ -9869,6 +9986,23 @@
 	}
 }
 
+static void get_crypto_attrib(struct sip_srtp *srtp, const char **a_crypto)
+{
+	/* Set encryption properties */
+	if (srtp) {
+		if (!srtp->crypto) {
+			srtp->crypto = sdp_crypto_setup();
+		}
+		if (srtp->crypto && (sdp_crypto_offer(srtp->crypto) >= 0)) {
+			*a_crypto = sdp_crypto_attrib(srtp->crypto);
+		}
+
+		if (!*a_crypto) {
+			ast_log(LOG_WARNING, "No SRTP key management enabled\n");
+		}
+	}
+}
+
 /*! \brief Add Session Description Protocol message
 
     If oldsdp is TRUE, then the SDP version number is not incremented. This mechanism
@@ -9906,6 +10040,9 @@
 	struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */
 	struct ast_str *a_text = ast_str_alloca(1024);  /* Attributes for text */
 	struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */
+	const char *a_crypto = NULL;
+	const char *v_a_crypto = NULL;
+	const char *t_a_crypto = NULL;
 
 	format_t x;
 	format_t capability = 0;
@@ -9997,7 +10134,9 @@
 		/* 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. */
 		if (needvideo) {
-			ast_str_append(&m_video, 0, "m=video %d RTP/AVP", ast_sockaddr_port(&vdest));
+			get_crypto_attrib(p->vsrtp, &v_a_crypto);
+			ast_str_append(&m_video, 0, "m=video %d RTP/%s", ast_sockaddr_port(&vdest),
+				v_a_crypto ? "SAVP" : "AVP");
 
 			/* Build max bitrate string */
 			if (p->maxcallbitrate)
@@ -10011,7 +10150,9 @@
 		if (needtext) {
 			if (sipdebug_text)
 				ast_verbose("Lets set up the text sdp\n");
-			ast_str_append(&m_text, 0, "m=text %d RTP/AVP", ast_sockaddr_port(&tdest));
+			get_crypto_attrib(p->tsrtp, &t_a_crypto);
+			ast_str_append(&m_text, 0, "m=text %d RTP/%s", ast_sockaddr_port(&tdest),
+				t_a_crypto ? "SAVP" : "AVP");
 			if (debug) /* XXX should I use tdest below ? */
 				ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&p->ourip));
 		}
@@ -10021,7 +10162,9 @@
 		/* We break with the "recommendation" and send our IP, in order that our
 		   peer doesn't have to ast_gethostbyname() us */
 
-		ast_str_append(&m_audio, 0, "m=audio %d RTP/AVP", ast_sockaddr_port(&dest));
+		get_crypto_attrib(p->srtp, &a_crypto);
+		ast_str_append(&m_audio, 0, "m=audio %d RTP/%s", ast_sockaddr_port(&dest),
+			a_crypto ? "SAVP" : "AVP");
 
 		if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
 			hold = "a=recvonly\r\n";
@@ -10183,7 +10326,15 @@
  		len += m_text->used + a_text->used + strlen(hold);
 	if (add_t38)
 		len += m_modem->used + a_modem->used;
-
+	if (a_crypto) {
+		len += strlen(a_crypto);
+	}
+	if (v_a_crypto) {
+		len += strlen(v_a_crypto);
+	}
+	if (t_a_crypto) {
+		len += strlen(t_a_crypto);
+	}
 	add_header(resp, "Content-Type", "application/sdp");
 	add_header_contentLength(resp, len);
 	add_line(resp, version);
@@ -10197,6 +10348,9 @@
 		add_line(resp, m_audio->str);
 		add_line(resp, a_audio->str);
 		add_line(resp, hold);
+		if (a_crypto) {
+			add_line(resp, a_crypto);
+		}
 	} else if (p->offered_media[SDP_AUDIO].offered) {
 		snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].codecs);
 		add_line(resp, dummy_answer);
@@ -10205,6 +10359,9 @@
 		add_line(resp, m_video->str);
 		add_line(resp, a_video->str);
 		add_line(resp, hold);	/* Repeat hold for the video stream */
+		if (v_a_crypto) {
+			add_line(resp, v_a_crypto);
+		}
 	} else if (p->offered_media[SDP_VIDEO].offered) {
 		snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].codecs);
 		add_line(resp, dummy_answer);
@@ -10213,6 +10370,9 @@
 		add_line(resp, m_text->str);
 		add_line(resp, a_text->str);
 		add_line(resp, hold);	/* Repeat hold for the text stream */
+		if (t_a_crypto) {
+			add_line(resp, t_a_crypto);
+		}
 	} else if (p->offered_media[SDP_TEXT].offered) {
 		snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].codecs);
 		add_line(resp, dummy_answer);
@@ -10646,7 +10806,6 @@
  *
  * \param req The request/response to which we will add the header
  * \param pvt The sip_pvt which represents the call-leg
- * \param apr Redirecting data used to make the diversion header
  */
 static void add_diversion_header(struct sip_request *req, struct sip_pvt *pvt)
 {
@@ -10713,12 +10872,14 @@
 	return 0;
 }
 
-/*! \brief Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it
-	\param init 0 = Prepare request within dialog, 1= prepare request, new branch, 2= prepare new request and new dialog. do_proxy_auth calls this with init!=2
- \param p sip_pvt structure
- \param sdp unknown
- \param sipmethod unknown
-
+/*! 
+ * \brief Build REFER/INVITE/OPTIONS/SUBSCRIBE message and transmit it
+ * \param p sip_pvt structure
+ * \param sipmethod
+ * \param sdp unknown
+ * \param init 0 = Prepare request within dialog, 1= prepare request, new branch,
+ *  2= prepare new request and new dialog. do_proxy_auth calls this with init!=2
+ * \param explicit_uri
 */
 static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init, const char * const explicit_uri)
 {
@@ -17484,6 +17645,8 @@
 		ast_copy_string(buf, peer->cid_num, len);
 	} else  if (!strcasecmp(colname, "codecs")) {
 		ast_getformatname_multiple(buf, len -1, peer->capability);
+	} else if (!strcasecmp(colname, "encryption")) {
+		snprintf(buf, len, "%d", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP));
 	} else  if (!strncasecmp(colname, "chanvar[", 8)) {
 		char *chanvar=colname + 8;
 		struct ast_variable *v;
@@ -21020,8 +21183,13 @@
 				transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)));
 			} else if (p->t38.state == T38_DISABLED) {
 				/* If this is not a re-invite or something to ignore - it's critical */
-				ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
-				transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE);
+				if (p->srtp && !ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)) {
+					ast_log(LOG_WARNING, "Target does not support required crypto\n");
+					transmit_response_reliable(p, "488 Not Acceptable Here (crypto)", req);
+				} else {
+					ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
+					transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE : TRUE, FALSE);
+				}
 			}
 
 			p->invitestate = INV_TERMINATED;
@@ -25354,6 +25522,8 @@
 				ast_string_field_set(peer, unsolicited_mailbox, v->value);
 			} else if (!strcasecmp(v->name, "use_q850_reason")) {
 				ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_Q850_REASON);
+			} else if (!strcasecmp(v->name, "encryption")) {
+				ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_USE_SRTP);
 			} else if (!strcasecmp(v->name, "snom_aoc_enabled")) {
 				ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_SNOM_AOC);
 			}
@@ -26625,6 +26795,10 @@
 		res = AST_RTP_GLUE_RESULT_FORBID;
 	}
 
+	if (p->srtp) {
+		res = AST_RTP_GLUE_RESULT_FORBID;
+	}
+
 	sip_pvt_unlock(p);
 
 	return res;
@@ -27043,6 +27217,50 @@
 	} while (0));
 }
 
+/* SRTP */
+static int setup_srtp(struct sip_srtp **srtp)
+{
+	if (!ast_rtp_engine_srtp_is_registered()) {
+		ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n");
+		return -1;
+	}
+
+	if (!(*srtp = sip_srtp_alloc())) { /* Allocate SRTP data structure */
+		return -1;
+	}
+
+	return 0;
+}
+
+static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struct sip_srtp **srtp, const char *a)
+{
+	if (strncasecmp(a, "crypto:", 7)) {
+		return FALSE;
+	}
+	if (!*srtp) {
+		if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
+			ast_log(LOG_WARNING, "Ignoring unexpected crypto attribute in SDP answer\n");
+			return FALSE;
+		}
+
+		if (setup_srtp(srtp) < 0) {
+			return FALSE;
+		}
+	}
+
+	if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) {
+		return FALSE;
+	}
+
+	if (sdp_crypto_process((*srtp)->crypto, a, rtp) < 0) {
+		return FALSE;
+	}
+
+	ast_set_flag(*srtp, SRTP_CRYPTO_OFFER_OK);
+
+	return TRUE;
+}
+
 /*! \brief Reload module */
 static int sip_do_reload(enum channelreloadreason reason)
 {

Modified: team/group/v6-new/channels/sig_pri.h
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/sig_pri.h?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/channels/sig_pri.h (original)
+++ team/group/v6-new/channels/sig_pri.h Tue Jun  8 11:09:20 2010
@@ -410,7 +410,7 @@
 	 * AST_DEVICE_BUSY - All B channels are in use.
 	 * AST_DEVICE_UNAVAILABLE - Span is in alarm.
 	 * \note
-	 * Device name:  DAHDI/I<span>/congestion
+	 * Device name: \startverbatim DAHDI/I<span>/congestion. \endverbatim
 	 */
 	int congestion_devstate;
 #if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)

Modified: team/group/v6-new/channels/sip/dialplan_functions.c
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/sip/dialplan_functions.c?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/channels/sip/dialplan_functions.c (original)
+++ team/group/v6-new/channels/sip/dialplan_functions.c Tue Jun  8 11:09:20 2010
@@ -214,6 +214,10 @@
 			ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
 			return -1;
 		}
+	} else if (!strcasecmp(args.param, "secure_signaling")) {
+		snprintf(buf, buflen, "%s", p->socket.type == SIP_TRANSPORT_TLS ? "1" : "");
+	} else if (!strcasecmp(args.param, "secure_media")) {
+		snprintf(buf, buflen, "%s", p->srtp ? "1" : "");
 	} else {
 		res = -1;
 	}

Modified: team/group/v6-new/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/channels/sip/include/sip.h?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/channels/sip/include/sip.h (original)
+++ team/group/v6-new/channels/sip/include/sip.h Tue Jun  8 11:09:20 2010
@@ -307,10 +307,8 @@
 #define SIP_PAGE2_RTAUTOCLEAR			(1 <<  1)    /*!< GP: Should we clean memory from peers after expiry? */
 #define SIP_PAGE2_RPID_UPDATE			(1 <<  2)
 #define SIP_PAGE2_Q850_REASON			(1 <<  3)    /*!< DP: Get/send cause code via Reason header */
-
 #define SIP_PAGE2_SYMMETRICRTP			(1 <<  4)    /*!< GDP: Whether symmetric RTP is enabled or not */
 #define SIP_PAGE2_STATECHANGEQUEUE		(1 <<  5)    /*!< D: Unsent state pending change exists */
-
 #define SIP_PAGE2_CONNECTLINEUPDATE_PEND	(1 <<  6)
 #define SIP_PAGE2_RPID_IMMEDIATE		(1 <<  7)
 #define SIP_PAGE2_RPORT_PRESENT			(1 <<  8)   /*!< Was rport received in the Via header? */
@@ -345,6 +343,7 @@
 #define SIP_PAGE2_UDPTL_DESTINATION		(1 << 25)  /*!< DP: Use source IP of RTP as destination if NAT is enabled */
 #define SIP_PAGE2_VIDEOSUPPORT_ALWAYS		(1 << 26)  /*!< DP: Always set up video, even if endpoints don't support it */
 #define SIP_PAGE2_HAVEPEERCONTEXT	(1 << 27)	/*< Are we associated with a configured peer context? */
+#define SIP_PAGE2_USE_SRTP              (1 << 28)    /*!< DP: Whether we should offer (only)  SRTP */
 
 #define SIP_PAGE2_FLAGS_TO_COPY \
 	(SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_IGNORESDPVERSION | \
@@ -352,7 +351,7 @@
 	SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_FAX_DETECT | \
 	SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS | SIP_PAGE2_PREFERRED_CODEC | \
 	SIP_PAGE2_RPID_IMMEDIATE | SIP_PAGE2_RPID_UPDATE | SIP_PAGE2_SYMMETRICRTP |\
-	SIP_PAGE2_Q850_REASON | SIP_PAGE2_HAVEPEERCONTEXT)
+	SIP_PAGE2_Q850_REASON | SIP_PAGE2_HAVEPEERCONTEXT | SIP_PAGE2_USE_SRTP)
 
 
 #define SIP_PAGE3_SNOM_AOC               (1 << 0)  /*!< DPG: Allow snom aoc messages */
@@ -965,6 +964,7 @@
 	                                       *   or respect the other endpoint's request for frame sizes (on)
 	                                       *   for incoming calls
 	                                       */
+	unsigned short req_secure_signaling:1;/*!< Whether we are required to have secure signaling or not */
 	char tag[11];                     /*!< Our tag for this session */
 	int timer_t1;                     /*!< SIP timer T1, ms rtt */
 	int timer_b;                      /*!< SIP timer B, ms */
@@ -1048,6 +1048,9 @@
 	AST_LIST_HEAD_NOLOCK(request_queue, sip_request) request_queue; /*!< Requests that arrived but could not be processed immediately */
 	struct sip_invite_param *options;   /*!< Options for INVITE */
 	struct sip_st_dlg *stimer;          /*!< SIP Session-Timers */
+	struct sip_srtp *srtp;              /*!< Structure to hold Secure RTP session data for audio */
+	struct sip_srtp *vsrtp;             /*!< Structure to hold Secure RTP session data for video */
+	struct sip_srtp *tsrtp;             /*!< Structure to hold Secure RTP session data for text */
 
 	int red;                            /*!< T.140 RTP Redundancy */
 	int hangupcause;                    /*!< Storage of hangupcause copied from our owner before we disconnect from the AST channel (only used at hangup) */

Modified: team/group/v6-new/configure.ac
URL: http://svnview.digium.com/svn/asterisk/team/group/v6-new/configure.ac?view=diff&rev=269012&r1=269011&r2=269012
==============================================================================
--- team/group/v6-new/configure.ac (original)
+++ team/group/v6-new/configure.ac Tue Jun  8 11:09:20 2010
@@ -377,6 +377,7 @@

[... 1538 lines stripped ...]



More information about the svn-commits mailing list