master
text 309 lines 10.5 KB
Raw
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
24 import iotests
25 import subprocess
26 import re
27
28 iotests.script_initialize(
29 supported_fmts=['raw'],
30 supported_protocols=['ssh'],
31 )
32
33 def 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
45 def blockdev_create(vm, options):
46 vm.blockdev_create(options, filters=[iotests.filter_qmp_testfiles, filter_hash])
47
48 with 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()