0

I am trying to connect to an FTPS server which requires anonymous login with a .pfx certificate.

I have been given instructions for how to access it through the gui application SmartFTP which does work, thus I know I haven't got any firewall issues etc. However, for this workflow getting access to it through python would be ideal. Below are the settings I have been given:

Protocol: FTPS (Explicit)
Host: xxx.xxx.xxx.xxx
Port: 21
login type: Anonymous
Client Certificate: Enabled (providing a .pfx file)
Send FEAT: Send before and after login

I am having trouble picking the python module best suited to this with a full example using a .pfx certificate. Currently I have only tried the standard FTP module using the below code. Does anyone have a worked example?

from ftplib import FTP_TLS

    ftps = FTP_TLS(host='xxx.xxx.xxx.xxx',
                   keyfile=r"/path/to.pfx"
                   )
    ftps.login()
    ftps.prot_p()
    ftps.retrlines('LIST')
    ftps.quit()

Using the above code I get:

ValueError: certfile must be specified

Client versions: Ubuntu == 14.04, Python == 3.6.2

Update

Think I am a little closer with the code below but getting a new error:

from ftplib import FTP_TLS
import tempfile
import OpenSSL.crypto


def pfx_to_pem(pfx_path, pfx_password):
    """ Decrypts the .pfx file to be used with requests. """
    with tempfile.NamedTemporaryFile(suffix='.pem') as t_pem:
        f_pem = open(t_pem.name, 'wb')
        pfx = open(pfx_path, 'rb').read()
        p12 = OpenSSL.crypto.load_pkcs12(pfx, pfx_password)
        f_pem.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()))
        f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, p12.get_certificate()))
        ca = p12.get_ca_certificates()
        if ca is not None:
            for cert in ca:
                f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))
        f_pem.close()
        yield t_pem.name


pfx = pfx_to_pem(r"/path/to.pfx", 'password')
ftps = FTP_TLS(host='xxx.xxx.xxx.xxx',
               context=pfx
               )
ftps.login()
ftps.prot_p()
# ftps.prot_c()
print(ftps.retrlines('LIST'))
ftps.quit()

Error: ftplib.error_perm: 534 Local policy on server does not allow TLS secure connections.

Any Ideas?

Cheers

Richard Ellison
  • 315
  • 6
  • 14
  • Possible duplicate of [Connecting to 'Explicit FTP over TLS' in Python (??)](https://stackoverflow.com/questions/44057732/connecting-to-explicit-ftp-over-tls-in-python) – tripleee Apr 29 '19 at 05:33

1 Answers1

0

It sounds like you try to do SFTP. FTP over SSL is not the same as SFTP. As far as I know SFTP (which is related to SSH) is not possible with the standard library.

See this for more about SFTP in Python: SFTP in Python? (platform independent)