17c477526SPhilippe Mathieu-Daudé#!/usr/bin/env python3 29dd003a9SVladimir Sementsov-Ogievskiy# group: rw 356ea7450SKevin Wolf# 456ea7450SKevin Wolf# Test ssh image creation 556ea7450SKevin Wolf# 656ea7450SKevin Wolf# Copyright (C) 2018 Red Hat, Inc. 756ea7450SKevin Wolf# 800af1935SKevin Wolf# Creator/Owner: Kevin Wolf <kwolf@redhat.com> 900af1935SKevin Wolf# 1056ea7450SKevin Wolf# This program is free software; you can redistribute it and/or modify 1156ea7450SKevin Wolf# it under the terms of the GNU General Public License as published by 1256ea7450SKevin Wolf# the Free Software Foundation; either version 2 of the License, or 1356ea7450SKevin Wolf# (at your option) any later version. 1456ea7450SKevin Wolf# 1556ea7450SKevin Wolf# This program is distributed in the hope that it will be useful, 1656ea7450SKevin Wolf# but WITHOUT ANY WARRANTY; without even the implied warranty of 1756ea7450SKevin Wolf# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1856ea7450SKevin Wolf# GNU General Public License for more details. 1956ea7450SKevin Wolf# 2056ea7450SKevin Wolf# You should have received a copy of the GNU General Public License 2156ea7450SKevin Wolf# along with this program. If not, see <http://www.gnu.org/licenses/>. 2256ea7450SKevin Wolf# 2356ea7450SKevin Wolf 2400af1935SKevin Wolfimport iotests 2500af1935SKevin Wolfimport subprocess 2600af1935SKevin Wolfimport re 2756ea7450SKevin Wolf 287d814059SJohn Snowiotests.script_initialize( 297d814059SJohn Snow supported_fmts=['raw'], 307d814059SJohn Snow supported_protocols=['ssh'], 317d814059SJohn Snow) 3256ea7450SKevin Wolf 339ac10f2eSMax Reitzdef filter_hash(qmsg): 349ac10f2eSMax Reitz def _filter(key, value): 359ac10f2eSMax Reitz if key == 'hash' and re.match('[0-9a-f]+', value): 369ac10f2eSMax Reitz return 'HASH' 379ac10f2eSMax Reitz return value 38*48f1fcd5SHanna Reitz if isinstance(qmsg, str): 39*48f1fcd5SHanna Reitz # Strip key type and fingerprint 40*48f1fcd5SHanna Reitz p = r"\S+ (key fingerprint) '(md5|sha1|sha256):[0-9a-f]+'" 41*48f1fcd5SHanna Reitz return re.sub(p, r"\1 '\2:HASH'", qmsg) 42*48f1fcd5SHanna Reitz else: 439ac10f2eSMax Reitz return iotests.filter_qmp(qmsg, _filter) 4456ea7450SKevin Wolf 4500af1935SKevin Wolfdef blockdev_create(vm, options): 466055cdf3SKevin Wolf vm.blockdev_create(options, filters=[iotests.filter_qmp_testfiles, filter_hash]) 4756ea7450SKevin Wolf 4800af1935SKevin Wolfwith iotests.FilePath('t.img') as disk_path, \ 4900af1935SKevin Wolf iotests.VM() as vm: 5056ea7450SKevin Wolf 5100af1935SKevin Wolf remote_path = iotests.remote_filename(disk_path) 5256ea7450SKevin Wolf 5300af1935SKevin Wolf # 5400af1935SKevin Wolf # Successful image creation (defaults) 5500af1935SKevin Wolf # 5600af1935SKevin Wolf iotests.log("=== Successful image creation (defaults) ===") 5700af1935SKevin Wolf iotests.log("") 5856ea7450SKevin Wolf 5900af1935SKevin Wolf vm.launch() 6000af1935SKevin Wolf blockdev_create(vm, { 'driver': 'ssh', 6100af1935SKevin Wolf 'location': { 6200af1935SKevin Wolf 'path': disk_path, 6300af1935SKevin Wolf 'server': { 6400af1935SKevin Wolf 'host': '127.0.0.1', 6500af1935SKevin Wolf 'port': '22' 6656ea7450SKevin Wolf } 6756ea7450SKevin Wolf }, 6800af1935SKevin Wolf 'size': 4194304 }) 6900af1935SKevin Wolf vm.shutdown() 7056ea7450SKevin Wolf 71b8c1f901SMax Reitz iotests.img_info_log(remote_path) 7200af1935SKevin Wolf iotests.log("") 7300af1935SKevin Wolf iotests.img_info_log(disk_path) 7456ea7450SKevin Wolf 7500af1935SKevin Wolf # 7600af1935SKevin Wolf # Test host-key-check options 7700af1935SKevin Wolf # 7800af1935SKevin Wolf iotests.log("=== Test host-key-check options ===") 7900af1935SKevin Wolf iotests.log("") 8056ea7450SKevin Wolf 81bf783261SDaniel P. Berrangé iotests.log("--- no host key checking --") 82bf783261SDaniel P. Berrangé iotests.log("") 83bf783261SDaniel P. Berrangé 8400af1935SKevin Wolf vm.launch() 8500af1935SKevin Wolf blockdev_create(vm, { 'driver': 'ssh', 8600af1935SKevin Wolf 'location': { 8700af1935SKevin Wolf 'path': disk_path, 8800af1935SKevin Wolf 'server': { 8900af1935SKevin Wolf 'host': '127.0.0.1', 9000af1935SKevin Wolf 'port': '22' 9156ea7450SKevin Wolf }, 9200af1935SKevin Wolf 'host-key-check': { 9300af1935SKevin Wolf 'mode': 'none' 9456ea7450SKevin Wolf } 9556ea7450SKevin Wolf }, 9600af1935SKevin Wolf 'size': 8388608 }) 9700af1935SKevin Wolf vm.shutdown() 9856ea7450SKevin Wolf 99b8c1f901SMax Reitz iotests.img_info_log(remote_path) 10056ea7450SKevin Wolf 101bf783261SDaniel P. Berrangé iotests.log("--- known_hosts key checking --") 102bf783261SDaniel P. Berrangé iotests.log("") 103bf783261SDaniel P. Berrangé 10400af1935SKevin Wolf vm.launch() 10500af1935SKevin Wolf blockdev_create(vm, { 'driver': 'ssh', 10600af1935SKevin Wolf 'location': { 10700af1935SKevin Wolf 'path': disk_path, 10800af1935SKevin Wolf 'server': { 10900af1935SKevin Wolf 'host': '127.0.0.1', 11000af1935SKevin Wolf 'port': '22' 11156ea7450SKevin Wolf }, 11200af1935SKevin Wolf 'host-key-check': { 11300af1935SKevin Wolf 'mode': 'known_hosts' 11456ea7450SKevin Wolf } 11556ea7450SKevin Wolf }, 11600af1935SKevin Wolf 'size': 4194304 }) 11700af1935SKevin Wolf vm.shutdown() 11856ea7450SKevin Wolf 119b8c1f901SMax Reitz iotests.img_info_log(remote_path) 12056ea7450SKevin Wolf 121b10d49d7SPino Toscano keys = subprocess.check_output( 122b10d49d7SPino Toscano 'ssh-keyscan 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' + 123b10d49d7SPino Toscano 'cut -d" " -f3', 124b10d49d7SPino Toscano shell=True).rstrip().decode('ascii').split('\n') 125b10d49d7SPino Toscano 126b10d49d7SPino Toscano # Mappings of base64 representations to digests 127b10d49d7SPino Toscano md5_keys = {} 128b10d49d7SPino Toscano sha1_keys = {} 129bf783261SDaniel P. Berrangé sha256_keys = {} 130b10d49d7SPino Toscano 131b10d49d7SPino Toscano for key in keys: 132b10d49d7SPino Toscano md5_keys[key] = subprocess.check_output( 133b10d49d7SPino Toscano 'echo %s | base64 -d | md5sum -b | cut -d" " -f1' % key, 134b10d49d7SPino Toscano shell=True).rstrip().decode('ascii') 135b10d49d7SPino Toscano 136b10d49d7SPino Toscano sha1_keys[key] = subprocess.check_output( 137b10d49d7SPino Toscano 'echo %s | base64 -d | sha1sum -b | cut -d" " -f1' % key, 1388eb5e674SMax Reitz shell=True).rstrip().decode('ascii') 13956ea7450SKevin Wolf 140bf783261SDaniel P. Berrangé sha256_keys[key] = subprocess.check_output( 141bf783261SDaniel P. Berrangé 'echo %s | base64 -d | sha256sum -b | cut -d" " -f1' % key, 142bf783261SDaniel P. Berrangé shell=True).rstrip().decode('ascii') 143bf783261SDaniel P. Berrangé 14400af1935SKevin Wolf vm.launch() 145b10d49d7SPino Toscano 146b10d49d7SPino Toscano # Find correct key first 147b10d49d7SPino Toscano matching_key = None 148b10d49d7SPino Toscano for key in keys: 149b10d49d7SPino Toscano result = vm.qmp('blockdev-add', 150b10d49d7SPino Toscano driver='ssh', node_name='node0', path=disk_path, 151b10d49d7SPino Toscano server={ 152b10d49d7SPino Toscano 'host': '127.0.0.1', 153b10d49d7SPino Toscano 'port': '22', 154b10d49d7SPino Toscano }, host_key_check={ 155b10d49d7SPino Toscano 'mode': 'hash', 156b10d49d7SPino Toscano 'type': 'md5', 157b10d49d7SPino Toscano 'hash': md5_keys[key], 158b10d49d7SPino Toscano }) 159b10d49d7SPino Toscano 160b10d49d7SPino Toscano if 'error' not in result: 161b10d49d7SPino Toscano vm.qmp('blockdev-del', node_name='node0') 162b10d49d7SPino Toscano matching_key = key 163b10d49d7SPino Toscano break 164b10d49d7SPino Toscano 165b10d49d7SPino Toscano if matching_key is None: 166b10d49d7SPino Toscano vm.shutdown() 167b10d49d7SPino Toscano iotests.notrun('Did not find a key that fits 127.0.0.1') 168b10d49d7SPino Toscano 169bf783261SDaniel P. Berrangé iotests.log("--- explicit md5 key checking --") 170bf783261SDaniel P. Berrangé iotests.log("") 171bf783261SDaniel P. Berrangé 17200af1935SKevin Wolf blockdev_create(vm, { 'driver': 'ssh', 17300af1935SKevin Wolf 'location': { 17400af1935SKevin Wolf 'path': disk_path, 17500af1935SKevin Wolf 'server': { 17600af1935SKevin Wolf 'host': '127.0.0.1', 17700af1935SKevin Wolf 'port': '22' 17856ea7450SKevin Wolf }, 17900af1935SKevin Wolf 'host-key-check': { 18000af1935SKevin Wolf 'mode': 'hash', 18100af1935SKevin Wolf 'type': 'md5', 18200af1935SKevin Wolf 'hash': 'wrong', 18356ea7450SKevin Wolf } 18456ea7450SKevin Wolf }, 18500af1935SKevin Wolf 'size': 2097152 }) 186bf783261SDaniel P. Berrangé 18700af1935SKevin Wolf blockdev_create(vm, { 'driver': 'ssh', 18800af1935SKevin Wolf 'location': { 18900af1935SKevin Wolf 'path': disk_path, 19000af1935SKevin Wolf 'server': { 19100af1935SKevin Wolf 'host': '127.0.0.1', 19200af1935SKevin Wolf 'port': '22' 19356ea7450SKevin Wolf }, 19400af1935SKevin Wolf 'host-key-check': { 19500af1935SKevin Wolf 'mode': 'hash', 19600af1935SKevin Wolf 'type': 'md5', 197b10d49d7SPino Toscano 'hash': md5_keys[matching_key], 19856ea7450SKevin Wolf } 19956ea7450SKevin Wolf }, 20000af1935SKevin Wolf 'size': 8388608 }) 20100af1935SKevin Wolf vm.shutdown() 20256ea7450SKevin Wolf 203b8c1f901SMax Reitz iotests.img_info_log(remote_path) 20456ea7450SKevin Wolf 205bf783261SDaniel P. Berrangé iotests.log("--- explicit sha1 key checking --") 206bf783261SDaniel P. Berrangé iotests.log("") 207bf783261SDaniel P. Berrangé 20800af1935SKevin Wolf vm.launch() 20900af1935SKevin Wolf blockdev_create(vm, { 'driver': 'ssh', 21000af1935SKevin Wolf 'location': { 21100af1935SKevin Wolf 'path': disk_path, 21200af1935SKevin Wolf 'server': { 21300af1935SKevin Wolf 'host': '127.0.0.1', 21400af1935SKevin Wolf 'port': '22' 21556ea7450SKevin Wolf }, 21600af1935SKevin Wolf 'host-key-check': { 21700af1935SKevin Wolf 'mode': 'hash', 21800af1935SKevin Wolf 'type': 'sha1', 21900af1935SKevin Wolf 'hash': 'wrong', 22056ea7450SKevin Wolf } 22156ea7450SKevin Wolf }, 22200af1935SKevin Wolf 'size': 2097152 }) 22300af1935SKevin Wolf blockdev_create(vm, { 'driver': 'ssh', 22400af1935SKevin Wolf 'location': { 22500af1935SKevin Wolf 'path': disk_path, 22600af1935SKevin Wolf 'server': { 22700af1935SKevin Wolf 'host': '127.0.0.1', 22800af1935SKevin Wolf 'port': '22' 22956ea7450SKevin Wolf }, 23000af1935SKevin Wolf 'host-key-check': { 23100af1935SKevin Wolf 'mode': 'hash', 23200af1935SKevin Wolf 'type': 'sha1', 233b10d49d7SPino Toscano 'hash': sha1_keys[matching_key], 23456ea7450SKevin Wolf } 23556ea7450SKevin Wolf }, 23600af1935SKevin Wolf 'size': 4194304 }) 23700af1935SKevin Wolf vm.shutdown() 23856ea7450SKevin Wolf 239b8c1f901SMax Reitz iotests.img_info_log(remote_path) 24056ea7450SKevin Wolf 241bf783261SDaniel P. Berrangé iotests.log("--- explicit sha256 key checking --") 242bf783261SDaniel P. Berrangé iotests.log("") 243bf783261SDaniel P. Berrangé 244bf783261SDaniel P. Berrangé vm.launch() 245bf783261SDaniel P. Berrangé blockdev_create(vm, { 'driver': 'ssh', 246bf783261SDaniel P. Berrangé 'location': { 247bf783261SDaniel P. Berrangé 'path': disk_path, 248bf783261SDaniel P. Berrangé 'server': { 249bf783261SDaniel P. Berrangé 'host': '127.0.0.1', 250bf783261SDaniel P. Berrangé 'port': '22' 251bf783261SDaniel P. Berrangé }, 252bf783261SDaniel P. Berrangé 'host-key-check': { 253bf783261SDaniel P. Berrangé 'mode': 'hash', 254bf783261SDaniel P. Berrangé 'type': 'sha256', 255bf783261SDaniel P. Berrangé 'hash': 'wrong', 256bf783261SDaniel P. Berrangé } 257bf783261SDaniel P. Berrangé }, 258bf783261SDaniel P. Berrangé 'size': 2097152 }) 259bf783261SDaniel P. Berrangé blockdev_create(vm, { 'driver': 'ssh', 260bf783261SDaniel P. Berrangé 'location': { 261bf783261SDaniel P. Berrangé 'path': disk_path, 262bf783261SDaniel P. Berrangé 'server': { 263bf783261SDaniel P. Berrangé 'host': '127.0.0.1', 264bf783261SDaniel P. Berrangé 'port': '22' 265bf783261SDaniel P. Berrangé }, 266bf783261SDaniel P. Berrangé 'host-key-check': { 267bf783261SDaniel P. Berrangé 'mode': 'hash', 268bf783261SDaniel P. Berrangé 'type': 'sha256', 269bf783261SDaniel P. Berrangé 'hash': sha256_keys[matching_key], 270bf783261SDaniel P. Berrangé } 271bf783261SDaniel P. Berrangé }, 272bf783261SDaniel P. Berrangé 'size': 4194304 }) 273bf783261SDaniel P. Berrangé vm.shutdown() 274bf783261SDaniel P. Berrangé 275bf783261SDaniel P. Berrangé iotests.img_info_log(remote_path) 276bf783261SDaniel P. Berrangé 27700af1935SKevin Wolf # 27800af1935SKevin Wolf # Invalid path and user 27900af1935SKevin Wolf # 28000af1935SKevin Wolf iotests.log("=== Invalid path and user ===") 28100af1935SKevin Wolf iotests.log("") 28256ea7450SKevin Wolf 28300af1935SKevin Wolf vm.launch() 28400af1935SKevin Wolf blockdev_create(vm, { 'driver': 'ssh', 28500af1935SKevin Wolf 'location': { 28600af1935SKevin Wolf 'path': '/this/is/not/an/existing/path', 28700af1935SKevin Wolf 'server': { 28800af1935SKevin Wolf 'host': '127.0.0.1', 28900af1935SKevin Wolf 'port': '22' 29000af1935SKevin Wolf }, 29100af1935SKevin Wolf 'host-key-check': { 29200af1935SKevin Wolf 'mode': 'none' 29356ea7450SKevin Wolf } 29456ea7450SKevin Wolf }, 29500af1935SKevin Wolf 'size': 4194304 }) 29600af1935SKevin Wolf blockdev_create(vm, { 'driver': 'ssh', 29700af1935SKevin Wolf 'location': { 29800af1935SKevin Wolf 'path': disk_path, 29900af1935SKevin Wolf 'user': 'invalid user', 30000af1935SKevin Wolf 'server': { 30100af1935SKevin Wolf 'host': '127.0.0.1', 30200af1935SKevin Wolf 'port': '22' 30300af1935SKevin Wolf }, 30400af1935SKevin Wolf 'host-key-check': { 30500af1935SKevin Wolf 'mode': 'none' 30656ea7450SKevin Wolf } 30756ea7450SKevin Wolf }, 30800af1935SKevin Wolf 'size': 4194304 }) 30900af1935SKevin Wolf vm.shutdown() 310