Parcourir la source

[1298] check notify source address

against the master address in the config. error if they don't match, start transfer if they do
Jelte Jansen il y a 13 ans
Parent
commit
681e0e8b37

+ 19 - 2
src/bin/xfrin/tests/xfrin_test.py

@@ -1891,7 +1891,7 @@ class TestXfrin(unittest.TestCase):
         self.assertEqual(self.xfr.command_handler("notify",
                                                   self.args)['result'][0], 1)
 
-    def test_command_handler_notify_known_zone(self):
+    def test_command_handler_notify_known_zone_bad_addr(self):
         # try it with a known zone
         self.args['master'] = TEST_MASTER_IPV6_ADDRESS
 
@@ -1903,6 +1903,23 @@ class TestXfrin(unittest.TestCase):
                   }
                 ]}
         self.xfr.config_handler(zones)
+        # the command should now fail
+        self.assertEqual(self.xfr.command_handler("notify",
+                                                  self.args)['result'][0], 1)
+
+    def test_command_handler_notify_known_zone(self):
+        # try it with a known zone
+        self.args['master'] = TEST_MASTER_IPV6_ADDRESS
+
+        # but use a different address in the actual command
+        zones = { 'zones': [
+                  { 'name': TEST_ZONE_NAME_STR,
+                    'master_addr': TEST_MASTER_IPV6_ADDRESS,
+                    'master_port': TEST_MASTER_PORT
+                  }
+                ]}
+        self.xfr.config_handler(zones)
+        # the command should now fail
         self.assertEqual(self.xfr.command_handler("notify",
                                                   self.args)['result'][0], 0)
 
@@ -1911,7 +1928,7 @@ class TestXfrin(unittest.TestCase):
         # This is actually NOT the address given in the command, which
         # would at this point not make sense, see the TODO in
         # xfrin.py.in Xfrin.command_handler())
-        self.assertEqual(TEST_MASTER_IPV4_ADDRESS,
+        self.assertEqual(TEST_MASTER_IPV6_ADDRESS,
                          self.xfr.xfrin_started_master_addr)
         self.assertEqual(int(TEST_MASTER_PORT),
                          self.xfr.xfrin_started_master_port)

+ 18 - 7
src/bin/xfrin/xfrin.py.in

@@ -1061,6 +1061,8 @@ class Xfrin:
                 # we should check if it matches one of them, and then use it.)
                 (zone_name, rrclass) = self._parse_zone_name_and_class(args)
                 zone_info = self._get_zone_info(zone_name, rrclass)
+                notify_addr = self._parse_master_and_port(args, zone_name,
+                                                          rrclass)
                 if zone_info is None:
                     # TODO what to do? no info known about zone. defaults?
                     errmsg = "Got notification to retransfer unknown zone " + zone_name.to_text()
@@ -1068,13 +1070,22 @@ class Xfrin:
                     answer = create_answer(1, errmsg)
                 else:
                     master_addr = zone_info.get_master_addr_info()
-                    ret = self.xfrin_start(zone_name,
-                                           rrclass,
-                                           self._get_db_file(),
-                                           master_addr,
-                                           zone_info.tsig_key, RRType.AXFR(),
-                                           True)
-                    answer = create_answer(ret[0], ret[1])
+                    request_type = RRType.AXFR()
+                    if notify_addr == master_addr:
+                        ret = self.xfrin_start(zone_name,
+                                               rrclass,
+                                               self._get_db_file(),
+                                               master_addr,
+                                               zone_info.tsig_key, request_type,
+                                               True)
+                        answer = create_answer(ret[0], ret[1])
+                    else:
+                        errmsg = "Got notification for " + zone_name.to_text()\
+                               + "from unknown address: " + notify_addr[2][0];
+                        logger.error(XFRIN_NOTIFY_UNKNOWN_MASTER,
+                                     zone_name.to_text(), notify_addr[2][0],
+                                     master_addr[2][0])
+                        answer = create_answer(1, errmsg)
 
             elif command == 'retransfer' or command == 'refresh':
                 # Xfrin receives the retransfer/refresh from cmdctl(sent by bindctl).

+ 6 - 0
src/bin/xfrin/xfrin_messages.mes

@@ -70,6 +70,12 @@ was killed.
 There was a problem sending a message to the zone manager. This most
 likely means that the msgq daemon has quit or was killed.
 
+% XFRIN_NOTIFY_UNKNOWN_MASTER got notification to retransfer zone %1 from %2, expected %3
+The system received a notify for the given zone, but the address it came
+from does not match the master address in the Xfrin configuration. The notify
+is ignored. This may indicate that the configuration for the master is wrong,
+that a wrong machine is sending notifies, or that fake notifies are being sent.
+
 % XFRIN_IMPORT_DNS error importing python DNS module: %1
 There was an error importing the python DNS module pydnspp. The most
 likely cause is a PYTHONPATH problem.