Rev 4729: Fix gssapi ftp client mode handling in http://bazaar.launchpad.net/~vila/bzr/integration

Vincent Ladeuil v.ladeuil+lp at free.fr
Tue Oct 6 16:58:24 BST 2009


At http://bazaar.launchpad.net/~vila/bzr/integration

------------------------------------------------------------
revno: 4729 [merge]
revision-id: v.ladeuil+lp at free.fr-20091006155812-mie06vdxp373lqxd
parent: pqm at pqm.ubuntu.com-20091006133835-5mq5guz7d72tvpbd
parent: v.ladeuil+lp at free.fr-20091006082414-2gw236e7n81hppxp
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: integration
timestamp: Tue 2009-10-06 17:58:12 +0200
message:
  Fix gssapi ftp client mode handling
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/tests/ftp_server/pyftpdlib_based.py pyftpdlib_based.py-20090227151014-882k9q34m1gwnhvi-1
  bzrlib/transport/ftp/__init__.py ftp.py-20051116161804-58dc9506548c2a53
  bzrlib/transport/ftp/_gssapi.py _gssapi.py-20080611190840-7ejrtp884bk5eu72-2
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2009-10-06 02:38:44 +0000
+++ b/NEWS	2009-10-06 15:58:12 +0000
@@ -104,6 +104,10 @@
   with some combinations of remote and local formats.  This was causing
   "unknown object type identifier 60" errors.  (Andrew Bennetts, #427736)
 
+* ftp transports were built differently when the kerberos python module was
+  present leading to obscure failures related to ASCII/BINARY modes.
+  (Vincent Ladeuil, #443041)
+
 * Network streams now decode adjacent records of the same type into a
   single stream, reducing layering churn. (Robert Collins)
 

=== modified file 'bzrlib/tests/ftp_server/pyftpdlib_based.py'
--- a/bzrlib/tests/ftp_server/pyftpdlib_based.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/ftp_server/pyftpdlib_based.py	2009-10-06 08:24:14 +0000
@@ -84,7 +84,7 @@
         line = self.fs.fs2ftp(path)
         if self.fs.isfile(self.fs.realpath(path)):
             why = "Not a directory: %s" % line
-            self.log('FAIL SIZE "%s". %s.' % (line, why))
+            self.log('FAIL NLST "%s". %s.' % (line, why))
             self.respond("550 %s."  %why)
         else:
             ftpserver.FTPHandler.ftp_NLST(self, path)
@@ -180,8 +180,7 @@
         self._port = self._ftp_server.socket.getsockname()[1]
         self._ftpd_starting = threading.Lock()
         self._ftpd_starting.acquire() # So it can be released by the server
-        self._ftpd_thread = threading.Thread(
-                target=self._run_server,)
+        self._ftpd_thread = threading.Thread(target=self._run_server,)
         self._ftpd_thread.start()
         # Wait for the server thread to start (i.e release the lock)
         self._ftpd_starting.acquire()
@@ -202,7 +201,11 @@
         self._ftpd_running = True
         self._ftpd_starting.release()
         while self._ftpd_running:
-            self._ftp_server.serve_forever(timeout=0.1, count=1)
+            try:
+                self._ftp_server.serve_forever(timeout=0.1, count=1)
+            except select.error, e:
+                if e.args[0] != errno.EBADF:
+                    raise
         self._ftp_server.close_all(ignore_all=True)
 
     def add_user(self, user, password):

=== modified file 'bzrlib/transport/ftp/__init__.py'
--- a/bzrlib/transport/ftp/__init__.py	2009-07-22 06:51:13 +0000
+++ b/bzrlib/transport/ftp/__init__.py	2009-10-06 08:24:14 +0000
@@ -25,17 +25,13 @@
 """
 
 from cStringIO import StringIO
-import errno
 import ftplib
 import getpass
 import os
-import os.path
-import urlparse
 import random
 import socket
 import stat
 import time
-from warnings import warn
 
 from bzrlib import (
     config,
@@ -51,8 +47,6 @@
     register_urlparse_netloc_protocol,
     Server,
     )
-from bzrlib.transport.local import LocalURLServer
-import bzrlib.ui
 
 
 register_urlparse_netloc_protocol('aftp')
@@ -99,8 +93,9 @@
             self.is_active = True
         else:
             self.is_active = False
-        
-        # Most modern FTP servers support the APPE command. If ours doesn't, we (re)set this flag accordingly later.
+
+        # Most modern FTP servers support the APPE command. If ours doesn't, we
+        # (re)set this flag accordingly later.
         self._has_append = True
 
     def _get_FTP(self):
@@ -113,6 +108,8 @@
             self._set_connection(connection, credentials)
         return connection
 
+    connection_class = ftplib.FTP
+
     def _create_connection(self, credentials=None):
         """Create a new connection with the provided credentials.
 
@@ -138,13 +135,9 @@
                ((self._host, self._port, user, '********',
                 self.is_active),))
         try:
-            connection = ftplib.FTP()
+            connection = self.connection_class()
             connection.connect(host=self._host, port=self._port)
-            if user and user != 'anonymous' and \
-                    password is None: # '' is a valid password
-                password = auth.get_password('ftp', self._host, user,
-                                             port=self._port)
-            connection.login(user=user, passwd=password)
+            self._login(connection, auth, user, password)
             connection.set_pasv(not self.is_active)
             # binary mode is the default
             connection.voidcmd('TYPE I')
@@ -157,6 +150,13 @@
                                         " %s" % str(e), orig_error=e)
         return connection, (user, password)
 
