[asterisk-commits] branch oej/securertp - r7892 in
/team/oej/securertp: ./ channels/ include/ast...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Jan 9 10:25:25 CST 2006
Author: oej
Date: Mon Jan 9 10:25:20 2006
New Revision: 7892
URL: http://svn.digium.com/view/asterisk?rev=7892&view=rev
Log:
Integrating Mikael Magnusson's secure RTP patch with a few tiny changes
Modified:
team/oej/securertp/channels/chan_sip.c
team/oej/securertp/include/asterisk/aes.h
team/oej/securertp/include/asterisk/rtp.h
team/oej/securertp/res/Makefile
team/oej/securertp/rtp.c
Modified: team/oej/securertp/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/securertp/channels/chan_sip.c?rev=7892&r1=7891&r2=7892&view=diff
==============================================================================
--- team/oej/securertp/channels/chan_sip.c (original)
+++ team/oej/securertp/channels/chan_sip.c Mon Jan 9 10:25:20 2006
@@ -109,6 +109,18 @@
#define DEFAULT_MAX_EXPIRY 3600
#define DEFAULT_REGISTRATION_TIMEOUT 20
#define DEFAULT_MAX_FORWARDS "70"
+
+#define SRTP_MASTER_LEN 30
+#define SRTP_MASTERKEY_LEN 16
+#define SRTP_MASTERSALT_LEN (SRTP_MASTER_LEN - SRTP_MASTERKEY_LEN)
+#define SRTP_MASTER_LEN64 ((SRTP_MASTER_LEN * 8 + 5) / 6 + 1)
+
+/*! \brief structure for secure RTP audio */
+struct sip_srtp {
+ char *a_crypto;
+ unsigned char local_key[SRTP_MASTER_LEN];
+ char local_key64[SRTP_MASTER_LEN64];
+};
/* guard limit must be larger than guard secs */
/* guard min must be < 1000, and should be >= 250 */
@@ -704,6 +716,7 @@
struct ast_variable *chanvars; /*!< Channel variables to set for call */
struct sip_pvt *next; /*!< Next call in chain */
struct sip_invite_param *options; /*!< Options for INVITE */
+ struct sip_srtp *srtp; /*!< Structure for Secure RTP session data */
} *iflist = NULL;
#define FLAG_RESPONSE (1 << 0)
@@ -1993,6 +2006,235 @@
}
+/*
+ * SRTP sdescriptions
+ * Specified in: draft-ietf-mmusic-sdescriptions-12.txt
+ */
+
+static struct sip_srtp *sip_srtp_alloc(void)
+{
+ struct sip_srtp *srtp = malloc(sizeof(*srtp));
+
+ if (srtp)
+ memset(srtp, 0, sizeof(*srtp));
+ else
+ ast_log(LOG_ERROR, "Out of memory, can't allocate srtp structure\n");
+
+ return srtp;
+}
+
+static void sip_srtp_destroy(struct sip_srtp *srtp)
+{
+ free(srtp->a_crypto);
+ srtp->a_crypto = NULL;
+}
+
+
+static int setup_crypto(struct sip_pvt *p)
+{
+ if (!ast_srtp_is_registered()) {
+ ast_log(LOG_ERROR, "No SRTP module loaded, can't setup SRTP session.\n");
+ return -1;
+ }
+
+ p->srtp = sip_srtp_alloc(); /* Allocate SRTP data structure */
+ if (!p->srtp)
+ return -1;
+
+ if (ast_srtp_get_random(p->srtp->local_key, sizeof(p->srtp->local_key)) < 0) {
+ sip_srtp_destroy(p->srtp);
+ p->srtp = NULL;
+ return -1;
+ }
+
+ ast_base64encode(p->srtp->local_key64, p->srtp->local_key,
+ SRTP_MASTER_LEN, sizeof(p->srtp->local_key64));
+ return 0;
+}
+
+static int set_crypto_policy(struct ast_srtp_policy *policy,
+ int suite_val, const unsigned char *master_key,
+ unsigned long ssrc, int inbound)
+{
+ const unsigned char *master_salt = NULL;
+
+ master_salt = master_key + SRTP_MASTERKEY_LEN;
+ if (ast_srtp_policy_set_master_key(policy,
+ master_key, SRTP_MASTERKEY_LEN,
+ master_salt, SRTP_MASTERSALT_LEN) < 0)
+ return -1;
+
+
+ if (ast_srtp_policy_set_suite(policy, suite_val)) {
+ ast_log(LOG_WARNING, "Could not set remote SRTP suite\n");
+ return -1;
+ }
+
+ ast_srtp_policy_set_ssrc(policy, ssrc, inbound);
+
+ return 0;
+}
+
+static int activate_crypto(struct sip_pvt *p, int suite_val,
+ unsigned char *remote_key)
+{
+ struct ast_srtp_policy *local_policy = NULL;
+ struct ast_srtp_policy *remote_policy = NULL;
+ int res = -1;
+ struct sip_srtp *srtp = p->srtp;
+
+ if (!srtp)
+ return -1;
+
+ local_policy = ast_srtp_policy_alloc();
+ if (!local_policy)
+ goto err;
+
+ remote_policy = ast_srtp_policy_alloc();
+ if (!remote_policy) {
+ goto err;
+ }
+
+ if (set_crypto_policy(local_policy, suite_val, srtp->local_key,
+ ast_rtp_get_ssrc(p->rtp), 0) < 0)
+ goto err;
+
+ if (set_crypto_policy(remote_policy, suite_val, remote_key, 0, 1) < 0)
+ goto err;
+
+ if (ast_rtp_add_srtp_policy(p->rtp, local_policy)) {
+ ast_log(LOG_WARNING, "Could not set local SRTP policy\n");
+ goto err;
+ }
+
+ if (ast_rtp_add_srtp_policy(p->rtp, remote_policy)) {
+ ast_log(LOG_WARNING, "Could not set remote SRTP policy\n");
+ goto err;
+ }
+
+
+ if (option_debug > 1)
+ ast_log(LOG_DEBUG, "SRTP policy activated\n");
+ res = 0;
+
+err:
+ if (local_policy)
+ ast_srtp_policy_destroy(local_policy);
+
+ if (remote_policy)
+ ast_srtp_policy_destroy(remote_policy);
+ return res;
+}
+
+static int process_crypto(struct sip_pvt *p, const char *attr)
+{
+ char *str = NULL;
+ char *name = NULL;
+ char *tag = NULL;
+ char *suite = NULL;
+ char *key_params = NULL;
+ char *key_param = NULL;
+ char *session_params = NULL;
+ char *key_salt = NULL;
+ char *lifetime = NULL;
+ int found = 0;
+ int attr_len = strlen(attr);
+ int key_len = 0;
+ unsigned char remote_key[SRTP_MASTER_LEN];
+ int suite_val = 0;
+ struct sip_srtp *srtp = p->srtp;
+
+ if (!ast_srtp_is_registered())
+ return -1;
+
+ /* Crypto already accepted */
+ if (srtp && srtp->a_crypto)
+ return -1;
+
+ str = ast_strdupa(attr);
+
+ name = strsep(&str, ":");
+ tag = strsep(&str, " ");
+ suite = strsep(&str, " ");
+ key_params = strsep(&str, " ");
+ session_params = strsep(&str, " ");
+
+ if (!tag || !suite) {
+ ast_log(LOG_WARNING, "Unrecognized a=%s", attr);
+ return -1;
+ }
+
+ if (session_params) {
+ ast_log(LOG_WARNING, "Unsupported crypto parameters: %s",
+ session_params);
+ return -1;
+ }
+
+ if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
+ suite_val = AST_AES_CM_128_HMAC_SHA1_80;
+ } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
+ suite_val = AST_AES_CM_128_HMAC_SHA1_32;
+ } else {
+ ast_log(LOG_WARNING, "Unsupported crypto suite: %s",
+ suite);
+ return -1;
+ }
+
+ while ((key_param = strsep(&key_params, ";"))) {
+ char *method = NULL;
+ char *info = NULL;
+
+ method = strsep(&key_param, ":");
+ info = strsep(&key_param, ";");
+
+ if (!strcmp(method, "inline")) {
+ key_salt = strsep(&info, "|");
+ lifetime = strsep(&info, "|");
+
+ if (lifetime) {
+ ast_log(LOG_NOTICE, "Crypto life time unsupported: %s\n",
+ attr);
+ continue;
+ }
+
+/* if (info || strncmp(lifetime, "2^", 2)) { */
+/* ast_log(LOG_NOTICE, "MKI unsupported: %s\n", */
+/* attr); */
+/* continue; */
+/* } */
+
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ ast_log(LOG_NOTICE, "SRTP crypto offer not acceptable\n");
+ return -1;
+ }
+
+ if (!srtp) {
+ setup_crypto(p);
+ srtp = p->srtp;
+ }
+
+ key_len = ast_base64decode(remote_key, key_salt, sizeof(remote_key));
+ if (key_len != SRTP_MASTER_LEN) {
+ ast_log(LOG_WARNING, "SRTP sdescriptions key %d != %d\n",
+ key_len, SRTP_MASTER_LEN);
+ return -1;
+ }
+
+ if (activate_crypto(p, suite_val, remote_key) < 0)
+ return -1;
+
+ srtp->a_crypto = malloc(attr_len+11);
+ snprintf(srtp->a_crypto, attr_len+10,
+ "a=crypto:%s %s inline:%s\r\n",
+ tag, suite, srtp->local_key64);
+
+ return 0;
+}
/*! \brief sip_call: Initiate SIP call from PBX
@@ -2031,6 +2273,18 @@
} else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
/* Check whether there is a variable with a name starting with SIPADDHEADER */
p->options->addsipheaders = 1;
+ } 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");
+ return -1;
+ }
+
+ if (!p->srtp) {
+ if (setup_crypto(p) < 0) {
+ ast_log(LOG_WARNING, "SIP SRTP sdes setup failed\n");
+ return -1;
+ }
+ }
}
@@ -2176,6 +2430,10 @@
if (p->chanvars) {
ast_variables_destroy(p->chanvars);
p->chanvars = NULL;
+ }
+ if (p->srtp) {
+ sip_srtp_destroy(p->srtp);
+ p->srtp = NULL;
}
ast_mutex_destroy(&p->lock);
@@ -3091,6 +3349,7 @@
snprintf(tagbuf, len, "as%08x", thread_safe_rand());
}
+
/*! \brief sip_alloc: Allocate SIP_PVT structure and set defaults ---*/
static struct sip_pvt *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
int useglobal_nat, const int intended_method)
@@ -3484,6 +3743,7 @@
int x,y;
int debug=sip_debug_test_pvt(p);
struct ast_channel *bridgepeer = NULL;
+ int secure_audio = 0;
if (!p->rtp) {
ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
@@ -3519,9 +3779,24 @@
sdpLineNum_iterator_init(&iterator);
ast_set_flag(p, SIP_NOVIDEO);
while ((m = get_sdp_iterate(&iterator, req, "m"))[0] != '\0') {
+ char protocol[5] = "";
int found = 0;
- if ((sscanf(m, "audio %d/%d RTP/AVP %n", &x, &y, &len) == 2) ||
- (sscanf(m, "audio %d RTP/AVP %n", &x, &len) == 1)) {
+
+ len = -1;
+ if ((sscanf(m, "audio %d/%d RTP/%4s %n", &x, &y, protocol, &len) == 3) ||
+ (sscanf(m, "audio %d RTP/%4s %n", &x, protocol, &len) == 2)) {
+ 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;
+ }
+
+ if (len < 0) {
+ ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m);
+ continue;
+ }
+
found = 1;
portno = x;
/* Scan through the RTP payload types specified in a "m=" line: */
@@ -3541,7 +3816,13 @@
if (p->vrtp)
ast_rtp_pt_clear(p->vrtp); /* Must be cleared in case no m=video line exists */
+ len= -1;
if (p->vrtp && (sscanf(m, "video %d RTP/AVP %n", &x, &len) == 1)) {
+ if (len < 0) {
+ ast_log(LOG_WARNING, "Unknown SDP media type in offer: %s\n", m);
+ continue;
+ }
+
found = 1;
ast_clear_flag(p, SIP_NOVIDEO);
vportno = x;
@@ -3628,9 +3909,14 @@
sendonly=1;
continue;
}
+ if (!strncasecmp(a, "crypto:", 7)) {
+ process_crypto(p, a);
+ continue;
+ }
if (!strcasecmp(a, "sendrecv")) {
sendonly=0;
}
+
if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) continue;
if (debug)
ast_verbose("Found description format %s\n", mimeSubtype);
@@ -3638,6 +3924,11 @@
ast_rtp_set_rtpmap_type(p->rtp, codec, "audio", mimeSubtype);
if (p->vrtp)
ast_rtp_set_rtpmap_type(p->vrtp, 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;
}
/* Now gather all of the codecs that were asked for: */
@@ -4399,6 +4690,8 @@
char m_video[256];
char a_audio[1024];
char a_video[1024];
+ char crypto_buf[128];
+ const char *a_crypto = NULL;
char *m_audio_next = m_audio;
char *m_video_next = m_video;
size_t m_audio_left = sizeof(m_audio);
@@ -4413,6 +4706,8 @@
struct sockaddr_in dest;
struct sockaddr_in vdest = { 0, };
int debug;
+ const char *protocol = NULL;
+ struct sip_srtp *srtp = p->srtp;
debug = sip_debug_test_pvt(p);
@@ -4458,6 +4753,24 @@
ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ntohs(vsin.sin_port));
}
+ if (srtp) {
+ if (srtp->a_crypto) {
+ a_crypto = srtp->a_crypto;
+ } else {
+ const char *crypto_suite = "AES_CM_128_HMAC_SHA1_80";
+ snprintf(crypto_buf, sizeof(crypto_buf),
+ "a=crypto:1 %s inline:%s\r\n",
+ crypto_suite, srtp->local_key64);
+ a_crypto = crypto_buf;
+ }
+ }
+
+ if (a_crypto) {
+ protocol = "SAVP";
+ } else {
+ protocol = "AVP";
+ }
+
/* We break with the "recommendation" and send our IP, in order that our
peer doesn't have to ast_gethostbyname() us */
@@ -4467,7 +4780,7 @@
snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr));
snprintf(t, sizeof(t), "t=0 0\r\n");
- ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
+ ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/%s", ntohs(dest.sin_port), protocol);
ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
/* Prefer the codec we were requested to use, first, no matter what */
@@ -4551,6 +4864,9 @@
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)
+ len += strlen(a_crypto);
+
add_header(resp, "Content-Type", "application/sdp");
add_header_contentLength(resp, len);
add_line(resp, v);
@@ -4560,6 +4876,8 @@
add_line(resp, t);
add_line(resp, m_audio);
add_line(resp, a_audio);
+ if (a_crypto)
+ add_line(resp, a_crypto);
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);
Modified: team/oej/securertp/include/asterisk/aes.h
URL: http://svn.digium.com/view/asterisk/team/oej/securertp/include/asterisk/aes.h?rev=7892&r1=7891&r2=7892&view=diff
==============================================================================
--- team/oej/securertp/include/asterisk/aes.h (original)
+++ team/oej/securertp/include/asterisk/aes.h Mon Jan 9 10:25:20 2006
@@ -115,6 +115,8 @@
#ifdef AES_ENCRYPT
+#define aes_encrypt ast_aes_encrypt
+
typedef struct
{ aes_32t ks[KS_LENGTH];
} aes_encrypt_ctx;
@@ -139,6 +141,8 @@
#endif
#ifdef AES_DECRYPT
+
+#define aes_decrypt ast_aes_decrypt
typedef struct
{ aes_32t ks[KS_LENGTH];
Modified: team/oej/securertp/include/asterisk/rtp.h
URL: http://svn.digium.com/view/asterisk/team/oej/securertp/include/asterisk/rtp.h?rev=7892&r1=7891&r2=7892&view=diff
==============================================================================
--- team/oej/securertp/include/asterisk/rtp.h (original)
+++ team/oej/securertp/include/asterisk/rtp.h Mon Jan 9 10:25:20 2006
@@ -68,6 +68,66 @@
*/
struct ast_rtp;
+struct ast_srtp;
+
+struct ast_srtp_policy;
+
+struct ast_srtp_cb {
+ int (*no_ctx)(struct ast_rtp *rtp, unsigned long ssrc, void *data);
+};
+
+struct ast_srtp_res {
+ int (*create)(struct ast_srtp **srtp, struct ast_rtp *rtp,
+ struct ast_srtp_policy *policy);
+ void (*destroy)(struct ast_srtp *srtp);
+ int (*add_stream)(struct ast_srtp *srtp, struct ast_srtp_policy *policy);
+ void (*set_cb)(struct ast_srtp *srtp,
+ const struct ast_srtp_cb *cb, void *data);
+ int (*unprotect)(struct ast_srtp *srtp, void *buf, int *size);
+ int (*protect)(struct ast_srtp *srtp, void **buf, int *size);
+ int (*get_random)(unsigned char *key, size_t len);
+};
+
+/* Crypto suites */
+enum ast_srtp_suite {
+ AST_AES_CM_128_HMAC_SHA1_80 = 1,
+ AST_AES_CM_128_HMAC_SHA1_32 = 2,
+ AST_F8_128_HMAC_SHA1_80 = 3
+};
+
+enum ast_srtp_ealg {
+ AST_MIKEY_SRTP_EALG_NULL = 0,
+ AST_MIKEY_SRTP_EALG_AESCM = 1
+};
+
+enum ast_srtp_aalg {
+ AST_MIKEY_SRTP_AALG_NULL = 0,
+ AST_MIKEY_SRTP_AALG_SHA1HMAC = 1
+};
+
+struct ast_srtp_policy_res {
+ struct ast_srtp_policy *(*alloc)(void);
+ void (*destroy)(struct ast_srtp_policy *policy);
+ int (*set_suite)(struct ast_srtp_policy *policy,
+ enum ast_srtp_suite suite);
+ int (*set_master_key)(struct ast_srtp_policy *policy,
+ const unsigned char *key, size_t key_len,
+ const unsigned char *salt, size_t salt_len);
+ int (*set_encr_alg)(struct ast_srtp_policy *policy,
+ enum ast_srtp_ealg ealg);
+ int (*set_auth_alg)(struct ast_srtp_policy *policy,
+ enum ast_srtp_aalg aalg);
+ void (*set_encr_keylen)(struct ast_srtp_policy *policy, int ekeyl);
+ void (*set_auth_keylen)(struct ast_srtp_policy *policy, int akeyl);
+ void (*set_srtp_auth_taglen)(struct ast_srtp_policy *policy, int autht);
+ void (*set_srtp_encr_enable)(struct ast_srtp_policy *policy, int enable);
+ void (*set_srtcp_encr_enable)(struct ast_srtp_policy *policy, int enable);
+ void (*set_srtp_auth_enable)(struct ast_srtp_policy *policy, int enable);
+ void (*set_ssrc)(struct ast_srtp_policy *policy, unsigned long ssrc,
+ int inbound);
+};
+
+
typedef int (*ast_rtp_callback)(struct ast_rtp *rtp, struct ast_frame *f, void *data);
/*!
@@ -162,6 +222,32 @@
void ast_rtp_reload(void);
+int ast_rtp_register_srtp(struct ast_srtp_res *srtp_res, struct ast_srtp_policy_res *policy_res);
+
+int ast_rtp_unregister_srtp(struct ast_srtp_res *srtp_res, struct ast_srtp_policy_res *policy_res);
+
+int ast_srtp_is_registered(void);
+
+unsigned int ast_rtp_get_ssrc(struct ast_rtp *rtp);
+void ast_rtp_set_srtp_cb(struct ast_rtp *rtp, const struct ast_srtp_cb *cb,
+ void *data);
+int ast_rtp_add_srtp_policy(struct ast_rtp *rtp, struct ast_srtp_policy *policy);
+struct ast_srtp_policy *ast_srtp_policy_alloc(void);
+int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite);
+int ast_srtp_policy_set_master_key(struct ast_srtp_policy *policy, const unsigned char *key, size_t key_len, const unsigned char *salt, size_t salt_len);
+int ast_srtp_policy_set_encr_alg(struct ast_srtp_policy *policy, enum ast_srtp_ealg ealg);
+int ast_srtp_policy_set_auth_alg(struct ast_srtp_policy *policy, enum ast_srtp_aalg aalg);
+void ast_srtp_policy_set_encr_keylen(struct ast_srtp_policy *policy, int ekeyl);
+void ast_srtp_policy_set_auth_keylen(struct ast_srtp_policy *policy, int akeyl);
+void ast_srtp_policy_set_srtp_auth_taglen(struct ast_srtp_policy *policy, int autht);
+void ast_srtp_policy_set_srtp_encr_enable(struct ast_srtp_policy *policy, int enable);
+void ast_srtp_policy_set_srtcp_encr_enable(struct ast_srtp_policy *policy, int enable);
+void ast_srtp_policy_set_srtp_auth_enable(struct ast_srtp_policy *policy, int enable);
+void ast_srtp_policy_set_ssrc(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound);
+
+void ast_srtp_policy_destroy(struct ast_srtp_policy *policy);
+int ast_srtp_get_random(unsigned char *key, size_t len);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
Modified: team/oej/securertp/res/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/securertp/res/Makefile?rev=7892&r1=7891&r2=7892&view=diff
==============================================================================
--- team/oej/securertp/res/Makefile (original)
+++ team/oej/securertp/res/Makefile Mon Jan 9 10:25:20 2006
@@ -60,6 +60,12 @@
endif
endif # WITHOUT_ZAPTEL
+ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/local/include/srtp)$(wildcard $(CROSS_COMPILE_TARGET)/usr/include/srtp),)
+ MODS+=res_srtp.so
+ SRTP_LIBS=-lsrtp
+endif
+
+
#
# Work around buggy RedHat 9.0
#
@@ -109,6 +115,9 @@
res_config_odbc.so: res_config_odbc.o
$(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} ${CYG_RES_CONFIG_ODBC_LIB}
+res_srtp.so: res_srtp.o
+ $(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} ${SRTP_LIBS}
+
ifneq ($(wildcard .depend),)
include .depend
endif
Modified: team/oej/securertp/rtp.c
URL: http://svn.digium.com/view/asterisk/team/oej/securertp/rtp.c?rev=7892&r1=7891&r2=7892&view=diff
==============================================================================
--- team/oej/securertp/rtp.c (original)
+++ team/oej/securertp/rtp.c Mon Jan 9 10:25:20 2006
@@ -72,6 +72,9 @@
#ifdef SO_NO_CHECK
static int nochecksums = 0;
#endif
+
+struct ast_srtp_res *g_srtp_res;
+struct ast_srtp_policy_res *g_policy_res;
/*! \brief The value of each payload format mapping: */
struct rtpPayloadType {
@@ -124,6 +127,7 @@
int rtp_lookup_code_cache_code;
int rtp_lookup_code_cache_result;
struct ast_rtcp *rtcp;
+ struct ast_srtp *srtp;
};
/*!
@@ -348,6 +352,235 @@
rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
f = &rtp->f;
return f;
+}
+
+int ast_rtp_register_srtp(struct ast_srtp_res *srtp_res,
+ struct ast_srtp_policy_res *policy_res)
+{
+ if (g_srtp_res || g_policy_res)
+ return -1;
+
+ if (!srtp_res || !policy_res)
+ return -1;
+
+ g_srtp_res = srtp_res;
+ g_policy_res = policy_res;
+ return 0;
+}
+
+int ast_rtp_unregister_srtp(struct ast_srtp_res *srtp_res,
+ struct ast_srtp_policy_res *policy_res)
+{
+ g_srtp_res = NULL;
+ g_policy_res = NULL;
+ return 0;
+}
+
+int ast_srtp_is_registered(void)
+{
+ return g_srtp_res && g_policy_res;
+}
+
+unsigned int ast_rtp_get_ssrc(struct ast_rtp *rtp)
+{
+ return rtp->ssrc;
+}
+
+void ast_rtp_set_srtp_cb(struct ast_rtp *rtp, const struct ast_srtp_cb *cb,
+ void *data)
+{
+ if (!g_srtp_res || !rtp->srtp)
+ return;
+
+ g_srtp_res->set_cb(rtp->srtp, cb, data);
+}
+
+void
+ast_srtp_policy_set_ssrc(struct ast_srtp_policy *policy,
+ unsigned long ssrc, int inbound)
+{
+ if (!g_policy_res)
+ return;
+
+ g_policy_res->set_ssrc(policy, ssrc, inbound);
+}
+
+int ast_rtp_add_srtp_policy(struct ast_rtp *rtp, struct ast_srtp_policy *policy)
+{
+ int res;
+
+ if (!g_srtp_res)
+ return -1;
+
+ if (!rtp->srtp) {
+ res = g_srtp_res->create(&rtp->srtp, rtp, policy);
+ } else {
+ res = g_srtp_res->add_stream(rtp->srtp, policy);
+ }
+
+ return res;
+}
+
+struct ast_srtp_policy *ast_srtp_policy_alloc()
+{
+ if (!g_policy_res)
+ return NULL;
+
+ return g_policy_res->alloc();
+}
+
+void
+ast_srtp_policy_destroy(struct ast_srtp_policy *policy)
+{
+ if (!g_policy_res)
+ return;
+
+ g_policy_res->destroy(policy);
+}
+
+int
+ast_srtp_policy_set_suite(struct ast_srtp_policy *policy,
+ enum ast_srtp_suite suite)
+{
+ if (!g_policy_res)
+ return -1;
+
+ return g_policy_res->set_suite(policy, suite);
+}
+
+int
+ast_srtp_policy_set_master_key(struct ast_srtp_policy *policy,
+ const unsigned char *key, size_t key_len,
+ const unsigned char *salt, size_t salt_len)
+{
+ if (!g_policy_res)
+ return -1;
+
+ return g_policy_res->set_master_key(policy, key, key_len,
+ salt, salt_len);
+}
+
+int
+ast_srtp_policy_set_encr_alg(struct ast_srtp_policy *policy,
+ enum ast_srtp_ealg ealg)
+{
+ if (!g_policy_res)
+ return -1;
+
+ return g_policy_res->set_encr_alg(policy, ealg);
+}
+
+int
+ast_srtp_policy_set_auth_alg(struct ast_srtp_policy *policy,
+ enum ast_srtp_aalg aalg)
+{
+ if (!g_policy_res)
+ return -1;
+
+ return g_policy_res->set_auth_alg(policy, aalg);
+}
+
+void ast_srtp_policy_set_encr_keylen(struct ast_srtp_policy *policy, int ekeyl)
+{
+ if (!g_policy_res)
+ return;
+
+ return g_policy_res->set_encr_keylen(policy, ekeyl);
+}
+
+void
+ast_srtp_policy_set_auth_keylen(struct ast_srtp_policy *policy,
+ int akeyl)
+{
+ if (!g_policy_res)
+ return;
+
+ return g_policy_res->set_auth_keylen(policy, akeyl);
+}
+
+void
+ast_srtp_policy_set_srtp_auth_taglen(struct ast_srtp_policy *policy,
+ int autht)
+{
+ if (!g_policy_res)
+ return;
+
+ return g_policy_res->set_srtp_auth_taglen(policy, autht);
+}
+
+void
+ast_srtp_policy_set_srtp_encr_enable(struct ast_srtp_policy *policy,
+ int enable)
+{
+ if (!g_policy_res)
+ return;
+
+ return g_policy_res->set_srtp_encr_enable(policy, enable);
+}
+
+void
+ast_srtp_policy_set_srtcp_encr_enable(struct ast_srtp_policy *policy,
+ int enable)
+{
+ if (!g_policy_res)
+ return;
+
+ return g_policy_res->set_srtcp_encr_enable(policy, enable);
+}
+
+void
+ast_srtp_policy_set_srtp_auth_enable(struct ast_srtp_policy *policy,
+ int enable)
+{
+ if (!g_policy_res)
+ return;
+
+ return g_policy_res->set_srtp_auth_enable(policy, enable);
+}
+
+int ast_srtp_get_random(unsigned char *key, size_t len)
+{
+ if (!g_srtp_res)
+ return -1;
+
+ return g_srtp_res->get_random(key, len);
+}
+
+static int rtp_recvfrom(struct ast_rtp *rtp, void *buf, size_t size,
+ int flags, struct sockaddr *sa, socklen_t *salen)
+{
+ int len;
+
+ len = recvfrom(rtp->s, buf, size, flags, sa, salen);
+
+ if (len < 0)
+ return len;
+
+ if (g_srtp_res && rtp->srtp) {
+ int res;
+
+ res = g_srtp_res->unprotect(rtp->srtp, buf, &len);
+ if (res < 0)
+ return -1;
+ }
+
+ return len;
+}
+
+static int rtp_sendto(struct ast_rtp *rtp, void *buf, size_t size,
+ int flags, struct sockaddr *sa, socklen_t salen)
+{
+ int len = size;
+ void *temp = buf;
+
+ if (g_srtp_res && rtp->srtp) {
+ int res = g_srtp_res->protect(rtp->srtp, &temp, &len);
+
+ if (res < 0)
+ return -1;
+ }
+
+ return sendto(rtp->s, temp, len, flags, sa, salen);
}
static int rtpread(int *id, int fd, short events, void *cbdata)
@@ -440,7 +673,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);
@@ -1167,6 +1400,10 @@
close(rtp->rtcp->s);
free(rtp->rtcp);
}
+ if (g_srtp_res && rtp->srtp) {
+ g_srtp_res->destroy(rtp->srtp);
+ rtp->srtp = NULL;
+ }
free(rtp);
}
@@ -1229,7 +1466,7 @@
rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
for (x = 0; x < 6; x++) {
if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
- res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them));
+ res = rtp_sendto(rtp, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them));
if (res < 0)
ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n",
ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr),
@@ -1295,7 +1532,7 @@
rtpheader[2] = htonl(rtp->ssrc);
data[12] = level;
if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
- res = sendto(rtp->s, (void *)rtpheader, hdrlen + 1, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
+ res = rtp_sendto(rtp, (void *)rtpheader, hdrlen + 1, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
if (res <0)
ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
if(rtp_debug_test_addr(&rtp->them))
@@ -1365,7 +1602,7 @@
put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc));
if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
- res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
+ res = rtp_sendto(rtp, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
if (res <0) {
if (!rtp->nat || (rtp->nat && (ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) {
ast_log(LOG_DEBUG, "RTP Transmission error of packet %d to %s:%d: %s\n", rtp->seqno, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
@@ -1635,6 +1872,14 @@
ast_mutex_unlock(&c1->lock);
return AST_BRIDGE_FAILED_NOWARN;
}
+
+ 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);
+ return AST_BRIDGE_FAILED_NOWARN;
+ }
+
/* Get codecs from both sides */
if (pr0->get_codec)
codec0 = pr0->get_codec(c0);
More information about the asterisk-commits
mailing list