Commit c2922ba4 authored by Thomas Gambier's avatar Thomas Gambier 🚴🏼

slaprunner: fix multiple SSH keys in authorized-keys

See merge request nexedi/slapos!834
parents 7f8fcb25 d80168bf
...@@ -18,7 +18,7 @@ md5sum = 8d6878ff1d2e75010c50a1a2b0c13b24 ...@@ -18,7 +18,7 @@ md5sum = 8d6878ff1d2e75010c50a1a2b0c13b24
[template-runner] [template-runner]
filename = instance-runner.cfg filename = instance-runner.cfg
md5sum = 4a3e1ee61f49909fe3fd0843cde1bebe md5sum = 6e279c46b07bf56b7b037a8ee2c6587e
[template-runner-import-script] [template-runner-import-script]
filename = template/runner-import.sh.jinja2 filename = template/runner-import.sh.jinja2
......
...@@ -650,7 +650,13 @@ monitor-interface-url = ...@@ -650,7 +650,13 @@ monitor-interface-url =
monitor-httpd-port = 8386 monitor-httpd-port = 8386
buildout-shared-folder = $${runnerdirectory:home}/shared buildout-shared-folder = $${runnerdirectory:home}/shared
{% for k, v in slapparameter_dict.items() -%} {% for k, v in slapparameter_dict.items() -%}
{% if k == 'user-authorized-key' and v -%}
{% set key_list = v.split('\n') -%}
{{ k }} =
{{ key_list | join('\n ') }}
{% else -%}
{{ k }} = {{ v }} {{ k }} = {{ v }}
{% endif -%}
{% endfor -%} {% endfor -%}
[slapos-cfg] [slapos-cfg]
......
...@@ -321,9 +321,11 @@ class TestWeb(SlaprunnerTestCase): ...@@ -321,9 +321,11 @@ class TestWeb(SlaprunnerTestCase):
class TestSSH(SlaprunnerTestCase): class TestSSH(SlaprunnerTestCase):
@classmethod @classmethod
def getInstanceParameterDict(cls): def getInstanceParameterDict(cls):
cls.ssh_key = paramiko.RSAKey.generate(1024) cls.ssh_key_list = [paramiko.RSAKey.generate(1024) for i in range(2)]
return { return {
'user-authorized-key': 'ssh-rsa {}'.format(cls.ssh_key.get_base64()) 'user-authorized-key': 'ssh-rsa {}\nssh-rsa {}'.format(
*[key.get_base64() for key in cls.ssh_key_list]
)
} }
def test_connect(self): def test_connect(self):
...@@ -355,43 +357,44 @@ class TestSSH(SlaprunnerTestCase): ...@@ -355,43 +357,44 @@ class TestSSH(SlaprunnerTestCase):
key_policy = KeyPolicy() key_policy = KeyPolicy()
client.set_missing_host_key_policy(key_policy) client.set_missing_host_key_policy(key_policy)
with contextlib.closing(client): for ssh_key in self.ssh_key_list:
client.connect( with contextlib.closing(client):
username=username, client.connect(
hostname=parsed.hostname, username=username,
port=parsed.port, hostname=parsed.hostname,
pkey=self.ssh_key, port=parsed.port,
) pkey=ssh_key,
# Check fingerprint from server matches the published one. )
# Paramiko does not allow to get the fingerprint as SHA256 easily yet # Check fingerprint from server matches the published one.
# https://github.com/paramiko/paramiko/pull/1103 # Paramiko does not allow to get the fingerprint as SHA256 easily yet
self.assertEqual( # https://github.com/paramiko/paramiko/pull/1103
fingerprint_from_url, self.assertEqual(
quote( fingerprint_from_url,
# base64 encoded fingerprint adds an extra = at the end quote(
base64.b64encode( # base64 encoded fingerprint adds an extra = at the end
hashlib.sha256(key_policy.key.asbytes()).digest())[:-1], base64.b64encode(
# also encode / hashlib.sha256(key_policy.key.asbytes()).digest())[:-1],
safe='')) # also encode /
safe=''))
# Check shell is usable
channel = client.invoke_shell() # Check shell is usable
channel.settimeout(30) channel = client.invoke_shell()
received = '' channel.settimeout(30)
while True: received = ''
r = bytes2str(channel.recv(1024)) while True:
self.logger.debug("received >%s<", r) r = bytes2str(channel.recv(1024))
if not r: self.logger.debug("received >%s<", r)
break if not r:
received += r break
if 'slaprunner shell' in received: received += r
break if 'slaprunner shell' in received:
self.assertIn("Welcome to SlapOS slaprunner shell", received) break
self.assertIn("Welcome to SlapOS slaprunner shell", received)
# simple commands can also be executed ( this would be like `ssh bash -c 'pwd'` )
self.assertEqual( # simple commands can also be executed ( this would be like `ssh bash -c 'pwd'` )
self.computer_partition_root_path, self.assertEqual(
bytes2str(client.exec_command("pwd")[1].read(1000)).strip()) self.computer_partition_root_path,
bytes2str(client.exec_command("pwd")[1].read(1000)).strip())
class TestSlapOS(SlaprunnerTestCase): class TestSlapOS(SlaprunnerTestCase):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment