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