[gvfs] afp: implement user authentication using Diffie-Hellman 1
- From: Christian Kellner <gicmo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs] afp: implement user authentication using Diffie-Hellman 1
- Date: Thu, 25 Aug 2011 19:21:31 +0000 (UTC)
commit d32a6848e01be79f38e41206f1989924d1344bb2
Author: Carl-Anton Ingmarsson <ca ingmarsson gmail com>
Date: Mon Jun 13 16:12:44 2011 +0200
afp: implement user authentication using Diffie-Hellman 1
configure.ac | 15 ++
daemon/Makefile.am | 8 +-
daemon/gvfsafpconnection.c | 65 ++++++++--
daemon/gvfsafpconnection.h | 16 ++-
daemon/gvfsbackendafp.c | 312 ++++++++++++++++++++++++++++++++++++++------
daemon/gvfsbackendafp.h | 3 +
6 files changed, 361 insertions(+), 58 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index dea6913..9951ab0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -554,6 +554,21 @@ AM_CONDITIONAL(HAVE_ARCHIVE, test "$msg_archive" = "yes")
AC_SUBST(ARCHIVE_CFLAGS)
AC_SUBST(ARCHIVE_LIBS)
+dnl ***************************
+dnl *** Check for libgcrypt ***
+dnl ***************************
+GCRYPT_VERSION=1.2.2
+GCRYPT_LIBVER=1
+
+AM_PATH_LIBGCRYPT($GCRYPT_LIBVER:$GCRYPT_VERSION, have_gcrypt="yes",
+ have_gcrypt="no")
+
+if test "x$have_gcrypt" != "xno"; then
+ AC_DEFINE(HAVE_GCRYPT, 1, [Define to 1 if libgcrypt is available])
+fi
+AC_SUBST([LIBGCRYPT_CFLAGS])
+AC_SUBST([LIBGCRYPT_LIBS])
+
dnl Install bash-completion file?
AC_ARG_ENABLE([bash-completion],
AC_HELP_STRING([--disable-bash-completion],
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index b47e1d0..816387e 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -483,9 +483,13 @@ gvfsd_afp_CPPFLAGS = \
-DBACKEND_HEADER=gvfsbackendafp.h \
-DDEFAULT_BACKEND_TYPE=afp \
-DMAX_JOB_THREADS=1 \
- -DBACKEND_TYPES='"afp-server", G_VFS_TYPE_BACKEND_AFP,'
+ -DBACKEND_TYPES='"afp-server", G_VFS_TYPE_BACKEND_AFP,' \
+ $(LIBGCRYPT_CFLAGS)
+
+gvfsd_afp_LDADD = \
+ $(libraries) \
+ $(LIBGCRYPT_LIBS)
-gvfsd_afp_LDADD = $(libraries)
# GSettings stuff
gsettings_ENUM_NAMESPACE = org.gnome.system.gvfs
diff --git a/daemon/gvfsafpconnection.c b/daemon/gvfsafpconnection.c
index 7fed840..5bbeb80 100644
--- a/daemon/gvfsafpconnection.c
+++ b/daemon/gvfsafpconnection.c
@@ -21,6 +21,7 @@
*/
#include <string.h>
+#include <glib/gi18n.h>
#include "gvfsafpconnection.h"
@@ -38,7 +39,7 @@ struct _GVfsAfpReply
{
GDataInputStream parent_instance;
- AfpErrorCode error_code;
+ AfpResultCode result_code;
};
G_DEFINE_TYPE (GVfsAfpReply, g_vfs_afp_reply, G_TYPE_DATA_INPUT_STREAM);
@@ -54,7 +55,7 @@ g_vfs_afp_reply_class_init (GVfsAfpReplyClass *klass)
}
static GVfsAfpReply *
-g_vfs_afp_reply_new (AfpErrorCode error_code, const char *data, gsize len)
+g_vfs_afp_reply_new (AfpResultCode result_code, const char *data, gsize len)
{
GVfsAfpReply *reply;
@@ -67,7 +68,7 @@ g_vfs_afp_reply_new (AfpErrorCode error_code, const char *data, gsize len)
g_memory_input_stream_new (), NULL);
- reply->error_code = error_code;
+ reply->result_code = result_code;
return reply;
}
@@ -117,10 +118,10 @@ g_vfs_afp_reply_seek (GVfsAfpReply *reply, goffset offset, GSeekType type)
return g_seekable_seek (G_SEEKABLE (mem_stream), offset, type, NULL, NULL);
}
-AfpErrorCode
-g_vfs_afp_reply_get_error_code (GVfsAfpReply *reply)
+AfpResultCode
+g_vfs_afp_reply_get_result_code (GVfsAfpReply *reply)
{
- return reply->error_code;
+ return reply->result_code;
}
/*
@@ -588,8 +589,15 @@ read_reply_sync (GInputStream *input,
read_count = sizeof (DSIHeader);
res = g_input_stream_read_all (input, dsi_header, read_count, &bytes_read,
cancellable, error);
- if (!res || bytes_read < read_count)
+ if (!res)
+ return FALSE;
+
+ if (bytes_read < read_count)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Got EOS"));
return FALSE;
+ }
dsi_header->requestID = GUINT16_FROM_BE (dsi_header->requestID);
dsi_header->errorCode = GUINT32_FROM_BE (dsi_header->errorCode);
@@ -605,9 +613,16 @@ read_reply_sync (GInputStream *input,
read_count = dsi_header->totalDataLength;
res = g_input_stream_read_all (input, *data, read_count, &bytes_read, cancellable, error);
- if (!res || bytes_read < read_count)
+ if (!res)
+ {
+ g_free (*data);
+ return FALSE;
+ }
+ if (bytes_read < read_count)
{
g_free (*data);
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Got EOS"));
return FALSE;
}
@@ -639,7 +654,7 @@ send_request_sync (GOutputStream *output,
guint16 request_id,
guint32 writeOffset,
gsize len,
- char *data,
+ const char *data,
GCancellable *cancellable,
GError **error)
{
@@ -657,7 +672,7 @@ send_request_sync (GOutputStream *output,
write_count = sizeof (DSIHeader);
res = g_output_stream_write_all (output, &dsi_header, write_count,
&bytes_written, cancellable, error);
- if (!res || bytes_written < write_count)
+ if (!res)
return FALSE;
if (data == NULL)
@@ -666,7 +681,7 @@ send_request_sync (GOutputStream *output,
write_count = len;
res = g_output_stream_write_all (output, data, write_count, &bytes_written,
cancellable, error);
- if (!res || bytes_written < write_count)
+ if (!res)
return FALSE;
return TRUE;
@@ -711,6 +726,34 @@ g_vfs_afp_connection_send_command_sync (GVfsAfpConnection *afp_connection,
}
gboolean
+g_vfs_afp_connection_close (GVfsAfpConnection *afp_connection,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GVfsAfpConnectionPrivate *priv = afp_connection->priv;
+
+ guint16 req_id;
+ gboolean res;
+
+ /* close DSI session */
+ req_id = get_request_id (afp_connection);
+ res = send_request_sync (g_io_stream_get_output_stream (priv->conn),
+ DSI_CLOSE_SESSION, req_id, 0, 0, NULL,
+ cancellable, error);
+ if (!res)
+ {
+ g_io_stream_close (priv->conn, cancellable, NULL);
+ g_object_unref (priv->conn);
+ return FALSE;
+ }
+
+ res = g_io_stream_close (priv->conn, cancellable, error);
+ g_object_unref (priv->conn);
+
+ return res;
+}
+
+gboolean
g_vfs_afp_connection_open (GVfsAfpConnection *afp_connection,
GCancellable *cancellable,
GError **error)
diff --git a/daemon/gvfsafpconnection.h b/daemon/gvfsafpconnection.h
index 4c1d518..26fa832 100644
--- a/daemon/gvfsafpconnection.h
+++ b/daemon/gvfsafpconnection.h
@@ -32,16 +32,18 @@ typedef enum
AFP_COMMAND_GET_SRVR_INFO = 15,
AFP_COMMAND_GET_SRVR_PARMS = 16,
AFP_COMMAND_LOGIN = 18,
+ AFP_COMMAND_LOGIN_CONT = 19,
AFP_COMMAND_WRITE = 33,
AFP_COMMAND_WRITE_EXT = 61
} AfpCommandType;
typedef enum
{
- AFP_ERROR_NONE = 0,
- AFP_ERROR_USER_NOT_AUTH = -5023,
- AFP_ERROR_NO_MORE_SESSIONS = -1068
-} AfpErrorCode;
+ AFP_RESULT_NO_ERROR = 0,
+ AFP_RESULT_USER_NOT_AUTH = -5023,
+ AFP_RESULT_AUTH_CONTINUE = -5001,
+ AFP_RESULT_NO_MORE_SESSIONS = -1068
+} AfpResultCode;
/*
* GVfsAfpReply
@@ -59,7 +61,7 @@ typedef struct _GVfsAfpReply GVfsAfpReply;
char * g_vfs_afp_reply_read_pascal (GVfsAfpReply *reply);
gboolean g_vfs_afp_reply_seek (GVfsAfpReply *reply, goffset offset, GSeekType type);
-AfpErrorCode g_vfs_afp_reply_get_error_code (GVfsAfpReply *reply);
+AfpResultCode g_vfs_afp_reply_get_result_code (GVfsAfpReply *reply);
GType g_vfs_afp_reply_get_type (void) G_GNUC_CONST;
@@ -135,6 +137,10 @@ gboolean g_vfs_afp_connection_open (GVfsAfpConnection *af
GCancellable *cancellable,
GError **error);
+gboolean g_vfs_afp_connection_close (GVfsAfpConnection *afp_connection,
+ GCancellable *cancellable,
+ GError **error);
+
gboolean g_vfs_afp_connection_send_command_sync (GVfsAfpConnection *afp_connection,
GVfsAfpCommand *afp_command,
GCancellable *cancellable,
diff --git a/daemon/gvfsbackendafp.c b/daemon/gvfsbackendafp.c
index 87c83d1..9d1ae5f 100644
--- a/daemon/gvfsbackendafp.c
+++ b/daemon/gvfsbackendafp.c
@@ -27,6 +27,10 @@
#include <glib/gi18n.h>
#include <gio/gio.h>
+#ifdef HAVE_GCRYPT
+#include <gcrypt.h>
+#endif
+
#include "gvfsjobmount.h"
#include "gvfsjobenumerate.h"
#include "gvfskeyring.h"
@@ -76,7 +80,7 @@ get_srvr_parms_cb (GVfsAfpConnection *afp_connection,
GVfsJobEnumerate *job = G_VFS_JOB_ENUMERATE (user_data);
GVfsBackendAfp *afp_backend = G_VFS_BACKEND_AFP (job->backend);
- AfpErrorCode error_code;
+ AfpResultCode res_code;
guint8 num_volumes, i;
if (!reply)
@@ -85,8 +89,8 @@ get_srvr_parms_cb (GVfsAfpConnection *afp_connection,
return;
}
- error_code = g_vfs_afp_reply_get_error_code (reply);
- if (error_code != AFP_ERROR_NONE)
+ res_code = g_vfs_afp_reply_get_result_code (reply);
+ if (res_code != AFP_RESULT_NO_ERROR)
{
g_vfs_job_failed_literal (G_VFS_JOB (job), G_IO_ERROR,
G_IO_ERROR_FAILED, _("Volume enumeration failed"));
@@ -231,6 +235,233 @@ try_query_info (GVfsBackend *backend,
return TRUE;
}
+#ifdef HAVE_GCRYPT
+static gboolean
+dhx_login (GVfsBackendAfp *afp_backend,
+ const char *username,
+ const char *password,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gcry_error_t gcry_err;
+ gcry_mpi_t prime, base;
+ gcry_mpi_t ra;
+
+ /* Ma */
+ gcry_mpi_t ma;
+ guint8 ma_buf[16];
+
+ GVfsAfpCommand *comm;
+ GVfsAfpReply *reply;
+ AfpResultCode res_code;
+ gboolean res;
+ guint16 id;
+
+ /* Mb */
+ guint8 mb_buf[16];
+ gcry_mpi_t mb;
+
+ /* Nonce */
+ guint8 nonce_buf[32];
+ gcry_mpi_t nonce, nonce1;
+
+ /* Key */
+ gcry_mpi_t key;
+ guint8 key_buf[16];
+
+ gcry_cipher_hd_t cipher;
+ guint8 answer_buf[80] = { 0 };
+ size_t len;
+
+ static const guint8 C2SIV[] = { 0x4c, 0x57, 0x61, 0x6c, 0x6c, 0x61, 0x63, 0x65 };
+ static const guint8 S2CIV[] = { 0x43, 0x4a, 0x61, 0x6c, 0x62, 0x65, 0x72, 0x74 };
+ static const guint8 p[] = { 0xBA, 0x28, 0x73, 0xDF, 0xB0, 0x60, 0x57, 0xD4, 0x3F, 0x20, 0x24, 0x74, 0x4C, 0xEE, 0xE7, 0x5B };
+ static const guint8 g[] = { 0x07 };
+
+ if (strlen (password) > 64)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ _("Server doesn't support passwords longer than 64 characters"));
+ return FALSE;
+ }
+
+ /* create prime and base from vectors */
+ gcry_err = gcry_mpi_scan (&prime, GCRYMPI_FMT_USG, p, G_N_ELEMENTS (p), NULL);
+ g_assert (gcry_err == 0);
+
+ gcry_err = gcry_mpi_scan (&base, GCRYMPI_FMT_USG, g, G_N_ELEMENTS (g), NULL);
+ g_assert (gcry_err == 0);
+
+ /* generate random number ra != 0 */
+ ra = gcry_mpi_new (256);
+ while (gcry_mpi_cmp_ui (ra, 0) == 0)
+ gcry_mpi_randomize (ra, 256, GCRY_STRONG_RANDOM);
+
+ /* Secret key value must be less than half of prime */
+ if (gcry_mpi_get_nbits (ra) > 255)
+ gcry_mpi_clear_highbit (ra, 255);
+
+ /* generate ma */
+ ma = gcry_mpi_new (128);
+ gcry_mpi_powm (ma, base, ra, prime);
+ gcry_mpi_release (base);
+ gcry_err = gcry_mpi_print (GCRYMPI_FMT_USG, ma_buf, G_N_ELEMENTS (ma_buf), NULL,
+ ma);
+ g_assert (gcry_err == 0);
+ gcry_mpi_release (ma);
+
+ /* Create login command */
+ comm = g_vfs_afp_command_new (AFP_COMMAND_LOGIN);
+ g_vfs_afp_command_put_pascal (comm, afp_version_to_string (afp_backend->version));
+ g_vfs_afp_command_put_pascal (comm, AFP_UAM_DHX);
+ g_vfs_afp_command_put_pascal (comm, username);
+ g_vfs_afp_command_pad_to_even (comm);
+ g_output_stream_write_all (G_OUTPUT_STREAM(comm), ma_buf, G_N_ELEMENTS (ma_buf),
+ NULL, NULL, NULL);
+
+ res = g_vfs_afp_connection_send_command_sync (afp_backend->conn, comm,
+ cancellable, error);
+ g_object_unref (comm);
+ if (!res)
+ goto done;
+
+ reply = g_vfs_afp_connection_read_reply_sync (afp_backend->conn, cancellable, error);
+ if (!reply)
+ goto error;
+
+ res_code = g_vfs_afp_reply_get_result_code (reply);
+ if (res_code != AFP_RESULT_AUTH_CONTINUE)
+ {
+ g_object_unref (reply);
+ if (res_code == AFP_RESULT_USER_NOT_AUTH)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ _("An invalid username was provided"));
+ goto error;
+ }
+ else
+ goto generic_error;
+ }
+
+ id = g_data_input_stream_read_uint16 (G_DATA_INPUT_STREAM (reply),
+ NULL, NULL);
+
+ /* read Mb */
+ g_input_stream_read_all (G_INPUT_STREAM (reply), mb_buf, G_N_ELEMENTS (mb_buf),
+ NULL, NULL, NULL);
+ gcry_err = gcry_mpi_scan (&mb, GCRYMPI_FMT_USG, mb_buf, G_N_ELEMENTS (mb_buf), NULL);
+ g_assert (gcry_err == 0);
+
+ /* read Nonce */
+ g_input_stream_read_all (G_INPUT_STREAM (reply), nonce_buf, G_N_ELEMENTS (nonce_buf),
+ NULL, NULL, NULL);
+
+ g_object_unref (reply);
+
+ /* derive key */
+ key = gcry_mpi_new (128);
+ gcry_mpi_powm (key, mb, ra, prime);
+ gcry_mpi_release (mb);
+ gcry_err = gcry_mpi_print (GCRYMPI_FMT_USG, key_buf, G_N_ELEMENTS (key_buf), NULL,
+ key);
+ g_assert (gcry_err == 0);
+ gcry_mpi_release (key);
+
+ /* setup decrypt cipher */
+ gcry_err = gcry_cipher_open (&cipher, GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC,
+ 0);
+ g_assert (gcry_err == 0);
+
+ gcry_cipher_setiv (cipher, S2CIV, G_N_ELEMENTS (S2CIV));
+ gcry_cipher_setkey (cipher, key_buf, G_N_ELEMENTS (key_buf));
+
+ /* decrypt Nonce */
+ gcry_err = gcry_cipher_decrypt (cipher, nonce_buf, G_N_ELEMENTS (nonce_buf),
+ NULL, 0);
+ g_assert (gcry_err == 0);
+
+ gcry_err = gcry_mpi_scan (&nonce, GCRYMPI_FMT_USG, nonce_buf, 16, NULL);
+ g_assert (gcry_err == 0);
+
+ /* add one to nonce */
+ nonce1 = gcry_mpi_new (128);
+ gcry_mpi_add_ui (nonce1, nonce, 1);
+ gcry_mpi_release (nonce);
+
+ /* set client->server initialization vector */
+ gcry_cipher_setiv (cipher, C2SIV, G_N_ELEMENTS (C2SIV));
+
+ /* create encrypted answer */
+ gcry_err = gcry_mpi_print (GCRYMPI_FMT_USG, answer_buf, 16, &len, nonce1);
+ g_assert (gcry_err == 0);
+ gcry_mpi_release (nonce1);
+
+ if (len < 16)
+ {
+ memmove(answer_buf + 16 - len, answer_buf, len);
+ memset(answer_buf, 0, 16 - len);
+ }
+
+ memcpy (answer_buf + 16, password, strlen (password));
+
+ gcry_err = gcry_cipher_encrypt (cipher, answer_buf, G_N_ELEMENTS (answer_buf),
+ NULL, 0);
+ g_assert (gcry_err == 0);
+
+
+ /* Create Login Continue command */
+ comm = g_vfs_afp_command_new (AFP_COMMAND_LOGIN_CONT);
+ g_data_output_stream_put_byte (G_DATA_OUTPUT_STREAM (comm), 0, NULL, NULL);
+ g_data_output_stream_put_uint16 (G_DATA_OUTPUT_STREAM (comm), id, NULL, NULL);
+ g_output_stream_write_all (G_OUTPUT_STREAM (comm), answer_buf,
+ G_N_ELEMENTS (answer_buf), NULL, NULL, NULL);
+
+
+ res = g_vfs_afp_connection_send_command_sync (afp_backend->conn, comm,
+ cancellable, error);
+ g_object_unref (comm);
+ if (!res)
+ goto done;
+
+ reply = g_vfs_afp_connection_read_reply_sync (afp_backend->conn, cancellable, error);
+ if (!reply)
+ goto error;
+
+ res_code = g_vfs_afp_reply_get_result_code (reply);
+ g_object_unref (reply);
+ if (res_code != AFP_RESULT_NO_ERROR)
+ {
+ if (res_code == AFP_RESULT_USER_NOT_AUTH)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+ _("Server \"%s\" declined the submitted password"),
+ afp_backend->server_name);
+ goto error;
+ }
+ else
+ goto generic_error;
+ }
+
+ res = TRUE;
+
+done:
+ gcry_mpi_release (prime);
+ gcry_mpi_release (ra);
+
+ return res;
+
+error:
+ res = FALSE;
+ goto done;
+
+generic_error:
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Login to server \"%s\" failed"), afp_backend->server_name);
+ res = FALSE;
+ goto done;
+}
+#endif
+
static gboolean
do_login (GVfsBackendAfp *afp_backend,
const char *username,
@@ -243,8 +474,9 @@ do_login (GVfsBackendAfp *afp_backend,
if (anonymous)
{
GVfsAfpCommand *comm;
+ gboolean res;
GVfsAfpReply *reply;
- guint32 error_code;
+ AfpResultCode res_code;
if (!g_slist_find_custom (afp_backend->uams, AFP_UAM_NO_USER, g_str_equal))
{
@@ -256,23 +488,24 @@ do_login (GVfsBackendAfp *afp_backend,
comm = g_vfs_afp_command_new (AFP_COMMAND_LOGIN);
- g_vfs_afp_command_put_pascal (comm,
- afp_version_to_string (afp_backend->version));
+ g_vfs_afp_command_put_pascal (comm, afp_version_to_string (afp_backend->version));
g_vfs_afp_command_put_pascal (comm, AFP_UAM_NO_USER);
- if (!g_vfs_afp_connection_send_command_sync (afp_backend->conn, comm,
- cancellable, error))
+ res = g_vfs_afp_connection_send_command_sync (afp_backend->conn, comm,
+ cancellable, error);
+ g_object_unref (comm);
+ if (!res)
return FALSE;
reply = g_vfs_afp_connection_read_reply_sync (afp_backend->conn, cancellable, error);
if (!reply)
return FALSE;
- error_code = g_vfs_afp_reply_get_error_code (reply);
+ res_code = g_vfs_afp_reply_get_result_code (reply);
g_object_unref (reply);
- if (error_code != AFP_ERROR_NONE)
+ if (res_code != AFP_RESULT_NO_ERROR)
{
- if (error_code == AFP_ERROR_USER_NOT_AUTH)
+ if (res_code == AFP_RESULT_USER_NOT_AUTH)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
_("Anonymous login on server \"%s\" failed"),
@@ -286,22 +519,18 @@ do_login (GVfsBackendAfp *afp_backend,
return FALSE;
}
}
+
+ return TRUE;
}
else {
- /* Diffie-Hellman 2 */
- if (g_slist_find_custom (afp_backend->uams, AFP_UAM_DHX2, g_str_equal))
- {
- g_debug ("Diffie-Hellman 2\n");
- }
-
+#ifdef HAVE_GCRYPT
/* Diffie-Hellman */
- else if (g_slist_find_custom (afp_backend->uams, AFP_UAM_DHX, g_str_equal))
- {
- g_debug ("Diffie-Hellman\n");
- }
-
+ if (g_slist_find_custom (afp_backend->uams, AFP_UAM_DHX, g_str_equal))
+ return dhx_login (afp_backend, username, password, cancellable, error);
+#endif
+
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -309,14 +538,7 @@ do_login (GVfsBackendAfp *afp_backend,
afp_backend->server_name);
return FALSE;
}
-
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
- "Non anonymous login not implemented yet");
- return FALSE;
-
}
-
- return TRUE;
}
static gboolean
@@ -332,6 +554,7 @@ g_vfs_afp_server_login (GVfsBackendAfp *afp_backend,
gboolean anonymous;
GPasswordSave password_save;
char *prompt = NULL;
+ gboolean res;
GError *err = NULL;
addr = G_NETWORK_ADDRESS (afp_backend->addr);
@@ -370,7 +593,6 @@ g_vfs_afp_server_login (GVfsBackendAfp *afp_backend,
{
GAskPasswordFlags flags;
gboolean aborted;
- gboolean res;
if (prompt == NULL)
{
@@ -380,7 +602,7 @@ g_vfs_afp_server_login (GVfsBackendAfp *afp_backend,
prompt = g_strdup_printf (_("Enter password for afp as %s on %s"), initial_user, afp_backend->server_name);
else
/* translators: %s here is the hostname */
- prompt = g_strdup_printf (_("Enter password for ftp on %s"), afp_backend->server_name);
+ prompt = g_strdup_printf (_("Enter password for afp on %s"), afp_backend->server_name);
}
flags = G_ASK_PASSWORD_NEED_PASSWORD;
@@ -407,15 +629,23 @@ g_vfs_afp_server_login (GVfsBackendAfp *afp_backend,
g_set_error_literal (&err, G_IO_ERROR,
aborted ? G_IO_ERROR_FAILED_HANDLED : G_IO_ERROR_PERMISSION_DENIED,
_("Password dialog cancelled"));
+ res = FALSE;
break;
}
try_login:
+ /* Open connection */
+ res = g_vfs_afp_connection_open (afp_backend->conn, cancellable, &err);
+ if (!res)
+ break;
+
res = do_login (afp_backend, user, password, anonymous,
cancellable, &err);
if (!res)
{
+ g_vfs_afp_connection_close (afp_backend->conn, cancellable, NULL);
+
if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
g_clear_error (&err);
else
@@ -428,13 +658,12 @@ try_login:
g_free (olduser);
olduser = user;
-
g_free (password);
}
g_free (olduser);
- if (err != NULL)
+ if (!res)
{
g_free (user);
g_free (password);
@@ -541,13 +770,6 @@ do_mount (GVfsBackend *backend,
}
g_object_unref (reply);
-
- /* Open connection */
- res = g_vfs_afp_connection_open (afp_backend->conn, G_VFS_JOB (job)->cancellable,
- &err);
- if (!res)
- goto error;
-
res = g_vfs_afp_server_login (afp_backend, afp_backend->user, mount_source,
G_VFS_JOB (job)->cancellable, &err);
if (!res)
@@ -650,3 +872,13 @@ g_vfs_backend_afp_class_init (GVfsBackendAfpClass *klass)
backend_class->try_enumerate = try_enumerate;
}
+void
+g_vfs_afp_daemon_init (void)
+{
+ g_set_application_name (_("Apple Filing Protocol Service"));
+
+#ifdef HAVE_GCRYPT
+ gcry_check_version (NULL);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+}
diff --git a/daemon/gvfsbackendafp.h b/daemon/gvfsbackendafp.h
index 03d73bd..0e47d55 100644
--- a/daemon/gvfsbackendafp.h
+++ b/daemon/gvfsbackendafp.h
@@ -72,6 +72,9 @@ struct _GVfsBackendAfp
GType g_vfs_backend_afp_get_type (void) G_GNUC_CONST;
+#define BACKEND_SETUP_FUNC g_vfs_afp_daemon_init
+void g_vfs_afp_daemon_init (void);
+
G_END_DECLS
#endif /* _GVFSBACKENDAFP_H_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]