diff --git a/kmip/core/config_helper.py b/kmip/core/config_helper.py index 6621623..38754cc 100644 --- a/kmip/core/config_helper.py +++ b/kmip/core/config_helper.py @@ -45,15 +45,20 @@ class ConfigHelper(object): # Timeout measured in seconds DEFAULT_TIMEOUT = 30 - def __init__(self): + def __init__(self, path=None): self.logger = logging.getLogger(__name__) self.conf = SafeConfigParser() - if self.conf.read(CONFIG_FILE): - self.logger.debug("Using config file at {0}".format(CONFIG_FILE)) + + filenames = path + if not path: + filenames = CONFIG_FILE + + if self.conf.read(filenames): + self.logger.debug("Using config file at {0}".format(filenames)) else: self.logger.warning( - "Config file {0} not found".format(CONFIG_FILE)) + "Config file {0} not found".format(filenames)) def get_valid_value(self, direct_value, config_section, config_option_name, default_value): diff --git a/kmip/demos/pie/create.py b/kmip/demos/pie/create.py index 70a219f..fdaea59 100644 --- a/kmip/demos/pie/create.py +++ b/kmip/demos/pie/create.py @@ -44,7 +44,10 @@ if __name__ == '__main__': algorithm = getattr(enums.CryptographicAlgorithm, algorithm, None) # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: uid = client.create( algorithm, diff --git a/kmip/demos/pie/create_key_pair.py b/kmip/demos/pie/create_key_pair.py index e82eae5..018e838 100644 --- a/kmip/demos/pie/create_key_pair.py +++ b/kmip/demos/pie/create_key_pair.py @@ -43,7 +43,10 @@ if __name__ == '__main__': algorithm = getattr(enums.CryptographicAlgorithm, algorithm, None) # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: public_uid, private_uid = client.create_key_pair( algorithm, diff --git a/kmip/demos/pie/decrypt.py b/kmip/demos/pie/decrypt.py index 1b10aa6..f1764e8 100644 --- a/kmip/demos/pie/decrypt.py +++ b/kmip/demos/pie/decrypt.py @@ -54,7 +54,10 @@ if __name__ == '__main__': message = binascii.unhexlify(message[1:]) # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: # Decrypt the cipher text with the encryption key. try: plain_text = client.decrypt( diff --git a/kmip/demos/pie/derive_key.py b/kmip/demos/pie/derive_key.py index 122799b..f66e7e9 100644 --- a/kmip/demos/pie/derive_key.py +++ b/kmip/demos/pie/derive_key.py @@ -30,7 +30,10 @@ if __name__ == '__main__': config = opts.config # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: # Create keys to use for derivation try: key_id = client.create( diff --git a/kmip/demos/pie/destroy.py b/kmip/demos/pie/destroy.py index 7e7dc33..0302282 100644 --- a/kmip/demos/pie/destroy.py +++ b/kmip/demos/pie/destroy.py @@ -37,7 +37,10 @@ if __name__ == '__main__': sys.exit() # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: client.destroy(uid) logger.info("Successfully destroyed secret with ID: {0}".format( diff --git a/kmip/demos/pie/encrypt.py b/kmip/demos/pie/encrypt.py index 1946eeb..4a84ffe 100644 --- a/kmip/demos/pie/encrypt.py +++ b/kmip/demos/pie/encrypt.py @@ -50,7 +50,10 @@ if __name__ == '__main__': message = bytes(message, 'utf-8') # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: # Create an encryption key. try: key_id = client.create( diff --git a/kmip/demos/pie/get.py b/kmip/demos/pie/get.py index 90fc434..aaa8962 100644 --- a/kmip/demos/pie/get.py +++ b/kmip/demos/pie/get.py @@ -37,7 +37,10 @@ if __name__ == '__main__': sys.exit() # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: secret = client.get(uid) logger.info("Successfully retrieved secret with ID: {0}".format( diff --git a/kmip/demos/pie/get_attribute_list.py b/kmip/demos/pie/get_attribute_list.py index 27b3dad..2c25c1b 100644 --- a/kmip/demos/pie/get_attribute_list.py +++ b/kmip/demos/pie/get_attribute_list.py @@ -37,7 +37,10 @@ if __name__ == '__main__': sys.exit() # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: attribute_names = client.get_attribute_list(uid) logger.info("Successfully retrieved {0} attribute names:".format( diff --git a/kmip/demos/pie/locate.py b/kmip/demos/pie/locate.py index 2c10880..bbd1336 100644 --- a/kmip/demos/pie/locate.py +++ b/kmip/demos/pie/locate.py @@ -53,7 +53,10 @@ if __name__ == '__main__': attributes = [name_obj] # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: uuids = client.locate(attributes=attributes) logger.info("Located uuids: {0}".format(uuids)) diff --git a/kmip/demos/pie/mac.py b/kmip/demos/pie/mac.py index d30a34d..b5288ed 100644 --- a/kmip/demos/pie/mac.py +++ b/kmip/demos/pie/mac.py @@ -48,7 +48,10 @@ if __name__ == '__main__': algorithm = getattr(enums.CryptographicAlgorithm, algorithm, None) # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: uid, mac_data = client.mac(data, uid, algorithm) logger.info("Successfully done MAC using key with ID: " diff --git a/kmip/demos/pie/register_certificate.py b/kmip/demos/pie/register_certificate.py index f5eeae6..ffaa38a 100644 --- a/kmip/demos/pie/register_certificate.py +++ b/kmip/demos/pie/register_certificate.py @@ -91,7 +91,10 @@ if __name__ == '__main__': cert.operation_policy_name = opts.operation_policy_name # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: uid = client.register(cert) logger.info("Successfully registered certificate with ID: " diff --git a/kmip/demos/pie/register_opaque_object.py b/kmip/demos/pie/register_opaque_object.py index 043a77c..e0523c8 100644 --- a/kmip/demos/pie/register_opaque_object.py +++ b/kmip/demos/pie/register_opaque_object.py @@ -39,7 +39,10 @@ if __name__ == '__main__': obj.operation_policy_name = opts.operation_policy_name # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: uid = client.register(obj) logger.info("Successfully registered opaque object with ID: " diff --git a/kmip/demos/pie/register_private_key.py b/kmip/demos/pie/register_private_key.py index 7807f8f..ee27ffb 100644 --- a/kmip/demos/pie/register_private_key.py +++ b/kmip/demos/pie/register_private_key.py @@ -118,7 +118,10 @@ if __name__ == '__main__': key.operation_policy_name = opts.operation_policy_name # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: uid = client.register(key) logger.info("Successfully registered private key with ID: " diff --git a/kmip/demos/pie/register_public_key.py b/kmip/demos/pie/register_public_key.py index b76728e..bc867dd 100644 --- a/kmip/demos/pie/register_public_key.py +++ b/kmip/demos/pie/register_public_key.py @@ -60,7 +60,10 @@ if __name__ == '__main__': key.operation_policy_name = opts.operation_policy_name # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: uid = client.register(key) logger.info("Successfully registered public key with ID: " diff --git a/kmip/demos/pie/register_secret_data.py b/kmip/demos/pie/register_secret_data.py index b4e3628..2ac7072 100644 --- a/kmip/demos/pie/register_secret_data.py +++ b/kmip/demos/pie/register_secret_data.py @@ -41,7 +41,10 @@ if __name__ == '__main__': secret.operation_policy_name = opts.operation_policy_name # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: uid = client.register(secret) logger.info( diff --git a/kmip/demos/pie/register_symmetric_key.py b/kmip/demos/pie/register_symmetric_key.py index 65c3b5e..38a0689 100644 --- a/kmip/demos/pie/register_symmetric_key.py +++ b/kmip/demos/pie/register_symmetric_key.py @@ -44,7 +44,10 @@ if __name__ == '__main__': key.operation_policy_name = opts.operation_policy_name # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: try: uid = client.register(key) logger.info("Successfully registered symmetric key with ID: " diff --git a/kmip/demos/pie/sign.py b/kmip/demos/pie/sign.py index 286319b..291de5f 100644 --- a/kmip/demos/pie/sign.py +++ b/kmip/demos/pie/sign.py @@ -31,7 +31,10 @@ if __name__ == '__main__': config = opts.config # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: # Create keys to use for derivation try: signing_key_id = client.register( diff --git a/kmip/demos/pie/signature_verify.py b/kmip/demos/pie/signature_verify.py index b3dba5c..18010e7 100644 --- a/kmip/demos/pie/signature_verify.py +++ b/kmip/demos/pie/signature_verify.py @@ -31,7 +31,10 @@ if __name__ == '__main__': config = opts.config # Build the client and connect to the server - with client.ProxyKmipClient(config=config) as client: + with client.ProxyKmipClient( + config=config, + config_file=opts.config_file + ) as client: # Create keys to use for derivation try: signing_key_id = client.register( diff --git a/kmip/demos/units/activate.py b/kmip/demos/units/activate.py index 24c8f2e..27796e7 100644 --- a/kmip/demos/units/activate.py +++ b/kmip/demos/units/activate.py @@ -40,7 +40,7 @@ if __name__ == '__main__': sys.exit() # Build the client and connect to the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() # Activate the object diff --git a/kmip/demos/units/create.py b/kmip/demos/units/create.py index b41ff00..60179ef 100644 --- a/kmip/demos/units/create.py +++ b/kmip/demos/units/create.py @@ -74,7 +74,7 @@ if __name__ == '__main__': credential = credential_factory.create_credential(credential_type, credential_value) # Build the client and connect to the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() # Build the different object attributes diff --git a/kmip/demos/units/create_key_pair.py b/kmip/demos/units/create_key_pair.py index 86e8d71..c0e4dac 100644 --- a/kmip/demos/units/create_key_pair.py +++ b/kmip/demos/units/create_key_pair.py @@ -87,7 +87,7 @@ if __name__ == '__main__': credential = credential_factory.create_credential(credential_type, credential_value) # Build the client and connect to the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() algorithm_obj = attribute_factory.create_attribute(attribute_type, diff --git a/kmip/demos/units/destroy.py b/kmip/demos/units/destroy.py index cb27336..bedaa00 100644 --- a/kmip/demos/units/destroy.py +++ b/kmip/demos/units/destroy.py @@ -59,7 +59,7 @@ if __name__ == '__main__': credential = credential_factory.create_credential(credential_type, credential_value) # Build the client and connect to the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() # Destroy the SYMMETRIC_KEY object diff --git a/kmip/demos/units/discover_versions.py b/kmip/demos/units/discover_versions.py index ad9a662..4d18087 100644 --- a/kmip/demos/units/discover_versions.py +++ b/kmip/demos/units/discover_versions.py @@ -45,7 +45,7 @@ if __name__ == '__main__': protocol_versions.append(ProtocolVersion(int(mm[0]), int(mm[1]))) # Build the client and connect to the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() result = client.discover_versions(protocol_versions=protocol_versions) diff --git a/kmip/demos/units/get.py b/kmip/demos/units/get.py index db1cc0f..8db8c83 100644 --- a/kmip/demos/units/get.py +++ b/kmip/demos/units/get.py @@ -77,7 +77,7 @@ if __name__ == '__main__': key_format_type = KeyFormatType(format_type_enum) # Build the client and connect to the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() # Retrieve the SYMMETRIC_KEY object diff --git a/kmip/demos/units/locate.py b/kmip/demos/units/locate.py index 1e882ac..7eb6057 100644 --- a/kmip/demos/units/locate.py +++ b/kmip/demos/units/locate.py @@ -64,7 +64,7 @@ if __name__ == '__main__': credential = credential_factory.create_credential(credential_type, credential_value) # Build the client and connect to the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() # Build name attribute diff --git a/kmip/demos/units/query.py b/kmip/demos/units/query.py index 144d86d..298c003 100644 --- a/kmip/demos/units/query.py +++ b/kmip/demos/units/query.py @@ -56,7 +56,7 @@ if __name__ == '__main__': QueryFunction(QueryFunctionEnum.QUERY_EXTENSION_MAP)) # Build the client and connect to the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() result = client.query(query_functions=query_functions) diff --git a/kmip/demos/units/register.py b/kmip/demos/units/register.py index 6f177f7..05d4f1a 100644 --- a/kmip/demos/units/register.py +++ b/kmip/demos/units/register.py @@ -72,7 +72,7 @@ if __name__ == '__main__': # Build the client, connect to the server, register the secret, and # disconnect from the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() result = client.register(object_type, template_attribute, secret) diff --git a/kmip/demos/units/revoke.py b/kmip/demos/units/revoke.py index 800918b..b569b98 100644 --- a/kmip/demos/units/revoke.py +++ b/kmip/demos/units/revoke.py @@ -41,7 +41,7 @@ if __name__ == '__main__': sys.exit() # Build the client and connect to the server - client = KMIPProxy(config=config) + client = KMIPProxy(config=config, config_file=opts.config_file) client.open() # Activate the object diff --git a/kmip/demos/utils.py b/kmip/demos/utils.py index 7d8c686..7401162 100644 --- a/kmip/demos/utils.py +++ b/kmip/demos/utils.py @@ -86,6 +86,15 @@ def build_cli_parser(operation=None): default="client", dest="config", help="Client configuration group to load from configuration file") + parser.add_option( + "-s", + "--config-file", + action="store", + type="str", + default=None, + dest="config_file", + help="Path to the client configuration file." + ) if operation is Operation.CREATE: parser.add_option( diff --git a/kmip/pie/client.py b/kmip/pie/client.py index f9fbd7a..95c6c08 100644 --- a/kmip/pie/client.py +++ b/kmip/pie/client.py @@ -61,7 +61,8 @@ class ProxyKmipClient(object): ssl_version=None, username=None, password=None, - config='client'): + config='client', + config_file=None): """ Construct a ProxyKmipClient. @@ -88,6 +89,9 @@ class ProxyKmipClient(object): file. Use to load a specific set of configuration settings from the configuration file, instead of specifying them manually. Optional, defaults to the default client section, 'client'. + config_file (string): The path to the client's configuration file. + Optional, defaults to None. + """ self.logger = logging.getLogger() @@ -104,7 +108,9 @@ class ProxyKmipClient(object): ssl_version=ssl_version, username=username, password=password, - config=config) + config=config, + config_file=config_file + ) # TODO (peter-hamilton) Add a multiprocessing lock for synchronization. self._is_open = False diff --git a/kmip/services/kmip_client.py b/kmip/services/kmip_client.py index f4e861a..547190e 100644 --- a/kmip/services/kmip_client.py +++ b/kmip/services/kmip_client.py @@ -59,6 +59,7 @@ from kmip.core.utils import BytearrayStream import logging import logging.config import os +import six import socket import ssl @@ -73,15 +74,27 @@ class KMIPProxy: cert_reqs=None, ssl_version=None, ca_certs=None, do_handshake_on_connect=None, suppress_ragged_eofs=None, - username=None, password=None, timeout=30, config='client'): + username=None, password=None, timeout=30, config='client', + config_file=None): self.logger = logging.getLogger(__name__) self.credential_factory = CredentialFactory() self.config = config + if config_file: + if not isinstance(config_file, six.string_types): + raise ValueError( + "The client configuration file argument must be a string." + ) + if not os.path.exists(config_file): + raise ValueError( + "The client configuration file '{}' does not " + "exist.".format(config_file) + ) + self._set_variables(host, port, keyfile, certfile, cert_reqs, ssl_version, ca_certs, do_handshake_on_connect, suppress_ragged_eofs, - username, password, timeout) + username, password, timeout, config_file) self.batch_items = [] self.conformance_clauses = [ @@ -1553,8 +1566,8 @@ class KMIPProxy: def _set_variables(self, host, port, keyfile, certfile, cert_reqs, ssl_version, ca_certs, do_handshake_on_connect, suppress_ragged_eofs, - username, password, timeout): - conf = ConfigHelper() + username, password, timeout, config_file): + conf = ConfigHelper(config_file) # TODO: set this to a host list self.host_list_str = conf.get_valid_value( diff --git a/kmip/tests/unit/services/test_kmip_client.py b/kmip/tests/unit/services/test_kmip_client.py index a4c8b17..c9c7c95 100644 --- a/kmip/tests/unit/services/test_kmip_client.py +++ b/kmip/tests/unit/services/test_kmip_client.py @@ -96,6 +96,32 @@ class TestKMIPClient(TestCase): def tearDown(self): super(TestKMIPClient, self).tearDown() + def test_init_with_invalid_config_file_value(self): + """ + Test that the right error is raised when an invalid configuration file + value is provided to the client. + """ + kwargs = {'config_file': 1} + self.assertRaisesRegexp( + ValueError, + "The client configuration file argument must be a string.", + KMIPProxy, + **kwargs + ) + + def test_init_with_invalid_config_file_path(self): + """ + Test that the right error is raised when an invalid configuration file + path is provided to the client. + """ + kwargs = {'config_file': 'invalid'} + self.assertRaisesRegexp( + ValueError, + "The client configuration file 'invalid' does not exist.", + KMIPProxy, + **kwargs + ) + def test_close(self): """ Test that calling close on the client works as expected. @@ -646,13 +672,21 @@ class TestKMIPClient(TestCase): host_list_string = '127.0.0.1,127.0.0.3, 127.0.0.5' host_list_expected = ['127.0.0.1', '127.0.0.3', '127.0.0.5'] - self.client._set_variables(host=host_list_string, - port=None, keyfile=None, certfile=None, - cert_reqs=None, ssl_version=None, - ca_certs=None, - do_handshake_on_connect=False, - suppress_ragged_eofs=None, username=None, - password=None, timeout=None) + self.client._set_variables( + host=host_list_string, + port=None, + keyfile=None, + certfile=None, + cert_reqs=None, + ssl_version=None, + ca_certs=None, + do_handshake_on_connect=False, + suppress_ragged_eofs=None, + username=None, + password=None, + timeout=None, + config_file=None + ) self.assertEqual(host_list_expected, self.client.host_list) def test_host_is_invalid_input(self):