keys: Allow for pushing of Paramiko PEM format keys
End users don't really have a good way of using MDT if they can't push
additional MDT public keys. This adds functionality to generate a public key
line in a generic way and push Paramiko keys to the boards in the same way
OpenSSH public keys are pushed.
Change-Id: Ifdec1f4cea1d2934c07afa00e0b19c25962d368b
diff --git a/mdt/keys.py b/mdt/keys.py
index 964ee78..7864266 100644
--- a/mdt/keys.py
+++ b/mdt/keys.py
@@ -38,6 +38,12 @@
KEYFILE_PATH = os.path.join(config.CONFIG_BASEDIR, "keys", "mdt.key")
+def GenerateAuthorizedKeysLine(paramiko_key):
+ public_key = paramiko_key.get_base64()
+ authorized_keys_line = 'ssh-rsa {0} mdt'.format(public_key)
+ return authorized_keys_line
+
+
class Keystore:
def __init__(self):
if not os.path.exists(config.CONFIG_BASEDIR):
diff --git a/mdt/shell.py b/mdt/shell.py
index cef6128..313c79a 100644
--- a/mdt/shell.py
+++ b/mdt/shell.py
@@ -126,8 +126,9 @@
'''Usage: mdt pushkey [<path-to-ssh-public-key>]
Copies an SSH public key provided to the device's ~/.ssh/authorized_keys
-file. If no public key is provided, attempts to push MDTs previously generated
-public key from ~/.config/mdt/keys/mdt.key.
+file. If an MDT private key is provided, will push the public half of that key
+to the device's authorized_keys file. If no public key is provided, attempts to
+push MDTs previously generated public key from ~/.config/mdt/keys/mdt.key.
'''
def _pushMdtKey(self, client):
@@ -153,6 +154,12 @@
sftp.mkdir('/home/mendel/.ssh', mode=0o700)
with sftp.open('/home/mendel/.ssh/authorized_keys', 'a+b') as fp:
+ # Paramiko RSA private key -- get the public part by converting
+ if source_key.startswith('-----BEGIN RSA PRIVATE KEY-----'):
+ keyfp = io.StringIO(source_key)
+ pkey = RSAKey.from_private_key_file(keyfp)
+ source_key = keys.GenerateAuthorizedKeysLine(pkey)
+
fp.write('\r\n')
fp.write(source_key)
diff --git a/mdt/sshclient.py b/mdt/sshclient.py
index 270f758..9f4455d 100644
--- a/mdt/sshclient.py
+++ b/mdt/sshclient.py
@@ -79,11 +79,6 @@
finally:
self.client.close()
- def _generateAuthorizedKeysLine(self):
- public_key = self.keystore.key().get_base64()
- authorized_keys_line = 'ssh-rsa {0} mdt'.format(public_key)
- return authorized_keys_line
-
def _pushKeyViaKeymaster(self):
if not self.address:
raise discoverer.DeviceNotFoundError()
@@ -93,7 +88,7 @@
connection = http.client.HTTPConnection(self.address, KEYMASTER_PORT)
try:
- key_line = self._generateAuthorizedKeysLine()
+ key_line = keys.GenerateAuthorizedKeysLine(self.keystore.key())
connection.request('PUT', '/', key_line + '\r\n')
response = connection.getresponse()
except ConnectionRefusedError as e:
@@ -102,10 +97,15 @@
print()
print("Did you previously connect from a different machine? If so,\n"
"mdt-keymaster will not be running as it only accepts a single key.\n")
- print("You will need to either remove the key from ~/.ssh/authorized_keys\n"
- "via some other method (serial console, etc), or you will need to\n"
- "connect from the other machine to push an SSH public key to the\n"
- "authorized_keys file.")
+ print("You will need to either:\n"
+ " 1) Remove the key from /home/mendel/.ssh/authorized_keys on the\n"
+ " device via the serial console and then restart mdt-keymaster\n"
+ " by running 'sudo systemctl restart mdt-keymaster'\n"
+ "\n- or -\n\n"
+ " 2) Copy the mdt private key from your home directory on this host\n"
+ " in ~/.config/mdt/keys/mdt.key to the first machine and use\n"
+ " 'mdt pushkey mdt.key' to add that key to the device's\n"
+ " authorized_keys file.")
print()
raise KeyPushError(e)
except ConnectionError as e: