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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 201 - (hide annotations)
Sat Apr 22 18:30:24 2006 UTC (18 years, 10 months ago) by twoaday
File size: 57640 byte(s)
See ChangeLog.


1 werner 36 /* wptKeyEditDlgs.cpp - GPG key edit dialogs
2 twoaday 133 * Copyright (C) 2002-2006 Timo Schulz
3 werner 36 *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20 werner 42 #ifdef HAVE_CONFIG_H
21     #include <config.h>
22     #endif
23    
24 werner 36 #include <windows.h>
25     #include <commctrl.h>
26 werner 47 #include <time.h>
27 twoaday 200 #include <assert.h>
28    
29 werner 47 #include "resource.h"
30 werner 36 #include "wptTypes.h"
31     #include "wptW32API.h"
32     #include "wptVersion.h"
33     #include "wptGPG.h"
34     #include "wptCommonCtl.h"
35     #include "wptContext.h"
36     #include "wptDlgs.h"
37     #include "wptNLS.h"
38     #include "wptUTF8.h"
39     #include "wptErrors.h"
40     #include "wptKeylist.h"
41     #include "wptKeyManager.h"
42     #include "wptRegistry.h"
43     #include "wptKeyEdit.h"
44    
45     /* All edit key commands. */
46     enum keyedit_commands {
47     CMD_ADDKEY = 0,
48     CMD_ADDUID,
49     CMD_ADDPHOTO,
50     CMD_ADDREVOKER,
51     CMD_DELUID,
52     CMD_DELKEY,
53     CMD_EXPIRE,
54     CMD_SHOWPREF,
55 twoaday 170 //CMD_SETPREF,
56 werner 36 CMD_PASSWD,
57     CMD_PRIMARY,
58     CMD_TRUST,
59     CMD_REVUID,
60     CMD_REVKEY,
61     CMD_DISABLE,
62 twoaday 170 CMD_ENABLE,
63     CMD_SIGN,
64     CMD_LSIGN,
65 twoaday 195 CMD_CHECK,
66 twoaday 200 CMD_CLEAN,
67 werner 36 };
68    
69 twoaday 170 struct cmdlist_s {
70     const char *name;
71     unsigned int need_pair:1;
72     int id;
73     } cmdlist[] = {
74     {"ADDKEY", 1, CMD_ADDKEY},
75     {"ADDUID", 1, CMD_ADDUID},
76     {"ADDPHOTO", 1, CMD_ADDPHOTO},
77     {"ADDREVOKER", 1, CMD_ADDREVOKER},
78     {"DELUID", 1, CMD_DELUID},
79     {"DELKEY", 1, CMD_DELKEY},
80     {"EXPIRE", 1, CMD_EXPIRE},
81     {"SHOWPREF", 0, CMD_SHOWPREF},
82     /*{"SETPREF", 1, CMD_SETPREF},*/
83     {"PASSWD", 1, CMD_PASSWD},
84     {"PRIMARY", 1, CMD_PRIMARY},
85     {"TRUST", 0, CMD_TRUST},
86     {"REVUID", 1, CMD_REVUID},
87     {"REVKEY", 1, CMD_REVKEY},
88     {"DISABLE", 0, CMD_DISABLE},
89     {"ENABLE", 0, CMD_ENABLE},
90     {"SIGN", 0, CMD_SIGN},
91     {"LSIGN", 0, CMD_LSIGN},
92 twoaday 175 {"CHECK", 0, CMD_CHECK},
93 twoaday 195 {"CLEAN", 0, CMD_CLEAN},
94 twoaday 170 {NULL, 0}
95     };
96 werner 36
97 twoaday 170
98 werner 36 /* Symbolic ids for the subkey columns. */
99     enum subk_col_t {
100     SUBK_COL_DESC = 0,
101     SUBK_COL_KEYID = 1,
102     SUBK_COL_CREATION = 2,
103     SUBK_COL_EXPIRES = 3,
104     SUBK_COL_STATUS = 4,
105     SUBK_COL_C_FLAG = 5,
106     SUBK_COL_S_FLAG = 6,
107     SUBK_COL_E_FLAG = 7,
108     SUBK_COL_A_FLAG = 8
109     };
110    
111     /* Symbolic ids for the userid columns. */
112     enum uid_col_t {
113     UID_COL_VALID = 0,
114     UID_COL_NAME = 1,
115     UID_COL_EMAIL = 2,
116     UID_COL_CREATION = 3
117     };
118    
119 twoaday 176 /* Key edit callback context. */
120     struct keyedit_cb_s {
121 werner 36 const char *keyid;
122     const char *pass;
123     listview_ctrl_t lv;
124     void *opaque;
125     unsigned int finished:1;
126 twoaday 176 unsigned int is_protected:1;
127 werner 36 };
128 twoaday 176 typedef struct keyedit_cb_s *keyedit_cb_t;
129 werner 36
130 twoaday 176
131     /* Key generation callback context. */
132     struct keygen_cb_s {
133 werner 36 int bits;
134     int algo;
135     u32 expire;
136     char *fpr;
137 twoaday 200 char *name;
138     char *comment;
139     char *email;
140 werner 36 };
141 twoaday 176 typedef struct keygen_cb_s *keygen_cb_t;
142 werner 36
143 twoaday 200 /* Subclass context for the subkey list. */
144     static subclass_s keyedit_subkey_proc;
145 werner 36
146 twoaday 200 /* Subclass context for the user-id list. */
147 werner 36 static subclass_s keyedit_uid_proc;
148    
149     int keygen_check_date (SYSTEMTIME *st);
150     void get_userid_preflist (char **r_prefs, int * r_flags);
151 twoaday 150 char* get_subkey_keyid (const char *keyid);
152 werner 36
153    
154 twoaday 200 static GpgKeyEdit*
155     create_GpgKeyEdit (const char *keyid)
156     {
157     GpgKeyEdit *ke;
158    
159     ke = new GpgKeyEdit (keyid);
160     if (!ke)
161     BUG (NULL);
162     return ke;
163     }
164    
165    
166 werner 36 /* Associate each key with a combo box entry.
167     Skip the key in @k. */
168     static void
169 twoaday 200 do_init_keylist (HWND dlg, const char *keyid)
170 werner 36 {
171     gpg_keycache_t pub;
172     gpgme_key_t key;
173 twoaday 128 const char *s, *kid;
174     char *u;
175 werner 36 int i, n;
176    
177     pub = keycache_get_ctx (1);
178     if (!pub)
179     BUG (0);
180    
181     gpg_keycache_rewind (pub);
182 twoaday 128 while( !gpg_keycache_next_key (pub, 0, &key)) {
183     if (key->expired || key->revoked ||
184 twoaday 78 key->disabled || key->invalid)
185     continue;
186 werner 36 s = key->uids->uid;
187     kid = key->subkeys->keyid;
188 twoaday 200 if (!s || !strcmp (kid+8, keyid))
189 werner 36 continue;
190 twoaday 187 u = utf8_to_native (s);
191 werner 36 SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_ADDSTRING,
192     0, (WPARAM)(char *)u);
193     free (u);
194     }
195     gpg_keycache_rewind (pub);
196     n = SendDlgItemMessage( dlg, IDC_ADDREV_KEYLIST, CB_GETCOUNT, 0, 0 );
197     for (i = 0; i < n; i++) {
198     gpg_keycache_next_key (pub, 0, &key);
199     SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_SETITEMDATA,
200     (WPARAM)(int)i, (LPARAM)key);
201     }
202     SendDlgItemMessage (dlg, IDC_ADDREV_KEYLIST, CB_SETCURSEL, 0, 0);
203     }
204    
205    
206     /* Add a new user-id to the list view @lv. */
207     static void
208     do_add_new_userid (listview_ctrl_t lv,
209 twoaday 201 const char *utf8_name, const char *email,
210     const char *utf8_comment)
211 werner 36 {
212 twoaday 201 char *p, *uid, *com;
213 werner 36 size_t n;
214    
215 twoaday 185 n = strlen (utf8_name) + strlen (email) + 16;
216 twoaday 201 if (utf8_comment)
217     n += strlen (utf8_comment);
218     uid = utf8_to_native (utf8_name);
219 werner 36 p = new char[n+1];
220     if (!p)
221 twoaday 185 BUG (NULL);
222 twoaday 201 if (utf8_comment) {
223     com = utf8_to_native (utf8_comment);
224     if (!com)
225     BUG (NULL);
226     sprintf (p, "%s (%s)", uid, com);
227     free_if_alloc (com);
228     }
229 werner 36 else
230 twoaday 185 sprintf (p, "%s", uid);
231     free (uid);
232 werner 36
233     listview_add_item (lv, "");
234     listview_add_sub_item (lv, 0, 0, _("Ultimate" ));
235     listview_add_sub_item (lv, 0, 1, p);
236     listview_add_sub_item (lv, 0, 2, email && *email? email : "");
237     listview_add_sub_item (lv, 0, 3, get_key_created (time (NULL)));
238     free_if_alloc (p);
239 twoaday 129 }
240 werner 36
241    
242     static void
243 twoaday 176 do_add_new_subkey (listview_ctrl_t lv, keygen_cb_t keygen, unsigned int flags)
244 werner 36 {
245     char info[128], keyid[32];
246 twoaday 200 const char *expdate, *s;
247 werner 36 int n;
248    
249     expdate = keygen->expire? get_key_expire_date (keygen->expire) : _("Never");
250     _snprintf (info, sizeof info-1, "%d-bit %s",
251     keygen->bits,
252     get_key_pubalgo ((gpgme_pubkey_algo_t)keygen->algo));
253 twoaday 150 _snprintf (keyid, sizeof keyid-1, "0x%s", keygen->fpr+8);
254 werner 36 n = listview_count_items (lv, 0);
255     listview_add_item_pos (lv, n);
256     listview_add_sub_item (lv, n, 0, info);
257     listview_add_sub_item (lv, n, 1, keyid);
258     listview_add_sub_item (lv, n, 2, get_key_created (time (NULL)));
259     listview_add_sub_item (lv, n, 3, expdate);
260 twoaday 150 if (flags & KM_FLAG_REVOKED)
261     s = _("Revoked");
262     else if (flags & KM_FLAG_EXPIRED)
263     s = _("Expired");
264     else
265     s = _("OK");
266 werner 36 listview_add_sub_item (lv, n, 4, s);
267 twoaday 150 }
268 werner 36
269    
270     /* Try to find the GPG edit key index which belongs to the user ID
271 twoaday 160 given by the email address @email, @name is used as a fallback.
272     If @r_inf != NULL, the info context will be returned.
273 werner 36 Return value: index of the user ID or -1 on error. */
274     static int
275 twoaday 160 do_find_userid (const char *keyid, const char *email,
276     const char *name, gpg_uid_info_t *r_inf)
277 werner 36 {
278     GpgKeyEdit *ke;
279     gpgme_error_t err;
280     gpg_uid_info_t inf, ui;
281 twoaday 187 char *ui_name = NULL;
282 werner 36 int pos = -1;
283    
284 twoaday 200 ke = create_GpgKeyEdit (keyid);
285 werner 36 err = ke->getUseridInfo (&inf);
286     delete ke;
287     if (err) {
288     log_box (_("user ID"), MB_ERR,
289     _("Could not get key information for: \"%s\":\n%s"),
290     name, gpgme_strerror (err));
291     return -1;
292     }
293    
294     for (ui = inf; ui; ui = ui->next) {
295 twoaday 187 safe_free (ui_name);
296     ui_name = utf8_to_native (ui->name);
297     if (name && email && ui->email && ui_name) {
298 twoaday 160 if (!strcmp (ui->email, email) &&
299 twoaday 187 !strncmp (ui_name, name, strlen (name))) {
300 twoaday 160 pos = ui->index;
301     break;
302     }
303     continue;
304     }
305     if (ui->email) {
306     if (!strcmp (ui->email, email)) {
307     pos = ui->index;
308     break;
309     }
310     /* The email address is more unique, use the name just
311     as the fallbck when no email address is available. */
312     continue;
313     }
314 twoaday 187 if (ui_name && name && !strcmp (ui_name, name)) {
315 werner 36 pos = ui->index;
316     break;
317     }
318     }
319     if (r_inf)
320     *r_inf = inf;
321     else
322     gpg_uid_info_release (inf);
323 twoaday 187 safe_free (ui_name);
324 werner 36 return pos;
325     }
326    
327    
328 twoaday 128 /* Return true if @fname is a JPEG file. */
329     bool
330     is_jpg_file (const char *fname)
331     {
332     FILE *fp;
333     BYTE buf[10];
334     int n;
335    
336     fp = fopen (fname, "rb");
337     if (!fp)
338     return false;
339     n = fread (buf, 1, 10, fp);
340     fclose (fp);
341     if (n < 10)
342     return false;
343     return buf[6] == 'J' && buf[7] == 'F' &&
344     buf[8] == 'I' && buf[9] == 'F';
345     }
346    
347    
348 werner 36 /* Dialog box procedure to add a photo. */
349     BOOL CALLBACK
350     keyedit_addphoto_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
351     {
352 twoaday 200 static keyedit_cb_t cb;
353 werner 36 GpgKeyEdit *ke;
354 twoaday 200 gpgme_error_t err;
355     const char *s;
356     char file[128];
357 werner 36 int id;
358    
359     switch( msg ) {
360     case WM_INITDIALOG:
361 twoaday 200 cb = (keyedit_cb_t)lparam;
362     if (!cb)
363 werner 36 BUG (NULL);
364     SetDlgItemText (dlg, IDC_ADDPHOTO_INF, _("Remember that the image is stored within your public key. If you use a very large picture, your key will become very large as well! Keeping the image close to 240x288 is a good size to use."));
365     SetDlgItemText (dlg, IDC_ADDPHOTO_FILEINF, _("Pick an image to use for your photo ID.\nThe image must be a JPEG file."));
366     SetDlgItemText (dlg, IDC_ADDPHOTO_PWDINF, _("Passphrase"));
367 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
368 twoaday 128 SetWindowText (dlg, _("Add Photo ID"));
369 twoaday 105 SetForegroundWindow (dlg);
370 werner 36 break;
371    
372     case WM_DESTROY:
373     break;
374    
375     case WM_SYSCOMMAND:
376 twoaday 128 if (LOWORD (wparam) == SC_CLOSE)
377     EndDialog (dlg, TRUE);
378 werner 36 break;
379    
380     case WM_COMMAND:
381 twoaday 200 switch( LOWORD (wparam)) {
382 werner 36 case IDC_ADDPHOTO_SELFILE:
383 twoaday 128 s = get_fileopen_dlg (dlg, _("Select Image File"),
384 twoaday 180 "JPEG Files (*.jpg, *.jpeg)\0*.jpg;*.jpeg\0\0",
385 twoaday 128 NULL);
386     if (s && !is_jpg_file (s)) {
387     log_box (_("Add Photo"), MB_ERR,
388     _("'%s' is not a valid JPEG file."), s);
389     return FALSE;
390     }
391     if (s && *s)
392     SetDlgItemText (dlg, IDC_ADDPHOTO_FILE, s);
393 werner 36 break;
394    
395     case IDOK:
396 twoaday 128 if (!GetDlgItemText (dlg, IDC_ADDPHOTO_FILE, file, sizeof (file)-1)){
397     msg_box( dlg, _("Please enter a file name."), _("Add Photo"), MB_ERR);
398 werner 36 return FALSE;
399     }
400 twoaday 128 if (get_file_size (file) == 0 || get_file_size (file) > 6144 ) {
401     id = msg_box (dlg, _("The JPEG is really large.\n"
402 werner 36 "Are you sure you want to use it?"),
403 twoaday 128 _("Add Photo"), MB_YESNO|MB_INFO);
404     if (id == IDNO)
405 werner 36 return TRUE;
406     }
407 twoaday 200 ke = create_GpgKeyEdit (cb->keyid);
408     if (cb->pass)
409     ke->setPassphrase (cb->pass);
410 twoaday 176 else
411     ke->setNoPassphrase (true);
412 twoaday 200 err = ke->addPhotoid (file);
413 werner 36 delete ke;
414 twoaday 200 if (err) {
415     msg_box (dlg, gpgme_strerror (err), _("Add Photo"), MB_ERR);
416 werner 36 return FALSE;
417     }
418     else {
419 twoaday 200 cb->finished = 1;
420 twoaday 128 msg_box (dlg, _("Photo successfully added."),
421     _("GnuPG Status"), MB_OK);
422 werner 36 }
423     EndDialog (dlg, TRUE);
424     break;
425    
426     case IDCANCEL:
427     EndDialog (dlg, FALSE);
428     break;
429     }
430     break;
431     }
432     return FALSE;
433     }
434    
435    
436     /* Dialog box procedure to add a designated revoker. */
437     BOOL CALLBACK
438     keyedit_addrevoker_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
439     {
440 twoaday 200 static keyedit_cb_t cb;
441 twoaday 129 gpgme_error_t err;
442 werner 36 GpgKeyEdit *ke;
443 twoaday 201 char uid[128], *utf8_uid;
444 werner 36
445 twoaday 129 switch (msg) {
446 werner 36 case WM_INITDIALOG:
447 twoaday 200 cb = (keyedit_cb_t)lparam;
448     if (!cb)
449 twoaday 129 BUG (NULL);
450 twoaday 200 do_init_keylist (dlg, cb->keyid);
451 twoaday 129 SetDlgItemText (dlg, IDC_ADDREV_INF,
452     _("Appointing a key as designated revoker cannot be undone."));
453 werner 36 SetDlgItemText (dlg, IDC_ADDREV_KEYINF, _("Public key"));
454     SetDlgItemText (dlg, IDC_ADDREV_PWDINF, _("Passphrase"));
455 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
456 twoaday 128 SetWindowText (dlg, _("Add Revoker"));
457 twoaday 105 SetForegroundWindow (dlg);
458 werner 36 break;
459    
460     case WM_DESTROY:
461     break;
462    
463     case WM_SYSCOMMAND:
464 twoaday 200 if (LOWORD (wparam) == SC_CLOSE)
465     EndDialog (dlg, FALSE);
466 werner 36 break;
467    
468     case WM_COMMAND:
469 twoaday 200 switch (LOWORD (wparam)) {
470 werner 36 case IDOK:
471     if( !GetDlgItemText( dlg, IDC_ADDREV_KEYLIST, uid, sizeof uid-1 ) ) {
472     msg_box( dlg, _("Please select a user ID."), _("Add Revoker"), MB_ERR );
473     return FALSE;
474     }
475 twoaday 201 utf8_uid = native_to_utf8 (uid);
476 twoaday 200 ke = create_GpgKeyEdit (cb->keyid);
477     if (cb->pass)
478     ke->setPassphrase (cb->pass);
479 twoaday 176 else
480     ke->setNoPassphrase (true);
481 twoaday 201 err = ke->addDesignatedRevoker (utf8_uid);
482     free_if_alloc (utf8_uid);
483 werner 36 delete ke;
484     if (err) {
485     msg_box (dlg, gpgme_strerror (err), _("Add Revoker"), MB_ERR);
486     return TRUE;
487     }
488     else {
489 twoaday 200 cb->finished = 1;
490 twoaday 129 msg_box (dlg, _("Revoker successfully addded."),
491     _("GnuPG Status"), MB_OK);
492 werner 36 }
493 twoaday 129 EndDialog (dlg, TRUE);
494 werner 36 break;
495    
496     case IDCANCEL:
497 twoaday 129 EndDialog (dlg, FALSE);
498 werner 36 break;
499     }
500     break;
501     }
502     return FALSE;
503     }
504    
505    
506     /* Dialog box procedure to add a new user-ID. */
507     BOOL CALLBACK
508     keyedit_adduid_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
509     {
510 twoaday 176 static keyedit_cb_t ctx;
511 twoaday 200 keygen_cb_t keygen;
512 werner 36 gpgme_error_t err;
513     GpgKeyEdit *ke;
514     char *utf8_name = NULL;
515 twoaday 201 char *utf8_comment = NULL;
516 werner 36 char name[128], email[128], comment[128];
517     int rc;
518    
519 twoaday 176 switch (msg) {
520 werner 36 case WM_INITDIALOG:
521 twoaday 176 ctx = (keyedit_cb_t)lparam;
522 twoaday 200 if (!ctx)
523 werner 36 dlg_fatal_error(dlg, "Could not get dialog param!");
524     SetWindowText (dlg, _("Add new User ID"));
525     SetDlgItemText (dlg, IDC_ADDUID_INFNAME, _("&Name"));
526     SetDlgItemText (dlg, IDC_ADDUID_INFEMAIL, _("&Email"));
527     SetDlgItemText (dlg, IDC_ADDUID_INFCOMMENT, _("&Comment"));
528 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
529 werner 36 SetForegroundWindow (dlg);
530     return FALSE;
531    
532     case WM_SYSCOMMAND:
533 twoaday 176 if (LOWORD (wparam) == SC_CLOSE)
534 werner 36 EndDialog(dlg, TRUE);
535     return FALSE;
536    
537     case WM_COMMAND:
538     switch ( LOWORD( wparam ) ) {
539     case IDOK:
540 twoaday 200 keygen = (keygen_cb_t)ctx->opaque;
541     rc = GetDlgItemText (dlg, IDC_ADDUID_NAME, name, sizeof name-1);
542 werner 36 if (!rc || rc < 5) {
543     msg_box( dlg, _("Please enter a name (min. 5 chars.)"), _("UserID"), MB_ERR );
544     return FALSE;
545     }
546     if (strchr (name, '@')) {
547     msg_box( dlg, _("Please enter the email address in the email field and not in the name field"), _("UserID"), MB_INFO );
548     return FALSE;
549     }
550    
551     if( !GetDlgItemText( dlg, IDC_ADDUID_EMAIL, email, sizeof email -1 ) ) {
552     msg_box( dlg, _("Please enter an email address."), _("UserID"), MB_ERR );
553     return FALSE;
554     }
555 twoaday 190 if (check_email_address (email)) {
556 twoaday 175 msg_box (dlg, _("Invalid email address."), _("UserID"), MB_ERR);
557 werner 36 return FALSE;
558     }
559    
560 twoaday 175 rc = GetDlgItemText (dlg, IDC_ADDUID_COMMENT,
561     comment, sizeof comment -1);
562 twoaday 201 if (rc > 0)
563     utf8_comment = native_to_utf8 (comment);
564     utf8_name = native_to_utf8 (name);
565 werner 36
566 twoaday 200 ke = create_GpgKeyEdit (ctx->keyid);
567 twoaday 176 if (ctx->is_protected)
568 werner 36 ke->setPassphrase (ctx->pass);
569 twoaday 176 else
570     ke->setNoPassphrase (true);
571 twoaday 201 err = ke->addUserid (utf8_name, utf8_comment, email);
572 werner 36 if (err)
573     msg_box (dlg, gpgme_strerror (err), _("UserID"), MB_ERR);
574     else {
575     msg_box (dlg, _("user ID successfully added."), _("GnuPG Status"), MB_OK);
576     ctx->finished = 1;
577 twoaday 201 keygen->name = utf8_name;
578     keygen->comment = utf8_comment;
579 twoaday 200 keygen->email = m_strdup (email);
580 werner 36 }
581 twoaday 200 delete ke;
582 werner 36 EndDialog (dlg, TRUE);
583     return TRUE;
584    
585     case IDCANCEL:
586     EndDialog (dlg, FALSE);
587     return FALSE;
588     }
589     break;
590     }
591    
592     return FALSE;
593     }
594    
595    
596     static void
597     init_keysize_box (HWND dlg, int ctlid)
598     {
599     const char *sizelist[] = {
600 twoaday 200 "1024", "1536",
601     "2048", "2560",
602     "3072", "3854",
603     "4096", NULL
604 werner 36 };
605     int i;
606 twoaday 200
607 werner 36 for (i=0; sizelist[i] != NULL; i++)
608 twoaday 200 SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0,
609     (LPARAM)(char*)sizelist[i]);
610 werner 36 SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, (WPARAM)2, 0);
611     }
612    
613 twoaday 200
614 werner 36 static int
615     get_keysize_from_box (HWND dlg, int ctlid)
616     {
617     int pos;
618     char buf[32];
619    
620     pos = SendDlgItemMessage (dlg, ctlid, CB_GETCURSEL, 0, 0);
621     if (pos == CB_ERR)
622     return -1;
623     SendDlgItemMessage (dlg, ctlid, CB_GETLBTEXT, pos, (LPARAM)(char*)buf);
624     return atol (buf);
625     }
626    
627    
628 twoaday 175 /* Create a time_t from a system time @st. */
629     time_t
630     w32_mktime (SYSTEMTIME *st)
631     {
632     struct tm tm;
633    
634     memset (&tm, 0, sizeof (tm));
635     tm.tm_year = st->wYear-1900;
636     tm.tm_mday = st->wDay+1;
637     tm.tm_mon = st->wMonth-1;
638     return mktime (&tm);
639     }
640    
641    
642 twoaday 129 /* Dialog procedure for adding a new secondary key. */
643 werner 36 BOOL CALLBACK
644     keyedit_addsubkey_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
645     {
646 twoaday 176 static keyedit_cb_t ctx;
647 twoaday 200 keygen_cb_t keygen;
648 werner 36 GpgKeyEdit *ke;
649     gpgme_error_t err;
650 twoaday 175 SYSTEMTIME st;
651 twoaday 200 HWND hwnd;
652 werner 36 int index, size, valid;
653    
654     switch (msg) {
655     case WM_INITDIALOG:
656 twoaday 176 ctx = (keyedit_cb_t)lparam;
657 werner 36 if (!ctx)
658     dlg_fatal_error (dlg, "Could not get dialog param!");
659 twoaday 99
660 werner 36 SetWindowText (dlg, _("Add new Subkey"));
661     SetDlgItemText (dlg, IDC_ADDSUBKEY_INFALGO, _("Key type"));
662     SetDlgItemText (dlg, IDC_ADDSUBKEY_INFSIZE, _("Size in bits"));
663     SetDlgItemText (dlg, IDC_ADDSUBKEY_INFVALID, _("Key expiration"));
664 twoaday 99 SetDlgItemText (dlg, IDC_ADDSUBKEY_EXPIRE, _("&Never"));
665 twoaday 105 SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
666 twoaday 99
667 twoaday 200 hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
668     listbox_add_string (hwnd, "DSA (sign only)");
669     listbox_add_string (hwnd, "ElGamal (encrypt only)");
670     listbox_add_string (hwnd, "RSA (sign only)");
671     listbox_add_string (hwnd, "RSA (encrypt only)");
672 werner 36 CheckDlgButton (dlg, IDC_ADDSUBKEY_EXPIRE, BST_CHECKED);
673     EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
674     init_keysize_box (dlg, IDC_ADDSUBKEY_SIZE);
675 twoaday 105 SetForegroundWindow (dlg);
676 werner 36 return FALSE;
677    
678     case WM_SYSCOMMAND:
679 twoaday 200 if (LOWORD (wparam) == SC_CLOSE)
680 twoaday 150 EndDialog (dlg, TRUE);
681 werner 36 return FALSE;
682    
683     case WM_COMMAND:
684 twoaday 150 if (HIWORD (wparam) == BN_CLICKED &&
685     LOWORD (wparam) == IDC_ADDSUBKEY_EXPIRE) {
686 werner 36 if (IsDlgButtonChecked (dlg, IDC_ADDSUBKEY_EXPIRE))
687     EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), FALSE);
688     else
689     EnableWindow (GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE), TRUE);
690     }
691 twoaday 150 if (HIWORD (wparam) == LBN_SELCHANGE &&
692     LOWORD (wparam) == IDC_ADDSUBKEY_ALGO) {
693 werner 36 index = SendMessage ((HWND)lparam, LB_GETCURSEL, 0, 0);
694     if (index == 0)
695     SendDlgItemMessage (dlg, IDC_ADDSUBKEY_SIZE, CB_SETCURSEL, 0, 0);
696     }
697    
698 twoaday 150 switch (LOWORD (wparam)) {
699 werner 36 case IDOK:
700 twoaday 200 keygen = (keygen_cb_t)ctx->opaque;
701     assert (keygen);
702     hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_ALGO);
703     switch (listbox_get_cursel (hwnd)) {
704 werner 36 case 0: index = 2; break;
705     case 1: index = 4; break;
706     case 2: index = 5; break;
707     case 3: index = 6; break;
708 twoaday 150 default:
709 twoaday 200 msg_box (dlg, _("Please select one entry."),
710     _("Add Subkey"), MB_ERR);
711 werner 36 return FALSE;
712     }
713     size = get_keysize_from_box (dlg, IDC_ADDSUBKEY_SIZE);
714     if (index == 2 && size != 1024) {
715 twoaday 200 msg_box (dlg,_("DSS uses a fixed keysize of 1024. Size changed."),
716 twoaday 150 _("Add Subkey"), MB_INFO);
717 werner 36 size = 1024;
718     }
719 twoaday 175
720 twoaday 200 hwnd = GetDlgItem (dlg, IDC_ADDSUBKEY_EXPDATE);
721     DateTime_GetSystemtime (hwnd, &st);
722 twoaday 175 valid = w32_mktime (&st) - time (NULL);
723     valid /= 86400;
724    
725 werner 36 keygen->bits = size;
726     switch (index) {
727     case 2: keygen->algo = GPGME_PK_DSA; break;
728     case 4: keygen->algo = GPGME_PK_ELG_E; break;
729     case 5: keygen->algo = GPGME_PK_RSA_S; break;
730     case 6: keygen->algo = GPGME_PK_RSA_E; break;
731     }
732     if (valid > 0)
733     keygen->expire = time (NULL) + valid*24*60*60;
734    
735 twoaday 200 ke = create_GpgKeyEdit (ctx->keyid);
736 werner 36 ke->setCallback (keygen_cb, NULL);
737 twoaday 176 if (ctx->is_protected)
738 twoaday 150 ke->setPassphrase (ctx->pass);
739 twoaday 176 else
740     ke->setNoPassphrase (true);
741 werner 36 keygen_cb_dlg_create ();
742    
743     err = ke->addSubkey ((gpgme_pubkey_algo_t)index, size, valid);
744 twoaday 150 keygen->fpr = get_subkey_keyid (ctx->keyid);
745 werner 36 keygen_cb_dlg_destroy ();
746     keygen_cb (NULL, NULL, 0, 0, 0); /* flush */
747     if (err)
748     msg_box (dlg, gpgme_strerror (err), _("Add Subkey"), MB_ERR);
749     else {
750 twoaday 200 msg_box (dlg, _("Subkey successfully added."),
751     _("GnuPG Status"), MB_OK);
752 werner 36 ctx->finished = 1;
753     }
754     delete ke;
755 twoaday 129 EndDialog (dlg, TRUE);
756 werner 36 return TRUE;
757    
758     case IDCANCEL:
759 twoaday 129 EndDialog (dlg, FALSE);
760 werner 36 return FALSE;
761     }
762     break;
763     }
764    
765     return FALSE;
766 twoaday 129 }
767 werner 36
768    
769     BOOL
770     keyedit_add_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
771     {
772 twoaday 176 keyedit_cb_s cb;
773 twoaday 200 keygen_cb_s keygen;
774 werner 36 char *pass = NULL;
775     int cancel = 0;
776    
777     if (!k->key_pair) {
778 twoaday 200 msg_box (dlg, _("There is no secret key available!"),
779     _("Add user ID"), MB_ERR);
780 werner 36 return FALSE;
781     }
782    
783     if (k->is_protected) {
784 twoaday 200 pass = request_passphrase (_("Key Edit"), 1, &cancel);
785 werner 36 if (cancel)
786     return FALSE;
787     }
788 twoaday 200
789     memset (&keygen, 0, sizeof (keygen));
790 werner 36 memset (&cb, 0, sizeof cb);
791 twoaday 200 cb.opaque = &keygen;
792 twoaday 176 cb.is_protected = k->is_protected;
793     cb.pass = pass;
794 werner 36 cb.keyid = k->keyid;
795     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDUID,
796     dlg, keyedit_adduid_dlg_proc,
797     (LPARAM)&cb, _("Add user ID"),
798     IDS_WINPT_KEYEDIT_ADDUID);
799 twoaday 200 if (lv != NULL && cb.finished)
800     do_add_new_userid (lv, keygen.name, keygen.email, keygen.comment);
801 werner 36 if (cb.finished)
802     k->update = 1;
803    
804 twoaday 200 free_if_alloc (keygen.name);
805     free_if_alloc (keygen.email);
806     free_if_alloc (keygen.comment);
807 werner 36 sfree_if_alloc (pass);
808     return TRUE;
809     }
810    
811    
812 twoaday 200 /* Return the keyID of the last subkey. */
813 werner 36 char*
814 twoaday 150 get_subkey_keyid (const char *keyid)
815 werner 36 {
816     gpgme_error_t err;
817 twoaday 150 gpgme_key_t key;
818 werner 36 gpgme_ctx_t ctx;
819 twoaday 150 gpgme_subkey_t subk;
820 twoaday 200 char *kid = NULL;
821 werner 36
822     err = gpgme_new (&ctx);
823     if (err)
824     return NULL;
825     err = gpgme_get_key (ctx, keyid, &key, 0);
826 twoaday 150 gpgme_release (ctx);
827 werner 36 if (err)
828     return NULL;
829 twoaday 150 subk = get_nth_key (key, count_subkeys (key));
830 twoaday 200 if (subk != NULL)
831     kid = strdup (subk->keyid);
832 werner 36 gpgme_key_release (key);
833 twoaday 150 return kid;
834 werner 36 }
835    
836    
837     BOOL
838     keyedit_add_subkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
839     {
840 twoaday 176 keyedit_cb_s cb;
841     keygen_cb_s keygen;
842 werner 36 char *pass = NULL;
843     int cancel = 0;
844    
845     if (!k->key_pair) {
846 twoaday 200 msg_box (dlg, _("There is no secret key available!"),
847     _("Add Subkey"), MB_ERR);
848 werner 36 return FALSE;
849     }
850     if (k->is_protected) {
851     pass = request_passphrase (_("Key Edit"), 1, &cancel);
852     if (cancel)
853     return FALSE;
854     }
855    
856     memset (&keygen, 0, sizeof (keygen));
857     memset (&cb, 0, sizeof (cb));
858     cb.keyid = k->keyid;
859 twoaday 176 cb.is_protected = k->is_protected;
860     cb.pass = pass;
861 werner 36 cb.opaque = &keygen;
862     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_KEYEDIT_ADDSUBKEY,
863     dlg, keyedit_addsubkey_dlg_proc,
864     (LPARAM)&cb, _("Add new Subkey"),
865     IDS_WINPT_KEYEDIT_ADDSUBKEY);
866 twoaday 200 if (lv != NULL && cb.finished)
867     do_add_new_subkey (lv, &keygen, 0);
868 werner 36 if (cb.finished)
869     k->update = 1;
870    
871 twoaday 200 safe_free (keygen.fpr);
872     sfree_if_alloc (pass);
873 werner 36 return cb.finished? TRUE: FALSE;
874     }
875    
876    
877     BOOL
878     keyedit_set_pref_keyserver (winpt_key_t k, HWND dlg)
879     {
880     GpgKeyEdit *ke;
881     gpgme_error_t err;
882     struct URL_ctx_s *url;
883 twoaday 200 char *pass = NULL;
884 werner 36
885     url = (struct URL_ctx_s *)get_keyserver_URL_dlg (dlg);
886     if (url->cancel == 1) {
887     delete url;
888     return FALSE;
889     }
890    
891     pass = request_passphrase (_("Key Edit"), 1, &url->cancel);
892     if (url->cancel) {
893     delete url;
894     return FALSE;
895     }
896    
897 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
898 twoaday 175 if (k->is_protected)
899     ke->setPassphrase (pass);
900 twoaday 176 else
901     ke->setNoPassphrase (true);
902 twoaday 181 err = ke->setPreferredKeyserver (-1, url->url);
903 werner 36 if (!err)
904     msg_box (dlg, _("Preferred keyserver successfully set."), _("Key Edit"), MB_OK);
905 twoaday 188 else
906     msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
907 werner 36
908     sfree_if_alloc (pass);
909     delete ke;
910 twoaday 181 delete url;
911 werner 36 return err == 0? 0 : WPTERR_GENERAL;
912     }
913    
914    
915     /* Add a photo-ID to the key specified in @k. @dlg is the handle of
916     the calling dialog. */
917     BOOL
918     keyedit_add_photo (winpt_key_t k, HWND dlg)
919     {
920 twoaday 200 keyedit_cb_s cb;
921     char *pass = NULL;
922     int cancel;
923    
924 werner 36 if (!k->key_pair) {
925 twoaday 180 msg_box (dlg, _("There is no secret key available!"),
926     _("Add Photo"), MB_ERR);
927 werner 36 return FALSE;
928     }
929 twoaday 200
930     memset (&cb, 0, sizeof (cb));
931     if (k->is_protected) {
932     pass = request_passphrase (_("Key Edit"), 1, &cancel);
933     if (cancel)
934     return FALSE;
935     }
936     cb.pass = pass;
937     cb.keyid = k->keyid;
938    
939 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDPHOTO, dlg,
940 twoaday 200 keyedit_addphoto_dlg_proc, (LPARAM)&cb);
941    
942     if (cb.finished)
943     k->update = 1;
944     sfree_if_alloc (pass);
945 werner 36 return TRUE;
946     }
947    
948    
949     BOOL
950     keyedit_add_revoker (winpt_key_t k, HWND dlg)
951     {
952 twoaday 200 keyedit_cb_s cb;
953     char *pass = NULL;
954     int cancel;
955    
956 twoaday 129 if (!k->key_pair) {
957     msg_box (dlg, _("There is no secret key available!"), _("Add Revoker"), MB_ERR);
958 werner 36 return FALSE;
959     }
960 twoaday 200
961     if (k->is_protected) {
962     pass = request_passphrase (_("Key Edit"), 1, &cancel);
963     if (cancel)
964     return FALSE;
965     }
966    
967     memset (&cb, 0, sizeof (cb));
968     cb.is_protected = k->is_protected;
969     cb.keyid = k->keyid;
970     cb.pass = pass;
971 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_ADDREV, dlg,
972 twoaday 200 keyedit_addrevoker_dlg_proc, (LPARAM)&cb);
973    
974     if (cb.finished)
975     k->update = 1;
976     sfree_if_alloc (pass);
977 werner 36 return TRUE;
978 twoaday 129 }
979 werner 36
980    
981 twoaday 165 /* Change ownertrust of the given key @key.
982     Return TRUE if the ownertrust was changed. */
983     BOOL
984     keyedit_change_ownertrust (winpt_key_t key, HWND dlg)
985     {
986     int rc;
987    
988     rc = dialog_box_param (glob_hinst,
989     (LPCSTR)IDD_WINPT_KEYEDIT_OWNERTRUST,
990     dlg, keyedit_ownertrust_dlg_proc,
991     (LPARAM)key, _("Change Ownertrust"),
992     IDS_WINPT_KEYEDIT_OWNERTRUST);
993 twoaday 170 if (rc == TRUE) {
994     msg_box (dlg, _("Key status changed."), _("Key Edit"), MB_OK);
995 twoaday 165 key->update = 1;
996 twoaday 170 }
997 twoaday 165 return rc;
998     }
999    
1000    
1001 twoaday 180 /* Check if the given key is supposed to have IDEA
1002     for secret key protection. */
1003 werner 36 static int
1004 twoaday 180 is_idea_protect_algo (const char *keyid)
1005 werner 36 {
1006     winpt_key_s k;
1007     const unsigned char *sym_prefs;
1008     size_t n;
1009    
1010     memset (&k, 0, sizeof (k));
1011     if (winpt_get_pubkey (keyid, &k))
1012 twoaday 180 BUG (0);
1013 werner 36 sym_prefs = k.ext->sym_prefs;
1014 twoaday 180 if (!k.is_v3)
1015     return 0;
1016 werner 36 if (!sym_prefs)
1017     return 1; /* assume that only v3 keys have no symmetric cipher preferences
1018     and thus IDEA is explicit. */
1019     for (n = 0; sym_prefs[n]; n++)
1020     ;
1021     if ((n == 0 || n == 1) && *sym_prefs == 0x01)
1022     return 1;
1023     return 0;
1024 twoaday 180 }
1025 werner 36
1026    
1027     BOOL
1028 twoaday 129 keyedit_change_passwd (winpt_key_t k, HWND dlg)
1029 werner 36 {
1030 twoaday 200 gpgme_error_t err;
1031 werner 36 GpgKeyEdit *ke;
1032 twoaday 129 char *old_pass = NULL;
1033     char *new_pass = NULL;
1034 werner 36 int cancel = 0;
1035    
1036 twoaday 175 if (!k->key_pair) {
1037     msg_box (dlg, _("There is no secret key available!"),
1038     _("Key Edit"), MB_ERR);
1039 werner 36 return FALSE;
1040     }
1041    
1042 twoaday 180 if (!idea_available && is_idea_protect_algo (k->keyid)) {
1043     msg_box (dlg, _("Cannot change passphrase because the key\n"
1044     "is protected with the IDEA encryption algorithm."),
1045     _("Key Edit"), MB_ERR);
1046 werner 36 return FALSE;
1047     }
1048    
1049 twoaday 129 if (k->is_protected) {
1050     old_pass = request_passphrase (_("Current (old) Passphrase"), 1, &cancel);
1051 twoaday 128 if (cancel)
1052 werner 36 return FALSE;
1053     }
1054 twoaday 129 new_pass = request_passphrase2 (_("New Passphrase" ), 1, &cancel);
1055     if (cancel) {
1056     free_if_alloc (old_pass);
1057 werner 36 return FALSE;
1058     }
1059    
1060 twoaday 129 if (is_8bit_string (new_pass)) {
1061     msg_box (dlg, _("The passphrase contains 8-bit characters.\n"
1062 werner 36 "It is not suggested to use charset specific characters."),
1063 twoaday 129 _("Key Edit"), MB_ERR);
1064     free_if_alloc (old_pass);
1065     free_if_alloc (new_pass);
1066 werner 36 return FALSE;
1067     }
1068    
1069 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
1070 werner 36 ke->setPassphrase (k->is_protected? old_pass : NULL);
1071 twoaday 200 err = ke->changePassphrase (new_pass, 0);
1072     if (err)
1073     msg_box (dlg, gpgme_strerror (err), _("Change Passwd"), MB_ERR);
1074 werner 36 else
1075     msg_box (dlg, _("Passphrase successfully changed."), _("GnuPG status"), MB_OK);
1076     sfree_if_alloc (old_pass);
1077     sfree_if_alloc (new_pass);
1078     delete ke;
1079     return TRUE;
1080     }
1081    
1082    
1083 twoaday 165 /* Initialize sub key list from key @k and return
1084     the new listview control. */
1085 werner 36 listview_ctrl_t
1086 twoaday 165 subkey_list_init (HWND dlg, winpt_key_t k)
1087 werner 36 {
1088     LV_ITEM lvi;
1089     gpgme_key_t key;
1090     gpgme_subkey_t sub;
1091     struct listview_column_s cols[] = {
1092     {0, 80, (char *)_("Description")},
1093     {1, 78, (char *)_("Key ID")},
1094     {2, 66, (char *)_("Creation")},
1095     {3, 66, (char *)_("Expires")},
1096     {4, 64, (char *)_("Status")},
1097     {5, 16, "C"/*ertify*/},
1098     {6, 16, "S"/*ign*/},
1099     {7, 16, "E"/*ncrypt*/},
1100     {8, 16, "A"/*uth*/},
1101     {0, 0, 0}
1102     };
1103     listview_ctrl_t lv;
1104     char buf[256], tmp[128];
1105     const char *t;
1106     int nkeys = 0, rc = 0, i, bits;
1107    
1108 twoaday 200 if (get_pubkey (k->keyid, &key)) {
1109     msg_box (dlg, _("Could not find key."), _("Key Edit"), MB_ERR);
1110 werner 36 return NULL;
1111     }
1112 twoaday 133 if (!k->ctx)
1113     k->ctx = key;
1114 werner 36 nkeys = count_subkeys (key);
1115     if( !nkeys ) {
1116 twoaday 165 msg_box (dlg, _("No subkey(s) found."), _("Key Edit"), MB_ERR);
1117 werner 36 return NULL;
1118     }
1119    
1120     rc = listview_new( &lv );
1121     if( rc )
1122     BUG( dlg );
1123    
1124     lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_KEYLIST );
1125     for( i = 0; cols[i].fieldname != NULL; i++ )
1126     listview_add_column( lv, &cols[i] );
1127    
1128     for( i = 0; i < nkeys; i++ ) {
1129     listview_add_item( lv, "" );
1130     listview_add_sub_item( lv, 0, 1, "" );
1131     memset( &lvi, 0, sizeof lvi );
1132     lvi.mask = LVIF_PARAM;
1133 twoaday 165 lvi.lParam = (LPARAM)key;
1134 werner 36 if( ListView_SetItem( lv->ctrl, &lvi ) == FALSE )
1135     return NULL;
1136     }
1137    
1138     listview_set_ext_style( lv );
1139     for( i = 0, sub = key->subkeys; i < nkeys; i++, sub = sub->next ) {
1140     memset( buf, 0, sizeof buf );
1141    
1142     bits = sub->length;
1143     _snprintf( tmp, sizeof tmp-1, "%d-bit ", bits );
1144     strcat( buf, tmp );
1145    
1146     _snprintf( tmp, sizeof tmp-1, "%s", get_key_pubalgo (sub->pubkey_algo));
1147     strcat( buf, tmp );
1148    
1149     listview_add_sub_item( lv, i, 0, buf );
1150     t = sub->keyid;
1151     if( !t )
1152     t = "DEADBEEFDEADBEEF";
1153     _snprintf( tmp, sizeof tmp-1, "0x%s", t+8 );
1154     listview_add_sub_item( lv, i, 1, tmp );
1155    
1156     t = get_key_created (sub->timestamp);
1157     if( !t )
1158 werner 116 t = "????" "-??" "-??";
1159 werner 36 listview_add_sub_item( lv, i, 2, t );
1160    
1161     if( sub->expires ) {
1162     t = get_key_created (sub->expires);
1163     listview_add_sub_item( lv, i, 3, t );
1164     }
1165     else
1166     listview_add_sub_item( lv, i, 3, _("Never") );
1167    
1168     if( sub->expired )
1169     t = _("Expired");
1170     else if( sub->revoked )
1171     t = _("Revoked");
1172     else
1173     t = _("OK");
1174     listview_add_sub_item( lv, i, 4, t );
1175    
1176     if (sub->can_certify) t = "*"; else t = "";
1177     listview_add_sub_item (lv, i, 5, t);
1178     if (sub->can_sign) t = "*"; else t = "";
1179     listview_add_sub_item( lv, i, 6, t );
1180     if (sub->can_encrypt) t = "*"; else t = "";
1181     listview_add_sub_item( lv, i, 7, t );
1182     if (sub->can_authenticate) t = "*"; else t = "";
1183     listview_add_sub_item (lv, i, 8, t);
1184     }
1185     return lv;
1186 twoaday 200 }
1187 werner 36
1188    
1189     static listview_ctrl_t
1190     userid_list_init (HWND dlg, winpt_key_t k)
1191     {
1192     listview_ctrl_t lv = NULL;
1193     gpgme_key_t key;
1194     gpgme_key_sig_t ks;
1195     gpgme_user_id_t u;
1196     int nuids = 0, rc, j, u_attr;
1197     struct listview_column_s cols[] = {
1198     {0, 72, (char *)_("Validity")},
1199     {1, 150, (char *)_("Name")},
1200     {2, 110, (char *)_("Email")},
1201     {3, 76, (char *)_("Creation")},
1202     {0, 0, 0}
1203     };
1204     const char *attr;
1205    
1206 twoaday 129 if (get_pubkey (k->keyid, &key)) {
1207     msg_box (dlg, _("Could not find key."), _("Key Edit"), MB_ERR);
1208 werner 36 return NULL;
1209     }
1210    
1211     nuids = count_userids (key);
1212     if (!nuids) {
1213     msg_box (dlg, _("No user ID(s) found."), _("Key Edit"), MB_ERR);
1214     return NULL;
1215     }
1216    
1217     rc = listview_new (&lv);
1218 twoaday 129 if (rc)
1219     BUG (dlg);
1220 werner 36 lv->ctrl = GetDlgItem( dlg, IDC_KEYEDIT_UIDLIST );
1221     for( j = 0; cols[j].fieldname != NULL; j++ )
1222     listview_add_column( lv, &cols[j] );
1223    
1224     for( j = 0; j < nuids; j++ ) {
1225     listview_add_item( lv, " " );
1226     listview_add_sub_item( lv, 0, 1, " " );
1227     }
1228    
1229     listview_set_ext_style (lv);
1230     for (j = 0, u=key->uids; j < nuids; u=u->next, j++) {
1231     if (u->revoked)
1232     attr = _("Revoked");
1233     else {
1234     u_attr = (int)u->validity;
1235     attr = get_key_trust2 (NULL, u_attr, 0, 0);
1236     }
1237     listview_add_sub_item( lv, j, 0, (char *)attr );
1238    
1239     /* XXX: add comment if available */
1240     attr = u->name;
1241     if (attr) {
1242 twoaday 187 char *uid = utf8_to_native (attr);
1243 werner 36 if (uid) {
1244 twoaday 160 listview_add_sub_item (lv, j, 1, uid);
1245     free (uid);
1246 werner 36 }
1247     }
1248     else
1249 twoaday 160 listview_add_sub_item (lv, j, 1, _("Invalid user ID"));
1250 werner 36 attr = u->email;
1251     if (attr)
1252     listview_add_sub_item (lv, j, 2, attr);
1253    
1254 twoaday 129 ks = get_selfsig (u, k->keyid, 1);
1255 werner 36 if (ks)
1256     listview_add_sub_item (lv, j, 3, get_key_created (ks->timestamp));
1257     }
1258     if( !k->key_pair ) {
1259     CheckDlgButton( dlg, IDC_KEYUID_ADD, BST_INDETERMINATE );
1260     CheckDlgButton( dlg, IDC_KEYUID_REVOKE, BST_INDETERMINATE );
1261     }
1262     return lv;
1263 twoaday 200 }
1264 werner 36
1265    
1266     static void
1267 twoaday 170 do_init_cmdlist (HWND dlg, int is_keypair)
1268     {
1269     const char *s;
1270 werner 36 int i = 0;
1271    
1272 twoaday 170 for (i = 0; (s=cmdlist[i].name); i++) {
1273     if (is_keypair)
1274     SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1275     (LPARAM)(char *)s);
1276     else if (!cmdlist[i].need_pair)
1277     SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_ADDSTRING, 0,
1278     (LPARAM)(char *)s);
1279 werner 36 }
1280 twoaday 170 SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_SETCURSEL, 0, 0);
1281     }
1282 werner 36
1283    
1284 twoaday 165 /* Return 1 if the requested command is RFC2440. */
1285 werner 36 static int
1286 twoaday 165 is_cmd_openpgp (int cmdid)
1287 werner 36 {
1288 twoaday 165 switch (cmdid) {
1289 werner 36 case CMD_ADDKEY:
1290     case CMD_ADDPHOTO:
1291     case CMD_ADDREVOKER:
1292 twoaday 170 //case CMD_SETPREF:
1293 werner 36 return 1;
1294     }
1295     return 0;
1296 twoaday 165 }
1297 werner 36
1298    
1299 twoaday 165 /* Display a message box with a short description of the commands. */
1300 werner 36 static void
1301 twoaday 165 do_show_help (HWND dlg)
1302 werner 36 {
1303     char helptext[2048];
1304    
1305 twoaday 165 _snprintf (helptext, sizeof (helptext)-1,
1306 twoaday 170 _(
1307 werner 36 "ADDUID \t\tadd a user ID\r\n"
1308     "ADDPHOTO \t\tadd a photo ID\r\n"
1309     "DELUID \t\tdelete a user ID\r\n"
1310     "ADDKEY \t\tadd a secondard key\r\n"
1311     "DELKEY \t\tdelete a secondary key\r\n"
1312     "ADDREVOKER\t\tadd a revocation key\r\n"
1313     "EXPIRE \t\tchange the expire date\r\n"
1314     "SHOWPREF \t\tlist preferences (verbose)\r\n"
1315 twoaday 170 "SETPREF \t\tset preference list\r\n"
1316 werner 36 "UPDPREF \t\tupdated preferences\r\n"
1317     "PASSWD \t\tchange the passphrase\r\n"
1318     "PRIMARY \t\tflag user ID as primary\r\n"
1319     "TRUST \t\tchange the ownertrust\r\n"
1320     "REVUID \t\trevoke a user ID\r\n"
1321     "REVKEY \t\trevoke a secondary key\r\n"
1322     "DISABLE \t\tdisable a key\r\n"
1323     "ENABLE \t\tenable a key\r\n"
1324 twoaday 170 "SIGN \t\tsign a user-id (exportable)\r\n"
1325 twoaday 195 "LSIGN \t\tsign a user-id (non-exportable)\r\n"
1326     "CLEAN \t\tremove unusable signatures from key\r\n"
1327     ));
1328 twoaday 165 msg_box (dlg, helptext, _("Key Edit Help"), MB_OK);
1329     }
1330 werner 36
1331    
1332     static int
1333     do_editkey_delkey (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1334     {
1335     gpgme_error_t err;
1336     GpgKeyEdit *ke;
1337     int j, id;
1338     char tmp[64];
1339    
1340     if (!k->key_pair)
1341     return FALSE; /* XXX: shall we allow to modify non-secret keys?? */
1342    
1343     if( listview_count_items( lv, 0 ) == 1 ) {
1344     msg_box( dlg, _("Primary key can not be deleted!"), _("Key Edit"), MB_ERR);
1345     return FALSE;
1346     }
1347     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1348     msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1349     return FALSE;
1350     }
1351     if( j == 0 ) {
1352     msg_box( dlg, _("Primary subkey can not be deleted!"), _("Key Edit"), MB_ERR );
1353     return FALSE;
1354     }
1355    
1356 twoaday 200 /* XXX: change the warning to make clear that verification won't work
1357     any longer if this is a sign-only key. */
1358     listview_get_item_text (lv, j, 0, tmp, sizeof (tmp) -1);
1359     id = log_box (_("Key Edit"), MB_YESNO|MB_ICONWARNING,
1360 werner 36 _("\"Subkey %s.\"\n\n"
1361     "Anything encrypted to the selected subkey will no longer\n"
1362     "be able to be decrypted.\n\n"
1363 twoaday 200 "Do you really want to delete this subkey?"), tmp);
1364     if (id == IDNO)
1365 werner 36 return FALSE;
1366    
1367     ke = new GpgKeyEdit (k->keyid);
1368     if (!ke)
1369     BUG (NULL);
1370     err = ke->delKey (j);
1371     if (err)
1372     msg_box (dlg, gpgme_strerror (err), _("Delete Subkey"), MB_ERR);
1373     else {
1374     listview_del_item (lv, j);
1375     k->update = 1;
1376     status_box (dlg, _("Subkey successfully deleted."), _("GnuPG status"));
1377     }
1378     delete ke;
1379     return err? FALSE : TRUE;
1380 twoaday 200 }
1381 werner 36
1382    
1383     /* Set the expiration date for the selected key in list view @lv.
1384     Return value: TRUE on success. */
1385     static int
1386     do_editkey_expire (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1387     {
1388     gpgme_error_t err;
1389     GpgKeyEdit *ke;
1390     date_s udd = {0};
1391     char buf[256], * pass = NULL;
1392     int j, cancel = 0;
1393    
1394     if (!k->key_pair) {
1395 twoaday 41 msg_box (dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR);
1396 werner 36 return FALSE;
1397     }
1398 twoaday 41 if ((j = listview_get_curr_pos (lv)) == -1) {
1399 werner 36 msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1400     return FALSE;
1401     }
1402 twoaday 41
1403     /* If a key already expired, it is possible the user wants to
1404     set a new expiration date.. */
1405     listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, sizeof buf -1);
1406     if (!strcmp (buf, _("Expired"))) {
1407     cancel = msg_box (dlg, _("Key already expired.\n\n"
1408     "Do you want to change the expiration date?"),
1409     _("Key Edit"), MB_QUEST_ASK);
1410     if (cancel == IDNO)
1411     return FALSE;
1412     cancel = 0;
1413 werner 36 }
1414 twoaday 41
1415 werner 36 memset (&udd, 0, sizeof udd);
1416     udd.text = _("Key Expiration Date");
1417     dialog_box_param (glob_hinst, (LPCSTR)IDD_WINPT_DATE, dlg,
1418     date_dlg_proc, (LPARAM)&udd,
1419     _("Key Expiration Date"), IDS_WINPT_DATE);
1420     if (udd.cancel == 1)
1421     return FALSE;
1422     if (!keygen_check_date (&udd.st)) {
1423     msg_box (dlg, _("The date you have chosen lies in the past."),
1424     _("Key Edit"), MB_ERR);
1425     return FALSE;
1426     }
1427     if( k->is_protected ) {
1428 twoaday 41 pass = request_passphrase (_("Key Edit"), 1, &cancel);
1429     if (cancel)
1430 werner 36 return FALSE;
1431     }
1432    
1433     ke = new GpgKeyEdit (k->keyid);
1434     if (!ke)
1435     BUG (NULL);
1436     if (k->is_protected)
1437     ke->setPassphrase (pass);
1438 twoaday 176 else
1439     ke->setNoPassphrase (true);
1440 twoaday 175 err = ke->setKeyExpireDate (j, w32_mktime (&udd.st), false);
1441 werner 36 if (err)
1442     msg_box (dlg, gpgme_strerror (err), _("Expire Subkey"), MB_ERR);
1443     else {
1444     _snprintf (buf, sizeof buf - 1, "%04d-%02d-%02d",
1445     udd.st.wYear, udd.st.wMonth, udd.st.wDay);
1446     listview_add_sub_item (lv, j, SUBK_COL_EXPIRES, buf);
1447     k->update = 1;
1448     msg_box (dlg, _("Subkey expire date successfully set."),
1449     _("GnuPG status"), MB_OK);
1450     }
1451     sfree_if_alloc (pass);
1452     delete ke;
1453     return TRUE;
1454     }
1455    
1456    
1457     /* Revoke the selected key in the list view @lv. @k contains
1458     control information about the global key.
1459     Return value: TRUE on success. */
1460     static int
1461     do_editkey_revoke (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1462     {
1463     gpgme_error_t err;
1464     GpgKeyEdit *ke;
1465     char buf[256];
1466     char *pass = NULL;
1467     int j, cancel = 0;
1468    
1469     if (!k->key_pair) {
1470     msg_box (dlg, _("There is no secret key available!"), _("Key Edit"), MB_ERR);
1471     return FALSE;
1472     }
1473    
1474     if ((j = listview_get_curr_pos (lv)) == -1) {
1475     msg_box( dlg, _("Please select a key."), _("Key Edit"), MB_ERR );
1476     return FALSE;
1477     }
1478     else if (listview_count_items (lv, 0) == 1) {
1479     msg_box( dlg, _("No subkeys were found, if you want to revoke the\n"
1480     "whole key, please use the Key Manager command directly.\n\n"
1481     "This command is only available to revoke single subkeys"),
1482     _("Key Edit"), MB_INFO );
1483     return FALSE;
1484     }
1485    
1486     listview_get_item_text (lv, j, SUBK_COL_STATUS, buf, sizeof (buf)-1);
1487     if (!strcmp (buf, _("Revoked"))) {
1488     msg_box (dlg, _("Key already revoked."), _("Key Edit"), MB_ERR);
1489     return FALSE;
1490     }
1491    
1492     if (k->is_protected) {
1493     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1494     if (cancel)
1495     return FALSE;
1496     }
1497    
1498     ke = new GpgKeyEdit (k->keyid);
1499     if (!ke)
1500     BUG (NULL);
1501     if (k->is_protected)
1502     ke->setPassphrase (pass);
1503 twoaday 176 else
1504     ke->setNoPassphrase (true);
1505 werner 36 err = ke->revokeSubkey (j, 0, NULL);
1506     if (err)
1507     msg_box( dlg, gpgme_strerror (err), _("Revoke Subkey"), MB_ERR);
1508     else {
1509     listview_add_sub_item (lv, j, SUBK_COL_STATUS, _("Revoked"));
1510     k->update = 1;
1511     msg_box( dlg, _("Subkey successfully revoked."), _("GnuPG Status"), MB_OK );
1512     }
1513     sfree_if_alloc (pass);
1514     delete ke;
1515     return TRUE;
1516     }
1517    
1518    
1519     /* Revoked the selected userid in list view @lv.
1520     Return value: TRUE on success. */
1521     int
1522     do_editkey_revuid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1523     {
1524     gpgme_error_t err;
1525     GpgKeyEdit *ke;
1526 twoaday 160 char buf[128], email[128];
1527     char inf[512];
1528     char *pass = NULL;
1529 werner 36 int cancel = 0, id = 0, j;
1530    
1531     if (!k->key_pair) {
1532 twoaday 160 msg_box (dlg, _("There is no secret key available!"),
1533     _("Revoke user ID"), MB_ERR);
1534 werner 36 return FALSE;
1535     }
1536    
1537 twoaday 160 if (listview_count_items (lv, 0) == 1) {
1538     msg_box (dlg, _("Key has only one user ID."), _("Key Edit"), MB_ERR);
1539 werner 36 return FALSE;
1540     }
1541    
1542     if( (j = listview_get_curr_pos( lv )) == -1 ) {
1543     msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1544     return FALSE;
1545     }
1546    
1547 twoaday 160 listview_get_item_text( lv, j, UID_COL_VALID, buf, sizeof buf - 1);
1548     if (strstr (buf, _("Revoked"))) {
1549     msg_box (dlg, _("This user ID has been already revoked."),
1550     _("Key Edit"), MB_INFO);
1551 werner 36 return FALSE;
1552     }
1553    
1554 twoaday 160 listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof buf -1);
1555     _snprintf (inf, sizeof (inf) -1, _("user ID \"%s\".\n\n"
1556     "Do you really want to revoke this user ID?"), buf);
1557     if (msg_box (dlg, inf, _("Key Edit"), MB_WARN_ASK) == IDNO)
1558 werner 36 return FALSE;
1559 twoaday 160 if (k->is_protected) {
1560 werner 36 pass = request_passphrase (_("Key Edit"), 1, &cancel);
1561 twoaday 68 if (cancel)
1562 werner 36 return FALSE;
1563     }
1564 twoaday 160 listview_get_item_text (lv, j, UID_COL_EMAIL, email, sizeof (email)-1);
1565     listview_get_item_text (lv, j, UID_COL_NAME, buf, sizeof (buf)-1);
1566     id = do_find_userid (k->keyid, email, buf, NULL);
1567 werner 36 if (id == -1)
1568     BUG (NULL);
1569    
1570     ke = new GpgKeyEdit (k->keyid);
1571     if (!ke)
1572     BUG (NULL);
1573     if (k->is_protected)
1574     ke->setPassphrase (pass);
1575 twoaday 176 else
1576     ke->setNoPassphrase (true);
1577 werner 36 err = ke->revokeUserid (id);
1578     if (err)
1579 twoaday 160 msg_box (dlg, gpgme_strerror (err), _("Revoke User ID"), MB_ERR);
1580 werner 36 else {
1581     listview_add_sub_item (lv, j, 0, _("Revoked"));
1582     k->update = 1;
1583     status_box (dlg, _("User ID successfully revoked"), _("GnuPG Status"));
1584     }
1585     sfree_if_alloc (pass);
1586     delete ke;
1587     return err? FALSE : TRUE;
1588     }
1589    
1590    
1591     static int
1592     do_editkey_setpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1593     {
1594     gpgme_error_t rc;
1595     GpgKeyEdit *ke;
1596     char buf[256], * pass = NULL, * prefs;
1597     int j, id, cancel=0, flags=0;
1598    
1599     if ((j = listview_get_curr_pos (lv)) == -1) {
1600     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1601     return FALSE;
1602     }
1603     listview_get_item_text (lv, j, 2, buf, sizeof buf-1);
1604 twoaday 160 id = do_find_userid (k->keyid, buf, NULL, NULL);
1605 werner 36 if (id == -1)
1606     BUG (dlg);
1607     if (k->is_protected) {
1608     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1609     if (cancel)
1610     return FALSE;
1611     }
1612    
1613     ke = new GpgKeyEdit (k->keyid);
1614     if (!ke)
1615     BUG (NULL);
1616     if (k->is_protected)
1617     ke->setPassphrase (pass);
1618 twoaday 176 else
1619     ke->setNoPassphrase (true);
1620 werner 36
1621     get_userid_preflist (&prefs, &flags);
1622    
1623     rc = ke->setUseridPreferences (id, prefs);
1624 twoaday 176 if (rc)
1625     msg_box (dlg, _("Could not set user ID preferences"), _("Key Edit"), MB_ERR);
1626 werner 36
1627     sfree_if_alloc (pass);
1628     free_if_alloc (prefs);
1629     delete ke;
1630     return 0;
1631     }
1632    
1633    
1634     static int
1635     do_editkey_primary (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1636     {
1637     gpgme_error_t err;
1638     GpgKeyEdit *ke;
1639     int j, id, cancel=0;
1640 twoaday 197 char buf[256], *pass = NULL;
1641 werner 36
1642     if (listview_count_items (lv, 0) == 1)
1643     return TRUE;
1644     if ((j = listview_get_curr_pos (lv)) == -1) {
1645     msg_box( dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR );
1646     return FALSE;
1647     }
1648     listview_get_item_text (lv, j, 2, buf, sizeof buf-1);
1649 twoaday 160 id = do_find_userid (k->keyid, buf, NULL, NULL);
1650 werner 36 if (id == -1)
1651 twoaday 197 BUG (0);
1652 werner 36 if (k->is_protected) {
1653     pass = request_passphrase (_("Key Edit"), 1, &cancel);
1654 twoaday 128 if (cancel)
1655 werner 36 return FALSE;
1656     }
1657    
1658     ke = new GpgKeyEdit (k->keyid);
1659     if (k->is_protected)
1660     ke->setPassphrase (pass);
1661 twoaday 176 else
1662     ke->setNoPassphrase (true);
1663 werner 36 err = ke->setPrimaryUserid (id);
1664     if (err)
1665     msg_box (dlg, gpgme_strerror (err), _("Primary"), MB_ERR);
1666     else {
1667     k->update = 1;
1668     status_box (dlg, _("User ID successfully flagged"), _("GnuPG Status"));
1669     }
1670    
1671     sfree_if_alloc (pass);
1672     delete ke;
1673     return err? FALSE : TRUE;
1674     }
1675    
1676    
1677 twoaday 123
1678 twoaday 128 #define CIPHER 11
1679     #define HASH 11
1680     #define COMPR 4
1681    
1682 werner 36 static int
1683     parse_preflist (HWND dlg, const char *list)
1684     {
1685 twoaday 123 char buf[128] = {0};
1686     char *p, *pbuf = buf;
1687     const char *ciphers[CIPHER] = {"", "IDEA", "3DES",
1688 twoaday 128 "CAST5", "BLOWFISH", "", "",
1689     "AES", "AES192", "AES256", "TWOFISH"};
1690     const char *hash[HASH] = {"", "MD5", "SHA1", "RMD160", "",
1691     "", "", "", "SHA256", "SHA384", "SHA512"};
1692 twoaday 123 const char *compress[COMPR] = {"", "ZIP", "ZLIB", "BZIP2"};
1693 werner 36 int n=0;
1694    
1695     strncpy (buf, list, 127);
1696     p = strtok (pbuf, " ");
1697     while (p != NULL) {
1698     int algid = atol (p+1);
1699     n++;
1700     switch (*p) {
1701     case 'S':
1702 twoaday 123 SendDlgItemMessage (dlg, IDC_SHOWPREF_CIPHERS, LB_ADDSTRING, 0,
1703     (LPARAM)(const char*)ciphers[algid % CIPHER]);
1704 werner 36 break;
1705    
1706     case 'H':
1707 twoaday 123 SendDlgItemMessage (dlg, IDC_SHOWPREF_HASH, LB_ADDSTRING, 0,
1708     (LPARAM)(const char*)hash[algid % HASH]);
1709 werner 36 break;
1710    
1711     case 'Z':
1712 twoaday 123 SendDlgItemMessage (dlg, IDC_SHOWPREF_ZIP, LB_ADDSTRING, 0,
1713     (LPARAM)(const char*)compress[algid % COMPR]);
1714 werner 36 break;
1715    
1716     default:
1717     n--;
1718     }
1719     p = strtok (NULL, " ");
1720     }
1721     return n;
1722     }
1723    
1724    
1725     /* Dialog box procedure to show the key preferences. */
1726     BOOL CALLBACK
1727     showpref_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1728     {
1729 twoaday 176 static keyedit_cb_t cb = NULL;
1730 werner 36 gpg_uid_info_t inf=NULL;
1731 twoaday 200 gpgme_key_t key;
1732 werner 36 char buf[128];
1733     int pos;
1734    
1735     switch (msg) {
1736     case WM_INITDIALOG:
1737 twoaday 176 cb = (keyedit_cb_t)lparam;
1738 twoaday 200 if (!cb)
1739     BUG (NULL);
1740     key = (gpgme_key_t)cb->opaque;
1741     _snprintf (buf, sizeof (buf)-1, "%s <%s>",
1742     key->uids->name, key->uids->email);
1743 werner 36 SetDlgItemText (dlg, IDC_SHOWPREF_INFO, buf);
1744 twoaday 200 pos = do_find_userid (cb->keyid, key->uids->email, NULL, &inf);
1745 werner 36 if (inf) {
1746     const char *prefs = inf->prefs;
1747     if (prefs && *prefs) {
1748     if (parse_preflist (dlg, prefs) <= 0)
1749     pos = -1;
1750     }
1751     else
1752     pos = -1;
1753     gpg_uid_info_release (inf);
1754     if (pos == -1) {
1755     msg_box (dlg, _("No preferences available."), _("Key Edit"), MB_ERR);
1756     EndDialog (dlg, TRUE);
1757     }
1758     if (inf->flags.mdc)
1759     CheckDlgButton (dlg, IDC_SHOWPREF_MDC, BST_CHECKED);
1760     }
1761 twoaday 128 SetDlgItemText (dlg, IDC_SHOWPREF_MDC, _("MDC feature"));
1762     SetDlgItemText (dlg, IDC_SHOWPREF_PREFINF, _("Preferences"));
1763 twoaday 200 SetDlgItemText (dlg, IDC_SHOWPREF_UIDHINT, _("user ID:"));
1764 werner 36 SetWindowText (dlg, _("Key Preferences"));
1765     SetForegroundWindow (dlg);
1766     break;
1767    
1768     case WM_COMMAND:
1769     switch (LOWORD (wparam)) {
1770     case IDOK:
1771     EndDialog (dlg, TRUE);
1772     break;
1773     }
1774     break;
1775     }
1776     return FALSE;
1777     }
1778    
1779    
1780     static int
1781     do_editkey_showpref (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1782     {
1783 twoaday 176 struct keyedit_cb_s cb;
1784 werner 36
1785     if (k->is_v3)
1786     return TRUE;
1787    
1788     if (listview_get_curr_pos (lv) == -1) {
1789     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1790     return FALSE;
1791     }
1792    
1793     memset (&cb, 0, sizeof (cb));
1794 twoaday 200 cb.opaque = k->ctx;
1795     cb.keyid = k->keyid;
1796 werner 36 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYEDIT_SHOWPREF, dlg,
1797     showpref_dlg_proc, (LPARAM)&cb);
1798     return TRUE;
1799     }
1800    
1801    
1802     static int
1803     do_editkey_deluid (winpt_key_t k, HWND dlg, listview_ctrl_t lv)
1804     {
1805     gpgme_error_t err;
1806     GpgKeyEdit *ke;
1807 twoaday 160 char email[128], name[128];
1808     char inf[384];
1809 werner 36 int j, id = 0;
1810    
1811     if (!k->key_pair)
1812     return FALSE; /* XXX: see do_editkey_delsubkey */
1813    
1814 twoaday 160 if (listview_count_items (lv, 0) == 1) {
1815     msg_box (dlg, _("Primary user ID can not be deleted!"),
1816     _("Key Edit"), MB_ERR);
1817 werner 36 return FALSE;
1818     }
1819 twoaday 160 if ((j = listview_get_curr_pos (lv)) == -1) {
1820     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1821 werner 36 return FALSE;
1822     }
1823    
1824     /* XXX: add a hint that also all signatures will be deleted? */
1825 twoaday 160 listview_get_item_text (lv, j, UID_COL_NAME, name, DIM(name) -1);
1826     _snprintf (inf, DIM (inf)-1, _("user ID \"%s\".\n\n"
1827 twoaday 193 "All signatures on this user ID will be also deleted."
1828     "\n\n"
1829 twoaday 160 "Do you really want to delete this user ID?"),
1830     name);
1831     if (msg_box (dlg, inf, _("Key Edit"), MB_YESNO|MB_ICONWARNING) == IDNO)
1832 werner 36 return FALSE;
1833    
1834 twoaday 160 listview_get_item_text (lv, j, UID_COL_EMAIL, email, DIM (email)-1);
1835     listview_get_item_text (lv, j, UID_COL_NAME, name, DIM (name)-1);
1836     id = do_find_userid (k->keyid, email, name, NULL);
1837 werner 36 if (id == -1)
1838     BUG (dlg);
1839    
1840     ke = new GpgKeyEdit (k->keyid);
1841     if (!ke)
1842     BUG (NULL);
1843    
1844     err = ke->delUserid (id);
1845 twoaday 160 if (err)
1846     msg_box (dlg, gpgme_strerror (err), _("Delete user ID"), MB_ERR);
1847 werner 36 else {
1848 twoaday 160 listview_del_item (lv, j);
1849 werner 36 k->update = 1;
1850 twoaday 160 status_box (dlg, _("User ID successfully deleted"), _("GnuPG Status"));
1851 werner 36 }
1852     delete ke;
1853     return err? FALSE : TRUE;
1854 twoaday 193 }
1855 werner 36
1856    
1857 twoaday 193 /* Subclass routine for the subkey listview control to allow shortcuts. */
1858 werner 36 static BOOL CALLBACK
1859 twoaday 193 subkey_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1860 werner 36 {
1861 twoaday 193 int virt_key = 0;
1862     winpt_key_t key;
1863    
1864     switch (msg) {
1865 werner 36 case WM_KEYUP:
1866 twoaday 193 virt_key = (int)wparam;
1867     key = (winpt_key_t)keyedit_subkey_proc.opaque;
1868     if (!key || !key->key_pair)
1869     break;
1870    
1871     switch (virt_key) {
1872 werner 36 case VK_DELETE:
1873 twoaday 193 SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1874     CB_SETCURSEL, CMD_DELKEY, 0);
1875     send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1876 werner 36 break;
1877    
1878     case VK_INSERT:
1879 twoaday 200 SendDlgItemMessage (keyedit_subkey_proc.dlg, IDC_KEYEDIT_CMD,
1880     CB_SETCURSEL, CMD_ADDKEY, 0);
1881     send_cmd_id (keyedit_subkey_proc.dlg, IDOK);
1882 werner 36 break;
1883     }
1884     }
1885 twoaday 193 return CallWindowProc (keyedit_subkey_proc.old, dlg, msg, wparam, lparam);
1886     }
1887 werner 36
1888    
1889     static BOOL CALLBACK
1890     uid_subclass_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
1891     {
1892 twoaday 193 int virt_key = 0;
1893     winpt_key_t key;
1894    
1895     switch (msg) {
1896 werner 36 case WM_KEYUP:
1897 twoaday 193 virt_key = (int)wparam;
1898     key = (winpt_key_t)keyedit_uid_proc.opaque;
1899     if (!key || !key->key_pair)
1900     break;
1901    
1902 werner 36 switch (virt_key) {
1903     case VK_DELETE:
1904     SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1905     CB_SETCURSEL, CMD_DELUID, 0);
1906     send_cmd_id (keyedit_uid_proc.dlg, IDOK);
1907     break;
1908    
1909     case VK_INSERT:
1910     SendDlgItemMessage (keyedit_uid_proc.dlg, IDC_KEYEDIT_CMD,
1911     CB_SETCURSEL, CMD_ADDUID, 0);
1912     send_cmd_id (keyedit_uid_proc.dlg, IDOK);
1913     break;
1914     }
1915     }
1916 twoaday 193 return CallWindowProc (keyedit_uid_proc.old, dlg, msg, wparam, lparam);
1917     }
1918 werner 36
1919    
1920 twoaday 193 /* Enable the key @k when @enable is 1, disable it otherwise. */
1921 twoaday 165 static void
1922 twoaday 193 do_editkey_enable_disable (winpt_key_t k, HWND dlg,
1923     listview_ctrl_t lv, int enable)
1924 twoaday 165 {
1925     km_enable_disable_key (lv, dlg, 0, enable);
1926     k->update = 1;
1927     }
1928    
1929    
1930 twoaday 170 /* Return default secret key. */
1931     static gpgme_key_t
1932     get_default_key (void)
1933     {
1934     gpgme_key_t def_sk;
1935     char *keyid = get_gnupg_default_key ();
1936    
1937     get_seckey (keyid, &def_sk);
1938     free_if_alloc (keyid);
1939     return def_sk;
1940     }
1941    
1942    
1943 twoaday 195
1944     static void
1945     do_editkey_clean (winpt_key_t k, HWND dlg)
1946     {
1947     gpgme_error_t err;
1948     GpgKeyEdit *ke;
1949    
1950 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
1951 twoaday 195 err = ke->cleanKey ();
1952     if (err)
1953 twoaday 197 msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
1954     else {
1955 twoaday 195 msg_box (dlg, _("Finished to compact key."), _("Key Edit"), MB_OK);
1956 twoaday 197 k->update = 1;
1957     }
1958 twoaday 195 delete ke;
1959     }
1960    
1961    
1962 twoaday 193 /* Start the dialog to list and display the status of all
1963     signatures for this key. */
1964 twoaday 175 static void
1965     do_editkey_check (winpt_key_t k, HWND dlg)
1966     {
1967 twoaday 176 if (!k->ctx)
1968     get_pubkey (k->keyid, &k->ctx);
1969     if (!k->uid && k->ctx)
1970     k->uid = k->ctx->uids->uid;
1971 twoaday 175 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_KEYSIG_TREE, dlg,
1972 twoaday 176 sigtree_dlg_proc, (LPARAM)k);
1973 twoaday 175 }
1974    
1975    
1976 twoaday 170 static int
1977     do_editkey_sign_userid (winpt_key_t k, HWND dlg, listview_ctrl_t lv, int mode)
1978     {
1979     gpgme_error_t err;
1980     GpgKeyEdit *ke;
1981     char *pass = NULL;
1982     char email[64], name[128];
1983     int uid_index;
1984     int cancel = 0;
1985    
1986     uid_index = listview_get_curr_pos (lv);
1987     if (uid_index == -1) {
1988     msg_box (dlg, _("Please select a user ID."), _("Key Edit"), MB_ERR);
1989     return FALSE;
1990     }
1991     if (mode == CMD_SIGN) {
1992     cancel = msg_box (dlg, _("Do you really want to make this sig exportable?"),
1993     _("Key Edit"), MB_QUEST_ASK);
1994     if (cancel == IDNO)
1995     return FALSE;
1996     }
1997    
1998     listview_get_item_text (lv, uid_index, UID_COL_EMAIL, email, sizeof (email)-1);
1999     listview_get_item_text (lv, uid_index, UID_COL_NAME, name, sizeof (name)-1);
2000     uid_index = do_find_userid (k->keyid, email, name, NULL);
2001     if (k->is_protected) {
2002     pass = request_passphrase (_("Key Edit"), 1, &cancel);
2003     if (cancel)
2004     return FALSE;
2005     }
2006 twoaday 200 ke = create_GpgKeyEdit (k->keyid);
2007 twoaday 175 if (k->is_protected)
2008     ke->setPassphrase (pass);
2009 twoaday 176 else
2010     ke->setNoPassphrase (true);
2011 twoaday 170 ke->setLocalUser (get_default_key ());
2012     err = ke->signUserid (uid_index,
2013     mode == CMD_SIGN? GPG_EDITKEY_SIGN : GPG_EDITKEY_LSIGN,
2014     0, NULL);
2015     if (!err) {
2016     msg_box (dlg, _("Key successfully signed."), _("Key Edit"), MB_OK);
2017     k->update = 1;
2018     }
2019     else
2020     msg_box (dlg, gpgme_strerror (err), _("Key Edit"), MB_ERR);
2021     delete ke;
2022     sfree_if_alloc (pass);
2023     return !err? TRUE : FALSE;
2024     }
2025    
2026    
2027     static int
2028     lookup_cmd (HWND dlg)
2029     {
2030     char buf[64];
2031     int i;
2032    
2033     i = SendDlgItemMessage (dlg, IDC_KEYEDIT_CMD, CB_GETCURSEL, 0, 0);
2034     if (i == LB_ERR)
2035     return LB_ERR;
2036     GetDlgItemText (dlg, IDC_KEYEDIT_CMD, buf, sizeof (buf)-1);
2037     for (i=0; cmdlist[i].name != NULL; i++) {
2038     if (!strcmp (buf, cmdlist[i].name))
2039     return cmdlist[i].id;
2040     }
2041     return LB_ERR;
2042     }
2043    
2044 twoaday 193
2045 twoaday 133 /* Dialog box procedure for the edit key dialog. */
2046 werner 36 BOOL CALLBACK
2047     keyedit_main_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
2048     {
2049     static winpt_key_t k;
2050     static listview_ctrl_t lvsub = NULL, lvuid = NULL;
2051 twoaday 165 int cmd;
2052 werner 36 HWND item;
2053    
2054 twoaday 193 switch (msg) {
2055 werner 36 case WM_INITDIALOG:
2056     k = (winpt_key_t)lparam;
2057     if (!k)
2058     BUG (NULL);
2059 twoaday 170 do_init_cmdlist (dlg, k->key_pair);
2060 werner 36 lvsub = subkey_list_init (dlg, k);
2061 twoaday 193 if (!lvsub)
2062     BUG (0);
2063 werner 36 lvuid = userid_list_init (dlg, k);
2064 twoaday 193 if (!lvuid)
2065     BUG (0);
2066     item = GetDlgItem (dlg, IDC_KEYEDIT_KEYLIST);
2067     keyedit_subkey_proc.opaque = (void*)k;
2068 werner 36 keyedit_subkey_proc.dlg = dlg;
2069     keyedit_subkey_proc.current = (WNDPROC)subkey_subclass_proc;
2070 twoaday 193 keyedit_subkey_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2071     if (keyedit_subkey_proc.old) {
2072     if( !SetWindowLong (item, GWL_WNDPROC,
2073     (LONG)keyedit_subkey_proc.current)) {
2074     msg_box (dlg, _("Could not set subkey window procedure."),
2075     _("Key Edit"), MB_ERR);
2076     BUG (0);
2077 werner 36 }
2078     }
2079 twoaday 193 item = GetDlgItem (dlg, IDC_KEYEDIT_UIDLIST);
2080     keyedit_uid_proc.opaque = (void*)k;
2081 werner 36 keyedit_uid_proc.dlg = dlg;
2082     keyedit_uid_proc.current = (WNDPROC)uid_subclass_proc;
2083 twoaday 193 keyedit_uid_proc.old = (WNDPROC)GetWindowLong (item, GWL_WNDPROC);
2084     if (keyedit_uid_proc.old) {
2085     if (!SetWindowLong (item, GWL_WNDPROC,
2086     (LONG)keyedit_uid_proc.current)) {
2087     msg_box (dlg, _("Could not set user ID window procedure."),
2088     _("Key Edit"), MB_ERR);
2089     BUG (0);
2090 werner 36 }
2091     }
2092 twoaday 170 if (k->ctx->revoked) {
2093 werner 36 EnableWindow (GetDlgItem (dlg, IDC_KEYEDIT_CMD), FALSE);
2094     EnableWindow (GetDlgItem (dlg, IDOK), FALSE);
2095     }
2096     SetDlgItemText (dlg, IDC_KEYEDIT_CMDINF, _("Command>"));
2097 twoaday 117 SetDlgItemText (dlg, IDCANCEL, _("&Close"));
2098 twoaday 88 SetDlgItemText (dlg, IDC_KEYEDIT_HELP, _("&Help"));
2099     SetWindowText (dlg, _("Key Edit"));
2100 twoaday 170 SetForegroundWindow (dlg);
2101     center_window (dlg, NULL);
2102 werner 36 return TRUE;
2103    
2104     case WM_DESTROY:
2105 twoaday 193 if (lvsub) {
2106     listview_release (lvsub);
2107 werner 36 lvsub = NULL;
2108     }
2109 twoaday 193 if (lvuid) {
2110     listview_release (lvuid);
2111 werner 36 lvuid = NULL;
2112     }
2113     break;
2114    
2115     case WM_NOTIFY:
2116     NMHDR * notify;
2117     notify = (NMHDR *)lparam;
2118     if (notify && notify->code == NM_DBLCLK &&
2119     notify->idFrom == IDC_KEYEDIT_UIDLIST)
2120     do_editkey_showpref (k, dlg, lvuid);
2121     break;
2122    
2123     case WM_COMMAND:
2124     switch( LOWORD( wparam ) ) {
2125     case IDOK:
2126 twoaday 170 cmd = lookup_cmd (dlg);
2127 werner 36 if (cmd == LB_ERR) {
2128     msg_box( dlg, _("Please select a command."), _("Key Edit"), MB_INFO );
2129     return FALSE;
2130     }
2131     if (k->is_v3 && is_cmd_openpgp (cmd)) {
2132     msg_box (dlg, _("This command cannot be used with PGP 2 (v3) keys.\n"),
2133     _("Key Edit"), MB_ERR);
2134     return FALSE;
2135     }
2136     switch (cmd) {
2137     case CMD_SHOWPREF: do_editkey_showpref (k, dlg, lvuid); break;
2138     case CMD_DELKEY: do_editkey_delkey (k, dlg, lvsub); break;
2139     case CMD_ADDKEY: keyedit_add_subkey (k, dlg, lvsub); break;
2140     case CMD_EXPIRE: do_editkey_expire (k, dlg, lvsub); break;
2141     case CMD_REVKEY: do_editkey_revoke (k, dlg, lvsub); break;
2142     /*case CMD_SETPREF:do_editkey_setpref( k, dlg, lvuid ); break;*/
2143     case CMD_ADDUID: keyedit_add_userid( k, dlg, lvuid ); break;
2144     case CMD_ADDREVOKER: keyedit_add_revoker( k, dlg ); break;
2145     case CMD_ADDPHOTO: keyedit_add_photo( k, dlg ); break;
2146     case CMD_REVUID: do_editkey_revuid( k, dlg, lvuid ); break;
2147     case CMD_DELUID: do_editkey_deluid( k, dlg, lvuid ); break;
2148     case CMD_PASSWD: keyedit_change_passwd( k, dlg ); break;
2149     case CMD_PRIMARY: do_editkey_primary( k, dlg, lvuid ); break;
2150 twoaday 165 case CMD_ENABLE: do_editkey_enable_disable (k, dlg, lvsub, 1); break;
2151     case CMD_DISABLE: do_editkey_enable_disable (k, dlg, lvsub, 0); break;
2152 twoaday 175 case CMD_CHECK: do_editkey_check (k, dlg); break;
2153 twoaday 165 case CMD_TRUST: keyedit_change_ownertrust (k, dlg); break;
2154 twoaday 170 case CMD_SIGN:
2155     case CMD_LSIGN: do_editkey_sign_userid (k, dlg,
2156     lvuid, cmd);
2157     break;
2158 twoaday 195 case CMD_CLEAN: do_editkey_clean (k, dlg);
2159 werner 36 }
2160     break;
2161    
2162     case IDCANCEL:
2163     EndDialog (dlg, FALSE);
2164     break;
2165    
2166     case IDC_KEYEDIT_HELP:
2167     do_show_help (dlg);
2168     break;
2169     }
2170     break;
2171     }
2172     return FALSE;
2173 twoaday 133 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26