summaryrefslogtreecommitdiff
path: root/daemon/gvfsftptask.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/gvfsftptask.c')
-rw-r--r--daemon/gvfsftptask.c80
1 files changed, 57 insertions, 23 deletions
diff --git a/daemon/gvfsftptask.c b/daemon/gvfsftptask.c
index 2209c2b1..5da8e549 100644
--- a/daemon/gvfsftptask.c
+++ b/daemon/gvfsftptask.c
@@ -250,9 +250,7 @@ g_vfs_ftp_task_acquire_connection (GVfsFtpTask *task)
task->conn = g_vfs_ftp_connection_new (ftp->addr, task->cancellable, &task->error);
if (G_LIKELY (task->conn != NULL))
{
- g_vfs_ftp_task_receive (task, 0, NULL);
- if (ftp->use_tls)
- g_vfs_ftp_task_enable_tls (task, reconnect_certificate_cb, ftp);
+ g_vfs_ftp_task_initial_handshake (task, reconnect_certificate_cb, ftp);
g_vfs_ftp_task_login (task, ftp->user, ftp->password);
g_vfs_ftp_task_setup_connection (task);
if (G_LIKELY (!g_vfs_ftp_task_is_in_error (task)))
@@ -1188,7 +1186,7 @@ g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task)
if (g_vfs_ftp_task_is_in_error (task))
return;
- if (task->backend->use_tls)
+ if (task->backend->tls_mode != G_VFS_FTP_TLS_MODE_NONE)
g_vfs_ftp_connection_data_connection_enable_tls (task->conn,
task->backend->server_identity,
reconnect_certificate_cb,
@@ -1198,38 +1196,74 @@ g_vfs_ftp_task_open_data_connection (GVfsFtpTask *task)
}
/**
- * g_vfs_ftp_task_enable_tls:
+ * g_vfs_ftp_task_initial_handshake:
* @task: a task
* @cb: callback called if there's a verification error
* @user_data: user data passed to @cb
*
- * Tries to enable tls on the control connection to an ftp server.
- * If the operation fails, @task will be set into an error state.
+ * Performs the initial handshake with an FTP server, including reading the
+ * greeting and activating TLS. If the operation fails, @task will be set into
+ * an error state.
**/
gboolean
-g_vfs_ftp_task_enable_tls (GVfsFtpTask *task,
- CertificateCallback cb,
- gpointer user_data)
+g_vfs_ftp_task_initial_handshake (GVfsFtpTask *task,
+ CertificateCallback cb,
+ gpointer user_data)
{
if (g_vfs_ftp_task_is_in_error (task))
return FALSE;
- if (!g_vfs_ftp_task_send (task, 0, "AUTH TLS"))
- return FALSE;
+ /* In implicit mode, we do the TLS handshake first, then receive the FTP
+ * greeting. Explicit mode is practically the opposite.
+ */
- if (!g_vfs_ftp_connection_enable_tls (task->conn,
- task->backend->server_identity,
- cb,
- user_data,
- task->cancellable,
- &task->error))
- return FALSE;
+ if (task->backend->tls_mode == G_VFS_FTP_TLS_MODE_IMPLICIT)
+ {
+ if (!g_vfs_ftp_connection_enable_tls (task->conn,
+ task->backend->server_identity,
+ TRUE,
+ cb,
+ user_data,
+ task->cancellable,
+ &task->error))
+ return FALSE;
+
+ if (!g_vfs_ftp_task_receive (task, 0, NULL))
+ return FALSE;
+ }
+ else if (task->backend->tls_mode == G_VFS_FTP_TLS_MODE_EXPLICIT)
+ {
+ if (!g_vfs_ftp_task_receive (task, 0, NULL))
+ return FALSE;
+
+ if (!g_vfs_ftp_task_send (task, 0, "AUTH TLS"))
+ return FALSE;
+
+ if (!g_vfs_ftp_connection_enable_tls (task->conn,
+ task->backend->server_identity,
+ FALSE,
+ cb,
+ user_data,
+ task->cancellable,
+ &task->error))
+ return FALSE;
+ }
+ else
+ {
+ if (!g_vfs_ftp_task_receive (task, 0, NULL))
+ return FALSE;
+ }
- if (!g_vfs_ftp_task_send (task, 0, "PBSZ 0"))
- return FALSE;
+ /* Request TLS also for the data channels. */
- if (!g_vfs_ftp_task_send (task, 0, "PROT P"))
- return FALSE;
+ if (task->backend->tls_mode != G_VFS_FTP_TLS_MODE_NONE)
+ {
+ if (!g_vfs_ftp_task_send (task, 0, "PBSZ 0"))
+ return FALSE;
+
+ if (!g_vfs_ftp_task_send (task, 0, "PROT P"))
+ return FALSE;
+ }
return TRUE;
}