/[winpt]/trunk/Src/wptKeyManager.cpp
ViewVC logotype

Annotation of /trunk/Src/wptKeyManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 33 - (hide annotations)
Tue Oct 25 07:46:20 2005 UTC (19 years, 4 months ago) by twoaday
File size: 30541 byte(s)
More bug fixes and cleanups.
See ChangeLog for details.

1 twoaday 2 /* wptKeyManager.cpp - Handy functions for the Key Manager dialog
2 twoaday 19 * Copyright (C) 2001-2005 Timo Schulz
3 twoaday 24 * Copyright (C) 2005 g10 Code GmbH
4 twoaday 2 *
5     * This file is part of WinPT.
6     *
7     * WinPT is free software; you can redistribute it and/or
8     * modify it under the terms of the GNU General Public License
9     * as published by the Free Software Foundation; either version 2
10     * of the License, or (at your option) any later version.
11     *
12     * WinPT 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 GNU
15     * General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with WinPT; if not, write to the Free Software Foundation,
19     * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20     */
21     #include <windows.h>
22     #include <commctrl.h>
23     #include <stdio.h>
24    
25 twoaday 25 #include "gpgme.h"
26 twoaday 2 #include "../resource.h"
27     #include "wptTypes.h"
28     #include "wptW32API.h"
29     #include "wptVersion.h"
30     #include "wptCommonCtl.h"
31     #include "wptNLS.h"
32     #include "wptErrors.h"
33 twoaday 23 #include "wptContext.h"
34 twoaday 2 #include "wptGPG.h"
35     #include "wptKeylist.h"
36     #include "wptFileManager.h"
37     #include "wptDlgs.h"
38     #include "wptKeyserver.h"
39     #include "wptKeyManager.h"
40     #include "wptKeylist.h"
41     #include "wptHTTP.h"
42 twoaday 23 #include "wptKeyEdit.h"
43     #include "wptImport.h"
44 twoaday 2
45    
46 twoaday 25 /* Return a user friendly key representation in @buf of
47 twoaday 23 the key given by @keyid. */
48 twoaday 2 static void
49 twoaday 23 key_get_clip_info (const char *keyid, char *buf, size_t buflen)
50 twoaday 2 {
51     gpgme_key_t pk;
52    
53 twoaday 23 if (get_pubkey (keyid, &pk))
54 twoaday 25 BUG (NULL);
55 twoaday 2 _snprintf (buf, buflen-1,
56     "pub %04d%s/%s %s %s\r\n"
57 twoaday 23 " Primary key fingerprint: %s\r\n",
58     pk->subkeys->length,
59     get_key_pubalgo (pk->subkeys->pubkey_algo),
60     pk->subkeys->keyid+8,
61     get_key_created (pk->subkeys->timestamp),
62     pk->uids->uid,
63     get_key_fpr (pk));
64 twoaday 2 }
65    
66    
67 twoaday 25 #if 0
68 twoaday 23 /* Quoted the user-id given by @uid. If @uid is already
69     quoted @uid is returned without any modifications.
70     Return value: quoted @uid. */
71 twoaday 2 char*
72 twoaday 22 km_quote_uid (const char *uid)
73 twoaday 2 {
74 twoaday 23 char *q;
75    
76     if (*uid == '"' && uid[strlen (uid)-1] == '"')
77     return m_strdup (uid);
78     q = new char[strlen (uid) + 4];
79 twoaday 2 if (!q)
80     BUG (NULL);
81     _snprintf (q, strlen (uid) + 3, "\"%s\"", uid);
82     return q;
83 twoaday 23 }
84 twoaday 25 #endif
85 twoaday 2
86    
87 twoaday 25 /* Check if list view @lv contains a secret key at position @pos.
88     If utrust is valid, set it to 1 if the key is valid -1 otherwise.
89     Return value: 1 normal key, 2 smart card key. */
90 twoaday 2 int
91 twoaday 22 km_check_for_seckey (listview_ctrl_t lv, int pos, int *utrust)
92 twoaday 2 {
93 twoaday 16 char t[32], t2[64];
94     int type = 0;
95 twoaday 2
96 twoaday 22 if (utrust)
97     *utrust = 0;
98     listview_get_item_text (lv, pos, 5, t, DIM (t)-1);
99     listview_get_item_text (lv, pos, 2, t2, DIM (t2)-1);
100 twoaday 2 if (!strcmp (t2, "pub/sec"))
101     type = 1;
102     else if (!strcmp (t2, "pub/crd"))
103     type = 2;
104 twoaday 22 if ((strstr (t, "Expired") || strstr (t, "Revoked")) && utrust)
105     *utrust = -1;
106     else if (stristr (t, "Ultimate") && utrust)
107 twoaday 2 *utrust = 1;
108     return type;
109 twoaday 25 }
110 twoaday 2
111    
112 twoaday 25 /* Check if the key at position @pos is protected with a passwd. */
113 twoaday 2 int
114 twoaday 22 km_check_if_protected (listview_ctrl_t lv, int pos)
115 twoaday 2 {
116     gpgme_key_t key;
117 twoaday 23 winpt_key_s k;
118 twoaday 22
119     key = (gpgme_key_t)listview_get_item2 (lv, pos);
120 twoaday 23 if (!key)
121 twoaday 22 return 1; /* assume yes */
122 twoaday 23 winpt_get_pubkey (key->subkeys->keyid, &k);
123     return k.is_protected;
124 twoaday 25 }
125 twoaday 2
126    
127     int
128     km_check_key_status (listview_ctrl_t lv, int pos)
129     {
130 twoaday 22 int flags = km_get_key_status (lv, pos);
131 twoaday 2
132 twoaday 22 if (flags & KM_FLAG_EXPIRED) {
133     msg_box (lv->ctrl, _("This key has expired!\n"
134     "Key check failed."), _("Key Manager"), MB_ERR);
135     return -1;
136 twoaday 2 }
137 twoaday 22 else if (flags & KM_FLAG_REVOKED) {
138     msg_box (lv->ctrl, _("This key has been revoked by its owner!\n"
139     "Key check failed."), _("Key Manager"), MB_ERR);
140     return -1;
141     }
142 twoaday 2
143     return 0;
144     } /* km_check_key_status */
145    
146    
147     int
148 twoaday 22 km_get_key_status (listview_ctrl_t lv, int pos)
149 twoaday 2 {
150 twoaday 22 gpgme_key_t key;
151     int flags = 0;
152 twoaday 2
153 twoaday 22 if (pos == -1)
154 twoaday 2 return 0;
155 twoaday 22 key = (gpgme_key_t)listview_get_item2 (lv, pos);
156     if (key == NULL)
157     return 0;
158 twoaday 23
159     if (key->expired)
160 twoaday 22 flags |= KM_FLAG_EXPIRED;
161 twoaday 23 if (key->revoked)
162 twoaday 22 flags |= KM_FLAG_REVOKED;
163 twoaday 23 if (key->disabled)
164 twoaday 22 flags |= KM_FLAG_DISABLED;
165 twoaday 2 return flags;
166     } /* km_get_key_status */
167    
168    
169 twoaday 23 /* Interface to enable or disable a key (@enable = 1 then enable).
170     The key is retrieved from a list control @lv at the pos @pos. */
171 twoaday 2 int
172 twoaday 19 km_enable_disable_key (listview_ctrl_t lv, HWND dlg, int pos, int enable)
173 twoaday 2 {
174 twoaday 23 GpgKeyEdit *ke;
175 twoaday 2 gpgme_error_t err;
176     char keyid[32];
177    
178 twoaday 22 listview_get_item_text (lv, pos, 1, keyid, DIM (keyid)-1);
179 twoaday 23
180     ke = new GpgKeyEdit (keyid);
181     if (!ke)
182 twoaday 22 BUG (NULL);
183 twoaday 23
184 twoaday 25 err = enable? ke->enable () : ke->disable ();
185 twoaday 23 if (!err) {
186     show_msg (dlg, 1500, _("Key status changed."));
187     keycache_set_reload (1); /* XXX: set update flag */
188 twoaday 2 }
189 twoaday 23 else
190 twoaday 25 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
191 twoaday 23 delete ke;
192     return err? WPTERR_GENERAL : 0;
193     }
194    
195    
196    
197     /* Create a string that contain all keyids from
198     the key list @rset separated by a space. */
199     char*
200 twoaday 25 gpg_keylist_to_pattern (gpgme_key_t *rset, int n)
201 twoaday 23 {
202     char *p;
203 twoaday 25 int i;
204 twoaday 23
205 twoaday 24 if (!n)
206     return NULL;
207     p = (char *)calloc (1, n*(16+1)+n+2);
208 twoaday 23 if (!p)
209 twoaday 25 BUG (NULL);
210     for (i=0; i < n; i++) {
211 twoaday 23 strcat (p, rset[i]->subkeys->keyid);
212     strcat (p, " ");
213 twoaday 2 }
214 twoaday 23 return p;
215     }
216    
217    
218     /* Export the keys given in @rset to the clipboard.
219     Return value: 0 on success. */
220 twoaday 25 static gpgme_error_t
221     gpg_clip_export (gpgme_key_t *rset, int n)
222 twoaday 23 {
223     gpgme_error_t err = 0;
224     gpgme_ctx_t ctx = NULL;
225     gpgme_data_t keydata = NULL;
226     char *patt=NULL;
227    
228 twoaday 19 err = gpgme_new (&ctx);
229 twoaday 23 if (err)
230     return err;
231     gpgme_set_armor (ctx, 1);
232     err = gpgme_data_new (&keydata);
233     if (err)
234     goto leave;
235    
236 twoaday 25 patt = gpg_keylist_to_pattern (rset, n);
237 twoaday 23 if (!patt) {
238     err = gpg_error (GPG_ERR_ENOMEM);
239     goto leave;
240 twoaday 2 }
241    
242 twoaday 23 err = gpgme_op_export (ctx, patt, 0, keydata);
243     if (err)
244     goto leave;
245    
246     gpg_data_release_and_set_clipboard (keydata, 1);
247    
248     leave:
249     if (patt)
250     free (patt);
251 twoaday 19 gpgme_release (ctx);
252 twoaday 23 return err;
253     }
254 twoaday 2
255    
256 twoaday 23 /* Export the selected keys in @lv to the clipboard. */
257 twoaday 2 int
258     km_clip_export (HWND dlg, listview_ctrl_t lv)
259     {
260     gpgme_error_t err;
261 twoaday 23 gpgme_key_t *rset;
262 twoaday 25 char buf[256];
263     int n=0;
264     int rc=0;
265 twoaday 2
266 twoaday 23 rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
267 twoaday 2 if (!n) {
268     msg_box (dlg, _("No key was selected for export."), _("Key Manager"), MB_ERR);
269     rc = WPTERR_GENERAL;
270     goto leave;
271     }
272    
273 twoaday 25 err = gpg_clip_export (rset, n);
274 twoaday 2 if (err) {
275     msg_box( dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
276     rc = WPTERR_GENERAL;
277     goto leave;
278     }
279     if (n == 1) {
280 twoaday 25 key_get_clip_info (rset[0]->subkeys->keyid, buf, sizeof (buf)-1);
281 twoaday 2 set_clip_text2 (NULL, buf, strlen (buf), 0);
282     }
283    
284     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
285    
286     leave:
287 twoaday 23 free (rset);
288 twoaday 2 return rc;
289     } /* km_clip_export */
290    
291    
292 twoaday 23 /* Export the selected secret key from @lv into @fname.
293     It is only allowed to export a single secret key. */
294 twoaday 2 int
295 twoaday 22 km_privkey_export (HWND dlg, listview_ctrl_t lv, const char *fname)
296 twoaday 2 {
297 twoaday 23 gpgme_key_t *rset;
298 twoaday 2 gpgme_error_t err;
299 twoaday 23 int n = 0;
300 twoaday 2
301 twoaday 23 rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
302 twoaday 22 if (!n) {
303 twoaday 25 msg_box (dlg, _("No key was selected for export."),
304     _("Key Manager"), MB_ERR);
305 twoaday 2 return WPTERR_GENERAL;
306     }
307 twoaday 22 if (n > 1) {
308 twoaday 25 msg_box (dlg, _("Only one secret key can be exported."),
309     _("Key Manager"), MB_ERR);
310 twoaday 23 free (rset);
311 twoaday 2 return 0; /* we checked this before, so we just quit */
312     }
313    
314 twoaday 23 err = gpg_export_seckey (rset[0]->subkeys->keyid, fname);
315     if (err)
316     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
317     else
318 twoaday 25 log_box (_("Key Manager"), MB_OK,
319 twoaday 23 _("Secret key successfully saved in '%s'."), fname);
320 twoaday 2
321 twoaday 23 free (rset);
322     return err? WPTERR_GENERAL : 0;
323     }
324 twoaday 2
325    
326     int
327     km_file_export (HWND dlg, listview_ctrl_t lv, const char * fname)
328     {
329 twoaday 23 gpgme_key_t *rset;
330 twoaday 2 gpgme_data_t keydata;
331     gpgme_error_t err;
332     gpgme_ctx_t ctx;
333 twoaday 23 char *patt;
334     int n;
335 twoaday 2
336 twoaday 25 rset = keylist_enum_recipients (lv, KEYLIST_LIST, &n);
337 twoaday 23 if (!n) {
338 twoaday 25 msg_box (dlg, _("No key was selected for export."),
339     _("Key Manager"), MB_ERR);
340 twoaday 2 return WPTERR_GENERAL;
341     }
342    
343 twoaday 23 err = gpgme_data_new (&keydata);
344 twoaday 25 if (err)
345     BUG (NULL);
346 twoaday 23 err = gpgme_new (&ctx);
347 twoaday 25 if (err)
348     BUG (NULL);
349 twoaday 23 gpgme_set_armor (ctx, 1);
350    
351     /*gpgme_set_comment (ctx, "Generated by WinPT "PGM_VERSION);*/
352 twoaday 25 patt = gpg_keylist_to_pattern (rset, n);
353 twoaday 2
354 twoaday 23 err = gpgme_op_export( ctx, patt, 0, keydata);
355 twoaday 2 if( err ) {
356     msg_box( dlg, gpgme_strerror( err ), _("Key Manager"), MB_ERR );
357     goto leave;
358     }
359    
360     log_box( _("Key Manager"), MB_OK,
361     _("Key(s) successfully saved in '%s'."), fname );
362    
363     leave:
364 twoaday 23 err = gpg_data_release_and_set_file( keydata, fname );
365     if (err)
366     log_box (_("Key Manager"), MB_OK,
367     _("Could not save data to '%s'."), fname);
368     gpgme_release (ctx);
369     free (patt);
370 twoaday 2 return (int)err;
371     } /* km_file_export */
372    
373    
374     static int
375 twoaday 19 extract_dash_escaped_key (void)
376 twoaday 2 {
377     gpgme_data_t inp, plain;
378     gpgme_error_t err;
379    
380 twoaday 23 err = gpg_data_new_from_clipboard (&inp, 0);
381 twoaday 19 if (err) {
382     msg_box (NULL, gpgme_strerror( err ), _("Key Manager"), MB_ERR);
383 twoaday 2 return -1;
384     }
385 twoaday 23 gpg_data_extract_plaintext (inp, &plain);
386     gpg_data_release_and_set_clipboard (plain, 0);
387 twoaday 19 gpgme_data_release (inp);
388 twoaday 2
389     return 0;
390     } /* extract_dash_escaped_key */
391    
392    
393 twoaday 25 /* Import keys from the clipboard. */
394 twoaday 2 int
395 twoaday 25 km_clip_import (HWND dlg)
396 twoaday 2 {
397     gpgme_error_t err;
398 twoaday 32 int pgptype;
399 twoaday 2 int id;
400     int has_data = 0;
401    
402 twoaday 25 if (!gpg_clip_istext_avail (&has_data) && !has_data) {
403     msg_box( dlg, winpt_strerror (WPTERR_CLIP_ISEMPTY), _("Key Manager"), MB_ERR);
404 twoaday 2 return WPTERR_CLIP_ISEMPTY;
405     }
406 twoaday 25 err = gpg_clip_is_secured (&pgptype, &has_data);
407     if (err)
408     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
409     if (!has_data) {
410     msg_box (dlg, _("No valid OpenPGP data found."), _("Key Manager"), MB_ERR);
411 twoaday 2 return WPTERR_GENERAL;
412     }
413 twoaday 25 if (!(pgptype & PGP_PUBKEY) && !(pgptype & PGP_SECKEY)) {
414     msg_box (dlg, _("No valid OpenPGP keys found."), _("Key Manager"), MB_ERR);
415 twoaday 2 return WPTERR_GENERAL;
416     }
417 twoaday 25 if (pgptype & PGP_DASH_ESCAPED) {
418     id = msg_box (dlg, _("The key you want to import is dash escacped.\n"
419     "Do you want to extract the key?"),
420     _("Key Manager"), MB_YESNO);
421 twoaday 22 if (id == IDYES)
422     extract_dash_escaped_key ();
423 twoaday 2 else
424 twoaday 25 msg_box (dlg, _("Cannot import dash escaped OpenPGP keys."),
425     _("Key Manager"), MB_INFO);
426 twoaday 2 }
427    
428 twoaday 25 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
429 twoaday 2 clip_import_dlg_proc, NULL,
430 twoaday 25 _("Key Import"), IDS_WINPT_IMPORT);
431 twoaday 2
432     return 0;
433 twoaday 25 }
434 twoaday 2
435    
436 twoaday 25 /* Import a key from the http URL @url. */
437 twoaday 2 int
438 twoaday 25 km_http_import (HWND dlg, const char *url)
439 twoaday 2 {
440     http_hd_t hd;
441 twoaday 25 FILE *fp;
442     char *p;
443     char tmpfile[500];
444 twoaday 2 int statcode;
445     int rc = 0;
446    
447     if (strncmp (url, "http://", 7)) {
448     log_box (_("Key Import HTTP"), MB_ERR, _("Invalid HTTP URL: %s"), url);
449     return WPTERR_GENERAL;
450     }
451    
452 twoaday 25 GetTempPath (sizeof (tmpfile)-128, tmpfile);
453     p = make_filename (tmpfile, "winpt_file_http", "tmp");
454 twoaday 2 if (!p)
455     BUG (0);
456     fp = fopen (p, "wb");
457 twoaday 25 if (!fp) {
458 twoaday 2 free_if_alloc (p);
459     log_box (_("Key Import HTTP"), MB_ERR, "%s: %s", p, winpt_strerror (WPTERR_FILE_CREAT));
460     return WPTERR_FILE_CREAT;
461     }
462 twoaday 25
463 twoaday 2 /* parse URL */
464     rc = http_send_request2 (url, &hd);
465     if (!rc)
466     rc = http_parse_response (hd, &statcode);
467     if (!rc)
468     rc = http_parse_data (hd, fp);
469     http_hd_free (hd);
470     fclose (fp);
471 twoaday 25 if (rc) {
472 twoaday 22 msg_box (dlg, winpt_strerror (rc), _("Key Import HTTP"), MB_ERR);
473 twoaday 25 rc = WPTERR_GENERAL;
474 twoaday 2 }
475     km_file_import (dlg, p);
476 twoaday 25 unlink (p);
477 twoaday 2 free_if_alloc (p);
478 twoaday 25 return rc;
479 twoaday 2 }
480    
481 twoaday 22
482 twoaday 23 /* Import a key from the given file @fname.
483     On success an import statistics dialog is shown. */
484 twoaday 2 int
485 twoaday 23 km_file_import (HWND dlg, const char *fname)
486 twoaday 2 {
487     gpgme_data_t keydata = NULL;
488     gpgme_ctx_t ctx;
489 twoaday 22 gpgme_error_t err;
490 twoaday 2 fm_state_s fm_stat;
491 twoaday 23 gpgme_import_result_t res;
492 twoaday 2
493 twoaday 22 memset (&fm_stat, 0, sizeof (fm_stat));
494     fm_stat.opaque = m_strdup (fname);
495 twoaday 2
496 twoaday 22 dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_IMPORT, dlg,
497 twoaday 2 file_import_dlg_proc, (LPARAM)&fm_stat,
498 twoaday 22 _("File Import"), IDS_WINPT_IMPORT);
499     if (fm_stat.cancel == 1 ) {
500     free_if_alloc (fm_stat.opaque);
501 twoaday 2 return WPTERR_GENERAL;
502 twoaday 22 }
503 twoaday 2
504 twoaday 25 err = gpgme_new (&ctx);
505     if (err)
506     BUG (NULL);
507 twoaday 23 err = gpgme_data_new_from_file (&keydata, fname, 1);
508 twoaday 25 if (err) {
509     msg_box (dlg, _("Could not read key-data from file."),
510     _("Key Manager"), MB_ERR);
511 twoaday 2 goto leave;
512     }
513    
514 twoaday 23 err = gpgme_op_import (ctx, keydata);
515     if (err) {
516 twoaday 25 msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
517 twoaday 2 goto leave;
518 twoaday 25 }
519 twoaday 22
520 twoaday 23 res = gpgme_op_import_result (ctx);
521 twoaday 25 if (res->new_revocations == 0 && fm_stat.import.revcert == 1)
522     res->new_revocations = 1;
523     if (res->secret_imported == 0 && fm_stat.import.has_seckey == 1)
524     res->secret_imported = 1;
525    
526 twoaday 23 print_import_status (res);
527     if (res->no_user_id > 0) {
528 twoaday 22 msg_box (dlg, _("Key without a self signature was dectected!\n"
529 twoaday 2 "(This key is NOT usable for encryption, etc)\n"
530     "\n"
531 twoaday 22 "Cannot import these key(s)!"), _("Import"), MB_INFO);
532 twoaday 2 }
533 twoaday 22
534     leave:
535     gpgme_data_release (keydata);
536     gpgme_release (ctx);
537     free_if_alloc (fm_stat.opaque);
538 twoaday 2 return (int)err;
539 twoaday 23 }
540 twoaday 2
541    
542 twoaday 23 /* Mark the keys in @rset as deleted in the keycache. */
543 twoaday 2 static void
544 twoaday 24 delete_keys_from_cache (gpgme_key_t *rset, size_t n)
545 twoaday 2 {
546 twoaday 25 gpg_keycache_t pub = keycache_get_ctx (1);
547 twoaday 23 int i=0;
548 twoaday 2
549 twoaday 24 while (n-- > 0)
550 twoaday 25 gpg_keycache_delete_key (pub, rset[i++]->subkeys->keyid);
551 twoaday 23 }
552 twoaday 2
553    
554 twoaday 25 /* Delete all selected keys from the list view @lv. */
555 twoaday 2 int
556     km_delete_keys (listview_ctrl_t lv, HWND dlg)
557     {
558     gpgme_error_t err;
559 twoaday 23 gpgme_ctx_t ctx;
560     gpgme_key_t *rset, k;
561 twoaday 2 char keyid[32], uid[256], date[64], keylen[64];
562 twoaday 22 int with_seckey=0, seckey_type=0, confirm=0;
563 twoaday 23 int i, rc, n, k_pos=0;
564 twoaday 2
565 twoaday 22 if (listview_get_curr_pos (lv) == -1) {
566     msg_box (dlg, _("Please select a key."), _("Key Manager"), MB_ERR);
567 twoaday 2 return WPTERR_GENERAL;
568     }
569 twoaday 22
570     if (listview_count_items (lv, 1) > 8) {
571 twoaday 25 i = msg_box (NULL, _("Do you really want to confirm each key?"),
572     _("Delete Confirmation"), MB_YESNOCANCEL|MB_ICONQUESTION);
573 twoaday 22 if (i == IDCANCEL)
574     return 0;
575     if (i != IDNO)
576     confirm = 1;
577     }
578     else
579     confirm = 1;
580 twoaday 23
581 twoaday 20 n = listview_count_items (lv, 0);
582 twoaday 23 rset = (gpgme_key_t *)calloc (n+1, sizeof (gpgme_key_t));
583     if (!rset)
584     BUG (NULL);
585 twoaday 20 for( i = 0; i < n; i++ ) {
586 twoaday 2 if( listview_get_item_state( lv, i ) ) {
587     listview_get_item_text( lv, i, 0, uid, sizeof uid - 1 );
588     listview_get_item_text( lv, i, 1, keyid, sizeof keyid - 1 );
589     listview_get_item_text( lv, i, 3, keylen, sizeof keylen - 1 );
590     listview_get_item_text( lv, i, 7, date, sizeof date - 1 );
591 twoaday 22 seckey_type = km_check_for_seckey (lv, i, NULL);
592     if (confirm && !seckey_type) {
593 twoaday 2 rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
594     _("Do you really want to delete this key?\n\n"
595     "pub %s %s %s\n"
596     " \"%s\""), keylen, keyid, date, uid );
597 twoaday 23 if (rc == IDYES) {
598     get_pubkey (keyid, &k);
599     rset[k_pos++] = k;
600     }
601 twoaday 2 with_seckey = 0;
602     }
603 twoaday 22 else if (confirm) {
604 twoaday 2 rc = log_box( _("Key Manager"), MB_YESNO|MB_ICONWARNING,
605     _("Do you really want to delete this KEY PAIR?\n\n"
606     "Please remember that you are not able to decrypt\n"
607     "messages you stored with this key any longer.\n"
608     "\n"
609     "pub/sec %s %s %s\n"
610     " \"%s\""), keylen, keyid, date, uid );
611     if( rc == IDYES ) {
612 twoaday 25 if (seckey_type == 2)
613 twoaday 2 msg_box( dlg, _("The actual secret key is stored on a smartcard.\n"
614     "Only the public key and the secret key \n"
615     "placeholder will be deleted.\n"), _("Key Manager"), MB_OK );
616 twoaday 23 get_pubkey (keyid, &k);
617     rset[k_pos++] = k;
618 twoaday 2 }
619     with_seckey = 1;
620     }
621 twoaday 22 else {
622     with_seckey = 1;
623 twoaday 23 get_pubkey (keyid, &k);
624     rset[k_pos++] = k;
625 twoaday 22 }
626 twoaday 2 }
627     }
628    
629 twoaday 23 if (k_pos == 0) {
630     free (rset);
631     return 0;
632 twoaday 2 }
633 twoaday 23
634     err = gpgme_new (&ctx);
635     if (err)
636     BUG (NULL);
637 twoaday 25 n=k_pos;
638 twoaday 24 for (i=0; i < k_pos; i++) {
639 twoaday 23 err = gpgme_op_delete (ctx, rset[i], with_seckey);
640     if (err)
641     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
642     else
643 twoaday 25 n--;
644 twoaday 2 }
645 twoaday 25 if (n == 0)
646     show_msg (dlg, 1500, _("GnuPG Status: Finished"));
647 twoaday 23 gpgme_release (ctx);
648 twoaday 2 listview_del_items (lv);
649 twoaday 24 delete_keys_from_cache (rset, k_pos);
650 twoaday 23 free (rset);
651 twoaday 2
652     return (int)err;
653 twoaday 25 }
654 twoaday 2
655    
656     int
657     km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char * host, u16 port)
658     {
659     char keyid[32];
660     const char *t;
661     int id;
662    
663     id = listview_get_curr_pos( lv );
664     if( id == -1 ) {
665     msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
666     return WPTERR_GENERAL;
667     }
668    
669     listview_get_item_text( lv, id, 1, keyid, sizeof keyid - 1 );
670     id = log_box (_("Key Manager"), MB_YESNO,
671     _("Do you really want to send '%s' to keyserver %s?"),
672     keyid, host);
673     if (id == IDYES) {
674     t = keyid;
675     if (!strncmp (keyid, "0x", 2))
676     t += 2;
677     hkp_send_key (dlg, host, port, t);
678     }
679    
680     return 0;
681     } /* km_send_to_keyserver */
682    
683    
684     int
685     km_send_to_mail_recipient( listview_ctrl_t lv, HWND dlg )
686     {
687 twoaday 23 #if 0 /*FIXME*/
688 twoaday 2 gpgme_key_t key;
689     gpgme_ctx_t ctx=NULL;
690     gpgme_recipients_t rset=NULL;
691     gpgme_error_t rc;
692     const char * s;
693     char keyid[32], tmp[192+256], * p =NULL;
694     int pos;
695    
696     if( listview_count_items( lv, 1 ) > 1 ) {
697     msg_box( dlg, _("Please only select one key."), _("Key Manager"), MB_INFO|MB_OK );
698     return WPTERR_GENERAL;
699     }
700     pos = listview_get_curr_pos( lv );
701     if( pos == -1 ) {
702     msg_box( dlg, _("Please select a key."), _("Key Manager"), MB_ERR );
703     return WPTERR_GENERAL;
704     }
705     listview_get_item_text( lv, pos, 1, keyid, sizeof keyid-1 );
706     if( get_pubkey( keyid, &key ) )
707     BUG( NULL );
708 twoaday 23 s = key->uids->name;
709 twoaday 2 GetTempPath (sizeof tmp-1, tmp);
710     strncat (tmp, s, sizeof tmp-200);
711     strncat (tmp, ".asc", sizeof tmp-200);
712     p = fm_quote_file (tmp);
713    
714     rc = gpgme_recipients_new( &rset );
715     if( !rc )
716     rc = gpgme_recipients_add_name( rset, keyid );
717     if( !rc )
718     rc = gpgme_new( &ctx );
719     if( !rc ) {
720 twoaday 23 gpgme_set_armor (ctx, 1);
721 twoaday 2 rc = gpgme_op_file_export( ctx, rset, p );
722     }
723     if( rc )
724     msg_box( dlg, gpgme_strerror( rc ), _("Key Manager"), MB_ERR );
725     else
726     mapi_send_pubkey (keyid, tmp);
727     free_if_alloc( p );
728     gpgme_recipients_release( rset );
729     gpgme_release( ctx );
730     return rc;
731 twoaday 23 #endif
732     return 0;
733 twoaday 2 }
734    
735    
736     static void
737     km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos)
738     {
739     int idx;
740     char keyid[32];
741     const char *t;
742    
743     if (pos != 0)
744     idx = pos;
745     else
746     idx = listview_get_curr_pos (lv);
747     if (idx != -1)
748     {
749     listview_get_item_text (lv, idx, 1, keyid, sizeof keyid - 1);
750     t = keyid;
751     if (!strncmp (keyid, "0x", 2))
752     t += 2;
753     hkp_recv_key (dlg, default_keyserver, default_keyserver_port, t, 0, KM_KS_REFRESH);
754     }
755     }
756    
757    
758     void
759     km_refresh_from_keyserver (listview_ctrl_t lv, HWND dlg)
760     {
761     int idx, id, i;
762    
763     if (kserver_check_inet_connection ())
764     {
765     msg_box (dlg, _("Could not connect to keyserver, abort procedure."),
766     _("Key Manager"), MB_ERR);
767     return;
768     }
769     idx = listview_count_items (lv, 0);
770     if (listview_count_items (lv, 1) == idx) {
771     id = msg_box (dlg, _("Do you really want to refresh all keys in the keyring?"), _("Key Manager"), MB_YESNO);
772     if (id == IDNO)
773     return;
774     for (i = 0; i < idx; i++)
775     km_refresh_one_key (lv, dlg, i);
776     }
777     else if (idx == 1)
778     km_refresh_one_key (lv, dlg, 0);
779     else {
780     for (i=0; i < listview_count_items (lv, 0); i++) {
781     if (listview_get_item_state (lv, i))
782     km_refresh_one_key (lv, dlg, i);
783     }
784     }
785     } /* km_refresh_from_keyserver */
786    
787    
788     void
789 twoaday 23 km_set_clip_info (const char *uid)
790 twoaday 2 {
791     char buf[256];
792    
793 twoaday 23 key_get_clip_info (uid, buf, 255);
794     set_clip_text (NULL, buf, strlen (buf));
795 twoaday 2 } /* km_set_clip_info */
796    
797    
798    
799 twoaday 23 /* Return TRUE if the key in the list @lv at pos @pos is an
800     old version 3 key. */
801 twoaday 2 int
802 twoaday 20 km_key_is_v3 (listview_ctrl_t lv, int pos)
803 twoaday 2 {
804     gpgme_key_t pk;
805     char keyid[32];
806    
807 twoaday 20 listview_get_item_text (lv, pos, 1, keyid, sizeof keyid-1);
808     if (get_pubkey (keyid, &pk))
809     BUG (NULL);
810 twoaday 23 if (strlen (pk->subkeys->fpr) == 32 &&
811     pk->subkeys->pubkey_algo == GPGME_PK_RSA)
812     return -1;
813     return 0;
814     }
815 twoaday 2
816    
817 twoaday 33 /* Update the default key entry in the status bar for dialog @dlg. */
818 twoaday 2 void
819 twoaday 23 km_update_default_key_str (HWND dlg)
820 twoaday 2 {
821 twoaday 33 char *keyid, defkeyinf[512];
822     const char *fmt;
823 twoaday 2
824 twoaday 33 /* XXX: also show the name? */
825 twoaday 2 keyid = get_gnupg_default_key ();
826     if (!keyid)
827     BUG (0);
828     if( (keyid[0] >= 'A' && keyid[0] <= 'Z') || (keyid[0] >= 'a' && keyid[0] <= 'z')
829     || (keyid[0] == '0' && keyid[1] == 'x') )
830     fmt = _("Default Key: %s");
831     else
832     fmt = _("Default Key: 0x%s");
833 twoaday 23 _snprintf (defkeyinf, sizeof defkeyinf - 1, fmt, keyid);
834     SendMessage (dlg, SB_SETTEXT, 0, (LPARAM)defkeyinf);
835     free_if_alloc (keyid);
836 twoaday 33 }
837 twoaday 2
838    
839 twoaday 33 /* Count all keys and show from @lv results in the status bar @sb. */
840 twoaday 2 void
841 twoaday 23 km_complete_status_bar (HWND sb, listview_ctrl_t lv)
842 twoaday 2 {
843 twoaday 23 char txt_sec[128], txt_pub[128];
844 twoaday 2 int nkeys = 0, nsec = 0, i;
845    
846 twoaday 23 nkeys = listview_count_items (lv, 0);
847     for (i = 0; i < nkeys; i++) {
848     if (km_check_for_seckey (lv, i, NULL))
849 twoaday 2 nsec++;
850     }
851 twoaday 28 _snprintf (txt_sec, sizeof (txt_sec)-1, _("%d secret keys"), nsec);
852     _snprintf (txt_pub, sizeof (txt_pub)-1, _("%d keys"), nkeys);
853 twoaday 23 SendMessage (sb, SB_SETTEXT, 1, (LPARAM)txt_sec);
854     SendMessage (sb, SB_SETTEXT, 2, (LPARAM)txt_pub);
855 twoaday 33 }
856 twoaday 2
857    
858 twoaday 33 /* Set trust of selected key in @lv (at @pos) to ultimate. */
859 twoaday 22 int
860 twoaday 2 km_set_implicit_trust (HWND dlg, listview_ctrl_t lv, int pos)
861     {
862 twoaday 23 GpgKeyEdit *ke;
863     gpgme_error_t err;
864 twoaday 2 char keyid[32];
865    
866     listview_get_item_text (lv, pos, 1, keyid, 31);
867 twoaday 23
868     ke = new GpgKeyEdit (keyid);
869     if (!ke)
870 twoaday 2 BUG (0);
871    
872 twoaday 23 err = ke->setTrust (GPGME_VALIDITY_ULTIMATE);
873 twoaday 2 if (err)
874     msg_box (dlg, gpgme_strerror (err), _("Key Manager"), MB_ERR);
875 twoaday 22 else
876 twoaday 2 show_msg (dlg, 1500, _("GnuPG Status: Finished"));
877    
878 twoaday 23 delete ke;
879 twoaday 22 return (int)err;
880 twoaday 2 }
881    
882    
883 twoaday 22 void
884     km_find_key (HWND dlg, listview_ctrl_t lv)
885     {
886     int oldpos = listview_get_curr_pos (lv);
887     int n;
888 twoaday 28 char *name = get_input_dialog (dlg, _("Search"), _("Search for:"));
889 twoaday 22 if (name == NULL)
890     return;
891     if (oldpos < 0)
892     oldpos = 0;
893     n = listview_find (lv, name);
894     if (n != -1) {
895     listview_select_one (lv, n);
896     listview_scroll (lv, oldpos, n);
897     }
898     else {
899     const char *s = _("String pattern \"%s\" not found.");
900     char *p = new char[strlen (s) + strlen (name) + 2];
901     if (!p)
902     BUG (0);
903     sprintf (p, s, name);
904     msg_box (dlg, p, _("Key Manager"), MB_INFO);
905     free_if_alloc (p);
906     }
907     free_if_alloc (name);
908     }
909    
910    
911    
912     void
913     km_dump_key (gpgme_key_t key)
914     {
915     #if _DEBUG
916     log_box ("DEBUG", MB_OK,
917 twoaday 23 "%d %d %s %d\n%s", key->subkeys->length,
918     key->subkeys->pubkey_algo,
919     key->subkeys->keyid,
920     key->subkeys->timestamp,
921     key->uids->uid);
922 twoaday 22 #endif
923     }
924    
925 twoaday 23 #if 0
926 twoaday 2 gpg_optfile_t
927 twoaday 33 km_groupdb_open (void)
928 twoaday 2 {
929     gpg_optfile_t opt;
930     char * optfile;
931     int err = 0;
932    
933     optfile = get_gnupg_cfgfile();
934     if( !optfile )
935     BUG( NULL );
936     if( parse_gpg_options( optfile, &opt ) )
937     err = 1;
938     free_if_alloc( optfile );
939     return err? NULL : opt;
940     } /* km_groupdb_open */
941    
942    
943     int
944     km_groupdb_expand_recipients( const char *name, gpgme_recipients_t rset )
945     {
946 twoaday 25 gpg_keycache_t kc;
947 twoaday 2 gpgme_key_t pk;
948     gpg_optfile_t opt;
949     gpg_group_t grp;
950     gpg_member_t mbr;
951     int no_trust = 0, n;
952    
953     kc = keycache_get_ctx( 1 );
954     if( !kc )
955     BUG( NULL );
956    
957     opt = km_groupdb_open( );
958     if( !opt )
959     return WPTERR_FILE_OPEN;
960    
961     grp = find_group( opt, name );
962     if( !grp )
963     return WPTERR_GENERAL;
964    
965     /* we are paranoid and check that all group members exist in the
966     key cache. there is no need that it is really the real key, but
967     an entry should be available. the rest is up to GPG. */
968     for( mbr = grp->list; mbr; mbr = mbr->next ) {
969     if( gpgme_keycache_find_key( kc, mbr->name, 0, &pk ) )
970     BUG( NULL );
971 twoaday 23 n = count_userids (pk);
972 twoaday 2 while( n-- ) {
973 twoaday 23 gpgme_user_id_t u = get_nth_userid (pk, n);
974     const char * s = u->uid;
975 twoaday 2 if( s && stristr( s, mbr->name )
976 twoaday 23 && u->validity < 3 )
977 twoaday 2 no_trust++;
978     }
979     }
980    
981     gpgme_recipients_add_name( rset, name );
982     release_gpg_options( opt );
983    
984     return no_trust;
985     } /* km_groupdb_expand_recipients */
986    
987    
988     static HTREEITEM
989     km_tv_insert_item( HWND tree, HTREEITEM parent, const char *text )
990     {
991     TVINSERTSTRUCT tvis;
992     HTREEITEM node;
993    
994     memset( &tvis, 0, sizeof tvis );
995     tvis.hParent = parent;
996     tvis.hInsertAfter = TVI_LAST;
997     tvis.item.mask = TVIF_TEXT;
998     tvis.item.pszText = (char *)text;
999     node = TreeView_InsertItem( tree, &tvis );
1000     return node;
1001     } /* km_tv_insert_item */
1002    
1003    
1004     int
1005     km_groups_new( km_group_t *r_gc, HWND ctrl )
1006     {
1007     km_group_t gc;
1008    
1009     gc = new km_group_s;
1010     if (!gc)
1011     BUG (NULL);
1012     gc->tree = ctrl;
1013     gc->gh = km_groupdb_open ();
1014     *r_gc = gc;
1015     return 0;
1016     } /* km_groups_new */
1017    
1018    
1019     void
1020     km_groups_sync( km_group_t gc )
1021     {
1022     char * optfile;
1023    
1024     optfile = get_gnupg_cfgfile ();
1025     if( !optfile )
1026     BUG( NULL );
1027     commit_gpg_options( optfile, gc->gh );
1028     free_if_alloc( optfile );
1029     gc->need_sync = 0;
1030     } /* km_groups_sync */
1031    
1032    
1033     void
1034     km_groups_release (km_group_t gc)
1035     {
1036     if( gc ) {
1037     /* xxx: this reset the default key (sync=1) */
1038     gc->need_sync=0;
1039     if (gc->need_sync)
1040     km_groups_sync (gc);
1041     if (gc->gh)
1042     release_gpg_options( gc->gh );
1043     gc->gh = NULL;
1044     gc->tree = NULL;
1045     delete gc;
1046     }
1047     } /* km_groups_release */
1048    
1049    
1050     int
1051     km_groups_load( km_group_t gc )
1052     {
1053     HTREEITEM n;
1054     gpg_group_t grp, g;
1055     gpg_member_t mbr;
1056     u32 gid = 0;
1057    
1058     if( !gc->gh )
1059     return 0;
1060     grp = gc->gh->grp;
1061     if( !grp )
1062     return 0; /* no groups */
1063    
1064     for( g = grp; g; g = g->next ) {
1065     n = km_tv_insert_item( gc->tree, NULL, g->name );
1066     for( mbr = g->list; mbr; mbr = mbr->next ) {
1067     if( mbr->used && mbr->name )
1068     km_tv_insert_item( gc->tree, n, mbr->name );
1069     }
1070     }
1071     DragAcceptFiles( gc->tree, TRUE );
1072     gc->need_sync = 0;
1073     return 0;
1074     } /* km_groups_load */
1075    
1076    
1077     int
1078     km_groups_add( km_group_t gc, listview_ctrl_t lv, int km_index )
1079     {
1080     TVITEM tvi;
1081     char uid[128], valid[64], text[128];
1082     int i_valid;
1083    
1084     memset( &tvi, 0, sizeof tvi );
1085     tvi.hItem = TreeView_GetSelection( gc->tree );
1086     tvi.pszText = text;
1087     tvi.cchTextMax = sizeof text -1;
1088     tvi.mask = TVIF_TEXT;
1089     TreeView_GetItem( gc->tree, &tvi );
1090    
1091    
1092     listview_get_item_text( lv, km_index, 0, uid, sizeof uid -1 );
1093     listview_get_item_text( lv, km_index, 5, valid, sizeof valid -1 );
1094    
1095     if( strstr( valid, "Ultimate" ) )
1096     i_valid = 5;
1097     else if( !strstr( valid, "Full" ) )
1098     i_valid = 4;
1099     else if( !strstr( valid, "Marginal" ) )
1100     i_valid = 3;
1101     else
1102     i_valid = 0;
1103    
1104     /* we can't add the full name. one way would be to use the first
1105     text until a space appears.
1106     group_add_entry(&gc->gh, gid, i_valid, uid);
1107     treeview_add_item(gc->tree, tvi.hItem, uid);
1108     */
1109     gc->need_sync = 1;
1110    
1111     return 0;
1112     } /* km_groups_add */
1113    
1114    
1115     static int
1116     km_groups_del_main( km_group_t gc )
1117     {
1118     TVITEM tvi;
1119     char text[128];
1120     int id;
1121    
1122     memset( &tvi, 0, sizeof tvi );
1123     tvi.hItem = TreeView_GetSelection( gc->tree );
1124     tvi.pszText = text;
1125     tvi.cchTextMax = sizeof text -1;
1126     tvi.mask = TVIF_TEXT;
1127     TreeView_GetItem( gc->tree, &tvi );
1128    
1129     id = log_box( _("Key Manager"), MB_INFO_ASK,
1130     _("Do you really want to delete this group?\n\n%s"), text);
1131     if( id == IDNO )
1132     return 0;
1133     delete_group( gc->gh, text );
1134     TreeView_DeleteItem( gc->tree, &tvi );
1135     gc->need_sync = 1;
1136    
1137     return 0;
1138     } /* km_groups_del */
1139    
1140    
1141     static int
1142     km_groups_del_entry( km_group_t gc )
1143     {
1144     TVITEM tvi;
1145     HTREEITEM root;
1146     int id;
1147     char text[128], info[256];
1148     gpg_group_t grp = NULL;
1149    
1150     memset( &tvi, 0, sizeof tvi );
1151     tvi.hItem = TreeView_GetSelection( gc->tree );
1152     tvi.pszText = text;
1153     tvi.cchTextMax = sizeof text-1;
1154     tvi.mask = TVIF_TEXT;
1155     TreeView_GetItem( gc->tree, &tvi );
1156    
1157     _snprintf( info, sizeof info -1,
1158     _("Do you really want to delete this entry?\n\n%s"), text );
1159    
1160     id = msg_box( gc->tree, info, _("Key Manager"), MB_INFO_ASK );
1161     if( id == IDNO )
1162     return 0;
1163    
1164     root = TreeView_GetParent( gc->tree, tvi.hItem );
1165     if( root ) {
1166     }
1167    
1168     delete_member( gc->gh, /*fixme*/NULL, text );
1169     TreeView_DeleteItem( gc->tree, &tvi );
1170     gc->need_sync = 1;
1171     return 0;
1172     } /* km_groups_del_entry */
1173    
1174    
1175     int
1176     km_groups_del( km_group_t gc )
1177     {
1178     if ( TreeView_GetParent( gc->tree, TreeView_GetSelection( gc->tree ) ) )
1179     return km_groups_del_entry( gc );
1180     else
1181     return km_groups_del_main( gc );
1182     } /* km_groups_del */
1183 twoaday 23 #endif

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26