Browse Source

[2313] Validate option space name.

Marcin Siodelski 12 years ago
parent
commit
85da7d68f1

+ 19 - 1
src/lib/dhcpsrv/option_space.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -13,12 +13,30 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <dhcpsrv/option_space.h>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/predicate.hpp>
 
 namespace isc {
 namespace dhcp {
 
 OptionSpace::OptionSpace(const std::string& name, const bool vendor_space)
     : name_(name), vendor_space_(vendor_space) {
+    if (!validateName(name_)) {
+        isc_throw(InvalidOptionSpace, "Invalid option space name "
+                  << name_);
+    }
+}
+
+bool
+OptionSpace::validateName(const std::string& name) {
+    if (boost::algorithm::all(name, boost::is_from_range('a', 'z') ||
+                              boost::is_from_range('A', 'Z') ||
+                              boost::is_digit() ||
+                              boost::is_any_of("-_")) &&
+        !name.empty()) {
+        return (true);
+    }
+    return (false);
 }
 
 } // end of isc::dhcp namespace

+ 18 - 1
src/lib/dhcpsrv/option_space.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -69,6 +69,23 @@ public:
     /// the vendor space.
     bool isVendorSpace() const { return (vendor_space_); }
 
+    /// @brief Mark option space as vendor space or non-vendor space.
+    ///
+    /// @param a boolean value indicating that this option space is
+    /// a vendor space (true) or non-vendor space (false).
+    void setVendorSpace(const bool vendor_space) {
+        vendor_space_ = vendor_space;
+    }
+
+    /// @brief Checks that the provided option space name is valid.
+    ///
+    /// It is expected that option space name consists of upper or
+    /// lower case letters or digits. All other characters are
+    /// prohibited.
+    ///
+    /// @param name option space name to be validated.
+    static bool validateName(const std::string& name);
+
 private:
     std::string name_;  ///< Holds option space name.
 

+ 52 - 1
src/lib/dhcpsrv/tests/option_space_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -36,6 +36,57 @@ TEST(OptionSpaceTest, constructor) {
     OptionSpace space2("abc", false);
     EXPECT_EQ("abc", space2.getName());
     EXPECT_FALSE(space2.isVendorSpace());
+
+    // Verify that constructor throws exception if invalid
+    // option space name is provided.
+    EXPECT_THROW(OptionSpace("invalid%space.name"), InvalidOptionSpace);
+}
+
+// The purpose of this test is to verify that the vendor-space flag
+// can be overriden.
+TEST(OptionSpaceTest, setVendorSpace) {
+    OptionSpace space("isc", true);
+    EXPECT_EQ("isc", space.getName());
+    EXPECT_TRUE(space.isVendorSpace());
+
+    // Override the vendor space flag.
+    space.setVendorSpace(false);
+    EXPECT_FALSE(space.isVendorSpace());
+}
+
+// The purpose of this test is to verify that the static function
+// to validate the option space name works correctly.
+TEST(OptionSpaceTest, validateName) {
+    // Positive test scenarios: letters, digits, dashes, underscores
+    // lower/upper case allowed.
+    EXPECT_TRUE(OptionSpace::validateName("abc"));
+    EXPECT_TRUE(OptionSpace::validateName("dash-allowed"));
+    EXPECT_TRUE(OptionSpace::validateName("two-dashes-allowed"));
+    EXPECT_TRUE(OptionSpace::validateName("underscore_allowed"));
+    EXPECT_TRUE(OptionSpace::validateName("underscore_three_times_allowed"));
+    EXPECT_TRUE(OptionSpace::validateName("digits0912"));
+    EXPECT_TRUE(OptionSpace::validateName("1234"));
+    EXPECT_TRUE(OptionSpace::validateName("UPPER_CASE_allowed"));
+
+    // Negative test scenarions: empty strings, dots, spaces are not
+    // allowed
+    EXPECT_FALSE(OptionSpace::validateName(""));
+    EXPECT_FALSE(OptionSpace::validateName(" "));
+    EXPECT_FALSE(OptionSpace::validateName(" isc "));
+    EXPECT_FALSE(OptionSpace::validateName("isc "));
+    EXPECT_FALSE(OptionSpace::validateName(" isc"));
+    EXPECT_FALSE(OptionSpace::validateName("isc with-space"));
+
+    // Test other special characters
+    const char specials[] = { '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
+                              '+', '=', '[', ']', '{', '}', ';', ':', '"', '\'',
+                              '\\', '|', '<','>', ',', '.', '?', '~', '`' };
+    for (int i = 0; i < sizeof(specials); ++i) {
+        std::ostringstream stream;
+        stream << "abc" << specials[i];
+        EXPECT_FALSE(OptionSpace::validateName(stream.str()))
+            << "Test failed for special character '" << specials[i] << "'.";
+    }
 }
 
 }; // end of anonymous namespace