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

Contents of /trunk/Src/wptKeyEditDlgs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File size: 48365 byte(s)
WinPT initial checkin.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26