~carifio/seahorse/seahorse-remove-broken-help-buttons

« back to all changes in this revision

Viewing changes to plugins/applet/seahorse-applet.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2008-07-22 09:20:59 UTC
  • mto: (3.2.1 sid) (1.4.2 upstream)
  • mto: This revision was merged to the branch mainline in revision 59.
  • Revision ID: james.westby@ubuntu.com-20080722092059-q336t49r9uaveij3
Tags: upstream-2.23.5
ImportĀ upstreamĀ versionĀ 2.23.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 * seahorse-applet.c
3
 
 * 
4
 
 * Copyright (C) 2005 Adam Schreiber <sadam@clemson.edu>
5
 
 * Copyright (C) 1999 Dave Camp
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or modify
8
 
 * it under the terms of the GNU General Public License as published by
9
 
 * the Free Software Foundation; either version 2 of the License, or
10
 
 * (at your option) any later version.
11
 
 * 
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
 */
21
 
 
22
 
#include <config.h>
23
 
#include <gnome.h>
24
 
#include <panel-applet.h>
25
 
 
26
 
#include <dbus/dbus-glib-bindings.h>
27
 
 
28
 
#include <cryptui.h>
29
 
 
30
 
#include "seahorse-applet.h"
31
 
#include "seahorse-gtkstock.h"
32
 
#include "seahorse-context.h"
33
 
#include "seahorse-pgp-key.h"
34
 
#include "seahorse-libdialogs.h"
35
 
#include "seahorse-widget.h"
36
 
#include "seahorse-util.h"
37
 
#include "seahorse-gconf.h"
38
 
#include "seahorse-secure-memory.h"
39
 
#include "seahorse-check-button-control.h"
40
 
 
41
 
#define APPLET_SCHEMAS                SEAHORSE_SCHEMAS "/applet"
42
 
#define SHOW_CLIPBOARD_STATE_KEY      APPLET_SCHEMAS "/show_clipboard_state"
43
 
#define DISPLAY_CLIPBOARD_ENC_KEY     APPLET_SCHEMAS "/display_encrypted_clipboard"
44
 
#define DISPLAY_CLIPBOARD_DEC_KEY     APPLET_SCHEMAS "/display_decrypted_clipboard"
45
 
 
46
 
/* -----------------------------------------------------------------------------
47
 
 * Initialize Crypto 
48
 
 */
49
 
 
50
 
 /* Setup in init_crypt */
51
 
DBusGConnection *dbus_connection = NULL;
52
 
DBusGProxy      *dbus_key_proxy = NULL;
53
 
DBusGProxy      *dbus_crypto_proxy = NULL;
54
 
CryptUIKeyset   *dbus_keyset = NULL;
55
 
 
56
 
static gboolean
57
 
init_crypt ()
58
 
{
59
 
    GError *error = NULL;
60
 
    
61
 
    if (!dbus_connection) {
62
 
        dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
63
 
        if (!dbus_connection) {
64
 
            
65
 
            return FALSE;
66
 
        }
67
 
 
68
 
        dbus_key_proxy = dbus_g_proxy_new_for_name (dbus_connection, "org.gnome.seahorse",
69
 
                                               "/org/gnome/seahorse/keys",
70
 
                                               "org.gnome.seahorse.KeyService");
71
 
        
72
 
        dbus_crypto_proxy = dbus_g_proxy_new_for_name (dbus_connection, "org.gnome.seahorse",
73
 
                                               "/org/gnome/seahorse/crypto",
74
 
                                               "org.gnome.seahorse.CryptoService");
75
 
        
76
 
        dbus_keyset = cryptui_keyset_new ("openpgp", TRUE);
77
 
    }
78
 
    
79
 
    return TRUE;
80
 
}
81
 
/* -----------------------------------------------------------------------------
82
 
 * ICONS AND STATE 
83
 
 */
84
 
 
85
 
#define ICON_CLIPBOARD_UNKNOWN      "seahorse-applet-unknown"
86
 
#define ICON_CLIPBOARD_TEXT         "seahorse-applet-text"
87
 
#define ICON_CLIPBOARD_ENCRYPTED    "seahorse-applet-encrypted"
88
 
#define ICON_CLIPBOARD_SIGNED       "seahorse-applet-signed"
89
 
#define ICON_CLIPBOARD_KEY          "seahorse-applet-key"
90
 
#define ICON_CLIPBOARD_DEFAULT      ICON_CLIPBOARD_ENCRYPTED
91
 
 
92
 
static const gchar *clipboard_icons[] = {
93
 
    ICON_CLIPBOARD_UNKNOWN,
94
 
    ICON_CLIPBOARD_TEXT,
95
 
    ICON_CLIPBOARD_ENCRYPTED,
96
 
    ICON_CLIPBOARD_SIGNED,
97
 
    ICON_CLIPBOARD_KEY,
98
 
    NULL
99
 
};
100
 
 
101
 
typedef enum {
102
 
    SEAHORSE_TEXT_TYPE_NONE,
103
 
    SEAHORSE_TEXT_TYPE_PLAIN,
104
 
    SEAHORSE_TEXT_TYPE_KEY,
105
 
    SEAHORSE_TEXT_TYPE_MESSAGE,
106
 
    SEAHORSE_TEXT_TYPE_SIGNED
107
 
} SeahorseTextType;
108
 
 
109
 
typedef struct _SeahorsePGPHeader {
110
 
    const gchar *header;
111
 
    const gchar *footer;
112
 
    SeahorseTextType type;
113
 
} SeahorsePGPHeader;    
114
 
 
115
 
