1 # Copyright (c) Twisted Matrix Laboratories.
2 # See LICENSE for details.
5 Tests for L{twisted.conch.openssh_compat}.
10 from twisted.trial.unittest import TestCase
11 from twisted.python.filepath import FilePath
12 from twisted.python.compat import set
15 import Crypto.Cipher.DES3
20 from twisted.conch.openssh_compat.factory import OpenSSHFactory
22 from twisted.conch.test import keydata
23 from twisted.test.test_process import MockOS
26 class OpenSSHFactoryTests(TestCase):
28 Tests for L{OpenSSHFactory}.
30 if getattr(os, "geteuid", None) is None:
31 skip = "geteuid/seteuid not available"
32 elif OpenSSHFactory is None:
33 skip = "Cannot run without PyCrypto or PyASN1"
36 self.factory = OpenSSHFactory()
37 self.keysDir = FilePath(self.mktemp())
38 self.keysDir.makedirs()
39 self.factory.dataRoot = self.keysDir.path
41 self.keysDir.child("ssh_host_foo").setContent("foo")
42 self.keysDir.child("bar_key").setContent("foo")
43 self.keysDir.child("ssh_host_one_key").setContent(
44 keydata.privateRSA_openssh)
45 self.keysDir.child("ssh_host_two_key").setContent(
46 keydata.privateDSA_openssh)
47 self.keysDir.child("ssh_host_three_key").setContent(
50 self.keysDir.child("ssh_host_one_key.pub").setContent(
51 keydata.publicRSA_openssh)
53 self.mockos = MockOS()
54 self.patch(os, "seteuid", self.mockos.seteuid)
55 self.patch(os, "setegid", self.mockos.setegid)
58 def test_getPublicKeys(self):
60 L{OpenSSHFactory.getPublicKeys} should return the available public keys
63 keys = self.factory.getPublicKeys()
64 self.assertEqual(len(keys), 1)
65 keyTypes = keys.keys()
66 self.assertEqual(keyTypes, ['ssh-rsa'])
69 def test_getPrivateKeys(self):
71 L{OpenSSHFactory.getPrivateKeys} should return the available private
72 keys in the data directory.
74 keys = self.factory.getPrivateKeys()
75 self.assertEqual(len(keys), 2)
76 keyTypes = keys.keys()
77 self.assertEqual(set(keyTypes), set(['ssh-rsa', 'ssh-dss']))
78 self.assertEqual(self.mockos.seteuidCalls, [])
79 self.assertEqual(self.mockos.setegidCalls, [])
82 def test_getPrivateKeysAsRoot(self):
84 L{OpenSSHFactory.getPrivateKeys} should switch to root if the keys
85 aren't readable by the current user.
87 keyFile = self.keysDir.child("ssh_host_two_key")
88 # Fake permission error by changing the mode
90 self.addCleanup(keyFile.chmod, 0777)
91 # And restore the right mode when seteuid is called
92 savedSeteuid = os.seteuid
95 return savedSeteuid(euid)
96 self.patch(os, "seteuid", seteuid)
97 keys = self.factory.getPrivateKeys()
98 self.assertEqual(len(keys), 2)
99 keyTypes = keys.keys()
100 self.assertEqual(set(keyTypes), set(['ssh-rsa', 'ssh-dss']))
101 self.assertEqual(self.mockos.seteuidCalls, [0, os.geteuid()])
102 self.assertEqual(self.mockos.setegidCalls, [0, os.getegid()])