File sftp.patch of Package mc.8407

Upstream fixes for SFTP, ported from upstream merge,
git diff 9dcf03342a2719a61765d94d5bcaf4f579475be1..ab0c2afba5a142c6091bd40d913c75f4669f1280

Index: mc-4.8.15/src/vfs/sftpfs/config_parser.c
===================================================================
--- mc-4.8.15.orig/src/vfs/sftpfs/config_parser.c
+++ mc-4.8.15/src/vfs/sftpfs/config_parser.c
@@ -79,17 +79,18 @@ static struct
     size_t offset;
 } config_variables[] =
 {
-    {"^\\s*User\\s+(.*)$", NULL, STRING, 0},
-    {"^\\s*HostName\\s+(.*)$", NULL, STRING, 0},
-    {"^\\s*IdentitiesOnly\\s+(.*)$", NULL, BOOLEAN, 0},
-    {"^\\s*IdentityFile\\s+(.*)$", NULL, FILENAME, 0},
-    {"^\\s*Port\\s+(.*)$", NULL, INTEGER, 0},
-    {"^\\s*PasswordAuthentication\\s+(.*)$", NULL, BOOLEAN, 0},
-    {"^\\s*PubkeyAuthentication\\s+(.*)$", NULL, STRING, 0},
+    {"^\\s*User\\s+(.*)$", NULL, STRING, offsetof (sftpfs_ssh_config_entity_t, user)},
+    {"^\\s*HostName\\s+(.*)$", NULL, STRING, offsetof (sftpfs_ssh_config_entity_t, real_host)},
+    {"^\\s*IdentitiesOnly\\s+(.*)$", NULL, BOOLEAN, offsetof (sftpfs_ssh_config_entity_t, identities_only)},
+    {"^\\s*IdentityFile\\s+(.*)$", NULL, FILENAME, offsetof (sftpfs_ssh_config_entity_t, identity_file)},
+    {"^\\s*Port\\s+(.*)$", NULL, INTEGER, offsetof (sftpfs_ssh_config_entity_t, port)},
+    {"^\\s*PasswordAuthentication\\s+(.*)$", NULL, BOOLEAN, offsetof (sftpfs_ssh_config_entity_t, password_auth)},
+    {"^\\s*PubkeyAuthentication\\s+(.*)$", NULL, STRING, offsetof (sftpfs_ssh_config_entity_t, pubkey_auth)},
     {NULL, NULL, 0, 0}
 };
 /* *INDENT-ON* */
 
+/* --------------------------------------------------------------------------------------------- */
 /*** file scope functions ************************************************************************/
 /* --------------------------------------------------------------------------------------------- */
 /**
@@ -131,9 +132,8 @@ sftpfs_correct_file_name (const char *fi
 
 /* --------------------------------------------------------------------------------------------- */
 
-/* FIXME: is pointer arith correct here? */
 #define POINTER_TO_STRUCTURE_MEMBER(type)  \
-    ((type) (config_entity + (off_t) config_variables[i].offset))
+    ((type) ((char *) config_entity + (size_t) config_variables[i].offset))
 
 /**
  * Parse string and filling one config entity by parsed data.
@@ -210,6 +210,7 @@ sftpfs_fill_config_entity_from_config (F
     gboolean host_block_hit = FALSE;
     gboolean pattern_block_hit = FALSE;
     mc_search_t *host_regexp;
+    gboolean ok = TRUE;
 
     mc_return_val_if_error (mcerror, FALSE);
 
@@ -217,21 +218,26 @@ sftpfs_fill_config_entity_from_config (F
     host_regexp->search_type = MC_SEARCH_T_REGEX;
     host_regexp->is_case_sensitive = FALSE;
 
-    while (!feof (ssh_config_handler))
+    while (TRUE)
     {
         char *cr;
+
         if (fgets (buffer, BUF_MEDIUM, ssh_config_handler) == NULL)
         {
-            if (errno != 0)
+            int e = errno;
+
+            if (!feof (ssh_config_handler))
             {
-                mc_propagate_error (mcerror, errno,
+                mc_propagate_error (mcerror, e,
                                     _("sftp: an error occurred while reading %s: %s"),
-                                    SFTPFS_SSH_CONFIG, strerror (errno));
-                mc_search_free (host_regexp);
-                return FALSE;
+                                    SFTPFS_SSH_CONFIG, strerror (e));
+                ok = FALSE;
+                goto done;
             }
+
             break;
         }
+
         cr = strrchr (buffer, '\n');
         if (cr != NULL)
             *cr = '\0';
@@ -243,7 +249,7 @@ sftpfs_fill_config_entity_from_config (F
 
             /* if previous host block exactly describe our connection */
             if (host_block_hit)
