~ubuntu-branches/ubuntu/raring/gnome-online-accounts/raring-proposed

« back to all changes in this revision

Viewing changes to .pc/CVE-2013-0240.patch/src/goabackend/goautils.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-03-21 13:22:10 UTC
  • Revision ID: package-import@ubuntu.com-20130321132210-9gouq9rhdvlrm4g7
Tags: 3.6.2-1ubuntu1
* SECURITY UPDATE: incorrect ssl cert validation (LP: #1117411)
  - debian/patches/CVE-2013-0240.patch: properly validate ssl certs and
    fix cancellation in src/goa/goaenums.h, src/goa/goaerror.c,
    src/goabackend/goaewsclient.c, src/goabackend/goaewsclient.h,
    src/goabackend/goaexchangeprovider.c,
    src/goabackend/goagoogleprovider.c,
    src/goabackend/goahttpclient.*, src/goabackend/goautils.*,
    src/goabackend/goawebview.c.
  - debian/libgoa-1.0-0.symbols: updated with new symbol.
  - CVE-2013-0240
  - CVE-2013-1799

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 
2
/*
 
3
 * Copyright (C) 2012 Red Hat, Inc.
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Lesser General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Lesser General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General
 
16
 * Public License along with this library; if not, write to the
 
17
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 
18
 * Boston, MA 02111-1307, USA.
 
19
 *
 
20
 * Authors: Debarshi Ray <debarshir@gnome.org>
 
21
 *          Ray Strode <rstrode@redhat.com>
 
22
 */
 
23
 
 
24
#include "config.h"
 
25
 
 
26
#include <glib/gi18n-lib.h>
 
27
#include <libsecret/secret.h>
 
28
 
 
29
#include "goaprovider.h"
 
30
#include "goalogging.h"
 
31
#include "goautils.h"
 
32
 
 
33
static const SecretSchema secret_password_schema =
 
34
{
 
35
  "org.gnome.OnlineAccounts", SECRET_SCHEMA_DONT_MATCH_NAME,
 
36
  {
 
37
    { "goa-identity", SECRET_SCHEMA_ATTRIBUTE_STRING },
 
38
    { "NULL", 0 }
 
39
  }
 
40
};
 
41
 
 
42
gboolean
 
43
goa_utils_check_duplicate (GoaClient              *client,
 
44
                           const gchar            *identity,
 
45
                           const gchar            *provider_type,
 
46
                           GoaPeekInterfaceFunc    func,
 
47
                           GError                **error)
 
48
{
 
49
  GList *accounts;
 
50
  GList *l;
 
51
  gboolean ret;
 
52
 
 
53
  ret = FALSE;
 
54
 
 
55
  accounts = goa_client_get_accounts (client);
 
56
  for (l = accounts; l != NULL; l = l->next)
 
57
    {
 
58
      GoaObject *object = GOA_OBJECT (l->data);
 
59
      GoaAccount *account;
 
60
      gpointer *interface;
 
61
      const gchar *identity_from_object;
 
62
      const gchar *provider_type_from_object;
 
63
 
 
64
      account = goa_object_peek_account (object);
 
65
      interface = (*func) (object);
 
66
      if (interface == NULL)
 
67
        continue;
 
68
 
 
69
      provider_type_from_object = goa_account_get_provider_type (account);
 
70
      if (g_strcmp0 (provider_type_from_object, provider_type) != 0)
 
71
        continue;
 
72
 
 
73
      identity_from_object = goa_account_get_identity (account);
 
74
      if (g_strcmp0 (identity_from_object, identity) == 0)
 
75
        {
 
76
          const gchar *presentation_identity;
 
77
          const gchar *provider_name;
 
78
 
 
79
          presentation_identity = goa_account_get_presentation_identity (account);
 
80
          provider_name = goa_account_get_provider_name (account);
 
81
          g_set_error (error,
 
82
                       GOA_ERROR,
 
83
                       GOA_ERROR_ACCOUNT_EXISTS,
 
84
                       _("A %s account already exists for %s"),
 
85
                       provider_name,
 
86
                       presentation_identity);
 
87
          goto out;
 
88
        }
 
89
    }
 
90
 
 
91
  ret = TRUE;
 
92
 
 
93
 out:
 
94
  g_list_free_full (accounts, g_object_unref);
 
95
  return ret;
 
96
}
 
97
 
 
98
void
 
99
goa_utils_set_dialog_title (GoaProvider *provider, GtkDialog *dialog, gboolean add_account)
 
100
{
 
101
  gchar *provider_name;
 
102
  gchar *title;
 
103
 
 
104
  provider_name = goa_provider_get_provider_name (GOA_PROVIDER (provider), NULL);
 
105
  /* Translators: the %s is the name of the provider. eg., Google. */
 
106
  title = g_strdup_printf (_("%s account"), provider_name);
 
107
  gtk_window_set_title (GTK_WINDOW (dialog), title);
 
108
  g_free (title);
 
109
  g_free (provider_name);
 
110
}
 
111
 
 
112
gboolean
 
113
goa_utils_delete_credentials_sync (GoaProvider   *provider,
 
114
                                   GoaAccount    *object,
 
115
                                   GCancellable  *cancellable,
 
116
                                   GError       **error)
 
117
{
 
118
  gboolean ret;
 
119
  gchar *password_key;
 
120
  const gchar *identity;
 
121
 
 
122
  g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
 
123
  g_return_val_if_fail (GOA_IS_ACCOUNT (object), FALSE);
 
124
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
 
125
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
126
 
 
127
  ret = FALSE;
 
128
 
 
129
  password_key = NULL;
 
130
 
 
131
  identity = goa_account_get_id (object);
 
132
 
 
133
  password_key = g_strdup_printf ("%s:gen%d:%s",
 
134
                                  goa_provider_get_provider_type (GOA_PROVIDER (provider)),
 
135
                                  goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
 
136
                                  identity);
 
137
 
 
138
  if (!secret_password_clear_sync (&secret_password_schema,
 
139
                                   cancellable,
 
140
                                   NULL,
 
141
                                   "goa-identity", password_key,
 
142
                                   NULL))
 
143
    {
 
144
      g_set_error_literal (error,
 
145
                           GOA_ERROR,
 
146
                           GOA_ERROR_FAILED, /* TODO: more specific */
 
147
                           _("Failed to delete credentials from the keyring"));
 
148
      goto out;
 
149
    }
 
150
 
 
151
  ret = TRUE;
 
152
 
 
153
 out:
 
154
  g_free (password_key);
 
155
  return ret;
 
156
}
 
157
 
 
158
GVariant *
 
159
goa_utils_lookup_credentials_sync (GoaProvider   *provider,
 
160
                                   GoaObject     *object,
 
161
                                   GCancellable  *cancellable,
 
162
                                   GError       **error)
 
163
{
 
164
  gchar *password_key;
 
165
  GVariant *ret;
 
166
  gchar *password;
 
167
  const gchar *identity;
 
168
 
 
169
  g_return_val_if_fail (GOA_IS_PROVIDER (provider), NULL);
 
170
  g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE);
 
171
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
 
172
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
173
 
 
174
  ret = NULL;
 
175
  password_key = NULL;
 
176
  password = NULL;
 
177
 
 
178
  identity = goa_account_get_id (goa_object_peek_account (object));
 
179
 
 
180
  password_key = g_strdup_printf ("%s:gen%d:%s",
 
181
                                  goa_provider_get_provider_type (GOA_PROVIDER (provider)),
 
182
                                  goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
 
183
                                  identity);
 
184
 
 
185
  password = secret_password_lookup_sync (&secret_password_schema,
 
186
                                          cancellable,
 
187
                                          NULL,
 
188
                                          "goa-identity", password_key,
 
189
                                          NULL);
 
190
  if (password == NULL)
 
191
    {
 
192
      g_set_error_literal (error,
 
193
                           GOA_ERROR,
 
194
                           GOA_ERROR_FAILED, /* TODO: more specific */
 
195
                           _("Failed to retrieve credentials from the keyring"));
 
196
      goto out;
 
197
    }
 
198
 
 
199
  ret = g_variant_parse (NULL, /* GVariantType */
 
200
                         password,
 
201
                         NULL, /* limit */
 
202
                         NULL, /* endptr */
 
203
                         error);
 
204
  if (ret == NULL)
 
205
    {
 
206
      g_prefix_error (error, _("Error parsing result obtained from the keyring: "));
 
207
      goto out;
 
208
    }
 
209
 
 
210
  if (g_variant_is_floating (ret))
 
211
    g_variant_ref_sink (ret);
 
212
 
 
213
 out:
 
214
  g_free (password);
 
215
  g_free (password_key);
 
216
  return ret;
 
217
}
 