static const SeahorsePGPHeader seahorse_pgp_headers[] = {
116
 
    { 
117
 
        "-----BEGIN PGP MESSAGE-----", 
118
 
        "-----END PGP MESSAGE-----", 
119
 
        SEAHORSE_TEXT_TYPE_MESSAGE 
120
 
    }, 
121
 
    {
122
 
        "-----BEGIN PGP SIGNED MESSAGE-----",
123
 
        "-----END PGP SIGNATURE-----",
124
 
        SEAHORSE_TEXT_TYPE_SIGNED
125
 
    }, 
126
 
    {
127
 
        "-----BEGIN PGP PUBLIC KEY BLOCK-----",
128
 
        "-----END PGP PUBLIC KEY BLOCK-----",
129
 
        SEAHORSE_TEXT_TYPE_KEY
130
 
    }, 
131
 
    {
132
 
        "-----BEGIN PGP PRIVATE KEY BLOCK-----",
133
 
        "-----END PGP PRIVATE KEY BLOCK-----",
134
 
        SEAHORSE_TEXT_TYPE_KEY
135
 
    }
136
 
};
137
 
 
138
 
/* -----------------------------------------------------------------------------
139
 
 * OBJECT DECLARATION
140
 
 */
141
 
 
142
 
typedef struct _SeahorseAppletPrivate {
143
 
    GtkWidget           *image;
144
 
    GtkTooltips         *tooltips;
145
 
    SeahorseContext     *context;
146
 
    GtkClipboard        *board;
147
 
    GtkWidget           *menu;
148
 
    SeahorseTextType    clipboard_contents;
149
 
} SeahorseAppletPrivate;
150
 
 
151
 
#define SEAHORSE_APPLET_GET_PRIVATE(obj)  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SEAHORSE_TYPE_APPLET, SeahorseAppletPrivate))
152
 
 
153
 
G_DEFINE_TYPE (SeahorseApplet, seahorse_applet, PANEL_TYPE_APPLET);
154
 
 
155
 
/* -----------------------------------------------------------------------------
156
 
 * INTERNAL HELPERS
157
 
 */
158
 
 
159
 
static void
160
 
init_context (SeahorseApplet *sapplet)
161
 
{
162
 
    SeahorseAppletPrivate *priv;
163
 
    
164
 
    priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
165
 
    if (!priv->context) {
166
 
        priv->context = seahorse_context_new (SEAHORSE_CONTEXT_APP, SKEY_PGP);
167
 
        seahorse_context_load_local_keys_async (priv->context);
168
 
    }
169
 
}
170
 
 
171
 
SeahorseTextType    
172
 
detect_text_type (const gchar *text, gint len, const gchar **start, const gchar **end)
173
 
{
174
 
    const SeahorsePGPHeader *header;
175
 
    const gchar *pos = NULL;
176
 
    const gchar *t;
177
 
    int i;
178
 
    
179
 
    if (len == -1)
180
 
        len = strlen (text);
181
 
    
182
 
    /* Find the first of the headers */
183
 
    for (i = 0; i < (sizeof (seahorse_pgp_headers) / sizeof (seahorse_pgp_headers[0])); i++) {
184
 
        t = g_strstr_len (text, len, seahorse_pgp_headers[i].header);
185
 
        if (t != NULL) {
186
 
            if (pos == NULL || (t < pos)) {
187
 
                header = &(seahorse_pgp_headers[i]);
188
 
                pos = t;
189
 
            }
190
 
        }
191
 
    }
192
 
    
193
 
    if (pos != NULL) {
194
 
        
195
 
        if (start)
196
 
            *start = pos;
197
 
        
198
 
        /* Find the end of that block */
199
 
        t = g_strstr_len (pos, len - (pos - text), header->footer);
200
 
        if (t != NULL && end)
201
 
            *end = t + strlen(header->footer);
202
 
        else if (end)
203
 
            *end = NULL;
204
 
            
205
 
        return header->type;
206
 
    }
207
 
    
208
 
    return SEAHORSE_TEXT_TYPE_PLAIN;
209
 
}
210
 
 
211
 
static void 
212
 
update_icon (SeahorseApplet *sapplet)
213
 
{
214
 
    SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
215
 
    const char *stock = NULL;
216
 
    
217
 
    if (seahorse_gconf_get_boolean (SHOW_CLIPBOARD_STATE_KEY)) {
218
 
        switch (priv->clipboard_contents) {
219
 
        case SEAHORSE_TEXT_TYPE_NONE:
220
 
            stock = ICON_CLIPBOARD_UNKNOWN;
221
 
            break;
222
 
        case SEAHORSE_TEXT_TYPE_PLAIN:
223
 
            stock = ICON_CLIPBOARD_TEXT;
224
 
            break;
225
 
        case SEAHORSE_TEXT_TYPE_KEY:
226
 
            stock = ICON_CLIPBOARD_KEY;
227
 
            break;
228
 
        case SEAHORSE_TEXT_TYPE_MESSAGE:
229
 
            stock = ICON_CLIPBOARD_ENCRYPTED;
230
 
            break;
231
 
        case SEAHORSE_TEXT_TYPE_SIGNED:
232
 
            stock = ICON_CLIPBOARD_SIGNED;
233
 
            break;
234
 
        default:
235
 
            g_assert_not_reached ();
236
 
            return;
237
 
        };
238
 
        
239
 
    } else {
240
 
        stock = ICON_CLIPBOARD_DEFAULT;
241
 
    }
242
 
    
243
 
    gtk_image_set_from_stock (GTK_IMAGE (priv->image), stock, GTK_ICON_SIZE_LARGE_TOOLBAR);
244
 
}
245
 
 
246
 
static void
247
 
