Merged revisions 93668 via svnmerge from
authorTilghman Lesher <tilghman@meg.abyt.es>
Tue, 18 Dec 2007 18:39:25 +0000 (18:39 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Tue, 18 Dec 2007 18:39:25 +0000 (18:39 +0000)
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

channels/chan_iax2.c
channels/chan_sip.c

index 1d1ba7f..7f0bf1a 100644 (file)
@@ -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);
index d6fa8f9..8a6484a 100644 (file)
@@ -3088,9 +3088,36 @@ static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_i
 
        /* First check on peer name */
        if (newpeername) {
-               var = ast_load_realtime("sippeers", "name", newpeername, NULL);
                if (realtimeregs)
                        varregs = ast_load_realtime("sipregs", "name", newpeername, NULL);
+
+               var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL);
+               if (!var && sin) {
+                       var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
+                       if (!var) {
+                               var = ast_load_realtime("sippeers", "name", newpeername, 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(var->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;
+                                               }
+                                       }
+                               }
+                       }
+               }
        } else if (sin) {       /* Then check on IP address for dynamic peers */
                ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
                portnum = ntohs(sin->sin_port);