218
 
 
219
gboolean
 
220
goa_utils_store_credentials_for_id_sync (GoaProvider   *provider,
 
221
                                         const gchar   *id,
 
222
                                         GVariant      *credentials,
 
223
                                         GCancellable  *cancellable,
 
224
                                         GError       **error)
 
225
{
 
226
  gboolean ret;
 
227
  gchar *credentials_str;
 
228
  gchar *password_description;
 
229
  gchar *password_key;
 
230
 
 
231
  g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
 
232
  g_return_val_if_fail (id != NULL && id[0] != '\0', FALSE);
 
233
  g_return_val_if_fail (credentials != NULL, FALSE);
 
234
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
 
235
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
236
 
 
237
  ret = FALSE;
 
238
 
 
239
  credentials_str = g_variant_print (credentials, TRUE);
 
240
  g_variant_ref_sink (credentials);
 
241
  g_variant_unref (credentials);
 
242
 
 
243
  password_key = g_strdup_printf ("%s:gen%d:%s",
 
244
                                  goa_provider_get_provider_type (GOA_PROVIDER (provider)),
 
245
                                  goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
 
246
                                  id);
 
247
  /* Translators: The %s is the type of the provider, e.g. 'google' or 'facebook' */
 
248
  password_description = g_strdup_printf (_("GOA %s credentials for identity %s"),
 
249
                                          goa_provider_get_provider_type (GOA_PROVIDER (provider)),
 
250
                                          id);
 
251
 
 
252
  if (!secret_password_store_sync (&secret_password_schema,
 
253
                                   SECRET_COLLECTION_DEFAULT, /* default keyring */
 
254
                                   password_description,
 
255
                                   credentials_str,
 
256
                                   cancellable,
 
257
                                   NULL,
 
258
                                   "goa-identity", password_key,
 
259
                                   NULL))
 
260
    {
 
261
      g_set_error_literal (error,
 
262
                           GOA_ERROR,
 
263
                           GOA_ERROR_FAILED, /* TODO: more specific */
 
264
                           _("Failed to store credentials in the keyring"));
 
265
      goto out;
 
266
    }
 
267
 
 
268
  ret = TRUE;
 
269
 
 
270
 out:
 
271
  g_free (credentials_str);
 
272
  g_free (password_key);
 
273
  g_free (password_description);
 
274
  return ret;
 
275
}
 
