| Bug tracker at http://code.google.com/p/pyftpdlib/issues/list |
| |
| |
| History |
| ======= |
| |
| Version: 1.3.1 - Date: XXXX-XX-XX |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #262: FTPS is now able to load a certificate chain file. (patch by |
| briantomko) |
| * #277: added a make file for running tests and for other repetitive tasks |
| (also for Windows). |
| * #281: tarballs are now hosted on PYPI. |
| * #285: test suite requires unittest2 module on python < 2.7. |
| |
| BUG FIXES |
| |
| * #261: (FTPS) SSL shutdown does not properly work on Windows. |
| * #280: (Python 2) unable to complete directory listing with invalid UTF8 |
| characters. (patch by dn@devicenull.org) |
| * #283: always use a single 'pyftpdlib' logger. |
| |
| |
| Version: 1.3.0 - Date: 2013-11-07 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #253: benchmark script's new --timeout option. |
| * #270: new -V / --verbose cmdline option to enable a more verbose logging. |
| |
| BUG FIXES |
| |
| * #254: bench.py script hadn't been ported to Python 3. |
| * #263: MultiprocessFTPServer leaks memory and file descriptors. (patch by |
| Juan J. Martinez) |
| * #265: FTPServer class cannot be used with Circus. |
| * #272: pyftpdlib fails when imported on OpenBSD because of Python bug |
| http://bugs.python.org/issue3770 |
| * #273: IOLoop.fileno() on BSD systems raises AttributeError. (patch by |
| Michael Ross) |
| |
| |
| Version: 1.2.0 - Date: 2013-04-22 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #250: added FTPServer's backlog argument controlling the queue of accepted |
| connections. |
| * #251: IOLoop.fileno() method for epoll() and kqueue() pollers. |
| * #252: FTPServer 'address' parameter can also be an existent socket object. |
| |
| BUG FIXES |
| |
| * #245: ThreadedFTPServer hogs all CPU resources after a client connects. |
| |
| |
| Version: 1.1.0 - Date: 2013-04-09 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #240: enabled "python -m pyftpdlib" cmdline syntax and got rid of |
| "python -m pyftpdlib.ftpserver" syntax which was deprecated in 1.0.0. |
| * #241: empty passwords are now allowed for anonymous and other users. |
| * #244: pysendfile is no longer a dependency if we're on Python >= 3.3 as |
| os.sendfile() will be used instead. |
| * #247: on python 3.3 use time.monotonic() instead of time.time() so that the |
| scheduler won't break in case of system clock updates. |
| * #248: bench.py memory usage is highly overestimated. |
| |
| BUG FIXES |
| |
| * #238: username is not logged in case of failed authentication. |
| (patch by tlockert) |
| * #243: an erroneous error message is given in case the address passed to |
| bind() is already in use. |
| * #245: ThreadedFTPServer hogs all CPU resources after a client connects. |
| * #246: ThrottledDTPHandler was broken. |
| |
| INCOMPATIBLE API CHANGES |
| |
| * "python -m pyftpdlib.ftpserver" cmdline syntax doesn't work anymore |
| |
| |
| Version: 1.0.1 - Date: 2013-02-22 |
| --------------------------------- |
| |
| BUG FIXES |
| |
| * #236: MultiprocessFTPServer and ThreadedFTPServer hanging in case of failed |
| authentication. |
| |
| |
| Version: 1.0.0 - Date: 2013-02-19 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #76: python 3.x porting. |
| * #198: full unicode support (RFC-2640). |
| * #203: asyncore IO loop has been rewritten from scratch and now supports |
| epoll() on Linux and kqueue() on OSX/BSD. |
| Also select() (Windows) and poll() pollers have been rewritten |
| resulting in pyftpdlib being an order of magnitude faster and more |
| scalable than ever. |
| * #204: a new FilesystemError exception class is available in order send |
| custom error strings to client from an AbstracteFS subclass. |
| * #207: added on_connect() and on_disconnect() callback methods to FTPHandler |
| class. |
| * Issues 212: provided two new classes: |
| - pyftpdlib.servers.ThreadedFTPServer |
| - pyftpdlib.servers.MultiprocessFTPServer (POSIX only) |
| They can be used to change the base async-based concurrecy model and |
| use a multiple threads / processes based approach instead. |
| Your FTPHandler subclasses will finally be free to block! ;) |
| * #219: it is not possible to instantiate different FPTS classes using |
| different SSL certificates. |
| * #213: DummyAuthorizer.validate_authentication() has changed in that it |
| no longer returns a bool but instead raises AuthenticationFailed() |
| exception to signal a failed authentication. |
| This has been done in order allow customized error messages on failed |
| auth. Also it now expects a third 'handler' argument which is passed in |
| order to allow IP-based authentication logic. Existing code overriding |
| validate_authentication() must be changed in accordance. |
| * #223: ftpserver.py has been split in submodules. |
| * #225: logging module is now used for logging. ftpserver.py's log(), logline() |
| and logerror() functions are deprecated. |
| * #231: FTPHandler.ftp_* methods implementing filesystem-related commands |
| now return a meaningful value on success (tipically the path name). |
| * #234: FTPHandler and DTPHandler class provide a nice __repr__. |
| * #235: FTPServer.serve_forever() has a new handle_exit parameter which |
| can be set to False in order to avoid handling SIGTERM/SIGINT signals |
| and logging server start and stop. |
| * #236: big logging refactoring; by default only useful messages are logged |
| (as opposed to *all* commands and responses exchanged by client and |
| server). Also, FTPHandler has a new 'log_prefix' attribute which can |
| be used to format every line logged. |
| |
| BUG FIXES |
| |
| * #131: IPv6 dual-stack support was broken. |
| * #206: can't change directory (CWD) when using UnixAuthorizer and process |
| cwd is == "/root". |
| * #211: pyftpdlib doesn't work if deprecated py-sendfile 1.2.4 module is |
| installed. |
| * #215: usage of FTPHandler.sleeping attribute could lead to 100% CPU usage. |
| FTPHandler.sleeping is now removed. self.add_channel() / |
| self.del_channel() should be used instead. |
| * #222: an unhandled exception in handle_error() or close() can cause server |
| to crash. |
| * #229: backslashes on UNIX are not handled properly. |
| * #232: hybrid IPv4/IPv6 support is broken. (patch by Claus Klein) |
| |
| NEW MODULES |
| |
| All the code contained in pyftpdlib/ftpserver.py and pyftpdlib/contrib |
| namespaces has been moved here: |
| |
| * pyftpdlib.authorizers |
| * pyftpdlib.filesystems |
| * pyftpdlib.servers |
| * pyftpdlib.handlers |
| * pyftpdlib.log |
| |
| NEW APIS |
| |
| * pyftpdlib.authorizers.AuthenticationFailed |
| * pyftpdlib.filesystems.FilesystemError |
| * pyftpdlib.servers.ThreadedFTPServer |
| * pyftpdlib.servers.MultiprocessFTPServer |
| * pyftpdlib.handlers.FTPHandler's on_connect() and on_disconnect() callbacks. |
| * pyftpdlib.handlers.FTPHandler.ftp_* methods return a meaningful value on |
| success. |
| * FTPServer, FTPHandler, DTPHandler new ioloop attribute. |
| * pyftpdlib.lib.ioloop.IOLoop class (not supposed to be used directly) |
| * pyftpdlib.handlers.FTPHandler.log_prefix |
| |
| DEPRECATED NAME SPACES |
| |
| * pyftpdlib.ftpserver |
| * pyftpdlib.contrib.* |
| |
| INCOMPATIBLE API CHANGES |
| |
| * All the main classes have been extracted from ftpserver.py and split into sub |
| modules. |
| |
| ---------------------------------------------------------------------------- |
| BEFORE | NOW |
| ---------------------------------------------------------------------------- |
| pyftpdlib.ftpserver.FTPServer | pyftpdlib.servers.FTPServer |
| pyftpdlib.ftpserver.FTPHandler | pyftpdlib.handlers.FTPHandler |
| pyftpdlib.ftpserver.DTPHandler | pyftpdlib.handlers.DTPHandler |
| pyftpdlib.ftpserver.DummyAuthorizer | pyftpdlib.authorizers.DummyAuthorizer |
| pyftpdlib.ftpserver.AbstractedFS | pyftpdlib.filesystems.AbstractedFS |
| ---------------------------------------------------------------------------- |
| |
| Same for pyftpflib.contribs namespace which is deprecated. |
| |
| ------------------------------------------------------------------------------------------- |
| BEFORE | NOW |
| ------------------------------------------------------------------------------------------- |
| pyftpdlib.contrib.handlers.TLS_FTPHandler | pyftpdlib.handlers.TLS_FTPHandler |
| pyftpdlib.contrib.authorizers.UnixAuthorizer | pyftpdlib.authorizers.UnixAuthorizer |
| pyftpdlib.contrib.authorizers.WindowsAuthorizer | pyftpdlib.authorizers.WindowsAuthorizer |
| pyftpdlib.contrib.filesystems.UnixFilesystem | pyftpdlib.filesystems.UnixFilesystem |
| ------------------------------------------------------------------------------------------- |
| |
| Both imports from pyftpdlib.ftpserver and pyftpdlib.contrib.* will still work |
| though and will raise a DeprecationWarning exception. |
| |
| * DummyAuthorizer.validate_authentication() signature has changed. A third |
| 'handler' argument is now expected. |
| |
| * DummyAuthorizer.validate_authentication() is no longer expected to return a |
| bool. Instead it is supposed to raise AuthenticationFailed(msg) in case of |
| failed authentication and return None otherwise. |
| (see issue 213) |
| |
| * ftpserver.py's log(), logline() and logerror() functions are deprecated. |
| logging module is now used instead. See: |
| http://code.google.com/p/billiejoex/wiki/Tutorial#4.2_-_Logging_management |
| |
| * Unicode is now used instead of bytes pretty much everywhere. |
| |
| * FTPHandler.__init__() and TLS_FTPHandler.__init__() signatures have changed: |
| - __init__(conn, server) |
| + __init__(conn, server, ioloop=None) |
| |
| * FTPServer.server_forever() signature has changed: |
| - serve_forever(timeout=1.0, use_poll=False, count=None) |
| + serve_forever(timeout=1.0, blocking=True, handle_exit=True) |
| |
| * FTPServer.close_all() signature has changed: |
| - close_all(ignore_all=False) |
| + close_all() |
| |
| * FTPServer.serve_forever() and FTPServer.close_all() are no longer class |
| methods. |
| |
| * asyncore.dispatcher and asynchat.async_chat classes has been replaced by: |
| - pyftpdlib.ioloop.Acceptor |
| - pyftpdlib.ioloop.Connector |
| - pyftpdlib.ioloop.AsyncChat |
| Any customization relying on asyncore (e.g. use of asyncore.socket_map to |
| figure out the number of connected clients) will no longer work. |
| |
| * pyftpdlib.ftpserver.CallLater and pyftpdlib.ftpserver.CallEvery are |
| deprecated. Instead, use self.ioloop.call_later() and self.ioloop.call_every() |
| from within the FTPHandler. Also delay() method of the returned object has |
| been removed. |
| |
| * FTPHandler.sleeping attribute is removed. self.add_channel() and |
| self.del_channel() should be used to pause and restart the handler. |
| |
| MINOR INCOMPATIBLE API CHANGES |
| |
| - FTPHandler.respond(resp) |
| + FTPHandler.respond(resp, logfun=logger.debug) |
| |
| - FTPHandler.log(resp) |
| + FTPHandler.log(resp, logfun=logger.info) |
| |
| - FTPHandler.logline(resp) |
| + FTPHandler.logline(resp, logfun=logger.debug) |
| |
| |
| Version: 0.7.0 - Date: 2012-01-25 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #152: uploads (from server to client) on UNIX are now from 2x (Linux) to 3x |
| (OSX) faster because of sendfile(2) system call usage. |
| * #155: AbstractedFS "root" and "cwd" are no longer read-only properties but |
| can be set via setattr(). |
| * #168: added FTPHandler.logerror() method. It can be overridden to provide |
| more information (e.g. username) when logging exception tracebacks. |
| * #174: added support for SITE CHMOD command (change file mode). |
| * #177: setuptools is now used in setup.py |
| * #178: added anti flood script in demo directory. |
| * #181: added CallEvery class to call a function every x seconds. |
| * #185: pass Debian licenscheck tool. |
| * #189: the internal scheduler has been rewritten from scratch and it is an |
| order of magnitude faster, especially for operations like cancel() |
| which are involved when clients are disconnected (hence invoked very |
| often). Some benchmarks: |
| - schedule : +0.5x |
| - reschedule : +1.7x |
| - cancel : +477x (with 1 milion scheduled functions) |
| - run: : +8x |
| Also, a single scheduled function now consumes 1/3 of the memory thanks |
| to __slots__ usage. |
| * #195: enhanced unix_daemon.py script which (now uses python-daemon library). |
| * #196: added callback for failed login attempt. |
| * #200: FTPServer.server_forever() is now a class method. |
| * #202: added benchmark script. |
| |
| BUG FIXES |
| |
| * #156: data connection must be closed before sending 226/426 reply. This was |
| against RFC-959 and was causing problems with older FTP clients. |
| * #161: MLSD 'unique' fact can provide the same value for files having a |
| similar device/inode but that in fact are different. |
| (patch by Andrew Scheller) |
| * #162: (FTPS) SSL shutdown() is not invoked for the control connection. |
| * #163: FEAT erroneously reports MLSD. (patch by Andrew Scheller) |
| * #166: (FTPS) an exception on send() can cause server to crash (DoS). |
| * #167: fix some typos returned on HELP. |
| * #170: PBSZ and PROT commands are now allowed before authentication fixing |
| problems with non-compliant FTPS clients. |
| * #171: (FTPS) an exception when shutting down the SSL layer can cause server |
| to crash (DoS). |
| * #173: file last modification time shown in LIST response might be in a |
| language different than English causing problems with some clients. |
| * #175: FEAT response now omits to show those commands which are removed from |
| proto_cmds map. |
| * #176: SO_REUSEADDR option is now used for passive data sockets to prevent |
| server running out of free ports when using passive_ports directive. |
| * #187: match proftpd LIST format for files having last modification time |
| > 6 months. |
| * #188: fix maximum recursion depth exceeded exception occurring if client |
| quickly connects and disconnects data channel. |
| * #191: (FTPS) during SSL shutdown() operation the server can end up in an |
| infinite loop hogging CPU resources. |
| * #199: UnixAuthorizer with require_valid_shell option is broken. |
| |
| MAJOR API CHANGES SINCE 0.6.0: |
| |
| * New FTPHandler.use_sendfile attribute. |
| * sendfile() is now automatically used instead of plain send() if |
| pysendfile module is installed. |
| * FTPServer.serve_forever() is a classmethod. |
| * AbstractedFS root and cwd properties can now be set via setattr(). |
| * New CallLater class. |
| * New FTPHandler.on_login_failed(username, password) method. |
| * New FTPHandler.logerror(msg) method. |
| * New FTPHandler.log_exception(instance) method. |
| |
| |
| Version: 0.6.0 - Date: 2011-01-24 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #68: added full FTPS (FTP over SSL/TLS) support provided by new |
| TLS_FTPHandler class defined in pyftpdlib.contrib.handlers module. |
| * #86: pyftpdlib now reports all ls and MDTM timestamps as GMT times, as |
| recommended in RFC-3659. A FTPHandler.use_gmt_times attributed has |
| been added and can be set to False in case local times are desired |
| instead. |
| * #124: pyftpdlib now accepts command line options to configure a stand alone |
| anonymous FTP server when running pyftpdlib with python's -m option. |
| * #125: logs are now provided in a standardized format parsable by log |
| analyzers. FTPHandler class provides two new methods to standardize |
| both commands and transfers logging: log_cmd() and log_transfer(). |
| * #127: added FTPHandler.masquerade_address_map option which allows you to |
| define multiple 1 to 1 mappings in case you run a FTP server with |
| multiple private IP addresses behind a NAT firewall with multiple |
| public IP addresses. |
| * #128: files and directories owner and group names and os.readlink are now |
| resolved via AbstractedFS methods instead of in format_list(). |
| * #129: |
| #139: added 4 new callbacks to FTPHandler class: |
| on_incomplete_file_sent(), on_incomplete_file_received(), on_login() |
| and on_logout(). |
| * #130: added UnixAuthorizer and WindowsAuthorizer classes defined in the new |
| pyftpdlib.contrib.authorizers module. |
| * #131: pyftpdlib is now able to serve both IPv4 and IPv6 at the same time by |
| using a single socket. |
| * #133: AbstractedFS constructor now accepts two argumets: root and cmd_channel |
| breaking compatibility with previous version. Also, root and and cwd |
| attributes became properties. The previous bug consisting in resetting |
| the root from the ftp handler after user login has been fixed to ease |
| the development of subclasses. |
| * #134: enabled TCP_NODELAY socket option for the FTP command channels |
| resulting in pyftpdlib being twice faster. |
| * #135: Python 2.3 support has been dropped. |
| * #137: added new pyftpdlib.contrib.filesystems module within |
| UnixFilesystem class which permits the client to escape its home |
| directory and navigate the real filesystem. |
| * #138: added DTPHandler.get_elapsed_time() method which returns the transfer |
| elapsed time in seconds. |
| * #144: a "username" parameter is now passed to authorizer's |
| terminate_impersonation() method. |
| * #149: ftpserver.proto_cmds dictionary refactoring and get rid of |
| _CommandProperty class. |
| |
| BUG FIXES |
| |
| * #120: an ActiveDTP() instance is not garbage collected in case a client |
| issuing PORT disconnects before establishing the data connection. |
| * #122: a wrong variable name was used in AbstractedFS.validpath method. |
| * #123: PORT command doesn't bind to correct address in case an alias is |
| created for the local network interface. |
| * #140: pathnames returned in PWD response should have double-quotes '"' |
| escaped. |
| * #143: EINVAL not properly handled causes server crash on OSX. |
| * #146: SIZE and MDTM commands are now rejected unless the "l" permission has |
| been specified for the user. |
| * #150: path traversal bug: it is possible to move/rename a file outside of the |
| user home directory. |
| |
| MAJOR API CHANGES SINCE 0.5.2 |
| |
| * dropped Python 2.3 support. |
| * all classes are now new-style classes. |
| * AbstractedFS class: |
| * __init__ now accepts two arguments: root and cmd_channel. |
| * root and cwd attributes are now read-only properties. |
| * 3 new methods have been added: |
| - get_user_by_uid() |
| - get_group_by_gid() |
| - readlink() |
| * FTPHandler class: |
| * new class attributes: |
| - use_gmt_times |
| - tcp_no_delay |
| - masquerade_address_map |
| * new methods: |
| - on_incomplete_file_sent() |
| - on_incomplete_file_received() |
| - on_login() |
| - on_logout() |
| - log_cmd() |
| - log_transfer() |
| * proto_cmds class attribute has been added. The FTPHandler class no |
| longer relies on "ftpserver.proto_cmds" global dictionary but on |
| "ftpserver.FTPHandler.proto_cmds" instead. |
| * FTPServer class: |
| - max_cons attribute defaults to 512 by default instead of 0 (unlimited). |
| - server_forever()'s map argument is gone. |
| * DummyAuthorizer: |
| - ValueError exceptions are now raised instead of AuthorizerError. |
| - terminate_impersonation() method now expects a "username" parameter. |
| * DTPHandler.get_elapsed_time() method has been added. |
| * Added a new package in pyftpdlib namespace: "contrib". Modules (and classes) |
| defined here: |
| - pyftpdlib.contrib.handlers.py (TLS_FTPHandler) |
| - pyftpdlib.contrib.authorizers.py (UnixAuthorizer, WindowsAuthorizer) |
| - pyftpdlib.contrib.filesystems (UnixFilesystem) |
| |
| MINOR API CHANGES SINCE 0.5.2 |
| |
| * FTPHandler renamed objects: |
| - data_server -> _dtp_acceptor |
| - current_type -> _current_type |
| - restart_position -> _restart_position |
| - quit_pending -> _quit_pending |
| - af -> _af |
| - on_dtp_connection -> _on_dtp_connection |
| - on_dtp_close -> _on_dtp_close |
| - idler -> _idler |
| * AbstractedFS.rnfr attribute moved to FTPHandler._rnfr. |
| |
| |
| Version: 0.5.2 - Date: 2009-09-14 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #103: added unix_daemon.py script. |
| * #108: a new ThrottledDTPHandler class has been added for limiting the speed |
| of downloads and uploads. |
| |
| BUG FIXES |
| |
| * #100: fixed a race condition in FTPHandler constructor which could throw an |
| exception in case of connection bashing (DoS). (thanks Bram Neijt) |
| * #102: FTPServer.close_all() now removes any unfired delayed call left behind |
| to prevent potential memory leaks. |
| * #104: fixed a bug in FTPServer.handle_accept() where socket.accept() could |
| return None instead of a valid address causing the server to crash. |
| (OS X only, reported by Wentao Han) |
| * #104: an unhandled EPIPE exception might be thrown by asyncore.recv() when |
| dealing with ill-behaved clients on OS X . (reported by Wentao Han) |
| * #105: ECONNABORTED might be thrown by socket.accept() on FreeBSD causing the |
| server to crash. |
| * #109: an unhandled EBADF exception might be thrown when using poll() on OSX |
| and FreeBSD. |
| * #111: the license used was not MIT as stated in source files. |
| * #112: fixed a MDTM related test case failure occurring on 64 bit OSes. |
| * #113: fixed unix_ftp.py which was treating anonymous as a normal user. |
| * #114: MLST is now denied unless the "l" permission has been specified for the |
| user. |
| * #115: asyncore.dispatcher.close() is now called before doing any other |
| cleanup operation when client disconnects. This way we avoid an endless |
| loop which hangs the server in case an exception is raised in close() |
| method. (thanks Arkadiusz Wahlig) |
| * #116: extra carriage returns were added to files transferred in ASCII mode. |
| * #118: CDUP always changes to "/". |
| * #119: QUIT sent during a transfer caused a memory leak. |
| |
| |
| API CHANGES SINCE 0.5.1: |
| |
| * ThrottledDTPHandler class has been added. |
| * FTPHandler.process_command() method has been added. |
| |
| |
| Version: 0.5.1 - Date: 2009-01-21 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #79: added two new callback methods to FTPHandler class to handle |
| "on_file_sent" and "on_file_received" events. |
| * #82: added table of contents in documentation. |
| * #92: ASCII transfers are now 200% faster on those systems using "\r\n" as |
| line separator (typically Windows). |
| * #94: a bigger buffer size for send() and recv() has been set resulting in a |
| considerable speedup (about 40% faster) for both incoming and outgoing |
| data transfers. |
| * #98: added preliminary support for SITE command. |
| * #99: a new script implementing FTPS (FTP over TLS/SSL) has been added to the |
| demo directory. See: |
| http://code.google.com/p/pyftpdlib/source/browse/trunk/demo/tls_ftpd.py |
| |
| BUG FIXES |
| |
| * #78: the idle timeout of passive data connections gets stopped in case of |
| rejected "site-to-site" connections. |
| * #80: demo/md5_ftpd.py should use hashlib module instead of the deprecated md5 |
| module. |
| * #81: fixed some tests which were failing on SunOS. |
| * #84: fixed a very rare unhandled exception which could occur when retrieving |
| the first bytes of a corrupted file. |
| * #85: a positive MKD response is supposed to include the name of the new |
| directory. |
| * #87: SIZE should be rejected when the current TYPE is ASCII. |
| * #88: REST should be rejected when the current TYPE is ASCII. |
| * #89: "TYPE AN" was erroneously treated as synonym for "TYPE A" when "TYPE L7" |
| should have been used instead. |
| * #90: an unhandled exception can occur when using MDTM against a file modified |
| before year 1900. |
| * #91: an unhandled exception can occur in case accept() returns None instead |
| of a socket (it happens sometimes). |
| * #95: anonymous is now treated as any other case-sensitive user. |
| |
| API CHANGES SINCE 0.5.0: |
| |
| * FTPHandler gained a new "_extra_feats" private attribute. |
| * FTPHandler gained two new methods: "on_file_sent" and "on_file_received". |
| |
| |
| Version: 0.5.0 - Date: 2008-09-20 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #72: pyftpdlib now provides configurable idle timeouts to disconnect client |
| after a long time of inactivity. |
| * #73: imposed a delay before replying for invalid credentials to minimize the |
| risk of brute force password guessing (RFC-1123). |
| * #74: it is now possible to define permission exceptions for certain |
| directories (e.g. creating a user which does not have write permission |
| except for one sub-directory in FTP root). |
| * # Improved bandwidth throttling capabilities of demo/throttled_ftpd.py |
| script by having used the new CallLater class which drastically reduces |
| the number of time.time() calls. |
| |
| BUG FIXES |
| |
| * #62: some unit tests were failing on certain dual core machines. |
| * #71: socket handles are leaked when a data transfer is in progress and user |
| QUITs. |
| * #75: orphaned file was left behind in case STOU failed for insufficient user |
| permissions. |
| * #77: incorrect OOB data management on FreeBSD. |
| |
| API CHANGES SINCE 0.4.0: |
| |
| * FTPHandler, DTPHandler, PassiveDTP and ActiveDTP classes gained a new timeout |
| class attribute. |
| * DummyAuthorizer class gained a new override_perm method. |
| * A new class called CallLater has been added. |
| * AbstractedFS.get_stat_dir method has been removed. |
| |
| |
| Version: 0.4.0 - Date: 2008-05-16 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #65: It is now possible to assume the id of real users when using system |
| dependent authorizers. |
| * #67: added IPv6 support. |
| |
| BUG FIXES |
| |
| * #64: Issue #when authenticating as anonymous user when using UNIX and Windows |
| authorizers. |
| * #66: WinNTAuthorizer does not determine the real user home directory. |
| * #69: DummyAuthorizer incorrectly uses class attribute instead of instance |
| attribute for user_table dictionary. |
| * #70: a wrong NOOP response code was given. |
| |
| API CHANGES SINCE 0.3.0: |
| |
| * DummyAuthorizer class has now two new methods: impersonate_user() and |
| terminate_impersonation(). |
| |
| |
| Version: 0.3.0 - Date: 2008-01-17 |
| --------------------------------- |
| |
| ENHANCEMENTS |
| |
| * #42: implemented FEAT command (RFC-2389). |
| * #48: real permissions, owner, and group for files on UNIX platforms are now |
| provided when processing LIST command. |
| * #51: added the new demo/throttled_ftpd.py script. |
| * #52: implemented MLST and MLSD commands (RFC-3659). |
| * #58: implemented OPTS command (RFC-2389). |
| * #59: iterators are now used for calculating requests requiring long time to |
| complete (LIST and MLSD commands) drastically increasing the daemon |
| scalability when dealing with many connected clients. |
| * #61: extended the set of assignable user permissions. |
| |
| BUG FIXES |
| |
| * #41: an unhandled exception occurred on QUIT if user was not yet |
| authenticated. |
| * #43: hidden the server identifier returned in STAT response. |
| * #44: a wrong response code was given on PORT in case of failed connection |
| attempt. |
| * #45: a wrong response code was given on HELP if the provided argument wasn't |
| recognized as valid command. |
| * #46: a wrong response code was given on PASV in case of unauthorized FXP |
| connection attempt. |
| * #47: can't use FTPServer.max_cons option on Python 2.3. |
| * #49: a "550 No such file or directory" was returned when LISTing a directory |
| containing a broken symbolic link. |
| * #50: DTPHandler class did not respect what specified in ac_out_buffer_size |
| attribute. |
| * #53: received strings having trailing white spaces was erroneously stripped. |
| * #54: LIST/NLST/STAT outputs are now sorted by file name. |
| * #55: path traversal vulnerability in case of symbolic links escaping user's |
| home directory. |
| * #56: can't rename broken symbolic links. |
| * #57: invoking LIST/NLST over a symbolic link which points to a direoctory |
| shouldn't list its content. |
| * #60: an unhandled IndexError exception error was raised in case of certain |
| bad formatted PORT requests. |
| |
| API CHANGES SINCE 0.2.0: |
| |
| * New IteratorProducer and BufferedIteratorProducer classes have been added. |
| * DummyAuthorizer class changes: |
| * The permissions management has been changed and the set of available |
| permissions have been extended (see Issue #61). add_user() method |
| now accepts "eladfm" permissions beyond the old "r" and "w". |
| * r_perm() and w_perm() methods have been removed. |
| * New has_perm() and get_perms() methods have been added. |
| |
| * AbstractedFS class changes: |
| * normalize() method has been renamed in ftpnorm(). |
| * translate() method has been renamed in ftp2fs(). |
| * New methods: fs2ftp(), stat(), lstat(), islink(), realpath(), lexists(), |
| validpath(). |
| * get_list_dir(), get_stat_dir() and format_list() methods now return an |
| iterator object instead of a string. |
| * format_list() method has a new "ignore_err" keyword argument. |
| * global debug() function has been removed. |
| |
| |
| Version: 0.2.0 - Date: 2007-09-17 |
| --------------------------------- |
| |
| MAJOR ENHANCEMENTS |
| |
| * #5: it is now possible to set a maximum number of connecions and a maximum |
| number of connections from the same IP address. |
| * #36: added support for FXP site-to-site transfer. |
| * #39: added NAT/Firewall support with PASV (passive) mode connections. |
| * #40: it is now possible to set a range of ports to use for passive |
| connections. |
| |
| RFC-RELATED ENHANCEMENTS |
| |
| * #6: accept TYPE AN and TYPE L8 as synonyms for TYPE ASCII and TYPE Binary. |
| * #7: a new USER command can now be entered at any point to begin the login |
| sequence again. |
| * #10: HELP command arguments are now accepted. |
| * #12: 554 error response is now returned on RETR/STOR if RESTart fails. |
| * #15: STAT used with an argument now returns directory LISTing over the |
| command channel (RFC-959). |
| |
| SECURITY ENHANCEMENTS |
| |
| * #3: stop buffering when extremely long lines are received over the command |
| channel. |
| * #11: data connection is now rejected in case a privileged port is specified |
| in PORT command. |
| * #25: limited the number of attempts to find a unique filename when |
| processing STOU command. |
| |
| USABILITY ENHANCEMENTS |
| |
| * # Provided an overridable attribute to easily set number of maximum login |
| attempts before disconnecting. |
| * # Docstrings are now provided for almost every method and function. |
| * #30: HELP response now includes the command syntax. |
| * #31: a compact list of recognized commands is now provided on HELP. |
| * #32: a detailed error message response is not returned to client in |
| case the transfer is interrupted for some unexpected reason. |
| * #38: write access can now be optionally granted for anonymous user. |
| |
| TEST SUITE ENHANCEMENTS |
| |
| * # File creation/removal moved into setUp and tearDown methods to avoid |
| leaving behind orphaned temporary files in the event of a test suite |
| failure. |
| * #7: added test case for USER provided while already authenticated. |
| * #7: added test case for REIN while a transfer is in progress. |
| * #28: added ABOR tests. |
| |
| BUG FIXES |
| |
| * #4: socket's "reuse_address" feature was used after the socket's binding. |
| * #8: STOU string response didn't follow RFC-1123 specifications. |
| * #9: corrected path traversal vulnerability affecting file-system path |
| translations. |
| * #14: a wrong response code was returned on CDUP. |
| * #17: SIZE is now rejected for not regular files. |
| * #18: a wrong ABOR response code type was returned. |
| * #19: watch for STOU preceded by REST which makes no sense. |
| * #20: "attempted login" counter wasn't incremented on wrong username. |
| * #21: STAT wasn't permitted if user wasn't authenticated yet. |
| * #22: corrected memory leaks occurring on KeyboardInterrupt/SIGTERM. |
| * #23: PASS wasn't rejected when user was already authenticated. |
| * #24: Implemented a workaround over os.strerror() for those systems where it |
| is not available (Python CE). |
| * #24: problem occurred on Windows when using '\\' as user's home directory. |
| * #26: select() in now used by default instead of poll() because of a bug |
| inherited from asyncore. |
| * #33: some FTPHandler class attributes wasn't resetted on REIN. |
| * #35: watch for APPE preceded by REST which makes no sense. |
| |
| |
| Version: 0.1.1 - Date: 2007-03-27 |
| ---------------------------------- |
| |
| * Port selection on PASV command has been randomized to prevent a remote user |
| to guess how many data connections are in progress on the server. |
| * Fixed bug in demo/unix_ftpd.py script. |
| * ftp_server.serve_forever now automatically re-use address if current system |
| is posix. |
| * License changed to MIT. |
| |
| |
| Version: 0.1.0 - Date: 2007-02-26 |
| ---------------------------------- |
| |
| * First proof of concept beta release. |