Added width_pixel and height_pixel parameters to Channel.get_pty() and

resize_pty(), and Client.invoke_shell().  Perhaps useless, but more RFC
compliant.  Updated methods to include these parameters in server messages.

Adjusted Channel.resize_pty() to neither request nor wait for a response, as
per RFC 4254 6.7 (A response SHOULD NOT be sent to this message.)  This is
necessary as certain hosts have been observed to not acknowledge this type of
channel request (Cisco IOS XR), which causes paramiko to end the session.
This commit is contained in:
Phillip Heller 2012-11-20 16:10:16 -05:00 committed by Jeff Forcier
parent 277526315e
commit edc9eaf4f2
2 changed files with 23 additions and 10 deletions

View File

@ -122,7 +122,8 @@ class Channel (object):
out += '>' out += '>'
return out return out
def get_pty(self, term='vt100', width=80, height=24): def get_pty(self, term='vt100', width=80, height=24, width_pixels=0,
height_pixels=0):
""" """
Request a pseudo-terminal from the server. This is usually used right Request a pseudo-terminal from the server. This is usually used right
after creating a client channel, to ask the server to provide some after creating a client channel, to ask the server to provide some
@ -136,6 +137,10 @@ class Channel (object):
@type width: int @type width: int
@param height: height (in characters) of the terminal screen @param height: height (in characters) of the terminal screen
@type height: int @type height: int
@param width_pixels: width (in pixels) of the terminal screen
@type width_pixels: int
@param height_pixels: height (in pixels) of the terminal screen
@type height_pixels: int
@raise SSHException: if the request was rejected or the channel was @raise SSHException: if the request was rejected or the channel was
closed closed
@ -150,8 +155,8 @@ class Channel (object):
m.add_string(term) m.add_string(term)
m.add_int(width) m.add_int(width)
m.add_int(height) m.add_int(height)
# pixel height, width (usually useless) m.add_int(width_pixels)
m.add_int(0).add_int(0) m.add_int(height_pixels)
m.add_string('') m.add_string('')
self._event_pending() self._event_pending()
self.transport._send_user_message(m) self.transport._send_user_message(m)
@ -239,7 +244,7 @@ class Channel (object):
self.transport._send_user_message(m) self.transport._send_user_message(m)
self._wait_for_event() self._wait_for_event()
def resize_pty(self, width=80, height=24): def resize_pty(self, width=80, height=24, width_pixels=0, height_pixels=0):
""" """
Resize the pseudo-terminal. This can be used to change the width and Resize the pseudo-terminal. This can be used to change the width and
height of the terminal emulation created in a previous L{get_pty} call. height of the terminal emulation created in a previous L{get_pty} call.
@ -248,6 +253,10 @@ class Channel (object):
@type width: int @type width: int
@param height: new height (in characters) of the terminal screen @param height: new height (in characters) of the terminal screen
@type height: int @type height: int
@param width_pixels: new width (in pixels) of the terminal screen
@type width_pixels: int
@param height_pixels: new height (in pixels) of the terminal screen
@type height_pixels: int
@raise SSHException: if the request was rejected or the channel was @raise SSHException: if the request was rejected or the channel was
closed closed
@ -258,13 +267,12 @@ class Channel (object):
m.add_byte(chr(MSG_CHANNEL_REQUEST)) m.add_byte(chr(MSG_CHANNEL_REQUEST))
m.add_int(self.remote_chanid) m.add_int(self.remote_chanid)
m.add_string('window-change') m.add_string('window-change')
m.add_boolean(True) m.add_boolean(False)
m.add_int(width) m.add_int(width)
m.add_int(height) m.add_int(height)
m.add_int(0).add_int(0) m.add_int(width_pixels)
self._event_pending() m.add_int(height_pixels)
self.transport._send_user_message(m) self.transport._send_user_message(m)
self._wait_for_event()
def exit_status_ready(self): def exit_status_ready(self):
""" """

View File

@ -377,7 +377,8 @@ class SSHClient (object):
stderr = chan.makefile_stderr('rb', bufsize) stderr = chan.makefile_stderr('rb', bufsize)
return stdin, stdout, stderr return stdin, stdout, stderr
def invoke_shell(self, term='vt100', width=80, height=24): def invoke_shell(self, term='vt100', width=80, height=24, width_pixels=0,
height_pixels=0):
""" """
Start an interactive shell session on the SSH server. A new L{Channel} Start an interactive shell session on the SSH server. A new L{Channel}
is opened and connected to a pseudo-terminal using the requested is opened and connected to a pseudo-terminal using the requested
@ -389,13 +390,17 @@ class SSHClient (object):
@type width: int @type width: int
@param height: the height (in characters) of the terminal window @param height: the height (in characters) of the terminal window
@type height: int @type height: int
@param width_pixels: the width (in pixels) of the terminal window
@type width_pixels: int
@param height_pixels: the height (in pixels) of the terminal window
@type height_pixels: int
@return: a new channel connected to the remote shell @return: a new channel connected to the remote shell
@rtype: L{Channel} @rtype: L{Channel}
@raise SSHException: if the server fails to invoke a shell @raise SSHException: if the server fails to invoke a shell
""" """
chan = self._transport.open_session() chan = self._transport.open_session()
chan.get_pty(term, width, height) chan.get_pty(term, width, height, width_pixels, height_pixels)
chan.invoke_shell() chan.invoke_shell()
return chan return chan