+    def _login(self, connection, auth, user, password):
+        # '' is a valid password
+        if user and user != 'anonymous' and password is None:
+            password = auth.get_password('ftp', self._host,
+                                         user, port=self._port)
+        connection.login(user=user, passwd=password)
+
     def _reconnect(self):
         """Create a new connection with the previously used credentials"""
         credentials = self._get_credentials()
@@ -391,7 +391,6 @@
         location.
         """
         text = f.read()
-        
         abspath = self._remote_path(relpath)
         if self.has(relpath):
             ftp = self._get_FTP()
@@ -426,18 +425,18 @@
         except ftplib.error_perm, e:
             # Check whether the command is not supported (reply code 502)
             if str(e).startswith('502 '):
-                warning("FTP server does not support file appending natively. " \
-                    "Performance may be severely degraded! (%s)", e)
+                warning("FTP server does not support file appending natively. "
+                        "Performance may be severely degraded! (%s)", e)
                 self._has_append = False
                 self._fallback_append(relpath, text, mode)
             else:
                 self._translate_perm_error(e, abspath, extra='error appending',
                     unknown_exc=errors.NoSuchFile)
-            
         except ftplib.error_temp, e:
             if retries > _number_of_retries:
-                raise errors.TransportError("FTP temporary error during APPEND %s." \
-                        "Aborting." % abspath, orig_error=e)
+                raise errors.TransportError(
+                    "FTP temporary error during APPEND %s. Aborting."
+                    % abspath, orig_error=e)
             else:
                 warning("FTP temporary error: %s. Retrying.", str(e))
                 self._reconnect()
@@ -445,9 +444,9 @@
 
     def _fallback_append(self, relpath, text, mode = None):
         remote = self.get(relpath)
-        remote.seek(0, 2)
+        remote.seek(0, os.SEEK_END)
         remote.write(text)
-        remote.seek(0, 0)
+        remote.seek(0)
         return self.put_file(relpath, remote, mode)
 
     def _setmode(self, relpath, mode):

=== modified file 'bzrlib/transport/ftp/_gssapi.py'
--- a/bzrlib/transport/ftp/_gssapi.py	2009-09-18 01:25:08 +0000
+++ b/bzrlib/transport/ftp/_gssapi.py	2009-10-06 08:24:14 +0000
@@ -97,52 +97,22 @@
 
     """
 
-    def _create_connection(self, credentials=None):
-        """Create a new connection with the provided credentials.
-
-        :param credentials: The credentials needed to establish the connection.
-
-        :return: The created connection and its associated credentials.
-
-        The credentials are a tuple with the username and password. The
-        password is used if GSSAPI Authentication is not available.
+    connection_class = GSSAPIFtp
+
+    def _login(self, connection, auth, user, password):
+        """Login with GSSAPI Authentication.
+
+        The password is used if GSSAPI Authentication is not available.
 
         The username and password can both be None, in which case the
         credentials specified in the URL or provided by the
         AuthenticationConfig() are used.
         """
-        if credentials is None:
-            user, password = self._user, self._password
-        else:
-            user, password = credentials
-
-        auth = config.AuthenticationConfig()
-        if user is None:
-            user = auth.get_user('ftp', self._host, port=self._port,
-                                 default=getpass.getuser())
-        mutter("Constructing FTP instance against %r" %
-               ((self._host, self._port, user, '********',
-                self.is_active),))
         try:
-            connection = GSSAPIFtp()
-            connection.connect(host=self._host, port=self._port)
-            try:
-                connection.gssapi_login(user=user)
-            except ftplib.error_perm, e:
-                if user and user != 'anonymous' and \
-                        password is None: # '' is a valid password
-                    password = auth.get_password('ftp', self._host, user,
-                                                 port=self._port)
-                connection.login(user=user, passwd=password)
-            connection.set_pasv(not self.is_active)
-        except socket.error, e:
-            raise errors.SocketConnectionError(self._host, self._port,
-                                               msg='Unable to connect to',
-                                               orig_error= e)
+            connection.gssapi_login(user=user)
         except ftplib.error_perm, e:
-            raise errors.TransportError(msg="Error setting up connection:"
-                                        " %s" % str(e), orig_error=e)
-        return connection, (user, password)
+            super(GSSAPIFtpTransport, self)._login(connection, auth,
+                                                   user, password)
 
 
 def get_test_permutations():



More information about the bazaar-commits mailing list