-                return TRUE;
+                goto done;
 
             host_pattern_offset = mc_search_getstart_result_by_num (host_regexp, 1);
             host_pattern = &buffer[host_pattern_offset];
@@ -271,8 +277,10 @@ sftpfs_fill_config_entity_from_config (F
             sftpfs_fill_config_entity_from_string (config_entity, buffer);
         }
     }
+
+  done:
     mc_search_free (host_regexp);
-    return TRUE;
+    return ok;
 }
 
 /* --------------------------------------------------------------------------------------------- */
@@ -389,16 +397,6 @@ sftpfs_fill_connection_data_from_config
 void
 sftpfs_init_config_variables_patterns (void)
 {
-    size_t structure_offsets[] = {
-        offsetof (sftpfs_ssh_config_entity_t, user),
-        offsetof (sftpfs_ssh_config_entity_t, real_host),
-        offsetof (sftpfs_ssh_config_entity_t, identities_only),
-        offsetof (sftpfs_ssh_config_entity_t, identity_file),
-        offsetof (sftpfs_ssh_config_entity_t, port),
-        offsetof (sftpfs_ssh_config_entity_t, password_auth),
-        offsetof (sftpfs_ssh_config_entity_t, pubkey_auth)
-    };
-
     int i;
 
     for (i = 0; config_variables[i].pattern != NULL; i++)
@@ -407,7 +405,6 @@ sftpfs_init_config_variables_patterns (v
             mc_search_new (config_variables[i].pattern, -1, DEFAULT_CHARSET);
         config_variables[i].pattern_regexp->search_type = MC_SEARCH_T_REGEX;
         config_variables[i].pattern_regexp->is_case_sensitive = FALSE;
-        config_variables[i].offset = structure_offsets[i];
     }
 }
 