detect_received(GtkClipboard *board, const gchar *text, SeahorseApplet *sapplet)
248
 
{
249
 
    SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
250
 
    
251
 
    if (!text || !*text)
252
 
        priv->clipboard_contents = SEAHORSE_TEXT_TYPE_NONE;
253
 
    else
254
 
        priv->clipboard_contents = detect_text_type (text, -1, NULL, NULL);
255
 
    
256
 
    update_icon (sapplet);
257
 
}
258
 
 
259
 
static void 
260
 
handle_clipboard_owner_change(GtkClipboard *clipboard, GdkEvent *event, 
261
 
                              SeahorseApplet *sapplet)
262
 
{
263
 
    SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
264
 
    priv->board = clipboard; 
265
 
    
266
 
    if (seahorse_gconf_get_boolean (SHOW_CLIPBOARD_STATE_KEY)) 
267
 
        gtk_clipboard_request_text (clipboard,
268
 
             (GtkClipboardTextReceivedFunc)detect_received, sapplet);
269
 
    else
270
 
        update_icon (sapplet);
271
 
}
272
 
 
273
 
/* Makes URL in About Dialog Clickable */
274
 
static void about_dialog_activate_link_cb (GtkAboutDialog *about,
275
 
                                           const gchar *url,
276
 
                                           gpointer data)
277
 
{
278
 
        gnome_url_show (url, NULL);
279
 
}
280
 
 
281
 
static void
282
 
about_cb (BonoboUIComponent *uic, SeahorseApplet *sapplet, const gchar *verbname)
283
 
{                   
284
 
    static gboolean been_here = FALSE;
285
 
    
286
 
    static const gchar *authors [] = {
287
 
        "Adam Schreiber <sadam@clemson.edu>",
288
 
        "Stef Walter <stef@memberwebs.com>",
289
 
        NULL    
290
 
    };
291
 
 
292
 
    static const gchar *documenters[] = {
293
 
        "Adam Schreiber <sadam@clemson.edu>",
294
 
        NULL
295
 
    };
296
 
    
297
 
    static const gchar *artists[] = {
298
 
        "Stef Walter <stef@memberwebs.com>",
299
 
        NULL    
300
 
    };
301
 
    
302
 
        if (!been_here)
303
 
        {
304
 
                been_here = TRUE;
305
 
                gtk_about_dialog_set_url_hook (about_dialog_activate_link_cb, NULL, NULL);
306
 
        }
307
 
        
308
 
    gtk_show_about_dialog (NULL, 
309
 
                "name", _("seahorse-applet"),
310
 
                "version", VERSION,
311
 
                "comments", _("Use PGP/GPG to encrypt/decrypt/sign/verify/import the clipboard."),
312
 
                "copyright", "\xC2\xA9 2005, 2006 Adam Schreiber",
313
 
                "authors", authors,
314
 
                "documenters", documenters,
315
 
                "artists", artists,
316
 
                "translator-credits", _("translator-credits"),
317
 
                "logo-icon-name", "seahorse-applet",
318
 
                "website", "http://www.gnome.org/projects/seahorse",
319
 
                "website-label", _("Seahorse Project Homepage"),
320
 
                NULL);
321
 
}
322
 
 
323
 
static void
324
 
display_text (gchar *title, gchar *text, gboolean editable)
325
 
{
326
 
    GtkWidget *dialog, *scrolled_window, *text_view;
327
 
    GtkTextBuffer *buffer;
328
 
    GdkPixbuf *pixbuf;
329
 
 
330
 
    dialog = gtk_dialog_new_with_buttons (title, NULL, 0,
331
 
                                          GTK_STOCK_CLOSE, GTK_RESPONSE_NONE, NULL);
332
 
 
333
 
    gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 450);
334
 
    g_signal_connect_swapped (dialog, "response", 
335
 
                              G_CALLBACK (gtk_widget_destroy), dialog);
336
 
 
337
 
    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
338
 
    gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scrolled_window);
339
 
 
340
 
    text_view = gtk_text_view_new ();
341
 
    gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), editable);
342
 
    gtk_text_view_set_left_margin (GTK_TEXT_VIEW (text_view), 8);
343
 
    gtk_text_view_set_right_margin (GTK_TEXT_VIEW (text_view), 8);
344
 
    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), GTK_WRAP_WORD);
345
 
    gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
346
 
    
347
 
    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
348
 
    gtk_text_buffer_set_text (buffer, text, strlen (text));
349
 
 
350
 
    pixbuf = gtk_widget_render_icon (dialog, 
351
 
                                     ICON_CLIPBOARD_DEFAULT, 
352
 
                                     (GtkIconSize)-1, 
353
 
                                     NULL);
354
 
                                     
355
 
    gtk_window_set_icon (GTK_WINDOW (dialog), pixbuf);
356
 
    
357
 
    g_object_unref(pixbuf);
358
 
    
359
 
    gtk_widget_show_all (dialog);
360
 
}
361
 
 
362
 
static void
363
 
encrypt_received (GtkClipboard *board, const gchar *text, SeahorseApplet *sapplet)
364
 
