Commit 07888d97 by willmcgugan@gmail.com

Applied patch to sftp that searches for ssh keys in default locations

parent dccbc1f3
......@@ -14,7 +14,6 @@ import threading
import os
import paramiko
from getpass import getuser
from binascii import hexlify
from fs.base import *
from fs.path import *
......@@ -34,17 +33,18 @@ else:
class thread_local(object):
def __init__(self):
self._map = {}
def __getattr__(self,attr):
def __getattr__(self, attr):
try:
return self._map[(threading.currentThread().ident,attr)]
return self._map[(threading.currentThread().ident, attr)]
except KeyError:
raise AttributeError, attr
def __setattr__(self,attr,value):
self._map[(threading.currentThread().ident,attr)] = value
raise AttributeError(attr)
def __setattr__(self, attr, value):
self._map[(threading.currentThread().ident, attr)] = value
if not hasattr(paramiko.SFTPFile,"__enter__"):
if not hasattr(paramiko.SFTPFile, "__enter__"):
paramiko.SFTPFile.__enter__ = lambda self: self
paramiko.SFTPFile.__exit__ = lambda self,et,ev,tb: self.close() and False
......@@ -70,8 +70,17 @@ class SFTPFS(FS):
'atomic.setcontents' : False
}
def __init__(self, connection, root_path="/", encoding=None, hostkey=None, username='', password=None, pkey=None, agent_auth=True, no_auth=False):
def __init__(self,
connection,
root_path="/",
encoding=None,
hostkey=None,
username='',
password=None,
pkey=None,
agent_auth=True,
no_auth=False,
look_for_keys=True):
"""SFTPFS constructor.
The only required argument is 'connection', which must be something
......@@ -95,6 +104,8 @@ class SFTPFS(FS):
:param pkey: Public key
:param agent_auth: attempt to authorize with the user's public keys
:param no_auth: attempt to log in without any kind of authorization
:param look_for_keys: Look for keys in the same locations as ssh,
if other authentication is not succesful
"""
......@@ -160,6 +171,9 @@ class SFTPFS(FS):
if agent_auth and not connection.is_authenticated():
self._agent_auth(connection, username)
if look_for_keys and not connection.is_authenticated():
self._userkeys_auth(connection, username, password)
if not connection.is_authenticated():
try:
connection.auth_none(username)
......@@ -200,6 +214,39 @@ class SFTPFS(FS):
pass
return None
@classmethod
def _userkeys_auth(cls, transport, username, password):
"""
Attempt to authenticate to the given transport using any of the private
keys in the users ~/.ssh and ~/ssh dirs
Derived from http://www.lag.net/paramiko/docs/paramiko.client-pysrc.html
"""
keyfiles = []
rsa_key = os.path.expanduser('~/.ssh/id_rsa')
dsa_key = os.path.expanduser('~/.ssh/id_dsa')
if os.path.isfile(rsa_key):
keyfiles.append((paramiko.rsakey.RSAKey, rsa_key))
if os.path.isfile(dsa_key):
keyfiles.append((paramiko.dsskey.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((paramiko.rsakey.RSAKey, rsa_key))
if os.path.isfile(dsa_key):
keyfiles.append((paramiko.dsskey.DSSKey, dsa_key))
for pkey_class, filename in keyfiles:
key = pkey_class.from_private_key_file(filename, password)
try:
transport.auth_publickey(username, key)
return key
except paramike.SSHException:
pass
return None
def __del__(self):
self.close()
......
# -*- coding: utf-8 -*-
"""
The `utils` module provides a number of utility functions that don't belong in the Filesystem interface. Generally the functions in this module work with multiple Filesystems, for instance moving and copying between non-similar Filesystems.
The `utils` module provides a number of utility functions that don't belong
in the Filesystem interface. Generally the functions in this module work with
multiple Filesystems, for instance moving and copying between non-similar Filesystems.
"""
......@@ -206,7 +208,6 @@ def movedir(fs1, fs2, create_destination=True, ignore_errors=False, chunk_size=6
parent_dir1 = dir1
fs1 = fs1.opendir(dir1)
print fs1
if parent_dir1 in ('', '/'):
raise RemoveRootError(dir1)
......@@ -596,4 +597,3 @@ if __name__ == "__main__":
t1.tree()
t2.tree()
......@@ -12,6 +12,7 @@ from fs.errors import ResourceNotFoundError
import re
import fnmatch
class HideFS(WrapFS):
"""FS wrapper that hides resources if they match a wildcard(s).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment