summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2014-02-24 10:08:46 -0800
committerJeff Forcier <jeff@bitprophet.org>2014-02-24 10:08:46 -0800
commit4bcac18d17b62d3553f4fd91c9e904c1d5808cfe (patch)
tree99156678db8905fd81c515fd740cb9bd2b040a9b
parent15568537131aceccf12b845c830d8f42e4c264f8 (diff)
downloadparamiko-4bcac18d17b62d3553f4fd91c9e904c1d5808cfe.tar.gz
Host key docs (order + tweaks)
-rw-r--r--paramiko/hostkeys.py163
-rw-r--r--sites/docs/api/hostkeys.rst1
2 files changed, 80 insertions, 84 deletions
diff --git a/paramiko/hostkeys.py b/paramiko/hostkeys.py
index 1eed350a..ceb9051f 100644
--- a/paramiko/hostkeys.py
+++ b/paramiko/hostkeys.py
@@ -16,9 +16,6 @@
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-"""
-`.HostKeys`
-"""
import base64
import binascii
@@ -31,95 +28,21 @@ from paramiko.rsakey import RSAKey
from paramiko.util import get_logger, constant_time_bytes_eq
-class InvalidHostKey(Exception):
-
- def __init__(self, line, exc):
- self.line = line
- self.exc = exc
- self.args = (line, exc)
-
-
-class HostKeyEntry:
- """
- Representation of a line in an OpenSSH-style "known hosts" file.
- """
-
- def __init__(self, hostnames=None, key=None):
- self.valid = (hostnames is not None) and (key is not None)
- self.hostnames = hostnames
- self.key = key
-
- def from_line(cls, line, lineno=None):
- """
- Parses the given line of text to find the names for the host,
- the type of key, and the key data. The line is expected to be in the
- format used by the openssh known_hosts file.
-
- Lines are expected to not have leading or trailing whitespace.
- 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
- """
- log = get_logger('paramiko.hostkeys')
- fields = line.split(' ')
- if len(fields) < 3:
- # Bad number of fields
- log.info("Not enough fields found in known_hosts in line %s (%r)" %
- (lineno, line))
- return None
- fields = fields[:3]
-
- names, keytype, key = fields
- names = names.split(',')
-
- # Decide what kind of key we're looking at and create an object
- # to hold it accordingly.
- try:
- if keytype == 'ssh-rsa':
- key = RSAKey(data=base64.decodestring(key))
- elif keytype == 'ssh-dss':
- key = DSSKey(data=base64.decodestring(key))
- else:
- log.info("Unable to handle key of type %s" % (keytype,))
- return None
- except binascii.Error, e:
- raise InvalidHostKey(line, e)
-
- return cls(names, key)
- from_line = classmethod(from_line)
-
- def to_line(self):
- """
- Returns a string in OpenSSH known_hosts file format, or None if
- the object is not in a valid state. A trailing newline is
- included.
- """
- if self.valid:
- return '%s %s %s\n' % (','.join(self.hostnames), self.key.get_name(),
- self.key.get_base64())
- return None
-
- def __repr__(self):
- return '<HostKeyEntry %r: %r>' % (self.hostnames, self.key)
-
-
class HostKeys (UserDict.DictMixin):
"""
- Representation of an openssh-style "known hosts" file. Host keys can be
+ Representation of an OpenSSH-style "known hosts" file. Host keys can be
read from one or more files, and then individual hosts can be looked up to
verify server keys during SSH negotiation.
- A HostKeys object can be treated like a dict; any dict lookup is equivalent
- to calling `lookup`.
+ A `.HostKeys` object can be treated like a dict; any dict lookup is
+ equivalent to calling `lookup`.
.. versionadded:: 1.5.3
"""
def __init__(self, filename=None):
"""
- 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.
:param filename: filename to load host keys from, or ``None``
@@ -150,7 +73,7 @@ class HostKeys (UserDict.DictMixin):
def load(self, filename):
"""
- Read a file of known SSH host keys, in the format used by openssh.
+ Read a file of known SSH host keys, in the format used by OpenSSH.
This type of file unfortunately doesn't exist on Windows, but on
posix, it will usually be stored in
``os.path.expanduser("~/.ssh/known_hosts")``.
@@ -181,7 +104,7 @@ class HostKeys (UserDict.DictMixin):
def save(self, filename):
"""
- Save host keys into a file, in the format used by openssh. The order of
+ Save host keys into a file, in the format used by OpenSSH. The order of
keys in the file will be preserved when possible (if these keys were
loaded from a file originally). The single exception is that combined
lines will be split into individual key lines, which is arguably a bug.
@@ -314,7 +237,7 @@ class HostKeys (UserDict.DictMixin):
def hash_host(hostname, salt=None):
"""
- 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.
:param hostname: the hostname to hash
@@ -336,3 +259,75 @@ class HostKeys (UserDict.DictMixin):
return hostkey.replace('\n', '')
hash_host = staticmethod(hash_host)
+
+class InvalidHostKey(Exception):
+ def __init__(self, line, exc):
+ self.line = line
+ self.exc = exc
+ self.args = (line, exc)
+
+
+class HostKeyEntry:
+ """
+ Representation of a line in an OpenSSH-style "known hosts" file.
+ """
+
+ def __init__(self, hostnames=None, key=None):
+ self.valid = (hostnames is not None) and (key is not None)
+ self.hostnames = hostnames
+ self.key = key
+
+ def from_line(cls, line, lineno=None):
+ """
+ Parses the given line of text to find the names for the host,
+ the type of key, and the key data. The line is expected to be in the
+ format used by the OpenSSH known_hosts file.
+
+ Lines are expected to not have leading or trailing whitespace.
+ 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
+ """
+ log = get_logger('paramiko.hostkeys')
+ fields = line.split(' ')
+ if len(fields) < 3:
+ # Bad number of fields
+ log.info("Not enough fields found in known_hosts in line %s (%r)" %
+ (lineno, line))
+ return None
+ fields = fields[:3]
+
+ names, keytype, key = fields
+ names = names.split(',')
+
+ # Decide what kind of key we're looking at and create an object
+ # to hold it accordingly.
+ try:
+ if keytype == 'ssh-rsa':
+ key = RSAKey(data=base64.decodestring(key))
+ elif keytype == 'ssh-dss':
+ key = DSSKey(data=base64.decodestring(key))
+ else:
+ log.info("Unable to handle key of type %s" % (keytype,))
+ return None
+ except binascii.Error, e:
+ raise InvalidHostKey(line, e)
+
+ return cls(names, key)
+ from_line = classmethod(from_line)
+
+ def to_line(self):
+ """
+ Returns a string in OpenSSH known_hosts file format, or None if
+ the object is not in a valid state. A trailing newline is
+ included.
+ """
+ if self.valid:
+ return '%s %s %s\n' % (','.join(self.hostnames), self.key.get_name(),
+ self.key.get_base64())
+ return None
+
+ def __repr__(self):
+ return '<HostKeyEntry %r: %r>' % (self.hostnames, self.key)
diff --git a/sites/docs/api/hostkeys.rst b/sites/docs/api/hostkeys.rst
index 0859fbed..770652fd 100644
--- a/sites/docs/api/hostkeys.rst
+++ b/sites/docs/api/hostkeys.rst
@@ -2,3 +2,4 @@ Host keys / ``known_hosts`` files
=================================
.. automodule:: paramiko.hostkeys
+ :member-order: bysource