Пример #1
0
/**
 * em_utils_folder_is_drafts:
 * @registry: an #ESourceRegistry
 * @folder: a #CamelFolder
 *
 * Decides if @folder is a Drafts folder.
 *
 * Returns %TRUE if this is a Drafts folder or %FALSE otherwise.
 **/
gboolean
em_utils_folder_is_drafts (ESourceRegistry *registry,
                           CamelFolder *folder)
{
	CamelFolder *local_drafts_folder;
	CamelSession *session;
	CamelStore *store;
	GList *list, *iter;
	gchar *folder_uri;
	gboolean is_drafts = FALSE;
	const gchar *extension_name;

	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);

	store = camel_folder_get_parent_store (folder);
	session = camel_service_ref_session (CAMEL_SERVICE (store));

	local_drafts_folder =
		e_mail_session_get_local_folder (
		E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_DRAFTS);

	if (folder == local_drafts_folder) {
		is_drafts = TRUE;
		goto exit;
	}

	folder_uri = e_mail_folder_uri_from_folder (folder);

	store = camel_folder_get_parent_store (folder);

	extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
	list = e_source_registry_list_sources (registry, extension_name);

	for (iter = list; iter != NULL; iter = g_list_next (iter)) {
		ESource *source = E_SOURCE (iter->data);
		ESourceExtension *extension;
		const gchar *drafts_folder_uri;

		extension = e_source_get_extension (source, extension_name);

		drafts_folder_uri =
			e_source_mail_composition_get_drafts_folder (
			E_SOURCE_MAIL_COMPOSITION (extension));

		if (drafts_folder_uri != NULL)
			is_drafts = e_mail_folder_uri_equal (
				session, folder_uri, drafts_folder_uri);

		if (is_drafts)
			break;
	}

	g_list_free_full (list, (GDestroyNotify) g_object_unref);
	g_free (folder_uri);

