]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
sync with 1.2
authorRussell Bryant <russell@russellbryant.com>
Tue, 18 Dec 2007 18:34:29 +0000 (18:34 +0000)
committerRussell Bryant <russell@russellbryant.com>
Tue, 18 Dec 2007 18:34:29 +0000 (18:34 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2-netsec@93669 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c
channels/chan_sip.c

index 9492d5c2fb90965a46d357956bfbffb0756f63d2..6eae6823c803403260fc4bc91cff26991fe7f539 100644 (file)
@@ -2625,11 +2625,13 @@ static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in
        struct iax2_peer *peer=NULL;
        time_t regseconds, nowtime;
        int dynamic=0;
+       char iabuf[INET_ADDRSTRLEN];
 
-       if (peername)
-               var = ast_load_realtime("iaxpeers", "name", peername, NULL);
-       else {
-               char iabuf[INET_ADDRSTRLEN];
+       if (peername) {
+               var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
+               if (!var)
+                       var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
+       } else {
                char porta[25];
                ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
                sprintf(porta, "%d", ntohs(sin->sin_port));
@@ -2644,6 +2646,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;
 
@@ -2720,13 +2745,46 @@ 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;
+       char iabuf[INET_ADDRSTRLEN];
 
-       var = ast_load_realtime("iaxusers", "name", username, NULL);
+       var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
+       if (!var && sin)
+               var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(iabuf, sizeof(iabuf), 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(iabuf, sizeof(iabuf), sin->sin_addr), "port", porta, NULL);
+               if (!var)
+                       var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(iabuf, sizeof(iabuf), 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;
 
@@ -4878,7 +4936,7 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
        ast_mutex_unlock(&userl.lock);
        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 */
                        destroy_user(user);
index d942f15afbfa648cc4f65102644ba7d85c36e829..0a05ab02cc82ecb0834ecb28bbfc989cadc2d956 100644 (file)
@@ -81,6 +81,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/dnsmgr.h"
 #include "asterisk/devicestate.h"
 #include "asterisk/linkedlists.h"
+#include "asterisk/dnsmgr.h"
 
 #ifdef OSP_SUPPORT
 #include "asterisk/astosp.h"
@@ -1725,9 +1726,35 @@ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *
        char iabuf[80];
 
        /* First check on peer name */
-       if (newpeername) 
-               var = ast_load_realtime("sippeers", "name", peername, NULL);
-       else if (sin) { /* Then check on IP address */
+       if (newpeername) {
+               var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL);
+               if (!var && sin) {
+                       var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(iabuf, sizeof(iabuf), 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 */
                ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
                var = ast_load_realtime("sippeers", "host", iabuf, NULL);       /* First check for fixed IP hosts */
                if (!var)