1
# -*- test-case-name: twisted.conch.test.test_manhole -*-
2
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
3
# See LICENSE for details.
6
insults/SSH integration support.
11
from zope.interface import implements
13
from twisted.conch import avatar, interfaces as iconch, error as econch
14
from twisted.conch.ssh import factory, keys, session
15
from twisted.cred import credentials, checkers, portal
16
from twisted.python import components
18
from twisted.conch.insults import insults
21
"""A feeble class for making one attribute look like another.
23
This should be replaced with a real class at some point, probably.
24
Try not to write new code that uses it.
26
def __init__(self, **kw):
27
self.__dict__.update(kw)
29
def __getattr__(self, name):
30
raise AttributeError(self.name, "has no attribute", name)
32
class TerminalSessionTransport:
33
def __init__(self, proto, chainedProtocol, avatar, width, height):
36
self.chainedProtocol = chainedProtocol
38
session = self.proto.session
40
self.proto.makeConnection(
41
_Glue(write=self.chainedProtocol.dataReceived,
42
loseConnection=lambda: avatar.conn.sendClose(session),
43
name="SSH Proto Transport"))
46
self.proto.loseConnection()
48
self.chainedProtocol.makeConnection(
49
_Glue(write=self.proto.write,
50
loseConnection=loseConnection,
51
name="Chained Proto Transport"))
54
# chainedProtocol is supposed to be an ITerminalTransport,
55
# maybe. That means perhaps its terminalProtocol attribute is
56
# an ITerminalProtocol, it could be. So calling terminalSize
57
# on that should do the right thing But it'd be nice to clean
59
self.chainedProtocol.terminalProtocol.terminalSize(width, height)
61
class TerminalSession(components.Adapter):
62
implements(iconch.ISession)
64
transportFactory = TerminalSessionTransport
65
chainedProtocolFactory = insults.ServerProtocol
67
def getPty(self, term, windowSize, attrs):
68
self.height, self.width = windowSize[:2]
70
def openShell(self, proto):
71
self.transportFactory(
72
proto, self.chainedProtocolFactory(),
73
iconch.IConchUser(self.original),
74
self.width, self.height)
76
def execCommand(self, proto, cmd):
77
raise econch.ConchError("Cannot execute commands")
82
class TerminalUser(avatar.ConchUser, components.Adapter):
83
def __init__(self, original, avatarId):
84
components.Adapter.__init__(self, original)
85
avatar.ConchUser.__init__(self)
86
self.channelLookup['session'] = session.SSHSession
89
userFactory = TerminalUser
90
sessionFactory = TerminalSession
92
transportFactory = TerminalSessionTransport
93
chainedProtocolFactory = insults.ServerProtocol
95
def _getAvatar(self, avatarId):
96
comp = components.Componentized()
97
user = self.userFactory(comp, avatarId)
98
sess = self.sessionFactory(comp)
100
sess.transportFactory = self.transportFactory
101
sess.chainedProtocolFactory = self.chainedProtocolFactory
103
comp.setComponent(iconch.IConchUser, user)
104
comp.setComponent(iconch.ISession, sess)
108
def __init__(self, transportFactory=None):
109
if transportFactory is not None:
110
self.transportFactory = transportFactory
112
def requestAvatar(self, avatarId, mind, *interfaces):
114
if i is iconch.IConchUser:
115
return (iconch.IConchUser,
116
self._getAvatar(avatarId),
118
raise NotImplementedError()
120
class ConchFactory(factory.SSHFactory):
121
publicKey = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEArzJx8OYOnJmzf4tfBEvLi8DVPrJ3/c9k2I/Az64fxjHf9imyRJbixtQhlH9lfNjUIx+4LmrJH5QNRsFporcHDKOTwTTYLh5KmRpslkYHRivcJSkbh/C+BR3utDS555mV'
124
'ssh-rsa' : keys.Key.fromString(publicKey)
128
privateKey = """-----BEGIN RSA PRIVATE KEY-----
129
MIIByAIBAAJhAK8ycfDmDpyZs3+LXwRLy4vA1T6yd/3PZNiPwM+uH8Yx3/YpskSW
130
4sbUIZR/ZXzY1CMfuC5qyR+UDUbBaaK3Bwyjk8E02C4eSpkabJZGB0Yr3CUpG4fw
131
vgUd7rQ0ueeZlQIBIwJgbh+1VZfr7WftK5lu7MHtqE1S1vPWZQYE3+VUn8yJADyb
132
Z4fsZaCrzW9lkIqXkE3GIY+ojdhZhkO1gbG0118sIgphwSWKRxK0mvh6ERxKqIt1
133
xJEJO74EykXZV4oNJ8sjAjEA3J9r2ZghVhGN6V8DnQrTk24Td0E8hU8AcP0FVP+8
134
PQm/g/aXf2QQkQT+omdHVEJrAjEAy0pL0EBH6EVS98evDCBtQw22OZT52qXlAwZ2
135
gyTriKFVoqjeEjt3SZKKqXHSApP/AjBLpF99zcJJZRq2abgYlf9lv1chkrWqDHUu
136
DZttmYJeEfiFBBavVYIF1dOlZT0G8jMCMBc7sOSZodFnAiryP+Qg9otSBjJ3bQML
137
pSTqy7c3a2AScC/YyOwkDaICHnnD3XyjMwIxALRzl0tQEKMXs6hH8ToUdlLROCrP
138
EhQ0wahUTCk1gKA4uPD6TMTChavbh4K63OvbKg==
139
-----END RSA PRIVATE KEY-----"""
141
'ssh-rsa' : keys.Key.fromString(privateKey)
145
def __init__(self, portal):