diff options
author | David Zeuthen <davidz@redhat.com> | 2011-05-26 14:02:50 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2011-05-26 14:02:50 -0400 |
commit | d8f3227b1f5f0e62713a697c2a0d34671d0edcbe (patch) | |
tree | 20bffa4fe7dd501e957e363edf5bbd11e4796f3e | |
parent | 5bcbe2a3eac4821892680e0655b27ab8c128ab15 (diff) |
Remove service-specific code
Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r-- | data/dbus-interfaces.xml | 128 | ||||
-rw-r--r-- | doc/goa-docs.xml | 15 | ||||
-rw-r--r-- | doc/goa-sections.txt | 181 | ||||
-rw-r--r-- | doc/goa.types | 10 | ||||
-rw-r--r-- | src/examples/Makefile.am | 15 | ||||
-rw-r--r-- | src/examples/mail-monitor.c | 203 | ||||
-rw-r--r-- | src/goabackend/Makefile.am | 12 | ||||
-rw-r--r-- | src/goabackend/goabackend.h | 6 | ||||
-rw-r--r-- | src/goabackend/goabackendtypes.h | 18 | ||||
-rw-r--r-- | src/goabackend/goagenericmailprovider.c | 1013 | ||||
-rw-r--r-- | src/goabackend/goagenericmailprovider.h | 42 | ||||
-rw-r--r-- | src/goabackend/goagoogleprovider.c | 32 | ||||
-rw-r--r-- | src/goabackend/goaimapauth.c | 84 | ||||
-rw-r--r-- | src/goabackend/goaimapauth.h | 88 | ||||
-rw-r--r-- | src/goabackend/goaimapauthlogin.c | 371 | ||||
-rw-r--r-- | src/goabackend/goaimapauthlogin.h | 47 | ||||
-rw-r--r-- | src/goabackend/goaimapauthoauth.c | 568 | ||||
-rw-r--r-- | src/goabackend/goaimapauthoauth.h | 46 | ||||
-rw-r--r-- | src/goabackend/goaimapclient.c | 704 | ||||
-rw-r--r-- | src/goabackend/goaimapclient.h | 64 | ||||
-rw-r--r-- | src/goabackend/goainternetmail.c | 1595 | ||||
-rw-r--r-- | src/goabackend/goainternetmail.h | 52 | ||||
-rw-r--r-- | src/goabackend/goaprovider.c | 2 |
23 files changed, 14 insertions, 5282 deletions
diff --git a/data/dbus-interfaces.xml b/data/dbus-interfaces.xml index 76edf37..0de4a5e 100644 --- a/data/dbus-interfaces.xml +++ b/data/dbus-interfaces.xml @@ -36,11 +36,10 @@ <!-- ProviderType: The provider of the account. Known values include <variablelist> - <varlistentry><term>google</term><listitem><para>The account is a Google Account. See the #org.gnome.OnlineAccounts.GoogleAccount D-Bus interface for more details.</para></listitem></varlistentry> - <varlistentry><term>facebook</term><listitem><para>The account is a Facebook Account. See the #org.gnome.OnlineAccounts.FacebookAccount D-Bus interface for more details.</para></listitem></varlistentry> - <varlistentry><term>yahoo</term><listitem><para>The account is a Yahoo Account. See the #org.gnome.OnlineAccounts.YahooAccount D-Bus interface for more details.</para></listitem></varlistentry> - <varlistentry><term>twitter</term><listitem><para>The account is a Twitter Account. See the #org.gnome.OnlineAccounts.TwitterAccount D-Bus interface for more details.</para></listitem></varlistentry> - <varlistentry><term>generic_mail</term><listitem><para>The account is a Mail Account for Internet-based mail. See the #org.gnome.OnlineAccounts.Mail D-Bus interface for more details.</para></listitem></varlistentry> + <varlistentry><term>google</term><listitem><para>The account is a Google Account.</para></listitem></varlistentry> + <varlistentry><term>facebook</term><listitem><para>The account is a Facebook Account.</para></listitem></varlistentry> + <varlistentry><term>yahoo</term><listitem><para>The account is a Yahoo Account.</para></listitem></varlistentry> + <varlistentry><term>twitter</term><listitem><para>The account is a Twitter Account.</para></listitem></varlistentry> </variablelist> --> <property name="ProviderType" type="s" access="read"/> @@ -226,20 +225,6 @@ email-like messaging capabilities. --> <interface name="org.gnome.OnlineAccounts.Mail"> - <!-- - CreateMonitor: - @monitor_object: Object path of the resulting monitor object. - - Creates a new #org.gnome.OnlineAccounts.Mail.Monitor object for - listening to incoming mail messages. The returned object will - stay alive until its - org.gnome.OnlineAccounts.Mail.Monitor.Close() is called or the - caller vanishes from the message bus. - --> - <method name="CreateMonitor"> - <arg name="monitor_object" type="o" direction="out"/> - </method> - <!-- EmailAddress: The email address for the account or blank if there is no such address or if it isnt' known or isn't in a standard @@ -318,111 +303,6 @@ </interface> <!-- - org.gnome.OnlineAccounts.Mail.Monitor: - - An interface used for monitoring for incoming messages. Use the - org.gnome.OnlineAccounts.Mail.CreateMonitor() method on the - #org.gnome.OnlineAccounts.Mail interface to create an object - with this interface. - --> - <interface name="org.gnome.OnlineAccounts.Mail.Monitor"> - - <!-- Connected: - %TRUE if currently connected to the server, %FALSE if not. - - If %FALSE, a client should periodically call the - org.gnome.OnlineAccounts.Mail.Monitor.Refresh() method when - network connectivity is available. - --> - <property name="Connected" type="b" access="read"/> - - <!-- Refresh: - Forcibly does a server roundtrip to check for new messages. - - Normally this isn't needed as implementations typically uses - techniques such as <ulink - url="http://en.wikipedia.org/wiki/IMAP_IDLE">IMAP - IDLE</ulink> to keep the current. - - As a side-effect, this also updates the - #org.gnome.OnlineAccounts.Mail.Monitor:Connected property - - specifically this property might bet se to %FALSE (in case - network connectivity was lost) or %TRUE (in case network - connectivity was acquired). - - This method won't return until the check is done so it is - appropriate to e.g. show a spinner while the operation is - pending. - --> - <method name="Refresh"/> - - <!-- Close: - Method that can be used to close the monitor and release all - resources used for it. - --> - <method name="Close"/> - - <!-- MessageReceived: - @uid: Unique ID of the message. - @from: Name of sender. - @subject: The subject of the message. - @excerpt: Plain-text excerpt of the message. - @uri: An URI that can be used to open the message or blank if no such URI exists. - @can_be_marked_as_spam: %TRUE if the message can be marked as Spam. - @can_be_starred: %TRUE if the message can be Starred. - - Signal emitted when a new message is received. - - TODO: When gnome-shell can handle GVariant instances then add extras back and fold can_be* stuff into it: @extras: Other information about the message (currently unused). - --> - <signal name="MessageReceived"> - <arg name="uid" type="s"/> - <arg name="from" type="s"/> - <arg name="subject" type="s"/> - <arg name="excerpt" type="s"/> - <arg name="uri" type="s"/> - <arg name="can_be_marked_as_spam" type="b"/> - <arg name="can_be_starred" type="b"/> - <!-- arg name="extras" type="a{sv}"/ --> - </signal> - - <!-- AddStar: - @uid: Unique ID of message. - - Adds a star to a message. The @uid parameter should be - obtained from a - #org.gnome.OnlineAccounts.Mail.Monitor::MessageReceived - signal where the @can_be_starred parameter was %TRUE. - --> - <method name="AddStar"> - <arg name="uid" type="s" direction="in"/> - </method> - - <!-- MarkAsSpam: - @uid: Unique ID of message. - - Marks a message as spam. The @uid parameter should be - obtained from a - #org.gnome.OnlineAccounts.Mail.Monitor::MessageReceived - signal where the @can_be_starred parameter was %TRUE. - --> - <method name="MarkAsSpam"> - <arg name="uid" type="s" direction="in"/> - </method> - - <method name="SimulateMessageReceived"> - <arg name="uid" type="s" direction="in"/> - <arg name="from" type="s" direction="in"/> - <arg name="subject" type="s" direction="in"/> - <arg name="excerpt" type="s" direction="in"/> - <arg name="uri" type="s" direction="in"/> - <arg name="can_be_marked_as_spam" type="b" direction="in"/> - <arg name="can_be_starred" type="b" direction="in"/> - <!-- arg name="extras" type="a{sv}"/ --> - </method> - </interface> - - <!-- org.gnome.OnlineAccounts.Calendar: An account object implements this interface if it provides diff --git a/doc/goa-docs.xml b/doc/goa-docs.xml index ca3d742..4cbe935 100644 --- a/doc/goa-docs.xml +++ b/doc/goa-docs.xml @@ -103,14 +103,12 @@ </chapter> <chapter> <title>Credentials Interfaces</title> - <xi:include href="../src/goa/goa-generated-doc-org.gnome.OnlineAccounts.PasswordBased.xml"/> <xi:include href="../src/goa/goa-generated-doc-org.gnome.OnlineAccounts.OAuthBased.xml"/> <xi:include href="../src/goa/goa-generated-doc-org.gnome.OnlineAccounts.OAuth2Based.xml"/> </chapter> <chapter> <title>Service-specific Interfaces</title> <xi:include href="../src/goa/goa-generated-doc-org.gnome.OnlineAccounts.Mail.xml"/> - <xi:include href="../src/goa/goa-generated-doc-org.gnome.OnlineAccounts.Mail.Monitor.xml"/> <xi:include href="../src/goa/goa-generated-doc-org.gnome.OnlineAccounts.Calendar.xml"/> <xi:include href="../src/goa/goa-generated-doc-org.gnome.OnlineAccounts.Contacts.xml"/> </chapter> @@ -126,11 +124,9 @@ <xi:include href="xml/GoaObjectManagerClient.xml"/> <xi:include href="xml/GoaManager.xml"/> <xi:include href="xml/GoaAccount.xml"/> - <xi:include href="xml/GoaPasswordBased.xml"/> <xi:include href="xml/GoaOAuthBased.xml"/> <xi:include href="xml/GoaOAuth2Based.xml"/> <xi:include href="xml/GoaMail.xml"/> - <xi:include href="xml/GoaMailMonitor.xml"/> <xi:include href="xml/GoaCalendar.xml"/> <xi:include href="xml/GoaContacts.xml"/> </chapter> @@ -147,17 +143,6 @@ <xi:include href="xml/goaoauth2provider.xml"/> </chapter> <chapter> - <title>Service Implementations</title> - <xi:include href="xml/goainternetmail.xml"/> - </chapter> - <chapter> - <title>IMAP Client</title> - <xi:include href="xml/goaimapauth.xml"/> - <xi:include href="xml/goaimapauthlogin.xml"/> - <xi:include href="xml/goaimapauthoauth.xml"/> - <xi:include href="xml/goaimapclient.xml"/> - </chapter> - <chapter> <title>Providers</title> <xi:include href="xml/goagenericmailprovider.xml"/> <xi:include href="xml/goagoogleprovider.xml"/> diff --git a/doc/goa-sections.txt b/doc/goa-sections.txt index 66f6f50..b246dde 100644 --- a/doc/goa-sections.txt +++ b/doc/goa-sections.txt @@ -49,20 +49,16 @@ GoaObject GoaObjectIface goa_object_get_manager goa_object_get_account -goa_object_get_password_based goa_object_get_oauth_based goa_object_get_oauth2_based goa_object_get_mail -goa_object_get_mail_monitor goa_object_get_calendar goa_object_get_contacts goa_object_peek_manager goa_object_peek_account -goa_object_peek_password_based goa_object_peek_oauth_based goa_object_peek_oauth2_based goa_object_peek_mail -goa_object_peek_mail_monitor goa_object_peek_calendar goa_object_peek_contacts GoaObjectProxy @@ -73,11 +69,9 @@ GoaObjectSkeletonClass goa_object_skeleton_new goa_object_skeleton_set_manager goa_object_skeleton_set_account -goa_object_skeleton_set_password_based goa_object_skeleton_set_oauth_based goa_object_skeleton_set_oauth2_based goa_object_skeleton_set_mail -goa_object_skeleton_set_mail_monitor goa_object_skeleton_set_calendar goa_object_skeleton_set_contacts <SUBSECTION Standard> @@ -264,51 +258,6 @@ goa_oauth_based_skeleton_get_type </SECTION> <SECTION> -<FILE>GoaPasswordBased</FILE> -GoaPasswordBased -GoaPasswordBasedIface -goa_password_based_interface_info -goa_password_based_override_properties -goa_password_based_call_get_password -goa_password_based_call_get_password_finish -goa_password_based_call_get_password_sync -goa_password_based_complete_get_password -GoaPasswordBasedProxy -GoaPasswordBasedProxyClass -goa_password_based_proxy_new -goa_password_based_proxy_new_finish -goa_password_based_proxy_new_sync -goa_password_based_proxy_new_for_bus -goa_password_based_proxy_new_for_bus_finish -goa_password_based_proxy_new_for_bus_sync -GoaPasswordBasedSkeleton -GoaPasswordBasedSkeletonClass -goa_password_based_skeleton_new -<SUBSECTION Standard> -GOA_PASSWORD_BASED -GOA_PASSWORD_BASED_GET_IFACE -GOA_PASSWORD_BASED_PROXY -GOA_PASSWORD_BASED_PROXY_CLASS -GOA_PASSWORD_BASED_PROXY_GET_CLASS -GOA_PASSWORD_BASED_SKELETON -GOA_PASSWORD_BASED_SKELETON_CLASS -GOA_PASSWORD_BASED_SKELETON_GET_CLASS -GOA_IS_PASSWORD_BASED -GOA_IS_PASSWORD_BASED_PROXY -GOA_IS_PASSWORD_BASED_PROXY_CLASS -GOA_IS_PASSWORD_BASED_SKELETON -GOA_IS_PASSWORD_BASED_SKELETON_CLASS -GOA_TYPE_PASSWORD_BASED -GOA_TYPE_PASSWORD_BASED_PROXY -GOA_TYPE_PASSWORD_BASED_SKELETON -GoaPasswordBasedProxyPrivate -GoaPasswordBasedSkeletonPrivate -goa_password_based_get_type -goa_password_based_proxy_get_type -goa_password_based_skeleton_get_type -</SECTION> - -<SECTION> <FILE>GoaObjectManagerClient</FILE> GoaObjectManagerClient GoaObjectManagerClientClass @@ -439,16 +388,6 @@ goa_oauth_provider_get_type </SECTION> <SECTION> -<FILE>goagenericmailprovider</FILE> -GoaGenericMailProvider -<SUBSECTION Standard> -GOA_GENERIC_MAIL_PROVIDER -GOA_IS_GENERIC_MAIL_PROVIDER -GOA_TYPE_GENERIC_MAIL_PROVIDER -goa_generic_mail_provider_get_type -</SECTION> - -<SECTION> <FILE>goagoogleprovider</FILE> GoaGoogleProvider <SUBSECTION Standard> @@ -494,10 +433,6 @@ GoaMail GoaMailIface goa_mail_override_properties goa_mail_interface_info -goa_mail_call_create_monitor -goa_mail_call_create_monitor_finish -goa_mail_call_create_monitor_sync -goa_mail_complete_create_monitor goa_mail_get_email_address goa_mail_set_email_address goa_mail_get_imap_host @@ -552,58 +487,6 @@ goa_mail_skeleton_get_type </SECTION> <SECTION> -<FILE>GoaMailMonitor</FILE> -GoaMailMonitor -GoaMailMonitorIface -goa_mail_monitor_interface_info -goa_mail_monitor_override_properties -goa_mail_monitor_get_connected -goa_mail_monitor_set_connected -goa_mail_monitor_call_refresh -goa_mail_monitor_call_refresh_finish -goa_mail_monitor_call_refresh_sync -goa_mail_monitor_complete_refresh -goa_mail_monitor_call_close -goa_mail_monitor_call_close_finish -goa_mail_monitor_call_close_sync -goa_mail_monitor_complete_close -goa_mail_monitor_emit_message_received -GoaMailMonitorProxy -GoaMailMonitorProxyClass -goa_mail_monitor_proxy_new -goa_mail_monitor_proxy_new_finish -goa_mail_monitor_proxy_new_sync -goa_mail_monitor_proxy_new_for_bus -goa_mail_monitor_proxy_new_for_bus_finish -goa_mail_monitor_proxy_new_for_bus_sync -GoaMailMonitorSkeleton -GoaMailMonitorSkeletonClass -goa_mail_monitor_skeleton_new -<SUBSECTION Standard> -GOA_TYPE_MAIL_MONITOR -GOA_IS_MAIL_MONITOR -GOA_MAIL_MONITOR -GOA_MAIL_MONITOR_GET_IFACE -GOA_TYPE_MAIL_MONITOR_PROXY -GOA_IS_MAIL_MONITOR_PROXY -GOA_IS_MAIL_MONITOR_PROXY_CLASS -GOA_MAIL_MONITOR_PROXY -GOA_MAIL_MONITOR_PROXY_CLASS -GOA_MAIL_MONITOR_PROXY_GET_CLASS -GOA_TYPE_MAIL_MONITOR_SKELETON -GOA_IS_MAIL_MONITOR_SKELETON -GOA_IS_MAIL_MONITOR_SKELETON_CLASS -GOA_MAIL_MONITOR_SKELETON -GOA_MAIL_MONITOR_SKELETON_CLASS -GOA_MAIL_MONITOR_SKELETON_GET_CLASS -GoaMailMonitorProxyPrivate -GoaMailMonitorSkeletonPrivate -goa_mail_monitor_get_type -goa_mail_monitor_proxy_get_type -goa_mail_monitor_skeleton_get_type -</SECTION> - -<SECTION> <FILE>GoaCalendar</FILE> GoaCalendar GoaCalendarIface @@ -684,70 +567,6 @@ goa_contacts_skeleton_get_type </SECTION> <SECTION> -<FILE>goaimapclient</FILE> -GoaImapClient -goa_imap_client_new -goa_imap_client_connect_sync -goa_imap_client_run_command_sync -goa_imap_client_idle_sync -goa_imap_client_disconnect_sync -<SUBSECTION Standard> -GOA_IMAP_CLIENT -GOA_IS_IMAP_CLIENT -GOA_TYPE_IMAP_CLIENT -goa_imap_client_get_type -</SECTION> - -<SECTION> -<FILE>goainternetmail</FILE> -GoaInternetMail -goa_internet_mail_new -<SUBSECTION Standard> -GOA_INTERNET_MAIL -GOA_IS_INTERNET_MAIL -GOA_TYPE_INTERNET_MAIL -goa_internet_mail_get_type -</SECTION> - -<SECTION> -<FILE>goaimapauth</FILE> -GoaImapAuth -GoaImapAuthClass -goa_imap_auth_run_sync -<SUBSECTION Standard> -GoaImapAuthPrivate -GOA_IMAP_AUTH -GOA_IS_IMAP_AUTH -GOA_TYPE_IMAP_AUTH -GOA_IMAP_AUTH_CLASS -GOA_IS_IMAP_AUTH_CLASS -GOA_IMAP_AUTH_GET_CLASS -goa_imap_auth_get_type -</SECTION> - -<SECTION> -<FILE>goaimapauthoauth</FILE> -GoaImapAuthOAuth -goa_imap_auth_oauth_new -<SUBSECTION Standard> -GOA_IMAP_AUTH_OAUTH -GOA_IS_IMAP_AUTH_OAUTH -GOA_TYPE_IMAP_AUTH_OAUTH -goa_imap_auth_oauth_get_type -</SECTION> - -<SECTION> -<FILE>goaimapauthlogin</FILE> -GoaImapAuthLogin -goa_imap_auth_login_new -<SUBSECTION Standard> -GOA_IMAP_AUTH_LOGIN -GOA_IS_IMAP_AUTH_LOGIN -GOA_TYPE_IMAP_AUTH_LOGIN -goa_imap_auth_login_get_type -</SECTION> - -<SECTION> <FILE>goalog</FILE> GoaLogLevel goa_log diff --git a/doc/goa.types b/doc/goa.types index 71b9622..566c848 100644 --- a/doc/goa.types +++ b/doc/goa.types @@ -9,15 +9,11 @@ goa_object_manager_client_get_type goa_object_get_type goa_object_proxy_get_type goa_object_skeleton_get_type -goa_password_based_get_type goa_oauth_based_get_type goa_oauth2_based_get_type goa_mail_get_type goa_mail_proxy_get_type goa_mail_skeleton_get_type -goa_mail_monitor_get_type -goa_mail_monitor_proxy_get_type -goa_mail_monitor_skeleton_get_type goa_calendar_get_type goa_calendar_proxy_get_type goa_calendar_skeleton_get_type @@ -26,15 +22,9 @@ goa_contacts_proxy_get_type goa_contacts_skeleton_get_type goa_provider_get_type -goa_generic_mail_provider_get_type goa_oauth_provider_get_type goa_oauth2_provider_get_type goa_google_provider_get_type goa_facebook_provider_get_type goa_yahoo_provider_get_type goa_twitter_provider_get_type -goa_imap_auth_get_type -goa_imap_auth_login_get_type -goa_imap_auth_oauth_get_type -goa_imap_client_get_type -goa_internet_mail_get_type diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am index 7b423f4..5dff64c 100644 --- a/src/examples/Makefile.am +++ b/src/examples/Makefile.am @@ -15,20 +15,5 @@ INCLUDES = \ $(WARN_CFLAGS) \ $(NULL) -noinst_PROGRAMS = mail-monitor - -mail_monitor_SOURCES = \ - mail-monitor.c \ - $(NULL) - -mail_monitor_CFLAGS = \ - $(GLIB_CFLAGS) \ - $(NULL) - -mail_monitor_LDADD = \ - $(GLIB_LIBS) \ - $(top_builddir)/src/goa/libgoa-1.0.la \ - $(NULL) - clean-local : rm -f *~ diff --git a/src/examples/mail-monitor.c b/src/examples/mail-monitor.c deleted file mode 100644 index 0254184..0000000 --- a/src/examples/mail-monitor.c +++ /dev/null @@ -1,203 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#include "config.h" -#include <glib/gi18n.h> -#include <stdlib.h> - -#include "goa/goa.h" - -static void -on_message_received (GoaMailMonitor *monitor, - const gchar *guid, - const gchar *from, - const gchar *subject, - const gchar *excerpt, - const gchar *uri, - GVariant *extras, - gpointer user_data) -{ - g_print ("Message Received:\n" - " GUID: %s\n" - " From: %s\n" - " Subject: %s\n" - " URI: %s\n" - " Excerpt: %s\n" - "\n", - guid, - from, - subject, - uri, - excerpt); -} - -static void -on_notify_connected (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - GoaMailMonitor *monitor = GOA_MAIL_MONITOR (object); - g_print ("Connected: %d\n" - "\n", - goa_mail_monitor_get_connected (monitor)); -} - -int -main (int argc, - char *argv[]) -{ - gint ret; - GMainLoop *loop; - GError *error; - GoaClient *client; - GList *accounts; - GList *l; - GoaMailMonitor *monitor; - gchar *opt_account; - GOptionEntry opt_entries[] = - { - { "account", 'a', 0, G_OPTION_ARG_STRING, &opt_account, "The account to monitor", NULL }, - { NULL} - }; - GOptionContext *opt_context; - gchar *monitor_object_path; - - ret = 1; - monitor = NULL; - client = NULL; - accounts = NULL; - opt_account = NULL; - monitor_object_path = NULL; - - g_type_init (); - - opt_context = g_option_context_new ("goa mail monitor example"); - error = NULL; - g_option_context_add_main_entries (opt_context, opt_entries, NULL); - if (!g_option_context_parse (opt_context, &argc, &argv, &error)) - { - g_printerr ("Error parsing options: %s\n", error->message); - g_error_free (error); - goto out; - } - if (opt_account == NULL) - { - g_printerr ("Incorrect usage, try --help.\n"); - goto out; - } - - loop = g_main_loop_new (NULL, FALSE); - - error = NULL; - client = goa_client_new_sync (NULL, /* GCancellable */ - &error); - if (client == NULL) - { - g_printerr ("Error creating a GOA client: %s (%s, %d)\n", - error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } - - accounts = goa_client_get_accounts (client); - for (l = accounts; l != NULL; l = l->next) - { - GoaObject *object = GOA_OBJECT (l->data); - GoaAccount *account; - GoaMail *mail; - - account = goa_object_peek_account (object); - if (account == NULL) - continue; - - if (!(g_strcmp0 (goa_account_get_id (account), opt_account) == 0 || - g_strcmp0 (g_dbus_object_get_object_path (G_DBUS_OBJECT (object)), opt_account) == 0)) - continue; - - mail = goa_object_peek_mail (object); - if (mail == NULL) - { - g_printerr ("Given account does not implement the Mail interface\n"); - goto out; - } - - /* Start monitoring account */ - g_print ("Monitoring incoming messages for %s\n", goa_account_get_id (account)); - error = NULL; - if (!goa_mail_call_create_monitor_sync (mail, - &monitor_object_path, - NULL, /* GCancellable */ - &error)) - { - g_printerr ("Error creating mail monitor: %s (%s, %d)\n", - error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } - - error = NULL; - monitor = goa_mail_monitor_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - "org.gnome.OnlineAccounts", - monitor_object_path, - NULL, /* GCancellable */ - &error); - if (monitor == NULL) - { - g_printerr ("Error creating monitor proxy: %s (%s, %d)\n", - error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - goto out; - } - g_signal_connect (monitor, - "notify::connected", - G_CALLBACK (on_notify_connected), - NULL); - g_signal_connect (monitor, - "message-received", - G_CALLBACK (on_message_received), - NULL); - break; - } - - if (monitor_object_path == NULL) - { - g_printerr ("Didn't find requested account.\n"); - goto out; - } - - g_main_loop_run (loop); - - ret = 0; - - out: - if (monitor != NULL) - g_object_unref (monitor); - if (client != NULL) - g_object_unref (client); - g_free (monitor_object_path); - g_list_foreach (accounts, (GFunc) g_object_unref, NULL); - g_list_free (accounts); - g_free (opt_account); - g_option_context_free (opt_context); - return ret; -} diff --git a/src/goabackend/Makefile.am b/src/goabackend/Makefile.am index d8b9855..e8b83aa 100644 --- a/src/goabackend/Makefile.am +++ b/src/goabackend/Makefile.am @@ -46,18 +46,12 @@ libgoa_backend_1_0_la_HEADERS = \ goalogging.h \ goaeditablelabel.h \ goaprovider.h \ - goagenericmailprovider.h \ goaoauthprovider.h \ goaoauth2provider.h \ goagoogleprovider.h \ goafacebookprovider.h \ goayahooprovider.h \ goatwitterprovider.h \ - goaimapauth.h \ - goaimapauthlogin.h \ - goaimapauthoauth.h \ - goaimapclient.h \ - goainternetmail.h \ $(NULL) libgoa_backend_1_0_la_SOURCES = \ @@ -68,18 +62,12 @@ libgoa_backend_1_0_la_SOURCES = \ goaeditablelabel.h goaeditablelabel.c \ goaprovider.h goaprovider.c \ goalogging.h goalogging.c \ - goagenericmailprovider.h goagenericmailprovider.c \ goaoauthprovider.h goaoauthprovider.c \ goaoauth2provider.h goaoauth2provider.c \ goagoogleprovider.h goagoogleprovider.c \ goafacebookprovider.h goafacebookprovider.c \ goayahooprovider.h goayahooprovider.c \ goatwitterprovider.h goatwitterprovider.c \ - goaimapauth.h goaimapauth.c \ - goaimapauthlogin.h goaimapauthlogin.c \ - goaimapauthoauth.h goaimapauthoauth.c \ - goaimapclient.h goaimapclient.c \ - goainternetmail.h goainternetmail.c \ $(NULL) libgoa_backend_1_0_la_CPPFLAGS = \ diff --git a/src/goabackend/goabackend.h b/src/goabackend/goabackend.h index be0f136..2fecaef 100644 --- a/src/goabackend/goabackend.h +++ b/src/goabackend/goabackend.h @@ -32,18 +32,12 @@ #include <goabackend/goalogging.h> #include <goabackend/goaeditablelabel.h> #include <goabackend/goaprovider.h> -#include <goabackend/goagenericmailprovider.h> #include <goabackend/goaoauthprovider.h> #include <goabackend/goaoauth2provider.h> #include <goabackend/goagoogleprovider.h> #include <goabackend/goafacebookprovider.h> #include <goabackend/goayahooprovider.h> #include <goabackend/goatwitterprovider.h> -#include <goabackend/goaimapauth.h> -#include <goabackend/goaimapauthlogin.h> -#include <goabackend/goaimapauthoauth.h> -#include <goabackend/goaimapclient.h> -#include <goabackend/goainternetmail.h> #undef __GOA_BACKEND_INSIDE_GOA_BACKEND_H__ #endif /* __GOA_BACKEND_H__ */ diff --git a/src/goabackend/goabackendtypes.h b/src/goabackend/goabackendtypes.h index 46e4438..9fda675 100644 --- a/src/goabackend/goabackendtypes.h +++ b/src/goabackend/goabackendtypes.h @@ -36,9 +36,6 @@ G_BEGIN_DECLS struct _GoaProvider; typedef struct _GoaProvider GoaProvider; -struct _GoaGenericMailProvider; -typedef struct _GoaGenericMailProvider GoaGenericMailProvider; - struct _GoaOAuthProvider; typedef struct _GoaOAuthProvider GoaOAuthProvider; @@ -57,21 +54,6 @@ typedef struct _GoaYahooProvider GoaYahooProvider; struct _GoaTwitterProvider; typedef struct _GoaTwitterProvider GoaTwitterProvider; -struct _GoaImapAuth; -typedef struct _GoaImapAuth GoaImapAuth; - -struct _GoaImapAuthLogin; -typedef struct _GoaImapAuthLogin GoaImapAuthLogin; - -struct _GoaImapAuthOAuth; -typedef struct _GoaImapAuthOAuth GoaImapAuthOAuth; - -struct _GoaImapClient; -typedef struct _GoaImapClient GoaImapClient; - -struct _GoaInternetMail; -typedef struct _GoaInternetMail GoaInternetMail; - struct _GoaEditableLabel; typedef struct _GoaEditableLabel GoaEditableLabel; diff --git a/src/goabackend/goagenericmailprovider.c b/src/goabackend/goagenericmailprovider.c deleted file mode 100644 index 35e25e1..0000000 --- a/src/goabackend/goagenericmailprovider.c +++ /dev/null @@ -1,1013 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#include "config.h" -#include <glib/gi18n-lib.h> - -#include "goalogging.h" -#include "goaprovider.h" -#include "goagenericmailprovider.h" -#include "goaimapclient.h" -#include "goaimapauthlogin.h" -#include "goaeditablelabel.h" - -#include "goainternetmail.h" - -/** - * GoaGenericMailProvider: - * - * The #GoaGenericMailProvider structure contains only private data and should - * only be accessed using the provided API. - */ -struct _GoaGenericMailProvider -{ - /*< private >*/ - GoaProvider parent_instance; -}; - -typedef struct _GoaGenericMailProviderClass GoaGenericMailProviderClass; - -struct _GoaGenericMailProviderClass -{ - GoaProviderClass parent_class; -}; - -/** - * SECTION:goagenericmailprovider - * @title: GoaGenericMailProvider - * @short_description: A provider for standards-based mail servers - * - * #GoaGenericMailProvider is used to access standards-based Internet - * mail servers. - */ - -G_DEFINE_TYPE_WITH_CODE (GoaGenericMailProvider, goa_generic_mail_provider, GOA_TYPE_PROVIDER, - g_io_extension_point_implement (GOA_PROVIDER_EXTENSION_POINT_NAME, - g_define_type_id, - "generic_mail", - 0)); - -/* ---------------------------------------------------------------------------------------------------- */ - -static const gchar * -get_provider_type (GoaProvider *_provider) -{ - return "generic_mail"; -} - -static const gchar * -get_name (GoaProvider *_provider) -{ - return _("Mail Account"); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static gboolean on_handle_get_password (GoaPasswordBased *interface, - GDBusMethodInvocation *invocation, - const gchar *id, - gpointer user_data); - -static gboolean -build_object (GoaProvider *provider, - GoaObjectSkeleton *object, - GKeyFile *key_file, - const gchar *group, - GError **error) -{ - GoaAccount *account; - GoaMail *mail; - GoaPasswordBased *password_based; - gboolean ret; - gchar *email_address; - gchar *imap_host; - gchar *imap_user_name; - gchar *imap_password; - gboolean imap_use_tls; - gboolean imap_ignore_bad_tls; - gchar *smtp_host; - gchar *smtp_user_name; - gchar *smtp_password; - gboolean smtp_use_tls; - gboolean smtp_ignore_bad_tls; - gboolean enabled; - - account = NULL; - mail = NULL; - password_based = NULL; - email_address = NULL; - imap_host = NULL; - imap_user_name = NULL; - imap_password = NULL; - smtp_host = NULL; - smtp_user_name = NULL; - smtp_password = NULL; - ret = FALSE; - - /* Chain up */ - if (!GOA_PROVIDER_CLASS (goa_generic_mail_provider_parent_class)->build_object (provider, - object, - key_file, - group, - error)) - goto out; - - account = goa_object_get_account (GOA_OBJECT (object)); - - /* mail */ - mail = goa_object_get_mail (GOA_OBJECT (object)); - enabled = g_key_file_get_boolean (key_file, group, "Enabled", NULL); - if (enabled) - { - email_address = g_key_file_get_string (key_file, group, "EmailAddress", NULL); - - imap_host = g_key_file_get_string (key_file, group, "ImapHost", NULL); - imap_user_name = g_key_file_get_string (key_file, group, "ImapUserName", NULL); - imap_password = g_key_file_get_string (key_file, group, "ImapPassword", NULL); - imap_use_tls = g_key_file_get_boolean (key_file, group, "ImapUseTls", NULL); - imap_ignore_bad_tls = g_key_file_get_boolean (key_file, group, "ImapIgnoreBadTls", NULL); - - smtp_host = g_key_file_get_string (key_file, group, "SmtpHost", NULL); - smtp_user_name = g_key_file_get_string (key_file, group, "SmtpUserName", NULL); - smtp_password = g_key_file_get_string (key_file, group, "SmtpPassword", NULL); - smtp_use_tls = g_key_file_get_boolean (key_file, group, "SmtpUseTls", NULL); - smtp_ignore_bad_tls = g_key_file_get_boolean (key_file, group, "SmtpIgnoreBadTls", NULL); - if (imap_host != NULL && smtp_host != NULL) - { - if (mail == NULL) - { - GoaImapAuth *imap_auth; - if (imap_user_name == NULL) - imap_user_name = g_strdup (g_get_user_name ()); - imap_auth = goa_imap_auth_login_new (provider, GOA_OBJECT (object), imap_user_name, imap_password); - mail = goa_internet_mail_new (imap_host, - imap_user_name, - imap_use_tls, - imap_ignore_bad_tls, - imap_auth, - smtp_host, - smtp_user_name, - smtp_use_tls, - smtp_ignore_bad_tls); - goa_object_skeleton_set_mail (object, mail); - g_object_unref (imap_auth); - } - } - else - { - if (mail != NULL) - goa_object_skeleton_set_mail (object, NULL); - } - /* TODO: support substitutions a'la ${USERNAME}@redhat.com for e.g. system-wide .conf files */ - goa_mail_set_email_address (mail, email_address); - } - else - { - if (mail != NULL) - goa_object_skeleton_set_mail (object, NULL); - } - - password_based = goa_object_get_password_based (GOA_OBJECT (object)); - if (password_based == NULL) - { - password_based = goa_password_based_skeleton_new (); - /* Ensure D-Bus method invocations run in their own thread */ - g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (password_based), - G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); - goa_object_skeleton_set_password_based (object, password_based); - g_signal_connect (password_based, - "handle-get-password", - G_CALLBACK (on_handle_get_password), - NULL); - } - - ret = TRUE; - - out: - g_free (email_address); - if (password_based != NULL) - g_object_unref (password_based); - if (mail != NULL) - g_object_unref (mail); - g_free (imap_host); - g_free (imap_user_name); - g_free (imap_password); - g_free (smtp_host); - g_free (smtp_user_name); - g_free (smtp_password); - if (account != NULL) - g_object_unref (account); - return ret; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static gboolean -ensure_credentials_sync (GoaProvider *provider, - GoaObject *object, - gint *out_expires_in, - GCancellable *cancellable, - GError **error) -{ - /* TODO: we could try and log into the mail server etc. but for now we don't */ - if (out_expires_in != NULL) - *out_expires_in = 0; - return TRUE; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -add_entry (GtkWidget *table, - guint row, - const gchar *text, - GtkWidget **out_entry) -{ - GtkWidget *label; - GtkWidget *entry; - - label = gtk_label_new (NULL); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), text); - gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, - row, row + 1, - GTK_FILL, GTK_FILL, 0, 0); - entry = gtk_entry_new (); - gtk_table_attach (GTK_TABLE (table), entry, - 1, 2, - row, row + 1, - GTK_FILL, GTK_FILL, 0, 0); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); - if (out_entry != NULL) - *out_entry = entry; -} - -static void -add_check_button (GtkWidget *table, - guint row, - const gchar *text, - GtkWidget **out_check_button) -{ - GtkWidget *button; - button = gtk_check_button_new_with_mnemonic (text); - gtk_table_attach (GTK_TABLE (table), button, - 1, 2, - row, row + 1, - GTK_FILL, GTK_FILL, 0, 0); - if (out_check_button != NULL) - *out_check_button = button; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -typedef struct -{ - GtkDialog *dialog; - GMainLoop *loop; - - GtkWidget *cluebar; - GtkWidget *cluebar_label; - - GtkWidget *intro_address_entry; - GtkWidget *intro_desc_entry; - - GtkWidget *imap_server_entry; - GtkWidget *imap_user_entry; - GtkWidget *imap_password_entry; - GtkWidget *imap_show_password; - GtkWidget *imap_use_tls; - GtkWidget *imap_ignore_bad_tls; - - GtkWidget *smtp_server_entry; - GtkWidget *smtp_user_entry; - GtkWidget *smtp_password_entry; - GtkWidget *smtp_show_password; - GtkWidget *smtp_use_tls; - GtkWidget *smtp_ignore_bad_tls; - - gchar *account_object_path; - - GError *error; -} AddAccountData; - -/* ---------------------------------------------------------------------------------------------------- */ - - -static void -update_intro (AddAccountData *data) -{ - const gchar *address; - const gchar *desc; - gboolean address_valid; - gboolean desc_valid; - - address_valid = FALSE; - desc_valid = FALSE; - - address = gtk_entry_get_text (GTK_ENTRY (data->intro_address_entry)); - if (address != NULL) - { - const gchar *s; - /* TODO: could do more validation */ - s = strstr (address, "@"); - if (s != NULL && strstr (s + 1, ".") != NULL) - address_valid = TRUE; - } - - desc = gtk_entry_get_text (GTK_ENTRY (data->intro_desc_entry)); - if (desc != NULL && strlen (desc) > 0) - { - desc_valid = TRUE; - } - - gtk_dialog_set_response_sensitive (data->dialog, GTK_RESPONSE_OK, address_valid && desc_valid); -} - -static void -on_intro_entry_changed (GtkEditable *editable, - gpointer user_data) -{ - AddAccountData *data = user_data; - update_intro (data); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -on_imap_show_password_toggled (GtkToggleButton *button, - gpointer user_data) -{ - AddAccountData *data = user_data; - gtk_entry_set_visibility (GTK_ENTRY (data->imap_password_entry), - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->imap_show_password))); -} - -static void -on_imap_tls_toggled (GtkToggleButton *button, - gpointer user_data) -{ - AddAccountData *data = user_data; - gtk_widget_set_sensitive (data->imap_ignore_bad_tls, - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->imap_use_tls))); -} - -static void -update_imap (AddAccountData *data) -{ - gboolean can_go_forward; - - can_go_forward = FALSE; - if (gtk_entry_get_text_length (GTK_ENTRY (data->imap_server_entry)) > 0 && - gtk_entry_get_text_length (GTK_ENTRY (data->imap_user_entry)) > 0 && - gtk_entry_get_text_length (GTK_ENTRY (data->imap_password_entry)) > 0) - { - can_go_forward = TRUE; - } - gtk_dialog_set_response_sensitive (data->dialog, GTK_RESPONSE_OK, can_go_forward); -} - -static void -on_imap_entry_changed (GtkEditable *editable, - gpointer user_data) -{ - AddAccountData *data = user_data; - update_imap (data); -} - -static gboolean -check_imap_settings (AddAccountData *data, - GError **error) -{ - GoaImapClient *client; - GoaImapAuth *auth; - gboolean ret; - GError *local_error; - - ret = FALSE; - - auth = goa_imap_auth_login_new (NULL, - NULL, - gtk_entry_get_text (GTK_ENTRY (data->imap_user_entry)), - gtk_entry_get_text (GTK_ENTRY (data->imap_password_entry))); - - /* TODO: run in thread and show spinner while connecting */ - client = goa_imap_client_new (); - if (!goa_imap_client_connect_sync (client, - gtk_entry_get_text (GTK_ENTRY (data->imap_server_entry)), - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->imap_use_tls)), - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->imap_ignore_bad_tls)), - auth, - NULL, /* cancellable */ - error)) - goto out; - - ret = TRUE; - - out: - local_error = NULL; - if (!goa_imap_client_disconnect_sync (client, - NULL, /* GCancellable */ - &local_error)) - { - goa_warning ("Error closing connection: %s (%s, %d)", - local_error->message, g_quark_to_string (local_error->domain), local_error->code); - g_error_free (local_error); - } - g_object_unref (client); - g_object_unref (auth); - return ret; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -on_smtp_show_password_toggled (GtkToggleButton *button, - gpointer user_data) -{ - AddAccountData *data = user_data; - gtk_entry_set_visibility (GTK_ENTRY (data->smtp_password_entry), - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->smtp_show_password))); -} - -static void -on_smtp_tls_toggled (GtkToggleButton *button, - gpointer user_data) -{ - AddAccountData *data = user_data; - gtk_widget_set_sensitive (data->smtp_ignore_bad_tls, - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->smtp_use_tls))); -} - -static void -update_smtp (AddAccountData *data) -{ - gboolean can_go_forward; - - can_go_forward = FALSE; - if (gtk_entry_get_text_length (GTK_ENTRY (data->smtp_server_entry)) > 0 && - gtk_entry_get_text_length (GTK_ENTRY (data->smtp_user_entry)) > 0 && - gtk_entry_get_text_length (GTK_ENTRY (data->smtp_password_entry)) > 0) - { - can_go_forward = TRUE; - } - gtk_dialog_set_response_sensitive (data->dialog, GTK_RESPONSE_OK, can_go_forward); -} - -static void -on_smtp_entry_changed (GtkEditable *editable, - gpointer user_data) -{ - AddAccountData *data = user_data; - update_smtp (data); -} - -static gboolean -check_smtp_settings (AddAccountData *data, - GError **error) -{ - /* TODO */ - g_warning ("TODO check_smtp_settings()"); - return TRUE; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -intro_auto_set_other_pages (AddAccountData *data) -{ - const gchar *address; - const gchar *s; - gchar *user_name; - gchar *imap_server; - gchar *smtp_server; - - /* These are just guesses - the use will be able to override himself */ - - address = gtk_entry_get_text (GTK_ENTRY (data->intro_address_entry)); - s = strstr (address, "@"); - g_assert (s != NULL); - user_name = g_strndup (address, s - address); - imap_server = g_strdup_printf ("imap.%s", s + 1); - smtp_server = g_strdup_printf ("smtp.%s", s + 1); - - gtk_entry_set_text (GTK_ENTRY (data->imap_user_entry), user_name); - gtk_entry_set_text (GTK_ENTRY (data->imap_server_entry), imap_server); - gtk_entry_set_text (GTK_ENTRY (data->smtp_server_entry), smtp_server); - - g_free (user_name); - g_free (imap_server); - g_free (smtp_server); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -add_account_cb (GoaManager *manager, - GAsyncResult *res, - gpointer user_data) -{ - AddAccountData *data = user_data; - goa_manager_call_add_account_finish (manager, - &data->account_object_path, - res, - &data->error); - g_main_loop_quit (data->loop); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static GoaObject * -add_account (GoaProvider *_provider, - GoaClient *client, - GtkDialog *dialog, - GtkBox *vbox, - GError **error) -{ - GoaGenericMailProvider *provider = GOA_GENERIC_MAIL_PROVIDER (_provider); - AddAccountData data; - GoaObject *ret; - GtkWidget *header_label; - GtkWidget *table; - GtkWidget *notebook; - guint row; - gint response; - GError *local_error; - gchar *s; - GVariantBuilder builder; - - ret = NULL; - - memset (&data, 0, sizeof (AddAccountData)); - data.loop = g_main_loop_new (NULL, FALSE); - data.dialog = dialog; - data.error = NULL; - - data.cluebar = gtk_info_bar_new (); - gtk_info_bar_set_message_type (GTK_INFO_BAR (data.cluebar), GTK_MESSAGE_ERROR); - gtk_widget_set_no_show_all (data.cluebar, TRUE); - data.cluebar_label = gtk_label_new (""); - gtk_label_set_line_wrap (GTK_LABEL (data.cluebar_label), TRUE); - gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (data.cluebar))), - data.cluebar_label); - gtk_box_pack_start (GTK_BOX (vbox), data.cluebar, FALSE, TRUE, 0); - - header_label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (header_label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (vbox), header_label, FALSE, TRUE, 0); - - notebook = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE); - gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE); - gtk_widget_set_margin_left (notebook, 12); - gtk_box_pack_start (GTK_BOX (vbox), notebook, FALSE, TRUE, 0); - - gtk_widget_show_all (GTK_WIDGET (vbox)); - gtk_dialog_add_button (dialog, "_Forward", GTK_RESPONSE_OK); - gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK); - gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, FALSE); - - /* ------------------------------------------------------------ */ - /* Set up the Intro page */ - - row = 0; - table = gtk_table_new (2, 2, FALSE); - gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), table, NULL, -1); - gtk_table_set_row_spacings (GTK_TABLE (table), 12); - gtk_table_set_col_spacings (GTK_TABLE (table), 12); - add_entry (table, row++, _("Email _Address"), &data.intro_address_entry); - add_entry (table, row++, _("_Description"), &data.intro_desc_entry); - g_signal_connect (data.intro_address_entry, - "changed", - G_CALLBACK (on_intro_entry_changed), - &data); - g_signal_connect (data.intro_desc_entry, - "changed", - G_CALLBACK (on_intro_entry_changed), - &data); - gtk_widget_show_all (table); - - /* ------------------------------------------------------------ */ - /* Show the Intro page */ - - s = g_strconcat ("<b>", _("New Mail Account"), "</b>", NULL); - gtk_label_set_markup (GTK_LABEL (header_label), s); - g_free (s); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0); - gtk_widget_show_all (GTK_WIDGET (vbox)); - gtk_widget_grab_focus (data.intro_address_entry); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response != GTK_RESPONSE_OK) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_DIALOG_DISMISSED, - "dismissed"); - goto out; - } - - /* ------------------------------------------------------------ */ - /* Then set up the IMAP page */ - - row = 0; - table = gtk_table_new (2, 2, FALSE); - gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), table, NULL, -1); - gtk_table_set_row_spacings (GTK_TABLE (table), 12); - gtk_table_set_col_spacings (GTK_TABLE (table), 12); - add_entry (table, row++, _("IMAP _Server"), &data.imap_server_entry); - add_entry (table, row++, _("_User Name"), &data.imap_user_entry); - add_entry (table, row++, _("_Password"), &data.imap_password_entry); - add_check_button (table, row++, _("Sho_w Password"), &data.imap_show_password); - add_check_button (table, row++, _("Use s_ecure connection"), &data.imap_use_tls); - add_check_button (table, row++, _("_Don't check certificates"), &data.imap_ignore_bad_tls); - gtk_entry_set_text (GTK_ENTRY (data.imap_user_entry), g_get_user_name ()); - gtk_entry_set_visibility (GTK_ENTRY (data.imap_password_entry), FALSE); - g_signal_connect (data.imap_show_password, - "toggled", - G_CALLBACK (on_imap_show_password_toggled), - &data); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data.imap_use_tls), TRUE); - g_signal_connect (data.imap_use_tls, - "toggled", - G_CALLBACK (on_imap_tls_toggled), - &data); - g_signal_connect (data.imap_server_entry, - "changed", - G_CALLBACK (on_imap_entry_changed), - &data); - g_signal_connect (data.imap_user_entry, - "changed", - G_CALLBACK (on_imap_entry_changed), - &data); - g_signal_connect (data.imap_password_entry, - "changed", - G_CALLBACK (on_imap_entry_changed), - &data); - gtk_widget_show_all (table); - - /* ------------------------------------------------------------ */ - /* Then set up the SMTP page */ - - row = 0; - table = gtk_table_new (2, 2, FALSE); - gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), table, NULL, -1); - gtk_table_set_row_spacings (GTK_TABLE (table), 12); - gtk_table_set_col_spacings (GTK_TABLE (table), 12); - add_entry (table, row++, _("SMTP _Server"), &data.smtp_server_entry); - add_entry (table, row++, _("_User Name"), &data.smtp_user_entry); - add_entry (table, row++, _("_Password"), &data.smtp_password_entry); - add_check_button (table, row++, _("Sho_w Password"), &data.smtp_show_password); - add_check_button (table, row++, _("Use s_ecure connection"), &data.smtp_use_tls); - add_check_button (table, row++, _("_Don't check certificates"), &data.smtp_ignore_bad_tls); - gtk_entry_set_text (GTK_ENTRY (data.smtp_user_entry), g_get_user_name ()); - gtk_entry_set_visibility (GTK_ENTRY (data.smtp_password_entry), FALSE); - g_signal_connect (data.smtp_show_password, - "toggled", - G_CALLBACK (on_smtp_show_password_toggled), - &data); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data.smtp_use_tls), TRUE); - g_signal_connect (data.smtp_use_tls, - "toggled", - G_CALLBACK (on_smtp_tls_toggled), - &data); - g_signal_connect (data.smtp_server_entry, - "changed", - G_CALLBACK (on_smtp_entry_changed), - &data); - g_signal_connect (data.smtp_user_entry, - "changed", - G_CALLBACK (on_smtp_entry_changed), - &data); - g_signal_connect (data.smtp_password_entry, - "changed", - G_CALLBACK (on_smtp_entry_changed), - &data); - gtk_widget_show_all (table); - - /* ------------------------------------------------------------ */ - /* Then prefill other pages from the obtained info */ - intro_auto_set_other_pages (&data); - - /* ------------------------------------------------------------ */ - /* Then show the IMAP page */ - - s = g_strconcat ("<b>", _("Receiving Mail"), "</b>", NULL); - gtk_label_set_markup (GTK_LABEL (header_label), s); - g_free (s); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1); - gtk_widget_grab_focus (data.imap_server_entry); - - imap_again: - response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response != GTK_RESPONSE_OK) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_DIALOG_DISMISSED, - "dismissed"); - goto out; - } - - /* Check that IMAP settings work */ - local_error = NULL; - if (!check_imap_settings (&data, &local_error)) - { - gchar *markup; - markup = g_strdup_printf ("<b>%s:</b> %s", - _("Error connecting to IMAP server"), - local_error->message); - gtk_label_set_markup (GTK_LABEL (data.cluebar_label), markup); - gtk_widget_set_no_show_all (data.cluebar, FALSE); - gtk_widget_show_all (data.cluebar); - g_free (markup); - g_error_free (local_error); - goto imap_again; - } - - /* hide cluebar errors */ - gtk_widget_hide (data.cluebar); - - /* ------------------------------------------------------------ */ - /* Then show the SMTP page */ - - s = g_strconcat ("<b>", _("Sending Mail"), "</b>", NULL); - gtk_label_set_markup (GTK_LABEL (header_label), s); - g_free (s); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 2); - gtk_widget_grab_focus (data.smtp_server_entry); - - /* Re-use the password from the IMAP page */ - gtk_entry_set_text (GTK_ENTRY (data.smtp_password_entry), - gtk_entry_get_text (GTK_ENTRY (data.imap_password_entry))); - - smtp_again: - response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response != GTK_RESPONSE_OK) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_DIALOG_DISMISSED, - "dismissed"); - goto out; - } - - /* Check that SMTP settings work */ - local_error = NULL; - if (!check_smtp_settings (&data, &local_error)) - { - gchar *markup; - markup = g_strdup_printf ("<b>%s:</b> %s", - _("Error connecting to SMTP server"), - local_error->message); - gtk_label_set_markup (GTK_LABEL (data.cluebar_label), markup); - gtk_widget_set_no_show_all (data.cluebar, FALSE); - gtk_widget_show_all (data.cluebar); - g_free (markup); - g_error_free (local_error); - goto smtp_again; - } - - /* OK, everything is dandy, add the account */ - /* we want the GoaClient to update before this method returns (so it - * can create a proxy for the new object) so run the mainloop while - * waiting for this to complete - */ - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); - g_variant_builder_add (&builder, "{ss}", "Enabled", "true"); - g_variant_builder_add (&builder, "{ss}", "EmailAddress", - gtk_entry_get_text (GTK_ENTRY (data.intro_address_entry))); - g_variant_builder_add (&builder, "{ss}", "ImapHost", - gtk_entry_get_text (GTK_ENTRY (data.imap_server_entry))); - g_variant_builder_add (&builder, "{ss}", "ImapUserName", - gtk_entry_get_text (GTK_ENTRY (data.imap_user_entry))); - g_variant_builder_add (&builder, "{ss}", "ImapUseTls", - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data.imap_use_tls)) ? "true" : "false"); - g_variant_builder_add (&builder, "{ss}", "ImapIgnoreBadTls", - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data.imap_ignore_bad_tls)) ? "true" : "false"); - g_variant_builder_add (&builder, "{ss}", "SmtpHost", - gtk_entry_get_text (GTK_ENTRY (data.smtp_server_entry))); - g_variant_builder_add (&builder, "{ss}", "SmtpUserName", - gtk_entry_get_text (GTK_ENTRY (data.smtp_user_entry))); - g_variant_builder_add (&builder, "{ss}", "SmtpUseTls", - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data.smtp_use_tls)) ? "true" : "false"); - g_variant_builder_add (&builder, "{ss}", "SmtpIgnoreBadTls", - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data.smtp_ignore_bad_tls)) ? "true" : "false"); - goa_manager_call_add_account (goa_client_get_manager (client), - goa_provider_get_provider_type (GOA_PROVIDER (provider)), - gtk_entry_get_text (GTK_ENTRY (data.intro_desc_entry)), - g_variant_builder_end (&builder), - NULL, /* GCancellable* */ - (GAsyncReadyCallback) add_account_cb, - &data); - g_main_loop_run (data.loop); - if (data.error != NULL) - { - g_propagate_error (error, data.error); - goto out; - } - - ret = GOA_OBJECT (g_dbus_object_manager_get_object (goa_client_get_object_manager (client), - data.account_object_path)); - /* TODO: run in worker thread */ - g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&builder, "{sv}", "imap-password", - g_variant_new_string (gtk_entry_get_text (GTK_ENTRY (data.imap_password_entry)))); - g_variant_builder_add (&builder, "{sv}", "smtp-password", - g_variant_new_string (gtk_entry_get_text (GTK_ENTRY (data.smtp_password_entry)))); - if (!goa_provider_store_credentials_sync (GOA_PROVIDER (provider), - ret, - g_variant_builder_end (&builder), - NULL, /* GCancellable */ - error)) - goto out; - - out: - g_free (data.account_object_path); - if (data.loop != NULL) - g_main_loop_unref (data.loop); - return ret; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -show_account (GoaProvider *provider, - GoaClient *client, - GoaObject *object, - GtkBox *vbox, - GtkTable *table) -{ - gchar *email_address; - gchar *imap_host; - gchar *imap_user_name; - gboolean imap_use_tls; - gboolean imap_ignore_bad_tls; - gchar *smtp_host; - gchar *smtp_user_name; - gboolean smtp_use_tls; - gboolean smtp_ignore_bad_tls; - GString *str; - - /* Chain up */ - GOA_PROVIDER_CLASS (goa_generic_mail_provider_parent_class)->show_account (provider, client, object, vbox, table); - - email_address = goa_util_lookup_keyfile_string (object, "EmailAddress"); - goa_util_add_row_label (table, _("Email Address"), email_address); - - imap_host = goa_util_lookup_keyfile_string (object, "ImapHost"); - imap_user_name = goa_util_lookup_keyfile_string (object, "ImapUserName"); - imap_use_tls = goa_util_lookup_keyfile_boolean (object, "ImapUseTls"); - imap_ignore_bad_tls = goa_util_lookup_keyfile_boolean (object, "ImapIgnoreBadTls"); - str = g_string_new (imap_host); - if (g_strcmp0 (g_get_user_name (), imap_user_name) != 0) - g_string_append_printf (str, "\n<small>%s: %s</small>", - _("User Name"), - imap_user_name); - if (imap_use_tls) - { - if (imap_ignore_bad_tls) - g_string_append_printf (str, "\n<small><span foreground=\"red\">%s</span></small>", - _("Transport Security without Certificate Checks")); - } - else - { - g_string_append_printf (str, "\n<small><span foreground=\"red\">%s</span></small>", - _("No Transport Security")); - } - goa_util_add_row_label (table, _("IMAP Server"), str->str); - g_string_free (str, TRUE); - - smtp_host = goa_util_lookup_keyfile_string (object, "SmtpHost"); - smtp_user_name = goa_util_lookup_keyfile_string (object, "SmtpUserName"); - smtp_use_tls = goa_util_lookup_keyfile_boolean (object, "SmtpUseTls"); - smtp_ignore_bad_tls = goa_util_lookup_keyfile_boolean (object, "SmtpIgnoreBadTls"); - str = g_string_new (smtp_host); - if (g_strcmp0 (g_get_user_name (), smtp_user_name) != 0) - g_string_append_printf (str, "\n<small>%s: %s</small>", - _("User Name"), - smtp_user_name); - if (smtp_use_tls) - { - if (smtp_ignore_bad_tls) - g_string_append_printf (str, "\n<small><span foreground=\"red\">%s</span></small>", - _("Transport Security without Certificate Checks")); - } - else - { - g_string_append_printf (str, "\n<small><span foreground=\"red\">%s</span></small>", - _("No Transport Security")); - } - goa_util_add_row_label (table, _("SMTP Server"), str->str); - g_string_free (str, TRUE); - - goa_util_add_row_switch_from_keyfile (table, object, _("Enabled"), "Enabled"); - - /* TODO: we could have a "Edit" button */ - - g_free (smtp_host); - g_free (smtp_user_name); - g_free (imap_host); - g_free (imap_user_name); - g_free (email_address); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -goa_generic_mail_provider_init (GoaGenericMailProvider *provider) -{ -} - -static void -goa_generic_mail_provider_class_init (GoaGenericMailProviderClass *klass) -{ - GoaProviderClass *provider_class; - - provider_class = GOA_PROVIDER_CLASS (klass); - provider_class->get_provider_type = get_provider_type; - provider_class->get_name = get_name; - provider_class->add_account = add_account; - provider_class->build_object = build_object; - provider_class->show_account = show_account; - provider_class->ensure_credentials_sync = ensure_credentials_sync; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static gboolean -on_handle_get_password (GoaPasswordBased *interface, - GDBusMethodInvocation *invocation, - const gchar *id, - gpointer user_data) -{ - GoaObject *object; - GoaAccount *account; - GoaProvider *provider; - GError *error; - GVariant *credentials; - gchar *password; - - /* TODO: maybe log what app is requesting access */ - - password = NULL; - credentials = NULL; - - object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (interface))); - account = goa_object_peek_account (object); - provider = goa_provider_get_for_provider_type (goa_account_get_provider_type (account)); - - error = NULL; - credentials = goa_provider_lookup_credentials_sync (provider, - object, - NULL, /* GCancellable* */ - &error); - if (credentials == NULL) - { - g_prefix_error (&error, "Error looking up credentials in keyring: "); - g_dbus_method_invocation_take_error (invocation, error); - goto out; - } - - if (!g_variant_lookup (credentials, id, "s", &password)) - { - g_dbus_method_invocation_return_error (invocation, - GOA_ERROR, - GOA_ERROR_FAILED, - "Did not find password with id `%s' in credentials", - id); - goto out; - } - - goa_password_based_complete_get_password (interface, invocation, password); - - out: - g_free (password); - if (credentials != NULL) - g_variant_unref (credentials); - g_object_unref (provider); - return TRUE; /* invocation was handled */ -} - diff --git a/src/goabackend/goagenericmailprovider.h b/src/goabackend/goagenericmailprovider.h deleted file mode 100644 index b8a74bf..0000000 --- a/src/goabackend/goagenericmailprovider.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) -#error "Only <goabackend/goabackend.h> can be included directly." -#endif - -#ifndef __GOA_GENERIC_MAIL_PROVIDER_H__ -#define __GOA_GENERIC_MAIL_PROVIDER_H__ - -#include <goabackend/goabackendtypes.h> - -G_BEGIN_DECLS - -#define GOA_TYPE_GENERIC_MAIL_PROVIDER (goa_generic_mail_provider_get_type ()) -#define GOA_GENERIC_MAIL_PROVIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOA_TYPE_GENERIC_MAIL_PROVIDER, GoaGenericMailProvider)) -#define GOA_IS_GENERIC_MAIL_PROVIDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOA_TYPE_GENERIC_MAIL_PROVIDER)) - -GType goa_generic_mail_provider_get_type (void) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __GOA_GENERIC_MAIL_PROVIDER_H__ */ diff --git a/src/goabackend/goagoogleprovider.c b/src/goabackend/goagoogleprovider.c index 1e0364e..544244d 100644 --- a/src/goabackend/goagoogleprovider.c +++ b/src/goabackend/goagoogleprovider.c @@ -30,9 +30,6 @@ #include "goaoauthprovider.h" #include "goagoogleprovider.h" -#include "goainternetmail.h" -#include "goaimapauthoauth.h" - /** * GoaGoogleProvider: * @@ -296,26 +293,17 @@ build_object (GoaProvider *provider, { if (mail == NULL) { - GoaImapAuth *imap_auth; - gchar *request_uri; - request_uri = g_strdup_printf ("https://mail.google.com/mail/b/%s/imap/", email_address); - imap_auth = goa_imap_auth_oauth_new (GOA_OAUTH_PROVIDER (provider), - GOA_OBJECT (object), - request_uri); - mail = goa_internet_mail_new ("imap.gmail.com", - "", /* user_name */ - TRUE, /* use_tls */ - FALSE, /* ignore_bad_tls */ - imap_auth, - "smtp.gmail.com", - "", /* user_name */ - TRUE, /* use_tls */ - FALSE); /* ignore_bad_tls */ + mail = goa_mail_skeleton_new (); + g_object_set (G_OBJECT (mail), + "email-address", email_address, + "imap-host", "imap.gmail.com", + "imap-user-name", "", + "imap-use-tls", TRUE, + "smtp-host", "smtp.gmail.com", + "smtp-user-name", "", + "smtp-use-tls", TRUE, + NULL); goa_object_skeleton_set_mail (object, mail); - g_object_unref (imap_auth); - g_free (request_uri); - - goa_mail_set_email_address (mail, email_address); } } else diff --git a/src/goabackend/goaimapauth.c b/src/goabackend/goaimapauth.c deleted file mode 100644 index f8d0bf3..0000000 --- a/src/goabackend/goaimapauth.c +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#include "config.h" -#include <glib/gi18n-lib.h> -#include <stdlib.h> - -#include "goaimapauth.h" - -/** - * SECTION:goaimapauth - * @title: GoaImapAuth - * @short_description: Helper type for authenticating IMAP connections - * - * #GoaImapAuth is an abstract type used for authenticating - * IMAP connections. See #GoaImapAuthOAuth for a concrete - * implementation. - */ - -G_DEFINE_ABSTRACT_TYPE (GoaImapAuth, goa_imap_auth, G_TYPE_OBJECT); - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -goa_imap_auth_init (GoaImapAuth *client) -{ -} - -static void -goa_imap_auth_class_init (GoaImapAuthClass *klass) -{ -} - -/* ---------------------------------------------------------------------------------------------------- */ - -/** - * goa_imap_auth_run_sync: - * @auth: A #GoaImapAuth. - * @input: A valid #GDataInputStream. - * @output: A valid #GDataOutputStream. - * @cancellable: (allow-none): A #GCancellable or %NULL. - * @error: Return location for error or %NULL. - * - * Authenticates the IMAP connection represented by @input and - * @output. This method blocks the calling thread until authentication - * is done. - * - * Returns: %TRUE if authentication succeeded, %FALSE if @error is - * set. - */ -gboolean -goa_imap_auth_run_sync (GoaImapAuth *auth, - GDataInputStream *input, - GDataOutputStream *output, - GCancellable *cancellable, - GError **error) -{ - g_return_val_if_fail (GOA_IS_IMAP_AUTH (auth), FALSE); - g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (input), FALSE); - g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (output), FALSE); - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); - return GOA_IMAP_AUTH_GET_CLASS (auth)->run_sync (auth, input, output, cancellable, error); -} - -/* ---------------------------------------------------------------------------------------------------- */ diff --git a/src/goabackend/goaimapauth.h b/src/goabackend/goaimapauth.h deleted file mode 100644 index b60e08c..0000000 --- a/src/goabackend/goaimapauth.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) -#error "Only <goabackend/goabackend.h> can be included directly." -#endif - -#ifndef __GOA_IMAP_AUTH_H__ -#define __GOA_IMAP_AUTH_H__ - -#include <goabackend/goabackendtypes.h> - -G_BEGIN_DECLS - -#define GOA_TYPE_IMAP_AUTH (goa_imap_auth_get_type ()) -#define GOA_IMAP_AUTH(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOA_TYPE_IMAP_AUTH, GoaImapAuth)) -#define GOA_IMAP_AUTH_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GOA_TYPE_IMAP_AUTH, GoaImapAuthClass)) -#define GOA_IMAP_AUTH_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GOA_TYPE_IMAP_AUTH, GoaImapAuthClass)) -#define GOA_IS_IMAP_AUTH(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOA_TYPE_IMAP_AUTH)) -#define GOA_IS_IMAP_AUTH_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GOA_TYPE_IMAP_AUTH)) - -struct _GoaImapAuthClass; -struct _GoaImapAuthPrivate; -typedef struct _GoaImapAuthClass GoaImapAuthClass; -typedef struct _GoaImapAuthPrivate GoaImapAuthPrivate; - -/** - * GoaImapAuth: - * - * The #GoaImapAuth structure contains only private data and - * should only be accessed using the provided API. - */ -struct _GoaImapAuth -{ - /*< private >*/ - GObject parent_instance; - GoaImapAuthPrivate *priv; -}; - -/** - * GoaImapAuthClass: - * @parent_class: The parent class - * @run_sync: Virtual function for the goa_imap_auth_run_sync() method. - * - * Class structure for #GoaImapAuth. - */ -struct _GoaImapAuthClass -{ - GObjectClass parent_class; - gboolean (*run_sync) (GoaImapAuth *auth, - GDataInputStream *input, - GDataOutputStream *output, - GCancellable *cancellable, - GError **error); - /*< private >*/ - /* Padding for future expansion */ - gpointer goa_reserved[8]; -}; - -GType goa_imap_auth_get_type (void) G_GNUC_CONST; -gboolean goa_imap_auth_run_sync (GoaImapAuth *auth, - GDataInputStream *input, - GDataOutputStream *output, - GCancellable *cancellable, - GError **error); - -G_END_DECLS - -#endif /* __GOA_IMAP_AUTH_H__ */ diff --git a/src/goabackend/goaimapauthlogin.c b/src/goabackend/goaimapauthlogin.c deleted file mode 100644 index 96d5976..0000000 --- a/src/goabackend/goaimapauthlogin.c +++ /dev/null @@ -1,371 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#include "config.h" -#include <glib/gi18n-lib.h> -#include <stdlib.h> - -#include "goaprovider.h" -#include "goaimapauth.h" -#include "goaimapauthlogin.h" - -/** - * SECTION:goaimapauthlogin - * @title: GoaImapAuthLogin - * @short_description: LOGIN authentication method for IMAP - * - * #GoaImapAuthLogin implements the standard <ulink - * url="http://tools.ietf.org/html/rfc3501#section-6.2.3">LOGIN</ulink> - * authentication method (e.g. using usernames / passwords) for IMAP. - */ - -/** - * GoaImapAuthLogin: - * - * The #GoaImapAuthLogin structure contains only private data - * and should only be accessed using the provided API. - */ -struct _GoaImapAuthLogin -{ - GoaImapAuth parent_instance; - - GoaProvider *provider; - GoaObject *object; - gchar *user_name; - gchar *password; -}; - -typedef struct -{ - GoaImapAuthClass parent_class; - -} GoaImapAuthLoginClass; - -enum -{ - PROP_0, - PROP_PROVIDER, - PROP_OBJECT, - PROP_USER_NAME, - PROP_PASSWORD -}; - -static gboolean goa_imap_auth_login_run_sync (GoaImapAuth *_auth, - GDataInputStream *input, - GDataOutputStream *output, - GCancellable *cancellable, - GError **error); - -G_DEFINE_TYPE (GoaImapAuthLogin, goa_imap_auth_login, GOA_TYPE_IMAP_AUTH); - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -goa_imap_auth_login_finalize (GObject *object) -{ - GoaImapAuthLogin *auth = GOA_IMAP_AUTH_LOGIN (object); - - g_clear_object (&auth->provider); - g_clear_object (&auth->object); - g_free (auth->user_name); - g_free (auth->password); - - G_OBJECT_CLASS (goa_imap_auth_login_parent_class)->finalize (object); -} - -static void -goa_imap_auth_login_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GoaImapAuthLogin *auth = GOA_IMAP_AUTH_LOGIN (object); - - switch (prop_id) - { - case PROP_PROVIDER: - g_value_set_object (value, auth->provider); - break; - - case PROP_OBJECT: - g_value_set_object (value, auth->object); - break; - - case PROP_USER_NAME: - g_value_set_string (value, auth->user_name); - break; - - case PROP_PASSWORD: - g_value_set_string (value, auth->password); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -goa_imap_auth_login_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GoaImapAuthLogin *auth = GOA_IMAP_AUTH_LOGIN (object); - - switch (prop_id) - { - case PROP_PROVIDER: - auth->provider = g_value_dup_object (value); - break; - - case PROP_OBJECT: - auth->object = g_value_dup_object (value); - break; - - case PROP_USER_NAME: - auth->user_name = g_value_dup_string (value); - break; - - case PROP_PASSWORD: - auth->password = g_value_dup_string (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* ---------------------------------------------------------------------------------------------------- */ - - -static void -goa_imap_auth_login_init (GoaImapAuthLogin *client) -{ -} - -static void -goa_imap_auth_login_class_init (GoaImapAuthLoginClass *klass) -{ - GObjectClass *gobject_class; - GoaImapAuthClass *auth_class; - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = goa_imap_auth_login_finalize; - gobject_class->get_property = goa_imap_auth_login_get_property; - gobject_class->set_property = goa_imap_auth_login_set_property; - - auth_class = GOA_IMAP_AUTH_CLASS (klass); - auth_class->run_sync = goa_imap_auth_login_run_sync; - - /** - * GoaImapAuthLogin:provider: - * - * The #GoaProvider object for the account or %NULL. - */ - g_object_class_install_property (gobject_class, - PROP_PROVIDER, - g_param_spec_object ("provider", - "provider", - "provider", - GOA_TYPE_PROVIDER, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - /** - * GoaImapAuthLogin:object: - * - * The #GoaObject object for the account. - */ - g_object_class_install_property (gobject_class, - PROP_OBJECT, - g_param_spec_object ("object", - "object", - "object", - GOA_TYPE_OBJECT, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - /** - * GoaImapAuthLogin:user-name: - * - * The user name. - */ - g_object_class_install_property (gobject_class, - PROP_USER_NAME, - g_param_spec_string ("user-name", - "user-name", - "user-name", - NULL, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - /** - * GoaImapAuthLogin:password: - * - * The password or %NULL. - * - * If this is %NULL, the credentials are looked up using - * goa_provider_lookup_credentials_sync() using the - * #GoaImapAuthLogin:provider and #GoaImapAuthLogin:object for - * @provider and @object. The credentials are expected to be a - * %G_VARIANT_VARDICT and the key <literal>imap-password</literal> - * is used to look up the password. - */ - g_object_class_install_property (gobject_class, - PROP_PASSWORD, - g_param_spec_string ("password", - "password", - "password", - NULL, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -/** - * goa_imap_auth_login_new: - * @provider: (allow-none): A #GoaLoginProvider or %NULL. - * @object: (allow-none): An account object or %NULL. - * @user_name: The user name to use. - * @password: (allow-none): The password to use or %NULL to look it up (see the #GoaImapAuthLogin:password property). - * - * Creates a new #GoaImapAuth to be used for username/password authentication. - * - * Returns: (type GoaImapAuthLogin): A #GoaImapAuthLogin. Free with g_object_unref(). - */ -GoaImapAuth * -goa_imap_auth_login_new (GoaProvider *provider, - GoaObject *object, - const gchar *user_name, - const gchar *password) -{ - g_return_val_if_fail (provider == NULL || GOA_IS_PROVIDER (provider), NULL); - g_return_val_if_fail (object == NULL || GOA_IS_OBJECT (object), NULL); - g_return_val_if_fail (user_name != NULL, NULL); - return GOA_IMAP_AUTH (g_object_new (GOA_TYPE_IMAP_AUTH_LOGIN, - "provider", provider, - "object", object, - "user-name", user_name, - "password", password, - NULL)); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static gboolean -goa_imap_auth_login_run_sync (GoaImapAuth *_auth, - GDataInputStream *input, - GDataOutputStream *output, - GCancellable *cancellable, - GError **error) -{ - GoaImapAuthLogin *auth = GOA_IMAP_AUTH_LOGIN (_auth); - gchar *request; - gchar *response; - gboolean ret; - gchar *password; - - request = NULL; - response = NULL; - password = NULL; - ret = FALSE; - - /* TODO: support looking up the password from the keyring */ - if (auth->password != NULL) - { - password = g_strdup (auth->password); - } - else if (auth->provider != NULL && auth->object != NULL) - { - GVariant *credentials; - credentials = goa_provider_lookup_credentials_sync (auth->provider, - auth->object, - cancellable, - error); - if (credentials == NULL) - { - g_prefix_error (error, "Error looking up credentials for IMAP LOGIN in keyring: "); - goto out; - } - if (!g_variant_lookup (credentials, "imap-password", "s", &password)) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_FAILED, - "Did not find imap-password in credentials"); - g_variant_unref (credentials); - goto out; - } - g_variant_unref (credentials); - } - else - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_FAILED, - "Cannot do IMAP LOGIN without a password"); - goto out; - } - - request = g_strdup_printf ("A001 LOGIN %s %s\r\n", auth->user_name, password); - if (!g_data_output_stream_put_string (output, request, cancellable, error)) - goto out; - - again: - response = g_data_input_stream_read_line (input, NULL, cancellable, error); - if (response == NULL) - goto out; - /* ignore untagged responses */ - if (g_str_has_prefix (response, "*")) - { - g_free (response); - goto again; - } - if (!g_str_has_prefix (response, "A001 OK")) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_FAILED, - "Unexpected response `%s' while doing LOGIN authentication", - response); - goto out; - } - - ret = TRUE; - - out: - g_free (response); - g_free (request); - g_free (password); - return ret; -} diff --git a/src/goabackend/goaimapauthlogin.h b/src/goabackend/goaimapauthlogin.h deleted file mode 100644 index 5d2a1ba..0000000 --- a/src/goabackend/goaimapauthlogin.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) -#error "Only <goabackend/goabackend.h> can be included directly." -#endif - -#ifndef __GOA_IMAP_AUTH_LOGIN_H__ -#define __GOA_IMAP_AUTH_LOGIN_H__ - -#include <goabackend/goabackendtypes.h> - -G_BEGIN_DECLS - -#define GOA_TYPE_IMAP_AUTH_LOGIN (goa_imap_auth_login_get_type ()) -#define GOA_IMAP_AUTH_LOGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOA_TYPE_IMAP_AUTH_LOGIN, GoaImapAuthLogin)) -#define GOA_IS_IMAP_AUTH_LOGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOA_TYPE_IMAP_AUTH_LOGIN)) - - -GType goa_imap_auth_login_get_type (void) G_GNUC_CONST; -GoaImapAuth *goa_imap_auth_login_new (GoaProvider *provider, - GoaObject *object, - const gchar *user_name, - const gchar *password); - -G_END_DECLS - -#endif /* __GOA_IMAP_AUTH_LOGIN_H__ */ diff --git a/src/goabackend/goaimapauthoauth.c b/src/goabackend/goaimapauthoauth.c deleted file mode 100644 index 5b100f5..0000000 --- a/src/goabackend/goaimapauthoauth.c +++ /dev/null @@ -1,568 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#include "config.h" -#include <glib/gi18n-lib.h> -#include <stdlib.h> - -#include "goaimapauth.h" -#include "goaimapauthoauth.h" -#include "goaoauthprovider.h" - -/** - * SECTION:goaimapauthoauth - * @title: GoaImapAuthOAuth - * @short_description: XOAUTH authentication method for IMAP - * - * #GoaImapAuthOAuth implements the <ulink - * url="http://code.google.com/apis/gmail/oauth/protocol.html">XOAUTH</ulink> - * authentication method for IMAP. - */ - -/** - * GoaImapAuthOAuth: - * - * The #GoaImapAuthOAuth structure contains only private data - * and should only be accessed using the provided API. - */ -struct _GoaImapAuthOAuth -{ - GoaImapAuth parent_instance; - - GoaOAuthProvider *provider; - GoaObject *object; - gchar *request_uri; -}; - -typedef struct -{ - GoaImapAuthClass parent_class; - -} GoaImapAuthOAuthClass; - -enum -{ - PROP_0, - PROP_PROVIDER, - PROP_OBJECT, - PROP_REQUEST_URI -}; - -static gboolean goa_imap_auth_oauth_run_sync (GoaImapAuth *_auth, - GDataInputStream *input, - GDataOutputStream *output, - GCancellable *cancellable, - GError **error); - -G_DEFINE_TYPE (GoaImapAuthOAuth, goa_imap_auth_oauth, GOA_TYPE_IMAP_AUTH); - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -goa_imap_auth_oauth_finalize (GObject *object) -{ - GoaImapAuthOAuth *auth = GOA_IMAP_AUTH_OAUTH (object); - - g_object_unref (auth->provider); - g_object_unref (auth->object); - - G_OBJECT_CLASS (goa_imap_auth_oauth_parent_class)->finalize (object); -} - -static void -goa_imap_auth_oauth_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GoaImapAuthOAuth *auth = GOA_IMAP_AUTH_OAUTH (object); - - switch (prop_id) - { - case PROP_PROVIDER: - g_value_set_object (value, auth->provider); - break; - - case PROP_OBJECT: - g_value_set_object (value, auth->object); - break; - - case PROP_REQUEST_URI: - g_value_set_string (value, auth->request_uri); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -goa_imap_auth_oauth_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GoaImapAuthOAuth *auth = GOA_IMAP_AUTH_OAUTH (object); - - switch (prop_id) - { - case PROP_PROVIDER: - auth->provider = g_value_dup_object (value); - break; - - case PROP_OBJECT: - auth->object = g_value_dup_object (value); - break; - - case PROP_REQUEST_URI: - auth->request_uri = g_value_dup_string (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* ---------------------------------------------------------------------------------------------------- */ - - -static void -goa_imap_auth_oauth_init (GoaImapAuthOAuth *client) -{ -} - -static void -goa_imap_auth_oauth_class_init (GoaImapAuthOAuthClass *klass) -{ - GObjectClass *gobject_class; - GoaImapAuthClass *auth_class; - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = goa_imap_auth_oauth_finalize; - gobject_class->get_property = goa_imap_auth_oauth_get_property; - gobject_class->set_property = goa_imap_auth_oauth_set_property; - - auth_class = GOA_IMAP_AUTH_CLASS (klass); - auth_class->run_sync = goa_imap_auth_oauth_run_sync; - - /** - * GoaImapAuthOAuth:provider: - * - * The #GoaOAuthProvider object to use when calculating the XOAUTH mechanism parameter. - */ - g_object_class_install_property (gobject_class, - PROP_PROVIDER, - g_param_spec_object ("provider", - "provider", - "provider", - GOA_TYPE_OAUTH_PROVIDER, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - /** - * GoaImapAuthOAuth:object: - * - * The #GoaObject object to use when calculating the XOAUTH mechanism parameter. - */ - g_object_class_install_property (gobject_class, - PROP_OBJECT, - g_param_spec_object ("object", - "object", - "object", - GOA_TYPE_OBJECT, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - /** - * GoaImapAuthOAuth:request-uri: - * - * The request URI to use when calculating the XOAUTH mechanism parameter. - */ - g_object_class_install_property (gobject_class, - PROP_REQUEST_URI, - g_param_spec_string ("request-uri", - "request-uri", - "request-uri", - NULL, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -/** - * goa_imap_auth_oauth_new: - * @provider: A #GoaOAuthProvider. - * @object: An account object. - * @request_uri: The request URI to use. - * - * Creates a new #GoaImapAuth to be used for XOAUTH authentication. - * - * Returns: (type GoaImapAuthOAuth): A #GoaImapAuthOAuth. Free with g_object_unref(). - */ -GoaImapAuth * -goa_imap_auth_oauth_new (GoaOAuthProvider *provider, - GoaObject *object, - const gchar *request_uri) -{ - g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), NULL); - g_return_val_if_fail (GOA_IS_OBJECT (object), NULL); - return GOA_IMAP_AUTH (g_object_new (GOA_TYPE_IMAP_AUTH_OAUTH, - "provider", provider, - "object", object, - "request-uri", request_uri, - NULL)); -} - -/* ---------------------------------------------------------------------------------------------------- */ - - -#include <libsoup/soup.h> - -#define OAUTH_ENCODE_STRING(x_) (x_ ? soup_uri_encode( (x_), "!$&'()*+,;=@") : g_strdup ("")) - -#define SHA1_BLOCK_SIZE 64 -#define SHA1_LENGTH 20 - -/* - * hmac_sha1: - * @key: The key - * @message: The message - * - * Given the key and message, compute the HMAC-SHA1 hash and return the base-64 - * encoding of it. This is very geared towards OAuth, and as such both key and - * message must be NULL-terminated strings, and the result is base-64 encoded. - */ -static char * -hmac_sha1 (const char *key, const char *message) -{ - GChecksum *checksum; - char *real_key; - guchar ipad[SHA1_BLOCK_SIZE]; - guchar opad[SHA1_BLOCK_SIZE]; - guchar inner[SHA1_LENGTH]; - guchar digest[SHA1_LENGTH]; - gsize key_length, inner_length, digest_length; - int i; - - g_return_val_if_fail (key, NULL); - g_return_val_if_fail (message, NULL); - - checksum = g_checksum_new (G_CHECKSUM_SHA1); - - /* If the key is longer than the block size, hash it first */ - if (strlen (key) > SHA1_BLOCK_SIZE) { - guchar new_key[SHA1_LENGTH]; - - key_length = sizeof (new_key); - - g_checksum_update (checksum, (guchar*)key, strlen (key)); - g_checksum_get_digest (checksum, new_key, &key_length); - g_checksum_reset (checksum); - - real_key = g_memdup (new_key, key_length); - } else { - real_key = g_strdup (key); - key_length = strlen (key); - } - - /* Sanity check the length */ - g_assert (key_length <= SHA1_BLOCK_SIZE); - - /* Protect against use of the provided key by NULLing it */ - key = NULL; - - /* Stage 1 */ - memset (ipad, 0, sizeof (ipad)); - memset (opad, 0, sizeof (opad)); - - memcpy (ipad, real_key, key_length); - memcpy (opad, real_key, key_length); - - /* Stage 2 and 5 */ - for (i = 0; i < sizeof (ipad); i++) { - ipad[i] ^= 0x36; - opad[i] ^= 0x5C; - } - - /* Stage 3 and 4 */ - g_checksum_update (checksum, ipad, sizeof (ipad)); - g_checksum_update (checksum, (guchar*)message, strlen (message)); - inner_length = sizeof (inner); - g_checksum_get_digest (checksum, inner, &inner_length); - g_checksum_reset (checksum); - - /* Stage 6 and 7 */ - g_checksum_update (checksum, opad, sizeof (opad)); - g_checksum_update (checksum, inner, inner_length); - - digest_length = sizeof (digest); - g_checksum_get_digest (checksum, digest, &digest_length); - - g_checksum_free (checksum); - g_free (real_key); - - return g_base64_encode (digest, digest_length); -} - -static char * -sign_plaintext (const gchar *consumer_secret, - const gchar *token_secret) -{ - char *cs; - char *ts; - char *rv; - - cs = OAUTH_ENCODE_STRING (consumer_secret); - ts = OAUTH_ENCODE_STRING (token_secret); - rv = g_strconcat (cs, "&", ts, NULL); - - g_free (cs); - g_free (ts); - - return rv; -} - -static char * -sign_hmac (const gchar *consumer_secret, - const gchar *token_secret, - const gchar *http_method, - const gchar *request_uri, - const gchar *encoded_params) -{ - GString *text; - - text = g_string_new (NULL); - g_string_append (text, http_method); - g_string_append_c (text, '&'); - g_string_append_uri_escaped (text, request_uri, NULL, FALSE); - g_string_append_c (text, '&'); - g_string_append_uri_escaped (text, encoded_params, NULL, FALSE); - - /* PLAINTEXT signature value is the HMAC-SHA1 key value */ - gchar *key; - key = sign_plaintext (consumer_secret, token_secret); - - gchar *signature; - signature = hmac_sha1 (key, text->str); - - g_free (key); - g_string_free (text, TRUE); - - return signature; -} - -static GHashTable * -calculate_xoauth_params (const gchar *request_uri, - const gchar *consumer_key, - const gchar *consumer_secret, - const gchar *access_token, - const gchar *access_token_secret) -{ - gchar *signature; - GHashTable *params; - gchar *nonce; - gchar *timestamp; - GList *keys; - GList *l; - GString *normalized; - - nonce = g_strdup_printf ("%u", g_random_int ()); - timestamp = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) time (NULL)); - - params = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free); - g_hash_table_insert (params, "oauth_consumer_key", g_strdup (consumer_key)); - g_hash_table_insert (params, "oauth_nonce", nonce); /* takes ownership */ - g_hash_table_insert (params, "oauth_timestamp", timestamp); /* takes ownership */ - g_hash_table_insert (params, "oauth_version", g_strdup ("1.0")); - g_hash_table_insert (params, "oauth_signature_method", g_strdup ("HMAC-SHA1")); - g_hash_table_insert (params, "oauth_token", g_strdup (access_token)); - - normalized = g_string_new (NULL); - keys = g_hash_table_get_keys (params); - keys = g_list_sort (keys, (GCompareFunc) g_strcmp0); /* TODO: locale specific? */ - for (l = keys; l != NULL; l = l->next) - { - const gchar *key = l->data; - const gchar *value; - gchar *k; - gchar *v; - - value = g_hash_table_lookup (params, key); - if (normalized->len > 0) - g_string_append_c (normalized, '&'); - - k = OAUTH_ENCODE_STRING (key); - v = OAUTH_ENCODE_STRING (value); - - g_string_append_printf (normalized, "%s=%s", k, v); - - g_free (k); - g_free (v); - } - g_list_free (keys); - - signature = sign_hmac (consumer_secret, - access_token_secret, - "GET", - request_uri, - normalized->str); - g_hash_table_insert (params, "oauth_signature", signature); /* takes ownership */ - - g_string_free (normalized, TRUE); - return params; -} - -static gchar * -calculate_xoauth_param (const gchar *request_uri, - const gchar *consumer_key, - const gchar *consumer_secret, - const gchar *access_token, - const gchar *access_token_secret, - GError **error) -{ - gchar *ret; - GString *str; - GHashTable *params; - GList *keys; - GList *l; - - params = calculate_xoauth_params (request_uri, - consumer_key, - consumer_secret, - access_token, - access_token_secret); - str = g_string_new ("GET "); - g_string_append (str, request_uri); - g_string_append_c (str, ' '); - keys = g_hash_table_get_keys (params); - keys = g_list_sort (keys, (GCompareFunc) g_strcmp0); /* TODO: locale specific? */ - for (l = keys; l != NULL; l = l->next) - { - const gchar *key = l->data; - const gchar *value; - gchar *k; - gchar *v; - - value = g_hash_table_lookup (params, key); - if (l != keys) - g_string_append_c (str, ','); - - k = OAUTH_ENCODE_STRING (key); - v = OAUTH_ENCODE_STRING (value); - g_string_append_printf (str, "%s=\"%s\"", k, v); - g_free (k); - g_free (v); - } - g_list_free (keys); - - ret = g_base64_encode ((const guchar *) str->str, str->len); - g_string_free (str, TRUE); - g_hash_table_unref (params); - return ret; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static gboolean -goa_imap_auth_oauth_run_sync (GoaImapAuth *_auth, - GDataInputStream *input, - GDataOutputStream *output, - GCancellable *cancellable, - GError **error) -{ - GoaImapAuthOAuth *auth = GOA_IMAP_AUTH_OAUTH (_auth); - gchar *access_token; - gchar *access_token_secret; - gchar *xoauth_param; - gchar *request; - gchar *response; - gboolean ret; - - access_token = NULL; - access_token_secret = NULL; - xoauth_param = NULL; - request = NULL; - response = NULL; - ret = FALSE; - - access_token = goa_oauth_provider_get_access_token_sync (auth->provider, - auth->object, - FALSE, /* force_refresh */ - &access_token_secret, - NULL, /* out_access_token_expires_in */ - NULL, /* GCancellable */ - error); /* GError */ - if (access_token == NULL) - goto out; - - xoauth_param = calculate_xoauth_param (auth->request_uri, - goa_oauth_provider_get_consumer_key (auth->provider), - goa_oauth_provider_get_consumer_secret (auth->provider), - access_token, - access_token_secret, - error); - if (xoauth_param == NULL) - goto out; - - request = g_strdup_printf ("A001 AUTHENTICATE XOAUTH %s\r\n", xoauth_param); - if (!g_data_output_stream_put_string (output, request, cancellable, error)) - goto out; - - again: - response = g_data_input_stream_read_line (input, NULL, cancellable, error); - if (response == NULL) - goto out; - /* ignore untagged responses */ - if (g_str_has_prefix (response, "*")) - { - g_free (response); - goto again; - } - if (!g_str_has_prefix (response, "A001 OK")) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_FAILED, - "Unexpected response `%s' while doing XOAUTH authentication", - response); - goto out; - } - - ret = TRUE; - - out: - g_free (response); - g_free (request); - g_free (xoauth_param); - g_free (access_token); - g_free (access_token_secret); - return ret; -} diff --git a/src/goabackend/goaimapauthoauth.h b/src/goabackend/goaimapauthoauth.h deleted file mode 100644 index 746c442..0000000 --- a/src/goabackend/goaimapauthoauth.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) -#error "Only <goabackend/goabackend.h> can be included directly." -#endif - -#ifndef __GOA_IMAP_AUTH_OAUTH_H__ -#define __GOA_IMAP_AUTH_OAUTH_H__ - -#include <goabackend/goabackendtypes.h> - -G_BEGIN_DECLS - -#define GOA_TYPE_IMAP_AUTH_OAUTH (goa_imap_auth_oauth_get_type ()) -#define GOA_IMAP_AUTH_OAUTH(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOA_TYPE_IMAP_AUTH_OAUTH, GoaImapAuthOAuth)) -#define GOA_IS_IMAP_AUTH_OAUTH(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOA_TYPE_IMAP_AUTH_OAUTH)) - - -GType goa_imap_auth_oauth_get_type (void) G_GNUC_CONST; -GoaImapAuth *goa_imap_auth_oauth_new (GoaOAuthProvider *provider, - GoaObject *object, - const gchar *request_uri); - -G_END_DECLS - -#endif /* __GOA_IMAP_AUTH_OAUTH_H__ */ diff --git a/src/goabackend/goaimapclient.c b/src/goabackend/goaimapclient.c deleted file mode 100644 index 4d413d0..0000000 --- a/src/goabackend/goaimapclient.c +++ /dev/null @@ -1,704 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#include "config.h" -#include <glib/gi18n-lib.h> -#include <stdlib.h> - -#include "goalogging.h" -#include "goaimapauth.h" -#include "goaimapclient.h" - -/* The timeout used for non-IDLE commands */ -#define COMMAND_TIMEOUT_SEC 30 - -/** - * GoaImapClient: - * - * The #GoaImapClient structure contains only private data and should - * only be accessed using the provided API. - */ -struct _GoaImapClient -{ - /*< private >*/ - GObject parent_instance; - - /* The remaining data members are related to the running session - */ - GSocketClient *sc; - GSocketConnection *c; - GDataInputStream *dis; - GDataOutputStream *dos; - - /* counter used used for generating command tags */ - guint tag; - - GMutex *lock; -}; - -typedef struct _GoaImapClientClass GoaImapClientClass; - -struct _GoaImapClientClass -{ - GObjectClass parent_class; - void (*untagged_response) (GoaImapClient *client, - const gchar *response); -}; - -/** - * SECTION:goaimapclient - * @title: GoaImapClient - * @short_description: A simple IMAP client - * - * #GoaImapClient provides a way to talk to - * <ulink url="http://tools.ietf.org/html/rfc3501">IMAP</ulink> - * servers. - */ - -enum -{ - UNTAGGED_RESPONSE_SIGNAL, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -G_DEFINE_TYPE (GoaImapClient, goa_imap_client, G_TYPE_OBJECT); - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -goa_imap_client_finalize (GObject *object) -{ - GoaImapClient *client = GOA_IMAP_CLIENT (object); - - g_clear_object (&client->sc); - g_clear_object (&client->c); - g_clear_object (&client->dis); - g_clear_object (&client->dos); - g_mutex_free (client->lock); - - G_OBJECT_CLASS (goa_imap_client_parent_class)->finalize (object); -} - -static void -goa_imap_client_init (GoaImapClient *client) -{ - client->lock = g_mutex_new (); -} - -static void -goa_imap_client_class_init (GoaImapClientClass *klass) -{ - GObjectClass *gobject_class; - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = goa_imap_client_finalize; - - /** - * GoaImapClient::untagged-response: - * @client: The #GoaImapClient emitting the signal. - * @untagged_response: The untagged response. - * - * Signal emitted every an <ulink - * url="http://tools.ietf.org/html/rfc3501#section-2.2.2">untagged - * response</ulink> has been received. - * - * This signal is emitted in the same thread that calls the - * goa_imap_client_run_command_sync() method. - */ - signals[UNTAGGED_RESPONSE_SIGNAL] = - g_signal_new ("untagged-response", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GoaImapClientClass, untagged_response), - NULL, - NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -/** - * goa_imap_client_new: - * - * Creates a new #GoaImapClient instance. - * - * Typical usage includes connecting to the - * #GoaImapClient::untagged-response signals and then invoking - * goa_imap_client_connect_sync(). - * - * You can then use goa_imap_client_connect_sync(), - * goa_imap_client_idle_sync() and the - * #GoaImapClient::untagged-response handler to interact with - * the IMAP server. If the connection fails then the appropriate error - * e.g. #G_IO_ERROR_TIMED_OUT or %G_IO_ERROR_NETWORK_UNREACHABLE is - * returned. - * - * You can only make a single successful connection with each - * #GoaImapClient instance - just create a new instance if the - * connection breaks and you need to reconnect. - * - * Returns: (transfer full): A #GoaImapClient that should be freed with g_object_unref(). - */ -GoaImapClient * -goa_imap_client_new (void) -{ - return GOA_IMAP_CLIENT (g_object_new (GOA_TYPE_IMAP_CLIENT, NULL)); -} - - -/** - * goa_imap_client_connect_sync: - * @client: A #GoaImapClient. - * @host_and_port: The name and optionally port to connect to. - * @use_tls: Whether TLS should be used. - * @ignore_bad_tls: Whether errors (e.g. %G_TLS_ERROR_BAD_CERTIFICATE) about TLS certificates should be ignored. - * @auth: Object used for authenticating the connection. - * @cancellable: (allow-none): A #GCancellable or %NULL. - * @error: Return location for error or %NULL. - * - * Connects to the IMAP server represented by @host_and_port using - * @auth to authenticate the connection. The calling thread is blocked - * while the operation is pending. - * - * Returns: %TRUE if the connection was established and authentication - * worked, %FALSE if @error is set. - */ -gboolean -goa_imap_client_connect_sync (GoaImapClient *client, - const gchar *host_and_port, - gboolean use_tls, - gboolean ignore_bad_tls, - GoaImapAuth *auth, - GCancellable *cancellable, - GError **error) -{ - gboolean ret; - - g_return_val_if_fail (GOA_IS_IMAP_CLIENT (client), FALSE); - g_return_val_if_fail (host_and_port != NULL, FALSE); - g_return_val_if_fail (GOA_IS_IMAP_AUTH (auth), FALSE); - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - ret = FALSE; - - g_mutex_lock (client->lock); - - if (client->sc != NULL) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_FAILED, - "Already connected"); - goto out; - } - - client->sc = g_socket_client_new (); - if (use_tls) - g_socket_client_set_tls (client->sc, TRUE); - - if (ignore_bad_tls) - { - /* TODO: is it correct to just pass 0? */ - g_socket_client_set_tls_validation_flags (client->sc, 0); - } - - client->c = g_socket_client_connect_to_host (client->sc, - host_and_port, - use_tls ? 993 : 143, - cancellable, - error); - if (client->c == NULL) - goto out; - - /* fail quickly */ - g_socket_set_timeout (g_socket_connection_get_socket (client->c), COMMAND_TIMEOUT_SEC); - - client->dis = g_data_input_stream_new (g_io_stream_get_input_stream (G_IO_STREAM (client->c))); - client->dos = g_data_output_stream_new (g_io_stream_get_output_stream (G_IO_STREAM (client->c))); - g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (client->dis), FALSE); - g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (client->dos), FALSE); - g_data_input_stream_set_newline_type (client->dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); - - /* Authenticate via the passed in auth helper */ - if (!goa_imap_auth_run_sync (auth, - client->dis, - client->dos, - cancellable, - error)) - goto out; - - - ret = TRUE; - - out: - if (!ret) - { - g_clear_object (&client->sc); - g_clear_object (&client->c); - g_clear_object (&client->dis); - g_clear_object (&client->dos); - } - g_mutex_unlock (client->lock); - return ret; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -/** - * goa_imap_client_run_command_sync: - * @client: A #GoaImapClient. - * @command: The command to run. - * @cancellable: A #GCancellable or %NULL. - * @error: Return location for error. - * - * Submits @command to the remote IMAP server and blocks the calling - * thread until a response is received. Do not include a command tag - * in @command - this will automatically be appended. - * - * If the received response starts with <literal>BAD</literal> (a - * <ulink url="http://tools.ietf.org/html/rfc3501#section-7.1.3">protocol-level - * error</ulink>), then @error will be set to %GOA_ERROR_FAILED and - * %NULL is returned. Otherwise the full response string (excluding - * the command tag) is returned. - * - * If @command is <literal>IDLE</literal> (see - * <ulink url="http://tools.ietf.org/html/rfc2177">RFC 2177</ulink>) - * and @cancellable is cancelled, the continuation string - * <literal>DONE</literal> is written out automatically. - * While this method <emphasis>can</emphasis> be used for to submit - * the <literal>IDLE</literal> IMAP command, the - * goa_imap_client_idle_sync() method should be used instead. - * - * The timeout on the underlying socket will be set to 30 seconds - * except for the the <literal>IDLE</literal> command which never - * times out. - * - * Note that #GoaImapClient::untagged-response signals are - * emitted in the <emphasis role="strong">same</emphasis> thread that - * you call this method from - not the - * <link linkend="g-main-context-push-thread-default">thread-default main loop</link> - * of the thread that @client was constructed in, as one - * would except. - * - * Returns: The response or %NULL if error is set. - */ -gchar * -goa_imap_client_run_command_sync (GoaImapClient *client, - const gchar *command, - GCancellable *cancellable, - GError **error) -{ - gchar *s; - gchar *tag; - gchar *ret; - GString *response; - gsize len; - gboolean is_idle_command; - gboolean idle_has_sent_done; - GError *local_error; - - g_return_val_if_fail (GOA_IS_IMAP_CLIENT (client), NULL); - g_return_val_if_fail (command != NULL, NULL); - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - s = NULL; - tag = NULL; - response = NULL; - ret = NULL; - is_idle_command = FALSE; - idle_has_sent_done = FALSE; - - g_mutex_lock (client->lock); - - if (client->sc == NULL) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_FAILED, - "Not yet connected"); - goto out; - } - - if (g_strcmp0 (command, "IDLE") == 0) - is_idle_command = TRUE; - - /* select a timeout */ - if (is_idle_command) - { - /* never time out */ - g_socket_set_timeout (g_socket_connection_get_socket (client->c), 0); - } - else - { - /* fail quickly */ - g_socket_set_timeout (g_socket_connection_get_socket (client->c), COMMAND_TIMEOUT_SEC); - } - - tag = g_strdup_printf ("T%05d ", client->tag++); - s = g_strconcat (tag, command, "\r\n", NULL); - goa_debug ("Submitting command `%s'", s); - if (!g_data_output_stream_put_string (client->dos, s, cancellable, error)) - { - g_prefix_error (error, "Error putting string: "); - g_free (s); - goto out; - } - g_free (s); - - response = g_string_new (NULL); - again: - local_error = NULL; - s = g_data_input_stream_read_line (client->dis, NULL, cancellable, &local_error); - goa_debug ("Received response `%s'", s); - if (s == NULL) - { - if (local_error != NULL) - { - g_prefix_error (&local_error, "Error reading line: "); - /* if doing an IDLE that was cancelled, write the continuation string - * anyway, ignoring the cancellable - */ - if ((local_error->domain == G_IO_ERROR && local_error->code == G_IO_ERROR_CANCELLED) && is_idle_command) - { - if (!g_data_output_stream_put_string (client->dos, "DONE\r\n", NULL, error)) - { - /* if this fails, ignore the cancelled error */ - g_error_free (local_error); - g_prefix_error (error, "Error putting IDLE continuation string: "); - goto out; - } - /* TODO: this way we're ignoring the response to the IDLE command we just - * fired off.. it's not a problem per se, but it's annoying to see in - * debug output... we could sit around and wait for the response but there's - * really no point in doing so - */ - } - g_propagate_error (error, local_error); - } - else - { - g_set_error (error, GOA_ERROR, GOA_ERROR_FAILED, "No content to read"); - } - goto out; - } - len = strlen (s); - /* So far so good */ - g_string_append_len (response, s, len); - - /* Could be it's a literal string */ - if (len >= 3 && s[len-1] == '}') - { - gint n; - n = len - 2; - while (g_ascii_isdigit (s[n]) && n >= 0) - n--; - if (s[n] == '{') - { - gsize num_read; - gsize lit_len; - gchar *lit; - lit_len = atoi (s + n + 1); - /* Don't blindly allocate any big number of bytes */ - if (lit_len > 10*1024*1024) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_FAILED, - "Refusing to read an additional %" G_GSIZE_FORMAT " bytes for literal string", - lit_len); - g_free (s); - goto out; - } - lit = g_malloc0 (lit_len + 1); - if (!g_input_stream_read_all (G_INPUT_STREAM (client->dis), - lit, - lit_len, - &num_read, - cancellable, - error)) - { - g_free (lit); - g_prefix_error (error, - "Requested %" G_GSIZE_FORMAT " bytes for literal string " - "but only read %" G_GSSIZE_FORMAT ": ", - lit_len, num_read); - g_free (s); - goto out; - } - goa_debug ("Read literal string of %" G_GSIZE_FORMAT " bytes", lit_len); - /* include the original CRLF, then the literal string */ - g_string_append (response, "\r\n"); - g_string_append_len (response, lit, lit_len); - g_free (lit); - g_free (s); - /* then keep reading */ - goto again; - } - } - - if (g_str_has_prefix (response->str, tag)) - { - gint tag_len; - tag_len = strlen (tag); - if (g_str_has_prefix (response->str + tag_len, "BAD")) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_FAILED, - "BAD response to `%s': %s", - command, - response->str + tag_len + 4); - goto out; - } - ret = g_strdup (response->str + tag_len); - /* TODO: return additional response? */ - goto out; - } - else if (g_str_has_prefix (response->str, "*")) - { - /* untagged */ - g_signal_emit (client, signals[UNTAGGED_RESPONSE_SIGNAL], 0, response->str + 2); - } - else - { - /* TODO: not yet interesting to handle other unhandled responses.. - * Typically these are command continuation requests, see - * - * http://tools.ietf.org/html/rfc3501#section-7.5 - */ - /* g_debug ("unhandled response `%s'", response->str); */ - } - - /* If idling, when we receive real data, put the DONE continuation - * string so the IDLE command will terminate - */ - if (is_idle_command && !g_str_has_prefix (response->str, "+") && !idle_has_sent_done) - { - idle_has_sent_done = TRUE; - if (!g_data_output_stream_put_string (client->dos, "DONE\r\n", cancellable, error)) - { - g_prefix_error (error, "Error putting IDLE continuation string: "); - goto out; - } - } - - /* reset */ - g_string_set_size (response, 0); - goto again; - - out: - if (response != NULL) - g_string_free (response, TRUE); - g_free (tag); - g_mutex_unlock (client->lock); - return ret; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -typedef struct -{ - GoaImapClient *client; - GCancellable *local_cancellable; - gboolean timed_out; -} IdleData; - -static gboolean -timeout_while_idling_cb (gpointer user_data) -{ - IdleData *data = user_data; - data->timed_out = TRUE; - g_cancellable_cancel (data->local_cancellable); - return FALSE; -} - -static gboolean -cancel_in_idle_cb (gpointer user_data) -{ - GCancellable *cancellable = G_CANCELLABLE (user_data); - g_cancellable_cancel (cancellable); - return FALSE; -} - -static void -cancelled_while_idling_cb (GCancellable *cancellable, - gpointer user_data) -{ - IdleData *data = user_data; - - /* cancel in idle because right now calling g_cancellable_cancel() - * in a ::cancelled handler may deadlock, see - * - * https://bugzilla.gnome.org/show_bug.cgi?id=650252 - */ - g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - cancel_in_idle_cb, - g_object_ref (data->local_cancellable), - g_object_unref); -} - -/** - * goa_imap_client_idle_sync: - * @client: A #GoaImapClient. - * @max_idle_seconds: Max number of seconds to idle for. This should be no longer than 29 minutes. - * @cancellable: (allow-none): A #GCancellable or %NULL. - * @error: Return location for error or %NULL. - * - * Method used to sit and wait until something happens to the selected - * mailbox. When a change has been detected this method returns %TRUE. - * - * Otherwise the method simply blocks for @max_idle_seconds (in which - * case %TRUE is also returned) or until @cancellable is cancelled - - * in which case %FALSE is returned and @error is set to - * %G_IO_ERROR_CANCELLED. - * - * If the IMAP server supports the <ulink - * url="http://tools.ietf.org/html/rfc2177">IDLE</ulink> command then - * it is used. Otherwise: TODO: handle servers not using IMAP IDLE. - * - * Note that #GoaImapClient::untagged-response signals are - * emitted in the <emphasis role="strong">same</emphasis> thread that - * you call this method from - not the - * <link linkend="g-main-context-push-thread-default">thread-default main loop</link> - * of the thread that @client was constructed in, as one - * would except. - * - * Returns: %TRUE if the request completed, %FALSE if @error is set. - */ -gboolean -goa_imap_client_idle_sync (GoaImapClient *client, - guint max_idle_seconds, - GCancellable *cancellable, - GError **error) -{ - GError *local_error; - gboolean ret; - gchar *response; - guint timeout_id; - IdleData data; - gulong cancelled_id; - - g_return_val_if_fail (GOA_IS_IMAP_CLIENT (client), FALSE); - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - ret = FALSE; - cancelled_id = 0; - timeout_id = 0; - - data.client = g_object_ref (client); - data.local_cancellable = g_cancellable_new (); - data.timed_out = FALSE; - if (cancellable != NULL) - { - cancelled_id = g_cancellable_connect (cancellable, - G_CALLBACK (cancelled_while_idling_cb), - &data, - NULL); - } - - /* We use the default GMainContext for the wake-up. This might not - * be ideal but the only alternative is to create our own thread. - */ - timeout_id = g_timeout_add_seconds (max_idle_seconds, - timeout_while_idling_cb, - &data); - - /* OK, sit around and wait until the mailbox changes (e.g. new mail - * arriving)... For we use the IMAP IDLE command if it's available, - * see http://tools.ietf.org/html/rfc2177 - * - * (TODO: actually handle IDLE not being available) - */ - local_error = NULL; - response = goa_imap_client_run_command_sync (client, - "IDLE", - data.local_cancellable, - &local_error); - if (response == NULL) - { - if ((local_error->domain == G_IO_ERROR && local_error->code == G_IO_ERROR_CANCELLED) - && data.timed_out) - { - g_error_free (local_error); - } - else - { - g_propagate_error (error, local_error); - goto out; - } - } - else - { - g_free (response); - } - - ret = TRUE; - - out: - if (timeout_id > 0) - g_source_remove (timeout_id); - if (cancelled_id != 0) - g_cancellable_disconnect (cancellable, cancelled_id); - g_object_unref (data.local_cancellable); - g_object_unref (data.client); - return ret; -} - -/** - * goa_imap_client_disconnect_sync: - * @client: A #GoaImapClient. - * @cancellable: (allow-none): A #GCancellable or %NULL. - * @error: Return location for error or %NULL. - * - * Closes the connection used by @client, if any. The calling thread - * is blocked while the operation is pending. - * - * Returns: %TRUE if the connection was closed, %FALSE if @error is set. - */ -gboolean -goa_imap_client_disconnect_sync (GoaImapClient *client, - GCancellable *cancellable, - GError **error) -{ - gboolean ret; - - g_return_val_if_fail (GOA_IS_IMAP_CLIENT (client), FALSE); - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - g_mutex_lock (client->lock); - if (client->c == NULL) - ret = TRUE; - else - ret = g_io_stream_close (G_IO_STREAM (client->c), cancellable, error); - g_mutex_unlock (client->lock); - return ret; -} - diff --git a/src/goabackend/goaimapclient.h b/src/goabackend/goaimapclient.h deleted file mode 100644 index 439c43d..0000000 --- a/src/goabackend/goaimapclient.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) -#error "Only <goabackend/goabackend.h> can be included directly." -#endif - -#ifndef __GOA_IMAP_CLIENT_H__ -#define __GOA_IMAP_CLIENT_H__ - -#include <goabackend/goabackendtypes.h> - -G_BEGIN_DECLS - -#define GOA_TYPE_IMAP_CLIENT (goa_imap_client_get_type ()) -#define GOA_IMAP_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOA_TYPE_IMAP_CLIENT, GoaImapClient)) -#define GOA_IS_IMAP_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOA_TYPE_IMAP_CLIENT)) - -GType goa_imap_client_get_type (void) G_GNUC_CONST; -GoaImapClient *goa_imap_client_new (void); -gboolean goa_imap_client_connect_sync (GoaImapClient *client, - const gchar *host_and_port, - gboolean use_tls, - gboolean ignore_bad_tls, - GoaImapAuth *auth, - GCancellable *cancellable, - GError **error); -gchar *goa_imap_client_run_command_sync (GoaImapClient *client, - const gchar *command, - GCancellable *cancellable, - GError **error); -gboolean goa_imap_client_idle_sync (GoaImapClient *client, - guint max_idle_seconds, - GCancellable *cancellable, - GError **error); -gboolean goa_imap_client_disconnect_sync (GoaImapClient *client, - GCancellable *cancellable, - GError **error); - -// TODO: gint goa_imap_client_get_socket_fd (GoaImapClient *client); - - -G_END_DECLS - -#endif /* __GOA_IMAP_CLIENT_H__ */ diff --git a/src/goabackend/goainternetmail.c b/src/goabackend/goainternetmail.c deleted file mode 100644 index 31e74a2..0000000 --- a/src/goabackend/goainternetmail.c +++ /dev/null @@ -1,1595 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#include "config.h" -#include <glib/gi18n-lib.h> -#include <glib-unix.h> - -#include <rest/oauth-proxy.h> -#include <json-glib/json-glib.h> -#include <stdlib.h> - -#include "goalogging.h" -#include "goaimapauth.h" -#include "goaimapclient.h" -#include "goainternetmail.h" - -/** - * GoaInternetMail: - * - * The #GoaInternetMail structure contains only private data and should - * only be accessed using the provided API. - */ -struct _GoaInternetMail -{ - /*< private >*/ - GoaMailSkeleton parent_instance; - - gboolean imap_ignore_bad_tls; - GoaImapAuth *imap_auth; - - gboolean smtp_ignore_bad_tls; -}; - -typedef struct _GoaInternetMailClass GoaInternetMailClass; - -struct _GoaInternetMailClass -{ - GoaMailSkeletonClass parent_class; -}; - -enum -{ - PROP_0, - PROP_IMAP_IGNORE_BAD_TLS, - PROP_IMAP_AUTH, - PROP_SMTP_IGNORE_BAD_TLS -}; - -/** - * SECTION:goainternetmail - * @title: GoaInternetMail - * @short_description: Implementation of the #GoaMail interface for standards-based Internet Mail. - * - * #GoaInternetMail is an implementation of the #GoaMail D-Bus - * interface for IMAP and SMTP servers. - */ - -static void goa_internet_mail__goa_mail_iface_init (GoaMailIface *iface); - -G_DEFINE_TYPE_WITH_CODE (GoaInternetMail, goa_internet_mail, GOA_TYPE_MAIL_SKELETON, - G_IMPLEMENT_INTERFACE (GOA_TYPE_MAIL, goa_internet_mail__goa_mail_iface_init)); - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -goa_internet_mail_finalize (GObject *object) -{ - GoaInternetMail *mail = GOA_INTERNET_MAIL (object); - - g_object_unref (mail->imap_auth); - - G_OBJECT_CLASS (goa_internet_mail_parent_class)->finalize (object); -} - -static void -goa_internet_mail_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GoaInternetMail *mail = GOA_INTERNET_MAIL (object); - - switch (prop_id) - { - case PROP_IMAP_IGNORE_BAD_TLS: - g_value_set_boolean (value, mail->imap_ignore_bad_tls); - break; - - case PROP_IMAP_AUTH: - g_value_set_object (value, mail->imap_auth); - break; - - case PROP_SMTP_IGNORE_BAD_TLS: - g_value_set_boolean (value, mail->smtp_ignore_bad_tls); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -goa_internet_mail_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GoaInternetMail *mail = GOA_INTERNET_MAIL (object); - - switch (prop_id) - { - case PROP_IMAP_IGNORE_BAD_TLS: - mail->imap_ignore_bad_tls = g_value_get_boolean (value); - break; - - case PROP_IMAP_AUTH: - mail->imap_auth = g_value_dup_object (value); - break; - - case PROP_SMTP_IGNORE_BAD_TLS: - mail->smtp_ignore_bad_tls = g_value_get_boolean (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -goa_internet_mail_init (GoaInternetMail *mail) -{ - /* Ensure D-Bus method invocations run in their own thread */ - g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (mail), - G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); -} - -static void -goa_internet_mail_class_init (GoaInternetMailClass *klass) -{ - GObjectClass *gobject_class; - - gobject_class = G_OBJECT_CLASS (klass); - gobject_class->finalize = goa_internet_mail_finalize; - gobject_class->set_property = goa_internet_mail_set_property; - gobject_class->get_property = goa_internet_mail_get_property; - - g_object_class_install_property (gobject_class, - PROP_IMAP_IGNORE_BAD_TLS, - g_param_spec_boolean ("imap-ignore-bad-tls", - "imap-ignore-bad-tls", - "imap-ignore-bad-tls", - FALSE, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_IMAP_AUTH, - g_param_spec_object ("imap-auth", - "imap-auth", - "imap-auth", - GOA_TYPE_IMAP_AUTH, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, - PROP_SMTP_IGNORE_BAD_TLS, - g_param_spec_boolean ("smtp-ignore-bad-tls", - "smtp-ignore-bad-tls", - "smtp-ignore-bad-tls", - FALSE, - G_PARAM_READABLE | - G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - -} - -/* ---------------------------------------------------------------------------------------------------- */ - -/** - * goa_internet_mail_new: - * @imap_host: The IMAP server. - * @imap_user_name: (allow-none): The user name to use. - * @imap_use_tls: Whether TLS should be used connections to the IMAP server. - * @imap_ignore_bad_tls: Whether errors (e.g. %G_TLS_ERROR_BAD_CERTIFICATE) about TLS certificates while connecting to @imap_host should be ignored. - * @imap_auth: Object used for authenticating the IMAP connection. - * @smtp_host: The SMTP server. - * @smtp_user_name: (allow-none): The user name to use. - * @smtp_use_tls: Whether TLS should be used connections to the SMTP server. - * @smtp_ignore_bad_tls: Whether errors (e.g. %G_TLS_ERROR_BAD_CERTIFICATE) about TLS certificates while connecting to @smtp_host should be ignored. - * - * Creates a new #GoaMail object. - * - * Returns: (type GoaInternetMail): A new #GoaMail instance. - */ -GoaMail * -goa_internet_mail_new (const gchar *imap_host, - const gchar *imap_user_name, - gboolean imap_use_tls, - gboolean imap_ignore_bad_tls, - GoaImapAuth *imap_auth, - const gchar *smtp_host, - const gchar *smtp_user_name, - gboolean smtp_use_tls, - gboolean smtp_ignore_bad_tls) -{ - g_return_val_if_fail (imap_host != NULL, NULL); - return GOA_MAIL (g_object_new (GOA_TYPE_INTERNET_MAIL, - "imap-supported", TRUE, - "imap-host", imap_host, - "imap-user-name", imap_user_name, - "imap-use-tls", imap_use_tls, - "imap-ignore-bad-tls", imap_ignore_bad_tls, - "imap-auth", imap_auth, - "smtp-supported", TRUE, - "smtp-host", smtp_host, - "smtp-user-name", smtp_user_name, - "smtp-use-tls", smtp_use_tls, - "smtp-ignore-bad-tls", smtp_ignore_bad_tls, - NULL)); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -typedef struct -{ - volatile gint ref_count; - - GoaInternetMail *mail; - GoaMailMonitor *monitor; - - /* Used so we can nuke the monitor if the creator vanishes */ - guint name_watcher_id; - - /* Set only when we are connected */ - gchar *spam_folder; - gchar *starred_folder; - - /* Used to communicate with the thread running the IMAP client */ - GCancellable *imap_cancellable; - gboolean imap_request_close; - GMutex *imap_counter_lock; - GCond *imap_counter_cond; - gint imap_num_refreshes; - gint imap_num_connections_failed; -} MonitorData; - -static MonitorData * -monitor_data_ref (MonitorData *data) -{ - g_atomic_int_inc (&data->ref_count); - return data; -} - -static void -monitor_data_unref (MonitorData *data) -{ - if (g_atomic_int_dec_and_test (&data->ref_count)) - { - g_clear_object (&data->mail); - g_clear_object (&data->monitor); - if (data->name_watcher_id) - g_bus_unwatch_name (data->name_watcher_id); - - g_free (data->spam_folder); - g_free (data->starred_folder); - - g_clear_object (&data->imap_cancellable); - if (data->imap_counter_lock != NULL) - g_mutex_free (data->imap_counter_lock); - if (data->imap_counter_cond != NULL) - g_cond_free (data->imap_counter_cond); - g_slice_free (MonitorData, data); - } -} - -static void -nuke_monitor (MonitorData *data) -{ - /* unexport the D-Bus object */ - g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (data->monitor)); - /* nuke the running IMAP client */ - data->imap_request_close = TRUE; - g_mutex_lock (data->imap_counter_lock); - g_cancellable_cancel (data->imap_cancellable); - g_mutex_unlock (data->imap_counter_lock); - monitor_data_unref (data); -} - -static void -on_monitor_owner_vanished (GDBusConnection *connection, - const gchar *name, - gpointer user_data) -{ - MonitorData *data = user_data; - /* yippee ki yay motherfucker */ - nuke_monitor (data); -} - -/* ---------------------------------------------------------------------------------------------------- */ - -typedef struct -{ - MonitorData *monitor_data; - gint num_exists; - gint last_num_exists; - - gint uidvalidity; - - gchar **caps; - gchar *caps_string; -} ImapClientData; - -static gboolean -imap_client_has_capability (ImapClientData *data, - const gchar *capability) -{ - guint n; - gboolean ret; - - ret = FALSE; - - for (n = 0; data->caps != NULL && data->caps[n] != NULL; n++) - { - if (g_strcmp0 (data->caps[n], capability) == 0) - { - ret = TRUE; - goto out; - } - } - out: - return ret; -} - -static gboolean -parse_int (const gchar *s, - gint *out_result) -{ - gboolean ret; - gchar *endp; - gint result; - - g_return_val_if_fail (s != NULL, FALSE); - - ret = FALSE; - result = strtol (s, &endp, 0); - if (result == 0 && endp == s) - goto out; - - if (out_result != NULL) - *out_result = result; - - ret = TRUE; - - out: - return ret; -} - -static gboolean -fetch_check (const gchar *data, - guint *pos, - const gchar *key) -{ - gsize key_len; - gboolean ret; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (pos != NULL, FALSE); - g_return_val_if_fail (key != NULL, FALSE); - - ret = FALSE; - - key_len = strlen (key); - if (g_ascii_strncasecmp (data + *pos, key, key_len) == 0 && data[*pos + key_len] == ' ') - { - ret = TRUE; - *pos += key_len + 1; - goto out; - } - out: - return ret; -} - -static gchar ** -fetch_parenthesized_list (const gchar *data, - guint *pos) -{ - gchar **ret; - gchar *s; - guint start_pos; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (pos != NULL, FALSE); - - ret = NULL; - - if (data[*pos] != '(') - goto out; - *pos += 1; - start_pos = *pos; - - while (data[*pos] != ')' && data[*pos] != '\0') - *pos += 1; - if (data[*pos] != ')') - goto out; - - s = g_strndup (data + start_pos, *pos - start_pos); - ret = g_strsplit (s, " ", -1); - g_free (s); - - *pos += 1; - - out: - return ret; -} - -static gchar * -fetch_string (const gchar *data, - guint *pos) -{ - gchar *ret; - guint start_pos; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (pos != NULL, FALSE); - - ret = NULL; - - start_pos = *pos; - - while (data[*pos] != ' ' && data[*pos] != ')' && data[*pos] != '\0') - *pos += 1; - - ret = g_strndup (data + start_pos, *pos - start_pos); - - return ret; -} - -static gboolean -fetch_int (const gchar *data, - guint *pos, - gint *out_value) -{ - gchar *str_value; - gboolean ret; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (pos != NULL, FALSE); - g_return_val_if_fail (out_value != NULL, FALSE); - - str_value = NULL; - ret = FALSE; - - str_value = fetch_string (data, pos); - if (str_value == NULL) - goto out; - - if (!parse_int (str_value, out_value)) - goto out; - - ret = TRUE; - - out: - g_free (str_value); - return ret; -} - -static gchar * -fetch_quoted_string (const gchar *data, - guint *pos) -{ - gchar *ret; - guint start_pos; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (pos != NULL, FALSE); - - ret = NULL; - - if (data[*pos] != '"') - goto out; - *pos += 1; - - start_pos = *pos; - - while (data[*pos] != '"' && data[*pos] != '\0') - *pos += 1; - - ret = g_strndup (data + start_pos, *pos - start_pos); - - *pos += 1; - - out: - return ret; -} - -static gchar * -fetch_literal_string (const gchar *data, - guint *pos, - guint *out_len) -{ - gchar *ret; - guint start_pos; - guint len; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (pos != NULL, FALSE); - - ret = NULL; - - start_pos = *pos; - - if (data[*pos] != '{') - goto out; - *pos += 1; - while (g_ascii_isdigit (data[*pos])) - *pos += 1; - if (strncmp (data + *pos, "}\r\n", 3) != 0) - goto out; - *pos += 3; - - if (!parse_int (data + start_pos + 1, (gint*) &len)) - goto out; - - ret = g_strndup (data + *pos, len); - *pos += len; - - if (out_len != NULL) - *out_len = len; - - out: - return ret; -} - -/* TODO: try a little harder to make this a conformant RFC822 parser */ -static GHashTable * -parse_rfc822_headers (const gchar *rfc822_headers) -{ - GHashTable *ret; - gchar **lines; - guint n; - - ret = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); - lines = g_strsplit (rfc822_headers, "\r\n", -1); - for (n = 0; lines[n] != NULL; n++) - { - const gchar *line = lines[n]; - const gchar *s; - - if (line[0] == '\0') - continue; - - s = strstr (line, ": "); - if (s != NULL) - { - gchar *key; - gchar *value; - key = g_strndup (line, s - line); - value = g_strdup (s + 2); - g_hash_table_insert (ret, key, value); - } - else - { - goa_warning ("%s: ignoring mysterious line `%s' whilst parsing `%s'", - G_STRFUNC, line, rfc822_headers); - } - } - g_strfreev (lines); - - return ret; -} - -/* Simple FETCH response parser only handling a subset of FETCH - * responses, see - * - * http://tools.ietf.org/html/rfc3501#section-7.4.2 - * - * for more details. - */ -static void -imap_client_handle_fetch_response (ImapClientData *data, - guint message_seqnum, - const gchar *params) -{ - guint n; - gboolean parsed; - gboolean has_uid; - gint uid; - gchar *rfc822_headers; - guint rfc822_headers_len; - gchar *excerpt; - guint excerpt_len; - GHashTable *headers; - const gchar *from_header; - const gchar *subject_header; - gchar *uid_str; - gchar *uri; - /* GVariantBuilder extras_builder; */ - - g_return_if_fail (message_seqnum >= 1); - g_return_if_fail (params != NULL); - - uid = 0; - has_uid = FALSE; - excerpt = NULL; - rfc822_headers = NULL; - headers = NULL; - uid_str = NULL; - uri = NULL; - parsed = FALSE; - - if (params[0] != '(') - goto out; - n = 1; - while (params[n] != ')' && params[n] != '\0') - { - if (fetch_check (params, &n, "UID")) - { - if (!fetch_int (params, &n, &uid)) - goto out; - has_uid = TRUE; - } - else if (fetch_check (params, &n, "BODY[HEADER.FIELDS (Date From To Cc Subject)]")) - { - rfc822_headers = fetch_literal_string (params, &n, &rfc822_headers_len); - if (rfc822_headers == NULL) - goto out; - } - else if (fetch_check (params, &n, "BODY[TEXT]<0>")) - { - excerpt = fetch_literal_string (params, &n, &excerpt_len); - if (excerpt == NULL) - goto out; - } - else - { - /* Don't know how to handle unknown params so fail completely */ - goto out; - } - /* advance to next value in FETCH response list, if any */ - while (params[n] == ' ') - n++; - } - - if (!has_uid || rfc822_headers == NULL || excerpt == NULL) - goto out; - - /* OK, message is valid */ - parsed = TRUE; - - uid_str = g_strdup_printf ("%" G_GUINT64_FORMAT, - ((guint64) data->uidvalidity << 32) | ((guint64) uid)); - headers = parse_rfc822_headers (rfc822_headers); - from_header = g_hash_table_lookup (headers, "From"); - subject_header = g_hash_table_lookup (headers, "Subject"); - if (from_header == NULL) - from_header = ""; - if (subject_header == NULL) - subject_header = ""; - - /* TODO: set this */ - uri = g_strdup (""); - - /* extras is currently unused (and not currently in the D-Bus signature) */ - /* g_variant_builder_init (&extras_builder, G_VARIANT_TYPE_VARDICT); */ - - /* Emit D-Bus message */ - goa_mail_monitor_emit_message_received (data->monitor_data->monitor, - uid_str, - from_header, - subject_header, - excerpt, - uri, - data->monitor_data->spam_folder != NULL, - data->monitor_data->starred_folder != NULL); - /* g_variant_builder_end (&extras_builder)); */ - out: - if (!parsed) - { - /* Use goa_warning() since we want bug-reports in order to improve the FETCH parser */ - goa_warning ("Failed parsing FETCH response for message with sequence number %d and parameters `%s'. " - "Please report this to %s", - message_seqnum, - params, - PACKAGE_BUGREPORT); - } - g_free (uri); - g_free (uid_str); - if (headers != NULL) - g_hash_table_unref (headers); - g_free (rfc822_headers); - g_free (excerpt); -} - -static void -imap_client_handle_xlist_response (ImapClientData *data, - const gchar *response) -{ - guint pos; - gchar **flags; - gchar *delimiter; - gchar *name; - gboolean is_spam; - gboolean is_starred; - guint n; - - flags = NULL; - delimiter = NULL; - name = NULL; - is_spam = FALSE; - is_starred = FALSE; - - /* http://code.google.com/apis/gmail/imap/#xlist and - * http://tools.ietf.org/html/rfc3501#section-7.2.2 - * - * Example: XLIST (\HasChildren \HasNoChildren \Starred) "/" "[Gmail]/Starred" - */ - pos = sizeof "XLIST " - 1; - flags = fetch_parenthesized_list (response, &pos); - if (flags == NULL) - { - goa_warning ("Error extracting flags from XLIST response `%s'", response); - goto out; - } - pos += 1; - delimiter = fetch_quoted_string (response, &pos); - if (delimiter == NULL) - { - goa_warning ("Error extracting delimiter from XLIST response `%s'", response); - goto out; - } - pos += 1; - name = fetch_quoted_string (response, &pos); - if (name == NULL) - { - goa_warning ("Error extracting name from XLIST response `%s'", response); - goto out; - } - - for (n = 0; flags[n] != NULL; n++) - { - if (g_strcmp0 (flags[n], "\\Spam") == 0) - is_spam = TRUE; - else if (g_strcmp0 (flags[n], "\\Starred") == 0) - is_starred = TRUE; - } - - if (is_spam) - { - goa_info ("Setting the Spam folder to `%s'", name); - g_free (data->monitor_data->spam_folder); - data->monitor_data->spam_folder = g_strdup (name); - } - else if (is_starred) - { - goa_info ("Setting the Starred folder to `%s'", name); - g_free (data->monitor_data->starred_folder); - data->monitor_data->starred_folder = g_strdup (name); - } - - out: - g_strfreev (flags); - g_free (delimiter); - g_free (name); -} - -static void -imap_client_on_untagged_response (GoaImapClient *client, - const gchar *response, - gpointer user_data) -{ - ImapClientData *data = user_data; - gchar s[64+1]; - gint i; - gint n; - - if (sscanf (response, "%d %64s", &i, s) == 2 && g_strcmp0 (s, "EXISTS") == 0) - { - data->num_exists = i; - } - else if (sscanf (response, "%d %64s", &i, s) == 2 && g_strcmp0 (s, "EXPUNGE") == 0) - { - /* See http://tools.ietf.org/html/rfc3501#section-7.4.1 */ - data->num_exists -= 1; - data->last_num_exists -= 1; - } - else if (sscanf (response, "OK [UIDVALIDITY %d]", &i) == 1) - { - data->uidvalidity = i; - } - else if (sscanf (response, "%d %64s%n", &i, s, &n) == 2 && g_strcmp0 (s, "FETCH") == 0) - { - const gchar *params; - params = response + n; - while (g_ascii_isspace (*params)) - params++; - imap_client_handle_fetch_response (data, i, params); - } - else if (g_str_has_prefix (response, "CAPABILITY ")) - { - /* http://tools.ietf.org/html/rfc3501#section-7.2.1 */ - g_strfreev (data->caps); - g_free (data->caps_string); - data->caps_string = g_strdup (response + sizeof "CAPABILITY " - 1); - data->caps = g_strsplit (data->caps_string, " ", -1); - } - else if (g_str_has_prefix (response, "XLIST ")) - { - imap_client_handle_xlist_response (data, response); - } - else - { - goa_debug ("unhandled untagged response `%s'", response); - } -} - -static void -imap_client_sync_single (ImapClientData *data) -{ - GError *error; - gchar *response; - GoaImapClient *client; - - g_strfreev (data->caps); - g_free (data->caps_string); - data->caps = NULL; - data->caps_string = NULL; - - /* Get ourselves an IMAP client and connect to the server */ - data->num_exists = -1; - client = goa_imap_client_new (); - - g_signal_connect (client, - "untagged-response", - G_CALLBACK (imap_client_on_untagged_response), - data); - - error = NULL; - if (!goa_imap_client_connect_sync (client, - goa_mail_get_imap_host (GOA_MAIL (data->monitor_data->mail)), - goa_mail_get_imap_use_tls (GOA_MAIL (data->monitor_data->mail)), - data->monitor_data->mail->imap_ignore_bad_tls, - data->monitor_data->mail->imap_auth, - NULL, /* GCancellable */ - &error)) - goto out; - - /* Houston, we have a connection */ - goa_mail_monitor_set_connected (data->monitor_data->monitor, TRUE); - - /* Request capabilities unless we received them already */ - if (data->caps == NULL) - { - /* http://tools.ietf.org/html/rfc3501#section-6.1.1 */ - error = NULL; - response = goa_imap_client_run_command_sync (client, - "CAPABILITY", - NULL, /* GCancellable */ - &error); - if (response == NULL) - goto out; - g_free (response); - } - if (!imap_client_has_capability (data, "IMAP4rev1")) - { - g_set_error (&error, - GOA_ERROR, - GOA_ERROR_FAILED, - "Expected capability IMAP4rev1 but server reported: %s", - data->caps_string); - goto out; - } - goa_info ("IMAP Server reported capabilities: %s", data->caps_string); - - /* If available, use the XLIST command to find the Spam and Starred folders */ - if (imap_client_has_capability (data, "XLIST")) - { - /* http://code.google.com/apis/gmail/imap/#xlist and - * http://tools.ietf.org/html/rfc3501#section-6.3.8 - */ - error = NULL; - response = goa_imap_client_run_command_sync (client, - "XLIST \"\" \"*\"", - NULL, /* GCancellable */ - &error); - if (response == NULL) - goto out; - g_free (response); - } - - /* First, select the INBOX - this is guaranteed to emit the EXISTS untagged response */ - error = NULL; - response = goa_imap_client_run_command_sync (client, - "SELECT INBOX", - NULL, /* GCancellable */ - &error); - if (response == NULL) - goto out; - g_free (response); - - if (data->num_exists == -1) - { - g_set_error (&error, - GOA_ERROR, - GOA_ERROR_FAILED, - "Expected EXISTS untagged response for SELECT but received none"); - goto out; - } - data->last_num_exists = data->num_exists; - - /* This is the main loop where we idle, then refresh, then idle, - * then refresh again and around and around she goes... - */ - while (TRUE) - { - /* If the connection is closed/severed, this is the way we find out since - * the IDLE command submitted above disables timeouts - */ - response = goa_imap_client_run_command_sync (client, - "NOOP", - NULL, /* GCancellable */ - &error); - if (response == NULL) - goto out; - g_free (response); - - goa_debug ("EXISTS delta: %d", data->num_exists - data->last_num_exists); - - /* Fetch newly received messages, if any - the D-Bus signal will - * get emitted from imap_client_handle_fetch_response() that - * will be called while the command is pending - */ - if (data->num_exists > data->last_num_exists) - { - GString *request_str; - guint num_new_messages; - guint n; - - num_new_messages = data->num_exists - data->last_num_exists; - request_str = g_string_new ("FETCH "); - for (n = 0; n < num_new_messages; n++) - { - if (n > 0) - g_string_append_c (request_str, ','); - g_string_append_printf (request_str, "%d", data->last_num_exists + 1 + n); - } - - g_string_append (request_str, - " (" - "UID " - "BODY.PEEK[HEADER.FIELDS (Date From To Cc Subject)] " - "BODY.PEEK[TEXT]<0.1000>" - ")"); - error = NULL; - response = goa_imap_client_run_command_sync (client, - request_str->str, - NULL, /* GCancellable */ - &error); - g_string_free (request_str, TRUE); - if (response == NULL) - goto out; - g_free (response); - } - data->last_num_exists = data->num_exists; - - /* Wake up waiters */ - g_mutex_lock (data->monitor_data->imap_counter_lock); - data->monitor_data->imap_num_refreshes += 1; - g_cond_broadcast (data->monitor_data->imap_counter_cond); - g_mutex_unlock (data->monitor_data->imap_counter_lock); - - goa_debug ("Idling"); - - /* Never idle for more than 25 minutes cf. the recommendation - * in RFC 2177: http://tools.ietf.org/html/rfc2177 - */ - error = NULL; - if (!goa_imap_client_idle_sync (client, - 25 * 60, - data->monitor_data->imap_cancellable, - &error)) - { - if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED) - { - g_cancellable_reset (data->monitor_data->imap_cancellable); - g_error_free (error); - error = NULL; - } - else - { - goto out; - } - } - - /* Check if asked to close */ - if (data->monitor_data->imap_request_close) - goto out; - - } /* Main loop */ - - out: - /* We no longer have a connection */ - goa_mail_monitor_set_connected (data->monitor_data->monitor, FALSE); - - /* Wake up waiters */ - g_mutex_lock (data->monitor_data->imap_counter_lock); - data->monitor_data->imap_num_connections_failed += 1; - g_cond_broadcast (data->monitor_data->imap_counter_cond); - g_mutex_unlock (data->monitor_data->imap_counter_lock); - - if (error != NULL) - { - goa_info ("IMAP connection failed: error: %s (%s, %d)", - error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - } - else - { - goa_info ("IMAP connection closed"); - } - g_signal_handlers_disconnect_by_func (client, - G_CALLBACK (imap_client_on_untagged_response), - data); - error = NULL; - if (!goa_imap_client_disconnect_sync (client, - NULL, /* GCancellable */ - &error)) - { - goa_warning ("Error closing connection: %s (%s, %d)", - error->message, g_quark_to_string (error->domain), error->code); - g_error_free (error); - } - g_object_unref (client); -} - -static void -imap_client_sync (MonitorData *data) -{ - ImapClientData *imap_data; - - imap_data = g_slice_new0 (ImapClientData); - imap_data->monitor_data = monitor_data_ref (data); - - goa_info ("Using thread for IMAP client at %s for account %s", - goa_mail_get_imap_host (GOA_MAIL (data->mail)), - g_dbus_object_get_object_path (g_dbus_interface_get_object (G_DBUS_INTERFACE (data->mail)))); - - while (TRUE) - { - GPollFD poll_fd; - - goa_info ("Connecting to IMAP server at %s for account %s", - goa_mail_get_imap_host (GOA_MAIL (data->mail)), - g_dbus_object_get_object_path (g_dbus_interface_get_object (G_DBUS_INTERFACE (data->mail)))); - - /* tries connecting - blocks until the connection is closed */ - imap_client_sync_single (imap_data); - - if (data->imap_request_close) - goto out; - - goa_info ("Not connected anymore. Sleeping until Refresh() is called..."); - - /* Wait to get woken up */ - if (g_cancellable_make_pollfd (data->imap_cancellable, &poll_fd)) - { - gint poll_ret; - do - { - poll_ret = g_poll (&poll_fd, 1, -1); - } - while (poll_ret == -1 && errno == EINTR); - g_cancellable_release_fd (data->imap_cancellable); - g_cancellable_reset (data->imap_cancellable); - } - - if (data->imap_request_close) - goto out; - } - - out: - - /* Wake up waiters (if any) */ - g_mutex_lock (data->imap_counter_lock); - data->imap_num_refreshes = -1; - data->imap_num_connections_failed = -1; - g_cond_broadcast (data->imap_counter_cond); - g_mutex_unlock (data->imap_counter_lock); - - goa_info ("Exiting IMAP client thread"); - - monitor_data_unref (imap_data->monitor_data); - g_strfreev (imap_data->caps); - g_free (imap_data->caps_string); - g_slice_free (ImapClientData, imap_data); -} - - -/* ---------------------------------------------------------------------------------------------------- */ - -/* runs in thread dedicated to the method invocation */ -static gboolean -monitor_on_handle_refresh (GoaMailMonitor *monitor, - GDBusMethodInvocation *invocation, - gpointer user_data) -{ - MonitorData *data = user_data; - gint orig_imap_num_connections_failed; - gint orig_imap_num_refreshes; - gboolean refreshed, connection_failed, closed; - gint num_attempts; - - monitor_data_ref (data); - - num_attempts = 0; - again: - g_mutex_lock (data->imap_counter_lock); - orig_imap_num_refreshes = data->imap_num_refreshes; - orig_imap_num_connections_failed = data->imap_num_connections_failed; - /* Wake up the IMAP client thread - this will cause either a connection - * failure or a refresh - */ - g_cancellable_cancel (data->imap_cancellable); - g_cond_wait (data->imap_counter_cond, data->imap_counter_lock); - num_attempts += 1; - - closed = (orig_imap_num_refreshes == -1); - refreshed = (orig_imap_num_refreshes != data->imap_num_refreshes); - connection_failed = (orig_imap_num_connections_failed != data->imap_num_connections_failed); - g_mutex_unlock (data->imap_counter_lock); - - g_warn_if_fail (refreshed || connection_failed || closed); - - if (refreshed) - { - goa_mail_monitor_complete_refresh (monitor, invocation); - goto out; - } - - if (closed) - { - g_dbus_method_invocation_return_error (invocation, - GOA_ERROR, - GOA_ERROR_FAILED, - "The monitor was closed"); - goto out; - } - - /* Try at least three times to cope with broken connections */ - if (connection_failed && num_attempts < 3) - goto again; - - if (connection_failed) - { - g_dbus_method_invocation_return_error (invocation, - GOA_ERROR, - GOA_ERROR_FAILED, - "Failed to reconnect (tried %d times)", - num_attempts); - goto out; - } - - /* should never end up here but if we do, make sure - * the bug reporters can give us something useful - */ - goa_warning ("Unexpected state while trying to refresh: refreshed=%d connection_failed=%d closed=%d num_attempts=%d", - refreshed, connection_failed, closed, num_attempts); - g_dbus_method_invocation_return_error (invocation, - GOA_ERROR, - GOA_ERROR_FAILED, - "Failed with unexpected state: " - "refreshed=%d connection_failed=%d closed=%d num_attempts=%d", - refreshed, connection_failed, closed, num_attempts); - - out: - monitor_data_unref (data); - return TRUE; /* invocation was handled */ -} - -/* runs in thread dedicated to the method invocation */ -static gboolean -monitor_on_handle_close (GoaMailMonitor *monitor, - GDBusMethodInvocation *invocation, - gpointer user_data) -{ - MonitorData *data = user_data; - /* yippee ki yay motherfucker */ - nuke_monitor (data); - goa_mail_monitor_complete_close (monitor, invocation); - return TRUE; /* invocation was handled */ -} - -/* runs in thread dedicated to the method invocation */ -static gboolean -monitor_on_handle_simulate_message_received (GoaMailMonitor *monitor, - GDBusMethodInvocation *invocation, - const gchar *uid, - const gchar *from, - const gchar *subject, - const gchar *excerpt, - const gchar *uri, - gboolean can_be_marked_as_spam, - gboolean can_be_starred, - gpointer user_data) -{ - goa_mail_monitor_emit_message_received (monitor, uid, from, subject, excerpt, uri, can_be_marked_as_spam, can_be_starred); - goa_mail_monitor_complete_simulate_message_received (monitor, invocation); - return TRUE; /* invocation was handled */ -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -on_untagged_response_uidvalidity (GoaImapClient *client, - const gchar *response, - gpointer user_data) -{ - guint *uidvalidity = user_data; - guint n; - - if (sscanf (response, "OK [UIDVALIDITY %d]", &n) == 1) - *uidvalidity = n; -} - - -typedef gboolean (*ImapHelperFunc) (GoaImapClient *client, - gpointer user_data, - GError **error); - -static gboolean -imap_helper (const gchar *imap_host, - gboolean imap_use_tls, - gboolean imap_ignore_bad_tls, - GoaImapAuth *auth, - guint uidvalidity, - ImapHelperFunc func, - gpointer func_user_data, - GError **error) -{ - GoaImapClient *client; - gchar *response; - guint read_uidvalidity; - gboolean ret; - - client = NULL; - read_uidvalidity = 0; - ret = FALSE; - - client = goa_imap_client_new (); - g_signal_connect (client, - "untagged-response", - G_CALLBACK (on_untagged_response_uidvalidity), - &read_uidvalidity); - if (!goa_imap_client_connect_sync (client, - imap_host, - imap_use_tls, - imap_ignore_bad_tls, - auth, - NULL, /* GCancellable */ - error)) - goto out; - - response = goa_imap_client_run_command_sync (client, - "SELECT INBOX", - NULL, /* GCancellable */ - error); - if (response == NULL) - goto out; - g_free (response); - - if (read_uidvalidity != uidvalidity) - { - g_set_error (error, - GOA_ERROR, - GOA_ERROR_FAILED, - "UID validity does not match"); - goto out; - } - - if (!func (client, func_user_data, error)) - goto out; - - ret = TRUE; - - out: - if (client != NULL) - { - GError *local_error; - - g_signal_handlers_disconnect_by_func (client, - G_CALLBACK (on_untagged_response_uidvalidity), - &uidvalidity); - - local_error = NULL; - if (!goa_imap_client_disconnect_sync (client, - NULL, /* GCancellable */ - &local_error)) - { - goa_warning ("Error closing connection: %s (%s, %d)", - local_error->message, g_quark_to_string (local_error->domain), local_error->code); - g_error_free (local_error); - } - g_object_unref (client); - } - - return ret; -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static gboolean -add_star_func (GoaImapClient *client, - gpointer user_data, - GError **error) -{ - const gchar *request = user_data; - gchar *response; - response = goa_imap_client_run_command_sync (client, - request, - NULL, /* GCancellable */ - error); - if (response == NULL) - return FALSE; - g_free (response); - return TRUE; -} - -/* runs in thread dedicated to the method invocation */ -static gboolean -monitor_on_handle_add_star (GoaMailMonitor *monitor, - GDBusMethodInvocation *invocation, - const gchar *message_uid_as_str, - gpointer user_data) -{ - MonitorData *data = user_data; - GError *error; - guint64 message_uid; - gchar *request; - gchar *endp; - - request = NULL; - error = NULL; - - monitor_data_ref (data); - - if (data->starred_folder == NULL) - { - error = g_error_new (GOA_ERROR, - GOA_ERROR_FAILED, - "Starred folder not found"); - goto out; - } - message_uid = strtoll (message_uid_as_str, &endp, 10); - if (*endp != '\0' || endp == message_uid_as_str) - { - error = g_error_new (GOA_ERROR, - GOA_ERROR_FAILED, - "Given message UID is not valid"); - goto out; - } - - request = g_strdup_printf ("UID COPY %d %s", - (gint) (message_uid & 0xffffffff), - data->starred_folder); - imap_helper (goa_mail_get_imap_host (GOA_MAIL (data->mail)), - goa_mail_get_imap_use_tls (GOA_MAIL (data->mail)), - data->mail->imap_ignore_bad_tls, - data->mail->imap_auth, - (message_uid >> 32), - add_star_func, - request, - &error); - out: - if (error == NULL) - goa_mail_monitor_complete_add_star (monitor, invocation); - else - g_dbus_method_invocation_take_error (invocation, error); - g_free (request); - monitor_data_unref (data); - return TRUE; /* invocation was handled */ -} - -/* ---------------------------------------------------------------------------------------------------- */ - - -static gboolean -mark_as_spam_func (GoaImapClient *client, - gpointer user_data, - GError **error) -{ - const gchar **requests = user_data; - gboolean ret; - guint n; - - ret = FALSE; - for (n = 0; requests[n] != NULL; n++) - { - gchar *response; - response = goa_imap_client_run_command_sync (client, requests[n], NULL, error); - if (response == NULL) - goto out; - g_free (response); - } - ret = TRUE; - - out: - return ret; -} - -/* runs in thread dedicated to the method invocation */ -static gboolean -monitor_on_handle_mark_as_spam (GoaMailMonitor *monitor, - GDBusMethodInvocation *invocation, - const gchar *message_uid_as_str, - gpointer user_data) -{ - MonitorData *data = user_data; - GError *error; - guint64 message_uid; - gchar **requests; - gchar *endp; - - requests = NULL; - error = NULL; - - monitor_data_ref (data); - - if (data->spam_folder == NULL) - { - error = g_error_new (GOA_ERROR, - GOA_ERROR_FAILED, - "Spam folder not found"); - goto out; - } - message_uid = strtoll (message_uid_as_str, &endp, 10); - if (*endp != '\0' || endp == message_uid_as_str) - { - error = g_error_new (GOA_ERROR, - GOA_ERROR_FAILED, - "Given message UID is not valid"); - goto out; - } - - requests = g_new0 (gchar*, 3); - requests[0] = g_strdup_printf ("UID COPY %d %s", - (gint) (message_uid & 0xffffffff), - data->spam_folder); - requests[1] = g_strdup_printf ("UID STORE %d +FLAGS (\\Deleted)", - (gint) (message_uid & 0xffffffff)); - imap_helper (goa_mail_get_imap_host (GOA_MAIL (data->mail)), - goa_mail_get_imap_use_tls (GOA_MAIL (data->mail)), - data->mail->imap_ignore_bad_tls, - data->mail->imap_auth, - (message_uid >> 32), - mark_as_spam_func, - requests, - &error); - out: - if (error == NULL) - goa_mail_monitor_complete_mark_as_spam (monitor, invocation); - else - g_dbus_method_invocation_take_error (invocation, error); - g_strfreev (requests); - monitor_data_unref (data); - return TRUE; /* invocation was handled */ -} - -/* ---------------------------------------------------------------------------------------------------- */ - -/* runs in thread dedicated to the method invocation */ -static gboolean -handle_create_monitor (GoaMail *_mail, - GDBusMethodInvocation *invocation) -{ - GoaInternetMail *mail = GOA_INTERNET_MAIL (_mail); - gchar *monitor_object_path; - GError *error; - MonitorData *data; - static gint _g_monitor_count = 0; - - monitor_object_path = NULL; - - goa_info ("Creating mail monitor for %s on account %s", - g_dbus_method_invocation_get_sender (invocation), - g_dbus_object_get_object_path (g_dbus_interface_get_object (G_DBUS_INTERFACE (mail)))); - - data = g_slice_new0 (MonitorData); - data->ref_count = 1; - data->mail = g_object_ref (mail); - data->monitor = goa_mail_monitor_skeleton_new (); - /* Be optimistic that the connection works - if this is not so, - * imap_client_sync() will clear the flag - */ - goa_mail_monitor_set_connected (data->monitor, TRUE); - g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (data->monitor), - G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); - g_signal_connect (data->monitor, - "handle-refresh", - G_CALLBACK (monitor_on_handle_refresh), - data); - g_signal_connect (data->monitor, - "handle-close", - G_CALLBACK (monitor_on_handle_close), - data); - g_signal_connect (data->monitor, - "handle-add-star", - G_CALLBACK (monitor_on_handle_add_star), - data); - g_signal_connect (data->monitor, - "handle-mark-as-spam", - G_CALLBACK (monitor_on_handle_mark_as_spam), - data); - g_signal_connect (data->monitor, - "handle-simulate-message-received", - G_CALLBACK (monitor_on_handle_simulate_message_received), - data); - - monitor_object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/mail_monitors/%d", _g_monitor_count++); - error = NULL; - if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (data->monitor), - g_dbus_method_invocation_get_connection (invocation), - monitor_object_path, - &error)) - { - g_prefix_error (&error, "Error exporting mail monitor: "); - g_dbus_method_invocation_return_gerror (invocation, error); - monitor_data_unref (data); - goto out; - } - - data->name_watcher_id = g_bus_watch_name_on_connection (g_dbus_method_invocation_get_connection (invocation), - g_dbus_method_invocation_get_sender (invocation), - G_BUS_NAME_WATCHER_FLAGS_NONE, - NULL, /* name_appeared_handler */ - on_monitor_owner_vanished, - data, - NULL); - - /* OK, we're in business - finish the invocation - * - * TODO: set up things so only caller can access the created object? - */ - goa_mail_complete_create_monitor (GOA_MAIL (mail), invocation, monitor_object_path); - - /* Create the IMAP client - this blocks our thread until the owner - * vanishes or the Close() method is called ... - * - * The data->imap_cancellable member can be used to wake up the loop - * to check for data->imap_request_close member or just to - * refresh... - */ - data->imap_cancellable = g_cancellable_new (); - data->imap_counter_lock = g_mutex_new (); - data->imap_counter_cond = g_cond_new (); - imap_client_sync (data); - - out: - g_free (monitor_object_path); - return TRUE; /* invocation was handled */ -} - -/* ---------------------------------------------------------------------------------------------------- */ - -static void -goa_internet_mail__goa_mail_iface_init (GoaMailIface *iface) -{ - iface->handle_create_monitor = handle_create_monitor; -} - -/* ---------------------------------------------------------------------------------------------------- */ diff --git a/src/goabackend/goainternetmail.h b/src/goabackend/goainternetmail.h deleted file mode 100644 index 20357bf..0000000 --- a/src/goabackend/goainternetmail.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: David Zeuthen <davidz@redhat.com> - */ - -#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION) -#error "Only <goabackend/goabackend.h> can be included directly." -#endif - -#ifndef __GOA_INTERNET_MAIL_H__ -#define __GOA_INTERNET_MAIL_H__ - -#include <goabackend/goabackendtypes.h> - -G_BEGIN_DECLS - -#define GOA_TYPE_INTERNET_MAIL (goa_internet_mail_get_type ()) -#define GOA_INTERNET_MAIL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOA_TYPE_INTERNET_MAIL, GoaInternetMail)) -#define GOA_IS_INTERNET_MAIL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOA_TYPE_INTERNET_MAIL)) - -GType goa_internet_mail_get_type (void) G_GNUC_CONST; -GoaMail *goa_internet_mail_new (const gchar *imap_host, - const gchar *imap_user_name, - gboolean imap_use_tls, - gboolean imap_ignore_bad_tls, - GoaImapAuth *imap_auth, - const gchar *smtp_host, - const gchar *smtp_user_name, - gboolean smtp_use_tls, - gboolean smtp_ignore_bad_tls); - - -G_END_DECLS - -#endif /* __GOA_INTERNET_MAIL_H__ */ diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c index da1e1af..072e380 100644 --- a/src/goabackend/goaprovider.c +++ b/src/goabackend/goaprovider.c @@ -30,7 +30,6 @@ #include "goafacebookprovider.h" #include "goayahooprovider.h" #include "goatwitterprovider.h" -#include "goagenericmailprovider.h" #include "goaeditablelabel.h" @@ -548,7 +547,6 @@ ensure_ep_and_builtins (void) type = GOA_TYPE_FACEBOOK_PROVIDER; type = GOA_TYPE_YAHOO_PROVIDER; type = GOA_TYPE_TWITTER_PROVIDER; - type = GOA_TYPE_GENERIC_MAIL_PROVIDER; type = type; /* for -Wunused-but-set-variable */ g_once_init_leave (&once_init_value, 1); |