diff --git a/CMakeLists.txt b/CMakeLists.txt index 0911d0b..9015c83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -380,6 +380,7 @@ set_target_properties(${PROJECT_NAME} PROPERTIES RELWITHDEBINFO_POSTFIX -${PROJE ############################################################################### # Testing ############################################################################### +option(SECURITY "Whether to build security test-suite" OFF) enable_testing() include(CTest) diff --git a/include/DiscoveryServerManager.h b/include/DiscoveryServerManager.h index 468ae0b..660f99a 100644 --- a/include/DiscoveryServerManager.h +++ b/include/DiscoveryServerManager.h @@ -132,6 +132,9 @@ class DiscoveryServerManager // Snapshops container snapshots_list snapshots; + // Participant PropertiesPolicy + PropertySeq properties_; + volatile bool no_callbacks; // ongoing participant destruction bool auto_shutdown; // close when event processing is finished? bool enable_prefix_validation; // allow multiple servers share the same prefix? (only for testing purposes) @@ -170,6 +173,13 @@ class DiscoveryServerManager void saveSnapshots( const std::string& file) const; + /** + * @brief: This method loads a set of properties into attributes + * @param [in] props_n: element containig the XML properties + */ + bool loadProperties( + tinyxml2::XMLElement* props_n); + // File where to save snapshots std::string snapshots_output_file; // validation required @@ -186,6 +196,7 @@ class DiscoveryServerManager DiscoveryServerManager( const std::string& xml_file_path, + const std::string& props_file_path, const bool shared_memory_off); #if FASTRTPS_VERSION_MAJOR >= 2 && FASTRTPS_VERSION_MINOR >= 2 FASTDDS_DEPRECATED_UNTIL(3, "eprosima::discovery_server::DiscoveryServerManager(const std::set& xml_snapshot_files," diff --git a/resources/xsd/discovery-server.xsd b/resources/xsd/discovery-server.xsd index e60dee7..0d32208 100644 --- a/resources/xsd/discovery-server.xsd +++ b/resources/xsd/discovery-server.xsd @@ -225,7 +225,7 @@ - + diff --git a/src/DiscoveryServerManager.cpp b/src/DiscoveryServerManager.cpp index 5545463..8a6a855 100644 --- a/src/DiscoveryServerManager.cpp +++ b/src/DiscoveryServerManager.cpp @@ -49,6 +49,9 @@ const char* TYPES = "types"; const char* PUBLISHER = "publisher"; const char* SUBSCRIBER = "subscriber"; const char* TOPIC = "topic"; +const char* PROPERTIES = "properties"; +const char* PROPERTY = "property"; +const char* VALUE = "value"; } // namespace DSxmlparser } // namespace fastrtps } // namespace eprosima @@ -60,6 +63,7 @@ const std::chrono::seconds DiscoveryServerManager::last_snapshot_delay_ = std::c DiscoveryServerManager::DiscoveryServerManager( const std::string& xml_file_path, + const std::string& props_file_path, const bool shared_memory_off) : no_callbacks(false) , auto_shutdown(true) @@ -101,6 +105,35 @@ DiscoveryServerManager::DiscoveryServerManager( // try load the enable_prefix_validation attribute enable_prefix_validation = root->BoolAttribute(s_sPrefixValidation.c_str(), enable_prefix_validation); + //try load properties + if (!props_file_path.empty()) + { + tinyxml2::XMLDocument props_doc; + + if (tinyxml2::XMLError::XML_SUCCESS == props_doc.LoadFile(props_file_path.c_str())) + { + tinyxml2::XMLElement* root = props_doc.FirstChildElement(eprosima::fastrtps::DSxmlparser::PROPERTIES); + if (root != nullptr) + { + if (!loadProperties(root)) + { + LOG_ERROR("Error loading PropertiesPolicy from properties file"); + return; + } + } + else + { + LOG_ERROR("Error retrieving properties element from properties file"); + return; + } + } + else + { + LOG_ERROR("Could not load properties file"); + return; + } + } + for (auto child = doc.FirstChildElement(s_sDS.c_str()); child != nullptr; child = child->NextSiblingElement(s_sDS.c_str())) { @@ -713,6 +746,30 @@ void DiscoveryServerManager::loadProfiles( } } +bool DiscoveryServerManager::loadProperties(tinyxml2::XMLElement* props_n) +{ + bool ret = true; + tinyxml2::XMLElement* prop = props_n->FirstChildElement(eprosima::fastrtps::DSxmlparser::PROPERTY); + + for (;prop != nullptr; prop = prop->NextSiblingElement(eprosima::fastrtps::DSxmlparser::PROPERTY)) + { + tinyxml2::XMLElement* name = prop->FirstChildElement(eprosima::fastrtps::DSxmlparser::NAME); + tinyxml2::XMLElement* value = prop->FirstChildElement(eprosima::fastrtps::DSxmlparser::VALUE); + + if (nullptr != name && nullptr != value) + { + properties_.push_back({name->GetText(), value->GetText()}); + } + else + { + LOG_ERROR("Missing name/value for property"); + ret = false; + } + } + + return ret; +} + void DiscoveryServerManager::onTerminate() { { @@ -956,6 +1013,15 @@ void DiscoveryServerManager::loadServer( (void)b; assert(b.discoveryProtocol == SERVER || b.discoveryProtocol == BACKUP); + // Extend Participant properties if applies + if (!properties_.empty()) + { + for (auto& prop : properties_) + { + dpQOS.properties().properties().emplace_back(prop); + } + } + // Create the participant or the associated events DelayedParticipantCreation event(creation_time, std::move(dpQOS), &DiscoveryServerManager::addServer); if (creation_time == getTime()) @@ -1225,6 +1291,15 @@ void DiscoveryServerManager::loadClient( dpQOS.transport().user_transports.push_back(udp_transport); } + // Extend Participant properties if applies + if (!properties_.empty()) + { + for (auto& prop : properties_) + { + dpQOS.properties().properties().emplace_back(prop); + } + } + GUID_t guid(dpQOS.wire_protocol().prefix, c_EntityId_RTPSParticipant); DelayedParticipantDestruction* destruction_event = nullptr; DelayedParticipantCreation* creation_event = nullptr; @@ -1330,6 +1405,15 @@ void DiscoveryServerManager::loadSimple( dpQOS.name() = name; } + // Extend Participant properties if applies + if (!properties_.empty()) + { + for (auto& prop : properties_) + { + dpQOS.properties().properties().emplace_back(prop); + } + } + GUID_t guid(dpQOS.wire_protocol().prefix, c_EntityId_RTPSParticipant); DelayedParticipantDestruction* destruction_event = nullptr; DelayedParticipantCreation* creation_event = nullptr; diff --git a/src/arguments.h b/src/arguments.h index 7087570..2721814 100644 --- a/src/arguments.h +++ b/src/arguments.h @@ -23,6 +23,7 @@ enum optionIndex UNKNOWN, HELP, CONFIG_FILE, + PROPERTIES_FILE, OUTPUT_FILE, SHM }; @@ -46,6 +47,9 @@ const option::Descriptor usage[] = { { CONFIG_FILE, 0, "c", "config-file", Arg::check_inp, " -c \t--config-file Mandatory configuration file path\n"}, + { PROPERTIES_FILE, 0, "p", "props-file", Arg::check_inp, + " -p \t--props-file Optional participant properties configuration file path\n"}, + { OUTPUT_FILE, 0, "o", "output-file", Arg::check_inp, " -o \t--output-file File to write result snapshots. If not specified" " snapshots will be written in the file specified in the snapshot\n"}, diff --git a/src/main.cpp b/src/main.cpp index 8e42da1..ead8334 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -122,8 +122,24 @@ int main( // Load Default XML files eprosima::fastrtps::xmlparser::XMLProfileManager::loadDefaultXMLFile(); + // Load properties file path from arg + pOp = options[PROPERTIES_FILE]; + + std::string path_to_properties; + + if ( nullptr != pOp ) + { + if ( pOp->count() != 1) + { + cout << "Only one properties file can be specified." << endl; + return 1; + } + + path_to_properties = pOp->arg; + } + // Create DiscoveryServerManager - DiscoveryServerManager manager(path_to_config, options[SHM]); + DiscoveryServerManager manager(path_to_config, path_to_properties, options[SHM]); if (!manager.correctly_created()) { return_code = 1; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0fbdeb6..9ca0530 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -180,6 +180,31 @@ foreach(TEST IN LISTS TEST_LIST) set_property(TEST ${TEST_NAME} PROPERTY LABELS xfail) endif() + if(SECURITY) + unset(TEST_NAME) + set(TEST_NAME "discovery_server_test.${TEST}.SECURITY") + list(APPEND TEST_CASE_LIST ${TEST_NAME}) + # Test without shared memory + add_test(NAME ${TEST_NAME} + COMMAND ${PYTHON_EXECUTABLE} ${RUN_TEST} + -e $ + -p ${TESTS_PARAMS} + -f $<$:$> + -t ${TEST} + -s false + -i false + -S true + -C ${PROJECT_SOURCE_DIR}/test/certs) + + set_tests_properties(${TEST_NAME} PROPERTIES + REQUIRED_FILES ${RUN_TEST} + REQUIRED_FILES ${TESTS_PARAMS}) + + if("${TEST}" IN_LIST FAIL_TEST_CASES) + set_property(TEST ${TEST_NAME} PROPERTY LABELS xfail) + endif() + endif() + endforeach() # Windows requires an special treatment of environmental variables diff --git a/test/certs/governance_all_enable.smime b/test/certs/governance_all_enable.smime new file mode 100644 index 0000000..7b234a6 --- /dev/null +++ b/test/certs/governance_all_enable.smime @@ -0,0 +1,72 @@ +MIME-Version: 1.0 +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----205663DC800FC27263B797AC629F745C" + +This is an S/MIME signed message + +------205663DC800FC27263B797AC629F745C +Content-Type: text/plain + + + + + + + + 0 + 230 + + + false + true + ENCRYPT + ENCRYPT + ENCRYPT + + + * + true + true + true + true + ENCRYPT + ENCRYPT + + + + + + + +------205663DC800FC27263B797AC629F745C +Content-Type: application/x-pkcs7-signature; name="smime.p7s" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="smime.p7s" + +MIIEeQYJKoZIhvcNAQcCoIIEajCCBGYCAQExDzANBglghkgBZQMEAgEFADALBgkq +hkiG9w0BBwGgggJAMIICPDCCAeOgAwIBAgIJALZwpgo2sxthMAoGCCqGSM49BAMC +MIGaMQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2Fu +dG9zMREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNV +BAMMFWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNh +QGVwcm9zaW1hLmNvbTAeFw0xNzA5MDYwOTAzMDNaFw0yNzA5MDQwOTAzMDNaMIGa +MQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2FudG9z +MREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNVBAMM +FWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNhQGVw +cm9zaW1hLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGLlhB3WQ8l1fpUE +3DfOoulA/de38Zfj7hmpKtOnxiH2q6RJbwhxvJeA7R7mkmAKaJKmzx695BjyiXVS +7bE7vgejEDAOMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgVTY1BEvT +4pw3GyBMzaUqmp69wi0kBkyOgq04OhyJ13UCICR125vvt0fUhXsXaxOAx28E4Ac9 +SVxpI+3UYs2kV5n0MYIB/TCCAfkCAQEwgagwgZoxCzAJBgNVBAYTAkVTMQswCQYD +VQQIDAJNQTEUMBIGA1UEBwwLVHJlcyBDYW50b3MxETAPBgNVBAoMCGVQcm9zaW1h +MREwDwYDVQQLDAhlUHJvc2ltYTEeMBwGA1UEAwwVZVByb3NpbWEgTWFpbiBUZXN0 +IENBMSIwIAYJKoZIhvcNAQkBFhNtYWluY2FAZXByb3NpbWEuY29tAgkAtnCmCjaz +G2EwDQYJYIZIAWUDBAIBBQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc +BgkqhkiG9w0BCQUxDxcNMjMwMjIxMDk1MjM0WjAvBgkqhkiG9w0BCQQxIgQguOmE +ipH9WhFwZt05wsDRKD9aInelvQO2SQANMKbmGV8weQYJKoZIhvcNAQkPMWwwajAL +BglghkgBZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0D +BzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZI +hvcNAwICASgwCgYIKoZIzj0EAwIERzBFAiBZyyAcaQ7KB5qI/oF276mxSspzFkCI +HH1qbSPHKfjueQIhAIJQDdUCbimYKFGJYYYBZ/JBrdzMaB6Ordmomvkgjcx0 + +------205663DC800FC27263B797AC629F745C-- + diff --git a/test/certs/governance_all_enable.xml b/test/certs/governance_all_enable.xml new file mode 100644 index 0000000..b800591 --- /dev/null +++ b/test/certs/governance_all_enable.xml @@ -0,0 +1,31 @@ + + + + + + + 0 + 230 + + + false + true + ENCRYPT + ENCRYPT + ENCRYPT + + + * + true + true + true + true + ENCRYPT + ENCRYPT + + + + + + diff --git a/test/certs/maincacert.pem b/test/certs/maincacert.pem new file mode 100644 index 0000000..b6d2da2 --- /dev/null +++ b/test/certs/maincacert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICPDCCAeOgAwIBAgIJALZwpgo2sxthMAoGCCqGSM49BAMCMIGaMQswCQYDVQQG +EwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2FudG9zMREwDwYDVQQK +DAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNVBAMMFWVQcm9zaW1h +IE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNhQGVwcm9zaW1hLmNv +bTAeFw0xNzA5MDYwOTAzMDNaFw0yNzA5MDQwOTAzMDNaMIGaMQswCQYDVQQGEwJF +UzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2FudG9zMREwDwYDVQQKDAhl +UHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNVBAMMFWVQcm9zaW1hIE1h +aW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNhQGVwcm9zaW1hLmNvbTBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABGLlhB3WQ8l1fpUE3DfOoulA/de38Zfj +7hmpKtOnxiH2q6RJbwhxvJeA7R7mkmAKaJKmzx695BjyiXVS7bE7vgejEDAOMAwG +A1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgVTY1BEvT4pw3GyBMzaUqmp69 +wi0kBkyOgq04OhyJ13UCICR125vvt0fUhXsXaxOAx28E4Ac9SVxpI+3UYs2kV5n0 +-----END CERTIFICATE----- diff --git a/test/certs/maincakey.pem b/test/certs/maincakey.pem new file mode 100644 index 0000000..bd7d89f --- /dev/null +++ b/test/certs/maincakey.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgRaipe1KYZNzj+35E +N2jvtzjRsQ7n9Me/vm35UKGuVI6hRANCAARi5YQd1kPJdX6VBNw3zqLpQP3Xt/GX +4+4ZqSrTp8Yh9qukSW8IcbyXgO0e5pJgCmiSps8eveQY8ol1Uu2xO74H +-----END PRIVATE KEY----- diff --git a/test/certs/mainpubcert.pem b/test/certs/mainpubcert.pem new file mode 100644 index 0000000..ab99f06 --- /dev/null +++ b/test/certs/mainpubcert.pem @@ -0,0 +1,44 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + ae:7b:ad:8c:07:5a:ea:f3 + Signature Algorithm: ecdsa-with-SHA256 + Issuer: C=ES, ST=MA, L=Tres Cantos, O=eProsima, OU=eProsima, CN=eProsima Main Test CA/emailAddress=mainca@eprosima.com + Validity + Not Before: Sep 6 09:04:05 2017 GMT + Not After : Sep 4 09:04:05 2027 GMT + Subject: C=ES, ST=MA, O=eProsima, OU=eProsima, CN=Main Publisher/emailAddress=mainpub@eprosima.com + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:55:95:f0:0b:1f:56:3f:80:4e:97:7e:1b:69:9c: + 7b:54:53:22:c4:a3:96:e9:99:2c:3d:c7:a8:8c:ec: + 1c:fd:d1:35:e7:ba:7d:63:01:9b:42:82:00:73:2c: + 52:e2:e1:0b:db:53:d9:45:a0:f8:64:1c:be:c5:0d: + 51:18:14:9f:90 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Signature Algorithm: ecdsa-with-SHA256 + 30:45:02:21:00:9c:e7:46:44:78:0c:95:eb:a7:38:9a:a7:af: + 4b:6c:bd:84:3b:bb:85:09:25:3d:49:b1:79:9e:e2:7e:dc:99: + 42:02:20:60:78:bd:d0:1e:cd:bc:4b:e3:25:2f:dd:56:6d:c8: + 29:78:3d:df:72:bc:bd:90:de:c6:19:b0:48:44:31:c7:46 +-----BEGIN CERTIFICATE----- +MIICHTCCAcOgAwIBAgIJAK57rYwHWurzMAoGCCqGSM49BAMCMIGaMQswCQYDVQQG +EwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2FudG9zMREwDwYDVQQK +DAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNVBAMMFWVQcm9zaW1h +IE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNhQGVwcm9zaW1hLmNv +bTAeFw0xNzA5MDYwOTA0MDVaFw0yNzA5MDQwOTA0MDVaMH4xCzAJBgNVBAYTAkVT +MQswCQYDVQQIDAJNQTERMA8GA1UECgwIZVByb3NpbWExETAPBgNVBAsMCGVQcm9z +aW1hMRcwFQYDVQQDDA5NYWluIFB1Ymxpc2hlcjEjMCEGCSqGSIb3DQEJARYUbWFp +bnB1YkBlcHJvc2ltYS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARVlfAL +H1Y/gE6XfhtpnHtUUyLEo5bpmSw9x6iM7Bz90TXnun1jAZtCggBzLFLi4QvbU9lF +oPhkHL7FDVEYFJ+Qow0wCzAJBgNVHRMEAjAAMAoGCCqGSM49BAMCA0gAMEUCIQCc +50ZEeAyV66c4mqevS2y9hDu7hQklPUmxeZ7iftyZQgIgYHi90B7NvEvjJS/dVm3I +KXg933K8vZDexhmwSEQxx0Y= +-----END CERTIFICATE----- diff --git a/test/certs/mainpubkey.pem b/test/certs/mainpubkey.pem new file mode 100644 index 0000000..cfb610b --- /dev/null +++ b/test/certs/mainpubkey.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgY5T1nA3Wpo8/JegF +k9vz0eTeboO2NB5LqoIDCICa8YChRANCAARVlfALH1Y/gE6XfhtpnHtUUyLEo5bp +mSw9x6iM7Bz90TXnun1jAZtCggBzLFLi4QvbU9lFoPhkHL7FDVEYFJ+Q +-----END PRIVATE KEY----- diff --git a/test/certs/permissions.smime b/test/certs/permissions.smime new file mode 100644 index 0000000..8f943a3 --- /dev/null +++ b/test/certs/permissions.smime @@ -0,0 +1,72 @@ +MIME-Version: 1.0 +Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----F7C423515E88F48AE4A6D4674403FDFE" + +This is an S/MIME signed message + +------F7C423515E88F48AE4A6D4674403FDFE +Content-Type: text/plain + + + + + + emailAddress=mainpub@eprosima.com, CN=Main Publisher, OU=eProsima, O=eProsima, ST=MA, C=ES + + 2013-06-01T13:00:00 + 2038-06-01T13:00:00 + + + + + 0 + 230 + + + + + * + + + + + * + + + + DENY + + + + +------F7C423515E88F48AE4A6D4674403FDFE +Content-Type: application/x-pkcs7-signature; name="smime.p7s" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="smime.p7s" + +MIIEeQYJKoZIhvcNAQcCoIIEajCCBGYCAQExDzANBglghkgBZQMEAgEFADALBgkq +hkiG9w0BBwGgggJAMIICPDCCAeOgAwIBAgIJALZwpgo2sxthMAoGCCqGSM49BAMC +MIGaMQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2Fu +dG9zMREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNV +BAMMFWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNh +QGVwcm9zaW1hLmNvbTAeFw0xNzA5MDYwOTAzMDNaFw0yNzA5MDQwOTAzMDNaMIGa +MQswCQYDVQQGEwJFUzELMAkGA1UECAwCTUExFDASBgNVBAcMC1RyZXMgQ2FudG9z +MREwDwYDVQQKDAhlUHJvc2ltYTERMA8GA1UECwwIZVByb3NpbWExHjAcBgNVBAMM +FWVQcm9zaW1hIE1haW4gVGVzdCBDQTEiMCAGCSqGSIb3DQEJARYTbWFpbmNhQGVw +cm9zaW1hLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGLlhB3WQ8l1fpUE +3DfOoulA/de38Zfj7hmpKtOnxiH2q6RJbwhxvJeA7R7mkmAKaJKmzx695BjyiXVS +7bE7vgejEDAOMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgVTY1BEvT +4pw3GyBMzaUqmp69wi0kBkyOgq04OhyJ13UCICR125vvt0fUhXsXaxOAx28E4Ac9 +SVxpI+3UYs2kV5n0MYIB/TCCAfkCAQEwgagwgZoxCzAJBgNVBAYTAkVTMQswCQYD +VQQIDAJNQTEUMBIGA1UEBwwLVHJlcyBDYW50b3MxETAPBgNVBAoMCGVQcm9zaW1h +MREwDwYDVQQLDAhlUHJvc2ltYTEeMBwGA1UEAwwVZVByb3NpbWEgTWFpbiBUZXN0 +IENBMSIwIAYJKoZIhvcNAQkBFhNtYWluY2FAZXByb3NpbWEuY29tAgkAtnCmCjaz +G2EwDQYJYIZIAWUDBAIBBQCggeQwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc +BgkqhkiG9w0BCQUxDxcNMjMwMjE2MTQwMjU5WjAvBgkqhkiG9w0BCQQxIgQgTNU9 +XvIPHn/lsXX4n0MFp6YijDkDkx7/yP8x/7IKOgMweQYJKoZIhvcNAQkPMWwwajAL +BglghkgBZQMEASowCwYJYIZIAWUDBAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0D +BzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZI +hvcNAwICASgwCgYIKoZIzj0EAwIERzBFAiALAu7jtqdmKZtGyfo0LSDccaZtpffa +bCqItPVlT2+9kAIhALxRDkvkB4uPOZbOdViYew0sFOoUr+wwHOKpEM8J4HkR + +------F7C423515E88F48AE4A6D4674403FDFE-- + diff --git a/test/certs/permissions.xml b/test/certs/permissions.xml new file mode 100644 index 0000000..2e99421 --- /dev/null +++ b/test/certs/permissions.xml @@ -0,0 +1,31 @@ + + + + + emailAddress=mainpub@eprosima.com, CN=Main Publisher, OU=eProsima, O=eProsima, ST=MA, C=ES + + 2013-06-01T13:00:00 + 2038-06-01T13:00:00 + + + + + 0 + 230 + + + + + * + + + + + * + + + + DENY + + + diff --git a/test/configuration/properties.xml b/test/configuration/properties.xml new file mode 100644 index 0000000..3db2819 --- /dev/null +++ b/test/configuration/properties.xml @@ -0,0 +1,45 @@ + + + + + dds.sec.auth.plugin + builtin.PKI-DH + + + + dds.sec.auth.builtin.PKI-DH.identity_ca + file:///maincacert.pem + + + dds.sec.auth.builtin.PKI-DH.identity_certificate + file:///mainpubcert.pem + + + dds.sec.auth.builtin.PKI-DH.private_key + file:///mainpubkey.pem + + + + dds.sec.access.plugin + builtin.Access-Permissions + + + + dds.sec.access.builtin.Access-Permissions.permissions_ca + file:///maincacert.pem + + + dds.sec.access.builtin.Access-Permissions.governance + file:///governance_all_enable.smime + + + dds.sec.access.builtin.Access-Permissions.permissions + file:///permissions.smime + + + + dds.sec.crypto.plugin + builtin.AES-GCM-GMAC + + + diff --git a/test/configuration/tests_params.json b/test/configuration/tests_params.json index 9f7ba3b..ce4ed7f 100644 --- a/test/configuration/tests_params.json +++ b/test/configuration/tests_params.json @@ -1,6 +1,10 @@ { "configurations": { + "properties": + { + "SECURITY": "/properties.xml" + }, "configuration_files": { "INTRAPROCESS_OFF": "/intraprocess_off.xml", diff --git a/test/run_test.py b/test/run_test.py index 83b5a8e..4aa3535 100644 --- a/test/run_test.py +++ b/test/run_test.py @@ -144,6 +144,20 @@ def parse_options(): required=False, help='Use intraprocess transport. Default one test with each.' ) + parser.add_argument( + '-S', + '--security', + type=str, + required=False, + help='Enable security in tests.' + ) + parser.add_argument( + '-C', + '--certs-path', + type=str, + required=False, + help='Path to certs path directory' + ) return parser.parse_args() @@ -246,6 +260,7 @@ def execute_validate_thread_test( ds_tool_path, process_params, config_file, + props_file, flags_in, fds_path=None, clear=True, @@ -350,10 +365,13 @@ def execute_validate_thread_test( # Launch if xml_config_file is not None: - # Create args with config file and outputfile - process_args = \ - [ds_tool_path, '-c', xml_config_file, '-o', result_file] + flags - + if props_file is not None: + process_args = \ + [ds_tool_path, '-c', xml_config_file, '-p', props_file, '-o', result_file] + flags + else: + # Create args with config file and outputfile + process_args = \ + [ds_tool_path, '-c', xml_config_file, '-o', result_file] + flags else: # Fastdds tool process_args = [fds_path, '-i', str(server_id)] @@ -414,6 +432,7 @@ def execute_validate_test( ds_tool_path, test_params, config_file, + props_file, flags, fds_path=None, clear=True, @@ -465,6 +484,7 @@ def execute_validate_test( ds_tool_path, process_config, config_file, + props_file, flags, fds_path, clear, @@ -497,7 +517,7 @@ def execute_validate_test( return result -def get_configurations(config_params, intraprocess, shm): +def get_configurations(config_params, intraprocess, shm, security): """ Extract configurations from json. @@ -511,6 +531,7 @@ def get_configurations(config_params, intraprocess, shm): :param config_params: dictionary with configurations. :param intraprocess: only use intra-process as configuration file. :param shm: only use shared memory as default transport. + :param security: enable security. :return: tuple of two arrays. First array is an array of tuples where first @@ -560,6 +581,24 @@ def get_configurations(config_params, intraprocess, shm): if shm is not None and shm: flags = [f for f in flags if f[0] != 'SHM_OFF'] + if security is not None: + if os.path.isfile(config_params['properties']['SECURITY']): + if os.path.exists(args.certs_path): + props_file = open(config_params['properties']['SECURITY'], "r+") + data = props_file.read() + #Replace all occurrences of the required label + data = data.replace('', args.certs_path) + props_file.seek(0) + props_file.write(data) + props_file.truncate() + props_file.close() + else: + logger.error('Certs path not found at ' + args.certs_path) + exit(1) + else: + logger.error('Properties file not found at ' + config_params['properties']['SECURITY']) + exit(1) + flags_combinatory = [] for i in range(1, 1+len(flags)): for combination in itertools.combinations(flags, i): @@ -585,6 +624,7 @@ def create_tests( tests=None, intraprocess=None, shm=None, + security=None, clear=True, fds_path=None, debug=False, @@ -606,6 +646,7 @@ def create_tests( :param shm: if set it specifies if shared memory is used or not. If None, both with and without shared memory will be executed. (Default: None) + :param security: Whether to load properties file to enable security. :param clear: if true remove generated files if test passes. :param fds_path: path to fastdds tool. This arg is not needed unless test must execute fastdds tool, in which case it will raise an error @@ -636,11 +677,17 @@ def create_tests( config_files, flags_combinatory = get_configurations( config_params, intraprocess, - shm + shm, + security ) test_results = True + if security is not None and security: + props_file = config_params['properties']['SECURITY'] + else: + props_file = None + # iterate over parameters for test_name, test in tests: for config_name, config_file in config_files: @@ -673,12 +720,18 @@ def create_tests( f' with config file <{config_file}>' f' and flags {flags}') + if props_file is not None: + logger.info(f'Using properties of file <{props_file}>') + for property in config_params['properties']: + test_id += '.' + property + test_results &= execute_validate_test( test_name, test_id, discovery_server_tool_path, params_file[test], config_file, + props_file, flags, fds_path, clear, @@ -824,6 +877,10 @@ def load_test_params(tests_params_path): if shm is not None: shm = shared.boolean_from_string(shm) + security = args.security + if security is not None and security: + security = shared.boolean_from_string(security) + result = create_tests( test_params, config_params, @@ -831,6 +888,7 @@ def load_test_params(tests_params_path): tests=args.test, intraprocess=intraprocess, shm=shm, + security=security, clear=not args.not_remove, fds_path=(args.fds if args.fds else None), debug=args.debug,