ftpslib is a python module providing a client class for FTP over TLS as described in RFC 4217. The FTP_TLS class is not tied to any specific SSL/TLS module, so third-party modules such as M2Crypto or TLSLite can be used. INSTALLING A distutils setup.py script is provided, so installing the module will, for most people, involve no more than `python setup.py install'. Run `python setup.py --help' for more options. For windows users, an installer executable is provided. USING Like Python's builtin ftplib, ftpslib aims to provided a low level interface to TLS-enabled FTP servers. The FTP_TLS class extends FTP and adds support for the new AUTH, CCC and PROT commands to manage the encryption of the control and data connections. FTP_TLS's constructor requires the `secureConnection' argument which is a function taking an unsecure socket as an argument and returning a TLS socket. Two such functions are provided, one using Python's builtin socket.ssl function and one using the M2Crypto module. See the CHOOSING A MODULE section for more on each of these functions. The commands to change the encryption state of a connection can be sent using either the standard voidcmd/sendcmd means or through the new convenience functions. The control connection is managed through `AUTH' and `CCC' (auth_tls and ccc methods), and the data connection is controlled through the `PROT' command. `TLS' and `TLS-C' are the only supported arguments to AUTH and both are equivalent. If the server supports TLS, the control connection will be encrypted after receipt of a 234 response in the clear. CCC can be used to switch the control connection back to an unencrypted state. As with AUTH, the state of the connection does not change until after the response is received. PROT controls whether future data connections will be encrypted or clear and takes an argument `P' (protect) or `C' (clear). The beginning state required by RFC 4217 is clear. The command `PBSZ 0' must be sent before using PROT: this is sent if using the prot_p and prot_c methods but must be sent manually if using sendcmd/voidcmd. The usual use of FTP and TLS is to encrypt as much of each connection as possible, sending `AUTH TLS' before login and sending `PROT P' before any data transfer. An example of this usage is provided in the module docstring. CAVEATS Although the FTP client controls when and which connections are encrypted, the server can enforce a policy by refusing to accept certain commands before connections are secured. Common behavior is to refuse to accept USER before encrypting the control connection and refuse to open data connections before `PROT P'. Clients should also not expect CCC to be supported. The end-of-file marker for binary data transfers is sent by closing the connection. Many FTP servers close the TCP socket without shutting down the TLS connection. ftpslib attempts to avoid this by using the method in test_ftpslib.py attached to Python bug 978833, overriding retrbinary to read from the socket's makefile wrapper instead of the socket itself. Although this appears to work for the builtin socket.ssl and M2Crypto, it is conceivable for a particular SSL implementation to still throw an exception in this case, and, regardless, the issue is still exposed when using ntransfercmd outside of retrbinary. Note that if an exception is thrown in retrbinary, the response from the last RETR will not be read, causing any future commands to be one response behind. This is especially troublesome if using passive FTP, as the FTP class will be unable to parse the 227 response to future PASV commands. Python class APIs are often ill-defined, in part a result of its lack of member protection features, and ftplib.FTP is no exception. In order to take advantage of the features of its parent class, ftpslib makes some assumptions about the stability of certain undocumented aspects of the FTP interface. The sock and file properties are assumed to be available to superclasses, and it is assumed that the behavior of any overridden methods will not drastically change in the future. When using CCC to revert the control connection from encrypted to clear, data is not flushed from the TLS layer before continuing to send FTP commands on the TCP layer. Although it would require some bizarre buffering and threading behavior, it is possible for a TLS implementation to be written in such a way as to create synchronization issues. CHOOSING A MODULE Like standards, the nice thing about Python SSL/TLS modules is that there are so many to choose from. Also like standards, each has its own special set of pitfalls and quirks. This section is meant more to be a short warning of possible shortcomings than a comprehensive guide for using ftpslib with every available module. socket.ssl: Python's builtin SSL class locks up on close() with some versions of Python (see https://sourceforge.net/tracker/?func=detail&atid=105470&aid=978833&group_id=5470). The class returned by socket.ssl does not provide a Socket interface, and thus an undocumented class in httplib, FakeSocket, is used to attempt to provide one. M2Crypto.SSL.Connection: M2Crypto's SSL Connection class, though providing a socket-like interface, makes an annoying change to the behavior of close. Rather than having it close the TCP connection, close() only closes the TLS connection, leaving the socket open. The provided secureSocket_m2crypto function attempts to circumvent this by returning a superclass of SSL.Connection with an overridden close method. AUTHOR ftpslib is written and maintained by David Shea. Send bugs and comments to david@gophernet.org.