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

Annotation of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 170 - (hide annotations)
Mon Jan 30 12:42:57 2006 UTC (19 years, 1 month ago) by twoaday
File size: 54266 byte(s)
2006-01-29  Timo Schulz  <ts@g10code.de>
 
        * wptKeyPropsDlg.cpp (keyprops_dlg_proc): Allow to use ESC
        to quit dialog.
        * wptKeysignDlg.cpp (sig_class_dlg_proc): More space for
        translations. Directly return sig class.
        (keysign_dlg_proc): Change msgbox title.
        * wptKeyEdit.cpp (signUserid): New.
        (getUseridIndex): New.
        (getKeyIndex): New.
        (getSigIndex): New.
        (clear): New.
        * wptKeyEditCB.cpp (cmd_sign_handler): Allow to select
        user-id first.
        * wptKeyEditDlgs.cpp (lookup_cmd): New.
        (do_editkey_sign_userid): New.
        (do_init_cmdlist): Differ between key pairs and public keys
        and allowed actions.
        (keyedit_change_ownertrust): Show msgbox on success.
        (get_default_key): New.
        * wptPassphraseDlg.cpp (request_passphrase): Reset @cancel.
         


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26