From fc703c961399b02cae13c57481cfdbcd73fb5fe6 Mon Sep 17 00:00:00 2001 From: Jonathan Rose Date: Tue, 15 May 2012 20:44:59 +0000 Subject: [PATCH] chan_sip: Check the right channel's host address for directmediapermit/deny Prior to this patch, when checking the addresses for directmediapermit and denydirectmediadeny, Asterisk would check the host address of the channel permit/deny was specified, which defers from the expectations of both our users and the development team. Instead, directmediapermit/deny now checks against the address of the channel that the peer with the ACL is connected to. (issue AST-876) Review: https://reviewboard.asterisk.org/r/1899/ ........ Merged revisions 366547 from http://svn.asterisk.org/svn/asterisk/branches/1.8 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@366591 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 52 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 33960ae85d..d87a267d46 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -29965,15 +29965,15 @@ static int reload_config(enum channelreloadreason reason) return 0; } -static int apply_directmedia_ha(struct sip_pvt *p, const char *op) +static int apply_directmedia_ha(struct sip_pvt *p1, struct sip_pvt *p2, const char *op) { struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, }; int res = AST_SENSE_ALLOW; - ast_rtp_instance_get_remote_address(p->rtp, &them); - ast_rtp_instance_get_local_address(p->rtp, &us); + ast_rtp_instance_get_remote_address(p1->rtp, &them); + ast_rtp_instance_get_local_address(p1->rtp, &us); - if ((res = ast_apply_ha(p->directmediaha, &them)) == AST_SENSE_DENY) { + if ((res = ast_apply_ha(p2->relatedpeer->directmediaha, &them)) == AST_SENSE_DENY) { const char *us_addr = ast_strdupa(ast_sockaddr_stringify(&us)); const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them)); @@ -29987,16 +29987,24 @@ static int apply_directmedia_ha(struct sip_pvt *p, const char *op) static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan) { struct sip_pvt *p; + struct ast_channel *opp_chan; + struct sip_pvt *opp; struct ast_udptl *udptl = NULL; - + p = chan->tech_pvt; if (!p) { return NULL; } - + + if (!(opp_chan = ast_bridged_channel(chan))) { + return NULL; + } else if ((opp_chan->tech != &sip_tech) || (!(opp = opp_chan->tech_pvt))) { + return NULL; + } + sip_pvt_lock(p); if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { - if (apply_directmedia_ha(p, "UDPTL T.38 data")) { + if (apply_directmedia_ha(p, opp, "UDPTL T.38 data")) { udptl = p->udptl; } } @@ -30050,12 +30058,20 @@ static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl) static enum ast_rtp_glue_result sip_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance) { struct sip_pvt *p = NULL; + struct ast_channel *opp_chan; + struct sip_pvt *opp = NULL; enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL; if (!(p = chan->tech_pvt)) { return AST_RTP_GLUE_RESULT_FORBID; } + if (!(opp_chan = ast_bridged_channel(chan))) { + return AST_RTP_GLUE_RESULT_FORBID; + } else if ((opp_chan->tech != &sip_tech) || (!(opp = opp_chan->tech_pvt))) { + return AST_RTP_GLUE_RESULT_FORBID; + } + sip_pvt_lock(p); if (!(p->rtp)) { sip_pvt_unlock(p); @@ -30067,7 +30083,7 @@ static enum ast_rtp_glue_result sip_get_rtp_peer(struct ast_channel *chan, struc if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { res = AST_RTP_GLUE_RESULT_REMOTE; - if (!apply_directmedia_ha(p, "audio")) { + if (!apply_directmedia_ha(p, opp, "audio")) { res = AST_RTP_GLUE_RESULT_FORBID; } } else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { @@ -30088,12 +30104,20 @@ static enum ast_rtp_glue_result sip_get_rtp_peer(struct ast_channel *chan, struc static enum ast_rtp_glue_result sip_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance) { struct sip_pvt *p = NULL; + struct ast_channel *opp_chan; + struct sip_pvt *opp = NULL; enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; if (!(p = chan->tech_pvt)) { return AST_RTP_GLUE_RESULT_FORBID; } + if (!(opp_chan = ast_bridged_channel(chan))) { + return AST_RTP_GLUE_RESULT_FORBID; + } else if ((opp_chan->tech != &sip_tech) || (!(opp = opp_chan->tech_pvt))) { + return AST_RTP_GLUE_RESULT_FORBID; + } + sip_pvt_lock(p); if (!(p->vrtp)) { sip_pvt_unlock(p); @@ -30105,7 +30129,7 @@ static enum ast_rtp_glue_result sip_get_vrtp_peer(struct ast_channel *chan, stru if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { res = AST_RTP_GLUE_RESULT_REMOTE; - if (!apply_directmedia_ha(p, "video")) { + if (!apply_directmedia_ha(p, opp, "video")) { res = AST_RTP_GLUE_RESULT_FORBID; } } @@ -30118,12 +30142,20 @@ static enum ast_rtp_glue_result sip_get_vrtp_peer(struct ast_channel *chan, stru static enum ast_rtp_glue_result sip_get_trtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance) { struct sip_pvt *p = NULL; + struct ast_channel *opp_chan; + struct sip_pvt *opp = NULL; enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID; if (!(p = chan->tech_pvt)) { return AST_RTP_GLUE_RESULT_FORBID; } + if (!(opp_chan = ast_bridged_channel(chan))) { + return AST_RTP_GLUE_RESULT_FORBID; + } else if ((opp_chan->tech != &sip_tech) || (!(opp = opp_chan->tech_pvt))) { + return AST_RTP_GLUE_RESULT_FORBID; + } + sip_pvt_lock(p); if (!(p->trtp)) { sip_pvt_unlock(p); @@ -30135,7 +30167,7 @@ static enum ast_rtp_glue_result sip_get_trtp_peer(struct ast_channel *chan, stru if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { res = AST_RTP_GLUE_RESULT_REMOTE; - if (!apply_directmedia_ha(p, "text")) { + if (!apply_directmedia_ha(p, opp, "text")) { res = AST_RTP_GLUE_RESULT_FORBID; } }