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);
}
/* --------------------------------------------------------------------------------------------- */