{
365
 
    gchar *signer = NULL;
366
 
    gchar *enctext = NULL;
367
 
    gchar **keys;
368
 
    gboolean ret;
369
 
 
370
 
    /* No text on clipboard */
371
 
    if (!text)
372
 
        return;
373
 
 
374
 
    /* Get the recipient list */
375
 
    keys = cryptui_prompt_recipients (dbus_keyset, _("Choose Recipient Keys"), &signer);
376
 
 
377
 
    /* User may have cancelled */
378
 
    if (keys && *keys) {
379
 
        ret = dbus_g_proxy_call (dbus_crypto_proxy, "EncryptText", NULL, 
380
 
                                G_TYPE_STRV, keys, 
381
 
                                G_TYPE_STRING, signer, 
382
 
                                G_TYPE_INT, 0,
383
 
                                G_TYPE_STRING, text,
384
 
                                G_TYPE_INVALID,
385
 
                                G_TYPE_STRING, &enctext,
386
 
                                G_TYPE_INVALID);
387
 
    
388
 
        if (ret) {
389
 
            /* And finish up */
390
 
            gtk_clipboard_set_text (board, enctext, strlen (enctext));
391
 
            detect_received (board, enctext, sapplet);
392
 
            
393
 
            if (seahorse_gconf_get_boolean (DISPLAY_CLIPBOARD_ENC_KEY) == TRUE)
394
 
                display_text (_("Encrypted Text"), enctext, FALSE);
395
 
        } else {
396
 
            seahorse_notification_display(_("Encryption Failed"),
397
 
                                          _("The clipboard could not be encrypted."),
398
 
                                          FALSE,
399
 
                                          NULL,
400
 
                                          GTK_WIDGET(sapplet));
401
 
        }
402
 
        g_strfreev(keys);
403
 
        g_free (signer);
404
 
        g_free (enctext);
405
 
    }
406
 
}
407
 
 
408
 
static void
409
 
encrypt_cb (GtkMenuItem *menuitem, SeahorseApplet *sapplet)
410
 
{
411
 
    SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
412
 
    
413
 
    if(!init_crypt ())
414
 
        return;
415
 
 
416
 
    gtk_clipboard_request_text (priv->board,
417
 
            (GtkClipboardTextReceivedFunc)encrypt_received, sapplet);
418
 
}
419
 
 
420
 
static void
421
 
sign_received (GtkClipboard *board, const gchar *text, SeahorseApplet *sapplet)
422
 
{
423
 
    gchar *signer = NULL;
424
 
    gchar *enctext = NULL;
425
 
    gboolean ret;
426
 
    
427
 
    /* No text on clipboard */
428
 
    if (!text)
429
 
        return;
430
 
 
431
 
    signer = cryptui_prompt_signer (dbus_keyset, _("Choose Key to Sign with"));
432
 
    if (signer == NULL)
433
 
        return;
434
 
 
435
 
    /* Perform the signing */
436
 
    ret = dbus_g_proxy_call (dbus_crypto_proxy, "SignText", NULL, 
437
 
                                G_TYPE_STRING, signer, 
438
 
                                G_TYPE_INT, 0,
439
 
                                G_TYPE_STRING, text,
440
 
                                G_TYPE_INVALID,
441
 
                                G_TYPE_STRING, &enctext,
442
 
                                G_TYPE_INVALID);
443
 
     
444
 
     if (ret) {                          
445
 
        /* And finish up */
446
 
        gtk_clipboard_set_text (board, enctext, strlen (enctext));
447
 
        detect_received (board, enctext, sapplet);
448
 
 
449
 
        if (seahorse_gconf_get_boolean (DISPLAY_CLIPBOARD_ENC_KEY) == TRUE)
450
 
            display_text (_("Signed Text"), enctext, FALSE);
451
 
    } else {
452
 
        seahorse_notification_display(_("Signing Failed"),
453
 
                                      _("The clipboard could not be Signed."),
454
 
                                      FALSE,
455
 
                                      NULL,
456
 
                                      GTK_WIDGET(sapplet));
457
 
    }
458
 
    
459
 
    g_free (signer);
460
 
    g_free (enctext);
461
 
}
462
 
 
463
 
static void
464
 
sign_cb (GtkMenuItem *menuitem, SeahorseApplet *sapplet)
465
 
{
466
 
    SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
467
 
 
468
 
    if(!init_crypt ())
469
 
        return;
470
 
 
471
 
    gtk_clipboard_request_text (priv->board,
472
 
            (GtkClipboardTextReceivedFunc)sign_received, sapplet);
473
 
}
474
 
 
475
 
/* When we try to 'decrypt' a key, this gets called */
476
 
static guint
477
 
import_keys (const gchar *text, SeahorseApplet *sapplet)
478
 
{
479
 
    gchar **keys, **k;
480
 
    gint nkeys = 0;
481
 
    gboolean ret;
482
 
 
483
 
    ret = dbus_g_proxy_call (dbus_key_proxy, "ImportKeys", NULL,
484
 
                             G_TYPE_STRING, "openpgp",
485
 
                             G_TYPE_STRING, text,
486
 
                             G_TYPE_INVALID,
487
 
                             G_TYPE_STRV, &keys,
488
 
                             G_TYPE_INVALID);
489
 
                             
490
 
    if (ret) {
491
 
        for (k = keys, nkeys = 0; *k; k++)
492
 
            nkeys++;
493
 
        g_strfreev (keys);
494
 
        
495
 
        if (!nkeys)
496
 
            seahorse_notification_display(_("Import Failed"),
497
 
                                      _("Keys were found but not imported."),
498
 
                                      FALSE,
499
 
                                      NULL,
500
 
                                      GTK_WIDGET(sapplet));
501
 
    }
502
 
    
503
 
    return nkeys;
504
 
}
505
 
 
506
 
/* Decrypt an encrypted message */
507
 
static gchar*
508
 
decrypt_text (const gchar *text, SeahorseApplet *sapplet)
509
 
