~ubuntu-branches/ubuntu/raring/vino/raring-proposed

« back to all changes in this revision

Viewing changes to .pc/git_auth_methods_setting.patch/capplet/vino-preferences.c

  • Committer: Package Import Robot
  • Author(s): Ritesh Khadgaray
  • Date: 2013-03-20 22:12:06 UTC
  • Revision ID: package-import@ubuntu.com-20130320221206-my0ztfmn9esw59p8
Tags: 3.6.2-0ubuntu3
* debian/patches/git_auth_methods_setting.patch:  
  - incorrect schema setting used for authentication-methods in 
    vino server ( lp: #1027086)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2003 Sun Microsystems, Inc.
 
3
 * Copyright (C) 2006 Jonh Wendell <wendell@bani.com.br> 
 
4
 * Copyright © 2010 Codethink Limited
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License as
 
8
 * published by the Free Software Foundation; either version 2 of the
 
9
 * License, or (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
19
 * 02111-1307, USA.
 
20
 *
 
21
 * Authors:
 
22
 *      Mark McLoughlin <mark@skynet.ie>
 
23
 *      Jonh Wendell <wendell@bani.com.br>
 
24
 *      Ryan Lortie <desrt@desrt.ca>
 
25
 */
 
26
 
 
27
#include "config.h"
 
28
 
 
29
#include "vino-connectivity-info.h"
 
30
#include "vino-radio-button.h"
 
31
#include "vino-message-box.h"
 
32
#include "vino-keyring.h"
 
33
 
 
34
#include <glib/gi18n.h>
 
35
#include <gtk/gtk.h>
 
36
 
 
37
typedef struct
 
38
{
 
39
  GtkApplication        parent_instance;
 
40
 
 
41
  VinoConnectivityInfo *info;
 
42
} VinoPreferences;
 
43
 
 
44
typedef GtkApplicationClass VinoPreferencesClass;
 
45
 
 
46
static GType vino_preferences_get_type (void);
 
47
G_DEFINE_TYPE (VinoPreferences, vino_preferences, GTK_TYPE_APPLICATION)
 
48
 
 
49
 
 
50
/* We define three GSettings mappings here:
 
51
 *
 
52
 * First, a relatively boring boolean inversion mapping.
 
53
 */
 
54
static gboolean
 
55
get_inverted (GValue   *value,
 
56
              GVariant *variant,
 
57
              gpointer  user_data)
 
58
{
 
59
  g_value_set_boolean (value, !g_variant_get_boolean (variant));
 
60
  return TRUE;
 
61
}
 
62
 
 
63
static GVariant *
 
64
set_inverted (const GValue       *value,
 
65
              const GVariantType *type,
 
66
              gpointer            user_data)
 
67
{
 
68
  return g_variant_new_boolean (!g_value_get_boolean (value));
 
69
}
 
70
 
 
71
/* Next, one that maps between the array-of-strings list of
 
72
 * authentication mechanisms and a boolean that is FALSE if the 'none'
 
73
 * and TRUE otherwise (ie: for 'vnc' in the list).
 
74
 */
 
75
static gboolean
 
76
get_authtype (GValue   *value,
 
77
              GVariant *variant,
 
78
              gpointer  user_data)
 
79
{
 
80
  GVariantIter iter;
 
81
  const gchar *type;
 
82
 
 
83
  g_variant_iter_init (&iter, variant);
 
84
  g_value_set_boolean (value, TRUE);
 
85
 
 
86
  while (g_variant_iter_next (&iter, "s", &type))
 
87
    if (strcmp (type, "none") == 0)
 
88
      g_value_set_boolean (value, FALSE);
 
89
 
 
90
  return TRUE;
 
91
}
 
92
 
 
93
static GVariant *
 
94
set_authtype (const GValue       *value,
 
95
              const GVariantType *type,
 
96
              gpointer            user_data)
 
97
{
 
98
  const gchar *authtype;
 
99
 
 
100
  if (g_value_get_boolean (value))
 
101
    authtype = "vnc";
 
102
  else
 
103
    authtype = "none";
 
104
 
 
105
  return g_variant_new_strv (&authtype, 1);
 
106
}
 
107
 
 
108
 
 
109
/* Finally, a somewhat evil mapping for the password setting:
 
110
 *
 
111
 * If the setting is 'keyring' then we load the password from the
 
112
 * keyring.  Else, it is assumed to be a base64-encoded string which is
 
113
 * the actual password.
 
114
 *
 
115
 * On setting the password, we always first try to use the keyring.  If
 
116
 * that is successful we write 'keyring' to the settings.  If it fails
 
117
 * then we base64-encode the password and write it to the settings.
 
118
 *
 
119
 * Doing it this way ensures that there is no ambiguity about what the
 
120
 * password is in the event that gnome-keyring becomes available then
 
121
 * unavailable again.
 
122
 */
 
123
static gboolean
 
124
get_password (GValue   *value,
 
125
              GVariant *variant,
 
126
              gpointer  user_data)
 
127
{
 
128
  const gchar *setting;
 
129
 
 
130
  setting = g_variant_get_string (variant, NULL);
 
131
 
 
132
  if (strcmp (setting, "keyring") == 0)
 
133
    {
 
134
      g_value_take_string (value, vino_keyring_get_password ());
 
135
      return TRUE;
 
136
    }
 
137
  else
 
138
    {
 
139
      gchar *decoded;
 
140
      gsize length;
 
141
      gboolean ok;
 
142
 
 
143
      decoded = (gchar *) g_base64_decode (setting, &length);
 
144
 
 
145
      if ((ok = g_utf8_validate (decoded, length, NULL)))
 
146
        g_value_take_string (value, g_strndup (decoded, length));
 
147
 
 
148
      return ok;
 
149
    }
 
150
}
 
151
 
 
152
static GVariant *
 
153
set_password (const GValue       *value,
 
154
              const GVariantType *type,
 
155
              gpointer            user_data)
 
156
{
 
157
  const gchar *string;
 
158
  gchar *base64;
 
159
 
 
160
  string = g_value_get_string (value);
 
161
 
 
162
  /* first, try to put it in the keyring */
 
163
  if (vino_keyring_set_password (string))
 
164
    return g_variant_new_string ("keyring");
 
165
 
 
166
  /* if that failed, store it in GSettings, base64 */
 
167
  base64 = g_base64_encode ((guchar *) string, strlen (string));
 
168
  return g_variant_new_from_data (G_VARIANT_TYPE_STRING,
 
169
                                  base64, strlen (base64) + 1,
 
170
                                  TRUE, g_free, base64);
 
171
}
 
172
 
 
173
typedef enum
 
174
{
 
175
  VINO_ICON_VISIBILITY_NEVER,
 
176
  VINO_ICON_VISIBILITY_ALWAYS,
 
177
  VINO_ICON_VISIBILITY_CLIENT
 
178
} VinoIconVisibility;
 
179
 
 
180
static gboolean
 
181
get_icon_visibility (GValue   *value,
 
182
                     GVariant *variant,
 
183
                     gpointer  user_data)
 
184
{
 
185
  const char *setting;
 
186
  char *name;
 
187
 
 
188
  setting = g_variant_get_string (variant, NULL);
 
189
 
 
190
  g_object_get (user_data, "name", &name, NULL);
 
191
 
 
192
  /* If the button name matches the setting, it should be active. */
 
193
  if (g_strcmp0 (name, setting) == 0)
 
194
      g_value_set_boolean (value, TRUE);
 
195
 
 
196
  g_free (name);
 
197
 
 
198
  return TRUE;
 
199
}
 
200
 
 
201
static GVariant *
 
202
set_icon_visibility (const GValue       *value,
 
203
                     const GVariantType *type,
 
204
                     gpointer            user_data)
 
205
{
 
206
  GVariant *variant = NULL;
 
207
  char *name;
 
208
 
 
209
  /* Don't act unless the button has been activated (turned ON). */
 
210
  if (!g_value_get_boolean (value))
 
211
    return NULL;
 
212
 
 
213
  /* GtkToggleButton *button = GTK_TOGGLE_BUTTON(user_data); */
 
214
  g_object_get (user_data, "name", &name, NULL);
 
215
  variant = g_variant_new_string (name);
 
216
 
 
217
  g_free (name);
 
218
 
 
219
  return variant;
 
220
}
 
221
 
 
222
static void
 
223
vino_preferences_dialog_response (GtkWidget *widget,
 
224
                                  gint       response,
 
225
                                  gpointer   user_data)
 
226
{
 
227
  GError *error = NULL;
 
228
  GdkScreen *screen;
 
229
 
 
230
  switch (response)
 
231
    {
 
232
    case GTK_RESPONSE_HELP:
 
233
      screen = gtk_widget_get_screen (widget);
 
234
 
 
235
      if (!gtk_show_uri (screen, "help:ubuntu-help/sharing-desktop",
 
236
                         GDK_CURRENT_TIME, &error))
 
237
        {
 
238
          GtkWidget *message_dialog;
 
239
 
 
240
          message_dialog =
 
241
            gtk_message_dialog_new (GTK_WINDOW (widget),
 
242
                                    GTK_DIALOG_DESTROY_WITH_PARENT,
 
243
                                    GTK_MESSAGE_ERROR,
 
244
                                    GTK_BUTTONS_CLOSE,
 
245
                                    _("There was an error displaying help:\n%s"),
 
246
                                    error->message);
 
247
          gtk_window_set_resizable (GTK_WINDOW (message_dialog), FALSE);
 
248
 
 
249
          g_signal_connect (message_dialog, "response",
 
250
                            G_CALLBACK (gtk_widget_destroy),
 
251
                            NULL);
 
252
 
 
253
          gtk_widget_show (message_dialog);
 
254
 
 
255
          g_error_free (error);
 
256
        }
 
257
      break;
 
258
 
 
259
    default:
 
260
      gtk_widget_destroy (widget);
 
261
    }
 
262
}
 
263
 
 
264
static void
 
265
vino_preferences_info_changed (VinoConnectivityInfo *info,
 
266
                               gpointer              user_data)
 
267
{
 
268
  VinoMessageBox *message_box = VINO_MESSAGE_BOX (user_data);
 
269
  gchar *internal_host, *external_host, *avahi_host;
 
270
  guint16 internal_port, external_port;
 
271
 
 
272
  if (!vino_connectivity_info_get (info,
 
273
                                   &internal_host, &internal_port,
 
274
                                   &external_host, &external_port,
 
275
                                   &avahi_host))
 
276
    {
 
277
      vino_message_box_set_label (message_box,
 
278
                                  _("Checking the connectivity of this machine..."));
 
279
      vino_message_box_show_image (message_box);
 
280
 
 
281
      return;
 
282
    }
 
283
 
 
284
  if (external_host || internal_host)
 
285
    {
 
286
      const gchar *host;
 
287
      GString *message;
 
288
      guint16 port;
 
289
      GString *url;
 
290
 
 
291
      message = g_string_new (NULL);
 
292
      url = g_string_new (NULL);
 
293
      host = external_host;
 
294
      port = external_port;
 
295
 
 
296
      if (host == NULL)
 
297
        {
 
298
          g_string_append (message, _("Your desktop is only reachable over "
 
299
                                      "the local network."));
 
300
          g_string_append_c (message, ' ');
 
301
 
 
302
          host = internal_host;
 
303
          port = internal_port;
 
304
        }
 
305
 
 
306
      g_string_append_printf (url, "<a href=\"vnc://%s::%d\">%s</a>",
 
307
                              host, (guint) port, host);
 
308
 
 
309
      if (avahi_host)
 
310
        {
 
311
          g_string_append (url, _(" or "));
 
312
          g_string_append_printf (url, "<a href=\"vnc://%s::%d\">%s</a>",
 
313
                                  avahi_host, internal_port, avahi_host);
 
314
        } 
 
315
      g_string_append_printf (message, _("Others can access your computer "
 
316
                                         "using the address %s."), url->str);
 
317
 
 
318
      vino_message_box_set_label (message_box, message->str);
 
319
      g_string_free (message, TRUE);
 
320
      g_string_free (url, TRUE);
 
321
    }
 
322
  else
 
323
    vino_message_box_set_label (message_box,
 
324
                                _("Nobody can access your desktop."));
 
325
 
 
326
  vino_message_box_hide_image (message_box);
 
327
 
 
328
  g_free (internal_host);
 
329
  g_free (external_host);
 
330
  g_free (avahi_host);
 
331
}
 
332
 
 
333
static GtkWindow *
 
334
vino_preferences_connect_ui (VinoPreferences *app,
 
335
                             GtkBuilder      *builder)
 
336
{
 
337
  struct {
 
338
    const gchar             *setting;
 
339
    const gchar             *name;
 
340
    const gchar             *property;
 
341
    GSettingsBindFlags       flags;
 
342
    GSettingsBindGetMapping  get_mapping;
 
343
    GSettingsBindSetMapping  set_mapping;
 
344
  } bindings[] = {
 
345
    { "enabled",                "allowed_toggle",        "active",    G_SETTINGS_BIND_DEFAULT, NULL,                NULL                },
 
346
 
 
347
    { "enabled",                "control_settings",      "sensitive", G_SETTINGS_BIND_GET,     NULL,                NULL                },
 
348
    { "view-only",              "view_only_toggle",      "active",    G_SETTINGS_BIND_DEFAULT, get_inverted,        set_inverted        },
 
349
 
 
350
    { "enabled",                "security_settings",     "sensitive", G_SETTINGS_BIND_GET,     NULL,                NULL                },
 
351
    { "prompt-enabled",         "prompt_enabled_toggle", "active",    G_SETTINGS_BIND_DEFAULT, NULL,                NULL                },
 
352
    { "authentication-methods", "password_toggle",       "active",    G_SETTINGS_BIND_DEFAULT, get_authtype,        set_authtype        },
 
353
    { "authentication-methods", "password_box",          "sensitive", G_SETTINGS_BIND_GET,     get_authtype,        NULL                },
 
354
    { "vnc-password",           "password_entry",        "text",      G_SETTINGS_BIND_DEFAULT, get_password,        set_password        },
 
355
    { "use-upnp",               "use_upnp_toggle",       "active",    G_SETTINGS_BIND_DEFAULT, NULL,                NULL                },
 
356
 
 
357
    { "enabled",                "notification_settings", "sensitive", G_SETTINGS_BIND_GET,     NULL,                NULL                },
 
358
 
 
359
    { "icon-visibility",        "icon_always_radio",     "active",    G_SETTINGS_BIND_DEFAULT, get_icon_visibility, set_icon_visibility },
 
360
    { "icon-visibility",        "icon_client_radio",     "active",    G_SETTINGS_BIND_DEFAULT, get_icon_visibility, set_icon_visibility },
 
361
    { "icon-visibility",        "icon_never_radio",      "active",    G_SETTINGS_BIND_DEFAULT, get_icon_visibility, set_icon_visibility }
 
362
  };
 
363
  GSettings *settings;
 
364
  gpointer window;
 
365
  gint i;
 
366
 
 
367
  settings = g_settings_new ("org.gnome.Vino");
 
368
 
 
369
  for (i = 0; i < G_N_ELEMENTS (bindings); i++)
 
370
  {
 
371
    GObject *object =  gtk_builder_get_object (builder, bindings[i].name);
 
372
    g_settings_bind_with_mapping (settings, bindings[i].setting,
 
373
                                  object,
 
374
                                  bindings[i].property,
 
375
                                  bindings[i].flags,
 
376
                                  bindings[i].get_mapping,
 
377
                                  bindings[i].set_mapping,
 
378
                                  object, NULL);
 
379
  }
 
380
 
 
381
  window = gtk_builder_get_object (builder, "vino_dialog");
 
382
  g_signal_connect (window, "response",
 
383
                    G_CALLBACK (vino_preferences_dialog_response), NULL);
 
384
 
 
385
/* Remove reporting of reachability from network to workaround GNOME bug
 
386
 * 596190.
 
387
 * TODO: Fix the bug and remove this workaround. */
 
388
#if 0
 
389
  app->info = vino_connectivity_info_new (gdk_screen_get_number (gtk_window_get_screen (window)));
 
390
  g_signal_connect (app->info, "changed",
 
391
                    G_CALLBACK (vino_preferences_info_changed),
 
392
                    gtk_builder_get_object (builder, "message"));
 
393
  vino_preferences_info_changed (app->info,
 
394
                                 gtk_builder_get_object (builder, "message"));
 
395
#endif
 
396
 
 
397
  g_object_unref (settings);
 
398
  g_object_unref (builder);
 
399
 
 
400
  return window;
 
401
}
 
402
 
 
403
static void
 
404
vino_preferences_create_window (GApplication *g_app)
 
405
{
 
406
  VinoPreferences *app = (VinoPreferences *) g_app;
 
407
  GError     *error = NULL;
 
408
  GtkBuilder *builder;
 
409
  const char *ui_file;
 
410
  GtkWindow  *window;
 
411
 
 
412
  vino_radio_button_get_type ();
 
413
  vino_message_box_get_type ();
 
414
 
 
415
#define VINO_UI_FILE "vino-preferences.ui"
 
416
  if (g_file_test (VINO_UI_FILE, G_FILE_TEST_EXISTS))
 
417
    ui_file = VINO_UI_FILE;
 
418
  else
 
419
    ui_file = VINO_UIDIR "/" VINO_UI_FILE;
 
420
#undef VINO_UI_FILE
 
421
 
 
422
  builder = gtk_builder_new ();
 
423
  if (!gtk_builder_add_from_file (builder, ui_file, &error))
 
424
    {
 
425
      g_warning ("Unable to load ui file '%s': %s", ui_file, error->message);
 
426
      g_error_free (error);
 
427
    }
 
428
 
 
429
  window = vino_preferences_connect_ui (app, builder);
 
430
  gtk_window_set_application (GTK_WINDOW (window), GTK_APPLICATION (app));
 
431
  gtk_widget_show_all(GTK_WIDGET(window));
 
432
}
 
433
 
 
434
static void
 
435
vino_preferences_finalize (GObject *object)
 
436
{
 
437
  VinoPreferences *app = (VinoPreferences *) object;
 
438
 
 
439
/* Remove reporting of reachability from network to workaround GNOME bug
 
440
 * 596190.
 
441
 * TODO: Fix the bug and remove this workaround. */
 
442
#if 0
 
443
  g_object_unref (app->info);
 
444
#endif
 
445
 
 
446
  G_OBJECT_CLASS (vino_preferences_parent_class)->finalize (object);
 
447
}
 
448
 
 
449
static void
 
450
vino_preferences_init (VinoPreferences *app)
 
451
{
 
452
}
 
453
 
 
454
static GtkApplication *
 
455
vino_preferences_new (void)
 
456
{
 
457
  g_type_init();
 
458
 
 
459
  return g_object_new (vino_preferences_get_type (),
 
460
                       "application-id", "org.gnome.Vino.Preferences",
 
461
                       "flags", G_APPLICATION_FLAGS_NONE,
 
462
                       NULL);
 
463
}
 
464
 
 
465
static void
 
466
vino_preferences_activate (GApplication *app)
 
467
{
 
468
  GList *list;
 
469
 
 
470
  list = gtk_application_get_windows (GTK_APPLICATION(app));
 
471
 
 
472
  if (list)
 
473
    gtk_window_present (GTK_WINDOW (list->data));
 
474
  else
 
475
    vino_preferences_create_window (app);
 
476
}
 
477
 
 
478
static void
 
479
vino_preferences_class_init (VinoPreferencesClass *class)
 
480
{
 
481
  GObjectClass *object_class = G_OBJECT_CLASS (class);
 
482
 
 
483
  G_APPLICATION_CLASS (class)->activate = vino_preferences_activate;
 
484
  object_class->finalize                = vino_preferences_finalize;
 
485
}
 
486
 
 
487
int
 
488
main (int argc, char **argv)
 
489
{
 
490
  GtkApplication *app;
 
491
  int status;
 
492
 
 
493
  bindtextdomain (GETTEXT_PACKAGE, VINO_LOCALEDIR);
 
494
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
495
  textdomain (GETTEXT_PACKAGE);
 
496
 
 
497
  gtk_init (&argc, &argv);
 
498
  app = vino_preferences_new ();
 
499
  status = g_application_run (G_APPLICATION(app), argc, argv);
 
500
  g_object_unref (app);
 
501
/* g_settings_sync() is not required with GApplication in recent versions of
 
502
 * Gio, bug 653914. */
 
503
#if GLIB_CHECK_VERSION (2, 29, 2)
 
504
#else
 
505
  g_settings_sync ();
 
506
#endif
 
507
 
 
508
  return status;
 
509
}