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

Contents of /trunk/Src/wptCardDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 48 - (show annotations)
Mon Oct 31 21:14:11 2005 UTC (19 years, 4 months ago) by werner
File size: 23418 byte(s)
More changes.  Compiles again but there are at least gettext issues with
w32-gettext.c.  I can't get a gpg-error build with ENABLE_NLS.

1 /* wptCardDlg.cpp - Smart Card support
2 * Copyright (C) 2003, 2004, 2005 Timo Schulz
3 * Copyright (C) 2005 g10 Code GmbH
4 *
5 * This file is part of WinPT.
6 *
7 * WinPT is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * WinPT is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with WinPT; if not, write to the Free Software Foundation,
19 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <windows.h>
27 #include <commctrl.h>
28 #include <ctype.h>
29
30 #include "resource.h"
31 #include "gpgme.h"
32 #include "wptTypes.h"
33 #include "wptW32API.h"
34 #include "wptErrors.h"
35 #include "wptRegistry.h"
36 #include "wptVersion.h"
37 #include "wptCommonCtl.h"
38 #include "wptDlgs.h"
39 #include "wptGPG.h"
40 #include "wptUTF8.h"
41 #include "wptCardEdit.h"
42 #include "wptCard.h"
43 #include "wptContext.h"
44
45 int keygen_check_date (SYSTEMTIME * st);
46
47 static const char * sex[] = {"Male", "Female", "Undefined", NULL};
48 static const char * lang[] = {"Undefined", "cs", "de", "en", "es", "fr", "hu",
49 "it", "nl", "pt", "ro", "ru", "zh", "at",
50 NULL};
51
52 static pin_cb_ctx_s pincb;
53
54 struct {
55 int ctlid;
56 const char * err;
57 } attr_tab[] = {
58 {IDC_CEDIT_AID, ""},
59 {IDC_CEDIT_VENDOR, "No Vendor"},
60 {IDC_CEDIT_VERSION,"No Version"},
61 {IDC_CEDIT_SERIAL, "No Serial-No"},
62 {IDC_CEDIT_NAME, "No Name"},
63 {IDC_CEDIT_NAME2, "No Surname"},
64 {IDC_CEDIT_KEYURL, "No Key-URL"},
65 {IDC_CEDIT_LOGIN, "No Login name"},
66 {0},
67 };
68
69
70
71 /* XXX: simplify code. */
72 char*
73 get_printable_version (const char *version)
74 {
75 static char buf[16];
76 char tmp_maj[3]={0}, tmp_min[3]={0};
77
78 strncpy (tmp_maj, version, 2);
79 strncpy (tmp_min, version+2, 2);
80 sprintf (buf, "%d.%d", atoi (tmp_maj), atoi (tmp_min));
81 return buf;
82 }
83
84 /* Return all card attributes from @card. @n contains
85 the number of items which were returned. */
86 char**
87 card_get_items (gpg_card_t card, int *n)
88 {
89 char **p;
90
91 *n= 8;
92 p = (char **)calloc (*n+1, sizeof (char*));
93 if (!p)
94 BUG (0);
95 p[0] = card->aid;
96 p[1] = card->vendor;
97 p[2] = get_printable_version (card->version);
98 p[3] = card->serial;
99 p[4] = card->givenname;
100 p[5] = card->surname;
101 p[6] = card->url;
102 p[7] = card->login;
103 return p;
104 }
105
106
107 static int
108 idx_from_lang (const char * _lang)
109 {
110 const char * s;
111 int i;
112
113 if (!_lang)
114 return 0;
115 for (i=0; (s = lang[i]); i++) {
116 if (!strcmp (_lang, s ))
117 return i;
118 }
119 return 0;
120 }
121
122
123 #if 0 /* @unused@ */
124 int
125 show_card_status (void)
126 {
127 int rc = 0;
128 int cardstat;
129
130 cardstat = pcsc_get_card_status ();
131 if ((cardstat & CARD_STATE_UNAWARE) || (cardstat & CARD_STATE_UNAVAIL))
132 rc = WPTERR_NOREADER;
133 else if (cardstat & CARD_STATE_EMPTY)
134 rc = WPTERR_NOCARD;
135 if (rc) {
136 msg_box (NULL, winpt_strerror (rc), _("Card Manager"), MB_ERR);
137 return -1;
138 }
139 return 0;
140 } /* show_card_status */
141 #endif
142
143 /* Check if there is a card in the reader and analyze the
144 returned information.
145 Return value: card context or NULL on error. */
146 gpg_card_t
147 gpg_card_load (void)
148 {
149 gpgme_error_t err;
150 GpgCardEdit *ce;
151 gpg_card_t card = NULL;
152 struct card_cb_s cb = {0};
153
154 ce = new GpgCardEdit ();
155 if (!ce)
156 BUG (0);
157 memset (&cb, 0, sizeof (cb));
158 ce->setCallback (card_callback, &cb);
159 err = ce->getCardStatus (&card);
160 if (err) {
161 msg_box (NULL, gpgme_strerror (err), _("Card Manager"), MB_ERR);
162 goto leave;
163 }
164
165 if (!card->aid || strncmp (card->aid, "D276000124", 10)) {
166 msg_box (NULL, winpt_strerror (WPTERR_NOPGPCARD), "WinPT", MB_ERR);
167 gpg_card_release (card);
168 card = NULL;
169 }
170 else {
171 struct winpt_key_s key;
172 memset (&key, 0, sizeof (key));
173 winpt_get_pubkey (card->fpr[1]+32, &key);
174 if (key.ext) {
175 key.ext->card_type = strdup (card->card_type);
176 if (!key.ext->card_type)
177 BUG (NULL);
178 /* memory will be released in gpg_keycache_release (). */
179 }
180 }
181
182 leave:
183 delete ce;
184 return card;
185 }
186
187
188 /* Print human friendly fingerprint to control @id in the
189 dialog @dlg. @fpr contains the raw fingerprint. */
190 static void
191 print_fpr (HWND dlg, int id, const char * fpr)
192 {
193 char buf[128], dig[2];
194 size_t i, c;
195
196 if (!fpr)
197 strcpy (buf, _("No Fingerprint"));
198 else {
199 memset (buf, 0, sizeof (buf));
200 for( i=0, c=0; i < strlen (fpr); i++) {
201 dig[0] = fpr[i]; dig[1] = 0;
202 strcat (buf, dig);
203 if (++c == 4) {
204 strcat (buf, " ");
205 c=0;
206 }
207 }
208 }
209 SetDlgItemText (dlg, id, buf);
210 }
211
212
213 /* Fill in all card information from @card. into the corresponding
214 dialog item fields in the dialog @dlg.
215 Return value: 0 on success. */
216 static int
217 card_status (HWND dlg, gpg_card_t card)
218 {
219 static int fprbuf[] = {IDC_CEDIT_FPR1, IDC_CEDIT_FPR2, IDC_CEDIT_FPR3, 0};
220 static int fprtime[] = {IDC_CEDIT_SIG_FPRTIME, IDC_CEDIT_DEC_FPRTIME, IDC_CEDIT_AUTH_FPRTIME, 0};
221 const char *s;
222 char **attrs;
223 char cardinf[128];
224 int idx=0, n=0;
225
226 if (!card->aid) {
227 msg_box( dlg, _("No OpenPGP smart card detected."), "WinPT", MB_ERR );
228 return -1;
229 }
230 SetDlgItemText (dlg, IDC_CEDIT_AID, card->aid);
231 SetDlgItemInt (dlg, IDC_CEDIT_SIGCOUNT, card->sig_count, TRUE);
232
233 for (idx=0; fprbuf[idx]; idx++) {
234 print_fpr (dlg, fprbuf[idx], card->fpr[idx]);
235 SetDlgItemText (dlg, fprtime[idx], card->fpr_created_str[idx]);
236 }
237
238 attrs = card_get_items (card, &n);
239 for (idx=1; attr_tab[idx].ctlid; idx++) {
240 s = attrs[idx];
241 SetDlgItemText (dlg, attr_tab[idx].ctlid, s && *s? s : attr_tab[idx].err);
242 }
243 free (attrs);
244
245 idx = idx_from_lang (card->lang);
246 SendDlgItemMessage (dlg, IDC_CEDIT_LANG, CB_SETCURSEL, (WPARAM)idx, 0);
247
248 switch (card->sex) {
249 case 'm': idx=0; break;
250 case 'f': idx=1; break;
251 default :
252 case 'u': idx=2; break;
253 }
254 SendDlgItemMessage (dlg, IDC_CEDIT_SEX, CB_SETCURSEL, (WPARAM)idx, 0);
255
256 s = card->serial;
257 while (s && *s == '0') s++;
258 _snprintf (cardinf, sizeof (cardinf)-1,
259 "Card Edit - %s serial no. %s version %s",
260 card->card_type, s, get_printable_version (card->version));
261 SetWindowText (dlg, cardinf);
262
263 return 0;
264 }
265
266
267 /* Initialize the enum combox boxes in dialog @dlg. */
268 static void
269 prepare_dialog (HWND dlg)
270 {
271 const char * s;
272 int i;
273
274 for (i=0; (s = sex[i]); i++)
275 SendDlgItemMessage (dlg, IDC_CEDIT_SEX, CB_ADDSTRING, 0, (LPARAM) s);
276 SendDlgItemMessage (dlg, IDC_CEDIT_SEX, CB_SETCURSEL, 0, 0);
277 for (i=0; (s = lang[i]); i++)
278 SendDlgItemMessage (dlg, IDC_CEDIT_LANG, CB_ADDSTRING, 0, (LPARAM)s);
279 SendDlgItemMessage (dlg, IDC_CEDIT_LANG, CB_SETCURSEL, 0, 0);
280 }
281
282
283 /* Return 0 if the given string @str has the proper format. */
284 static int
285 check_string (const char *str, int flags)
286 {
287 size_t i;
288 for (i=0; i < strlen (str); i++) {
289 if (flags & 0x02 && !isalpha (str[i]))
290 return -1;
291 }
292 return 0;
293 }
294
295
296 static int
297 do_proc_card_cmds (HWND dlg, struct pin_cb_ctx_s *pincb, gpg_card_t card)
298 {
299 static struct {
300 int id;
301 int cmd;
302 int us_ascii;
303 int changed;
304 } idctl[] = {
305 {IDC_CEDIT_NAME, GPG_EDITCARD_NAME, 1, 0},
306 {IDC_CEDIT_LANG2, GPG_EDITCARD_LANG, 1, 0},
307 {IDC_CEDIT_SEX2, GPG_EDITCARD_SEX, 1|1,0},
308 {IDC_CEDIT_KEYURL,GPG_EDITCARD_KEYURL,1|4,0},
309 {IDC_CEDIT_LOGIN, GPG_EDITCARD_LOGIN, 1, 0},
310 {0}
311 };
312 gpgme_error_t err;
313 GpgCardEdit *ce;
314 char buf[256], tmp[128];
315 int errc=0, use_arg2 = 0;
316 int i, id, n=0;
317
318 /* XXX rewrite the entire function */
319 for( i=0; idctl[i].id; i++ ) /* reset */
320 idctl[i].changed = 0;
321
322 if( SendMessage( GetDlgItem( dlg, IDC_CEDIT_LANG2 ), WM_GETTEXTLENGTH, 0, 0 ) ) {
323 idctl[1].changed = 1;
324 n++;
325 }
326 if( SendMessage( GetDlgItem( dlg, IDC_CEDIT_SEX2 ), WM_GETTEXTLENGTH, 0, 0 ) ) {
327 idctl[2].changed = 1;
328 n++;
329 }
330
331 if( SendDlgItemMessage( dlg, IDC_CEDIT_NAME2, EM_GETMODIFY, 0, 0 ) ) {
332 idctl[0].changed = 1;
333 n++;
334 }
335 for( i=0; (id = idctl[i].id); i++ ) {
336 if( SendDlgItemMessage( dlg, id, EM_GETMODIFY, 0, 0 ) ) {
337 idctl[i].changed = 1;
338 n++;
339 }
340 }
341 if (!pincb || !card) /* just return the changed elements */
342 return n;
343 if (!n)
344 return 0;
345 if (!pincb->apin) {
346 msg_box (dlg, _("No PINs found."), _("Card Edit"), MB_ERR);
347 return 0;
348 }
349
350 ce = new GpgCardEdit ();
351 if (!ce)
352 BUG (NULL);
353 ce->setAdminPIN (pincb->apin);
354 /*ce->setPIN (pincb->upin);*/
355 for( i=0; idctl[i].id; i++ ) {
356 if( idctl[i].changed ) {
357 GetDlgItemText( dlg, idctl[i].id, buf, sizeof (buf)-1 );
358 if (idctl[i].us_ascii && is_8bit_string (buf)) {
359 msg_box (dlg, _("Only plain ASCII is currently allowed."),
360 _("Card Edit"), MB_ERR);
361 errc--; continue;
362 }
363 if( (idctl[i].us_ascii & 2) && check_string( buf, 2 ) ) {
364 msg_box( dlg, _("Only alphabetic characters are allowed."),
365 _("Card Edit"), MB_ERR );
366 errc--; continue;
367 }
368 if ((idctl[i].us_ascii & 4) &&
369 (!strchr (buf, ':') || !strstr (buf, "//"))) {
370 /* XXX: better URL check. */
371 msg_box (dlg, _("Invalid URL."), _("Card Edit"), MB_ERR);
372 errc--; continue;
373 }
374 if( idctl[i].cmd == GPG_EDITCARD_NAME ) {
375 /* The "name" command actually needs two fields */
376 GetDlgItemText( dlg, IDC_CEDIT_NAME2, tmp, sizeof tmp-1 );
377 use_arg2 = 1;
378 }
379 else
380 use_arg2 = 0;
381 err = ce->doCmd (idctl[i].cmd, buf, use_arg2? tmp : NULL);
382 if (err) {
383 log_box (_("Card Edit"), MB_ERR,
384 _("Could not modify card attribute: %s"),
385 gpgme_strerror (err));
386 errc--;
387 /* If no card is inserted, we leave the loop. */
388 if (gpgme_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
389 break;
390 }
391 }
392 }
393 if (!errc) {
394 /* if the operation(s) succeeded, reset the modify flag for each control */
395 for( i = 0; idctl[i].id; i++ )
396 SendDlgItemMessage( dlg, idctl[i].id, EM_SETMODIFY, (WPARAM)(UINT)FALSE, 0 );
397 msg_box( dlg, _("Card attribute changed."), _("Card Edit"), MB_OK );
398 SetDlgItemText( dlg, IDC_CEDIT_LANG2, "" );
399 SetDlgItemText( dlg, IDC_CEDIT_SEX2, "" );
400 }
401 delete ce;
402 return errc;
403 } /* do_proc_card_cmds */
404
405
406 /* Cleanup pin callback @ctx. */
407 void
408 free_pincb (struct pin_cb_ctx_s *ctx)
409 {
410 if (!ctx)
411 return;
412 free_if_alloc (ctx->info_text);
413 sfree_if_alloc (ctx->upin);
414 sfree_if_alloc (ctx->apin);
415 }
416
417
418 /* Request a PIN from the user. @which decided if the
419 normal PIN or the admin PIN will be requested.
420 @card is used to show some information to the user.
421 @pincb is the actuall callback context.
422 Return value: 0 on success. */
423 static int
424 do_askpin (HWND dlg, int which, gpg_card_t card,
425 struct pin_cb_ctx_s *pincb)
426 {
427 const char * s, * fmt;
428 const char * n1, * n2, * serial;
429 char * p;
430 size_t n;
431
432 if( (which == CARD_ADMIN_PIN && pincb->apin) ||
433 (which == CARD_USER_PIN && pincb->upin) )
434 return 0;
435
436 if (which == CARD_ADMIN_PIN)
437 s = _("Please enter the 'Admin PIN'");
438 else if (which == CARD_USER_PIN)
439 s = _("Please enter the 'User PIN'");
440 else
441 s = _("Please enter the PIN");
442 pincb->which = which;
443 free_if_alloc( pincb->info_text );
444 if( card ) {
445 fmt = _("%s\nName: %s %s\nSerial-No: %s\n");
446 n1 = card->givenname;
447 n2 = card->surname;
448 if( !n1 || !n2 ) {
449 n1 = "No"; n2 = "Name";
450 }
451 serial = card->serial;
452 if (!serial)
453 serial = "No Serial ID";
454 n = strlen( n1 ) + strlen( n2 ) + strlen( fmt ) + strlen( serial ) + 3;
455 p = pincb->info_text = new char[strlen( s )+n+1 ];
456 if( !p )
457 BUG (0);
458 sprintf( p, fmt, s, n1, n2, serial );
459 }
460 else {
461 p = pincb->info_text = m_strdup (s);
462 if (!p)
463 BUG (0);
464 }
465 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_PIN, dlg,
466 pin_cb_dlg_proc, (LPARAM)pincb);
467 if (!pincb->apin && !pincb->upin) {
468 safe_free (pincb->info_text);
469 return -1;
470 }
471 return 0;
472 }
473
474
475 /* Dialog box procedure for card edit. */
476 BOOL CALLBACK
477 card_edit_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
478 {
479 static gpg_card_t card;
480 char tmp[128];
481 size_t n=0;
482
483 switch (msg) {
484 case WM_INITDIALOG:
485 card = (gpg_card_t)lparam;
486 if (!card)
487 BUG (0);
488 prepare_dialog (dlg);
489 if (card_status (dlg, card ))
490 EndDialog (dlg, TRUE);
491 center_window (dlg, NULL);
492 SetForegroundWindow (dlg);
493 return TRUE;
494
495 case WM_DESTROY:
496 free_pincb (&pincb);
497 memset (&pincb, 0, sizeof pincb);
498 break;
499
500 case WM_COMMAND:
501 switch( HIWORD( wparam ) ) {
502 case CBN_KILLFOCUS:
503 case CBN_EDITCHANGE:
504 case CBN_EDITUPDATE:
505 int ctlid = GetDlgCtrlID( (HWND)lparam );
506 int dstid = 0;
507
508 switch (ctlid) {
509 case IDC_CEDIT_LANG: dstid = IDC_CEDIT_LANG2; break;
510 case IDC_CEDIT_SEX: dstid = IDC_CEDIT_SEX2; break;
511 }
512 GetDlgItemText (dlg, ctlid, tmp, sizeof (tmp)-1);
513 SetDlgItemText (dlg, dstid, tmp);
514 break;
515 }
516 switch (LOWORD (wparam)) {
517 case IDC_CEDIT_CHPIN:
518 DialogBoxParam( glob_hinst, (LPCTSTR)IDD_WINPT_CARD_CHPIN, dlg,
519 card_changepin_dlg_proc, NULL );
520 break;
521
522 case IDC_CEDIT_NEWKEYS:
523 if (item_get_text_length (dlg, IDC_CEDIT_FPR1) > 0) {
524 int id = msg_box (dlg,
525 _("This operation will override the keys on the card.\n"
526 "Still proceed?"), _("Card Edit"), MB_WARN|MB_YESNO);
527 if (id == IDNO)
528 return TRUE;
529 }
530 DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_CARD_KEYGEN,
531 glob_hwnd, card_keygen_dlg_proc, NULL);
532 break;
533
534 case IDOK:
535 n = do_proc_card_cmds (dlg, NULL, NULL);
536 if (n) {
537 if (do_askpin (dlg, CARD_ADMIN_PIN, card, &pincb))
538 EndDialog (dlg, FALSE);
539 }
540 do_proc_card_cmds (dlg, &pincb, card);
541 free_pincb (&pincb);
542 if (!n)
543 EndDialog (dlg, TRUE);
544 break;
545
546 case IDCANCEL:
547 EndDialog( dlg, FALSE );
548 break;
549 }
550 break;
551 }
552
553 return FALSE;
554 }
555
556
557 static int /* fixme: works only roughly */
558 calc_days (int y2, int m2, int d2,
559 int y1, int m1, int d1)
560
561 {
562 int n=0;
563
564 if ((y2-y1) > 0)
565 n += (y2-y1)*365;
566 if ((m2-m1) > 0)
567 n += (m2-m1)*30;
568 if ((d2-d1) > 0)
569 n += (d2-d1);
570 else if ((d2-d1) < 0)
571 n -= (d1-d2);
572 return n;
573 }
574
575
576 /* Dialog box procedure for the key generation on cards. */
577 BOOL CALLBACK
578 card_keygen_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
579 {
580 gpgme_error_t err;
581 GpgCardEdit *ce;
582 char name[128], email[128], comment[128];
583 char pass[128];
584 int card_flags = GPG_CARDFLAG_NONE;
585 int expires=0, valid;
586 size_t n;
587
588 switch (msg) {
589 case WM_INITDIALOG:
590 center_window (dlg, NULL);
591 CheckDlgButton (dlg, IDC_CKEYGEN_REPLACE, BST_CHECKED);
592 CheckDlgButton (dlg, IDC_CKEYGEN_NEVER, BST_CHECKED);
593 CheckDlgButton (dlg, IDC_CKEYGEN_BACKUP, BST_CHECKED);
594 EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_VALID), FALSE);
595 SendDlgItemMessage (dlg, IDC_CKEYGEN_ALG, CB_ADDSTRING, 0,
596 (LPARAM)(const char*)"RSA");
597 SendDlgItemMessage (dlg, IDC_CKEYGEN_ALG, CB_SETCURSEL, 0, 0);
598 SetFocus (GetDlgItem (dlg, IDC_CKEYGEN_NAME));
599 SetForegroundWindow (dlg);
600 SetDlgItemText (dlg, IDC_CKEYGEN_NAMEINF, _("&Name"));
601 SetDlgItemText (dlg, IDC_CKEYGEN_CMTINF, _("&Comment (optional)"));
602 SetDlgItemText (dlg, IDC_CKEYGEN_EXPDATEINF, _("&Expire date"));
603 SetDlgItemText (dlg, IDC_CKEYGEN_PWDINF, _("Off-card passphrase"));
604 SetDlgItemText (dlg, IDC_CKEYGEN_NEVER, _("&Never"));
605 SetDlgItemText (dlg, IDC_CKEYGEN_MAILINF, _("Email &address"));
606 SetWindowText (dlg, _("Card Key Generation"));
607 return FALSE;
608
609 case WM_SYSCOMMAND:
610 if (LOWORD (wparam) == SC_CLOSE)
611 EndDialog (dlg, TRUE);
612 return FALSE;
613
614 case WM_COMMAND:
615 if (HIWORD (wparam) == BN_CLICKED &&
616 (LOWORD (wparam) == IDC_CKEYGEN_BACKUP) ||
617 LOWORD (wparam) == IDC_CKEYGEN_NEVER) {
618 EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_VALID),
619 IsDlgButtonChecked (dlg, IDC_CKEYGEN_NEVER)? 0: 1);
620 EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_PASS),
621 IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP)? 1 : 0);
622 return TRUE;
623 }
624
625 switch (LOWORD (wparam)) {
626 case IDOK:
627 n = item_get_text_length (dlg, IDC_CKEYGEN_NAME);
628 if (!n) {
629 msg_box (dlg, _("Please enter your name."), _("Card Edit"), MB_ERR);
630 return TRUE;
631 }
632 if (n < 5) {
633 msg_box (dlg, _("Name must be at least 5 characters long."),
634 _("Card Edit"), MB_INFO);
635 return TRUE;
636 }
637 n = item_get_text_length (dlg, IDC_CKEYGEN_EMAIL);
638 if (!n) {
639 msg_box (dlg, _("Please enter your e-mail address."),
640 _("Card Edit"), MB_ERR);
641 return TRUE;
642 }
643 GetDlgItemText (dlg, IDC_CKEYGEN_NAME, name, sizeof (name)-1);
644 GetDlgItemText (dlg, IDC_CKEYGEN_EMAIL, email, sizeof (email)-1);
645 if (!strchr (email, '@') || n < 3) {
646 msg_box (dlg, _("Please enter a valid e-mail address."),
647 _("Card Edit"), MB_ERR);
648 return TRUE;
649 }
650 n = GetDlgItemText (dlg, IDC_CKEYGEN_PASS, pass, sizeof (pass)-1);
651 if (!n && IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP)) {
652 msg_box (dlg, _("Please enter an off-card passphrase."), _("Card Edit"), MB_ERR);
653 return TRUE;
654 }
655 n = item_get_text_length (dlg, IDC_CKEYGEN_COMMENT);
656 if (n > 0)
657 GetDlgItemText (dlg, IDC_CKEYGEN_COMMENT, comment, sizeof (comment)-1);
658 if (is_8bit_string (name) || n > 0 && is_8bit_string (comment)) {
659 msg_box (dlg, _("Please use plain ASCII charset for the fields."),
660 _("Card Edit"), MB_INFO);
661 return TRUE;
662 }
663 memset (&pincb, 0, sizeof (pincb));
664 if (do_askpin (dlg, CARD_ADMIN_PIN, NULL, &pincb)) {
665 free_pincb (&pincb);
666 return TRUE;
667 }
668 if (do_askpin (dlg, CARD_USER_PIN, NULL, &pincb)) {
669 free_pincb (&pincb);
670 return TRUE;
671 }
672 ce = new GpgCardEdit ();
673 if (!ce)
674 BUG (0);
675
676 expires = !IsDlgButtonChecked (dlg, IDC_CKEYGEN_NEVER);
677 if (expires) {
678 SYSTEMTIME st, ct;
679 DateTime_GetSystemtime (GetDlgItem (dlg, IDC_CKEYGEN_VALID), &st);
680 if (!keygen_check_date (&st)) {
681 msg_box (dlg, _("The date you have chosen lies in the past."),
682 _("Card Edit"), MB_ERR);
683 free_pincb (&pincb);
684 delete ce;
685 return TRUE;
686 }
687 GetSystemTime (&ct);
688 /* XXX this is not very precise */
689 valid = calc_days (st.wYear, st.wMonth, st.wDay,
690 ct.wYear, ct.wMonth, ct.wDay);
691 }
692 if (IsDlgButtonChecked (dlg, IDC_CKEYGEN_REPLACE))
693 card_flags |= GPG_CARDFLAG_REPLACE;
694 if (IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP))
695 card_flags |= GPG_CARDFLAG_BAKENC;
696 ce->setKeygenPassphrase (pass);
697 ce->setPIN (pincb.upin);
698 ce->setAdminPIN (pincb.apin);
699
700 SetCursor (LoadCursor (NULL, IDC_WAIT));
701 err = ce->genKey (card_flags, name, email, n? comment: NULL,
702 expires? valid : 0, NULL);
703
704 SetCursor (LoadCursor (NULL, IDC_ARROW));
705
706 if (gpgme_err_code (err) == GPG_ERR_CANCELED)
707 msg_box (dlg, _("Operation was canceled. It seems that there are "
708 "existing\nkeys on the cards. You need to mark the "
709 "'Overwrite' flag."), _("Card Edit"), MB_INFO);
710 else
711 if (err)
712 msg_box (dlg, "The operation does not succeed.\n"
713 "Please make sure you entered the right PIN's."
714 , _("Card Edit"), MB_ERR);
715 else
716 msg_box (dlg, _("Keys successfully created."),
717 _("Card Edit"), MB_OK);
718 wipememory (pass, sizeof (pass));
719 free_pincb (&pincb);
720 delete ce;
721 return TRUE;
722
723 case IDCANCEL:
724 EndDialog (dlg, FALSE);
725 return FALSE;
726 }
727 break;
728 }
729 return FALSE;
730 }
731
732
733 /* Check if the given pinlen is valid.
734 @which decided what PIN will be used.
735 @pinlen is the pin length entered by the user.
736 Return value: 0 on success. */
737 static int
738 check_pin_len (int which, int flag, int pinlen)
739 {
740 if (!pinlen) {
741 if (flag)
742 msg_box (NULL, _("Please enter the old card PIN."), _("Card Edit"), MB_ERR);
743 else
744 msg_box (NULL, _("Please enter the new card PIN."), _("Card Edit"), MB_ERR);
745 return -1;
746 }
747 if (which == CARD_ADMIN_PIN
748 && pinlen < 8) {
749 msg_box (NULL, _("Admin PIN must be minimal 8 characters."), _("Card Edit"), MB_ERR);
750 return -1;
751 }
752 if (which == CARD_USER_PIN
753 && pinlen < 6) {
754 msg_box (NULL, _("PIN must be minimal 6 characters."), _("Card Edit"), MB_ERR);
755 return -1;
756 }
757 return 0;
758 }
759
760 /* Dialog box procedure to change the PIN. */
761 BOOL CALLBACK
762 card_changepin_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
763 {
764 static int hide = 1;
765 gpgme_error_t err;
766 GpgCardEdit *ce;
767 char pold[128], pnew[128], pnew2[128];
768 int which;
769 size_t n;
770
771 switch( msg ) {
772 case WM_INITDIALOG:
773 hide = 1;
774 CheckDlgButton (dlg, IDC_CHPIN_HIDE, BST_CHECKED);
775 center_window (dlg, NULL);
776 CheckDlgButton (dlg, IDC_CHPIN_ISWORK, BST_CHECKED);
777 SetWindowText (dlg, _("Change Card PIN"));
778 SetForegroundWindow (dlg);
779 break;
780
781 case WM_COMMAND:
782 if (HIWORD (wparam) == BN_CLICKED && LOWORD (wparam) == IDC_CHPIN_HIDE) {
783 HWND hwnd;
784 hide ^= 1;
785 hwnd = GetDlgItem (dlg, IDC_CHPIN_OLDPIN);
786 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
787 SetFocus (hwnd);
788 hwnd = GetDlgItem (dlg, IDC_CHPIN_NEWPIN);
789 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
790 SetFocus (hwnd);
791 hwnd = GetDlgItem (dlg, IDC_CHPIN_NEWPIN2);
792 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
793 SetFocus (hwnd);
794 }
795 switch( LOWORD( wparam ) ) {
796 case IDOK:
797 if (IsDlgButtonChecked (dlg, IDC_CHPIN_ISADMIN))
798 which = CARD_ADMIN_PIN;
799 else if (IsDlgButtonChecked (dlg, IDC_CHPIN_ISWORK))
800 which = CARD_USER_PIN;
801
802 n = item_get_text_length (dlg, IDC_CHPIN_OLDPIN);
803 if (check_pin_len (which, 1, n))
804 return TRUE;
805 n = item_get_text_length (dlg, IDC_CHPIN_NEWPIN);
806 if (check_pin_len (which, 0, n))
807 return TRUE;
808 n = item_get_text_length (dlg, IDC_CHPIN_NEWPIN2);
809 if (check_pin_len (which, 0, n))
810 return TRUE;
811 GetDlgItemText (dlg, IDC_CHPIN_OLDPIN, pold, sizeof (pold)-1);
812 GetDlgItemText (dlg, IDC_CHPIN_NEWPIN, pnew, sizeof (pnew)-1);
813 GetDlgItemText (dlg, IDC_CHPIN_NEWPIN2, pnew2, sizeof (pnew2)-1);
814 if (strcmp (pnew, pnew2)) {
815 msg_box (dlg, _("Passphrases do not match. Please try again."),
816 _("Card Edit"), MB_ERR);
817 return TRUE;
818 }
819
820 ce = new GpgCardEdit ();
821 if (!ce)
822 BUG (0);
823 if (which == CARD_ADMIN_PIN)
824 ce->setAdminPIN (pold);
825 else
826 ce->setPIN (pold);
827 ce->setNewPIN (pnew);
828 err = ce->changePIN (which == CARD_ADMIN_PIN? GPG_EDITCARD_CHAPIN :
829 GPG_EDITCARD_CHUPIN);
830 if (err)
831 msg_box (dlg, gpgme_strerror (err), _("Card Edit"), MB_ERR);
832 else {
833 msg_box (dlg, _("PIN successfully changed."),
834 _("Card Edit"), MB_OK);
835 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN, "");
836 SetDlgItemText (dlg, IDC_CHPIN_OLDPIN, "");
837 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN2, "");
838 }
839 wipememory (pold, sizeof (pold));
840 wipememory (pnew, sizeof (pnew));
841 wipememory (pnew2, sizeof (pnew2));
842 delete ce;
843 break;
844
845 case IDCANCEL:
846 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN, "");
847 SetDlgItemText (dlg, IDC_CHPIN_OLDPIN, "");
848 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN2, "");
849 EndDialog (dlg, FALSE);
850 break;
851 }
852 break;
853 }
854
855 return FALSE;
856 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26