Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hoogenm/de42e2ef85b38179297a0bba8d60778b to your computer and use it in GitHub Desktop.
Save hoogenm/de42e2ef85b38179297a0bba8d60778b to your computer and use it in GitHub Desktop.
# Combines several solutions found on the internet
class ImplicitFTP_TLS(ftplib.FTP_TLS):
"""FTP_TLS subclass to support implicit FTPS."""
"""Constructor takes a boolean parameter ignore_PASV_host whether o ignore the hostname"""
"""in the PASV response, and use the hostname from the session instead"""
def __init__(self, *args, **kwargs):
self.ignore_PASV_host = kwargs.get('ignore_PASV_host') == True
super().__init__(*args, {k: v for k, v in kwargs.items() if not k == 'ignore_PASV_host'})
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
def ntransfercmd(self, cmd, rest=None):
"""Override the ntransfercmd method"""
conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
conn = self.sock.context.wrap_socket(
conn, server_hostname=self.host, session=self.sock.session
)
return conn, size
def makepasv(self):
host, port = super().makepasv()
return (self.host if self.ignore_PASV_host else host), port
@bmcahill
Copy link

Internet stranger, I cannot thank you enough for this.

@sujeetpillai
Copy link

I agree with @bmcahill . This code was like a miracle!

@JebJeffery
Copy link

Thank you so much!

@Negaihoshi
Copy link

It's work! Thank you. You save our life.

@jakubfrasunek
Copy link

Oh my god... sir, you can't even imagine... this is pure gold, thank you so much!

@Niilavarnam
Copy link

Hello,

I'm not a python expert, I've been looking for days how to connect to FTP with TLS implicit on port 990, and there is no way. I've been searching and trying many things without success and I found this page, so thank you first of all.

Forgive my ignorance, but what should I add to this code to run it in my ide and see if it works with the FTP server I want to connect?
Thanks!

@jakubfrasunek
Copy link

jakubfrasunek commented Sep 4, 2024

@Niilavarnam Hi, this is just a class code that will replace the original one to enable implicit TLS. Connecting and other logic are up to you how you will manage it. For example:
ftps = ImplicitFTP_TLS()
ftps.ssl_version = ssl.PROTOCOL_TLSv1_2
ftps.connect(ftps_host, ftps_port, timeout=30)

@mcortegana
Copy link

It works!!! I will cry, you have saved us, we are grateful

@thenickg
Copy link

thenickg commented Feb 4, 2025

Worked for me. Thank you for saving me so much time, I was in a very deep rabbit hole without this. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment