From: Aaron Zauner <[email protected]>

OpenSSH has, for a while now, supported SSH keys with Ed25519. Host keys
are currently unsupported in Debian Jessie, but that might change in the
future. Thus these functions have been commented-out.

Signed-off-by: Aaron Zauner <[email protected]>
Signed-off-by: Brian Foley <[email protected]>
---
 lib/ssh.py                                         |  3 +++
 src/Ganeti/Constants.hs                            | 13 ++++++++++++-
 src/Ganeti/Types.hs                                |  1 +
 test/hs/Test/Ganeti/Objects.hs                     |  1 +
 test/py/ganeti.ssh_unittest.py                     |  8 ++++++++
 test/py/ganeti.tools.prepare_node_join_unittest.py | 12 ++++++++++++
 6 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/lib/ssh.py b/lib/ssh.py
index a8fe86d..38137a9 100644
--- a/lib/ssh.py
+++ b/lib/ssh.py
@@ -86,6 +86,8 @@ def GetUserFiles(user, mkdir=False, dircheck=True, 
kind=constants.SSHK_DSA,
     suffix = "rsa"
   elif kind == constants.SSHK_ECDSA:
     suffix = "ecdsa"
+  elif kind == constants.SSHK_ED25519:
+    suffix = "ed25519"
   else:
     raise errors.ProgrammerError("Unknown SSH key kind '%s'" % kind)
 
@@ -1106,6 +1108,7 @@ SSH_KEY_VALID_BITS = {
   constants.SSHK_DSA: KeyBitInfo(1024, lambda b: b == 1024),
   constants.SSHK_RSA: KeyBitInfo(2048, lambda b: b >= 768),
   constants.SSHK_ECDSA: KeyBitInfo(384, lambda b: b in [256, 384, 521]),
+  constants.SSHK_ED25519: KeyBitInfo(256, lambda b: b == 256),
 }
 
 
diff --git a/src/Ganeti/Constants.hs b/src/Ganeti/Constants.hs
index 420ccb6..3492a31 100644
--- a/src/Ganeti/Constants.hs
+++ b/src/Ganeti/Constants.hs
@@ -4693,8 +4693,11 @@ sshkEcdsa = Types.sshKeyTypeToRaw ECDSA
 sshkRsa :: String
 sshkRsa = Types.sshKeyTypeToRaw RSA
 
+sshkEd25519 :: String
+sshkEd25519 = Types.sshKeyTypeToRaw Ed25519
+
 sshkAll :: FrozenSet String
-sshkAll = ConstantUtils.mkSet [sshkRsa, sshkDsa, sshkEcdsa]
+sshkAll = ConstantUtils.mkSet [sshkRsa, sshkDsa, sshkEcdsa, sshkEd25519]
 
 -- * SSH authorized key types
 
@@ -4792,6 +4795,13 @@ sshHostEcdsaPriv = sshConfigDir ++ "/ssh_host_ecdsa_key"
 sshHostEcdsaPub :: String
 sshHostEcdsaPub = sshHostEcdsaPriv ++ ".pub"
 
+-- Ed25519 Host Keys are not supported by Debian < 8.0
+-- sshHostEd25519Priv :: String
+-- sshHostEd25519Priv = sshConfigDir ++ "/ssh_host_ed25519_key"
+
+-- sshHostEd25519Pub :: String
+-- sshHostEd25519Pub = sshHostEd25519Priv ++ ".pub"
+
 sshHostRsaPriv :: String
 sshHostRsaPriv = sshConfigDir ++ "/ssh_host_rsa_key"
 
@@ -4803,6 +4813,7 @@ sshDaemonKeyfiles =
   Map.fromList [ (sshkRsa, (sshHostRsaPriv, sshHostRsaPub))
                , (sshkDsa, (sshHostDsaPriv, sshHostDsaPub))
                , (sshkEcdsa, (sshHostEcdsaPriv, sshHostEcdsaPub))
+               -- sshHostEd25519Priv,
                ]
 
 -- * Node daemon setup
diff --git a/src/Ganeti/Types.hs b/src/Ganeti/Types.hs
index 318127e..2443dfe 100644
--- a/src/Ganeti/Types.hs
+++ b/src/Ganeti/Types.hs
@@ -961,6 +961,7 @@ $(THH.declareLADT ''String "SshKeyType"
   [ ("RSA", "rsa")
   , ("DSA", "dsa")
   , ("ECDSA", "ecdsa")
+  , ("Ed25519", "ed25519")
   ])
 $(THH.makeJSONInstance ''SshKeyType)
 
diff --git a/test/hs/Test/Ganeti/Objects.hs b/test/hs/Test/Ganeti/Objects.hs
index 76543da..2bdf66b 100644
--- a/test/hs/Test/Ganeti/Objects.hs
+++ b/test/hs/Test/Ganeti/Objects.hs
@@ -387,6 +387,7 @@ instance Arbitrary SshKeyType where
     [ pure RSA
     , pure DSA
     , pure ECDSA
+    , pure Ed25519
     ]
 
 -- | Generates a network instance with minimum netmasks of /24. Generating
diff --git a/test/py/ganeti.ssh_unittest.py b/test/py/ganeti.ssh_unittest.py
index 265adec..fffb846 100755
--- a/test/py/ganeti.ssh_unittest.py
+++ b/test/py/ganeti.ssh_unittest.py
@@ -150,6 +150,9 @@ class TestGetUserFiles(unittest.TestCase):
         constants.SSHK_ECDSA:
           (os.path.join(self.tmpdir, ".ssh", "id_ecdsa"),
            os.path.join(self.tmpdir, ".ssh", "id_ecdsa.pub")),
+        constants.SSHK_ED25519:
+          (os.path.join(self.tmpdir, ".ssh", "id_ed25519"),
+           os.path.join(self.tmpdir, ".ssh", "id_ed25519.pub")),
       }))
     self.assertEqual(os.listdir(self.tmpdir), [])
 
