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