summaryrefslogtreecommitdiffhomepage
path: root/channel.py
diff options
context:
space:
mode:
Diffstat (limited to 'channel.py')
-rw-r--r--channel.py57
1 files changed, 44 insertions, 13 deletions
diff --git a/channel.py b/channel.py
index 8f53d379..8bbe22a5 100644
--- a/channel.py
+++ b/channel.py
@@ -1,5 +1,5 @@
from message import Message
-from secsh import SSHException
+from secsh import SecshException
from transport import MSG_CHANNEL_REQUEST, MSG_CHANNEL_CLOSE, MSG_CHANNEL_WINDOW_ADJUST, MSG_CHANNEL_DATA, \
MSG_CHANNEL_EOF, MSG_CHANNEL_SUCCESS, MSG_CHANNEL_FAILURE
@@ -100,6 +100,22 @@ class Channel(object):
finally:
self.lock.release()
+ def check_pty_request(self, term, width, height, pixelwidth, pixelheight, modes):
+ "override me! return True if a pty of the given dimensions (for shell access, usually) can be provided"
+ return False
+
+ def check_shell_request(self):
+ "override me! return True if shell access will be provided"
+ return False
+
+ def check_subsystem_request(self, name):
+ "override me! return True if the given subsystem can be provided"
+ return False
+
+ def check_window_change_request(self, width, height, pixelwidth, pixelheight):
+ "override me! return True if the pty was resized"
+ return False
+
def handle_request(self, m):
key = m.get_string()
want_reply = m.get_boolean()
@@ -110,10 +126,25 @@ class Channel(object):
elif key == 'xon-xoff':
# ignore
ok = True
- elif (key == 'pty-req') or (key == 'shell'):
- if self.transport.server_mode:
- # humor them
- ok = True
+ elif key == 'pty-req':
+ term = m.get_string()
+ width = m.get_int()
+ height = m.get_int()
+ pixelwidth = m.get_int()
+ pixelheight = m.get_int()
+ modes = m.get_string()
+ ok = self.check_pty_request(term, width, height, pixelwidth, pixelheight, modes)
+ elif key == 'shell':
+ ok = self.check_shell_request()
+ elif key == 'subsystem':
+ name = m.get_string()
+ ok = self.check_subsystem_request(name)
+ elif key == 'window-change':
+ width = m.get_int()
+ height = m.get_int()
+ pixelwidth = m.get_int()
+ pixelheight = m.get_int()
+ ok = self.check_window_change_request(width, height, pixelwidth, pixelheight)
else:
self.log(DEBUG, 'Unhandled channel request "%s"' % key)
ok = False
@@ -155,7 +186,7 @@ class Channel(object):
def get_pty(self, term='vt100', width=80, height=24):
if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
+ raise SecshException('Channel is not open')
m = Message()
m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
@@ -171,7 +202,7 @@ class Channel(object):
def invoke_shell(self):
if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
+ raise SecshException('Channel is not open')
m = Message()
m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
@@ -181,7 +212,7 @@ class Channel(object):
def exec_command(self, command):
if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
+ raise SecshException('Channel is not open')
m = Message()
m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
@@ -192,7 +223,7 @@ class Channel(object):
def invoke_subsystem(self, subsystem):
if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
+ raise SecshException('Channel is not open')
m = Message()
m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
@@ -203,7 +234,7 @@ class Channel(object):
def resize_pty(self, width=80, height=24):
if self.closed or self.eof_received or self.eof_sent or not self.active:
- raise SSHException('Channel is not open')
+ raise SecshException('Channel is not open')
m = Message()
m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid)
@@ -500,9 +531,6 @@ class ChannelFile(object):
XXX Todo: the channel and its file-wrappers should be able to be closed or
garbage-collected independently, for compatibility with real sockets and
their file-wrappers. Currently, closing does nothing but flush the buffer.
- XXX Todo: translation of the various forms of newline is not implemented,
- let alone the universal newline. Line buffering (for writing) is
- implemented, though, which makes little sense without text mode support.
"""
def __init__(self, channel, mode = "r", buf_size = -1):
@@ -528,6 +556,9 @@ class ChannelFile(object):
self.newlines = None
self.softspace = False
+ def __repr__(self):
+ return '<secsh.ChannelFile from ' + repr(self.channel) + '>'
+
def __iter__(self):
return self