OLD | NEW |
| (Empty) |
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
2 # See LICENSE for details. | |
3 | |
4 """ | |
5 TAP plugin for creating telnet- and ssh-accessible manhole servers. | |
6 | |
7 @author: U{Jp Calderone<mailto:exarkun@twistedmatrix.com>} | |
8 """ | |
9 | |
10 from zope.interface import implements | |
11 | |
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 | |
18 | |
19 from twisted.conch.insults import insults | |
20 from twisted.conch import manhole, manhole_ssh, telnet | |
21 | |
22 class makeTelnetProtocol: | |
23 def __init__(self, portal): | |
24 self.portal = portal | |
25 | |
26 def __call__(self): | |
27 auth = telnet.AuthenticatingTelnetProtocol | |
28 args = (self.portal,) | |
29 return telnet.TelnetTransport(auth, *args) | |
30 | |
31 class chainedProtocolFactory: | |
32 def __init__(self, namespace): | |
33 self.namespace = namespace | |
34 | |
35 def __call__(self): | |
36 return insults.ServerProtocol(manhole.ColoredManhole, self.namespace) | |
37 | |
38 class _StupidRealm: | |
39 implements(portal.IRealm) | |
40 | |
41 def __init__(self, proto, *a, **kw): | |
42 self.protocolFactory = proto | |
43 self.protocolArgs = a | |
44 self.protocolKwArgs = kw | |
45 | |
46 def requestAvatar(self, avatarId, *interfaces): | |
47 if telnet.ITelnetProtocol in interfaces: | |
48 return (telnet.ITelnetProtocol, | |
49 self.protocolFactory(*self.protocolArgs, **self.protocolKwAr
gs), | |
50 lambda: None) | |
51 raise NotImplementedError() | |
52 | |
53 class Options(usage.Options): | |
54 optParameters = [ | |
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/pass
word file"]] | |
58 | |
59 def __init__(self): | |
60 usage.Options.__init__(self) | |
61 self.users = [] | |
62 self['namespace'] = None | |
63 | |
64 def opt_user(self, name): | |
65 self.users.append(name) | |
66 | |
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 m
ust be specified") | |
70 | |
71 def makeService(options): | |
72 """Create a manhole server service. | |
73 | |
74 @type options: C{dict} | |
75 @param options: A mapping describing the configuration of | |
76 the desired service. Recognized key/value pairs are:: | |
77 | |
78 "telnetPort": strports description of the address on which | |
79 to listen for telnet connections. If None, | |
80 no telnet service will be started. | |
81 | |
82 "sshPort": strports description of the address on which to | |
83 listen for ssh connections. If None, no ssh | |
84 service will be started. | |
85 | |
86 "namespace": dictionary containing desired initial locals | |
87 for manhole connections. If None, an empty | |
88 dictionary will be used. | |
89 | |
90 "passwd": Name of a passwd(5)-format username/password file. | |
91 | |
92 @rtype: L{twisted.application.service.IService} | |
93 @return: A manhole service. | |
94 """ | |
95 | |
96 svc = service.MultiService() | |
97 | |
98 namespace = options['namespace'] | |
99 if namespace is None: | |
100 namespace = {} | |
101 | |
102 checker = checkers.FilePasswordDB(options['passwd']) | |
103 | |
104 if options['telnetPort']: | |
105 telnetRealm = _StupidRealm(telnet.TelnetBootstrapProtocol, | |
106 insults.ServerProtocol, | |
107 manhole.ColoredManhole, | |
108 namespace) | |
109 | |
110 telnetPortal = portal.Portal(telnetRealm, [checker]) | |
111 | |
112 telnetFactory = protocol.ServerFactory() | |
113 telnetFactory.protocol = makeTelnetProtocol(telnetPortal) | |
114 telnetService = strports.service(options['telnetPort'], | |
115 telnetFactory) | |
116 telnetService.setServiceParent(svc) | |
117 | |
118 if options['sshPort']: | |
119 sshRealm = manhole_ssh.TerminalRealm() | |
120 sshRealm.chainedProtocolFactory = chainedProtocolFactory(namespace) | |
121 | |
122 sshPortal = portal.Portal(sshRealm, [checker]) | |
123 sshFactory = manhole_ssh.ConchFactory(sshPortal) | |
124 sshService = strports.service(options['sshPort'], | |
125 sshFactory) | |
126 sshService.setServiceParent(svc) | |
127 | |
128 return svc | |
OLD | NEW |