tap.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # -*- test-case-name: twisted.conch.test.test_tap -*-
  2. # Copyright (c) Twisted Matrix Laboratories.
  3. # See LICENSE for details.
  4. """
  5. Support module for making SSH servers with twistd.
  6. """
  7. from twisted.application import strports
  8. from twisted.conch import checkers as conch_checkers, unix
  9. from twisted.conch.openssh_compat import factory
  10. from twisted.cred import portal, strcred
  11. from twisted.python import usage
  12. class Options(usage.Options, strcred.AuthOptionMixin):
  13. synopsis = "[-i <interface>] [-p <port>] [-d <dir>] "
  14. longdesc = (
  15. "Makes a Conch SSH server. If no authentication methods are "
  16. "specified, the default authentication methods are UNIX passwords "
  17. "and SSH public keys. If --auth options are "
  18. "passed, only the measures specified will be used."
  19. )
  20. optParameters = [
  21. ["interface", "i", "", "local interface to which we listen"],
  22. ["port", "p", "tcp:22", "Port on which to listen"],
  23. ["data", "d", "/etc", "directory to look for host keys in"],
  24. [
  25. "moduli",
  26. "",
  27. None,
  28. "directory to look for moduli in " "(if different from --data)",
  29. ],
  30. ]
  31. compData = usage.Completions(
  32. optActions={
  33. "data": usage.CompleteDirs(descr="data directory"),
  34. "moduli": usage.CompleteDirs(descr="moduli directory"),
  35. "interface": usage.CompleteNetInterfaces(),
  36. }
  37. )
  38. def __init__(self, *a, **kw):
  39. usage.Options.__init__(self, *a, **kw)
  40. # Call the default addCheckers (for backwards compatibility) that will
  41. # be used if no --auth option is provided - note that conch's
  42. # UNIXPasswordDatabase is used, instead of twisted.plugins.cred_unix's
  43. # checker
  44. super().addChecker(conch_checkers.UNIXPasswordDatabase())
  45. super().addChecker(
  46. conch_checkers.SSHPublicKeyChecker(conch_checkers.UNIXAuthorizedKeysFiles())
  47. )
  48. self._usingDefaultAuth = True
  49. def addChecker(self, checker):
  50. """
  51. Add the checker specified. If any checkers are added, the default
  52. checkers are automatically cleared and the only checkers will be the
  53. specified one(s).
  54. """
  55. if self._usingDefaultAuth:
  56. self["credCheckers"] = []
  57. self["credInterfaces"] = {}
  58. self._usingDefaultAuth = False
  59. super().addChecker(checker)
  60. def makeService(config):
  61. """
  62. Construct a service for operating a SSH server.
  63. @param config: An L{Options} instance specifying server options, including
  64. where server keys are stored and what authentication methods to use.
  65. @return: A L{twisted.application.service.IService} provider which contains
  66. the requested SSH server.
  67. """
  68. t = factory.OpenSSHFactory()
  69. r = unix.UnixSSHRealm()
  70. t.portal = portal.Portal(r, config.get("credCheckers", []))
  71. t.dataRoot = config["data"]
  72. t.moduliRoot = config["moduli"] or config["data"]
  73. port = config["port"]
  74. if config["interface"]:
  75. # Add warning here
  76. port += ":interface=" + config["interface"]
  77. return strports.service(port, t)