[gnome-online-accounts/gnome-3-6] Guard against invalid SSL certificates
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts/gnome-3-6] Guard against invalid SSL certificates
- Date: Mon, 4 Mar 2013 12:12:21 +0000 (UTC)
commit ecad8142e9ac519b9fc74b96dcb5531052bbffe1
Author: Debarshi Ray <debarshir gnome org>
Date: Thu Jan 31 17:45:20 2013 +0100
Guard against invalid SSL certificates
None of the branded providers (eg., Google, Facebook and Windows Live)
should ever have an invalid certificate. So set "ssl-strict" on the
SoupSession object being used by GoaWebView.
Providers like ownCloud and Exchange might have to deal with
certificates that are not up to the mark. eg., self-signed
certificates. For those, show a warning when the account is being
created, and only proceed if the user decides to ignore it. In any
case, save the status of the certificate that was used to create the
account. So an account created with a valid certificate will never
work with an invalid one, and one created with an invalid certificate
will not throw any further warnings.
Fixes: CVE-2013-0240
src/goa/goaenums.h | 8 ++++--
src/goa/goaerror.c | 5 ++-
src/goabackend/goaewsclient.c | 25 ++++++++++++++++++-
src/goabackend/goaewsclient.h | 4 ++-
src/goabackend/goaexchangeprovider.c | 29 +++++++++++++++++++++--
src/goabackend/goagoogleprovider.c | 1 +
src/goabackend/goahttpclient.c | 25 ++++++++++++++++++-
src/goabackend/goahttpclient.h | 4 ++-
src/goabackend/goautils.c | 42 +++++++++++++++++++++++++++++++++-
src/goabackend/goautils.h | 5 +++-
src/goabackend/goawebview.c | 3 +-
11 files changed, 134 insertions(+), 17 deletions(-)
---
diff --git a/src/goa/goaenums.h b/src/goa/goaenums.h
index 2a13aec..bb17a5e 100644
--- a/src/goa/goaenums.h
+++ b/src/goa/goaenums.h
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2011, 2013 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
@@ -38,6 +38,7 @@ G_BEGIN_DECLS
* @GOA_ERROR_DIALOG_DISMISSED: The dialog was dismissed.
* @GOA_ERROR_ACCOUNT_EXISTS: Account already exists.
* @GOA_ERROR_NOT_AUTHORIZED: Not authorized to perform operation.
+ * @GOA_ERROR_SSL: Invalid SSL certificate.
*
* Error codes for the #GOA_ERROR error domain and the
* corresponding D-Bus error names.
@@ -48,10 +49,11 @@ typedef enum
GOA_ERROR_NOT_SUPPORTED, /* org.gnome.OnlineAccounts.Error.NotSupported */
GOA_ERROR_DIALOG_DISMISSED, /* org.gnome.OnlineAccounts.Error.DialogDismissed */
GOA_ERROR_ACCOUNT_EXISTS, /* org.gnome.OnlineAccounts.Error.AccountExists */
- GOA_ERROR_NOT_AUTHORIZED /* org.gnome.OnlineAccounts.Error.NotAuthorized */
+ GOA_ERROR_NOT_AUTHORIZED, /* org.gnome.OnlineAccounts.Error.NotAuthorized */
+ GOA_ERROR_SSL /* org.gnome.OnlineAccounts.Error.SSL */
} GoaError;
-#define GOA_ERROR_NUM_ENTRIES (GOA_ERROR_NOT_AUTHORIZED + 1)
+#define GOA_ERROR_NUM_ENTRIES (GOA_ERROR_SSL + 1)
G_END_DECLS
diff --git a/src/goa/goaerror.c b/src/goa/goaerror.c
index 9a238bf..de54abf 100644
--- a/src/goa/goaerror.c
+++ b/src/goa/goaerror.c
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2011, 2013 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
@@ -39,7 +39,8 @@ static const GDBusErrorEntry dbus_error_entries[] =
{GOA_ERROR_NOT_SUPPORTED, "org.freedesktop.Goa.Error.NotSupported"},
{GOA_ERROR_DIALOG_DISMISSED, "org.gnome.OnlineAccounts.Error.DialogDismissed"},
{GOA_ERROR_ACCOUNT_EXISTS, "org.gnome.OnlineAccounts.Error.AccountExists"},
- {GOA_ERROR_NOT_AUTHORIZED, "org.gnome.OnlineAccounts.Error.NotAuthorized"}
+ {GOA_ERROR_NOT_AUTHORIZED, "org.gnome.OnlineAccounts.Error.NotAuthorized"},
+ {GOA_ERROR_SSL, "org.gnome.OnlineAccounts.Error.SSL"}
};
GQuark
diff --git a/src/goabackend/goaewsclient.c b/src/goabackend/goaewsclient.c
index 30eb600..3a56f43 100644
--- a/src/goabackend/goaewsclient.c
+++ b/src/goabackend/goaewsclient.c
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2013 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
@@ -35,6 +35,7 @@
#include "goalogging.h"
#include "goaewsclient.h"
+#include "goautils.h"
struct _GoaEwsClient
{
@@ -78,6 +79,7 @@ typedef struct
GSimpleAsyncResult *res;
SoupMessage *msgs[2];
SoupSession *session;
+ gboolean accept_ssl_errors;
gulong cancellable_id;
xmlOutputBuffer *buf;
} AutodiscoverData;
@@ -171,7 +173,9 @@ ews_client_autodiscover_response_cb (SoupSession *session, SoupMessage *msg, gpo
{
GError *error;
AutodiscoverData *data = user_data;
+ GTlsCertificateFlags cert_flags;
gboolean op_res;
+ gboolean using_https;
guint status;
gint idx;
gsize size;
@@ -206,6 +210,16 @@ ews_client_autodiscover_response_cb (SoupSession *session, SoupMessage *msg, gpo
goto out;
}
+ if (!data->accept_ssl_errors)
+ {
+ using_https = soup_message_get_https_status (msg, NULL, &cert_flags);
+ if (using_https && cert_flags != 0)
+ {
+ goa_utils_set_error_ssl (&error, cert_flags);
+ goto out;
+ }
+ }
+
soup_buffer_free (soup_message_body_flatten (SOUP_MESSAGE (msg)->response_body));
g_debug ("The response headers");
g_debug ("===================");
@@ -397,6 +411,7 @@ goa_ews_client_autodiscover (GoaEwsClient *client,
const gchar *password,
const gchar *username,
const gchar *server,
+ gboolean accept_ssl_errors,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -435,9 +450,13 @@ goa_ews_client_autodiscover (GoaEwsClient *client,
data->res = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
goa_ews_client_autodiscover);
data->msgs[0] = ews_client_create_msg_for_url (url1, buf);
data->msgs[1] = ews_client_create_msg_for_url (url2, buf);
- data->session = soup_session_async_new_with_options (SOUP_SESSION_USE_NTLM, TRUE,
+ data->session = soup_session_async_new_with_options (SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
+ SOUP_SESSION_SSL_STRICT, FALSE,
+ SOUP_SESSION_USE_NTLM, TRUE,
SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
NULL);
+ data->accept_ssl_errors = accept_ssl_errors;
+
if (cancellable != NULL)
{
data->cancellable = g_object_ref (cancellable);
@@ -506,6 +525,7 @@ goa_ews_client_autodiscover_sync (GoaEwsClient *client,
const gchar *password,
const gchar *username,
const gchar *server,
+ gboolean accept_ssl_errors,
GCancellable *cancellable,
GError **error)
{
@@ -523,6 +543,7 @@ goa_ews_client_autodiscover_sync (GoaEwsClient *client,
password,
username,
server,
+ accept_ssl_errors,
cancellable,
ews_client_autodiscover_sync_cb,
&data);
diff --git a/src/goabackend/goaewsclient.h b/src/goabackend/goaewsclient.h
index 6f72c41..367ac74 100644
--- a/src/goabackend/goaewsclient.h
+++ b/src/goabackend/goaewsclient.h
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2013 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
@@ -42,6 +42,7 @@ void goa_ews_client_autodiscover (GoaEwsClient *client,
const gchar *password,
const gchar *username,
const gchar *server,
+ gboolean accept_ssl_errors,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer gpointer);
@@ -53,6 +54,7 @@ gboolean goa_ews_client_autodiscover_sync (GoaEwsClient *client,
const gchar *password,
const gchar *username,
const gchar *server,
+ gboolean accept_ssl_errors,
GCancellable *cancellable,
GError **error);
diff --git a/src/goabackend/goaexchangeprovider.c b/src/goabackend/goaexchangeprovider.c
index 8e7b3c0..37eef34 100644
--- a/src/goabackend/goaexchangeprovider.c
+++ b/src/goabackend/goaexchangeprovider.c
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2013 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
@@ -202,7 +202,9 @@ build_object (GoaProvider *provider,
host = g_key_file_get_string (key_file, group, "Host", NULL);
exchange = goa_exchange_skeleton_new ();
- g_object_set (G_OBJECT (exchange), "host", host, NULL);
+ g_object_set (G_OBJECT (exchange),
+ "host", host,
+ NULL);
goa_object_skeleton_set_exchange (object, exchange);
g_free (host);
}
@@ -256,6 +258,7 @@ ensure_credentials_sync (GoaProvider *provider,
GoaAccount *account;
GoaEwsClient *ews_client;
GoaExchange *exchange;
+ gboolean accept_ssl_errors;
gboolean ret;
const gchar *email_address;
const gchar *server;
@@ -301,6 +304,7 @@ ensure_credentials_sync (GoaProvider *provider,
}
exchange = goa_object_peek_exchange (object);
+ accept_ssl_errors = goa_util_lookup_keyfile_boolean (object, "AcceptSslErrors");
server = goa_exchange_get_host (exchange);
ews_client = goa_ews_client_new ();
@@ -309,6 +313,7 @@ ensure_credentials_sync (GoaProvider *provider,
password,
username,
server,
+ accept_ssl_errors,
cancellable,
error);
if (!ret)
@@ -584,6 +589,7 @@ add_account (GoaProvider *provider,
GVariantBuilder details;
GoaEwsClient *ews_client;
GoaObject *ret;
+ gboolean accept_ssl_errors;
const gchar *email_address;
const gchar *server;
const gchar *password;
@@ -592,6 +598,8 @@ add_account (GoaProvider *provider,
gint response;
ews_client = NULL;
+ accept_ssl_errors = FALSE;
+
ret = NULL;
memset (&data, 0, sizeof (AddAccountData));
@@ -636,6 +644,7 @@ add_account (GoaProvider *provider,
password,
username,
server,
+ accept_ssl_errors,
NULL,
autodiscover_cb,
&data);
@@ -646,6 +655,17 @@ add_account (GoaProvider *provider,
{
gchar *markup;
+ if (data.error->code == GOA_ERROR_SSL)
+ {
+ goa_spinner_button_set_label (GOA_SPINNER_BUTTON (data.spinner_button), _("_Ignore"));
+ accept_ssl_errors = TRUE;
+ }
+ else
+ {
+ goa_spinner_button_set_label (GOA_SPINNER_BUTTON (data.spinner_button), _("_Try Again"));
+ accept_ssl_errors = FALSE;
+ }
+
markup = g_strdup_printf ("<b>%s:</b> %s",
_("Error connecting to Microsoft Exchange server"),
data.error->message);
@@ -654,7 +674,6 @@ add_account (GoaProvider *provider,
gtk_label_set_markup (GTK_LABEL (data.cluebar_label), markup);
g_free (markup);
- goa_spinner_button_set_label (GOA_SPINNER_BUTTON (data.spinner_button), _("_Try Again"));
gtk_expander_set_expanded (GTK_EXPANDER (data.expander), TRUE);
gtk_widget_set_no_show_all (data.cluebar, FALSE);
gtk_widget_show_all (data.cluebar);
@@ -671,6 +690,7 @@ add_account (GoaProvider *provider,
g_variant_builder_add (&details, "{ss}", "CalendarEnabled", "true");
g_variant_builder_add (&details, "{ss}", "ContactsEnabled", "true");
g_variant_builder_add (&details, "{ss}", "Host", server);
+ g_variant_builder_add (&details, "{ss}", "AcceptSslErrors", (accept_ssl_errors) ? "true" : "false");
/* OK, everything is dandy, add the account */
/* we want the GoaClient to update before this method returns (so it
@@ -726,6 +746,7 @@ refresh_account (GoaProvider *provider,
GoaExchange *exchange;
GtkWidget *dialog;
GtkWidget *vbox;
+ gboolean accept_ssl_errors;
gboolean ret;
const gchar *email_address;
const gchar *server;
@@ -785,6 +806,7 @@ refresh_account (GoaProvider *provider,
username = goa_account_get_identity (account);
exchange = goa_object_peek_exchange (object);
+ accept_ssl_errors = goa_util_lookup_keyfile_boolean (object, "AcceptSslErrors");
server = goa_exchange_get_host (exchange);
goa_ews_client_autodiscover (ews_client,
@@ -792,6 +814,7 @@ refresh_account (GoaProvider *provider,
password,
username,
server,
+ accept_ssl_errors,
NULL,
autodiscover_cb,
&data);
diff --git a/src/goabackend/goagoogleprovider.c b/src/goabackend/goagoogleprovider.c
index 4a83310..a2643a9 100644
--- a/src/goabackend/goagoogleprovider.c
+++ b/src/goabackend/goagoogleprovider.c
@@ -678,6 +678,7 @@ ensure_credentials_sync (GoaProvider *provider,
uri_caldav,
username,
password,
+ FALSE,
cancellable,
error);
if (!ret)
diff --git a/src/goabackend/goahttpclient.c b/src/goabackend/goahttpclient.c
index 21140f1..9accecc 100644
--- a/src/goabackend/goahttpclient.c
+++ b/src/goabackend/goahttpclient.c
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2013 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
@@ -28,6 +28,7 @@
#include "goalogging.h"
#include "goahttpclient.h"
+#include "goautils.h"
struct _GoaHttpClient
{
@@ -71,6 +72,7 @@ typedef struct
GSimpleAsyncResult *res;
SoupMessage *msg;
SoupSession *session;
+ gboolean accept_ssl_errors;
gulong cancellable_id;
} CheckData;
@@ -132,7 +134,9 @@ http_client_check_response_cb (SoupSession *session, SoupMessage *msg, gpointer
{
GError *error;
CheckData *data = user_data;
+ GTlsCertificateFlags cert_flags;
gboolean op_res;
+ gboolean using_https;
error = NULL;
op_res = FALSE;
@@ -149,6 +153,16 @@ http_client_check_response_cb (SoupSession *session, SoupMessage *msg, gpointer
goto out;
}
+ if (!data->accept_ssl_errors)
+ {
+ using_https = soup_message_get_https_status (msg, NULL, &cert_flags);
+ if (using_https && cert_flags != 0)
+ {
+ goa_utils_set_error_ssl (&error, cert_flags);
+ goto out;
+ }
+ }
+
op_res = TRUE;
out:
@@ -165,6 +179,7 @@ goa_http_client_check (GoaHttpClient *client,
const gchar *uri,
const gchar *username,
const gchar *password,
+ gboolean accept_ssl_errors,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -180,9 +195,13 @@ goa_http_client_check (GoaHttpClient *client,
data = g_slice_new0 (CheckData);
data->res = g_simple_async_result_new (G_OBJECT (client), callback, user_data, goa_http_client_check);
- data->session = soup_session_async_new_with_options (SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+ data->session = soup_session_async_new_with_options (SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
+ SOUP_SESSION_SSL_STRICT, FALSE,
+ SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
NULL);
+ data->accept_ssl_errors = accept_ssl_errors;
+
data->msg = soup_message_new (SOUP_METHOD_GET, uri);
soup_message_headers_append (data->msg->request_headers, "Connection", "close");
@@ -248,6 +267,7 @@ goa_http_client_check_sync (GoaHttpClient *client,
const gchar *uri,
const gchar *username,
const gchar *password,
+ gboolean accept_ssl_errors,
GCancellable *cancellable,
GError **error)
{
@@ -264,6 +284,7 @@ goa_http_client_check_sync (GoaHttpClient *client,
uri,
username,
password,
+ accept_ssl_errors,
cancellable,
http_client_check_sync_cb,
&data);
diff --git a/src/goabackend/goahttpclient.h b/src/goabackend/goahttpclient.h
index 0e46f94..bad5c9b 100644
--- a/src/goabackend/goahttpclient.h
+++ b/src/goabackend/goahttpclient.h
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2013 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
@@ -41,6 +41,7 @@ void goa_http_client_check (GoaHttpClient *client,
const gchar *uri,
const gchar *username,
const gchar *password,
+ gboolean accept_ssl_errors,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer gpointer);
@@ -51,6 +52,7 @@ gboolean goa_http_client_check_sync (GoaHttpClient *client,
const gchar *uri,
const gchar *username,
const gchar *password,
+ gboolean accept_ssl_errors,
GCancellable *cancellable,
GError **error);
diff --git a/src/goabackend/goautils.c b/src/goabackend/goautils.c
index 199081c..eee2a89 100644
--- a/src/goabackend/goautils.c
+++ b/src/goabackend/goautils.c
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2013 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
@@ -442,3 +442,43 @@ goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar
g_free (group);
g_free (path);
}
+
+void
+goa_utils_set_error_ssl (GError **err, GTlsCertificateFlags flags)
+{
+ const gchar *error_msg;
+
+ switch (flags)
+ {
+ case G_TLS_CERTIFICATE_UNKNOWN_CA:
+ error_msg = _("The signing certificate authority is not known.");
+ break;
+
+ case G_TLS_CERTIFICATE_BAD_IDENTITY:
+ error_msg = _("The certificate does not match the expected identity of the site that it was "
+ "retrieved from.");
+ break;
+
+ case G_TLS_CERTIFICATE_NOT_ACTIVATED:
+ error_msg = _("The certificate's activation time is still in the future.");
+ break;
+
+ case G_TLS_CERTIFICATE_EXPIRED:
+ error_msg = _("The certificate has expired.");
+ break;
+
+ case G_TLS_CERTIFICATE_REVOKED:
+ error_msg = _("The certificate has been revoked.");
+ break;
+
+ case G_TLS_CERTIFICATE_INSECURE:
+ error_msg = _("The certificate's algorithm is considered insecure.");
+ break;
+
+ default:
+ error_msg = _("Invalid certificate.");
+ break;
+ }
+
+ g_set_error (err, GOA_ERROR, GOA_ERROR_SSL, error_msg);
+}
diff --git a/src/goabackend/goautils.h b/src/goabackend/goautils.h
index f38828f..fdce9cd 100644
--- a/src/goabackend/goautils.h
+++ b/src/goabackend/goautils.h
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2013 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
@@ -27,6 +27,7 @@
#ifndef __GOA_UTILS_H__
#define __GOA_UTILS_H__
+#include <gio/gio.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <goabackend/goabackendtypes.h>
@@ -71,6 +72,8 @@ void goa_utils_keyfile_set_boolean (GoaAccount *account, const gchar
void goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar *value);
+void goa_utils_set_error_ssl (GError **err, GTlsCertificateFlags flags);
+
G_END_DECLS
#endif /* __GOA_UTILS_H__ */
diff --git a/src/goabackend/goawebview.c b/src/goabackend/goawebview.c
index 952a927..2db1154 100644
--- a/src/goabackend/goawebview.c
+++ b/src/goabackend/goawebview.c
@@ -1,6 +1,6 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2013 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
@@ -221,6 +221,7 @@ goa_web_view_init (GoaWebView *self)
priv = self->priv;
session = webkit_get_default_session ();
+ g_object_set (session, SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE, SOUP_SESSION_SSL_STRICT, TRUE, NULL);
soup_session_add_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER_GNOME);
g_object_set (session, "accept-language-auto", TRUE, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]