def keystore_dir(tmpdir_factory): keystore_dir = str(tmpdir_factory.mktemp('keystore')) # Create the keystore assert cli.main(argv=['security', 'create_keystore', keystore_dir]) == 0 # Return path to keystore directory return keystore_dir
def test_generate_policy_no_nodes(capsys): with tempfile.TemporaryDirectory() as tmpdir: assert cli.main(argv=[ 'security', 'generate_policy', os.path.join(tmpdir, 'test-policy.xml') ]) != 0 stderr = capsys.readouterr().err.strip() assert stderr == 'No nodes detected in the ROS graph. No policy file was generated.'
def test_list_enclaves_uninitialized_keystore(capsys): with tempfile.TemporaryDirectory() as keystore_dir: # Verify that list_enclaves properly handles an uninitialized keystore assert cli.main(argv=['security', 'list_enclaves', keystore_dir]) != 0 assert ( capsys.readouterr().err.strip() == f"Unable to list enclaves: '{keystore_dir}' is not a valid keystore" )
def test_generate_policy_services(): with tempfile.TemporaryDirectory() as tmpdir: # Create a test-specific context so that generate_policy can still init context = rclpy.Context() rclpy.init(context=context) node = rclpy.create_node('test_generate_policy_services_node', context=context) try: # Create a server and client node.create_client(Trigger, 'test_generate_policy_services_client') node.create_service(Trigger, 'test_generate_policy_services_server', lambda request, response: response) # Generate the policy for the running node assert cli.main(argv=[ 'security', 'generate_policy', os.path.join(tmpdir, 'test-policy.xml') ]) == 0 finally: node.destroy_node() rclpy.shutdown(context=context) # Load the policy and pull out allowed replies and requests policy = load_policy(os.path.join(tmpdir, 'test-policy.xml')) profile = policy.find( path= 'profiles/profile[@ns="/"][@node="test_generate_policy_services_node"]' ) assert profile is not None service_reply_allowed = profile.find(path='services[@reply="ALLOW"]') assert service_reply_allowed is not None service_request_allowed = profile.find( path='services[@request="ALLOW"]') assert service_request_allowed is not None # Verify that the allowed replies include service_server and not service_client services = service_reply_allowed.findall('service') assert len([ s for s in services if s.text == 'test_generate_policy_services_server' ]) == 1 assert len([ s for s in services if s.text == 'test_generate_policy_services_client' ]) == 0 # Verify that the allowed requests include service_client and not service_server services = service_request_allowed.findall('service') assert len([ s for s in services if s.text == 'test_generate_policy_services_client' ]) == 1 assert len([ s for s in services if s.text == 'test_generate_policy_services_server' ]) == 0
def test_list_keys_no_keys(capsys): with tempfile.TemporaryDirectory() as keystore_dir: with capsys.disabled(): # First, create the keystore assert _keystore.create_keystore(keystore_dir) # Now verify that empty keystore we just created contains no keys assert cli.main(argv=['security', 'list_keys', keystore_dir]) == 0 assert len(capsys.readouterr().out.strip()) == 0
def test_verb_dump(self): with tempfile.TemporaryDirectory() as tmpdir: assert cli.main(argv=[ 'param', 'dump', '/foo/test_node', '--output-dir', tmpdir ]) is None # Compare generated parameter file against expected generated_param_file = os.path.join(tmpdir, self._output_file()) assert (open(generated_param_file, 'r').read() == EXPECTED_PARAMETER_FILE)
def test_generate_policy_topics(): with tempfile.TemporaryDirectory() as tmpdir: # Create a test-specific context so that generate_policy can still init context = rclpy.Context() rclpy.init(context=context) node = rclpy.create_node('test_generate_policy_topics_node', context=context) try: # Create a publisher and subscription node.create_publisher(Strings, 'test_generate_policy_topics_pub', 1) node.create_subscription(Strings, 'test_generate_policy_topics_sub', lambda msg: None, 1) # Generate the policy for the running node assert cli.main(argv=[ 'security', 'generate_policy', os.path.join(tmpdir, 'test-policy.xml') ]) == 0 finally: node.destroy_node() rclpy.shutdown(context=context) # Load the policy and pull out the allowed publications and subscriptions policy = load_policy(os.path.join(tmpdir, 'test-policy.xml')) profile = policy.find( path= 'profiles/profile[@ns="/"][@node="test_generate_policy_topics_node"]' ) assert profile is not None topics_publish_allowed = profile.find(path='topics[@publish="ALLOW"]') assert topics_publish_allowed is not None topics_subscribe_allowed = profile.find( path='topics[@subscribe="ALLOW"]') assert topics_subscribe_allowed is not None # Verify that the allowed publications include topic_pub and not topic_sub topics = topics_publish_allowed.findall('topic') assert len([ t for t in topics if t.text == 'test_generate_policy_topics_pub' ]) == 1 assert len([ t for t in topics if t.text == 'test_generate_policy_topics_sub' ]) == 0 # Verify that the allowed subscriptions include topic_sub and not topic_pub topics = topics_subscribe_allowed.findall('topic') assert len([ t for t in topics if t.text == 'test_generate_policy_topics_sub' ]) == 1 assert len([ t for t in topics if t.text == 'test_generate_policy_topics_pub' ]) == 0
def test_create_enclave_twice(tmpdir): keystore_dir = Path(tmpdir) # First, create the keystore sros2.keystore.create_keystore(keystore_dir) assert keystore_dir.is_dir() # Now using that keystore, create an enclave assert cli.main(argv=[ 'security', 'create_enclave', str(keystore_dir), '/test_enclave' ]) == 0 enclave_dir = keystore_dir / 'enclaves' / 'test_enclave' assert enclave_dir.is_dir() # Now create it again and confirm that the command doesn't fail assert cli.main(argv=[ 'security', 'create_enclave', str(keystore_dir), '/test_enclave' ]) == 0
def test_list_keys(capsys): with tempfile.TemporaryDirectory() as keystore_dir: with capsys.disabled(): # First, create the keystore assert _keystore.create_keystore(keystore_dir) # Now using that keystore, create a keypair assert _key.create_key(keystore_dir, '/test_enclave') # Now verify that the key we just created is included in the list assert cli.main(argv=['security', 'list_keys', keystore_dir]) == 0 assert capsys.readouterr().out.strip() == 'test_enclave'
def test_list_enclaves_no_keys(capsys): with tempfile.TemporaryDirectory() as keystore_dir: keystore_dir = pathlib.Path(keystore_dir) with capsys.disabled(): # First, create the keystore sros2.keystore.create_keystore(keystore_dir) assert keystore_dir.is_dir() # Now verify that empty keystore we just created contains no enclaves assert cli.main(argv=['security', 'list_enclaves', str(keystore_dir)]) == 0 assert len(capsys.readouterr().out.strip()) == 0
def node_keys_dir(tmpdir_factory): keystore_dir = str(tmpdir_factory.mktemp('keystore')) # First, create the keystore assert create_keystore(keystore_dir) # Now using that keystore, create a keypair along with other files required by DDS assert cli.main( argv=['security', 'create_key', keystore_dir, '/test_node']) == 0 node_dir = os.path.join(keystore_dir, 'test_node') assert os.path.isdir(os.path.join(keystore_dir, 'test_node')) # Return path to directory containing the node's files return node_dir
def test_verb_dump_print(self): with patch('sys.stdout', new=StringIO()) as fake_stdout: assert cli.main( argv=['param', 'dump', 'foo/test_node', '--print']) is None # Compare generated stdout against expected assert fake_stdout.getvalue().strip( ) == EXPECTED_PARAMETER_FILE[:-1] with tempfile.TemporaryDirectory() as tmpdir: assert cli.main(argv=[ 'param', 'dump', 'foo/test_node', '--output-dir', tmpdir, '--print' ]) is None not_generated_param_file = os.path.join(tmpdir, self._output_file()) with self.assertRaises(OSError) as context: open(not_generated_param_file, 'r') # Make sure the file was not create, thus '--print' did preempt assert '[Errno 2] No such file or directory' in str( context.exception)
def enclave_keys_dir(tmpdir_factory): keystore_dir = Path(str(tmpdir_factory.mktemp('keystore'))) # First, create the keystore assert _keystore.create_keystore(keystore_dir) # Now using that keystore, create a keypair along with other files required by DDS assert cli.main( argv=['security', 'create_key', str(keystore_dir), '/test_enclave']) == 0 enclave_dir = keystore_dir / 'enclaves' / 'test_enclave' assert enclave_dir.is_dir() # Return path to directory containing the enclave's files return enclave_dir
def test_list_keys(capsys): enclave_names = [ '/test_enclave', '/test/nested_enclave', '/sky/is/the/limit' ] with tempfile.TemporaryDirectory() as keystore_dir: with capsys.disabled(): # First, create the keystore assert _keystore.create_keystore(keystore_dir) # Now using that keystore, create a keypair for enclave_name in enclave_names: assert _key.create_key(keystore_dir, enclave_name) # Now verify that the key we just created is included in the list assert cli.main(argv=['security', 'list_keys', keystore_dir]) == 0 assert capsys.readouterr().out.strip() == '\n'.join( sorted(enclave_names))
def enclave_dir(tmpdir_factory, test_policy_dir) -> pathlib.Path: keystore_dir = pathlib.Path(str(tmpdir_factory.mktemp('keystore'))) # First, create the keystore as well as a keypair for the talker assert _keystore.create_keystore(keystore_dir) assert _key.create_key(keystore_dir, _test_identity) security_files_dir = keystore_dir.joinpath(f'enclaves{_test_identity}') assert security_files_dir.is_dir() # Now using that keystore, create a permissions file using the sample policy policy_file_path = test_policy_dir / 'sample.policy.xml' assert cli.main(argv=[ 'security', 'create_permission', str(keystore_dir), _test_identity, str(policy_file_path) ]) == 0 # Return path to directory containing the identity's files return security_files_dir
def test_list_enclaves(capsys): enclave_names = [ '/test_enclave', '/test/nested_enclave', '/sky/is/the/limit' ] with tempfile.TemporaryDirectory() as keystore_dir: keystore_dir = pathlib.Path(keystore_dir) with capsys.disabled(): # First, create the keystore sros2.keystore.create_keystore(keystore_dir) assert keystore_dir.is_dir() # Now using that keystore, create an enclave for enclave_name in enclave_names: sros2.keystore.create_enclave(keystore_dir, enclave_name) # Now verify that the enclave we just created is included in the list assert cli.main(argv=['security', 'list_enclaves', str(keystore_dir)]) == 0 assert capsys.readouterr().out.strip() == '\n'.join( sorted(enclave_names))
def test_list_keys_uninitialized_keystore(capsys): with tempfile.TemporaryDirectory() as keystore_dir: # Verify that list_keys properly handles an uninitialized keystore assert cli.main(argv=['security', 'list_keys', keystore_dir]) == 0 assert len(capsys.readouterr().out.strip()) == 0
def test_generate_policy_no_policy_file(capsys): with pytest.raises(SystemExit) as e: cli.main(argv=['security', 'generate_policy']) assert e.value.code != 0 stderr = capsys.readouterr().err.strip() assert 'following arguments are required: POLICY_FILE_PATH' in stderr
def test_verb_dump_invalid_path(self): assert cli.main( argv=['param', 'dump', 'foo/test_node', '--output-dir', 'invalid_path']) \ == "'invalid_path' is not a valid directory."
def test_verb_dump_invalid_node(self): assert cli.main( argv=['param', 'dump', 'invalid_node']) == 'Node not found' assert cli.main( argv=['param', 'dump', 'invalid_ns/test_node']) == 'Node not found'
def test_create_keystore(): def check_index_txt(path): with open(path, 'r') as f: lines = f.readlines() assert len(lines) == 0 def check_ca_cert_pem(path): with open(path, 'rb') as f: cert = x509.load_pem_x509_certificate(f.read(), cryptography_backend()) names = cert.subject.get_attributes_for_oid( x509.oid.NameOID.COMMON_NAME) assert len(names) == 1 assert names[0].value == u'sros2testCA' names = cert.subject.get_attributes_for_oid( x509.oid.NameOID.ORGANIZATION_NAME) assert len(names) == 0 def check_ca_conf(path): config = configparser.ConfigParser() successful_reads = config.read(path) assert len(successful_reads) == 1 assert config.sections() == [ ' ca ', ' CA_default ', ' policy_match ', ' local_ca_extensions ', ' req ', ' req_distinguished_name ', ' root_ca_extensions ', ] def check_ecdsaparam(path): with open(path, 'r') as f: # cryptography does not seem to know how to load ecparams lines = f.readlines() assert lines[0] == '-----BEGIN EC PARAMETERS-----\n' assert lines[-1] == '-----END EC PARAMETERS-----\n' def check_governance_xml(path): # validates valid XML ElementTree.parse(path) def check_ca_key_pem(path): with open(path, 'rb') as f: key = load_pem_private_key(f.read(), password=None, backend=cryptography_backend()) public = key.public_key() assert public.curve.name == 'secp256r1' with tempfile.TemporaryDirectory() as keystore_dir: assert cli.main( argv=['security', 'create_keystore', keystore_dir]) == 0 expected_files = ( ('governance.p7s', None), ('index.txt', check_index_txt), ('ca.cert.pem', check_ca_cert_pem), ('ca_conf.cnf', check_ca_conf), ('ecdsaparam', check_ecdsaparam), ('governance.xml', check_governance_xml), ('ca.key.pem', check_ca_key_pem), ('serial', None), ) for expected_file, file_validator in expected_files: path = os.path.join(keystore_dir, expected_file) assert os.path.isfile( path), 'Expected output file %s was not found.' % expected_file if file_validator: file_validator(path)
def test_list_keys_no_keystore(capsys): # Verify that list_keys properly handles a non-existent keystore keystore = os.path.join(tempfile.gettempdir(), 'non-existent') assert cli.main(argv=['security', 'list_keys', keystore]) != 0 assert capsys.readouterr().err.strip( ) == 'No such file or directory: {!r}'.format(keystore)
def test_list_enclaves_no_keystore(capsys): # Verify that list_enclaves properly handles a non-existent keystore keystore = os.path.join(tempfile.gettempdir(), 'non-existent') assert cli.main(argv=['security', 'list_enclaves', keystore]) != 0 assert (capsys.readouterr().err.strip() == f"Unable to list enclaves: '{keystore}' is not a valid keystore")