exit:
	g_object_unref (session);

	return is_drafts;
}
Пример #2
0
static void
send_receive_add_to_menu (SendReceiveData *data,
                          CamelService *service,
                          gint position)
{
	GtkWidget *menu_item;
	CamelProvider *provider;

	if (send_receive_find_menu_item (data, service) != NULL)
		return;

	provider = camel_service_get_provider (service);

	menu_item = gtk_menu_item_new ();
	gtk_widget_show (menu_item);

	e_binding_bind_property (
		service, "display-name",
		menu_item, "label",
		G_BINDING_SYNC_CREATE);

	if (provider && (provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0) {
		gpointer object;

		if (CAMEL_IS_OFFLINE_STORE (service))
			object = g_object_ref (service);
		else
			object = camel_service_ref_session (service);

		e_signal_connect_notify_object (
			object, "notify::online",
			G_CALLBACK (service_online_state_changed_cb), menu_item,
			0);

		g_object_unref (object);
	}

	g_hash_table_insert (
		data->menu_items, menu_item,
		g_object_ref (service));

	g_signal_connect (
		menu_item, "activate",
		G_CALLBACK (send_receive_account_item_activate_cb), data);

	/* Position is with respect to the sorted list of CamelService-s,
	 * not menu item position. */
	if (position < 0)
		gtk_menu_shell_append (data->menu, menu_item);
	else
		gtk_menu_shell_insert (data->menu, menu_item, position + 4);
}
Пример #3
0
void
mail_filter_rename_folder (CamelStore *store,
                           const gchar *old_folder_name,
                           const gchar *new_folder_name)
{
	CamelSession *session;
	EMFilterContext *fc;
	const gchar *config_dir;
	gchar *user, *system;
	GList *changed;
	gchar *old_uri;
	gchar *new_uri;

	g_return_if_fail (CAMEL_IS_STORE (store));
	g_return_if_fail (old_folder_name != NULL);
	g_return_if_fail (new_folder_name != NULL);

	session = camel_service_ref_session (CAMEL_SERVICE (store));

	old_uri = e_mail_folder_uri_build (store, old_folder_name);
	new_uri = e_mail_folder_uri_build (store, new_folder_name);

	fc = em_filter_context_new (E_MAIL_SESSION (session));
	config_dir = mail_session_get_config_dir ();
	user = g_build_filename (config_dir, "filters.xml", NULL);
	system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
	e_rule_context_load ((ERuleContext *) fc, system, user);
	g_free (system);

	changed = e_rule_context_rename_uri (
		(ERuleContext *) fc, old_uri, new_uri, g_str_equal);
	if (changed) {
		if (e_rule_context_save ((ERuleContext *) fc, user) == -1)
			g_warning ("Could not write out changed filter rules\n");
		e_rule_context_free_uri_list ((ERuleContext *) fc, changed);
	}

	g_free (user);
	g_object_unref (fc);

	g_free (old_uri);
	g_free (new_uri);

	g_object_unref (session);
}
Пример #4
0
static gboolean
ews_transport_connect_sync (CamelService *service,
			    GCancellable *cancellable,
			    GError **error)
{
	EEwsConnection *connection;
	CamelSession *session;
	CamelSettings *settings;
	gchar *auth_mech;
	gboolean success;

	/* Chain up to parent's method. */
	if (!CAMEL_SERVICE_CLASS (camel_ews_transport_parent_class)->connect_sync (service, cancellable, error))
		return FALSE;

	if (camel_service_get_connection_status (service) == CAMEL_SERVICE_DISCONNECTED)
		return FALSE;

	connection = ews_transport_ref_connection (CAMEL_EWS_TRANSPORT (service));
	if (connection) {
		g_object_unref (connection);
		return TRUE;
	}

	session = camel_service_ref_session (service);
	settings = camel_service_ref_settings (service);

	/* Try running an operation that requires authentication
	 * to make sure we have valid credentials available. */
	auth_mech = camel_network_settings_dup_auth_mechanism (CAMEL_NETWORK_SETTINGS (settings));

	success = camel_session_authenticate_sync (session, service,
			   auth_mech ? auth_mech : "NTLM", cancellable, error);

	g_free (auth_mech);

	g_object_unref (session);
	g_object_unref (settings);

	return success;
}
Пример #5
0
/**
 * em_utils_folder_is_outbox:
 * @registry: an #ESourceRegistry
 * @folder: a #CamelFolder
 *
 * Decides if @folder is an Outbox folder.
 *
 * Returns %TRUE if this is an Outbox folder or %FALSE otherwise.
 **/
gboolean
em_utils_folder_is_outbox (ESourceRegistry *registry,
                           CamelFolder *folder)
{
	CamelStore *store;
	CamelSession *session;
	CamelFolder *local_outbox_folder;
	gboolean is_outbox;

	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);

	store = camel_folder_get_parent_store (folder);
	session = camel_service_ref_session (CAMEL_SERVICE (store));

	local_outbox_folder =
		e_mail_session_get_local_folder (
		E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_OUTBOX);

	is_outbox = (folder == local_outbox_folder);

	g_object_unref (session);

	return is_outbox;
}
static gboolean
sendmail_send_to_sync (CamelTransport *transport,
                       CamelMimeMessage *message,
                       CamelAddress *from,
                       CamelAddress *recipients,
		       gboolean *out_sent_message_saved,
                       GCancellable *cancellable,
                       GError **error)
{
	CamelHeaderRaw *header, *savedbcc, *n, *tail;
	const gchar *from_addr, *addr;
	GPtrArray *argv_arr;
	gint i, len, fd[2], nullfd, wstat;
	CamelStream *filter;
	CamelMimeFilter *crlf;
	sigset_t mask, omask;
	CamelStream *out;
	CamelSendmailSettings *settings;
	const gchar *binary = SENDMAIL_PATH;
	gchar *custom_binary = NULL, *custom_args = NULL;
	gboolean success;
	pid_t pid;

	success = camel_internet_address_get (
		CAMEL_INTERNET_ADDRESS (from), 0, NULL, &from_addr);

	if (!success) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Failed to read From address"));
		return FALSE;
	}

	settings = CAMEL_SENDMAIL_SETTINGS (camel_service_ref_settings (CAMEL_SERVICE (transport)));

	if (!camel_sendmail_settings_get_send_in_offline (settings)) {
		CamelSession *session;
		gboolean is_online;

		session = camel_service_ref_session (CAMEL_SERVICE (transport));
		is_online = session && camel_session_get_online (session);
		g_clear_object (&session);

		if (!is_online) {
			g_set_error (
				error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE,
				_("Message send in offline mode is disabled"));
			return FALSE;
		}
	}

	if (camel_sendmail_settings_get_use_custom_binary (settings)) {
		custom_binary = camel_sendmail_settings_dup_custom_binary (settings);
		if (custom_binary && *custom_binary)
			binary = custom_binary;
	}

	if (camel_sendmail_settings_get_use_custom_args (settings)) {
		custom_args = camel_sendmail_settings_dup_custom_args (settings);
		/* means no arguments used */
		if (!custom_args)
			custom_args = g_strdup ("");
	}

	g_object_unref (settings);

	len = camel_address_length (recipients);
	for (i = 0; i < len; i++) {
		success = camel_internet_address_get (
			CAMEL_INTERNET_ADDRESS (recipients), i, NULL, &addr);

		if (!success) {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("Could not parse recipient list"));
			g_free (custom_binary);
			g_free (custom_args);

			return FALSE;
		}
	}

	argv_arr = parse_sendmail_args (
		binary,
		custom_args ? custom_args : "-i -f %F -- %R",
		from_addr,
		recipients);

	if (!argv_arr) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Could not parse arguments"));

		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	}

	/* unlink the bcc headers */
	savedbcc = NULL;
	tail = (CamelHeaderRaw *) &savedbcc;

	header = (CamelHeaderRaw *) &CAMEL_MIME_PART (message)->headers;
	n = header->next;
	while (n != NULL) {
		if (!g_ascii_strcasecmp (n->name, "Bcc")) {
			header->next = n->next;
			tail->next = n;
			n->next = NULL;
			tail = n;
		} else {
			header = n;
		}

		n = header->next;
	}

	if (pipe (fd) == -1) {
		g_set_error (
			error, G_IO_ERROR,
			g_io_error_from_errno (errno),
			_("Could not create pipe to '%s': %s: "
			"mail not sent"), binary, g_strerror (errno));

		/* restore the bcc headers */
		header->next = savedbcc;
		g_free (custom_binary);
		g_free (custom_args);
		g_ptr_array_free (argv_arr, TRUE);

		return FALSE;
	}

	/* Block SIGCHLD so the calling application doesn't notice
	 * sendmail exiting before we do.
	 */
	sigemptyset (&mask);
	sigaddset (&mask, SIGCHLD);
	sigprocmask (SIG_BLOCK, &mask, &omask);

	pid = fork ();
	switch (pid) {
	case -1:
		g_set_error (
			error, G_IO_ERROR,
			g_io_error_from_errno (errno),
			_("Could not fork '%s': %s: "
			"mail not sent"), binary, g_strerror (errno));
		close (fd[0]);
		close (fd[1]);
		sigprocmask (SIG_SETMASK, &omask, NULL);

		/* restore the bcc headers */
		header->next = savedbcc;
		g_free (custom_binary);
		g_free (custom_args);
		g_ptr_array_free (argv_arr, TRUE);

		return FALSE;
	case 0:
		/* Child process */
		nullfd = open ("/dev/null", O_RDWR);
		dup2 (fd[0], STDIN_FILENO);
		if (nullfd != -1) {
			/*dup2 (nullfd, STDOUT_FILENO);
			  dup2 (nullfd, STDERR_FILENO);*/
			close (nullfd);
		}
		close (fd[1]);

		execv (binary, (gchar **) argv_arr->pdata);
		_exit (255);
	}

	g_ptr_array_free (argv_arr, TRUE);

	/* Parent process. Write the message out. */
	close (fd[0]);
	out = camel_stream_fs_new_with_fd (fd[1]);

	/* XXX Workaround for lame sendmail implementations
	 *     that can't handle CRLF eoln sequences. */
	filter = camel_stream_filter_new (out);
	crlf = camel_mime_filter_crlf_new (
		CAMEL_MIME_FILTER_CRLF_DECODE,
		CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
	camel_stream_filter_add (CAMEL_STREAM_FILTER (filter), crlf);
	g_object_unref (crlf);
	g_object_unref (out);

	out = (CamelStream *) filter;
	if (camel_data_wrapper_write_to_stream_sync (
		CAMEL_DATA_WRAPPER (message), out, cancellable, error) == -1
	    || camel_stream_close (out, cancellable, error) == -1) {
		g_object_unref (out);
		g_prefix_error (error, _("Could not send message: "));

		/* Wait for sendmail to exit. */
		while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
			;

		sigprocmask (SIG_SETMASK, &omask, NULL);

		/* restore the bcc headers */
		header->next = savedbcc;
		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	}

	g_object_unref (out);

	/* Wait for sendmail to exit. */
	while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
		;

	sigprocmask (SIG_SETMASK, &omask, NULL);

	/* restore the bcc headers */
	header->next = savedbcc;

	if (!WIFEXITED (wstat)) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("'%s' exited with signal %s: mail not sent."),
			binary, g_strsignal (WTERMSIG (wstat)));
		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	} else if (WEXITSTATUS (wstat) != 0) {
		if (WEXITSTATUS (wstat) == 255) {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("Could not execute '%s': mail not sent."),
				binary);
		} else {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("'%s' exited with status %d: "
				"mail not sent."),
				binary, WEXITSTATUS (wstat));
		}
		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	}

	g_free (custom_binary);
	g_free (custom_args);

	return TRUE;
}
Пример #7
0
static gboolean
pop3_store_connect_sync (CamelService *service,
                         GCancellable *cancellable,
                         GError **error)
{
	CamelPOP3Store *store = (CamelPOP3Store *) service;
	CamelPOP3Engine *pop3_engine;
	CamelSettings *settings;
	CamelSession *session;
	const gchar *user_data_dir;
	gboolean success = TRUE;
	gchar *mechanism;

	session = camel_service_ref_session (service);
	user_data_dir = camel_service_get_user_data_dir (service);

	settings = camel_service_ref_settings (service);

	mechanism = camel_network_settings_dup_auth_mechanism (
		CAMEL_NETWORK_SETTINGS (settings));

	g_object_unref (settings);

	if (!camel_session_get_online (session)) {
		g_set_error (
			error, CAMEL_SERVICE_ERROR,
			CAMEL_SERVICE_ERROR_UNAVAILABLE,
			_("You must be working online to complete this operation"));
		success = FALSE;
		goto exit;
	}

	g_mutex_lock (&store->priv->property_lock);

	if (store->priv->cache == NULL) {
		CamelDataCache *cache;

		cache = camel_data_cache_new (user_data_dir, error);
		if (cache != NULL) {
			/* Ensure cache will never expire, otherwise
			 * it causes redownload of messages. */
			camel_data_cache_set_expire_age (cache, -1);
			camel_data_cache_set_expire_access (cache, -1);

			store->priv->cache = g_object_ref (cache);

			g_object_unref (cache);
		}
	}

	g_mutex_unlock (&store->priv->property_lock);

	success = connect_to_server (service, cancellable, error);

	if (!success)
		goto exit;

	success = camel_session_authenticate_sync (
		session, service, mechanism, cancellable, error);

	if (!success)
		goto exit;

	/* Now that we are in the TRANSACTION state,
	 * try regetting the capabilities */
	pop3_engine = camel_pop3_store_ref_engine (store);
	if (pop3_engine) {
		pop3_engine->state = CAMEL_POP3_ENGINE_TRANSACTION;
		if (!camel_pop3_engine_reget_capabilities (pop3_engine, cancellable, error))
			success = FALSE;
		g_clear_object (&pop3_engine);
	} else {
		g_set_error_literal (
			error, CAMEL_SERVICE_ERROR,
			CAMEL_SERVICE_ERROR_UNAVAILABLE,
			_("You must be working online to complete this operation"));
		success = FALSE;
	}

exit:
	g_free (mechanism);

	g_object_unref (session);

	if (!success) {
		/* to not leak possible connection to the server */
		g_mutex_lock (&store->priv->property_lock);
		g_clear_object (&store->priv->engine);
		g_mutex_unlock (&store->priv->property_lock);
	}

	return success;
}
Пример #8
0
static gboolean
ews_transport_can_server_side_sent_folder (CamelService *service,
					   EwsFolderId **folder_id,
					   GCancellable *cancellable)
{
	CamelSession *session;
	ESourceRegistry *registry;
	ESource *sibling, *source = NULL;
	gboolean is_server_side = FALSE;

	g_return_val_if_fail (CAMEL_IS_EWS_TRANSPORT (service), FALSE);
	g_return_val_if_fail (folder_id != NULL, FALSE);

	session = camel_service_ref_session (service);
	if (session && E_IS_MAIL_SESSION (session))
		registry = g_object_ref (e_mail_session_get_registry (E_MAIL_SESSION (session)));
	else
		registry = e_source_registry_new_sync (cancellable, NULL);

	if (!registry) {
		g_clear_object (&session);
		return FALSE;
	}

	sibling = e_source_registry_ref_source (registry, camel_service_get_uid (service));
	if (sibling) {
		GList *sources, *siter;

		sources = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_MAIL_SUBMISSION);
		for (siter = sources; siter; siter = siter->next) {
			source = siter->data;

			if (!source || g_strcmp0 (e_source_get_parent (source), e_source_get_parent (sibling)) != 0 ||
			    !e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_SUBMISSION) ||
			    !e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_COMPOSITION))
				source = NULL;
			else
				break;
		}

		if (source &&
		    e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_SUBMISSION) &&
		    e_source_has_extension (source, E_SOURCE_EXTENSION_MAIL_COMPOSITION)) {
			ESourceMailSubmission *subm_extension;
			CamelStore *store = NULL;
			gchar *folder_name = NULL;

			subm_extension = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_SUBMISSION);

			/* Copy messages on the server side only if the replies
			   might not be saved to the original folder, which is handled
			   by the evolution itself. */
			if (!e_source_mail_submission_get_replies_to_origin_folder (subm_extension) &&
			    e_source_mail_submission_get_sent_folder (subm_extension) &&
			    e_mail_folder_uri_parse (session,
				e_source_mail_submission_get_sent_folder (subm_extension),
				&store, &folder_name, NULL) & CAMEL_IS_EWS_STORE (store)) {
				CamelEwsStore *ews_store = CAMEL_EWS_STORE (store);
				gchar *folder_id_str;

				folder_id_str = camel_ews_store_summary_get_folder_id_from_name (
					ews_store->summary, folder_name);
				if (folder_id_str) {
					gchar *change_key;

					change_key = camel_ews_store_summary_get_change_key (ews_store->summary, folder_name, NULL);
					*folder_id = e_ews_folder_id_new (folder_id_str, change_key, FALSE);
					g_free (change_key);

					is_server_side = *folder_id != NULL;
				}

				g_free (folder_id_str);
			}

			g_clear_object (&store);
			g_free (folder_name);
		}

		g_list_free_full (sources, g_object_unref);
		g_object_unref (sibling);
	}

	g_object_unref (registry);
	g_clear_object (&session);

	return is_server_side;
}
Пример #9
0
void
mail_filter_delete_folder (CamelStore *store,
                           const gchar *folder_name,
                           EAlertSink *alert_sink)
{
	CamelSession *session;
	EMFilterContext *fc;
	const gchar *config_dir;
	gchar *user, *system;
	GList *deleted;
	gchar *uri;

	g_return_if_fail (CAMEL_IS_STORE (store));
	g_return_if_fail (folder_name != NULL);
	g_return_if_fail (E_IS_ALERT_SINK (alert_sink));

	session = camel_service_ref_session (CAMEL_SERVICE (store));

	uri = e_mail_folder_uri_build (store, folder_name);

	fc = em_filter_context_new (E_MAIL_SESSION (session));
	config_dir = mail_session_get_config_dir ();
	user = g_build_filename (config_dir, "filters.xml", NULL);
	system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
	e_rule_context_load ((ERuleContext *) fc, system, user);
	g_free (system);

	deleted = e_rule_context_delete_uri (
		(ERuleContext *) fc, uri, g_str_equal);
	if (deleted) {
		GString *s;
		guint s_count;
		gchar *info;
		GList *l;

		s = g_string_new ("");
		s_count = 0;
		for (l = deleted; l; l = l->next) {
			const gchar *name = (const gchar *) l->data;

			if (s_count == 0) {
				g_string_append (s, name);
			} else {
				if (s_count == 1) {
					g_string_prepend (s, "    ");
					g_string_append (s, "\n");
				}
				g_string_append_printf (s, "    %s\n", name);
			}
			s_count++;
		}

		info = g_strdup_printf (ngettext (
			/* Translators: The first %s is name of the affected
			 * filter rule(s), the second %s is URI of the removed
			 * folder. For more than one filter rule is each of
			 * them on a separate line, with four spaces in front
			 * of its name, without quotes. */
			"The filter rule \"%s\" has been modified to account "
			"for the deleted folder\n\"%s\".",
			"The following filter rules\n%s have been modified "
			"to account for the deleted folder\n\"%s\".",
			s_count), s->str, folder_name);
		e_alert_submit (
			alert_sink, "mail:filter-updated", info, NULL);
		g_string_free (s, TRUE);
		g_free (info);

		if (e_rule_context_save ((ERuleContext *) fc, user) == -1)
			g_warning ("Could not write out changed filter rules\n");
		e_rule_context_free_uri_list ((ERuleContext *) fc, deleted);
	}

	g_free (user);
	g_object_unref (fc);
	g_free (uri);

	g_object_unref (session);
}
static gboolean
smtp_transport_connect_sync (CamelService *service,
                             GCancellable *cancellable,
                             GError **error)
{
	CamelSmtpTransport *transport = CAMEL_SMTP_TRANSPORT (service);
	CamelNetworkSettings *network_settings;
	CamelSettings *settings;
	gchar *host;
	gchar *mechanism;
	gboolean auth_required;
	gboolean success = TRUE;

	/* Chain up to parent's method. */
	if (!CAMEL_SERVICE_CLASS (camel_smtp_transport_parent_class)->connect_sync (service, cancellable, error))
		return FALSE;

	smtp_debug_print_server_name (service, "Connecting to");

	settings = camel_service_ref_settings (service);

	network_settings = CAMEL_NETWORK_SETTINGS (settings);
	host = camel_network_settings_dup_host (network_settings);
	mechanism = camel_network_settings_dup_auth_mechanism (network_settings);

	g_object_unref (settings);

	/* We (probably) need to check popb4smtp before we connect ... */
	if (g_strcmp0 (mechanism, "POPB4SMTP") == 0) {
		GByteArray *chal;
		CamelSasl *sasl;

		sasl = camel_sasl_new ("smtp", "POPB4SMTP", service);
		chal = camel_sasl_challenge_sync (sasl, NULL, cancellable, error);
		if (chal != NULL)
			g_byte_array_free (chal, TRUE);

		if (camel_sasl_get_authenticated (sasl))
			success = connect_to_server (
				service, cancellable, error);
		else
			success = FALSE;

		g_object_unref (sasl);

		goto exit;
	}

	success = connect_to_server (service, cancellable, error);

	if (!success)
		return FALSE;

	/* check to see if AUTH is required, if so...then AUTH ourselves */
	auth_required =
		(mechanism != NULL) &&
		(transport->authtypes != NULL) &&
		(g_hash_table_size (transport->authtypes) > 0) &&
		(transport->flags & CAMEL_SMTP_TRANSPORT_IS_ESMTP);

	if (auth_required) {
		CamelSession *session;

		session = camel_service_ref_session (service);

		if (g_hash_table_lookup (transport->authtypes, mechanism)) {
			success = camel_session_authenticate_sync (
				session, service, mechanism,
				cancellable, error);
		} else {
			g_set_error (
				error, CAMEL_SERVICE_ERROR,
				CAMEL_SERVICE_ERROR_CANT_AUTHENTICATE,
				_("SMTP server %s does not support %s "
				"authentication"), host, mechanism);
			success = FALSE;
		}

		g_object_unref (session);

		if (!success)
			transport->connected = FALSE;
	}

exit:
	g_free (host);
	g_free (mechanism);

	return success;
}