paramiko/message.py

120 lines
2.9 KiB
Python

# implementation of a secsh "message"
import string, types, struct
from util import inflate_long, deflate_long
class Message(object):
"represents the encoding of a secsh message"
def __init__(self, content=''):
self.packet = content
self.idx = 0
self.seqno = -1
def __str__(self):
return self.packet
def __repr__(self):
return 'Message(' + repr(self.packet) + ')'
def get_remainder(self):
"remaining bytes still unparsed"
return self.packet[self.idx:]
def get_so_far(self):
"bytes that have been parsed"
return self.packet[:self.idx]
def get_bytes(self, n):
if self.idx + n > len(self.packet):
return '\x00'*n
b = self.packet[self.idx:self.idx+n]
self.idx = self.idx + n
return b
def get_byte(self):
return self.get_bytes(1)
def get_boolean(self):
b = self.get_bytes(1)
if b == '\x00':
return 0
else:
return 1
def get_int(self):
x = self.packet
i = self.idx
if i + 4 > len(x):
return 0
n = struct.unpack('>I', x[i:i+4])[0]
self.idx = i+4
return n
def get_mpint(self):
return inflate_long(self.get_string())
def get_string(self):
l = self.get_int()
if self.idx + l > len(self.packet):
return ''
str = self.packet[self.idx:self.idx+l]
self.idx = self.idx + l
return str
def get_list(self):
str = self.get_string()
l = string.split(str, ',')
return l
def add_bytes(self, b):
self.packet = self.packet + b
return self
def add_byte(self, b):
self.packet = self.packet + b
return self
def add_boolean(self, b):
if b:
self.add_byte('\x01')
else:
self.add_byte('\x00')
return self
def add_int(self, n):
self.packet = self.packet + struct.pack('>I', n)
return self
def add_mpint(self, z):
"this only works on positive numbers"
self.add_string(deflate_long(z))
return self
def add_string(self, s):
self.add_int(len(s))
self.packet = self.packet + s
return self
def add_list(self, l):
out = string.join(l, ',')
self.add_int(len(out))
self.packet = self.packet + out
return self
def add(self, i):
if type(i) == types.StringType:
return self.add_string(i)
elif type(i) == types.IntType:
return self.add_int(i)
elif type(i) == types.LongType:
if i > 0xffffffffL:
return self.add_mpint(i)
else:
return self.add_int(i)
elif type(i) == types.ListType:
return self.add_list(i)
else:
raise exception('Unknown type')