def override_user(self, username, password=None, homedir=None, perm=None, msg_login=None, msg_quit=None): """Overrides the options specified in the class constructor for a specific user. """ if (not password and not homedir and not perm and not msg_login and not msg_quit): raise AuthorizerError( "at least one keyword argument must be specified") if self.allowed_users and username not in self.allowed_users: raise AuthorizerError('%s is not an allowed user' % username) if self.rejected_users and username in self.rejected_users: raise AuthorizerError('%s is not an allowed user' % username) if username == "anonymous" and password: raise AuthorizerError("can't assign password to anonymous user") if not self.has_user(username): raise AuthorizerError('no such user %s' % username) if homedir is not None and not isinstance(homedir, unicode): homedir = homedir.decode('utf8') if username in self._dummy_authorizer.user_table: # re-set parameters del self._dummy_authorizer.user_table[username] self._dummy_authorizer.add_user(username, password or "", homedir or getcwdu(), perm or "", msg_login or "", msg_quit or "") if homedir is None: self._dummy_authorizer.user_table[username]['home'] = ""
def __init__(self, addr=None): os.mkdir('server') os.chdir('server') try: HOST = socket.gethostbyname('localhost') except socket.error: HOST = 'localhost' USER = '******' PASSWD = '12345' HOME = getcwdu() threading.Thread.__init__(self) self.__serving = False self.__stopped = False self.__lock = threading.Lock() self.__flag = threading.Event() if addr is None: addr = (HOST, 0) authorizer = DummyAuthorizer() authorizer.add_user(USER, PASSWD, HOME, perm='elradfmwM') # full perms authorizer.add_anonymous(HOME) self.handler.authorizer = authorizer # lowering buffer sizes = more cycles to transfer data # = less false positive test failures self.handler.dtp_handler.ac_in_buffer_size = 32768 self.handler.dtp_handler.ac_out_buffer_size = 32768 self.server = self.server_class(addr, self.handler) self.host, self.port = self.server.socket.getsockname()[:2] os.chdir('..')
def __init__(self, addr=None): os.mkdir ('server') os.chdir ('server') try: HOST = socket.gethostbyname ('localhost') except socket.error: HOST = 'localhost' USER = '******' PASSWD = '12345' HOME = getcwdu () threading.Thread.__init__(self) self.__serving = False self.__stopped = False self.__lock = threading.Lock() self.__flag = threading.Event() if addr is None: addr = (HOST, 0) authorizer = DummyAuthorizer() authorizer.add_user(USER, PASSWD, HOME, perm='elradfmwM') # full perms authorizer.add_anonymous(HOME) self.handler.authorizer = authorizer # lowering buffer sizes = more cycles to transfer data # = less false positive test failures self.handler.dtp_handler.ac_in_buffer_size = 32768 self.handler.dtp_handler.ac_out_buffer_size = 32768 self.server = self.server_class(addr, self.handler) self.host, self.port = self.server.socket.getsockname()[:2] os.chdir ('..')
def test_case(self): root = getcwdu() fs = filesystems.UnixFilesystem(root, None) self.assertEqual(fs.root, root) self.assertEqual(fs.cwd, root) cdup = os.path.dirname(root) self.assertEqual(fs.ftp2fs(u('..')), cdup) self.assertEqual(fs.fs2ftp(root), root)
def test_case(self): root = getcwdu() fs = UnixFilesystem(root, None) self.assertEqual(fs.root, root) self.assertEqual(fs.cwd, root) cdup = os.path.dirname(root) self.assertEqual(fs.ftp2fs(u('..')), cdup) self.assertEqual(fs.fs2ftp(root), root)
def main(): """Start a stand alone anonymous FTP server.""" usage = "python -m pyftpdlib.ftpserver [options]" parser = optparse.OptionParser(usage=usage, description=main.__doc__, formatter=CustomizedOptionFormatter()) parser.add_option('-i', '--interface', default=None, metavar="ADDRESS", help="specify the interface to run on (default all " "interfaces)") parser.add_option('-p', '--port', type="int", default=2121, metavar="PORT", help="specify port number to run on (default 21)") parser.add_option('-w', '--write', action="store_true", default=False, help="grants write access for the anonymous user " "(default read-only)") parser.add_option('-d', '--directory', default=getcwdu(), metavar="FOLDER", help="specify the directory to share (default current " "directory)") parser.add_option('-n', '--nat-address', default=None, metavar="ADDRESS", help="the NAT address to use for passive connections") parser.add_option('-r', '--range', default=None, metavar="FROM-TO", help="the range of TCP ports to use for passive " "connections (e.g. -r 8000-9000)") parser.add_option('-v', '--version', action='store_true', help="print pyftpdlib version and exit") options, args = parser.parse_args() if options.version: sys.exit("pyftpdlib %s" % __ver__) passive_ports = None if options.range: try: start, stop = options.range.split('-') start = int(start) stop = int(stop) except ValueError: parser.error('invalid argument passed to -r option') else: passive_ports = list(range(start, stop + 1)) # On recent Windows versions, if address is not specified and IPv6 # is installed the socket will listen on IPv6 by default; in this # case we force IPv4 instead. if os.name in ('nt', 'ce') and not options.interface: options.interface = '0.0.0.0' authorizer = DummyAuthorizer() perm = options.write and "elradfmwM" or "elr" authorizer.add_anonymous(options.directory, perm=perm) handler = FTPHandler handler.authorizer = authorizer handler.masquerade_address = options.nat_address handler.passive_ports = passive_ports ftpd = FTPServer((options.interface, options.port), FTPHandler) try: ftpd.serve_forever() finally: ftpd.close_all()
def test_override_user_homedir(self): auth = self.authorizer_class() user = self.get_current_user() dir = os.path.dirname(getcwdu()) auth.override_user(user, homedir=dir) self.assertEqual(auth.get_home_dir(user), dir) # make sure other settings keep using default values #self.assertEqual(auth.get_home_dir(user), self.get_current_user_homedir()) self.assertEqual(auth.get_perms(user), "elradfmw") self.assertEqual(auth.get_msg_login(user), "Login successful.") self.assertEqual(auth.get_msg_quit(user), "Goodbye.")
def test_ftp2fs(self): # Tests for ftp2fs method. def join(x, y): return os.path.join(x, y.replace('/', os.sep)) ae = self.assertEqual fs = AbstractedFS(u('/'), None) def goforit(root): fs._root = root fs._cwd = u('/') ae(fs.ftp2fs(u('')), root) ae(fs.ftp2fs(u('/')), root) ae(fs.ftp2fs(u('.')), root) ae(fs.ftp2fs(u('..')), root) ae(fs.ftp2fs(u('a')), join(root, u('a'))) ae(fs.ftp2fs(u('/a')), join(root, u('a'))) ae(fs.ftp2fs(u('/a/')), join(root, u('a'))) ae(fs.ftp2fs(u('a/..')), root) ae(fs.ftp2fs(u('a/b')), join(root, u(r'a/b'))) ae(fs.ftp2fs(u('/a/b')), join(root, u(r'a/b'))) ae(fs.ftp2fs(u('/a/b/..')), join(root, u('a'))) ae(fs.ftp2fs(u('/a/b/../..')), root) fs._cwd = u('/sub') ae(fs.ftp2fs(u('')), join(root, u('sub'))) ae(fs.ftp2fs(u('/')), root) ae(fs.ftp2fs(u('.')), join(root, u('sub'))) ae(fs.ftp2fs(u('..')), root) ae(fs.ftp2fs(u('a')), join(root, u('sub/a'))) ae(fs.ftp2fs(u('a/')), join(root, u('sub/a'))) ae(fs.ftp2fs(u('a/..')), join(root, u('sub'))) ae(fs.ftp2fs(u('a/b')), join(root, 'sub/a/b')) ae(fs.ftp2fs(u('a/b/..')), join(root, u('sub/a'))) ae(fs.ftp2fs(u('a/b/../..')), join(root, u('sub'))) ae(fs.ftp2fs(u('a/b/../../..')), root) # UNC paths must be collapsed ae(fs.ftp2fs(u('//a')), join(root, u('a'))) if os.sep == '\\': goforit(u(r'C:\dir')) goforit(u('C:\\')) # on DOS-derived filesystems (e.g. Windows) this is the same # as specifying the current drive directory (e.g. 'C:\\') goforit(u('\\')) elif os.sep == '/': goforit(u('/home/user')) goforit(u('/')) else: # os.sep == ':'? Don't know... let's try it anyway goforit(getcwdu())
def test_fs2ftp(self): # Tests for fs2ftp method. def join(x, y): return os.path.join(x, y.replace('/', os.sep)) ae = self.assertEqual fs = AbstractedFS(u('/'), None) def goforit(root): fs._root = root ae(fs.fs2ftp(root), u('/')) ae(fs.fs2ftp(join(root, u('/'))), u('/')) ae(fs.fs2ftp(join(root, u('.'))), u('/')) # can't escape from root ae(fs.fs2ftp(join(root, u('..'))), u('/')) ae(fs.fs2ftp(join(root, u('a'))), u('/a')) ae(fs.fs2ftp(join(root, u('a/'))), u('/a')) ae(fs.fs2ftp(join(root, u('a/..'))), u('/')) ae(fs.fs2ftp(join(root, u('a/b'))), u('/a/b')) ae(fs.fs2ftp(join(root, u('a/b'))), u('/a/b')) ae(fs.fs2ftp(join(root, u('a/b/..'))), u('/a')) ae(fs.fs2ftp(join(root, u('/a/b/../..'))), u('/')) fs._cwd = u('/sub') ae(fs.fs2ftp(join(root, 'a/')), u('/a')) if os.sep == '\\': goforit(u(r'C:\dir')) goforit(u('C:\\')) # on DOS-derived filesystems (e.g. Windows) this is the same # as specifying the current drive directory (e.g. 'C:\\') goforit(u('\\')) fs._root = u(r'C:\dir') ae(fs.fs2ftp(u('C:\\')), u('/')) ae(fs.fs2ftp(u('D:\\')), u('/')) ae(fs.fs2ftp(u('D:\\dir')), u('/')) elif os.sep == '/': goforit(u('/')) if os.path.realpath('/__home/user') != '/__home/user': self.fail('Test skipped (symlinks not allowed).') goforit(u('/__home/user')) fs._root = u('/__home/user') ae(fs.fs2ftp(u('/__home')), u('/')) ae(fs.fs2ftp(u('/')), u('/')) ae(fs.fs2ftp(u('/__home/userx')), u('/')) else: # os.sep == ':'? Don't know... let's try it anyway goforit(getcwdu())
if sys.version_info < (2, 7): import unittest2 as unittest # pip install unittest2 else: import unittest sendfile = _import_sendfile() # Attempt to use IP rather than hostname (test suite will run a lot faster) try: HOST = socket.gethostbyname('localhost') except socket.error: HOST = 'localhost' USER = '******' PASSWD = '12345' HOME = getcwdu() # Disambiguate TESTFN for parallel testing. if os.name == 'java': # Jython disallows @ in module names TESTFN_PREFIX = '$pyftpd-%s-' % os.getpid() else: TESTFN_PREFIX = '@pyftpd-%s-' % os.getpid() TIMEOUT = 2 BUFSIZE = 1024 INTERRUPTED_TRANSF_SIZE = 32768 NO_RETRIES = 5 OSX = sys.platform.startswith("darwin") POSIX = os.name == 'posix' WINDOWS = os.name == 'nt' TRAVIS = bool(os.environ.get('TRAVIS')) VERBOSITY = 1 if os.getenv('SILENT') else 2
def main(): """Start a stand alone anonymous FTP server.""" import optparse import sys import os from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.handlers import FTPHandler from pyftpdlib.servers import FTPServer from pyftpdlib._compat import getcwdu class CustomizedOptionFormatter(optparse.IndentedHelpFormatter): """Formats options shown in help in a prettier way.""" def format_option(self, option): result = [] opts = self.option_strings[option] result.append(' %s\n' % opts) if option.help: help_text = ' %s\n\n' % self.expand_default(option) result.append(help_text) return ''.join(result) usage = "python -m pyftpdlib.ftpserver [options]" parser = optparse.OptionParser(usage=usage, description=main.__doc__, formatter=CustomizedOptionFormatter()) parser.add_option('-i', '--interface', default='', metavar="ADDRESS", help="specify the interface to run on (default all " "interfaces)") parser.add_option('-p', '--port', type="int", default=21, metavar="PORT", help="specify port number to run on (default 21)") parser.add_option('-w', '--write', action="store_true", default=False, help="grants write access for the anonymous user " "(default read-only)") parser.add_option('-d', '--directory', default=getcwdu(), metavar="FOLDER", help="specify the directory to share (default current " "directory)") parser.add_option('-n', '--nat-address', default=None, metavar="ADDRESS", help="the NAT address to use for passive connections") parser.add_option('-r', '--range', default=None, metavar="FROM-TO", help="the range of TCP ports to use for passive " "connections (e.g. -r 8000-9000)") parser.add_option('-v', '--version', action='store_true', help="print pyftpdlib version and exit") options, args = parser.parse_args() if options.version: sys.exit("pyftpdlib %s" % __ver__) passive_ports = None if options.range: try: start, stop = options.range.split('-') start = int(start) stop = int(stop) except ValueError: parser.error('invalid argument passed to -r option') else: passive_ports = list(range(start, stop + 1)) # On recent Windows versions, if address is not specified and IPv6 # is installed the socket will listen on IPv6 by default; in this # case we force IPv4 instead. if os.name in ('nt', 'ce') and not options.interface: options.interface = '0.0.0.0' authorizer = DummyAuthorizer() perm = options.write and "elradfmwM" or "elr" authorizer.add_anonymous(options.directory, perm=perm) handler = FTPHandler handler.authorizer = authorizer handler.masquerade_address = options.nat_address handler.passive_ports = passive_ports ftpd = FTPServer((options.interface, options.port), FTPHandler) ftpd.serve_forever()
sendfile = None if os.name == 'posix': try: import sendfile except ImportError: pass # Attempt to use IP rather than hostname (test suite will run a lot faster) try: HOST = socket.gethostbyname('localhost') except socket.error: HOST = 'localhost' USER = '******' PASSWD = '12345' HOME = getcwdu() TESTFN = 'tmp-pyftpdlib' TESTFN_UNICODE = TESTFN + '-unicode-' + '\xe2\x98\x83' TESTFN_UNICODE_2 = TESTFN_UNICODE + '-2' TIMEOUT = 2 BUFSIZE = 1024 INTERRUPTED_TRANSF_SIZE = 32768 NO_RETRIES = 5 OSX = sys.platform.startswith("darwin") POSIX = os.name == 'posix' WINDOWS = os.name == 'nt' TRAVIS = bool(os.environ.get('TRAVIS')) VERBOSITY = 1 if os.getenv('SILENT') else 2 class TestCase(unittest.TestCase):
def main(): """Start a stand alone anonymous FTP server.""" usage = "python -m pyftpdlib.ftpserver [options]" parser = optparse.OptionParser(usage=usage, description=main.__doc__, formatter=CustomizedOptionFormatter()) parser.add_option('-i', '--interface', default=None, metavar="ADDRESS", help="specify the interface to run on (default all " "interfaces)") parser.add_option('-p', '--port', type="int", default=2121, metavar="PORT", help="specify port number to run on (default 21)") parser.add_option('-w', '--write', action="store_true", default=False, help="grants write access for the anonymous user " "(default read-only)") parser.add_option('-d', '--directory', default=getcwdu(), metavar="FOLDER", help="specify the directory to share (default current " "directory)") parser.add_option('-n', '--nat-address', default=None, metavar="ADDRESS", help="the NAT address to use for passive connections") parser.add_option('-r', '--range', default=None, metavar="FROM-TO", help="the range of TCP ports to use for passive " "connections (e.g. -r 8000-9000)") parser.add_option('-v', '--version', action='store_true', help="print pyftpdlib version and exit") parser.add_option('-V', '--verbose', action='store_true', help="activate a more verbose logging") options, args = parser.parse_args() if options.version: sys.exit("pyftpdlib %s" % __ver__) if options.verbose: import logging import pyftpdlib.log pyftpdlib.log.LEVEL = logging.DEBUG passive_ports = None if options.range: try: start, stop = options.range.split('-') start = int(start) stop = int(stop) except ValueError: parser.error('invalid argument passed to -r option') else: passive_ports = list(range(start, stop + 1)) # On recent Windows versions, if address is not specified and IPv6 # is installed the socket will listen on IPv6 by default; in this # case we force IPv4 instead. if os.name in ('nt', 'ce') and not options.interface: options.interface = '0.0.0.0' authorizer = DummyAuthorizer() perm = options.write and "elradfmwM" or "elr" authorizer.add_anonymous(options.directory, perm=perm) handler = FTPHandler handler.authorizer = authorizer handler.masquerade_address = options.nat_address handler.passive_ports = passive_ports ftpd = FTPServer((options.interface, options.port), FTPHandler) try: ftpd.serve_forever() finally: ftpd.close_all()