diff --git a/avocado/core/remoter.py b/avocado/core/remoter.py index 432085b27d04c2a621f84b880614ff31c0a9caac..ecd21c822cf7c909ba514f26b6c6e8f2b8c038db 100644 --- a/avocado/core/remoter.py +++ b/avocado/core/remoter.py @@ -20,6 +20,7 @@ import getpass import logging import time +from .settings import settings from ..utils import process LOG = logging.getLogger('avocado.test') @@ -70,6 +71,14 @@ class Remote(object): self.password = password self.port = port self.quiet = quiet + reject_unknown_hosts = settings.get_value('remoter.behavior', + 'reject_unknown_hosts', + key_type=bool, + default=True) + disable_known_hosts = settings.get_value('remoter.behavior', + 'disable_known_hosts', + key_type=bool, + default=False) self._setup_environment(host_string=hostname, user=username, password=password, @@ -78,7 +87,9 @@ class Remote(object): connection_attempts=attempts, linewise=True, abort_on_prompts=True, - abort_exception=ConnectionError) + abort_exception=ConnectionError, + reject_unknown_hosts=reject_unknown_hosts, + disable_known_hosts=disable_known_hosts) @staticmethod def _setup_environment(**kwargs): diff --git a/etc/avocado/avocado.conf b/etc/avocado/avocado.conf index f3c2f13125b08aa016b38888a931add881932e0b..af26b5dceebcbdb0974c5d0f370f3fefcda4908f 100644 --- a/etc/avocado/avocado.conf +++ b/etc/avocado/avocado.conf @@ -38,6 +38,19 @@ utf8 = # Keep job temporary files after jobs (useful for avocado debugging) keep_tmp_files = False +[remoter.behavior] +# __Insecure__, reject unknown SSH host keys. +# 'False' will leave you wide open to man-in-the-middle attacks! +# 'True' will only work with RSA keys (due to a bug in Paramiko). +# If using 'True', accept the remote host key fingerprint by using: +# $ ssh -oHostKeyAlgorithms='ssh-rsa' +reject_unknown_hosts = False +# __Insecure__, SSH layer to skip loading the user’s known-hosts +# file. Useful for avoiding exceptions in situations where a +# 'known host' changing its host key is actually valid (e.g. cloud +# servers such as EC2.) +disable_known_hosts = False + [job.output] # Base log level for --show-job-log. # Allowed levels: debug, info, warning, error, critical diff --git a/selftests/functional/test_thirdparty_bugs.py b/selftests/functional/test_thirdparty_bugs.py new file mode 100644 index 0000000000000000000000000000000000000000..eb08b2f86ca40da437bc84e66e98fbd9fcb160ff --- /dev/null +++ b/selftests/functional/test_thirdparty_bugs.py @@ -0,0 +1,32 @@ +import json +import sys +from avocado.utils import download + +if sys.version_info[:2] == (2, 6): + import unittest2 as unittest +else: + import unittest + + +class TestThirdPartyBugs(unittest.TestCase): + """ + Class created to verify third-party known issues + """ + + def test_paramiko_ecsda_bug(self): + # https://github.com/paramiko/paramiko/issues/243 + # Problems with using ECDSA known_hosts keys when negotiation also + # accepts RSA or DSS keys + try: + issue_url = 'https://api.github.com/repos/paramiko/paramiko/issues/243' + issue = json.load(download.url_open(issue_url)) + self.assertEqual(issue['state'], 'open', 'The issue %s is not open ' + 'anymore. Please double check and, if already fixed, ' + 'change the avocado.conf option ' + '"reject_unknown_hosts" defaults to True.' % + 'https://github.com/paramiko/paramiko/issues/243') + except download.urllib2.URLError as details: + raise unittest.SkipTest(details) + +if __name__ == '__main__': + unittest.main()