diff options
author | Sebastian Deiss <s.deiss@science-computing.de> | 2014-02-11 13:01:49 +0100 |
---|---|---|
committer | Sebastian Deiss <s.deiss@science-computing.de> | 2014-02-11 13:01:49 +0100 |
commit | e7f41de2f2dac5d03404f35edc5514f12e42c49f (patch) | |
tree | eae66247e741b2acdcc5ec10712af231992296a0 /paramiko/message.py | |
parent | a08ac06083a40eb1455e5fa14cd644f7a2350f16 (diff) | |
download | paramiko-e7f41de2f2dac5d03404f35edc5514f12e42c49f.tar.gz |
Merge branch scottkmaxwell:py3-support-without-py25 into
SebastianDeiss:gssapi-py3-support
Diffstat (limited to 'paramiko/message.py')
-rw-r--r-- | paramiko/message.py | 109 |
1 files changed, 79 insertions, 30 deletions
diff --git a/paramiko/message.py b/paramiko/message.py index c0e8692b..45086213 100644 --- a/paramiko/message.py +++ b/paramiko/message.py @@ -21,9 +21,9 @@ Implementation of an SSH2 "message". """ import struct -import cStringIO from paramiko import util +from paramiko.common import * class Message (object): @@ -37,6 +37,8 @@ class Message (object): paramiko doesn't support yet. """ + big_int = long(0xff000000) + def __init__(self, content=None): """ Create a new SSH2 Message. @@ -46,18 +48,12 @@ class Message (object): @type content: string """ if content != None: - self.packet = cStringIO.StringIO(content) + self.packet = BytesIO(content) else: - self.packet = cStringIO.StringIO() + self.packet = BytesIO() def __str__(self): - """ - Return the byte stream content of this Message, as a string. - - @return: the contents of this Message. - @rtype: string - """ - return self.packet.getvalue() + return self.asbytes() def __repr__(self): """ @@ -67,6 +63,15 @@ class Message (object): """ return 'paramiko.Message(' + repr(self.packet.getvalue()) + ')' + def asbytes(self): + """ + Return the byte stream content of this Message, as bytes. + + @return: the contents of this Message. + @rtype: bytes + """ + return self.packet.getvalue() + def rewind(self): """ Rewind the message to the beginning as if no items had been parsed @@ -112,7 +117,7 @@ class Message (object): b = self.packet.read(n) max_pad_size = 1<<20 # Limit padding to 1 MB if len(b) < n and n < max_pad_size: - return b + '\x00' * (n - len(b)) + return b + zero_byte * (n - len(b)) return b def get_byte(self): @@ -134,7 +139,7 @@ class Message (object): @rtype: bool """ b = self.get_bytes(1) - return b != '\x00' + return b != zero_byte def get_int(self): """ @@ -143,6 +148,19 @@ class Message (object): @return: a 32-bit unsigned integer. @rtype: int """ + byte = self.get_bytes(1) + if byte == max_byte: + return util.inflate_long(self.get_binary()) + byte += self.get_bytes(3) + return struct.unpack('>I', byte)[0] + + def get_size(self): + """ + Fetch an int from the stream. + + @return: a 32-bit unsigned integer. + @rtype: int + """ return struct.unpack('>I', self.get_bytes(4))[0] def get_int64(self): @@ -161,7 +179,7 @@ class Message (object): @return: an arbitrary-length integer. @rtype: long """ - return util.inflate_long(self.get_string()) + return util.inflate_long(self.get_binary()) def get_string(self): """ @@ -172,7 +190,30 @@ class Message (object): @return: a string. @rtype: string """ - return self.get_bytes(self.get_int()) + return self.get_bytes(self.get_size()) + + def get_text(self): + """ + Fetch a string from the stream. This could be a byte string and may + contain unprintable characters. (It's not unheard of for a string to + contain another byte-stream Message.) + + @return: a string. + @rtype: string + """ + return u(self.get_bytes(self.get_size())) + #return self.get_bytes(self.get_size()) + + def get_binary(self): + """ + Fetch a string from the stream. This could be a byte string and may + contain unprintable characters. (It's not unheard of for a string to + contain another byte-stream Message.) + + @return: a string. + @rtype: string + """ + return self.get_bytes(self.get_size()) def get_list(self): """ @@ -182,7 +223,7 @@ class Message (object): @return: a list of strings. @rtype: list of strings """ - return self.get_string().split(',') + return self.get_text().split(',') def add_bytes(self, b): """ @@ -212,12 +253,12 @@ class Message (object): @type b: bool """ if b: - self.add_byte('\x01') + self.packet.write(one_byte) else: - self.add_byte('\x00') + self.packet.write(zero_byte) return self - def add_int(self, n): + def add_size(self, n): """ Add an integer to the stream. @@ -227,6 +268,20 @@ class Message (object): self.packet.write(struct.pack('>I', n)) return self + def add_int(self, n): + """ + Add an integer to the stream. + + @param n: integer to add + @type n: int + """ + if n >= Message.big_int: + self.packet.write(max_byte) + self.add_string(util.deflate_long(n)) + else: + self.packet.write(struct.pack('>I', n)) + return self + def add_int64(self, n): """ Add a 64-bit int to the stream. @@ -255,7 +310,8 @@ class Message (object): @param s: string to add @type s: str """ - self.add_int(len(s)) + s = asbytes(s) + self.add_size(len(s)) self.packet.write(s) return self @@ -272,21 +328,14 @@ class Message (object): return self def _add(self, i): - if type(i) is str: - return self.add_string(i) - elif type(i) is int: - return self.add_int(i) - elif type(i) is long: - if i > 0xffffffffL: - return self.add_mpint(i) - else: - return self.add_int(i) - elif type(i) is bool: + if type(i) is bool: return self.add_boolean(i) + elif isinstance(i, integer_types): + return self.add_int(i) elif type(i) is list: return self.add_list(i) else: - raise Exception('Unknown type') + return self.add_string(i) def add(self, *seq): """ |