Even moar info fields
This commit is contained in:
parent
79a69e88c3
commit
8ddaac24ae
|
@ -45,8 +45,7 @@ class HostKeys (UserDict.DictMixin):
|
||||||
Create a new HostKeys object, optionally loading keys from an OpenSSH
|
Create a new HostKeys object, optionally loading keys from an OpenSSH
|
||||||
style host-key file.
|
style host-key file.
|
||||||
|
|
||||||
:param filename: filename to load host keys from, or ``None``
|
:param str filename: filename to load host keys from, or ``None``
|
||||||
:type filename: str
|
|
||||||
"""
|
"""
|
||||||
# emulate a dict of { hostname: { keytype: PKey } }
|
# emulate a dict of { hostname: { keytype: PKey } }
|
||||||
self._entries = []
|
self._entries = []
|
||||||
|
@ -58,12 +57,9 @@ class HostKeys (UserDict.DictMixin):
|
||||||
Add a host key entry to the table. Any existing entry for a
|
Add a host key entry to the table. Any existing entry for a
|
||||||
``(hostname, keytype)`` pair will be replaced.
|
``(hostname, keytype)`` pair will be replaced.
|
||||||
|
|
||||||
:param hostname: the hostname (or IP) to add
|
:param str hostname: the hostname (or IP) to add
|
||||||
:type hostname: str
|
:param str keytype: key type (``"ssh-rsa"`` or ``"ssh-dss"``)
|
||||||
:param keytype: key type (``"ssh-rsa"`` or ``"ssh-dss"``)
|
:param .PKey key: the key to add
|
||||||
:type keytype: str
|
|
||||||
:param key: the key to add
|
|
||||||
:type key: `.PKey`
|
|
||||||
"""
|
"""
|
||||||
for e in self._entries:
|
for e in self._entries:
|
||||||
if (hostname in e.hostnames) and (e.key.get_name() == keytype):
|
if (hostname in e.hostnames) and (e.key.get_name() == keytype):
|
||||||
|
@ -82,8 +78,7 @@ class HostKeys (UserDict.DictMixin):
|
||||||
not cleared. So multiple calls to `load` will just call `add`,
|
not cleared. So multiple calls to `load` will just call `add`,
|
||||||
replacing any existing entries and adding new ones.
|
replacing any existing entries and adding new ones.
|
||||||
|
|
||||||
:param filename: name of the file to read host keys from
|
:param str filename: name of the file to read host keys from
|
||||||
:type filename: str
|
|
||||||
|
|
||||||
:raises IOError: if there was an error reading the file
|
:raises IOError: if there was an error reading the file
|
||||||
"""
|
"""
|
||||||
|
@ -109,8 +104,7 @@ class HostKeys (UserDict.DictMixin):
|
||||||
loaded from a file originally). The single exception is that combined
|
loaded from a file originally). The single exception is that combined
|
||||||
lines will be split into individual key lines, which is arguably a bug.
|
lines will be split into individual key lines, which is arguably a bug.
|
||||||
|
|
||||||
:param filename: name of the file to write
|
:param str filename: name of the file to write
|
||||||
:type filename: str
|
|
||||||
|
|
||||||
:raises IOError: if there was an error writing the file
|
:raises IOError: if there was an error writing the file
|
||||||
|
|
||||||
|
@ -129,10 +123,8 @@ class HostKeys (UserDict.DictMixin):
|
||||||
``None`` is returned. Otherwise a dictionary of keytype to key is
|
``None`` is returned. Otherwise a dictionary of keytype to key is
|
||||||
returned. The keytype will be either ``"ssh-rsa"`` or ``"ssh-dss"``.
|
returned. The keytype will be either ``"ssh-rsa"`` or ``"ssh-dss"``.
|
||||||
|
|
||||||
:param hostname: the hostname (or IP) to lookup
|
:param str hostname: the hostname (or IP) to lookup
|
||||||
:type hostname: str
|
:return: dict of `str` -> `.PKey` keys associated with this host (or ``None``)
|
||||||
:return: keys associated with this host (or ``None``)
|
|
||||||
:rtype: dict(str, `.PKey`)
|
|
||||||
"""
|
"""
|
||||||
class SubDict (UserDict.DictMixin):
|
class SubDict (UserDict.DictMixin):
|
||||||
def __init__(self, hostname, entries, hostkeys):
|
def __init__(self, hostname, entries, hostkeys):
|
||||||
|
@ -177,13 +169,10 @@ class HostKeys (UserDict.DictMixin):
|
||||||
Return True if the given key is associated with the given hostname
|
Return True if the given key is associated with the given hostname
|
||||||
in this dictionary.
|
in this dictionary.
|
||||||
|
|
||||||
:param hostname: hostname (or IP) of the SSH server
|
:param str hostname: hostname (or IP) of the SSH server
|
||||||
:type hostname: str
|
:param .PKey key: the key to check
|
||||||
:param key: the key to check
|
:return:
|
||||||
:type key: `.PKey`
|
``True`` if the key is associated with the hostname; else ``False``
|
||||||
:return: ``True`` if the key is associated with the hostname; ``False``
|
|
||||||
if not
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
"""
|
||||||
k = self.lookup(hostname)
|
k = self.lookup(hostname)
|
||||||
if k is None:
|
if k is None:
|
||||||
|
@ -240,12 +229,9 @@ class HostKeys (UserDict.DictMixin):
|
||||||
Return a "hashed" form of the hostname, as used by OpenSSH when storing
|
Return a "hashed" form of the hostname, as used by OpenSSH when storing
|
||||||
hashed hostnames in the known_hosts file.
|
hashed hostnames in the known_hosts file.
|
||||||
|
|
||||||
:param hostname: the hostname to hash
|
:param str hostname: the hostname to hash
|
||||||
:type hostname: str
|
:param str salt: optional salt to use when hashing (must be 20 bytes long)
|
||||||
:param salt: optional salt to use when hashing (must be 20 bytes long)
|
:return: the hashed hostname as a `str`
|
||||||
:type salt: str
|
|
||||||
:return: the hashed hostname
|
|
||||||
:rtype: str
|
|
||||||
"""
|
"""
|
||||||
if salt is None:
|
if salt is None:
|
||||||
salt = rng.read(SHA.digest_size)
|
salt = rng.read(SHA.digest_size)
|
||||||
|
@ -287,8 +273,7 @@ class HostKeyEntry:
|
||||||
We don't bother to check for comments or empty lines. All of
|
We don't bother to check for comments or empty lines. All of
|
||||||
that should be taken care of before sending the line to us.
|
that should be taken care of before sending the line to us.
|
||||||
|
|
||||||
:param line: a line from an OpenSSH known_hosts file
|
:param str line: a line from an OpenSSH known_hosts file
|
||||||
:type line: str
|
|
||||||
"""
|
"""
|
||||||
log = get_logger('paramiko.hostkeys')
|
log = get_logger('paramiko.hostkeys')
|
||||||
fields = line.split(' ')
|
fields = line.split(' ')
|
||||||
|
|
|
@ -41,9 +41,9 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Create a new SSH2 message.
|
Create a new SSH2 message.
|
||||||
|
|
||||||
:param content: the byte stream to use as the message content (passed
|
:param str content:
|
||||||
in only when decomposing a message).
|
the byte stream to use as the message content (passed in only when
|
||||||
:type content: string
|
decomposing a message).
|
||||||
"""
|
"""
|
||||||
if content != None:
|
if content != None:
|
||||||
self.packet = cStringIO.StringIO(content)
|
self.packet = cStringIO.StringIO(content)
|
||||||
|
@ -53,17 +53,12 @@ class Message (object):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
Return the byte stream content of this message, as a string.
|
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.packet.getvalue()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""
|
"""
|
||||||
Returns a string representation of this object, for debugging.
|
Returns a string representation of this object, for debugging.
|
||||||
|
|
||||||
:rtype: string
|
|
||||||
"""
|
"""
|
||||||
return 'paramiko.Message(' + repr(self.packet.getvalue()) + ')'
|
return 'paramiko.Message(' + repr(self.packet.getvalue()) + ')'
|
||||||
|
|
||||||
|
@ -76,11 +71,8 @@ class Message (object):
|
||||||
|
|
||||||
def get_remainder(self):
|
def get_remainder(self):
|
||||||
"""
|
"""
|
||||||
Return the bytes of this message that haven't already been parsed and
|
Return the bytes (as a `str`) of this message that haven't already been
|
||||||
returned.
|
parsed and returned.
|
||||||
|
|
||||||
:return: a string of the bytes not parsed yet.
|
|
||||||
:rtype: string
|
|
||||||
"""
|
"""
|
||||||
position = self.packet.tell()
|
position = self.packet.tell()
|
||||||
remainder = self.packet.read()
|
remainder = self.packet.read()
|
||||||
|
@ -89,12 +81,9 @@ class Message (object):
|
||||||
|
|
||||||
def get_so_far(self):
|
def get_so_far(self):
|
||||||
"""
|
"""
|
||||||
Returns the bytes of this message that have been parsed and returned.
|
Returns the `str` bytes of this message that have been parsed and
|
||||||
The string passed into a message's constructor can be regenerated by
|
returned. The string passed into a message's constructor can be
|
||||||
concatenating ``get_so_far`` and `get_remainder`.
|
regenerated by concatenating ``get_so_far`` and `get_remainder`.
|
||||||
|
|
||||||
:return: a string of the bytes parsed so far.
|
|
||||||
:rtype: string
|
|
||||||
"""
|
"""
|
||||||
position = self.packet.tell()
|
position = self.packet.tell()
|
||||||
self.rewind()
|
self.rewind()
|
||||||
|
@ -102,12 +91,10 @@ class Message (object):
|
||||||
|
|
||||||
def get_bytes(self, n):
|
def get_bytes(self, n):
|
||||||
"""
|
"""
|
||||||
Return the next ``n`` bytes of the message, without decomposing into
|
Return the next ``n`` bytes of the message (as a `str`), without
|
||||||
an int, string, etc. Just the raw bytes are returned.
|
decomposing into an int, decoded string, etc. Just the raw bytes are
|
||||||
|
returned. Returns a string of ``n`` zero bytes if there weren't ``n``
|
||||||
:return: a string of the next ``n`` bytes of the message, or a string
|
bytes remaining in the message.
|
||||||
of ``n`` zero bytes, if there aren't ``n`` bytes remaining.
|
|
||||||
:rtype: string
|
|
||||||
"""
|
"""
|
||||||
b = self.packet.read(n)
|
b = self.packet.read(n)
|
||||||
max_pad_size = 1<<20 # Limit padding to 1 MB
|
max_pad_size = 1<<20 # Limit padding to 1 MB
|
||||||
|
@ -120,18 +107,15 @@ class Message (object):
|
||||||
Return the next byte of the message, without decomposing it. This
|
Return the next byte of the message, without decomposing it. This
|
||||||
is equivalent to `get_bytes(1) <get_bytes>`.
|
is equivalent to `get_bytes(1) <get_bytes>`.
|
||||||
|
|
||||||
:return: the next byte of the message, or ``'\000'`` if there aren't
|
:return:
|
||||||
|
the next (`str`) byte of the message, or ``'\000'`` if there aren't
|
||||||
any bytes remaining.
|
any bytes remaining.
|
||||||
:rtype: string
|
|
||||||
"""
|
"""
|
||||||
return self.get_bytes(1)
|
return self.get_bytes(1)
|
||||||
|
|
||||||
def get_boolean(self):
|
def get_boolean(self):
|
||||||
"""
|
"""
|
||||||
Fetch a boolean from the stream.
|
Fetch a boolean from the stream.
|
||||||
|
|
||||||
:return: ``True`` or ``False`` (from the message).
|
|
||||||
:rtype: bool
|
|
||||||
"""
|
"""
|
||||||
b = self.get_bytes(1)
|
b = self.get_bytes(1)
|
||||||
return b != '\x00'
|
return b != '\x00'
|
||||||
|
@ -140,8 +124,7 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Fetch an int from the stream.
|
Fetch an int from the stream.
|
||||||
|
|
||||||
:return: a 32-bit unsigned integer.
|
:return: a 32-bit unsigned `int`.
|
||||||
:rtype: int
|
|
||||||
"""
|
"""
|
||||||
return struct.unpack('>I', self.get_bytes(4))[0]
|
return struct.unpack('>I', self.get_bytes(4))[0]
|
||||||
|
|
||||||
|
@ -149,8 +132,7 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Fetch a 64-bit int from the stream.
|
Fetch a 64-bit int from the stream.
|
||||||
|
|
||||||
:return: a 64-bit unsigned integer.
|
:return: a 64-bit unsigned integer (`long`).
|
||||||
:rtype: long
|
|
||||||
"""
|
"""
|
||||||
return struct.unpack('>Q', self.get_bytes(8))[0]
|
return struct.unpack('>Q', self.get_bytes(8))[0]
|
||||||
|
|
||||||
|
@ -158,29 +140,23 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Fetch a long int (mpint) from the stream.
|
Fetch a long int (mpint) from the stream.
|
||||||
|
|
||||||
:return: an arbitrary-length integer.
|
:return: an arbitrary-length integer (`long`).
|
||||||
:rtype: long
|
|
||||||
"""
|
"""
|
||||||
return util.inflate_long(self.get_string())
|
return util.inflate_long(self.get_string())
|
||||||
|
|
||||||
def get_string(self):
|
def get_string(self):
|
||||||
"""
|
"""
|
||||||
Fetch a string from the stream. This could be a byte string and may
|
Fetch a `str` from the stream. This could be a byte string and may
|
||||||
contain unprintable characters. (It's not unheard of for a string to
|
contain unprintable characters. (It's not unheard of for a string to
|
||||||
contain another byte-stream message.)
|
contain another byte-stream message.)
|
||||||
|
|
||||||
:return: a string.
|
|
||||||
:rtype: string
|
|
||||||
"""
|
"""
|
||||||
return self.get_bytes(self.get_int())
|
return self.get_bytes(self.get_int())
|
||||||
|
|
||||||
def get_list(self):
|
def get_list(self):
|
||||||
"""
|
"""
|
||||||
Fetch a list of strings from the stream. These are trivially encoded
|
Fetch a `list` of `strings <str>` from the stream.
|
||||||
as comma-separated values in a string.
|
|
||||||
|
These are trivially encoded as comma-separated values in a string.
|
||||||
:return: a list of strings.
|
|
||||||
:rtype: list of strings
|
|
||||||
"""
|
"""
|
||||||
return self.get_string().split(',')
|
return self.get_string().split(',')
|
||||||
|
|
||||||
|
@ -188,8 +164,7 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Write bytes to the stream, without any formatting.
|
Write bytes to the stream, without any formatting.
|
||||||
|
|
||||||
:param b: bytes to add
|
:param str b: bytes to add
|
||||||
:type b: str
|
|
||||||
"""
|
"""
|
||||||
self.packet.write(b)
|
self.packet.write(b)
|
||||||
return self
|
return self
|
||||||
|
@ -198,8 +173,7 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Write a single byte to the stream, without any formatting.
|
Write a single byte to the stream, without any formatting.
|
||||||
|
|
||||||
:param b: byte to add
|
:param str b: byte to add
|
||||||
:type b: str
|
|
||||||
"""
|
"""
|
||||||
self.packet.write(b)
|
self.packet.write(b)
|
||||||
return self
|
return self
|
||||||
|
@ -208,8 +182,7 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Add a boolean value to the stream.
|
Add a boolean value to the stream.
|
||||||
|
|
||||||
:param b: boolean value to add
|
:param bool b: boolean value to add
|
||||||
:type b: bool
|
|
||||||
"""
|
"""
|
||||||
if b:
|
if b:
|
||||||
self.add_byte('\x01')
|
self.add_byte('\x01')
|
||||||
|
@ -221,8 +194,7 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Add an integer to the stream.
|
Add an integer to the stream.
|
||||||
|
|
||||||
:param n: integer to add
|
:param int n: integer to add
|
||||||
:type n: int
|
|
||||||
"""
|
"""
|
||||||
self.packet.write(struct.pack('>I', n))
|
self.packet.write(struct.pack('>I', n))
|
||||||
return self
|
return self
|
||||||
|
@ -231,8 +203,7 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Add a 64-bit int to the stream.
|
Add a 64-bit int to the stream.
|
||||||
|
|
||||||
:param n: long int to add
|
:param long n: long int to add
|
||||||
:type n: long
|
|
||||||
"""
|
"""
|
||||||
self.packet.write(struct.pack('>Q', n))
|
self.packet.write(struct.pack('>Q', n))
|
||||||
return self
|
return self
|
||||||
|
@ -242,8 +213,7 @@ class Message (object):
|
||||||
Add a long int to the stream, encoded as an infinite-precision
|
Add a long int to the stream, encoded as an infinite-precision
|
||||||
integer. This method only works on positive numbers.
|
integer. This method only works on positive numbers.
|
||||||
|
|
||||||
:param z: long int to add
|
:param long z: long int to add
|
||||||
:type z: long
|
|
||||||
"""
|
"""
|
||||||
self.add_string(util.deflate_long(z))
|
self.add_string(util.deflate_long(z))
|
||||||
return self
|
return self
|
||||||
|
@ -252,8 +222,7 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Add a string to the stream.
|
Add a string to the stream.
|
||||||
|
|
||||||
:param s: string to add
|
:param str s: string to add
|
||||||
:type s: str
|
|
||||||
"""
|
"""
|
||||||
self.add_int(len(s))
|
self.add_int(len(s))
|
||||||
self.packet.write(s)
|
self.packet.write(s)
|
||||||
|
@ -265,8 +234,7 @@ class Message (object):
|
||||||
a single string of values separated by commas. (Yes, really, that's
|
a single string of values separated by commas. (Yes, really, that's
|
||||||
how SSH2 does it.)
|
how SSH2 does it.)
|
||||||
|
|
||||||
:param l: list of strings to add
|
:param list l: list of strings to add
|
||||||
:type l: list(str)
|
|
||||||
"""
|
"""
|
||||||
self.add_string(','.join(l))
|
self.add_string(','.join(l))
|
||||||
return self
|
return self
|
||||||
|
@ -292,11 +260,11 @@ class Message (object):
|
||||||
"""
|
"""
|
||||||
Add a sequence of items to the stream. The values are encoded based
|
Add a sequence of items to the stream. The values are encoded based
|
||||||
on their type: str, int, bool, list, or long.
|
on their type: str, int, bool, list, or long.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
Longs are encoded non-deterministically. Don't use this method.
|
||||||
|
|
||||||
:param seq: the sequence of items
|
:param seq: the sequence of items
|
||||||
:type seq: sequence
|
|
||||||
|
|
||||||
@bug: longs are encoded non-deterministically. Don't use this method.
|
|
||||||
"""
|
"""
|
||||||
for item in seq:
|
for item in seq:
|
||||||
self._add(item)
|
self._add(item)
|
||||||
|
|
Loading…
Reference in New Issue