From 3319f556d6d4dda4d33165fbaccc332c21cf6502 Mon Sep 17 00:00:00 2001 From: Robey Pointer Date: Mon, 18 Feb 2008 23:47:36 -0800 Subject: [PATCH] [project @ robey@lag.net-20080219074736-1fkyp8jl95amj5ky] add WarningPolicy to SSHClient, which logs a warning when a server host key isn't known, but allows the connection. also added an option to avoid searching for private keys, and made it check ~/ssh/ for windows. --- paramiko/__init__.py | 5 +++-- paramiko/client.py | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/paramiko/__init__.py b/paramiko/__init__.py index c921871..058ca53 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -61,13 +61,13 @@ if sys.version_info < (2, 2): __author__ = "Robey Pointer " __date__ = "21 Jan 2008" -__version__ = "1.7.2 (Basil)" +__version__ = "1.7.3 (C...)" __version_info__ = (1, 7, 2) __license__ = "GNU Lesser General Public License (LGPL)" from transport import randpool, SecurityOptions, Transport -from client import SSHClient, MissingHostKeyPolicy, AutoAddPolicy, RejectPolicy +from client import SSHClient, MissingHostKeyPolicy, AutoAddPolicy, RejectPolicy, WarningPolicy from auth_handler import AuthHandler from channel import Channel, ChannelFile from ssh_exception import SSHException, PasswordRequiredException, \ @@ -110,6 +110,7 @@ __all__ = [ 'Transport', 'MissingHostKeyPolicy', 'AutoAddPolicy', 'RejectPolicy', + 'WarningPolicy', 'SecurityOptions', 'SubsystemHandler', 'Channel', diff --git a/paramiko/client.py b/paramiko/client.py index c4df949..606c58f 100644 --- a/paramiko/client.py +++ b/paramiko/client.py @@ -24,6 +24,7 @@ from binascii import hexlify import getpass import os import socket +import warnings from paramiko.agent import Agent from paramiko.common import * @@ -81,7 +82,17 @@ class RejectPolicy (MissingHostKeyPolicy): (key.get_name(), hostname, hexlify(key.get_fingerprint()))) raise SSHException('Unknown server %s' % hostname) - + +class WarningPolicy (MissingHostKeyPolicy): + """ + Policy for logging a python-style warning for an unknown host key, but + accepting it. This is used by L{SSHClient}. + """ + def missing_host_key(self, client, hostname, key): + warnings.warn('Unknown %s host key for %s: %s' % + (key.get_name(), hostname, hexlify(key.get_fingerprint()))) + + class SSHClient (object): """ A high-level representation of a session with an SSH server. This class @@ -213,7 +224,7 @@ class SSHClient (object): self._policy = policy def connect(self, hostname, port=22, username=None, password=None, pkey=None, - key_filename=None, timeout=None, allow_agent=True): + key_filename=None, timeout=None, allow_agent=True, look_for_keys=True): """ Connect to an SSH server and authenticate to it. The server's host key is checked against the system host keys (see L{load_system_host_keys}) @@ -251,6 +262,9 @@ class SSHClient (object): @type timeout: float @param allow_agent: set to False to disable connecting to the SSH agent @type allow_agent: bool + @param look_for_keys: set to False to disable searching for discoverable + private key files in C{~/.ssh/} + @type look_for_keys: bool @raise BadHostKeyException: if the server's host key could not be verified @@ -291,7 +305,7 @@ class SSHClient (object): if username is None: username = getpass.getuser() - self._auth(username, password, pkey, key_filename, allow_agent) + self._auth(username, password, pkey, key_filename, allow_agent, look_for_keys) def close(self): """ @@ -367,13 +381,13 @@ class SSHClient (object): """ return self._transport - def _auth(self, username, password, pkey, key_filename, allow_agent): + def _auth(self, username, password, pkey, key_filename, allow_agent, look_for_keys): """ Try, in order: - The key passed in, if one was passed in. - - Any key we can find through an SSH agent. - - Any "id_rsa" or "id_dsa" key discoverable in ~/.ssh/. + - Any key we can find through an SSH agent (if allowed). + - Any "id_rsa" or "id_dsa" key discoverable in ~/.ssh/ (if allowed). - Plain username/password auth, if a password was given. (The password might be needed to unlock a private key.) @@ -414,6 +428,17 @@ class SSHClient (object): keyfiles.append((RSAKey, rsa_key)) if os.path.isfile(dsa_key): keyfiles.append((DSSKey, dsa_key)) + # look in ~/ssh/ for windows users: + rsa_key = os.path.expanduser('~/ssh/id_rsa') + dsa_key = os.path.expanduser('~/ssh/id_dsa') + if os.path.isfile(rsa_key): + keyfiles.append((RSAKey, rsa_key)) + if os.path.isfile(dsa_key): + keyfiles.append((DSSKey, dsa_key)) + + if not look_for_keys: + keyfiles = [] + for pkey_class, filename in keyfiles: try: key = pkey_class.from_private_key_file(filename, password)