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
10
Jonathan Rose 13 years ago
parent 2e83949259
commit fc703c9613

@ -29965,15 +29965,15 @@ static int reload_config(enum channelreloadreason reason)
return 0; 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, }, }; struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
int res = AST_SENSE_ALLOW; int res = AST_SENSE_ALLOW;
ast_rtp_instance_get_remote_address(p->rtp, &them); ast_rtp_instance_get_remote_address(p1->rtp, &them);
ast_rtp_instance_get_local_address(p->rtp, &us); 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 *us_addr = ast_strdupa(ast_sockaddr_stringify(&us));
const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them)); const char *them_addr = ast_strdupa(ast_sockaddr_stringify(&them));
@ -29987,6 +29987,8 @@ static int apply_directmedia_ha(struct sip_pvt *p, const char *op)
static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan) static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan)
{ {
struct sip_pvt *p; struct sip_pvt *p;
struct ast_channel *opp_chan;
struct sip_pvt *opp;
struct ast_udptl *udptl = NULL; struct ast_udptl *udptl = NULL;
p = chan->tech_pvt; p = chan->tech_pvt;
@ -29994,9 +29996,15 @@ static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan)
return NULL; 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); sip_pvt_lock(p);
if (p->udptl && ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) { 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; 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) 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 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; enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
if (!(p = chan->tech_pvt)) { if (!(p = chan->tech_pvt)) {
return AST_RTP_GLUE_RESULT_FORBID; 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); sip_pvt_lock(p);
if (!(p->rtp)) { if (!(p->rtp)) {
sip_pvt_unlock(p); 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)) { if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
res = AST_RTP_GLUE_RESULT_REMOTE; 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; res = AST_RTP_GLUE_RESULT_FORBID;
} }
} else if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) { } 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) 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 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; enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
if (!(p = chan->tech_pvt)) { if (!(p = chan->tech_pvt)) {
return AST_RTP_GLUE_RESULT_FORBID; 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); sip_pvt_lock(p);
if (!(p->vrtp)) { if (!(p->vrtp)) {
sip_pvt_unlock(p); 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)) { if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
res = AST_RTP_GLUE_RESULT_REMOTE; 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; 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) 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 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; enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_FORBID;
if (!(p = chan->tech_pvt)) { if (!(p = chan->tech_pvt)) {
return AST_RTP_GLUE_RESULT_FORBID; 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); sip_pvt_lock(p);
if (!(p->trtp)) { if (!(p->trtp)) {
sip_pvt_unlock(p); 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)) { if (ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA)) {
res = AST_RTP_GLUE_RESULT_REMOTE; 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; res = AST_RTP_GLUE_RESULT_FORBID;
} }
} }

Loading…
Cancel
Save