{
510
 
    gchar *rawtext = NULL;
511
 
    gchar *signer = NULL;
512
 
    gboolean ret;
513
 
    
514
 
    ret = dbus_g_proxy_call (dbus_crypto_proxy, "DecryptText", NULL,
515
 
                             G_TYPE_STRING, "openpgp",
516
 
                             G_TYPE_INT, 0,
517
 
                             G_TYPE_STRING, text,
518
 
                             G_TYPE_INVALID, 
519
 
                             G_TYPE_STRING, &rawtext,
520
 
                             G_TYPE_STRING, &signer,
521
 
                             G_TYPE_INVALID);
522
 
 
523
 
    if (ret) {
524
 
        g_free (signer);
525
 
        
526
 
        return rawtext;
527
 
    } else {
528
 
        seahorse_notification_display(_("Decrypting Failed"),
529
 
                                      _("Text may be malformed."),
530
 
                                      FALSE,
531
 
                                      NULL,
532
 
                                      GTK_WIDGET(sapplet));
533
 
        return NULL;
534
 
    }
535
 
}
536
 
 
537
 
/* Verify a signed message */
538
 
static gchar*
539
 
verify_text (const gchar *text, SeahorseApplet *sapplet)
540
 
{
541
 
    gchar *rawtext = NULL;
542
 
    gchar *signer;
543
 
    gboolean ret;
544
 
 
545
 
    ret = dbus_g_proxy_call (dbus_crypto_proxy, "VerifyText", NULL,
546
 
                             G_TYPE_STRING, "openpgp",
547
 
                             G_TYPE_INT, 0,
548
 
                             G_TYPE_STRING, text,
549
 
                             G_TYPE_INVALID, 
550
 
                             G_TYPE_STRING, &rawtext,
551
 
                             G_TYPE_STRING, &signer,
552
 
                             G_TYPE_INVALID);
553
 
    
554
 
    if (ret) {
555
 
        /* Not interested in the signer */
556
 
        g_free (signer);
557
 
        return rawtext;
558
 
        
559
 
    } else {
560
 
        return NULL;
561
 
    }
562
 
}
563
 
 
564
 
static void
565
 
dvi_received (GtkClipboard *board, const gchar *text, SeahorseApplet *sapplet)
566
 
{
567
 
    SeahorseTextType type;      /* Type of the current block */
568
 
    gchar *rawtext = NULL;      /* Replacement text */
569
 
    guint keys = 0;             /* Number of keys imported */
570
 
    const gchar *start;         /* Pointer to start of the block */
571
 
    const gchar *end;           /* Pointer to end of the block */
572
 
    
573
 
    /* Try to figure out what clipboard contains */
574
 
    if (text == NULL)
575
 
                type = SEAHORSE_TEXT_TYPE_NONE;
576
 
        else 
577
 
            type = detect_text_type (text, -1, &start, &end);
578
 
    
579
 
    if (type == SEAHORSE_TEXT_TYPE_NONE || type == SEAHORSE_TEXT_TYPE_PLAIN) {
580
 
        seahorse_notification_display(_("No PGP key or message was found on clipboard"),
581
 
                                      _("No PGP data found."), FALSE, NULL, GTK_WIDGET(sapplet));
582
 
                return;
583
 
        }
584
 
    
585
 
    switch (type) {
586
 
 
587
 
    /* A key, import it */
588
 
    case SEAHORSE_TEXT_TYPE_KEY:
589
 
        keys = import_keys (text, sapplet);
590
 
        break;
591
 
 
592
 
    /* A message decrypt it */
593
 
    case SEAHORSE_TEXT_TYPE_MESSAGE:
594
 
        rawtext = decrypt_text (text, sapplet);
595
 
        break;
596
 
 
597
 
    /* A message verify it */
598
 
    case SEAHORSE_TEXT_TYPE_SIGNED:
599
 
        rawtext = verify_text (text, sapplet);
600
 
        break;
601
 
 
602
 
    default:
603
 
        g_assert_not_reached ();
604
 
        break;
605
 
    };
606
 
    
607
 
    /* We got replacement text */
608
 
    if (rawtext) {
609
 
 
610
 
        gtk_clipboard_set_text (board, rawtext, strlen (rawtext));
611
 
        detect_received (board, rawtext, sapplet);
612
 
        
613
 
        if (seahorse_gconf_get_boolean (DISPLAY_CLIPBOARD_DEC_KEY) == TRUE)
614
 
        {
615
 
            /* TRANSLATORS: This means 'The text that was decrypted' */
616
 
            display_text (_("Decrypted Text"), rawtext, TRUE);
617
 
        }
618
 
        
619
 
        g_free (rawtext);
620
 
        rawtext = NULL;
621
 
    }
622
 
}
623
 
 
624
 
static void
625
 
dvi_cb (GtkMenuItem *menuitem, SeahorseApplet *sapplet)
626
 
{
627
 
    SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
628
 
 
629
 
    if (!init_crypt ())
630
 
        return;
631
 
        
632
 
    gtk_clipboard_request_text (priv->board,
633
 
            (GtkClipboardTextReceivedFunc)dvi_received, sapplet);
634
 
}
635
 
 
636
 
void
637
 
properties_cb (BonoboUIComponent *uic, SeahorseApplet *sapplet, const char *verbname)
638
 
