1#!/usr/bin/env python3 2# 3# Test ssh image creation 4# 5# Copyright (C) 2018 Red Hat, Inc. 6# 7# Creator/Owner: Kevin Wolf <kwolf@redhat.com> 8# 9# This program is free software; you can redistribute it and/or modify 10# it under the terms of the GNU General Public License as published by 11# the Free Software Foundation; either version 2 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License for more details. 18# 19# You should have received a copy of the GNU General Public License 20# along with this program. If not, see <http://www.gnu.org/licenses/>. 21# 22 23import iotests 24import subprocess 25import re 26 27iotests.script_initialize( 28 supported_fmts=['raw'], 29 supported_protocols=['ssh'], 30) 31 32def filter_hash(qmsg): 33 def _filter(key, value): 34 if key == 'hash' and re.match('[0-9a-f]+', value): 35 return 'HASH' 36 return value 37 return iotests.filter_qmp(qmsg, _filter) 38 39def blockdev_create(vm, options): 40 vm.blockdev_create(options, filters=[iotests.filter_qmp_testfiles, filter_hash]) 41 42with iotests.FilePath('t.img') as disk_path, \ 43 iotests.VM() as vm: 44 45 remote_path = iotests.remote_filename(disk_path) 46 47 # 48 # Successful image creation (defaults) 49 # 50 iotests.log("=== Successful image creation (defaults) ===") 51 iotests.log("") 52 53 vm.launch() 54 blockdev_create(vm, { 'driver': 'ssh', 55 'location': { 56 'path': disk_path, 57 'server': { 58 'host': '127.0.0.1', 59 'port': '22' 60 } 61 }, 62 'size': 4194304 }) 63 vm.shutdown() 64 65 iotests.img_info_log(remote_path) 66 iotests.log("") 67 iotests.img_info_log(disk_path) 68 69 # 70 # Test host-key-check options 71 # 72 iotests.log("=== Test host-key-check options ===") 73 iotests.log("") 74 75 vm.launch() 76 blockdev_create(vm, { 'driver': 'ssh', 77 'location': { 78 'path': disk_path, 79 'server': { 80 'host': '127.0.0.1', 81 'port': '22' 82 }, 83 'host-key-check': { 84 'mode': 'none' 85 } 86 }, 87 'size': 8388608 }) 88 vm.shutdown() 89 90 iotests.img_info_log(remote_path) 91 92 vm.launch() 93 blockdev_create(vm, { 'driver': 'ssh', 94 'location': { 95 'path': disk_path, 96 'server': { 97 'host': '127.0.0.1', 98 'port': '22' 99 }, 100 'host-key-check': { 101 'mode': 'known_hosts' 102 } 103 }, 104 'size': 4194304 }) 105 vm.shutdown() 106 107 iotests.img_info_log(remote_path) 108 109 keys = subprocess.check_output( 110 'ssh-keyscan 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' + 111 'cut -d" " -f3', 112 shell=True).rstrip().decode('ascii').split('\n') 113 114 # Mappings of base64 representations to digests 115 md5_keys = {} 116 sha1_keys = {} 117 118 for key in keys: 119 md5_keys[key] = subprocess.check_output( 120 'echo %s | base64 -d | md5sum -b | cut -d" " -f1' % key, 121 shell=True).rstrip().decode('ascii') 122 123 sha1_keys[key] = subprocess.check_output( 124 'echo %s | base64 -d | sha1sum -b | cut -d" " -f1' % key, 125 shell=True).rstrip().decode('ascii') 126 127 vm.launch() 128 129 # Find correct key first 130 matching_key = None 131 for key in keys: 132 result = vm.qmp('blockdev-add', 133 driver='ssh', node_name='node0', path=disk_path, 134 server={ 135 'host': '127.0.0.1', 136 'port': '22', 137 }, host_key_check={ 138 'mode': 'hash', 139 'type': 'md5', 140 'hash': md5_keys[key], 141 }) 142 143 if 'error' not in result: 144 vm.qmp('blockdev-del', node_name='node0') 145 matching_key = key 146 break 147 148 if matching_key is None: 149 vm.shutdown() 150 iotests.notrun('Did not find a key that fits 127.0.0.1') 151 152 blockdev_create(vm, { 'driver': 'ssh', 153 'location': { 154 'path': disk_path, 155 'server': { 156 'host': '127.0.0.1', 157 'port': '22' 158 }, 159 'host-key-check': { 160 'mode': 'hash', 161 'type': 'md5', 162 'hash': 'wrong', 163 } 164 }, 165 'size': 2097152 }) 166 blockdev_create(vm, { 'driver': 'ssh', 167 'location': { 168 'path': disk_path, 169 'server': { 170 'host': '127.0.0.1', 171 'port': '22' 172 }, 173 'host-key-check': { 174 'mode': 'hash', 175 'type': 'md5', 176 'hash': md5_keys[matching_key], 177 } 178 }, 179 'size': 8388608 }) 180 vm.shutdown() 181 182 iotests.img_info_log(remote_path) 183 184 vm.launch() 185 blockdev_create(vm, { 'driver': 'ssh', 186 'location': { 187 'path': disk_path, 188 'server': { 189 'host': '127.0.0.1', 190 'port': '22' 191 }, 192 'host-key-check': { 193 'mode': 'hash', 194 'type': 'sha1', 195 'hash': 'wrong', 196 } 197 }, 198 'size': 2097152 }) 199 blockdev_create(vm, { 'driver': 'ssh', 200 'location': { 201 'path': disk_path, 202 'server': { 203 'host': '127.0.0.1', 204 'port': '22' 205 }, 206 'host-key-check': { 207 'mode': 'hash', 208 'type': 'sha1', 209 'hash': sha1_keys[matching_key], 210 } 211 }, 212 'size': 4194304 }) 213 vm.shutdown() 214 215 iotests.img_info_log(remote_path) 216 217 # 218 # Invalid path and user 219 # 220 iotests.log("=== Invalid path and user ===") 221 iotests.log("") 222 223 vm.launch() 224 blockdev_create(vm, { 'driver': 'ssh', 225 'location': { 226 'path': '/this/is/not/an/existing/path', 227 'server': { 228 'host': '127.0.0.1', 229 'port': '22' 230 }, 231 'host-key-check': { 232 'mode': 'none' 233 } 234 }, 235 'size': 4194304 }) 236 blockdev_create(vm, { 'driver': 'ssh', 237 'location': { 238 'path': disk_path, 239 'user': 'invalid user', 240 'server': { 241 'host': '127.0.0.1', 242 'port': '22' 243 }, 244 'host-key-check': { 245 'mode': 'none' 246 } 247 }, 248 'size': 4194304 }) 249 vm.shutdown() 250