From fd627ea382299981bd5def2d7892ee2dd4b8c035 Mon Sep 17 00:00:00 2001 From: Dennis Kliban Date: Mon, 1 Aug 2016 12:30:08 -0400 Subject: [PATCH] Removes ability to use password authentication when performing publishes using rsync re #1887 https://pulp.plan.io/issues/1887 re #1963 https://pulp.plan.io/issues/1963 re #1759 https://pulp.plan.io/issues/1759 --- pulp.spec | 1 - server/pulp/plugins/rsync/configuration.py | 111 +-------------------- server/pulp/plugins/rsync/publish.py | 13 +-- 3 files changed, 6 insertions(+), 119 deletions(-) diff --git a/pulp.spec b/pulp.spec index 9e0d59aa00..654b8f3c27 100644 --- a/pulp.spec +++ b/pulp.spec @@ -380,7 +380,6 @@ Requires: mod_xsendfile >= 0.12 Requires: m2crypto Requires: genisoimage Requires: kobo -Requires: sshpass # RHEL6 ONLY %if 0%{?rhel} == 6 Requires: nss >= 3.12.9 diff --git a/server/pulp/plugins/rsync/configuration.py b/server/pulp/plugins/rsync/configuration.py index d04c6411b1..159044de93 100644 --- a/server/pulp/plugins/rsync/configuration.py +++ b/server/pulp/plugins/rsync/configuration.py @@ -5,43 +5,6 @@ _LOG = logging.getLogger(__name__) -class OneOfValidation(object): - """ - Validates that the the value is one of possible values - """ - def __init__(self, values): - """ - :param values: list of valid values - """ - self.values = values - - def __call__(self, value, config): - """ - :param value: value to validate - :type value: any - :param config: distributor config - :type config: PulpCallConfig object - - :return: tuple indicating whether config value validates and error message or None - :rtype: (bool, str) or (bool, None) - """ - if value in self.values: - return (True, None) - else: - return (False, self._err(value)) - - def _err(self, value): - """ - :param value: value that did not pass validation - :type value: any - - :return: error message - :rtype: str - """ - params = {'value': value, 'allowed_values': ", ".join(self.values)} - return _("%(value)s is not in allowed values: %(allowed_values)s") % params - - class NonEmptyValidation(object): """ Validates that the value is not None @@ -110,68 +73,6 @@ def _err(self, value): return _("%(type)s type is not one of allowed types: %(allowed_types)s") % params -class RequireOptionalIf(object): - """ - Validates that if a particular config is present, other configs that are needed for it are also - present. - """ - def __init__(self, required_for_attr, condition): - """ - :param required_for_attr: a list of required config keys or dictionary with keys in the - config and values are lists of configs that need to be present - in the value of the key in config. - :type required_for_attr: list or dict - :param condition: callable that takes a config name and returns a boolean - :type condition: callable - """ - self.required_for_attr = required_for_attr - self.condition = condition - - def __call__(self, value, config): - """ - :param value: config name that is being validated - :type value: str - :param config: configuration instance to validate - :type config: pulp.plugins.config.PluginCallConfiguration - - :return: tuple indicating whether config value validates and error message or None - :rtype: (bool, str) or (bool, None) - """ - - subconfig = config - path = [] - if not self.condition(value): - return (True, None) - - if isinstance(self.required_for_attr, list): - fifo = [(x, subconfig, path) for x in self.required_for_attr] - elif isinstance(self.required_for_attr, dict): - fifo = [(val, subconfig.get(key), [key]) - for key, val in self.required_for_attr.iteritems()] - while fifo: - (required_for_attr, subconfig, path) = fifo.pop(0) - if isinstance(required_for_attr, list): - for x in required_for_attr: - fifo.insert(0, (x, subconfig, path)) - elif isinstance(required_for_attr, dict): - for key, val in required_for_attr.iteritems(): - fifo.insert(0, (val, subconfig.get(key)), path + [key]) - elif isinstance(required_for_attr, basestring): - if required_for_attr not in subconfig: - return (False, self._err(path + [required_for_attr])) - return (True, None) - - def _err(self, path): - """ - :param path: list of value that were missing - :type path: list - - :return: error message - :rtype: str - """ - return _("%(attribute)s attribute is required") % {'attribute': "::".join(path)} - - class RelativePathValidation(object): """ Validates that a path does not start with a forward slash. @@ -200,20 +101,14 @@ def _err(self, value): return _("attribute cannot start with a /") REMOTE_MANDATORY_KEYS = { - "auth_type": [OneOfValidation(["publickey", "password"]), - RequireOptionalIf({"remote": ["ssh_password", "ssh_user"]}, - lambda x: x == "password"), - RequireOptionalIf({"remote": ["ssh_identity_file", "ssh_user"]}, - lambda x: x == "publickey")], + "ssh_identity_file": [TypeValidation([basestring]), NonEmptyValidation()], + "ssh_user": [TypeValidation([basestring]), NonEmptyValidation()], "host": [TypeValidation([basestring]), NonEmptyValidation()], "root": [TypeValidation([basestring]), NonEmptyValidation()] } REMOTE_OPTIONAL_KEYS = { - "remote_units_path": [TypeValidation([basestring]), RelativePathValidation()], - "ssh_identity_file": [TypeValidation([basestring]), NonEmptyValidation()], - "ssh_user": [TypeValidation([basestring]), NonEmptyValidation()], - "ssh_password": [TypeValidation([basestring]), NonEmptyValidation()] + "remote_units_path": [TypeValidation([basestring]), RelativePathValidation()] } diff --git a/server/pulp/plugins/rsync/publish.py b/server/pulp/plugins/rsync/publish.py index 02f4488404..14ae12f973 100644 --- a/server/pulp/plugins/rsync/publish.py +++ b/server/pulp/plugins/rsync/publish.py @@ -96,23 +96,16 @@ def make_ssh_cmd(self, args=None): :rtype: list """ user = self.get_config().flatten()["remote"]['ssh_user'] - auth_type = self.get_config().flatten()["remote"]['auth_type'] - # -e 'ssh -l ssh_user -i ssh_identity_file' # use shared ssh connection for other threads cmd = ['ssh', '-l', user] - if auth_type == "publickey": - key = self.get_config().flatten()["remote"]['ssh_identity_file'] - cmd += ['-i', key] - cmd += ['-o', 'StrictHostKeyChecking no', + key = self.get_config().flatten()["remote"]['ssh_identity_file'] + cmd += ['-i', key, + '-o', 'StrictHostKeyChecking no', '-o', 'UserKnownHostsFile /dev/null', '-S', '/tmp/rsync_distributor-%r@%h:%p', '-o', 'ControlMaster auto', '-o', 'ControlPersist 10'] - if self.get_config().flatten()["remote"]['auth_type'] == 'password': - password_file = os.path.join(self.get_working_dir(), str(uuid.uuid4())) - open(password_file, 'w').write(self.get_config().flatten()['remote']['ssh_password']) - cmd = ['sshpass', '-f', password_file] + cmd if args: cmd += args return cmd