]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2086] Added subnet id range check
authorFrancis Dupont <fdupont@isc.org>
Mon, 13 Jun 2022 15:56:35 +0000 (17:56 +0200)
committerRazvan Becheriu <razvan@isc.org>
Thu, 23 Jun 2022 19:19:44 +0000 (22:19 +0300)
src/lib/dhcpsrv/parsers/dhcp_parsers.cc
src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc

index dfc4c5ea6efef804c7d414a74ccfd4c83a600d21..129c90350921f455b9282409da087f060de5cad9 100644 (file)
@@ -725,7 +725,9 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
     // Subnet ID is optional. If it is not supplied the value of 0 is used,
     // which means autogenerate. The value was inserted earlier by calling
     // SimpleParser4::setAllDefaults.
-    SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id"));
+    int64_t subnet_id_max = static_cast<int64_t>(SUBNET_ID_MAX);
+    SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id", 0,
+                                                          subnet_id_max));
 
     Subnet4Ptr subnet4(new Subnet4(addr, len, Triplet<uint32_t>(),
                                    Triplet<uint32_t>(), Triplet<uint32_t>(),
@@ -1238,7 +1240,9 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
     // Subnet ID is optional. If it is not supplied the value of 0 is used,
     // which means autogenerate. The value was inserted earlier by calling
     // SimpleParser6::setAllDefaults.
-    SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id"));
+    int64_t subnet_id_max = static_cast<int64_t>(SUBNET_ID_MAX);
+    SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id", 0,
+                                                          subnet_id_max));
 
     // We want to log whether rapid-commit is enabled, so we get this
     // before the actual subnet creation.
index 41a3ca29474ba3fb73874f385f46fa78c194826f..72603862b8b425fcf62b33eae22621785a702621 100644 (file)
@@ -3069,8 +3069,108 @@ TEST_F(ParseConfigTest, defaultSharedNetwork6) {
     EXPECT_FALSE(network->getDdnsUseConflictResolution().get());
 }
 
+// This test verifies a negative value for the subnet ID is rejected (v4).
+TEST_F(ParseConfigTest, negativeSubnetId4) {
+    std::string config =
+        "{"
+        "    \"subnet4\": [ {"
+        "        \"subnet\": \"192.0.2.0/24\","
+        "        \"id\": -1"
+        "    } ]"
+        "}";
+
+    ElementPtr json = Element::fromJSON(config);
+    EXPECT_TRUE(json);
+    ConstElementPtr status = parseElementSet(json, false);
+    int rcode = 0;
+    ConstElementPtr comment = parseAnswer(rcode, status);
+    ASSERT_TRUE(comment);
+    ASSERT_EQ(comment->getType(), Element::string);
+    EXPECT_EQ(1, rcode);
+    std::string expected = "Configuration parsing failed: ";
+    expected += "subnet configuration failed: ";
+    expected += "The 'id' value (-1) is not within expected range: ";
+    expected += "(0 - 4294967294)";
+    EXPECT_EQ(expected, comment->stringValue());
+}
+
+// This test verifies a negative value for the subnet ID is rejected (v6).
+TEST_F(ParseConfigTest, negativeSubnetId6) {
+    std::string config =
+        "{"
+        "    \"subnet6\": [ {"
+        "        \"subnet\": \"2001:db8:1::/64\","
+        "        \"id\": -1"
+        "    } ]"
+        "}";
+
+    ElementPtr json = Element::fromJSON(config);
+    EXPECT_TRUE(json);
+    ConstElementPtr status = parseElementSet(json, true);
+    int rcode = 0;
+    ConstElementPtr comment = parseAnswer(rcode, status);
+    ASSERT_TRUE(comment);
+    ASSERT_EQ(comment->getType(), Element::string);
+    EXPECT_EQ(1, rcode);
+    std::string expected = "Configuration parsing failed: ";
+    expected += "subnet configuration failed: ";
+    expected += "The 'id' value (-1) is not within expected range: ";
+    expected += "(0 - 4294967294)";
+    EXPECT_EQ(expected, comment->stringValue());
+}
+
+// This test verifies a too high value for the subnet ID is rejected (v4).
+TEST_F(ParseConfigTest, reservedSubnetId4) {
+    std::string config =
+        "{"
+        "    \"subnet4\": [ {"
+        "        \"subnet\": \"192.0.2.0/24\","
+        "        \"id\": 4294967295"
+        "    } ]"
+        "}";
+
+    ElementPtr json = Element::fromJSON(config);
+    EXPECT_TRUE(json);
+    ConstElementPtr status = parseElementSet(json, false);
+    int rcode = 0;
+    ConstElementPtr comment = parseAnswer(rcode, status);
+    ASSERT_TRUE(comment);
+    ASSERT_EQ(comment->getType(), Element::string);
+    EXPECT_EQ(1, rcode);
+    std::string expected = "Configuration parsing failed: ";
+    expected += "subnet configuration failed: ";
+    expected += "The 'id' value (4294967295) is not within expected range: ";
+    expected += "(0 - 4294967294)";
+    EXPECT_EQ(expected, comment->stringValue());
+}
+
+// This test verifies a too high value for the subnet ID is rejected (v6).
+TEST_F(ParseConfigTest, reservedSubnetId6) {
+    std::string config =
+        "{"
+        "    \"subnet6\": [ {"
+        "        \"subnet\": \"2001:db8:1::/64\","
+        "        \"id\": 4294967295"
+        "    } ]"
+        "}";
+
+    ElementPtr json = Element::fromJSON(config);
+    EXPECT_TRUE(json);
+    ConstElementPtr status = parseElementSet(json, true);
+    int rcode = 0;
+    ConstElementPtr comment = parseAnswer(rcode, status);
+    ASSERT_TRUE(comment);
+    ASSERT_EQ(comment->getType(), Element::string);
+    EXPECT_EQ(1, rcode);
+    std::string expected = "Configuration parsing failed: ";
+    expected += "subnet configuration failed: ";
+    expected += "The 'id' value (4294967295) is not within expected range: ";
+    expected += "(0 - 4294967294)";
+    EXPECT_EQ(expected, comment->stringValue());
+}
+
 // There's no test for ControlSocketParser, as it is tested in the DHCPv4 code
 // (see CtrlDhcpv4SrvTest.commandSocketBasic in
 // src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc).
 
-};  // Anonymous namespace
+}  // Anonymous namespace