diff --git a/salt/modules/ssh.py b/salt/modules/ssh.py index ac45bd2ca2..1e4a9aae27 100644 --- a/salt/modules/ssh.py +++ b/salt/modules/ssh.py @@ -78,6 +78,31 @@ def _format_auth_line(key, enc, comment, options): return line +def _expand_authorized_keys_path(path, user, home): + ''' + Expand the AuthorizedKeysFile expression. Defined in man sshd_config(5) + ''' + converted_object = [] + had_escape = False + for char in path: + if had_escape: + had_escape = False + if char == '%': + converted_object.append('%') + elif char == 'u': + converted_object.append(user) + elif char == 'h': + converted_object.append(home) + else: + raise CommandExecutionError('Unknown token character ' + char) + continue + if char == '%': + had_escape = True + if had_escape: + raise CommandExecutionError("Last character can't be scape character") + return "".join(converted_object) + + def _get_config_file(user, config): ''' Get absolute path to a user's ssh_config. @@ -85,8 +110,10 @@ def _get_config_file(user, config): uinfo = __salt__['user.info'](user) if not uinfo: raise CommandExecutionError('User {0!r} does not exist'.format(user)) + home = uinfo['home'] if not os.path.isabs(config): - config = os.path.join(uinfo['home'], config) + config = os.path.join(home, config) + config = _expand_authorized_keys_path(config, user, home) return config diff --git a/salt/states/ssh_auth.py b/salt/states/ssh_auth.py index 0fa1b4aeef..842149812c 100644 --- a/salt/states/ssh_auth.py +++ b/salt/states/ssh_auth.py @@ -29,6 +29,7 @@ to use a YAML 'explicit key', as demonstrated in the second example below. ssh_auth.present: - user: root - source: salt://ssh_keys/thatch.id_rsa.pub + - config: %h/.ssh/authorized_keys sshkeys: ssh_auth.present: @@ -239,7 +240,8 @@ def present( config The location of the authorized keys file relative to the user's home - directory, defaults to ".ssh/authorized_keys" + directory, defaults to ".ssh/authorized_keys". Token expansion %u and + %h for username and home path supported. ''' ret = {'name': name, 'changes': {}, @@ -382,7 +384,9 @@ def absent(name, config The location of the authorized keys file relative to the user's home - directory, defaults to ".ssh/authorized_keys" + directory, defaults to ".ssh/authorized_keys". Token expansion %u and + %h for username and home path supported. + ''' ret = {'name': name, 'changes': {}, diff --git a/tests/unit/modules/ssh_test.py b/tests/unit/modules/ssh_test.py new file mode 100644 index 0000000000..086f8efd04 --- /dev/null +++ b/tests/unit/modules/ssh_test.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +# import Python Libs +from __future__ import absolute_import + +# Import Salt Testing Libs +from salttesting import TestCase +from salttesting.helpers import ensure_in_syspath + +# Import Salt Libs +ensure_in_syspath('../../') +from salt.modules import ssh + + +class SSHAuthKeyPathTestCase(TestCase): + ''' + TestCase for salt.modules.ssh module's ssh AuthorizedKeysFile path + expansion + ''' + def test_expand_user_token(self): + ''' + Test if the %u token is correctly expanded + ''' + output = ssh._expand_authorized_keys_path('/home/%u', 'user', + '/home/user') + self.assertEqual(output, '/home/user') + + output = ssh._expand_authorized_keys_path('/home/%h', 'user', + '/home/user') + self.assertEqual(output, '/home//home/user') + + output = ssh._expand_authorized_keys_path('/srv/%h/aaa/%u%%', 'user', + '/home/user') + self.assertEqual(output, '/srv//home/user/aaa/user%')