Skip to content

Commit

Permalink
Updates per code review
Browse files Browse the repository at this point in the history
  • Loading branch information
zuohaocheng committed Jul 27, 2017
1 parent 5c2e1f4 commit 930a60a
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 13 deletions.
6 changes: 3 additions & 3 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -559,9 +559,9 @@ Extended handlers

.. data:: client_certfile

The path of the certificate to check the client certificate against.
When provided, only allowing clients with a valid certificate to connect
to the server (default ``None``).
The path to a file which contains a certificate to be used to identify
the client. If specified, only clients with a valid certificate are able
to connect to the server (default ``None``).

.. versionadded:: 1.5.3

Expand Down
9 changes: 4 additions & 5 deletions pyftpdlib/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3419,7 +3419,6 @@ class TLS_FTPHandler(SSLConnection, FTPHandler):
certfile = None
keyfile = None
ssl_protocol = SSL.SSLv23_METHOD
# client certificate configurable attributes
client_certfile = None
# - SSLv2 is easily broken and is considered harmful and dangerous
# - SSLv3 has several problems and is now dangerous
Expand Down Expand Up @@ -3454,7 +3453,7 @@ def __init__(self, conn, server, ioloop=None):
self._extra_feats = ['AUTH TLS', 'AUTH SSL', 'PBSZ', 'PROT']
self._pbsz = False
self._prot = False
self.ssl_context = self.get_ssl_context()
self.init_ssl_context()

def __repr__(self):
return FTPHandler.__repr__(self)
Expand All @@ -3467,9 +3466,9 @@ def verify_certs_callback(self, connection, x509,
self.log("Client certificate is valid.")
return ok

def get_ssl_context(self):
def init_ssl_context(self):
if self.ssl_context is None:
self.ssl_context = self.validate_ssl_options()
self.ssl_context = self.get_ssl_context()
if self.client_certfile is not None:
from OpenSSL.SSL import VERIFY_CLIENT_ONCE
from OpenSSL.SSL import VERIFY_FAIL_IF_NO_PEER_CERT
Expand All @@ -3481,7 +3480,7 @@ def get_ssl_context(self):
return self.ssl_context

@classmethod
def validate_ssl_options(cls):
def get_ssl_context(cls):
if cls.certfile is None:
raise ValueError("at least certfile must be specified")
ssl_context = SSL.Context(cls.ssl_protocol)
Expand Down
4 changes: 2 additions & 2 deletions pyftpdlib/servers.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ def __init__(self, address_or_socket, handler, ioloop=None, backlog=100):
self.ip_map = []
# in case of FTPS class not properly configured we want errors
# to be raised here rather than later, when client connects
if hasattr(handler, 'validate_ssl_options'):
handler.validate_ssl_options()
if hasattr(handler, 'get_ssl_context'):
handler.get_ssl_context()
if callable(getattr(address_or_socket, 'listen', None)):
sock = address_or_socket
sock.setblocking(0)
Expand Down
6 changes: 3 additions & 3 deletions pyftpdlib/test/test_functional_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,15 +370,15 @@ def try_protocol_combo(self, server_protocol, client_protocol):
# for proto in protos:
# self.try_protocol_combo(ssl.PROTOCOL_TLSv1, proto)

# On OSX TLS_FTPHandler.validate_ssl_options()._context does not exist.
# On OSX TLS_FTPHandler.get_ssl_context()._context does not exist.
@unittest.skipIf(OSX, "can't get options on OSX")
def test_ssl_options(self):
from OpenSSL import SSL
from OpenSSL._util import lib
from pyftpdlib.handlers import TLS_FTPHandler
try:
TLS_FTPHandler.ssl_context = None
ctx = TLS_FTPHandler.validate_ssl_options()
ctx = TLS_FTPHandler.get_ssl_context()
# Verify default opts.
with contextlib.closing(socket.socket()) as s:
s = SSL.Connection(ctx, s)
Expand All @@ -392,7 +392,7 @@ def test_ssl_options(self):
# ssl_proto is set to SSL.SSLv23_METHOD).
TLS_FTPHandler.ssl_context = None
TLS_FTPHandler.ssl_options = None
ctx = TLS_FTPHandler.validate_ssl_options()
ctx = TLS_FTPHandler.get_ssl_context()
with contextlib.closing(socket.socket()) as s:
s = SSL.Connection(ctx, s)
opts = lib.SSL_CTX_get_options(ctx._context)
Expand Down

0 comments on commit 930a60a

Please sign in to comment.