Fixes ssh_known_host to take port into account

Fixes #23626

Also adds port support for get_known_host, check_known_host, and
rm_known_host
This commit is contained in:
Jason Hamner 2015-07-21 11:03:52 -06:00
parent c4b15840c6
commit c7466e7894

View file

@ -27,7 +27,7 @@ from salt.exceptions import (
from salt.ext.six.moves import range
log = logging.getLogger(__name__)
DEFAULT_SSH_PORT = 22
def __virtual__():
# TODO: This could work on windows with some love
@ -637,7 +637,7 @@ def _parse_openssh_output(lines):
@decorators.which('ssh-keygen')
def get_known_host(user, hostname, config=None):
def get_known_host(user, hostname, config=None, port=None):
'''
Return information about known host from the configfile, if any.
If there is no such key, return None.
@ -653,7 +653,8 @@ def get_known_host(user, hostname, config=None):
if isinstance(full, dict):
return full
cmd = 'ssh-keygen -F "{0}" -f "{1}"'.format(hostname, full)
ssh_hostname = _hostname_and_port_to_ssh_hostname(hostname,port)
cmd = 'ssh-keygen -F "{0}" -f "{1}"'.format(ssh_hostname, full)
lines = __salt__['cmd.run'](cmd, ignore_retcode=True,
python_shell=False).splitlines()
known_hosts = list(_parse_openssh_output(lines))
@ -692,7 +693,7 @@ def recv_known_host(hostname, enc=None, port=None, hash_hostname=False):
def check_known_host(user=None, hostname=None, key=None, fingerprint=None,
config=None):
config=None,port=None):
'''
Check the record in known_hosts file, either by its value or by fingerprint
(it's enough to set up either key or fingerprint, you don't need to set up
@ -719,7 +720,7 @@ def check_known_host(user=None, hostname=None, key=None, fingerprint=None,
else:
config = config or '.ssh/known_hosts'
known_host = get_known_host(user, hostname, config=config)
known_host = get_known_host(user, hostname, config=config, port=port)
if not known_host:
return 'add'
@ -732,7 +733,7 @@ def check_known_host(user=None, hostname=None, key=None, fingerprint=None,
return 'exists'
def rm_known_host(user=None, hostname=None, config=None):
def rm_known_host(user=None, hostname=None, config=None, port=None):
'''
Remove all keys belonging to hostname from a known_hosts file.
@ -755,7 +756,8 @@ def rm_known_host(user=None, hostname=None, config=None):
return {'status': 'error',
'error': 'Known hosts file {0} does not exist'.format(full)}
cmd = 'ssh-keygen -R "{0}" -f "{1}"'.format(hostname, full)
ssh_hostname = _hostname_and_port_to_ssh_hostname(hostname,port)
cmd = 'ssh-keygen -R "{0}" -f "{1}"'.format(ssh_hostname, full)
cmd_result = __salt__['cmd.run'](cmd, python_shell=False)
# ssh-keygen creates a new file, thus a chown is required.
if os.geteuid() == 0 and user:
@ -789,8 +791,14 @@ def set_known_host(user=None,
if not hostname:
return {'status': 'error',
'error': 'hostname argument required'}
if port is not None and port != DEFAULT_SSH_PORT and hash_hostname:
return {'status': 'error',
'error': 'argument port can not be used in '
'conjunction with argument hash_hostname'}
update_required = False
stored_host = get_known_host(user, hostname, config)
stored_host = get_known_host(user, hostname, config,port)
if not stored_host:
update_required = True
@ -827,7 +835,12 @@ def set_known_host(user=None,
if key:
remote_host = {'hostname': hostname, 'enc': enc, 'key': key}
line = '{hostname} {enc} {key}\n'.format(**remote_host)
if hash_hostname or port == DEFAULT_SSH_PORT:
line = '{hostname} {enc} {key}\n'.format(**remote_host)
else:
remote_host['port'] = port
line = '[{hostname}]:{port} {enc} {key}\n'.format(**remote_host)
# ensure ~/.ssh exists
ssh_dir = os.path.dirname(full)
@ -975,3 +988,9 @@ def hash_known_hosts(user=None, config=None):
uinfo = __salt__['user.info'](user)
os.chown(full, uinfo['uid'], uinfo['gid'])
return {'status': 'updated', 'comment': cmd_result}
def _hostname_and_port_to_ssh_hostname(hostname,port=DEFAULT_SSH_PORT):
if not port or port == DEFAULT_SSH_PORT:
return hostname
else:
return '[{0}]:{1}'.format(hostname,port)