{
639
 
    SeahorseWidget *swidget;
640
 
    GtkWidget *widget;
641
 
    GdkPixbuf *pixbuf;
642
 
    
643
 
    /* SeahorseWidget needs a SeahorseContext initialized */
644
 
    init_context (sapplet);
645
 
    
646
 
    swidget = seahorse_widget_new ("applet-preferences", NULL);
647
 
    
648
 
    widget = glade_xml_get_widget (swidget->xml, swidget->name);
649
 
 
650
 
    pixbuf = gtk_widget_render_icon (widget, 
651
 
                                     ICON_CLIPBOARD_DEFAULT, 
652
 
                                     (GtkIconSize)-1, 
653
 
                                     NULL);
654
 
                                     
655
 
    gtk_window_set_icon (GTK_WINDOW (widget), pixbuf);
656
 
    
657
 
    g_object_unref(pixbuf);
658
 
    
659
 
    /* Preferences window is already open */
660
 
    if (!swidget)
661
 
        return;
662
 
    
663
 
    widget = glade_xml_get_widget (swidget->xml, "show-clipboard-state");
664
 
    if (widget && GTK_IS_CHECK_BUTTON (widget))
665
 
        seahorse_check_button_gconf_attach (GTK_CHECK_BUTTON (widget), SHOW_CLIPBOARD_STATE_KEY);
666
 
    
667
 
    widget = glade_xml_get_widget (swidget->xml, "display-encrypted-clipboard");
668
 
    if (widget && GTK_IS_CHECK_BUTTON (widget))
669
 
        seahorse_check_button_gconf_attach (GTK_CHECK_BUTTON (widget), DISPLAY_CLIPBOARD_ENC_KEY);
670
 
    
671
 
    widget = glade_xml_get_widget (swidget->xml, "display-decrypted-clipboard");
672
 
    if (widget && GTK_IS_CHECK_BUTTON (widget))
673
 
        seahorse_check_button_gconf_attach (GTK_CHECK_BUTTON (widget), DISPLAY_CLIPBOARD_DEC_KEY);
674
 
    
675
 
    seahorse_widget_show (swidget);
676
 
}
677
 
 
678
 
static void
679
 
help_cb (BonoboUIComponent *uic, SeahorseApplet *sapplet, const char *verbname)
680
 
{
681
 
    GError *err = NULL;
682
 
    
683
 
    gnome_help_display ("seahorse-applet", NULL, &err);
684
 
    if (err)
685
 
        seahorse_util_handle_error(err, _("Could not display the help file"));
686
 
}
687
 
 
688
 
static void
689
 
seahorse_popup_position_menu (GtkMenu *menu, int *x, int *y, gboolean *push_in, 
690
 
                              gpointer gdata)
691
 
{
692
 
    GtkWidget *widget;
693
 
    GtkRequisition requisition;
694
 
    gint menu_xpos;
695
 
    gint menu_ypos;
696
 
 
697
 
    widget = GTK_WIDGET (gdata);
698
 
 
699
 
    gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
700
 
    gdk_window_get_origin (widget->window, &menu_xpos, &menu_ypos);
701
 
 
702
 
    menu_xpos += widget->allocation.x;
703
 
    menu_ypos += widget->allocation.y;
704
 
 
705
 
    switch (panel_applet_get_orient (PANEL_APPLET (widget))) {
706
 
    case PANEL_APPLET_ORIENT_DOWN:
707
 
    case PANEL_APPLET_ORIENT_UP:
708
 
        if (menu_ypos > gdk_screen_get_height (gtk_widget_get_screen (widget)) / 2)
709
 
            menu_ypos -= requisition.height;
710
 
        else
711
 
            menu_ypos += widget->allocation.height;
712
 
        break;
713
 
    case PANEL_APPLET_ORIENT_RIGHT:
714
 
    case PANEL_APPLET_ORIENT_LEFT:
715
 
        if (menu_xpos > gdk_screen_get_width (gtk_widget_get_screen (widget)) / 2)
716
 
            menu_xpos -= requisition.width;
717
 
        else
718
 
            menu_xpos += widget->allocation.width;
719
 
        break;
720
 
    default:
721
 
        g_assert_not_reached ();
722
 
    }
723
 
           
724
 
    *x = menu_xpos;
725
 
    *y = menu_ypos;
726
 
    *push_in = TRUE;
727
 
}
728
 
 
729
 
static gboolean 
730
 
handle_button_press (GtkWidget *widget, GdkEventButton *event)
731
 
{
732
 
    GtkWidget *item;    
733
 
    SeahorseApplet *applet = SEAHORSE_APPLET (widget);
734
 
    SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (applet);
735
 
    
736
 
    if (event->button == 1) {
737
 
        
738
 
        if (priv->menu) {
739
 
            gtk_widget_destroy (priv->menu);
740
 
            priv->menu = NULL;
741
 
        }
742
 
        
743
 
        /* Build Menu */
744
 
        priv->menu = gtk_menu_new ();
745
 
        
746
 
        if (priv->clipboard_contents == SEAHORSE_TEXT_TYPE_PLAIN ||
747
 
            priv->clipboard_contents == SEAHORSE_TEXT_TYPE_NONE) {
748
 
            item = gtk_image_menu_item_new_with_mnemonic (_("_Encrypt Clipboard"));
749
 
            g_signal_connect (item, "activate", G_CALLBACK (encrypt_cb), applet);
750
 
            gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
751
 
        }
752
 
        
753
 
        if (priv->clipboard_contents == SEAHORSE_TEXT_TYPE_PLAIN ||
754
 
            priv->clipboard_contents == SEAHORSE_TEXT_TYPE_NONE) {
755
 
            item = gtk_image_menu_item_new_with_mnemonic (_("_Sign Clipboard"));
756
 
            g_signal_connect (item, "activate", G_CALLBACK (sign_cb), applet);
757
 
            gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
758
 
        }
759
 
        
760
 
        if (priv->clipboard_contents == SEAHORSE_TEXT_TYPE_MESSAGE ||
761
 
            priv->clipboard_contents == SEAHORSE_TEXT_TYPE_SIGNED) {
762
 
            item = gtk_image_menu_item_new_with_mnemonic (_("_Decrypt/Verify Clipboard"));
763
 
            g_signal_connect (item, "activate", G_CALLBACK (dvi_cb), applet);
764
 
            gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
765
 
        }
766
 
        
767
 
        if (priv->clipboard_contents == SEAHORSE_TEXT_TYPE_KEY) {
768
 
            item = gtk_image_menu_item_new_with_mnemonic (_("_Import Keys from Clipboard"));
769
 
            g_signal_connect (item, "activate", G_CALLBACK (dvi_cb), applet);
770
 
            gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
771
 
        }
772
 
        
773
 
        gtk_widget_show_all (priv->menu);
774
 
        
775
 
        gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, seahorse_popup_position_menu, 
776
 
                        (gpointer)applet, event->button, event->time);
777
 
        return TRUE;
778
 
    }