Index: mc-4.8.15/src/vfs/sftpfs/connection.c
===================================================================
--- mc-4.8.15.orig/src/vfs/sftpfs/connection.c
+++ mc-4.8.15/src/vfs/sftpfs/connection.c
@@ -71,12 +71,12 @@ sftpfs_open_socket (struct vfs_s_super *
     char port[BUF_TINY];
     int e;
 
-    mc_return_val_if_error (mcerror, -1);
+    mc_return_val_if_error (mcerror, LIBSSH2_INVALID_SOCKET);
 
     if (super->path_element->host == NULL || *super->path_element->host == '\0')
     {
         mc_propagate_error (mcerror, -1, "%s", _("sftp: Invalid host name."));
-        return -1;
+        return LIBSSH2_INVALID_SOCKET;
     }
 
     sprintf (port, "%hu", (unsigned short) super->path_element->port);
@@ -108,7 +108,7 @@ sftpfs_open_socket (struct vfs_s_super *
     if (e != 0)
     {
         mc_propagate_error (mcerror, -1, _("sftp: %s"), gai_strerror (e));
-        my_socket = -1;
+        my_socket = LIBSSH2_INVALID_SOCKET;
         goto ret;
     }
 
@@ -122,7 +122,7 @@ sftpfs_open_socket (struct vfs_s_super *
                 continue;
 
             vfs_print_message (_("sftp: %s"), unix_error_string (errno));
-            my_socket = -1;
+            my_socket = LIBSSH2_INVALID_SOCKET;
             goto ret;
         }
 
@@ -141,7 +141,7 @@ sftpfs_open_socket (struct vfs_s_super *
         else
             continue;
 
-        my_socket = -1;
+        my_socket = LIBSSH2_INVALID_SOCKET;
         break;
     }
 
@@ -170,6 +170,7 @@ sftpfs_recognize_auth_types (struct vfs_
     super_data->auth_type = NONE;
 
     /* check what authentication methods are available */
+    /* userauthlist is internally managed by libssh2 and freed by libssh2_session_free() */
     userauthlist = libssh2_userauth_list (super_data->session, super->path_element->user,
                                           strlen (super->path_element->user));
 
@@ -183,8 +184,6 @@ sftpfs_recognize_auth_types (struct vfs_
 
     if ((super_data->config_auth_type & AGENT) != 0)
         super_data->auth_type |= AGENT;
-
-    g_free (userauthlist);
 }
 
 /* --------------------------------------------------------------------------------------------- */
@@ -368,23 +367,28 @@ sftpfs_open_connection (struct vfs_s_sup
 
     super_data = (sftpfs_super_data_t *) super->data;
 
-    /* Create a session instance */
-    super_data->session = libssh2_session_init ();
-    if (super_data->session == NULL)
-        return (-1);
-
     /*
      * The application code is responsible for creating the socket
      * and establishing the connection
      */
     super_data->socket_handle = sftpfs_open_socket (super, mcerror);
-    if (super_data->socket_handle == -1)
+    if (super_data->socket_handle == LIBSSH2_INVALID_SOCKET)
+        return (-1);
+
+    /* Create a session instance */
+    super_data->session = libssh2_session_init ();
+    if (super_data->session == NULL)
         return (-1);
 
     /* ... start it up. This will trade welcome banners, exchange keys,
      * and setup crypto, compression, and MAC layers
      */
+#if LIBSSH2_VERSION_NUM < 0x010208
     rc = libssh2_session_startup (super_data->session, super_data->socket_handle);
+#else
+    rc = libssh2_session_handshake (super_data->session,
+                                    (libssh2_socket_t) super_data->socket_handle);
+#endif
     if (rc != 0)
     {
         mc_propagate_error (mcerror, -1, _("sftp: Failure establishing SSH session: (%d)"), rc);
@@ -430,14 +434,18 @@ sftpfs_close_connection (struct vfs_s_su
 {
     sftpfs_super_data_t *super_data;
 
-    mc_return_if_error (mcerror);
+    /* no mc_return_*_if_error() here because of abort open_connection handling too */
+    (void) mcerror;
 
     super_data = (sftpfs_super_data_t *) super->data;
     if (super_data == NULL)
         return;
 
-    vfs_path_element_free (super_data->original_connection_info);
-    super_data->original_connection_info = NULL;
+    if (super_data->sftp_session != NULL)
+    {
+        libssh2_sftp_shutdown (super_data->sftp_session);
+        super_data->sftp_session = NULL;
+    }
 
     if (super_data->agent != NULL)
     {
@@ -446,24 +454,19 @@ sftpfs_close_connection (struct vfs_s_su
         super_data->agent = NULL;
     }
 
-    if (super_data->sftp_session != NULL)
-    {
-        libssh2_sftp_shutdown (super_data->sftp_session);
-        super_data->sftp_session = NULL;
-    }
+    super_data->fingerprint = NULL;
 
     if (super_data->session != NULL)
     {
         libssh2_session_disconnect (super_data->session, shutdown_message);
+        libssh2_session_free (super_data->session);
         super_data->session = NULL;
     }
 
-    super_data->fingerprint = NULL;
-
-    if (super_data->socket_handle != -1)
+    if (super_data->socket_handle != LIBSSH2_INVALID_SOCKET)
     {
         close (super_data->socket_handle);
-        super_data->socket_handle = -1;
+        super_data->socket_handle = LIBSSH2_INVALID_SOCKET;
     }
 }
 
Index: mc-4.8.15/src/vfs/sftpfs/internal.h
===================================================================
--- mc-4.8.15.orig/src/vfs/sftpfs/internal.h
+++ mc-4.8.15/src/vfs/sftpfs/internal.h
@@ -16,6 +16,11 @@
 
 #define SFTP_DEFAULT_PORT 22
 
+/* LIBSSH2_INVALID_SOCKET is defined in libssh2 >= 1.4.1 */
+#ifndef LIBSSH2_INVALID_SOCKET
+#define LIBSSH2_INVALID_SOCKET -1
+#endif
+
 /*** enums ***************************************************************************************/
 
 typedef enum
Index: mc-4.8.15/src/vfs/sftpfs/vfs_subclass.c
===================================================================
--- mc-4.8.15.orig/src/vfs/sftpfs/vfs_subclass.c
+++ mc-4.8.15/src/vfs/sftpfs/vfs_subclass.c
@@ -104,6 +104,7 @@ sftpfs_cb_open_connection (struct vfs_s_
     }
 
     sftpfs_super_data = g_new0 (sftpfs_super_data_t, 1);
+    sftpfs_super_data->socket_handle = LIBSSH2_INVALID_SOCKET;
     sftpfs_super_data->original_connection_info = vfs_path_element_clone (vpath_element);
     super->data = sftpfs_super_data;
     super->path_element = vfs_path_element_clone (vpath_element);
@@ -137,11 +138,18 @@ static void
 sftpfs_cb_close_connection (struct vfs_class *me, struct vfs_s_super *super)
 {
     GError *mcerror = NULL;
+    sftpfs_super_data_t *sftpfs_super_data;
 
     (void) me;
     sftpfs_close_connection (super, "Normal Shutdown", &mcerror);
+
+    sftpfs_super_data = (sftpfs_super_data_t *) super->data;
+    if (sftpfs_super_data != NULL)
+        vfs_path_element_free (sftpfs_super_data->original_connection_info);
+
     mc_error_message (&mcerror, NULL);
-    g_free (super->data);
+
+    g_free (sftpfs_super_data);
 }
 
 /* --------------------------------------------------------------------------------------------- */
openSUSE Build Service is sponsored by