From f46859c98821e4fef06920da3b1af165b43dfb35 Mon Sep 17 00:00:00 2001 From: Hiro Ashiya Date: Tue, 31 Jul 2012 10:43:43 +0900 Subject: [PATCH 1/5] stop using Paramiko. instead ssh. --- setup.py | 4 ++-- src/sftpserver/__init__.py | 12 ++++++------ src/sftpserver/stub_sftp.py | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/setup.py b/setup.py index 75135c0..cd5269e 100644 --- a/setup.py +++ b/setup.py @@ -18,14 +18,14 @@ def read(*rel_names): setup( name='sftpserver', version='0.2', - url='http://github.com/rspivak/sftpserver', + url='http://github.com/kk6/sftpserver', license='MIT', description='sftpserver - a simple single-threaded sftp server', author='Ruslan Spivak', author_email='ruslan.spivak@gmail.com', packages=find_packages('src'), package_dir={'': 'src'}, - install_requires=['distribute', 'paramiko'], + install_requires=['distribute', 'ssh'], zip_safe=False, entry_points="""\ [console_scripts] diff --git a/src/sftpserver/__init__.py b/src/sftpserver/__init__.py index 26d03bd..a4665fd 100644 --- a/src/sftpserver/__init__.py +++ b/src/sftpserver/__init__.py @@ -30,7 +30,7 @@ import sys import textwrap -import paramiko +import ssh from sftpserver.stub_sftp import StubServer, StubSFTPServer @@ -39,8 +39,8 @@ def start_server(host, port, keyfile, level): - paramiko_level = getattr(paramiko.common, level) - paramiko.common.logging.basicConfig(level=paramiko_level) + ssh_level = getattr(ssh.common, level) + ssh.common.logging.basicConfig(level=ssh_level) server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) @@ -50,11 +50,11 @@ def start_server(host, port, keyfile, level): while True: conn, addr = server_socket.accept() - host_key = paramiko.RSAKey.from_private_key_file(keyfile) - transport = paramiko.Transport(conn) + host_key = ssh.RSAKey.from_private_key_file(keyfile) + transport = ssh.Transport(conn) transport.add_server_key(host_key) transport.set_subsystem_handler( - 'sftp', paramiko.SFTPServer, StubSFTPServer) + 'sftp', ssh.SFTPServer, StubSFTPServer) server = StubServer() transport.start_server(server=server) diff --git a/src/sftpserver/stub_sftp.py b/src/sftpserver/stub_sftp.py index 7f1ecc7..9b17617 100644 --- a/src/sftpserver/stub_sftp.py +++ b/src/sftpserver/stub_sftp.py @@ -21,7 +21,7 @@ """ import os -from paramiko import ServerInterface, SFTPServerInterface, SFTPServer, SFTPAttributes, \ +from ssh import ServerInterface, SFTPServerInterface, SFTPServer, SFTPAttributes, \ SFTPHandle, SFTP_OK, AUTH_SUCCESSFUL, OPEN_SUCCEEDED @@ -55,7 +55,7 @@ class StubSFTPServer (SFTPServerInterface): # assume current folder is a fine root # (the tests always create and eventualy delete a subfolder, so there shouldn't be any mess) ROOT = os.getcwd() - + def _realpath(self, path): return self.ROOT + self.canonicalize(path) From 4325d2628d132ffbba1d2fe1f34287b1056a4a3e Mon Sep 17 00:00:00 2001 From: Hiro Ashiya Date: Wed, 1 Aug 2012 01:02:04 +0900 Subject: [PATCH 2/5] Added an option for daemon startup. --- setup.py | 2 +- src/sftpserver/__init__.py | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index cd5269e..397aaed 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ def read(*rel_names): author_email='ruslan.spivak@gmail.com', packages=find_packages('src'), package_dir={'': 'src'}, - install_requires=['distribute', 'ssh'], + install_requires=['distribute', 'ssh', 'python-daemon'], zip_safe=False, entry_points="""\ [console_scripts] diff --git a/src/sftpserver/__init__.py b/src/sftpserver/__init__.py index a4665fd..8a9ae6d 100644 --- a/src/sftpserver/__init__.py +++ b/src/sftpserver/__init__.py @@ -31,6 +31,8 @@ import textwrap import ssh +from daemon import DaemonContext +from lockfile.pidlockfile import PIDLockFile from sftpserver.stub_sftp import StubServer, StubSFTPServer @@ -85,6 +87,12 @@ def main(): '-k', '--keyfile', dest='keyfile', metavar='FILE', help='Path to private key, for example /tmp/test_rsa.key' ) + parser.add_option( + '-d', '--daemon', action='store_true', dest='daemon', + default=False, + help=('To launch sftpserver as a daemon.' + 'How to kill: kill `cat /tmp/mydaemon.pid`') + ) options, args = parser.parse_args() @@ -92,7 +100,17 @@ def main(): parser.print_help() sys.exit(-1) - start_server(options.host, options.port, options.keyfile, options.level) + if options.daemon: + dc = DaemonContext( + pidfile=PIDLockFile('/tmp/mydaemon.pid'), + stderr=open('fake_err_console.txt', 'w+') + ) + with dc: + start_server(options.host, options.port, options.keyfile, + options.level) + else: + start_server(options.host, options.port, options.keyfile, + options.level) if __name__ == '__main__': From 650118961729935f761618ba8f3a34abba9ee22e Mon Sep 17 00:00:00 2001 From: Hiro Ashiya Date: Wed, 1 Aug 2012 13:24:07 +0900 Subject: [PATCH 3/5] update README.rst --- README.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index d98f1f2..0fcf4d9 100644 --- a/README.rst +++ b/README.rst @@ -34,16 +34,16 @@ Examples Debug level: WARNING, INFO, DEBUG [default: INFO] -k FILE, --keyfile=FILE Path to private key, for example /tmp/test_rsa.key + -d, --daemon To launch sftpserver as a daemon. How to kill: kill `cat /tmp/mydaemon.pid` $ sftpserver -k /tmp/test_rsa.key -l DEBUG Connecting with a Python client to our server: ->>> import paramiko ->>> pkey = paramiko.RSAKey.from_private_key_file('/tmp/test_rsa.key') ->>> transport = paramiko.Transport(('localhost', 3373)) ->>> transport.connect(username='admin', password='admin', pkey=pkey) ->>> sftp = paramiko.SFTPClient.from_transport(transport) +>>> import ssh +>>> transport = ssh.Transport(('localhost', 3373)) +>>> transport.connect(username='admin', password='admin') +>>> sftp = ssh.SFTPClient.from_transport(transport) >>> sftp.listdir('.') ['loop.py', 'stub_sftp.py'] From c1bc68fbebb3c856d9980848da1e6ce82d5770b3 Mon Sep 17 00:00:00 2001 From: Hiro Ashiya Date: Wed, 1 Aug 2012 17:12:08 +0900 Subject: [PATCH 4/5] switching out optparse for argparse --- src/sftpserver/__init__.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/sftpserver/__init__.py b/src/sftpserver/__init__.py index 8a9ae6d..a7799c0 100644 --- a/src/sftpserver/__init__.py +++ b/src/sftpserver/__init__.py @@ -26,7 +26,7 @@ import time import socket -import optparse +import argparse import sys import textwrap @@ -71,46 +71,46 @@ def main(): usage: sftpserver [options] -k/--keyfile should be specified """ - parser = optparse.OptionParser(usage=textwrap.dedent(usage)) - parser.add_option( + parser = argparse.ArgumentParser(usage=textwrap.dedent(usage)) + parser.add_argument( '--host', dest='host', default=HOST, - help='listen on HOST [default: %default]') - parser.add_option( - '-p', '--port', dest='port', type='int', default=PORT, - help='listen on PORT [default: %default]' + help='listen on HOST [default: %(default)s]') + parser.add_argument( + '-p', '--port', dest='port', type=int, default=PORT, + help='listen on PORT [default: %(default)s]' ) - parser.add_option( + parser.add_argument( '-l', '--level', dest='level', default='INFO', - help='Debug level: WARNING, INFO, DEBUG [default: %default]' + help='Debug level: WARNING, INFO, DEBUG [default: %(default)s]' ) - parser.add_option( + parser.add_argument( '-k', '--keyfile', dest='keyfile', metavar='FILE', help='Path to private key, for example /tmp/test_rsa.key' ) - parser.add_option( + parser.add_argument( '-d', '--daemon', action='store_true', dest='daemon', default=False, help=('To launch sftpserver as a daemon.' 'How to kill: kill `cat /tmp/mydaemon.pid`') ) - options, args = parser.parse_args() + args = parser.parse_args() - if options.keyfile is None: + if args.keyfile is None: parser.print_help() sys.exit(-1) - if options.daemon: + if args.daemon: dc = DaemonContext( pidfile=PIDLockFile('/tmp/mydaemon.pid'), stderr=open('fake_err_console.txt', 'w+') ) with dc: - start_server(options.host, options.port, options.keyfile, - options.level) + start_server(args.host, args.port, args.keyfile, + args.level) else: - start_server(options.host, options.port, options.keyfile, - options.level) + start_server(args.host, args.port, args.keyfile, + args.level) if __name__ == '__main__': From e6657bfb780e56b228386c56dec2e715f6b32bde Mon Sep 17 00:00:00 2001 From: Hiro Ashiya Date: Thu, 16 Aug 2012 23:27:52 +0900 Subject: [PATCH 5/5] update README --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 0fcf4d9..e7358f4 100644 --- a/README.rst +++ b/README.rst @@ -42,8 +42,9 @@ Examples Connecting with a Python client to our server: >>> import ssh +>>> pkey = paramiko.RSAKey.from_private_key_file('/tmp/test_rsa.key') >>> transport = ssh.Transport(('localhost', 3373)) ->>> transport.connect(username='admin', password='admin') +>>> transport.connect(username='admin', password='admin', pkey=pkey) >>> sftp = ssh.SFTPClient.from_transport(transport) >>> sftp.listdir('.') ['loop.py', 'stub_sftp.py']