779
 
    
780
 
    if (GTK_WIDGET_CLASS (seahorse_applet_parent_class)->button_press_event)
781
 
        return (* GTK_WIDGET_CLASS (seahorse_applet_parent_class)->button_press_event) (widget, event);
782
 
    
783
 
    return FALSE;
784
 
}
785
 
 
786
 
static void
787
 
set_atk_name_description (GtkWidget *widget, const gchar *name, const gchar *description)
788
 
{
789
 
    AtkObject *aobj = gtk_widget_get_accessible (widget);
790
 
    
791
 
    /* Check if gail is loaded */
792
 
    if (GTK_IS_ACCESSIBLE (aobj) == FALSE)
793
 
        return;
794
 
 
795
 
    atk_object_set_name (aobj, name);
796
 
    atk_object_set_description (aobj, description);
797
 
}
798
 
 
799
 
static void
800
 
gconf_notify (GConfClient *client, guint id, GConfEntry *entry, gpointer *data)
801
 
{
802
 
    update_icon (SEAHORSE_APPLET (data));
803
 
}
804
 
 
805
 
/* -----------------------------------------------------------------------------
806
 
 * OBJECT 
807
 
 */
808
 
 
809
 
static void
810
 
seahorse_applet_init (SeahorseApplet *applet)
811
 
{
812
 
    SeahorseAppletPrivate *priv;
813
 
    GdkAtom atom;
814
 
    GtkClipboard *board;
815
 
    
816
 
    priv = SEAHORSE_APPLET_GET_PRIVATE (applet);
817
 
    
818
 
    /* 
819
 
     * We initialize the context on first operation to avoid 
820
 
     * problems with slowing down gnome-panel loading at 
821
 
     * login.
822
 
     */
823
 
    
824
 
    priv->clipboard_contents = SEAHORSE_TEXT_TYPE_NONE;
825
 
    
826
 
    priv->image = gtk_image_new ();
827
 
    priv->tooltips = gtk_tooltips_new ();
828
 
 
829
 
    gtk_container_add (GTK_CONTAINER (applet), priv->image);
830
 
 
831
 
    g_object_ref (priv->tooltips);
832
 
    gtk_object_sink (GTK_OBJECT (priv->tooltips));
833
 
    gtk_tooltips_set_tip (priv->tooltips, GTK_WIDGET (applet), _("Encryption Applet"), NULL);
834
 
 
835
 
    set_atk_name_description (GTK_WIDGET (applet), _("Encryption Applet"), 
836
 
                              _("Use PGP/GPG to encrypt/decrypt/sign/verify/import the clipboard."));
837
 
 
838
 
    /* Setup Clipboard Handling */
839
 
    atom = gdk_atom_intern ("CLIPBOARD", FALSE);
840
 
    board = gtk_clipboard_get (atom);
841
 
    handle_clipboard_owner_change (board, NULL, applet);
842
 
    g_signal_connect (board, "owner-change",
843
 
                      G_CALLBACK (handle_clipboard_owner_change), applet);
844
 
    
845
 
    atom = gdk_atom_intern ("PRIMARY", FALSE);
846
 
    board = gtk_clipboard_get (atom);
847
 
    g_signal_connect (board, "owner-change",
848
 
                      G_CALLBACK (handle_clipboard_owner_change), applet);
849
 
                      
850
 
}
851
 
 
852
 
static void
853
 
seahorse_applet_change_background (PanelApplet *applet, PanelAppletBackgroundType type,
854
 
                                   GdkColor *colour, GdkPixmap *pixmap)
855
 
{
856
 
    GtkRcStyle *rc_style;
857
 
    GtkStyle *style;
858
 
 
859
 
    /* reset style */
860
 
    gtk_widget_set_style (GTK_WIDGET (applet), NULL);
861
 
    rc_style = gtk_rc_style_new ();
862
 
    gtk_widget_modify_style (GTK_WIDGET (applet), rc_style);
863
 
    gtk_rc_style_unref (rc_style);
864
 
 
865
 
    switch (type){
866
 
    case PANEL_NO_BACKGROUND:
867
 
        break;
868
 
    case PANEL_COLOR_BACKGROUND:
869
 
        gtk_widget_modify_bg (GTK_WIDGET (applet), GTK_STATE_NORMAL, colour);
870
 
        break;
871
 
    case PANEL_PIXMAP_BACKGROUND:
872
 
        style = gtk_style_copy (GTK_WIDGET (applet)->style);
873
 
 
874
 
        if (style->bg_pixmap[GTK_STATE_NORMAL])
875
 
            g_object_unref (style->bg_pixmap[GTK_STATE_NORMAL]);
876
 
 
877
 
        style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref (pixmap);
878
 
        gtk_widget_set_style (GTK_WIDGET (applet), style);
879
 
        g_object_unref (style);
880
 
        break;
881
 
    }
882
 
}
883
 
 
884
 
static void
885
 
seahorse_applet_finalize (GObject *object)
886
 
