Changeset 1507:fdb6f0b71ee1


Ignore:
Timestamp:
Jun 7, 2014, 10:11:10 AM (7 years ago)
Author:
Stefan Schwarzer <sschwarzer@…>
Branch:
default
Message:
Updated recipe with workaround for `M2Crypto.ftpslib.FTP_TLS`.

It should get much easier with the new `session.py` though (see
ticket #78).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/ftputil.txt

    r1478 r1507  
    12701270in the problem report! Be careful!
    12711271
    1272 Does ``ftputil`` support SSL?
    1273 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1274 
    1275 ``ftputil`` has no *built-in* SSL support. On the other hand,
    1276 you can use M2Crypto_ (in the source code archive, look for the
    1277 file ``M2Crypto/ftpslib.py``) which has a class derived from
    1278 ``ftplib.FTP`` that supports SSL. You then can use a class
    1279 (not an object of it) similar to the following as a "session
    1280 factory" in ``ftputil.FTPHost``'s constructor::
     1272Does ``ftputil`` support SSL/TLS?
     1273~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1274
     1275``ftputil`` has no *built-in* SSL/TLS support.
     1276
     1277On the other hand, there are two ways to get TLS support with
     1278ftputil:
     1279
     1280- In Python 2.7 and Python 3.2 and up, the ``ftplib`` library has a
     1281  class ``FTP_TLS`` that you can use for the ``session_factory``
     1282  keyword argument in the ``FTPHost`` constructor. You can't use the
     1283  class directly though if you need additional setup code in
     1284  comparison to ``ftplib.FTP``, for example calling ``prot_p``, to
     1285  secure the data connection. In that case, create your own session
     1286  factory by inheriting from ``ftplib.FTP_TLS``::
     1287
     1288    import ftplib
    12811289
    12821290    import ftputil
    12831291
    1284     from M2Crypto import ftpslib
    1285 
    1286     class SSLFTPSession(ftpslib.FTP_TLS):
    1287 
    1288         def __init__(self, host, userid, password):
     1292
     1293    class FTPTLSSession(ftplib.FTP_TLS):
     1294
     1295        def __init__(self, host, user, password):
     1296            ftplib.FTP_TLS.__init__(self)
     1297            self.connect(host, port)
     1298            self.login(user, password)
     1299            # Set up encrypted data connection.
     1300            self.prot_p()
     1301
     1302    # Note the `session_factory` parameter. Pass the class, not
     1303    # an instance.
     1304    host = ftputil.FTPHost(host, user, password,
     1305                           session_factory=FTPTLSSession)
     1306    # Use `host` as usual.
     1307
     1308- If you need to work with Python 2.6, you can use the
     1309  ``ftpslib.FTP_TLS`` class from the M2Crypto_ project. Again, you
     1310  can't use the class directly but need a recipe similar to that
     1311  above.
     1312
     1313  Unfortunately, ``M2Crypto.ftpslib.FTP_TLS`` (at least in version
     1314  0.22.3) doesn't work correctly if you pass unicode strings to its
     1315  methods. Since ``ftputil`` does exactly that at some point (even if
     1316  you used byte strings in ``ftputil`` calls) you need a workaround in
     1317  the session factory class::
     1318
     1319    import M2Crypto
     1320
     1321    import ftputil
     1322    import ftputil.tool
     1323
     1324
     1325    class M2CryptoSession(M2Crypto.ftpslib.FTP_TLS):
     1326
     1327        def __init__(self, host, user, password):
     1328            M2Crypto.ftpslib.FTP_TLS.__init__(self)
     1329            # Change the port number if needed.
     1330            self.connect(host, 21)
     1331            self.auth_tls()
     1332            self.login(user, password)
     1333            self.prot_p()
     1334            self._fix_socket()
     1335
     1336        def _fix_socket(self):
    12891337            """
    1290             Use M2Crypto's `FTP_TLS` class to establish an
    1291             SSL connection.
     1338            Change the socket object so that arguments to `sendall`
     1339            are converted to byte strings before being used.
    12921340            """
    1293             ftpslib.FTP_TLS.__init__(self)
    1294             # Do anything necessary to set up the SSL connection.
    1295             ...
    1296             self.connect(host, port)
    1297             self.login(userid, password)
    1298             ...
    1299 
    1300     # Note the `session_factory` parameter.
    1301     host = ftputil.FTPHost(host, userid, password,
    1302                            session_factory=SSLFTPSession)
     1341            original_sendall = self.sock.sendall
     1342            # Bound method, therefore no `self` argument.
     1343            def sendall(data):
     1344                data = ftputil.tool.as_bytes(data)
     1345                return original_sendall(data)
     1346            self.sock.sendall = sendall
     1347
     1348    # Note the `session_factory` parameter. Pass the class, not
     1349    # an instance.
     1350    host = ftputil.FTPHost(host, user, password,
     1351                           session_factory=M2CryptoSession)
    13031352    # Use `host` as usual.
    13041353
    1305 If you work with Python 2.7 or 3.2 and later, you can use a
    1306 similar recipe with the class ``FTP_TLS`` in the ``ftplib``
    1307 module. Note that you need to call ``prot_p`` on the ``FTP_TLS``
    1308 instance to actually use a secure transfer. This makes it still
    1309 necessary to define a session class similar to the one above.
    1310 
    1311 .. _M2Crypto: http://wiki.osafoundation.org/bin/view/Projects/MeTooCrypto#Downloads
     1354.. _M2Crypto: https://github.com/martinpaljak/M2Crypto
    13121355
    13131356How do I connect to a non-default port?
Note: See TracChangeset for help on using the changeset viewer.