aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-19 14:17:16 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-19 14:17:16 +0000
commitebd3af43fbc272034e175e362f843236f4ccd8e9 (patch)
treebcdc61e834bd23afa2615d4822441ca26b65b4f8 /channels
parente544867c9a1eaf871452b73c088793d188fc8faf (diff)
Make ACLs IPv6-capable.
ACLs can now be configured to match IPv6 networks. This is only relevant for ACLs in chan_sip for now since other channel drivers do not support IPv6 addressing. However, once those channel drivers are outfitted to support IPv6 addressing, the ACLs will already be ready for IPv6 support. https://reviewboard.asterisk.org/r/791 git-svn-id: http://svn.digium.com/svn/asterisk/trunk@277814 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_iax2.c25
-rw-r--r--channels/chan_sip.c75
-rw-r--r--channels/chan_skinny.c4
3 files changed, 46 insertions, 58 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 72e6b666c..92f070be2 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -2039,15 +2039,17 @@ static int addr_range_delme_cb(void *obj, void *arg, int flags)
static int addr_range_hash_cb(const void *obj, const int flags)
{
const struct addr_range *lim = obj;
- return abs((int) lim->ha.netaddr.s_addr);
+ struct sockaddr_in sin;
+ ast_sockaddr_to_sin(&lim->ha.addr, &sin);
+ return abs((int) sin.sin_addr.s_addr);
}
static int addr_range_cmp_cb(void *obj, void *arg, int flags)
{
struct addr_range *lim1 = obj, *lim2 = arg;
- return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
- (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
- CMP_MATCH | CMP_STOP : 0;
+ return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
+ !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
+ CMP_MATCH | CMP_STOP : 0;
}
static int peercnt_hash_cb(const void *obj, const int flags)
@@ -2066,8 +2068,13 @@ static int addr_range_match_address_cb(void *obj, void *arg, int flags)
{
struct addr_range *addr_range = obj;
struct sockaddr_in *sin = arg;
+ struct sockaddr_in ha_netmask_sin;
+ struct sockaddr_in ha_addr_sin;
+
+ ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
+ ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
- if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
+ if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
return CMP_MATCH | CMP_STOP;
}
return 0;
@@ -7385,6 +7392,7 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
int gotcapability = 0;
struct ast_variable *v = NULL, *tmpvar = NULL;
struct ao2_iterator i;
+ struct ast_sockaddr addr;
if (!iaxs[callno])
return res;
@@ -7442,10 +7450,11 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
}
/* Search the userlist for a compatible entry, and fill in the rest */
i = ao2_iterator_init(users, 0);
+ ast_sockaddr_from_sin(&addr, sin);
while ((user = ao2_iterator_next(&i))) {
if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */
!strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
- && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */
+ && ast_apply_ha(user->ha, &addr) /* Access is permitted from this IP */
&& (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */
apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */
if (!ast_strlen_zero(iaxs[callno]->username)) {
@@ -7787,6 +7796,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *
int x;
int expire = 0;
int res = -1;
+ struct ast_sockaddr addr;
ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
/* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
@@ -7841,7 +7851,8 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *
goto return_unref;
}
- if (!ast_apply_ha(p->ha, sin)) {
+ ast_sockaddr_from_sin(&addr, sin);
+ if (!ast_apply_ha(p->ha, &addr)) {
if (authdebug)
ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
goto return_unref;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 792ca6980..b6e167a79 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -3084,7 +3084,7 @@ static void build_via(struct sip_pvt *p)
static void ast_sip_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us, struct sip_pvt *p)
{
struct ast_sockaddr theirs;
- struct sockaddr_in theirs_sin, externip_sin, us_sin;
+ struct sockaddr_in externip_sin;
/* Set want_remap to non-zero if we want to remap 'us' to an externally
* reachable IP address and port. This is done if:
@@ -3112,16 +3112,13 @@ static void ast_sip_ouraddrfor(const struct ast_sockaddr *them, struct ast_socka
"remove \"localnet\" and/or \"externip\" settings.\n");
}
} else {
- ast_sockaddr_to_sin(&theirs, &theirs_sin);
- ast_sockaddr_to_sin(us, &us_sin);
-
want_remap = localaddr &&
!(ast_sockaddr_isnull(&externip) && stunaddr.sin_addr.s_addr) &&
- ast_apply_ha(localaddr, &theirs_sin) == AST_SENSE_ALLOW ;
+ ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;
}
if (want_remap &&
- (!sip_cfg.matchexterniplocally || !ast_apply_ha(localaddr, &us_sin)) ) {
+ (!sip_cfg.matchexterniplocally || !ast_apply_ha(localaddr, us)) ) {
/* if we used externhost or stun, see if it is time to refresh the info */
if (externexpire && time(NULL) >= externexpire) {
if (stunaddr.sin_addr.s_addr) {
@@ -12643,7 +12640,6 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
int transport_type;
const char *useragent;
struct ast_sockaddr oldsin, testsa;
- struct sockaddr_in testsin;
ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
@@ -12763,16 +12759,13 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st
}
/* Check that they're allowed to register at this IP */
- if (!ast_sockaddr_is_ipv6(&peer->addr)) {
- ast_sockaddr_to_sin(&peer->addr, &testsin);
- if (ast_apply_ha(sip_cfg.contact_ha, &testsin) != AST_SENSE_ALLOW ||
- ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) {
- ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", domain,
- ast_sockaddr_stringify_addr(&testsa));
- ast_string_field_set(peer, fullcontact, "");
- ast_string_field_set(pvt, our_contact, "");
- return PARSE_REGISTER_DENIED;
- }
+ if (ast_apply_ha(sip_cfg.contact_ha, &peer->addr) != AST_SENSE_ALLOW ||
+ ast_apply_ha(peer->contactha, &peer->addr) != AST_SENSE_ALLOW) {
+ ast_log(LOG_WARNING, "Domain '%s' disallowed by contact ACL (violating IP %s)\n", domain,
+ ast_sockaddr_stringify_addr(&testsa));
+ ast_string_field_set(peer, fullcontact, "");
+ ast_string_field_set(pvt, our_contact, "");
+ return PARSE_REGISTER_DENIED;
}
/* if the Contact header information copied into peer->addr matches the
@@ -13418,19 +13411,14 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
}
peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
- if (!ast_sockaddr_is_ipv6(addr)) {
- struct sockaddr_in sin_tmp;
-
- ast_sockaddr_to_sin(addr, &sin_tmp);
- if (!(peer && ast_apply_ha(peer->ha, &sin_tmp))) {
- /* Peer fails ACL check */
- if (peer) {
- unref_peer(peer, "register_verify: unref_peer: from find_peer operation");
- peer = NULL;
- res = AUTH_ACL_FAILED;
- } else {
- res = AUTH_NOT_FOUND;
- }
+ if (!(peer && ast_apply_ha(peer->ha, addr))) {
+ /* Peer fails ACL check */
+ if (peer) {
+ unref_peer(peer, "register_verify: unref_peer: from find_peer operation");
+ peer = NULL;
+ res = AUTH_ACL_FAILED;
+ } else {
+ res = AUTH_NOT_FOUND;
}
}
@@ -14533,15 +14521,11 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
}
return AUTH_DONT_KNOW;
}
- if (!ast_sockaddr_is_ipv6(addr)) {
- struct sockaddr_in sin_tmp;
- ast_sockaddr_to_sin(addr, &sin_tmp);
- if (!ast_apply_ha(peer->ha, &sin_tmp)) {
- ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
- unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");
- return AUTH_ACL_FAILED;
- }
+ if (!ast_apply_ha(peer->ha, addr)) {
+ ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
+ unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");
+ return AUTH_ACL_FAILED;
}
if (debug)
ast_verbose("Found peer '%s' for '%s' from %s\n",
@@ -16618,12 +16602,11 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
{
struct ast_ha *d;
const char *prefix = "Localnet:";
- char buf[INET_ADDRSTRLEN]; /* need to print two addresses */
for (d = localaddr; d ; prefix = "", d = d->next) {
ast_cli(a->fd, " %-24s%s/%s\n",
- prefix, ast_inet_ntoa(d->netaddr),
- inet_ntop(AF_INET, &d->netmask, buf, sizeof(buf)) );
+ prefix, ast_strdupa(ast_sockaddr_stringify_addr(&d->addr)),
+ ast_strdupa(ast_sockaddr_stringify_addr(&d->netmask)));
}
}
ast_cli(a->fd, " STUN server: %s:%d\n", ast_inet_ntoa(stunaddr.sin_addr), ntohs(stunaddr.sin_port));
@@ -27195,20 +27178,12 @@ static int reload_config(enum channelreloadreason reason)
static int apply_directmedia_ha(struct sip_pvt *p, const char *op)
{
struct ast_sockaddr us = { { 0, }, }, them = { { 0, }, };
- struct sockaddr_in them_sin;
int res = AST_SENSE_ALLOW;
ast_rtp_instance_get_remote_address(p->rtp, &them);
ast_rtp_instance_get_local_address(p->rtp, &us);
- /* Currently ast_apply_ha doesn't support IPv6 */
- if (ast_sockaddr_is_ipv6(&them)) {
- return res;
- }
-
- ast_sockaddr_to_sin(&them, &them_sin);
-
- if ((res = ast_apply_ha(p->directmediaha, &them_sin)) == AST_SENSE_DENY) {
+ if ((res = ast_apply_ha(p->directmediaha, &them)) == AST_SENSE_DENY) {
ast_debug(3, "Reinvite %s to %s denied by directmedia ACL on %s\n",
op, ast_strdupa(ast_sockaddr_stringify(&them)), ast_strdupa(ast_sockaddr_stringify(&us)));
}
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 31f70ec46..6d4968a7b 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -1877,8 +1877,10 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s)
AST_LIST_LOCK(&devices);
AST_LIST_TRAVERSE(&devices, d, list){
+ struct ast_sockaddr addr;
+ ast_sockaddr_from_sin(&addr, &s->sin);
if (!strcasecmp(req->data.reg.name, d->id)
- && ast_apply_ha(d->ha, &(s->sin))) {
+ && ast_apply_ha(d->ha, &addr)) {
s->device = d;
d->type = letohl(req->data.reg.type);
if (ast_strlen_zero(d->version_id)) {