[asterisk-commits] kmoore: branch kmoore/pimp_sip_srtp r386327 - in /team/kmoore/pimp_sip_srtp: ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Apr 22 16:16:39 CDT 2013
Author: kmoore
Date: Mon Apr 22 16:16:35 2013
New Revision: 386327
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386327
Log:
Fleshing out of work for SDES SRTP in chan_gulp/res_sip
Modified:
team/kmoore/pimp_sip_srtp/channels/chan_sip.c
team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample
team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h
team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h
team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h
team/kmoore/pimp_sip_srtp/main/sdp_srtp.c
team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c
team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c
Modified: team/kmoore/pimp_sip_srtp/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/channels/chan_sip.c?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/channels/chan_sip.c (original)
+++ team/kmoore/pimp_sip_srtp/channels/chan_sip.c Mon Apr 22 16:16:35 2013
@@ -33284,7 +33284,7 @@
return FALSE;
}
- if (ast_sdp_crypto_process((*srtp)->crypto, a, rtp, *srtp) < 0) {
+ if (ast_sdp_crypto_process(rtp, *srtp, a) < 0) {
return FALSE;
}
Modified: team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample (original)
+++ team/kmoore/pimp_sip_srtp/configs/res_sip.conf.sample Mon Apr 22 16:16:35 2013
@@ -22,3 +22,4 @@
;rtp_ipv6=yes ; Force IPv6 for RTP transport
;rtp_symmetric=yes ; Enable symmetric RTP support
;use_ptime=yes ; Whether to use the ptime value received from the endpoint or not
+;media_encryption=no ; Options for media encryption are deny, no, and sdes
Modified: team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h (original)
+++ team/kmoore/pimp_sip_srtp/include/asterisk/res_sip.h Mon Apr 22 16:16:35 2013
@@ -250,6 +250,8 @@
};
enum ast_sip_session_media_encryption {
+ /*! Invalid media encryption configuration */
+ AST_SIP_MEDIA_ENCRYPT_INVALID = 0,
/*! Do not allow any encryption of session media */
AST_SIP_MEDIA_ENCRYPT_DENY,
/*! Do not offer media encryption, but accept it if offered */
Modified: team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h (original)
+++ team/kmoore/pimp_sip_srtp/include/asterisk/res_sip_session.h Mon Apr 22 16:16:35 2013
@@ -26,6 +26,8 @@
#include "asterisk/channel.h"
/* Needed for ast_sockaddr struct */
#include "asterisk/netsock.h"
+/* Neeed for ast_sdp_srtp struct */
+#include "asterisk/sdp_srtp.h"
/* Forward declarations */
struct ast_sip_endpoint;
@@ -54,6 +56,8 @@
struct ast_sockaddr direct_media_addr;
/*! \brief SDP handler that setup the RTP */
struct ast_sip_session_sdp_handler *handler;
+ /*! \brief Holds SRTP information */
+ struct ast_sdp_srtp srtp;
/*! \brief Stream is on hold */
unsigned int held:1;
/*! \brief Stream type this session media handles */
Modified: team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h (original)
+++ team/kmoore/pimp_sip_srtp/include/asterisk/sdp_srtp.h Mon Apr 22 16:16:35 2013
@@ -81,8 +81,7 @@
* \retval 0 success
* \retval nonzero failure
*/
-int ast_sdp_crypto_process(struct ast_sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp);
-
+int ast_sdp_crypto_process(struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr);
/*! \brief Generate an SRTP a=crypto offer
*
Modified: team/kmoore/pimp_sip_srtp/main/sdp_srtp.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/main/sdp_srtp.c?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/main/sdp_srtp.c (original)
+++ team/kmoore/pimp_sip_srtp/main/sdp_srtp.c Mon Apr 22 16:16:35 2013
@@ -208,7 +208,7 @@
return res;
}
-int ast_sdp_crypto_process(struct ast_sdp_crypto *p, const char *attr, struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp)
+int ast_sdp_crypto_process(struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr)
{
char *str = NULL;
char *tag = NULL;
@@ -223,6 +223,7 @@
int suite_val = 0;
unsigned char remote_key[SRTP_MASTER_LEN];
int taglen = 0;
+ struct ast_sdp_crypto *crypto = srtp->crypto;
if (!ast_rtp_engine_srtp_is_registered()) {
return -1;
@@ -290,28 +291,28 @@
return -1;
}
- if (!memcmp(p->remote_key, remote_key, sizeof(p->remote_key))) {
+ if (!memcmp(crypto->remote_key, remote_key, sizeof(crypto->remote_key))) {
ast_debug(1, "SRTP remote key unchanged; maintaining current policy\n");
ast_set_flag(srtp, AST_SRTP_CRYPTO_OFFER_OK);
return 0;
}
- memcpy(p->remote_key, remote_key, sizeof(p->remote_key));
-
- if (ast_sdp_crypto_activate(p, suite_val, remote_key, rtp) < 0) {
- return -1;
- }
-
- if (!p->tag) {
+ memcpy(crypto->remote_key, remote_key, sizeof(crypto->remote_key));
+
+ if (ast_sdp_crypto_activate(crypto, suite_val, remote_key, rtp) < 0) {
+ return -1;
+ }
+
+ if (!crypto->tag) {
ast_log(LOG_DEBUG, "Accepting crypto tag %s\n", tag);
- p->tag = ast_strdup(tag);
- if (!p->tag) {
+ crypto->tag = ast_strdup(tag);
+ if (!crypto->tag) {
ast_log(LOG_ERROR, "Could not allocate memory for tag\n");
return -1;
}
}
/* Finally, rebuild the crypto line */
- if (ast_sdp_crypto_build_offer(p, taglen)) {
+ if (ast_sdp_crypto_build_offer(crypto, taglen)) {
return -1;
}
Modified: team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c (original)
+++ team/kmoore/pimp_sip_srtp/res/res_sip/sip_configuration.c Mon Apr 22 16:16:35 2013
@@ -286,8 +286,8 @@
endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_NONE;
} else if (!strcasecmp("sdes", var->value)) {
endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_SDES;
- } else if (!strcasecmp("dtls", var->value)) {
- endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_DTLS;
+ /*} else if (!strcasecmp("dtls", var->value)) {
+ endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_DTLS;*/
} else {
return -1;
}
Modified: team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c?view=diff&rev=386327&r1=386326&r2=386327
==============================================================================
--- team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c (original)
+++ team/kmoore/pimp_sip_srtp/res/res_sip_sdp_rtp.c Mon Apr 22 16:16:35 2013
@@ -47,6 +47,7 @@
#include "asterisk/causes.h"
#include "asterisk/sched.h"
#include "asterisk/acl.h"
+#include "asterisk/sdp_srtp.h"
#include "asterisk/res_sip.h"
#include "asterisk/res_sip_session.h"
@@ -457,6 +458,96 @@
session_media->rtp, pref);
}
+/*! \brief figure out media transport encryption type from the media transport string */
+static enum ast_sip_session_media_encryption get_media_encryption_type(pj_str_t transport)
+{
+ RAII_VAR(char *, transport_str, ast_strndup(transport.ptr, transport.slen), ast_free);
+ if (strstr(transport_str, "UDP/TLS")) {
+ return AST_SIP_MEDIA_ENCRYPT_DTLS;
+ } else if (strstr(transport_str, "SAVP")) {
+ return AST_SIP_MEDIA_ENCRYPT_SDES;
+ } else {
+ return AST_SIP_MEDIA_ENCRYPT_NONE;
+ }
+}
+
+/*!
+ * \brief Checks whether the encryption offered in SDP is compatible with the endpoint's configuration
+ * \internal
+ *
+ * \param endpoint_encryption Media encryption configured for the endpoint
+ * \param stream pjmedia_sdp_media stream description
+ *
+ * \retval AST_SIP_MEDIA_ENCRYPT_INVALID on encryption mismatch
+ * \retval The encryption requested in the SDP
+ */
+static enum ast_sip_session_media_encryption check_endpoint_media_encryption(
+ enum ast_sip_session_media_encryption endpoint_encryption,
+ const struct pjmedia_sdp_media *stream)
+{
+ enum ast_sip_session_media_encryption incoming_encryption;
+
+ incoming_encryption = get_media_encryption_type(stream->desc.transport);
+ if (incoming_encryption == AST_SIP_MEDIA_ENCRYPT_DTLS) {
+ /* DTLS not yet supported */
+ return AST_SIP_MEDIA_ENCRYPT_INVALID;
+ }
+
+ if (incoming_encryption == endpoint_encryption) {
+ return incoming_encryption;
+ }
+
+ switch (endpoint_encryption) {
+ case AST_SIP_MEDIA_ENCRYPT_DENY:
+ if (incoming_encryption != AST_SIP_MEDIA_ENCRYPT_NONE) {
+ /* Encryption offered, but not allowed */
+ return AST_SIP_MEDIA_ENCRYPT_INVALID;
+ }
+ break;
+ case AST_SIP_MEDIA_ENCRYPT_NONE:
+ if (incoming_encryption != AST_SIP_MEDIA_ENCRYPT_SDES) {
+ /* Can only silently upgrade to SDES from no encryption */
+ return AST_SIP_MEDIA_ENCRYPT_INVALID;
+ }
+ break;
+ case AST_SIP_MEDIA_ENCRYPT_SDES:
+ /* Can't silently upgrade or downgrade from SDES */
+ return AST_SIP_MEDIA_ENCRYPT_INVALID;
+ case AST_SIP_MEDIA_ENCRYPT_DTLS:
+ /* Can't silently upgrade or downgrade from DTLS */
+ return AST_SIP_MEDIA_ENCRYPT_INVALID;
+ case AST_SIP_MEDIA_ENCRYPT_INVALID:
+ /* This shouldn't ever happen */
+ return AST_SIP_MEDIA_ENCRYPT_INVALID;
+ }
+
+ return incoming_encryption;
+}
+
+static int setup_sdes_srtp(struct ast_sip_session_media *session_media,
+ const struct pjmedia_sdp_media *stream)
+{
+ pjmedia_sdp_attr *attr;
+ RAII_VAR(char *, crypto_str, NULL, ast_free);
+
+ /* check the stream for the required crypto attribute */
+ attr = pjmedia_sdp_media_find_attr2(stream, "crypto", NULL);
+ if (!attr) {
+ return -1;
+ }
+
+ crypto_str = ast_strndup(attr->value.ptr, attr->value.slen);
+ if (!crypto_str) {
+ return -1;
+ }
+
+ if (ast_sdp_crypto_process(session_media->rtp, &session_media->srtp, crypto_str)) {
+ return -1;
+ }
+
+ return 0;
+}
+
/*! \brief Function which negotiates an incoming media stream */
static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
@@ -464,12 +555,19 @@
char host[NI_MAXHOST];
RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
+ enum ast_sip_session_media_encryption incoming_encryption;
/* If no type formats have been configured reject this stream */
if (!ast_format_cap_has_type(session->endpoint->codecs, media_type)) {
return 0;
}
+ /* Ensure incoming encryption is compatible with the endpoint's configuration */
+ incoming_encryption = check_endpoint_media_encryption(session->endpoint->media_encryption, stream);
+ if (incoming_encryption == AST_SIP_MEDIA_ENCRYPT_INVALID) {
+ return -1;
+ }
+
ast_copy_pj_str(host, stream->conn ? &stream->conn->addr : &sdp->conn->addr, sizeof(host));
/* Ensure that the address provided is valid */
@@ -483,7 +581,32 @@
return -1;
}
+ if (incoming_encryption == AST_SIP_MEDIA_ENCRYPT_SDES
+ && setup_sdes_srtp(session_media, stream)) {
+ return -1;
+ }
+
return set_caps(session, session_media, stream);
+}
+
+static int add_crypto_to_stream(struct ast_sip_session_media *session_media,
+ pj_pool_t *pool, pjmedia_sdp_media *media)
+{
+ pj_str_t stmp;
+ pjmedia_sdp_attr *attr;
+ const char *crypto_attribute = ast_sdp_srtp_get_attrib(&session_media->srtp,
+ 0 /* DTLS can not be enabled for res_sip */,
+ 0 /* don't prefer 32byte tag length */);
+
+ if (!crypto_attribute) {
+ /* No crypto attribute to add */
+ return -1;
+ }
+
+ attr = pjmedia_sdp_attr_create(pool, "crypto", pj_cstr(&stmp, crypto_attribute));
+ media->attr[media->attr_count++] = attr;
+
+ return 0;
}
/*! \brief Function which creates an outgoing stream */
@@ -494,7 +617,6 @@
static const pj_str_t STR_IN = { "IN", 2 };
static const pj_str_t STR_IP4 = { "IP4", 3};
static const pj_str_t STR_IP6 = { "IP6", 3};
- static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
pjmedia_sdp_media *media;
char hostip[PJ_INET6_ADDRSTRLEN+2];
@@ -508,6 +630,7 @@
struct ast_format compat_format;
RAII_VAR(struct ast_format_cap *, caps, NULL, ast_format_cap_destroy);
enum ast_format_type media_type = stream_to_media_type(session_media->stream_type);
+ int crypto_res;
int direct_media_enabled = !ast_sockaddr_isnull(&session_media->direct_media_addr) &&
!ast_format_cap_is_empty(session->direct_media_cap);
@@ -524,9 +647,11 @@
return -1;
}
- /* TODO: This should eventually support SRTP */
+ crypto_res = add_crypto_to_stream(session_media, pool, media);
+
media->desc.media = pj_str(session_media->stream_type);
- media->desc.transport = STR_RTP_AVP;
+ media->desc.transport = pj_str(ast_sdp_get_rtp_profile(
+ !crypto_res, session_media->rtp, 0 /* not using AVPF */));
/* Add connection level details */
if (direct_media_enabled) {
More information about the asterisk-commits
mailing list