{
887
 
    SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (object);
888
 
 
889
 
    if (priv) {
890
 
        if (priv->context)
891
 
            seahorse_context_destroy (priv->context);
892
 
        priv->context = NULL;
893
 
        
894
 
        if (priv->menu)
895
 
            gtk_widget_destroy (priv->menu);
896
 
        priv->menu = NULL;
897
 
        
898
 
        if (priv->tooltips)
899
 
            g_object_unref (G_OBJECT (priv->tooltips));
900
 
        priv->tooltips = NULL;
901
 
    }
902
 
    
903
 
    if (G_OBJECT_CLASS (seahorse_applet_parent_class)->finalize)
904
 
        (* G_OBJECT_CLASS (seahorse_applet_parent_class)->finalize) (object);
905
 
        
906
 
    if (dbus_key_proxy)
907
 
        g_object_unref (dbus_key_proxy);
908
 
    dbus_key_proxy = NULL;
909
 
    
910
 
    if (dbus_crypto_proxy)
911
 
        g_object_unref (dbus_crypto_proxy);
912
 
    dbus_crypto_proxy = NULL;
913
 
    
914
 
    if (dbus_connection)
915
 
        dbus_g_connection_unref (dbus_connection);
916
 
    dbus_connection = NULL;
917
 
}
918
 
 
919
 
static void
920
 
seahorse_applet_class_init (SeahorseAppletClass *klass)
921
 
{
922
 
    GObjectClass *object_class;
923
 
    PanelAppletClass *applet_class;
924
 
    GtkWidgetClass *widget_class;
925
 
 
926
 
    object_class = G_OBJECT_CLASS (klass);
927
 
    applet_class = PANEL_APPLET_CLASS (klass);
928
 
    widget_class = GTK_WIDGET_CLASS(klass);
929
 
 
930
 
    object_class->finalize = seahorse_applet_finalize;
931
 
    applet_class->change_background = seahorse_applet_change_background;
932
 
    widget_class->button_press_event = handle_button_press;
933
 
 
934
 
    g_type_class_add_private (object_class, sizeof (SeahorseAppletPrivate));
935
 
    
936
 
}
937
 
 
938
 
 
939
 
/* -----------------------------------------------------------------------------
940
 
 * APPLET
941
 
 */
942
 
 
943
 
static const BonoboUIVerb seahorse_applet_menu_verbs [] = {
944
 
    BONOBO_UI_UNSAFE_VERB ("Props", properties_cb),
945
 
    BONOBO_UI_UNSAFE_VERB ("Help", help_cb),
946
 
    BONOBO_UI_UNSAFE_VERB ("About", about_cb),
947
 
    BONOBO_UI_VERB_END
948
 
};
949
 
 
950
 
static gboolean
951
 
seahorse_applet_fill (PanelApplet *applet)
952
 
{
953
 
    SeahorseApplet *sapplet = SEAHORSE_APPLET (applet);
954
 
    BonoboUIComponent *pcomp;
955
 
 
956
 
    /* Insert Icons into Stock */ 
957
 
    seahorse_gtkstock_init ();
958
 
    seahorse_gtkstock_add_icons (clipboard_icons);
959
 
    g_return_val_if_fail (PANEL_IS_APPLET (applet), FALSE);
960
 
    gtk_widget_show_all (GTK_WIDGET (applet));
961
 
 
962
 
    panel_applet_setup_menu_from_file (applet, UIDIR, "GNOME_SeahorseApplet.xml",
963
 
                                       NULL, seahorse_applet_menu_verbs, sapplet);
964
 
        
965
 
    pcomp = panel_applet_get_popup_component (applet);
966
 
 
967
 
    if (panel_applet_get_locked_down (applet))
968
 
        bonobo_ui_component_set_prop (pcomp, "/commands/Props", "hidden", "1", NULL);    
969
 
 
970
 
    update_icon (sapplet);
971
 
    seahorse_gconf_notify_lazy (APPLET_SCHEMAS, (GConfClientNotifyFunc)gconf_notify, 
972
 
                                sapplet, GTK_WIDGET (applet));
973
 
    
974
 
    return TRUE;
975
 
}
976
 
 
977
 
static gboolean
978
 
seahorse_applet_factory (PanelApplet *applet, const gchar *iid, gpointer data)
979
 
{
980
 
    gboolean retval = FALSE;
981
 
 
982
 
    if (!strcmp (iid, "OAFIID:GNOME_SeahorseApplet"))
983
 
        retval = seahorse_applet_fill (applet); 
984
 
   
985
 
    if (retval == FALSE)
986
 
        exit (-1);
987
 
 
988
 
    return retval;
989
 
}
990
 
 
991
 
/* 
992
 
 * We define our own main() since we have to do prior initialization.
993
 
 * This is copied from panel-applet.h
994
 
 */
995
 
 
996
 
int 
997
 
main (int argc, char *argv [])
998
 
{
999
 
    bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
1000
 
    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1001
 
    textdomain (GETTEXT_PACKAGE);
1002
 
 
1003
 
    seahorse_secure_memory_init ();
1004
 
    
1005
 
    gnome_program_init ("seahorse-applet", VERSION, LIBGNOMEUI_MODULE, argc, argv,
1006
 
                        GNOME_CLIENT_PARAM_SM_CONNECT, FALSE,
1007
 
                        GNOME_PROGRAM_STANDARD_PROPERTIES, GNOME_PARAM_NONE);
1008
 
    
1009
 
    return panel_applet_factory_main ("OAFIID:GNOME_SeahorseApplet_Factory", 
1010
 
                                      SEAHORSE_TYPE_APPLET, seahorse_applet_factory, NULL);
1011
 
}