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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 200 - (hide annotations)
Mon Apr 17 09:12:50 2006 UTC (18 years, 10 months ago) by twoaday
File size: 57398 byte(s)
2006-04-16  Timo Schulz  <ts@g10code.de>
 
        * wptHTTP.cpp (getErrorCode): New.
        (connect): Store winsock error code.
        * wptGPGMEData.cpp (is_armor_header): New.
        * wptGPG.cpp (check_gnupg_engine): Free context.
        (gnupg_backup_keyrings): Do not use global vars.
        * wptGPGUtil.cpp (gpg_export_seckey): Export in ascii format.
         
2006-04-15  Timo Schulz  <ts@g10code.de>
 
        * wptKeyManager.cpp (km_get_key): New.
        (km_key_show_revoc_info): New.
        * wptKeyRevokeDlg.cpp (key_revoke_dlg): Cleanups.
        (on_init_dialog): New.
        * wptKeyManagerDlg.cpp (key_manager_dlg_proc): Factour
        out some common code and use km_get_key() instead.
        * wptKeyEditDlgs.cpp (do_init_keylist): Change second
        param type. Change all callers.
        * wptKeyEdit.cpp (addNotation): New.
        * wptKeyEditCB.cpp (editkey_command_handler): Remove 'step'
        param everywhere. Change all callers.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26