qemu/tests/qemu-iotests/207
<<
>>
Prefs
   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    if isinstance(qmsg, str):
  39        # Strip key type and fingerprint
  40        p = r"\S+ (key fingerprint) '(md5|sha1|sha256):[0-9a-f]+'"
  41        return re.sub(p, r"\1 '\2:HASH'", qmsg)
  42    else:
  43        return iotests.filter_qmp(qmsg, _filter)
  44
  45def blockdev_create(vm, options):
  46    vm.blockdev_create(options, filters=[iotests.filter_qmp_testfiles, filter_hash])
  47
  48with iotests.FilePath('t.img') as disk_path, \
  49     iotests.VM() as vm:
  50
  51    remote_path = iotests.remote_filename(disk_path)
  52
  53    #
  54    # Successful image creation (defaults)
  55    #
  56    iotests.log("=== Successful image creation (defaults) ===")
  57    iotests.log("")
  58
  59    vm.launch()
  60    blockdev_create(vm, { 'driver': 'ssh',
  61                          'location': {
  62                              'path': disk_path,
  63                              'server': {
  64                                  'host': '127.0.0.1',
  65                                  'port': '22'
  66                              }
  67                          },
  68                          'size': 4194304 })
  69    vm.shutdown()
  70
  71    iotests.img_info_log(remote_path)
  72    iotests.log("")
  73    iotests.img_info_log(disk_path)
  74
  75    #
  76    # Test host-key-check options
  77    #
  78    iotests.log("=== Test host-key-check options ===")
  79    iotests.log("")
  80
  81    iotests.log("--- no host key checking --")
  82    iotests.log("")
  83
  84    vm.launch()
  85    blockdev_create(vm, { 'driver': 'ssh',
  86                          'location': {
  87                              'path': disk_path,
  88                              'server': {
  89                                  'host': '127.0.0.1',
  90                                  'port': '22'
  91                              },
  92                              'host-key-check': {
  93                                  'mode': 'none'
  94                              }
  95                          },
  96                          'size': 8388608 })
  97    vm.shutdown()
  98
  99    iotests.img_info_log(remote_path)
 100
 101    iotests.log("--- known_hosts key checking --")
 102    iotests.log("")
 103
 104    vm.launch()
 105    blockdev_create(vm, { 'driver': 'ssh',
 106                          'location': {
 107                              'path': disk_path,
 108                              'server': {
 109                                  'host': '127.0.0.1',
 110                                  'port': '22'
 111                              },
 112                              'host-key-check': {
 113                                  'mode': 'known_hosts'
 114                              }
 115                          },
 116                          'size': 4194304 })
 117    vm.shutdown()
 118
 119    iotests.img_info_log(remote_path)
 120
 121    keys = subprocess.check_output(
 122        'ssh-keyscan 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
 123        'cut -d" " -f3',
 124        shell=True).rstrip().decode('ascii').split('\n')
 125
 126    # Mappings of base64 representations to digests
 127    md5_keys = {}
 128    sha1_keys = {}
 129    sha256_keys = {}
 130
 131    for key in keys:
 132        md5_keys[key] = subprocess.check_output(
 133            'echo %s | base64 -d | md5sum -b | cut -d" " -f1' % key,
 134            shell=True).rstrip().decode('ascii')
 135
 136        sha1_keys[key] = subprocess.check_output(
 137            'echo %s | base64 -d | sha1sum -b | cut -d" " -f1' % key,
 138            shell=True).rstrip().decode('ascii')
 139
 140        sha256_keys[key] = subprocess.check_output(
 141            'echo %s | base64 -d | sha256sum -b | cut -d" " -f1' % key,
 142            shell=True).rstrip().decode('ascii')
 143
 144    vm.launch()
 145
 146    # Find correct key first
 147    matching_key = None
 148    for key in keys:
 149        result = vm.qmp('blockdev-add',
 150                        driver='ssh', node_name='node0', path=disk_path,
 151                        server={
 152                             'host': '127.0.0.1',
 153                             'port': '22',
 154                        }, host_key_check={
 155                             'mode': 'hash',
 156                             'type': 'md5',
 157                             'hash': md5_keys[key],
 158                        })
 159
 160        if 'error' not in result:
 161            vm.qmp('blockdev-del', node_name='node0')
 162            matching_key = key
 163            break
 164
 165    if matching_key is None:
 166        vm.shutdown()
 167        iotests.notrun('Did not find a key that fits 127.0.0.1')
 168
 169    iotests.log("--- explicit md5 key checking --")
 170    iotests.log("")
 171
 172    blockdev_create(vm, { 'driver': 'ssh',
 173                          'location': {
 174                              'path': disk_path,
 175                              'server': {
 176                                  'host': '127.0.0.1',
 177                                  'port': '22'
 178                              },
 179                              'host-key-check': {
 180                                  'mode': 'hash',
 181                                  'type': 'md5',
 182                                  'hash': 'wrong',
 183                              }
 184                          },
 185                          'size': 2097152 })
 186
 187    blockdev_create(vm, { 'driver': 'ssh',
 188                          'location': {
 189                              'path': disk_path,
 190                              'server': {
 191                                  'host': '127.0.0.1',
 192                                  'port': '22'
 193                              },
 194                              'host-key-check': {
 195                                  'mode': 'hash',
 196                                  'type': 'md5',
 197                                  'hash': md5_keys[matching_key],
 198                              }
 199                          },
 200                          'size': 8388608 })
 201    vm.shutdown()
 202
 203    iotests.img_info_log(remote_path)
 204
 205    iotests.log("--- explicit sha1 key checking --")
 206    iotests.log("")
 207
 208    vm.launch()
 209    blockdev_create(vm, { 'driver': 'ssh',
 210                          'location': {
 211                              'path': disk_path,
 212                              'server': {
 213                                  'host': '127.0.0.1',
 214                                  'port': '22'
 215                              },
 216                              'host-key-check': {
 217                                  'mode': 'hash',
 218                                  'type': 'sha1',
 219                                  'hash': 'wrong',
 220                              }
 221                          },
 222                          'size': 2097152 })
 223    blockdev_create(vm, { 'driver': 'ssh',
 224                          'location': {
 225                              'path': disk_path,
 226                              'server': {
 227                                  'host': '127.0.0.1',
 228                                  'port': '22'
 229                              },
 230                              'host-key-check': {
 231                                  'mode': 'hash',
 232                                  'type': 'sha1',
 233                                  'hash': sha1_keys[matching_key],
 234                              }
 235                          },
 236                          'size': 4194304 })
 237    vm.shutdown()
 238
 239    iotests.img_info_log(remote_path)
 240
 241    iotests.log("--- explicit sha256 key checking --")
 242    iotests.log("")
 243
 244    vm.launch()
 245    blockdev_create(vm, { 'driver': 'ssh',
 246                          'location': {
 247                              'path': disk_path,
 248                              'server': {
 249                                  'host': '127.0.0.1',
 250                                  'port': '22'
 251                              },
 252                              'host-key-check': {
 253                                  'mode': 'hash',
 254                                  'type': 'sha256',
 255                                  'hash': 'wrong',
 256                              }
 257                          },
 258                          'size': 2097152 })
 259    blockdev_create(vm, { 'driver': 'ssh',
 260                          'location': {
 261                              'path': disk_path,
 262                              'server': {
 263                                  'host': '127.0.0.1',
 264                                  'port': '22'
 265                              },
 266                              'host-key-check': {
 267                                  'mode': 'hash',
 268                                  'type': 'sha256',
 269                                  'hash': sha256_keys[matching_key],
 270                              }
 271                          },
 272                          'size': 4194304 })
 273    vm.shutdown()
 274
 275    iotests.img_info_log(remote_path)
 276
 277    #
 278    # Invalid path and user
 279    #
 280    iotests.log("=== Invalid path and user ===")
 281    iotests.log("")
 282
 283    vm.launch()
 284    blockdev_create(vm, { 'driver': 'ssh',
 285                          'location': {
 286                              'path': '/this/is/not/an/existing/path',
 287                              'server': {
 288                                  'host': '127.0.0.1',
 289                                  'port': '22'
 290                              },
 291                              'host-key-check': {
 292                                  'mode': 'none'
 293                              }
 294                          },
 295                          'size': 4194304 })
 296    blockdev_create(vm, { 'driver': 'ssh',
 297                          'location': {
 298                              'path': disk_path,
 299                              'user': 'invalid user',
 300                              'server': {
 301                                  'host': '127.0.0.1',
 302                                  'port': '22'
 303                              },
 304                              'host-key-check': {
 305                                  'mode': 'none'
 306                              }
 307                          },
 308                          'size': 4194304 })
 309    vm.shutdown()
 310