aboutsummaryrefslogtreecommitdiffstats
path: root/main/channel.c
diff options
context:
space:
mode:
authortwilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-06-08 05:29:08 +0000
committertwilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-06-08 05:29:08 +0000
commit9b1a36a294342fc418d9a359a4cf06bd90c4acb9 (patch)
treeecc27fc0db142ea1cd335a74cd1265f993fecd11 /main/channel.c
parent5f87b66641d86dbe7afec3b083016b2b1aceafc7 (diff)
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/ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@268894 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/channel.c')
-rw-r--r--main/channel.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/main/channel.c b/main/channel.c
index 42d42fb1b..c50cb6e13 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -65,6 +65,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/timing.h"
#include "asterisk/autochan.h"
#include "asterisk/stringfields.h"
+#include "asterisk/global_datastores.h"
#include "asterisk/data.h"
#ifdef HAVE_EPOLL
@@ -4803,6 +4804,46 @@ struct ast_channel *ast_request_and_dial(const char *type, format_t format, cons
return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL);
}
+static int set_security_requirements(const struct ast_channel *requestor, struct ast_channel *out)
+{
+ int ops[2][2] = {
+ {AST_OPTION_SECURE_SIGNALING, 0},
+ {AST_OPTION_SECURE_MEDIA, 0},
+ };
+ int i;
+ struct ast_channel *r = (struct ast_channel *) requestor; /* UGLY */
+ struct ast_datastore *ds;
+
+ if (!requestor || !out) {
+ return 0;
+ }
+
+ ast_channel_lock(r);
+ if ((ds = ast_channel_datastore_find(r, &secure_call_info, NULL))) {
+ struct ast_secure_call_store *encrypt = ds->data;
+ ops[0][1] = encrypt->signaling;
+ ops[1][1] = encrypt->media;
+ } else {
+ ast_channel_unlock(r);
+ return 0;
+ }
+ ast_channel_unlock(r);
+
+ for (i = 0; i < 2; i++) {
+ if (ops[i][1]) {
+ if (ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0)) {
+ /* We require a security feature, but the channel won't provide it */
+ return -1;
+ }
+ } else {
+ /* We don't care if we can't clear the option on a channel that doesn't support it */
+ ast_channel_setoption(out, ops[i][0], &ops[i][1], sizeof(ops[i][1]), 0);
+ }
+ }
+
+ return 0;
+}
+
struct ast_channel *ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
{
struct chanlist *chan;
@@ -4851,6 +4892,13 @@ struct ast_channel *ast_request(const char *type, format_t format, const struct
if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause)))
return NULL;
+ if (set_security_requirements(requestor, c)) {
+ ast_log(LOG_WARNING, "Setting security requirements failed\n");
+ c = ast_channel_release(c);
+ *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
+ return NULL;
+ }
+
/* no need to generate a Newchannel event here; it is done in the channel_alloc call */
return c;
}