276
 
 
277
gboolean
 
278
goa_utils_store_credentials_for_object_sync (GoaProvider   *provider,
 
279
                                             GoaObject     *object,
 
280
                                             GVariant      *credentials,
 
281
                                             GCancellable  *cancellable,
 
282
                                             GError       **error)
 
283
{
 
284
  const gchar *id;
 
285
 
 
286
  g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
 
287
  g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE);
 
288
  g_return_val_if_fail (credentials != NULL, FALSE);
 
289
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
 
290
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
291
 
 
292
  id = goa_account_get_id (goa_object_peek_account (object));
 
293
  return goa_utils_store_credentials_for_id_sync (provider, id, credentials, cancellable, error);
 
294
}
 
295
 
 
296
void
 
297
goa_utils_keyfile_remove_key (GoaAccount *account, const gchar *key)
 
298
{
 
299
  GError *error;
 
300
  GKeyFile *key_file;
 
301
  gchar *contents;
 
302
  gchar *group;
 
303
  gchar *path;
 
304
  gsize length;
 
305
 
 
306
  contents = NULL;
 
307
 
 
308
  path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
 
309
  group = g_strdup_printf ("Account %s", goa_account_get_id (account));
 
310
 
 
311
  key_file = g_key_file_new ();
 
312
  error = NULL;
 
313
  if (!g_key_file_load_from_file (key_file,
 
314
                                  path,
 
315
                                  G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
 
316
                                  &error))
 
317
    {
 
318
      goa_warning ("Error loading keyfile %s: %s (%s, %d)",
 
319
                   path,
 
320
                   error->message,
 
321
                   g_quark_to_string (error->domain),
 
322
                   error->code);
 
323
      g_error_free (error);
 
324
      goto out;
 
325
    }
 
326
 
 
327
  g_key_file_remove_key (key_file, group, key, NULL);
 
328
  contents = g_key_file_to_data (key_file, &length, NULL);
 
329
 
 
330
  error = NULL;
 
331
  if (!g_file_set_contents (path, contents, length, &error))
 
332
    {
 
333
      g_prefix_error (&error, "Error writing key-value-file %s: ", path);
 
334
      goa_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code);
 
335
      g_error_free (error);
 
336
      goto out;
 
337
    }
 
