1
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
2
# See LICENSE for details.
5
TAP plugin for creating telnet- and ssh-accessible manhole servers.
10
from zope.interface import implements
12
from twisted.internet import protocol
13
from twisted.application import service, strports
14
from twisted.conch.ssh import session
15
from twisted.conch import interfaces as iconch
16
from twisted.cred import portal, checkers
17
from twisted.python import usage
19
from twisted.conch.insults import insults
20
from twisted.conch import manhole, manhole_ssh, telnet
22
class makeTelnetProtocol:
23
def __init__(self, portal):
27
auth = telnet.AuthenticatingTelnetProtocol
29
return telnet.TelnetTransport(auth, *args)
31
class chainedProtocolFactory:
32
def __init__(self, namespace):
33
self.namespace = namespace
36
return insults.ServerProtocol(manhole.ColoredManhole, self.namespace)
39
implements(portal.IRealm)
41
def __init__(self, proto, *a, **kw):
42
self.protocolFactory = proto
44
self.protocolKwArgs = kw
46
def requestAvatar(self, avatarId, *interfaces):
47
if telnet.ITelnetProtocol in interfaces:
48
return (telnet.ITelnetProtocol,
49
self.protocolFactory(*self.protocolArgs, **self.protocolKwArgs),
51
raise NotImplementedError()
53
class Options(usage.Options):
55
["telnetPort", "t", None, "strports description of the address on which to listen for telnet connections"],
56
["sshPort", "s", None, "strports description of the address on which to listen for ssh connections"],
57
["passwd", "p", "/etc/passwd", "name of a passwd(5)-format username/password file"]]
60
usage.Options.__init__(self)
62
self['namespace'] = None
64
def opt_user(self, name):
65
self.users.append(name)
67
def postOptions(self):
68
if self['telnetPort'] is None and self['sshPort'] is None:
69
raise usage.UsageError("At least one of --telnetPort and --sshPort must be specified")
71
def makeService(options):
72
"""Create a manhole server service.
74
@type options: C{dict}
75
@param options: A mapping describing the configuration of
76
the desired service. Recognized key/value pairs are::
78
"telnetPort": strports description of the address on which
79
to listen for telnet connections. If None,
80
no telnet service will be started.
82
"sshPort": strports description of the address on which to
83
listen for ssh connections. If None, no ssh
84
service will be started.
86
"namespace": dictionary containing desired initial locals
87
for manhole connections. If None, an empty
88
dictionary will be used.
90
"passwd": Name of a passwd(5)-format username/password file.
92
@rtype: L{twisted.application.service.IService}
93
@return: A manhole service.
96
svc = service.MultiService()
98
namespace = options['namespace']
102
checker = checkers.FilePasswordDB(options['passwd'])
104
if options['telnetPort']:
105
telnetRealm = _StupidRealm(telnet.TelnetBootstrapProtocol,
106
insults.ServerProtocol,
107
manhole.ColoredManhole,
110
telnetPortal = portal.Portal(telnetRealm, [checker])
112
telnetFactory = protocol.ServerFactory()
113
telnetFactory.protocol = makeTelnetProtocol(telnetPortal)
114
telnetService = strports.service(options['telnetPort'],
116
telnetService.setServiceParent(svc)
118
if options['sshPort']:
119
sshRealm = manhole_ssh.TerminalRealm()
120
sshRealm.chainedProtocolFactory = chainedProtocolFactory(namespace)
122
sshPortal = portal.Portal(sshRealm, [checker])
123
sshFactory = manhole_ssh.ConchFactory(sshPortal)
124
sshService = strports.service(options['sshPort'],
126
sshService.setServiceParent(svc)