|
Packit |
79f644 |
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
Packit |
79f644 |
/*
|
|
Packit |
79f644 |
* Copyright © 2011 – 2017 Red Hat, Inc.
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
79f644 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
79f644 |
* License as published by the Free Software Foundation; either
|
|
Packit |
79f644 |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
79f644 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
79f644 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
79f644 |
* Lesser General Public License for more details.
|
|
Packit |
79f644 |
*
|
|
Packit |
79f644 |
* You should have received a copy of the GNU Lesser General
|
|
Packit |
79f644 |
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#include "config.h"
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#include <glib/gi18n-lib.h>
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
#include "goamailclient.h"
|
|
Packit |
79f644 |
#include "goautils.h"
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* The timeout used for non-IDLE commands */
|
|
Packit |
79f644 |
#define COMMAND_TIMEOUT_SEC 30
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
struct _GoaMailClient
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
/*< private >*/
|
|
Packit |
79f644 |
GObject parent_instance;
|
|
Packit |
79f644 |
};
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
typedef struct _GoaMailClientClass GoaMailClientClass;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
struct _GoaMailClientClass
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GObjectClass parent_class;
|
|
Packit |
79f644 |
};
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
G_DEFINE_TYPE (GoaMailClient, goa_mail_client, G_TYPE_OBJECT);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* ---------------------------------------------------------------------------------------------------- */
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
goa_mail_client_init (GoaMailClient *self)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
goa_mail_client_class_init (GoaMailClientClass *klass)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* ---------------------------------------------------------------------------------------------------- */
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
GoaMailClient *
|
|
Packit |
79f644 |
goa_mail_client_new (void)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
return GOA_MAIL_CLIENT (g_object_new (GOA_TYPE_MAIL_CLIENT, NULL));
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* ---------------------------------------------------------------------------------------------------- */
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
typedef struct
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GDataInputStream *input;
|
|
Packit |
79f644 |
GDataOutputStream *output;
|
|
Packit |
79f644 |
GIOStream *tls_conn;
|
|
Packit |
79f644 |
GSocket *socket;
|
|
Packit |
79f644 |
GSocketClient *sc;
|
|
Packit |
79f644 |
GSocketConnection *conn;
|
|
Packit |
79f644 |
GTlsCertificateFlags cert_flags;
|
|
Packit |
79f644 |
GoaMailAuth *auth;
|
|
Packit |
79f644 |
GoaTlsType tls_type;
|
|
Packit |
79f644 |
gboolean accept_ssl_errors;
|
|
Packit |
79f644 |
gchar *host_and_port;
|
|
Packit |
79f644 |
guint16 default_port;
|
|
Packit |
79f644 |
} CheckData;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
mail_client_check_data_free (CheckData *data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_object_unref (data->sc);
|
|
Packit |
79f644 |
g_object_unref (data->auth);
|
|
Packit |
79f644 |
g_clear_object (&data->input);
|
|
Packit |
79f644 |
g_clear_object (&data->output);
|
|
Packit |
79f644 |
g_clear_object (&data->socket);
|
|
Packit |
79f644 |
g_clear_object (&data->conn);
|
|
Packit |
79f644 |
g_clear_object (&data->tls_conn);
|
|
Packit |
79f644 |
g_free (data->host_and_port);
|
|
Packit |
79f644 |
g_slice_free (CheckData, data);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static gboolean
|
|
Packit |
79f644 |
mail_client_check_accept_certificate_cb (GTlsConnection *conn,
|
|
Packit |
79f644 |
GTlsCertificate *peer_cert,
|
|
Packit |
79f644 |
GTlsCertificateFlags errors,
|
|
Packit |
79f644 |
gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
CheckData *data = user_data;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* Fail the connection if the certificate is invalid. */
|
|
Packit |
79f644 |
data->cert_flags = errors;
|
|
Packit |
79f644 |
return FALSE;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
mail_client_check_event_cb (GSocketClient *sc,
|
|
Packit |
79f644 |
GSocketClientEvent event,
|
|
Packit |
79f644 |
GSocketConnectable *connectable,
|
|
Packit |
79f644 |
GIOStream *connection,
|
|
Packit |
79f644 |
gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
CheckData *data = user_data;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (event != G_SOCKET_CLIENT_TLS_HANDSHAKING)
|
|
Packit |
79f644 |
return;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
data->tls_conn = g_object_ref (connection);
|
|
Packit |
79f644 |
if (data->accept_ssl_errors)
|
|
Packit |
79f644 |
g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (data->tls_conn), 0);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_signal_connect (data->tls_conn,
|
|
Packit |
79f644 |
"accept-certificate",
|
|
Packit |
79f644 |
G_CALLBACK (mail_client_check_accept_certificate_cb),
|
|
Packit |
79f644 |
data);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
mail_client_check_auth_run_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GTask *task = G_TASK (user_data);
|
|
Packit |
79f644 |
CheckData *data;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
data = g_task_get_task_data (task);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
if (!goa_mail_auth_run_finish (data->auth, res, &error))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_warning ("goa_mail_auth_run() failed: %s (%s, %d)",
|
|
Packit |
79f644 |
error->message,
|
|
Packit |
79f644 |
g_quark_to_string (error->domain),
|
|
Packit |
79f644 |
error->code);
|
|
Packit |
79f644 |
g_task_return_error (task, error);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_io_stream_close (G_IO_STREAM (data->conn), NULL, NULL);
|
|
Packit |
79f644 |
g_task_return_boolean (task, TRUE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_object_unref (G_OBJECT (task));
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
mail_client_check_tls_conn_handshake_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GTask *task = G_TASK (user_data);
|
|
Packit |
79f644 |
CheckData *data;
|
|
Packit |
79f644 |
GCancellable *cancellable;
|
|
Packit |
79f644 |
GDataInputStream *input;
|
|
Packit |
79f644 |
GDataOutputStream *output;
|
|
Packit |
79f644 |
GInputStream *base_input;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
GOutputStream *base_output;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
input = NULL;
|
|
Packit |
79f644 |
output = NULL;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
cancellable = g_task_get_cancellable (task);
|
|
Packit |
79f644 |
data = g_task_get_task_data (task);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
if (!g_tls_connection_handshake_finish (G_TLS_CONNECTION (data->tls_conn), res, &error))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_warning ("g_tls_connection_handshake() failed: %s (%s, %d)",
|
|
Packit |
79f644 |
error->message,
|
|
Packit |
79f644 |
g_quark_to_string (error->domain),
|
|
Packit |
79f644 |
error->code);
|
|
Packit |
79f644 |
/* GIO sets G_TLS_ERROR_BAD_CERTIFICATE when it should be
|
|
Packit |
79f644 |
* setting G_TLS_ERROR_HANDSHAKE. Hence, lets check the
|
|
Packit |
79f644 |
* GTlsCertificate flags to accommodate future GIO fixes.
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
if (data->cert_flags != 0)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GError *tls_error;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
tls_error = NULL;
|
|
Packit |
79f644 |
goa_utils_set_error_ssl (&tls_error, data->cert_flags);
|
|
Packit |
79f644 |
g_task_return_error (task, tls_error);
|
|
Packit |
79f644 |
g_error_free (error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
error->domain = GOA_ERROR;
|
|
Packit |
79f644 |
error->code = GOA_ERROR_FAILED; /* TODO: more specific */
|
|
Packit |
79f644 |
g_task_return_error (task, error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_clear_object (&data->conn);
|
|
Packit |
79f644 |
data->conn = g_tcp_wrapper_connection_new (data->tls_conn, data->socket);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
base_input = g_io_stream_get_input_stream (G_IO_STREAM (data->conn));
|
|
Packit |
79f644 |
input = g_data_input_stream_new (base_input);
|
|
Packit |
79f644 |
g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (input), FALSE);
|
|
Packit |
79f644 |
g_data_input_stream_set_newline_type (input, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
|
|
Packit |
79f644 |
goa_mail_auth_set_input (data->auth, input);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
base_output = g_io_stream_get_output_stream (G_IO_STREAM (data->conn));
|
|
Packit |
79f644 |
output = g_data_output_stream_new (base_output);
|
|
Packit |
79f644 |
g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (output), FALSE);
|
|
Packit |
79f644 |
goa_mail_auth_set_output (data->auth, output);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
goa_mail_auth_run (data->auth, cancellable, mail_client_check_auth_run_cb, g_object_ref (task));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_clear_object (&input);
|
|
Packit |
79f644 |
g_clear_object (&output);
|
|
Packit |
79f644 |
g_object_unref (G_OBJECT (task));
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
mail_client_check_auth_starttls_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GTask *task = G_TASK (user_data);
|
|
Packit |
79f644 |
CheckData *data;
|
|
Packit |
79f644 |
GCancellable *cancellable;
|
|
Packit |
79f644 |
GSocketConnectable *server_identity;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
server_identity = NULL;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
cancellable = g_task_get_cancellable (task);
|
|
Packit |
79f644 |
data = g_task_get_task_data (task);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
if (!goa_mail_auth_starttls_finish (data->auth, res, &error))
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_warning ("goa_mail_auth_starttls() failed: %s (%s, %d)",
|
|
Packit |
79f644 |
error->message,
|
|
Packit |
79f644 |
g_quark_to_string (error->domain),
|
|
Packit |
79f644 |
error->code);
|
|
Packit |
79f644 |
g_task_return_error (task, error);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
server_identity = g_network_address_parse (data->host_and_port, data->default_port, &error);
|
|
Packit |
79f644 |
if (server_identity == NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_task_return_error (task, error);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
data->tls_conn = g_tls_client_connection_new (G_IO_STREAM (data->conn), server_identity, &error);
|
|
Packit |
79f644 |
if (data->tls_conn == NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_task_return_error (task, error);
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (data->accept_ssl_errors)
|
|
Packit |
79f644 |
g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (data->tls_conn), 0);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_signal_connect (data->tls_conn,
|
|
Packit |
79f644 |
"accept-certificate",
|
|
Packit |
79f644 |
G_CALLBACK (mail_client_check_accept_certificate_cb),
|
|
Packit |
79f644 |
data);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_tls_connection_handshake_async (G_TLS_CONNECTION (data->tls_conn),
|
|
Packit |
79f644 |
G_PRIORITY_DEFAULT,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
mail_client_check_tls_conn_handshake_cb,
|
|
Packit |
79f644 |
g_object_ref (task));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_clear_object (&server_identity);
|
|
Packit |
79f644 |
g_object_unref (G_OBJECT (task));
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
mail_client_check_connect_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GTask *task = G_TASK (user_data);
|
|
Packit |
79f644 |
CheckData *data;
|
|
Packit |
79f644 |
GCancellable *cancellable;
|
|
Packit |
79f644 |
GDataInputStream *input;
|
|
Packit |
79f644 |
GDataOutputStream *output;
|
|
Packit |
79f644 |
GInputStream *base_input;
|
|
Packit |
79f644 |
GError *error;
|
|
Packit |
79f644 |
GOutputStream *base_output;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
cancellable = g_task_get_cancellable (task);
|
|
Packit |
79f644 |
data = g_task_get_task_data (task);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
error = NULL;
|
|
Packit |
79f644 |
data->conn = g_socket_client_connect_to_host_finish (data->sc, res, &error);
|
|
Packit |
79f644 |
if (data->conn == NULL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_warning ("g_socket_client_connect_to_host() failed: %s (%s, %d)",
|
|
Packit |
79f644 |
error->message,
|
|
Packit |
79f644 |
g_quark_to_string (error->domain),
|
|
Packit |
79f644 |
error->code);
|
|
Packit |
79f644 |
/* GIO sets G_TLS_ERROR_BAD_CERTIFICATE when it should be
|
|
Packit |
79f644 |
* setting G_TLS_ERROR_HANDSHAKE. Hence, lets check the
|
|
Packit |
79f644 |
* GTlsCertificate flags to accommodate future GIO fixes.
|
|
Packit |
79f644 |
*/
|
|
Packit |
79f644 |
if (data->cert_flags != 0)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GError *tls_error;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
tls_error = NULL;
|
|
Packit |
79f644 |
goa_utils_set_error_ssl (&tls_error, data->cert_flags);
|
|
Packit |
79f644 |
g_task_return_error (task, tls_error);
|
|
Packit |
79f644 |
g_error_free (error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
error->domain = GOA_ERROR;
|
|
Packit |
79f644 |
error->code = GOA_ERROR_FAILED; /* TODO: more specific */
|
|
Packit |
79f644 |
g_task_return_error (task, error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
goto out;
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* fail quickly */
|
|
Packit |
79f644 |
data->socket = g_object_ref (g_socket_connection_get_socket (data->conn));
|
|
Packit |
79f644 |
g_socket_set_timeout (data->socket, COMMAND_TIMEOUT_SEC);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
base_input = g_io_stream_get_input_stream (G_IO_STREAM (data->conn));
|
|
Packit |
79f644 |
input = g_data_input_stream_new (base_input);
|
|
Packit |
79f644 |
g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (input), FALSE);
|
|
Packit |
79f644 |
g_data_input_stream_set_newline_type (input, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
|
|
Packit |
79f644 |
goa_mail_auth_set_input (data->auth, input);
|
|
Packit |
79f644 |
g_object_unref (input);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
base_output = g_io_stream_get_output_stream (G_IO_STREAM (data->conn));
|
|
Packit |
79f644 |
output = g_data_output_stream_new (base_output);
|
|
Packit |
79f644 |
g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (output), FALSE);
|
|
Packit |
79f644 |
goa_mail_auth_set_output (data->auth, output);
|
|
Packit |
79f644 |
g_object_unref (output);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
if (data->tls_type == GOA_TLS_TYPE_STARTTLS)
|
|
Packit |
79f644 |
goa_mail_auth_starttls (data->auth, cancellable, mail_client_check_auth_starttls_cb, g_object_ref (task));
|
|
Packit |
79f644 |
else
|
|
Packit |
79f644 |
goa_mail_auth_run (data->auth, cancellable, mail_client_check_auth_run_cb, g_object_ref (task));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
out:
|
|
Packit |
79f644 |
g_object_unref (G_OBJECT (task));
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
void
|
|
Packit |
79f644 |
goa_mail_client_check (GoaMailClient *self,
|
|
Packit |
79f644 |
const gchar *host_and_port,
|
|
Packit |
79f644 |
GoaTlsType tls_type,
|
|
Packit |
79f644 |
gboolean accept_ssl_errors,
|
|
Packit |
79f644 |
guint16 default_port,
|
|
Packit |
79f644 |
GoaMailAuth *auth,
|
|
Packit |
79f644 |
GCancellable *cancellable,
|
|
Packit |
79f644 |
GAsyncReadyCallback callback,
|
|
Packit |
79f644 |
gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
CheckData *data;
|
|
Packit |
79f644 |
GTask *task;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_if_fail (GOA_IS_MAIL_CLIENT (self));
|
|
Packit |
79f644 |
g_return_if_fail (host_and_port != NULL && host_and_port[0] != '\0');
|
|
Packit |
79f644 |
g_return_if_fail (GOA_IS_MAIL_AUTH (auth));
|
|
Packit |
79f644 |
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
task = g_task_new (self, cancellable, callback, user_data);
|
|
Packit |
79f644 |
g_task_set_source_tag (task, goa_mail_client_check);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
data = g_slice_new0 (CheckData);
|
|
Packit |
79f644 |
g_task_set_task_data (task, data, (GDestroyNotify) mail_client_check_data_free);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
data->sc = g_socket_client_new ();
|
|
Packit |
79f644 |
if (tls_type == GOA_TLS_TYPE_SSL)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
g_socket_client_set_tls (data->sc, TRUE);
|
|
Packit |
79f644 |
g_signal_connect (data->sc, "event", G_CALLBACK (mail_client_check_event_cb), data);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
data->host_and_port = g_strdup (host_and_port);
|
|
Packit |
79f644 |
data->tls_type = tls_type;
|
|
Packit |
79f644 |
data->accept_ssl_errors = accept_ssl_errors;
|
|
Packit |
79f644 |
data->default_port = default_port;
|
|
Packit |
79f644 |
data->auth = g_object_ref (auth);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_socket_client_connect_to_host_async (data->sc,
|
|
Packit |
79f644 |
data->host_and_port,
|
|
Packit |
79f644 |
data->default_port,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
mail_client_check_connect_cb,
|
|
Packit |
79f644 |
g_object_ref (task));
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_object_unref (task);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gboolean
|
|
Packit |
79f644 |
goa_mail_client_check_finish (GoaMailClient *self, GAsyncResult *res, GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GTask *task;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (GOA_IS_MAIL_CLIENT (self), FALSE);
|
|
Packit |
79f644 |
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (g_task_is_valid (res, self), FALSE);
|
|
Packit |
79f644 |
task = G_TASK (res);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_return_val_if_fail (g_task_get_source_tag (task) == goa_mail_client_check, FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return g_task_propagate_boolean (task, error);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
/* ---------------------------------------------------------------------------------------------------- */
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
typedef struct
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
GError **error;
|
|
Packit |
79f644 |
GMainLoop *loop;
|
|
Packit |
79f644 |
gboolean op_res;
|
|
Packit |
79f644 |
} CheckSyncData;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
static void
|
|
Packit |
79f644 |
mail_client_check_sync_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
CheckSyncData *data = user_data;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
data->op_res = goa_mail_client_check_finish (GOA_MAIL_CLIENT (source_object), res, data->error);
|
|
Packit |
79f644 |
g_main_loop_quit (data->loop);
|
|
Packit |
79f644 |
}
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
gboolean
|
|
Packit |
79f644 |
goa_mail_client_check_sync (GoaMailClient *self,
|
|
Packit |
79f644 |
const gchar *host_and_port,
|
|
Packit |
79f644 |
GoaTlsType tls_type,
|
|
Packit |
79f644 |
gboolean accept_ssl_errors,
|
|
Packit |
79f644 |
guint16 default_port,
|
|
Packit |
79f644 |
GoaMailAuth *auth,
|
|
Packit |
79f644 |
GCancellable *cancellable,
|
|
Packit |
79f644 |
GError **error)
|
|
Packit |
79f644 |
{
|
|
Packit |
79f644 |
CheckSyncData data;
|
|
Packit |
79f644 |
GMainContext *context = NULL;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
data.error = error;
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
context = g_main_context_new ();
|
|
Packit |
79f644 |
g_main_context_push_thread_default (context);
|
|
Packit |
79f644 |
data.loop = g_main_loop_new (context, FALSE);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
goa_mail_client_check (self,
|
|
Packit |
79f644 |
host_and_port,
|
|
Packit |
79f644 |
tls_type,
|
|
Packit |
79f644 |
accept_ssl_errors,
|
|
Packit |
79f644 |
default_port,
|
|
Packit |
79f644 |
auth,
|
|
Packit |
79f644 |
cancellable,
|
|
Packit |
79f644 |
mail_client_check_sync_cb,
|
|
Packit |
79f644 |
&data);
|
|
Packit |
79f644 |
g_main_loop_run (data.loop);
|
|
Packit |
79f644 |
g_main_loop_unref (data.loop);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
g_main_context_pop_thread_default (context);
|
|
Packit |
79f644 |
g_main_context_unref (context);
|
|
Packit |
79f644 |
|
|
Packit |
79f644 |
return data.op_res;
|
|
Packit |
79f644 |
}
|