@@ -513,6 +516,11 @@ class TestDetermineKeyBits():
     for b in [256, 384, 521]:
       self.assertEquals(b, DetermineKeyBits("ecdsa", b, None, None))
 
+  def testEd25519SpecificValues(self):
+    self.assertRaises(errors.OpPrereqError, ssh.DetermineKeyBits, "ed25519", 
256,
+                      None, None)
+    self.assertEquals(b, ssh.DetermineKeyBits("ed25519", b, None, None))
+
   def testRsaSpecificValues(self):
     self.assertRaises(errors.OpPrereqError, DetermineKeyBits, "dsa", 766,
                       None, None)
diff --git a/test/py/ganeti.tools.prepare_node_join_unittest.py 
b/test/py/ganeti.tools.prepare_node_join_unittest.py
index 7901199..5c33488 100755
--- a/test/py/ganeti.tools.prepare_node_join_unittest.py
+++ b/test/py/ganeti.tools.prepare_node_join_unittest.py
@@ -102,6 +102,10 @@ class TestUpdateSshDaemon(unittest.TestCase):
       constants.SSHK_ECDSA:
         (utils.PathJoin(self.tmpdir, "ecdsa.private"),
          utils.PathJoin(self.tmpdir, "ecdsa.public")),
+      # No Ed25519 Host-key support in Debian <8.0
+      #constants.SSHK_Ed25519:
+      #  (utils.PathJoin(self.tmpdir, "ed25519.private"),
+      #   utils.PathJoin(self.tmpdir, "ed25519.public")),
       }
 
   def tearDown(self):
@@ -146,6 +150,14 @@ class TestUpdateSshDaemon(unittest.TestCase):
         ],
       })
 
+  # No Ed25519 SSH Host Key support in Debian < 8.0
+  #def testDryRunEd25519(self):
+  #  self._TestDryRun({
+  #    constants.SSHS_SSH_HOST_KEY: [
+  #      (constants.SSHK_ED25519, "ed25519priv", "ed25519pub"),
+  #      ],
+  #    })
+
   def _RunCmd(self, fail, cmd, interactive=NotImplemented):
     self.assertTrue(interactive)
     self.assertEqual(cmd, [pathutils.DAEMON_UTIL, "reload-ssh-keys"])
-- 
2.8.0.rc3.226.g39d4020

Reply via email to