diff options
author | Tilghman Lesher <tilghman@meg.abyt.es> | 2007-12-18 18:39:25 +0000 |
---|---|---|
committer | Tilghman Lesher <tilghman@meg.abyt.es> | 2007-12-18 18:39:25 +0000 |
commit | df9dbc3951e8d6486d5fb11d3fb91424747e234b (patch) | |
tree | f294cc38eccb668a6c8dd6835f4a4ef465b7b6a5 /channels/chan_iax2.c | |
parent | c5b878622a4798c74931699e9156d278cd434937 (diff) |
Merged revisions 93668 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
................
r93668 | tilghman | 2007-12-18 12:29:39 -0600 (Tue, 18 Dec 2007) | 10 lines
Merged revisions 93667 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.2
........
r93667 | tilghman | 2007-12-18 12:23:06 -0600 (Tue, 18 Dec 2007) | 2 lines
Fixing AST-2007-027 (Closes issue #11119)
........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@93672 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_iax2.c')
-rw-r--r-- | channels/chan_iax2.c | 71 |
1 files changed, 64 insertions, 7 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 1d1ba7f78..7f0bf1a55 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -2942,15 +2942,17 @@ static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newcha */ static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin) { - struct ast_variable *var; + struct ast_variable *var = NULL; struct ast_variable *tmp; struct iax2_peer *peer=NULL; time_t regseconds = 0, nowtime; int dynamic=0; - if (peername) - var = ast_load_realtime("iaxpeers", "name", peername, NULL); - else { + if (peername) { + var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); + if (!var && sin) + var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr)); + } else if (sin) { char porta[25]; sprintf(porta, "%d", ntohs(sin->sin_port)); var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); @@ -2962,6 +2964,29 @@ static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in } } } + if (!var) { /* Last ditch effort */ + var = ast_load_realtime("iaxpeers", "name", peername, NULL); + /*!\note + * If this one loaded something, then we need to ensure that the host + * field matched. The only reason why we can't have this as a criteria + * is because we only have the IP address and the host field might be + * set as a name (and the reverse PTR might not match). + */ + if (var) { + for (tmp = var; tmp; tmp = tmp->next) { + if (!strcasecmp(tmp->name, "host")) { + struct in_addr sin2 = { 0, }; + struct ast_dnsmgr_entry *dnsmgr = NULL; + if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) { + /* No match */ + ast_variables_destroy(var); + var = NULL; + } + break; + } + } + } + } if (!var) return NULL; @@ -3035,13 +3060,45 @@ static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in return peer; } -static struct iax2_user *realtime_user(const char *username) +static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin) { struct ast_variable *var; struct ast_variable *tmp; struct iax2_user *user=NULL; - var = ast_load_realtime("iaxusers", "name", username, NULL); + var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); + if (!var) + var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr)); + if (!var && sin) { + char porta[6]; + snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); + var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); + if (!var) + var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); + } + if (!var) { /* Last ditch effort */ + var = ast_load_realtime("iaxusers", "name", username, NULL); + /*!\note + * If this one loaded something, then we need to ensure that the host + * field matched. The only reason why we can't have this as a criteria + * is because we only have the IP address and the host field might be + * set as a name (and the reverse PTR might not match). + */ + if (var) { + for (tmp = var; tmp; tmp = tmp->next) { + if (!strcasecmp(tmp->name, "host")) { + struct in_addr sin2 = { 0, }; + struct ast_dnsmgr_entry *dnsmgr = NULL; + if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) { + /* No match */ + ast_variables_destroy(var); + var = NULL; + } + break; + } + } + } + } if (!var) return NULL; @@ -5537,7 +5594,7 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies } user = best; if (!user && !ast_strlen_zero(iaxs[callno]->username)) { - user = realtime_user(iaxs[callno]->username); + user = realtime_user(iaxs[callno]->username, sin); if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ user = user_unref(user); |