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

Contents of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 78 - (show annotations)
Tue Nov 15 08:54:44 2005 UTC (19 years, 3 months ago) by twoaday
File size: 49521 byte(s)
2005-11-14  Timo Schulz  <ts@g10code.com>
 
        * wptGPG.cpp (check_gnupg_engine): Fix version check.
        * wptMainProc.cpp (winpt_main_proc): Check keyring
        file permissions always and do not use interative output
        when the windows session ends.
        * wptProxySettingsDlg.cpp (proxy_settings_dlg_proc):
        Localize all strings.
        * wptPassphraseDlg.cpp (passwd_dlg_proc): Likewise.
        * wptGPGPrefsDlg.cpp (gpg_prefs_dlg): Likewise.
        * wptKeyEditDlgs.cpp (do_init_keylist): Skip all
        non-valid keys.
         


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26