xref: /qemu/tests/qemu-iotests/207 (revision 2e8f72ac)
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