]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Reject trailing whitespaces in IP address
authorHironori Shiina <shiina.hironori@jp.fujitsu.com>
Wed, 26 Nov 2014 04:41:06 +0000 (13:41 +0900)
committerHironori Shiina <shiina.hironori@jp.fujitsu.com>
Wed, 26 Nov 2014 06:48:03 +0000 (15:48 +0900)
Trailing whitespaces in IP address or CIDR pass API validation. These
whitespaces sometimes cause serious troubles. For instance, a trailing
CR code in allocation pools cause an ovs-agent to crash when calling
iptables. In this case, a tenant user's operation mistake affects whole
system.

By modifying _validate_no_whitespace() to reject data with whitespaces
in the beginning and the end, the IP address and CIDR validation
detects invalid attributes. The MAC address validation already rejects
these whitespaces.

Change-Id: Id4589236cfd44c2fd5956c5ab4ab6871381a0c34
Closes-Bug: #1393329

neutron/api/v2/attributes.py
neutron/tests/unit/test_attributes.py

index 1edcb7d0b557928d3d38187b9757b018f472f171..0301aac03d4764796aa5b519c1276ad7d62b4a71 100644 (file)
@@ -143,7 +143,7 @@ def _validate_range(data, valid_values=None):
 
 def _validate_no_whitespace(data):
     """Validates that input has no whitespace."""
-    if len(data.split()) > 1:
+    if re.search('\s', data):
         msg = _("'%s' contains whitespace") % data
         LOG.debug(msg)
         raise n_exc.InvalidInput(error_message=msg)
index 510aac039883838c49d0601dc7917240f4c934aa..c94179dc3af3e061fc85ae7c2826ac95b2b928b8 100644 (file)
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import string
 import testtools
 
 from neutron.api.v2 import attributes
@@ -121,6 +122,14 @@ class TestAttributes(base.BaseTestCase):
                           attributes._validate_no_whitespace,
                           'i\thave\twhitespace')
 
+        for ws in string.whitespace:
+            self.assertRaises(n_exc.InvalidInput,
+                              attributes._validate_no_whitespace,
+                              '%swhitespace-at-head' % ws)
+            self.assertRaises(n_exc.InvalidInput,
+                              attributes._validate_no_whitespace,
+                              'whitespace-at-tail%s' % ws)
+
     def test_validate_range(self):
         msg = attributes._validate_range(1, [1, 9])
         self.assertIsNone(msg)
@@ -188,6 +197,10 @@ class TestAttributes(base.BaseTestCase):
         else:
             self.assertEqual(msg, err_msg % mac_addr)
 
+        mac_addr = "ff:16:3e:4f:00:00\r"
+        msg = validator(mac_addr)
+        self.assertEqual(msg, err_msg % mac_addr)
+
     def test_validate_mac_address(self):
         self._test_validate_mac_address(attributes._validate_mac_address)
 
@@ -216,6 +229,16 @@ class TestAttributes(base.BaseTestCase):
         msg = attributes._validate_ip_address(ip_addr)
         self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
 
+        for ws in string.whitespace:
+            ip_addr = '%s111.1.1.1' % ws
+            msg = attributes._validate_ip_address(ip_addr)
+            self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
+
+        for ws in string.whitespace:
+            ip_addr = '111.1.1.1%s' % ws
+            msg = attributes._validate_ip_address(ip_addr)
+            self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
+
     def test_validate_ip_pools(self):
         pools = [[{'end': '10.0.0.254'}],
                  [{'start': '10.0.0.254'}],
@@ -238,6 +261,13 @@ class TestAttributes(base.BaseTestCase):
             msg = attributes._validate_ip_pools(pool)
             self.assertIsNone(msg)
 
+        invalid_ip = '10.0.0.2\r'
+        pools = [[{'end': '10.0.0.254', 'start': invalid_ip}]]
+        for pool in pools:
+            msg = attributes._validate_ip_pools(pool)
+            self.assertEqual(msg,
+                             "'%s' is not a valid IP address" % invalid_ip)
+
     def test_validate_fixed_ips(self):
         fixed_ips = [
             {'data': [{'subnet_id': '00000000-ffff-ffff-ffff-000000000000',
@@ -499,6 +529,12 @@ class TestAttributes(base.BaseTestCase):
             error = "'%s' is not a valid IP subnet" % cidr
             self.assertEqual(msg, error)
 
+        # Invalid - IPv4 with trailing CR
+        cidr = "10.0.2.0/24\r"
+        msg = validator(cidr, None)
+        error = "'%s' is not a valid IP subnet" % cidr
+        self.assertEqual(msg, error)
+
     def test_validate_subnet(self):
         self._test_validate_subnet(attributes._validate_subnet)