Commit 7b4b2846 authored by Benjamin Peterson's avatar Benjamin Peterson

allow a SSLContext to be given to ftplib.FTP_TLS

parent 9fe67cee
......@@ -55,18 +55,26 @@ The module defines the following items:
*timeout* was added.
.. class:: FTP_TLS([host[, user[, passwd[, acct[, keyfile[, certfile[, timeout]]]]]]])
.. class:: FTP_TLS([host[, user[, passwd[, acct[, keyfile[, certfile[, context[, timeout]]]]]]]])
A :class:`FTP` subclass which adds TLS support to FTP as described in
:rfc:`4217`.
Connect as usual to port 21 implicitly securing the FTP control connection
before authenticating. Securing the data connection requires the user to
explicitly ask for it by calling the :meth:`prot_p` method.
*keyfile* and *certfile* are optional -- they can contain a PEM formatted
private key and certificate chain file name for the SSL connection.
explicitly ask for it by calling the :meth:`prot_p` method. *context*
is a :class:`ssl.SSLContext` object which allows bundling SSL configuration
options, certificates and private keys into a single (potentially
long-lived) structure. Please read :ref:`ssl-security` for best practices.
*keyfile* and *certfile* are a legacy alternative to *context* -- they
can point to PEM-formatted private key and certificate chain files
(respectively) for the SSL connection.
.. versionadded:: 2.7
.. versionchanged:: 2.7.10
The *context* parameter was added.
Here's a sample session using the :class:`FTP_TLS` class:
>>> from ftplib import FTP_TLS
......
......@@ -641,9 +641,21 @@ else:
ssl_version = ssl.PROTOCOL_SSLv23
def __init__(self, host='', user='', passwd='', acct='', keyfile=None,
certfile=None, timeout=_GLOBAL_DEFAULT_TIMEOUT):
certfile=None, context=None,
timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None):
if context is not None and keyfile is not None:
raise ValueError("context and keyfile arguments are mutually "
"exclusive")
if context is not None and certfile is not None:
raise ValueError("context and certfile arguments are mutually "
"exclusive")
self.keyfile = keyfile
self.certfile = certfile
if context is None:
context = ssl._create_stdlib_context(self.ssl_version,
certfile=certfile,
keyfile=keyfile)
self.context = context
self._prot_p = False
FTP.__init__(self, host, user, passwd, acct, timeout)
......@@ -660,8 +672,8 @@ else:
resp = self.voidcmd('AUTH TLS')
else:
resp = self.voidcmd('AUTH SSL')
self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile,
ssl_version=self.ssl_version)
self.sock = self.context.wrap_socket(self.sock,
server_hostname=self.host)
self.file = self.sock.makefile(mode='rb')
return resp
......@@ -692,8 +704,8 @@ else:
def ntransfercmd(self, cmd, rest=None):
conn, size = FTP.ntransfercmd(self, cmd, rest)
if self._prot_p:
conn = ssl.wrap_socket(conn, self.keyfile, self.certfile,
ssl_version=self.ssl_version)
conn = self.context.wrap_socket(conn,
server_hostname=self.host)
return conn, size
def retrbinary(self, cmd, callback, blocksize=8192, rest=None):
......
This diff is collapsed.
......@@ -15,6 +15,8 @@ Core and Builtins
Library
-------
- Backport the context argument to ftplib.FTP_TLS.
- Issue #23111: Maximize compatibility in protocol versions of ftplib.FTP_TLS.
- Issue #23112: Fix SimpleHTTPServer to correctly carry the query string and
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment