factory.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. # -*- test-case-name: twisted.conch.test.test_openssh_compat -*-
  2. # Copyright (c) Twisted Matrix Laboratories.
  3. # See LICENSE for details.
  4. """
  5. Factory for reading openssh configuration files: public keys, private keys, and
  6. moduli file.
  7. """
  8. import os, errno
  9. from twisted.python import log
  10. from twisted.python.util import runAsEffectiveUser
  11. from twisted.conch.ssh import keys, factory, common
  12. from twisted.conch.openssh_compat import primes
  13. class OpenSSHFactory(factory.SSHFactory):
  14. dataRoot = '/usr/local/etc'
  15. # For openbsd which puts moduli in a different directory from keys.
  16. moduliRoot = '/usr/local/etc'
  17. def getPublicKeys(self):
  18. """
  19. Return the server public keys.
  20. """
  21. ks = {}
  22. for filename in os.listdir(self.dataRoot):
  23. if filename[:9] == 'ssh_host_' and filename[-8:]=='_key.pub':
  24. try:
  25. k = keys.Key.fromFile(
  26. os.path.join(self.dataRoot, filename))
  27. t = common.getNS(k.blob())[0]
  28. ks[t] = k
  29. except Exception as e:
  30. log.msg('bad public key file %s: %s' % (filename, e))
  31. return ks
  32. def getPrivateKeys(self):
  33. """
  34. Return the server private keys.
  35. """
  36. privateKeys = {}
  37. for filename in os.listdir(self.dataRoot):
  38. if filename[:9] == 'ssh_host_' and filename[-4:]=='_key':
  39. fullPath = os.path.join(self.dataRoot, filename)
  40. try:
  41. key = keys.Key.fromFile(fullPath)
  42. except IOError as e:
  43. if e.errno == errno.EACCES:
  44. # Not allowed, let's switch to root
  45. key = runAsEffectiveUser(
  46. 0, 0, keys.Key.fromFile, fullPath)
  47. privateKeys[key.sshType()] = key
  48. else:
  49. raise
  50. except Exception as e:
  51. log.msg('bad private key file %s: %s' % (filename, e))
  52. else:
  53. privateKeys[key.sshType()] = key
  54. return privateKeys
  55. def getPrimes(self):
  56. try:
  57. return primes.parseModuliFile(self.moduliRoot+'/moduli')
  58. except IOError:
  59. return None