Even moar info fields

This commit is contained in:
Jeff Forcier 2014-02-26 12:55:58 -08:00
parent 79a69e88c3
commit 8ddaac24ae
2 changed files with 48 additions and 95 deletions

View File

@ -45,8 +45,7 @@ class HostKeys (UserDict.DictMixin):
Create a new HostKeys object, optionally loading keys from an OpenSSH
style host-key file.
:param filename: filename to load host keys from, or ``None``
:type filename: str
:param str filename: filename to load host keys from, or ``None``
"""
# emulate a dict of { hostname: { keytype: PKey } }
self._entries = []
@ -58,12 +57,9 @@ class HostKeys (UserDict.DictMixin):
Add a host key entry to the table. Any existing entry for a
``(hostname, keytype)`` pair will be replaced.
:param hostname: the hostname (or IP) to add
:type hostname: str
:param keytype: key type (``"ssh-rsa"`` or ``"ssh-dss"``)
:type keytype: str
:param key: the key to add
:type key: `.PKey`
:param str hostname: the hostname (or IP) to add
:param str keytype: key type (``"ssh-rsa"`` or ``"ssh-dss"``)
:param .PKey key: the key to add
"""
for e in self._entries:
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`,
replacing any existing entries and adding new ones.
:param filename: name of the file to read host keys from
:type filename: str
:param str filename: name of the file to read host keys from
: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
lines will be split into individual key lines, which is arguably a bug.
:param filename: name of the file to write
:type filename: str
:param str filename: name of the file to write
: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
returned. The keytype will be either ``"ssh-rsa"`` or ``"ssh-dss"``.
:param hostname: the hostname (or IP) to lookup
:type hostname: str
:return: keys associated with this host (or ``None``)
:rtype: dict(str, `.PKey`)
:param str hostname: the hostname (or IP) to lookup
:return: dict of `str` -> `.PKey` keys associated with this host (or ``None``)
"""
class SubDict (UserDict.DictMixin):
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
in this dictionary.
:param hostname: hostname (or IP) of the SSH server
:type hostname: str
:param key: the key to check
:type key: `.PKey`
:return: ``True`` if the key is associated with the hostname; ``False``
if not
:rtype: bool
:param str hostname: hostname (or IP) of the SSH server
:param .PKey key: the key to check
:return:
``True`` if the key is associated with the hostname; else ``False``
"""
k = self.lookup(hostname)
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
hashed hostnames in the known_hosts file.
:param hostname: the hostname to hash
:type hostname: str
:param salt: optional salt to use when hashing (must be 20 bytes long)
:type salt: str
:return: the hashed hostname
:rtype: str
:param str hostname: the hostname to hash
:param str salt: optional salt to use when hashing (must be 20 bytes long)
:return: the hashed hostname as a `str`
"""
if salt is None:
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
that should be taken care of before sending the line to us.
:param line: a line from an OpenSSH known_hosts file
:type line: str
:param str line: a line from an OpenSSH known_hosts file
"""
log = get_logger('paramiko.hostkeys')
fields = line.split(' ')

View File

@ -41,9 +41,9 @@ class Message (object):
"""
Create a new SSH2 message.
:param content: the byte stream to use as the message content (passed
in only when decomposing a message).
:type content: string
:param str content:
the byte stream to use as the message content (passed in only when
decomposing a message).
"""
if content != None:
self.packet = cStringIO.StringIO(content)
@ -53,17 +53,12 @@ class Message (object):
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()
def __repr__(self):
"""
Returns a string representation of this object, for debugging.
:rtype: string
"""
return 'paramiko.Message(' + repr(self.packet.getvalue()) + ')'
@ -76,11 +71,8 @@ class Message (object):
def get_remainder(self):
"""
Return the bytes of this message that haven't already been parsed and
returned.
:return: a string of the bytes not parsed yet.
:rtype: string
Return the bytes (as a `str`) of this message that haven't already been
parsed and returned.
"""
position = self.packet.tell()
remainder = self.packet.read()
@ -89,12 +81,9 @@ class Message (object):
def get_so_far(self):
"""
Returns the bytes of this message that have been parsed and returned.
The string passed into a message's constructor can be regenerated by
concatenating ``get_so_far`` and `get_remainder`.
:return: a string of the bytes parsed so far.
:rtype: string
Returns the `str` bytes of this message that have been parsed and
returned. The string passed into a message's constructor can be
regenerated by concatenating ``get_so_far`` and `get_remainder`.
"""
position = self.packet.tell()
self.rewind()
@ -102,12 +91,10 @@ class Message (object):
def get_bytes(self, n):
"""
Return the next ``n`` bytes of the message, without decomposing into
an int, string, etc. Just the raw bytes are returned.
:return: a string of the next ``n`` bytes of the message, or a string
of ``n`` zero bytes, if there aren't ``n`` bytes remaining.
:rtype: string
Return the next ``n`` bytes of the message (as a `str`), without
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``
bytes remaining in the message.
"""
b = self.packet.read(n)
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
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.
:rtype: string
"""
return self.get_bytes(1)
def get_boolean(self):
"""
Fetch a boolean from the stream.
:return: ``True`` or ``False`` (from the message).
:rtype: bool
"""
b = self.get_bytes(1)
return b != '\x00'
@ -140,8 +124,7 @@ class Message (object):
"""
Fetch an int from the stream.
:return: a 32-bit unsigned integer.
:rtype: int
:return: a 32-bit unsigned `int`.
"""
return struct.unpack('>I', self.get_bytes(4))[0]
@ -149,8 +132,7 @@ class Message (object):
"""
Fetch a 64-bit int from the stream.
:return: a 64-bit unsigned integer.
:rtype: long
:return: a 64-bit unsigned integer (`long`).
"""
return struct.unpack('>Q', self.get_bytes(8))[0]
@ -158,29 +140,23 @@ class Message (object):
"""
Fetch a long int (mpint) from the stream.
:return: an arbitrary-length integer.
:rtype: long
:return: an arbitrary-length integer (`long`).
"""
return util.inflate_long(self.get_string())
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 another byte-stream message.)
:return: a string.
:rtype: string
"""
return self.get_bytes(self.get_int())
def get_list(self):
"""
Fetch a list of strings from the stream. These are trivially encoded
as comma-separated values in a string.
Fetch a `list` of `strings <str>` from the stream.
:return: a list of strings.
:rtype: list of strings
These are trivially encoded as comma-separated values in a string.
"""
return self.get_string().split(',')
@ -188,8 +164,7 @@ class Message (object):
"""
Write bytes to the stream, without any formatting.
:param b: bytes to add
:type b: str
:param str b: bytes to add
"""
self.packet.write(b)
return self
@ -198,8 +173,7 @@ class Message (object):
"""
Write a single byte to the stream, without any formatting.
:param b: byte to add
:type b: str
:param str b: byte to add
"""
self.packet.write(b)
return self
@ -208,8 +182,7 @@ class Message (object):
"""
Add a boolean value to the stream.
:param b: boolean value to add
:type b: bool
:param bool b: boolean value to add
"""
if b:
self.add_byte('\x01')
@ -221,8 +194,7 @@ class Message (object):
"""
Add an integer to the stream.
:param n: integer to add
:type n: int
:param int n: integer to add
"""
self.packet.write(struct.pack('>I', n))
return self
@ -231,8 +203,7 @@ class Message (object):
"""
Add a 64-bit int to the stream.
:param n: long int to add
:type n: long
:param long n: long int to add
"""
self.packet.write(struct.pack('>Q', n))
return self
@ -242,8 +213,7 @@ class Message (object):
Add a long int to the stream, encoded as an infinite-precision
integer. This method only works on positive numbers.
:param z: long int to add
:type z: long
:param long z: long int to add
"""
self.add_string(util.deflate_long(z))
return self
@ -252,8 +222,7 @@ class Message (object):
"""
Add a string to the stream.
:param s: string to add
:type s: str
:param str s: string to add
"""
self.add_int(len(s))
self.packet.write(s)
@ -265,8 +234,7 @@ class Message (object):
a single string of values separated by commas. (Yes, really, that's
how SSH2 does it.)
:param l: list of strings to add
:type l: list(str)
:param list l: list of strings to add
"""
self.add_string(','.join(l))
return self
@ -293,10 +261,10 @@ class Message (object):
Add a sequence of items to the stream. The values are encoded based
on their type: str, int, bool, list, or long.
:param seq: the sequence of items
:type seq: sequence
.. warning::
Longs are encoded non-deterministically. Don't use this method.
@bug: longs are encoded non-deterministically. Don't use this method.
:param seq: the sequence of items
"""
for item in seq:
self._add(item)