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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 204 - (hide annotations)
Wed Apr 26 06:37:23 2006 UTC (18 years, 10 months ago) by twoaday
File size: 57134 byte(s)
2006-04-25  Timo Schulz  <ts@g10code.de>
                                                                                
        * wptFileManagerDlg.cpp (file_manager_dlg_proc): Handle IDCANCEL.
        * wptMDSumDlg.cpp (hash_selected_files): New.
        (mdsum_dlg_proc): Cleanups.
        * wptKeysignDlg.cpp (keysign_dlg_proc): Fix segv.
                                                                                
2006-04-23  Timo Schulz  <ts@g10code.de>
                                                                                
        * wptW32API.cpp (SetDlgItemText_utf8): New.
        (SetWindowText_utf8): New.
        (GetDlgItemText_utf8): New.
        * wptListView.cpp (listview_add_sub_item): Internal
        utf8 support.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26