338
 
 
339
 out:
 
340
  g_free (contents);
 
341
  g_key_file_free (key_file);
 
342
  g_free (group);
 
343
  g_free (path);
 
344
}
 
345
 
 
346
void
 
347
goa_utils_keyfile_set_boolean (GoaAccount *account, const gchar *key, gboolean value)
 
348
{
 
349
  GError *error;
 
350
  GKeyFile *key_file;
 
351
  gchar *contents;
 
352
  gchar *group;
 
353
  gchar *path;
 
354
  gsize length;
 
355
 
 
356
  contents = NULL;
 
357
 
 
358
  path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
 
359
  group = g_strdup_printf ("Account %s", goa_account_get_id (account));
 
360
 
 
361
  key_file = g_key_file_new ();
 
362
  error = NULL;
 
363
  if (!g_key_file_load_from_file (key_file,
 
364
                                  path,
 
365
                                  G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
 
366
                                  &error))
 
367
    {
 
368
      goa_warning ("Error loading keyfile %s: %s (%s, %d)",
 
369
                   path,
 
370
                   error->message,
 
371
                   g_quark_to_string (error->domain),
 
372
                   error->code);
 
373
      g_error_free (error);
 
374
      goto out;
 
375
    }
 
376
 
 
377
  g_key_file_set_boolean (key_file, group, key, value);
 
378
  contents = g_key_file_to_data (key_file, &length, NULL);
 
379
 
 
380
  error = NULL;
 
381
  if (!g_file_set_contents (path, contents, length, &error))
 
382
    {
 
383
      g_prefix_error (&error, "Error writing key-value-file %s: ", path);
 
384
      goa_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code);
 
385
      g_error_free (error);
 
386
      goto out;
 
387
    }
 
388
 
 
389
 out:
 
390
  g_free (contents);
 
391
  g_key_file_free (key_file);
 
392
  g_free (group);
 
393
  g_free (path);
 
394
}
 
395
 
 
396
void
 
397
goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar *value)
 
398
{
 
399
  GError *error;
 
400
  GKeyFile *key_file;
 
401
  gchar *contents;
 
402
  gchar *group;
 
403
  gchar *path;
 
404
  gsize length;
 
405
 
 
406
  contents = NULL;
 
407
 
 
408
  path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
 
409
  group = g_strdup_printf ("Account %s", goa_account_get_id (account));
 
410
 
 
411
  key_file = g_key_file_new ();
 
412
  error = NULL;
 
413
  if (!g_key_file_load_from_file (key_file,
 
414
                                  path,
 
415
                                  G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
 
416
                                  &error))
 
417
    {
 
418
      goa_warning ("Error loading keyfile %s: %s (%s, %d)",
 
419
                   path,
 
420
                   error->message,
 
421
                   g_quark_to_string (error->domain),
 
422
                   error->code);
 
423
      g_error_free (error);
 
424
      goto out;
 
425
    }
 
426
 
 
427
  g_key_file_set_string (key_file, group, key, value);
 
428
  contents = g_key_file_to_data (key_file, &length, NULL);
 
429
 
 
430
  error = NULL;
 
431
  if (!g_file_set_contents (path, contents, length, &error))
 
432
    {
 
433
      g_prefix_error (&error, "Error writing key-value-file %s: ", path);
 
434
      goa_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code);
 
435
      g_error_free (error);
 
436
      goto out;
 
437
    }
 
438
 
 
439
 out:
 
440
  g_free (contents);
 
441
  g_key_file_free (key_file);
 
442
  g_free (group);
 
443
  g_free (path);
 
444
}