Python FTP implicit TLS connection issue

Extending the solutions that have been proposed so far, the issue is that implicit FTPS connections need the socket to be ssl wrapped automatically, before we get a chance to call login(). A lot of the subclasses that people are proposing do this in the context of the connect method, we can more generally manage this by modifying the get/set of self.sock with a property to auto-wrap on set:

import ftplib
import ssl

class ImplicitFTP_TLS(ftplib.FTP_TLS):
    """FTP_TLS subclass that automatically wraps sockets in SSL to support implicit FTPS."""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._sock = None

    @property
    def sock(self):
        """Return the socket."""
        return self._sock

    @sock.setter
    def sock(self, value):
        """When modifying the socket, ensure that it is ssl wrapped."""
        if value is not None and not isinstance(value, ssl.SSLSocket):
            value = self.context.wrap_socket(value)
        self._sock = value

Usage is essentially the same as with the standard FTP_TLS class:

ftp_client = ImplicitFTP_TLS()
ftp_client.connect(host="ftp.example.com", port=990)
ftp_client.login(user="USERNAME", passwd='PASSWORD')
ftp_client.prot_p()

Leave a Comment