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

Contents of /trunk/Src/wptCardDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 185 - (show annotations)
Mon Mar 20 12:48:52 2006 UTC (18 years, 11 months ago) by twoaday
File size: 23602 byte(s)
2006-03-20  Timo Schulz  <ts@g10code.de>

        * wptUTF8.cpp (get_native_charset): Removed.
        (utf8_to_native): Rewritten.
        * wptKeyEditDlgs.cpp (do_add_new_userid): Correct charset
        handling.
        * wptKeygenCBDlg.cpp (keygen_cb): Do proper reset if needed.


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 *cb, 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 (!cb || !card) /* just return the changed elements */
342 return n;
343 if (!n)
344 return 0;
345 if (!cb->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 (cb->apin);
354 /*ce->setPIN (cb->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 *cb)
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 && cb->apin) ||
433 (which == CARD_USER_PIN && cb->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 cb->which = which;
443 free_if_alloc( cb->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 = cb->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 = cb->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)cb);
467 if (!cb->apin && !cb->upin) {
468 safe_free (cb->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, 0);
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 dlg, card_keygen_dlg_proc, 0);
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=0;
586 DWORD 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 SetDlgItemText (dlg, IDC_CKEYGEN_REPLACE, _("Overwrite old keys on the card"));
607 SetDlgItemText (dlg, IDC_CKEYGEN_BACKUP, _("Make off-card backup of encryption key"));
608 SetWindowText (dlg, _("Card Key Generation"));
609 return FALSE;
610
611 case WM_SYSCOMMAND:
612 if (LOWORD (wparam) == SC_CLOSE)
613 EndDialog (dlg, TRUE);
614 return FALSE;
615
616 case WM_COMMAND:
617 if (HIWORD (wparam) == BN_CLICKED &&
618 (LOWORD (wparam) == IDC_CKEYGEN_BACKUP) ||
619 LOWORD (wparam) == IDC_CKEYGEN_NEVER) {
620 EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_VALID),
621 IsDlgButtonChecked (dlg, IDC_CKEYGEN_NEVER)? 0: 1);
622 EnableWindow (GetDlgItem (dlg, IDC_CKEYGEN_PASS),
623 IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP)? 1 : 0);
624 return TRUE;
625 }
626
627 switch (LOWORD (wparam)) {
628 case IDOK:
629 n = item_get_text_length (dlg, IDC_CKEYGEN_NAME);
630 if (!n) {
631 msg_box (dlg, _("Please enter your name."), _("Card Edit"), MB_ERR);
632 return TRUE;
633 }
634 if (n < 5) {
635 msg_box (dlg, _("Name must be at least 5 characters long."),
636 _("Card Edit"), MB_INFO);
637 return TRUE;
638 }
639 n = item_get_text_length (dlg, IDC_CKEYGEN_EMAIL);
640 if (!n) {
641 msg_box (dlg, _("Please enter your e-mail address."),
642 _("Card Edit"), MB_ERR);
643 return TRUE;
644 }
645 GetDlgItemText (dlg, IDC_CKEYGEN_NAME, name, sizeof (name)-1);
646 GetDlgItemText (dlg, IDC_CKEYGEN_EMAIL, email, sizeof (email)-1);
647 if (!strchr (email, '@') || n < 3) {
648 msg_box (dlg, _("Please enter a valid e-mail address."),
649 _("Card Edit"), MB_ERR);
650 return TRUE;
651 }
652 n = GetDlgItemText (dlg, IDC_CKEYGEN_PASS, pass, sizeof (pass)-1);
653 if (!n && IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP)) {
654 msg_box (dlg, _("Please enter an off-card passphrase."), _("Card Edit"), MB_ERR);
655 return TRUE;
656 }
657 n = item_get_text_length (dlg, IDC_CKEYGEN_COMMENT);
658 if (n > 0)
659 GetDlgItemText (dlg, IDC_CKEYGEN_COMMENT, comment, sizeof (comment)-1);
660 if (is_8bit_string (name) || n > 0 && is_8bit_string (comment)) {
661 msg_box (dlg, _("Please use plain ASCII charset for the fields."),
662 _("Card Edit"), MB_INFO);
663 return TRUE;
664 }
665 memset (&pincb, 0, sizeof (pincb));
666 if (do_askpin (dlg, CARD_ADMIN_PIN, NULL, &pincb)) {
667 free_pincb (&pincb);
668 return TRUE;
669 }
670 if (do_askpin (dlg, CARD_USER_PIN, NULL, &pincb)) {
671 free_pincb (&pincb);
672 return TRUE;
673 }
674 ce = new GpgCardEdit ();
675 if (!ce)
676 BUG (0);
677
678 expires = !IsDlgButtonChecked (dlg, IDC_CKEYGEN_NEVER);
679 if (expires) {
680 SYSTEMTIME st, ct;
681 DateTime_GetSystemtime (GetDlgItem (dlg, IDC_CKEYGEN_VALID), &st);
682 if (!keygen_check_date (&st)) {
683 msg_box (dlg, _("The date you have chosen lies in the past."),
684 _("Card Edit"), MB_ERR);
685 free_pincb (&pincb);
686 delete ce;
687 return TRUE;
688 }
689 GetSystemTime (&ct);
690 /* XXX this is not very precise */
691 valid = calc_days (st.wYear, st.wMonth, st.wDay,
692 ct.wYear, ct.wMonth, ct.wDay);
693 }
694 if (IsDlgButtonChecked (dlg, IDC_CKEYGEN_REPLACE))
695 card_flags |= GPG_CARDFLAG_REPLACE;
696 if (IsDlgButtonChecked (dlg, IDC_CKEYGEN_BACKUP))
697 card_flags |= GPG_CARDFLAG_BAKENC;
698 ce->setKeygenPassphrase (pass);
699 ce->setPIN (pincb.upin);
700 ce->setAdminPIN (pincb.apin);
701
702 SetCursor (LoadCursor (NULL, IDC_WAIT));
703 err = ce->genKey (card_flags, name, email, n? comment: NULL,
704 expires? valid : 0, NULL);
705
706 SetCursor (LoadCursor (NULL, IDC_ARROW));
707
708 if (gpgme_err_code (err) == GPG_ERR_CANCELED)
709 msg_box (dlg, _("Operation was canceled. It seems that there are "
710 "existing\nkeys on the cards. You need to mark the "
711 "'Overwrite' flag."), _("Card Edit"), MB_INFO);
712 else
713 if (err)
714 msg_box (dlg, "The operation does not succeed.\n"
715 "Please make sure you entered the right PIN's."
716 , _("Card Edit"), MB_ERR);
717 else
718 msg_box (dlg, _("Keys successfully created."),
719 _("Card Edit"), MB_OK);
720 wipememory (pass, sizeof (pass));
721 free_pincb (&pincb);
722 delete ce;
723 return TRUE;
724
725 case IDCANCEL:
726 EndDialog (dlg, FALSE);
727 return FALSE;
728 }
729 break;
730 }
731 return FALSE;
732 }
733
734
735 /* Check if the given pinlen is valid.
736 @which decided what PIN will be used.
737 @pinlen is the pin length entered by the user.
738 Return value: 0 on success. */
739 static int
740 check_pin_len (int which, int flag, int pinlen)
741 {
742 if (!pinlen) {
743 if (flag)
744 msg_box (NULL, _("Please enter the old card PIN."), _("Card Edit"), MB_ERR);
745 else
746 msg_box (NULL, _("Please enter the new card PIN."), _("Card Edit"), MB_ERR);
747 return -1;
748 }
749 if (which == CARD_ADMIN_PIN
750 && pinlen < 8) {
751 msg_box (NULL, _("Admin PIN must be minimal 8 characters."), _("Card Edit"), MB_ERR);
752 return -1;
753 }
754 if (which == CARD_USER_PIN
755 && pinlen < 6) {
756 msg_box (NULL, _("PIN must be minimal 6 characters."), _("Card Edit"), MB_ERR);
757 return -1;
758 }
759 return 0;
760 }
761
762 /* Dialog box procedure to change the PIN. */
763 BOOL CALLBACK
764 card_changepin_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
765 {
766 static int hide = 1;
767 gpgme_error_t err;
768 GpgCardEdit *ce;
769 char pold[128], pnew[128], pnew2[128];
770 int which = 0;
771 DWORD n;
772
773 switch( msg ) {
774 case WM_INITDIALOG:
775 hide = 1;
776 CheckDlgButton (dlg, IDC_CHPIN_HIDE, BST_CHECKED);
777 center_window (dlg, NULL);
778 CheckDlgButton (dlg, IDC_CHPIN_ISWORK, BST_CHECKED);
779 SetWindowText (dlg, _("Change Card PIN"));
780 SetForegroundWindow (dlg);
781 break;
782
783 case WM_COMMAND:
784 if (HIWORD (wparam) == BN_CLICKED && LOWORD (wparam) == IDC_CHPIN_HIDE) {
785 HWND hwnd;
786 hide ^= 1;
787 hwnd = GetDlgItem (dlg, IDC_CHPIN_OLDPIN);
788 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
789 SetFocus (hwnd);
790 hwnd = GetDlgItem (dlg, IDC_CHPIN_NEWPIN);
791 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
792 SetFocus (hwnd);
793 hwnd = GetDlgItem (dlg, IDC_CHPIN_NEWPIN2);
794 SendMessage (hwnd, EM_SETPASSWORDCHAR, hide? '*' : 0, 0);
795 SetFocus (hwnd);
796 }
797 switch (LOWORD (wparam)) {
798 case IDOK:
799 if (IsDlgButtonChecked (dlg, IDC_CHPIN_ISADMIN))
800 which = CARD_ADMIN_PIN;
801 else if (IsDlgButtonChecked (dlg, IDC_CHPIN_ISWORK))
802 which = CARD_USER_PIN;
803
804 n = item_get_text_length (dlg, IDC_CHPIN_OLDPIN);
805 if (check_pin_len (which, 1, n))
806 return TRUE;
807 n = item_get_text_length (dlg, IDC_CHPIN_NEWPIN);
808 if (check_pin_len (which, 0, n))
809 return TRUE;
810 n = item_get_text_length (dlg, IDC_CHPIN_NEWPIN2);
811 if (check_pin_len (which, 0, n))
812 return TRUE;
813 GetDlgItemText (dlg, IDC_CHPIN_OLDPIN, pold, sizeof (pold)-1);
814 GetDlgItemText (dlg, IDC_CHPIN_NEWPIN, pnew, sizeof (pnew)-1);
815 GetDlgItemText (dlg, IDC_CHPIN_NEWPIN2, pnew2, sizeof (pnew2)-1);
816 if (strcmp (pnew, pnew2)) {
817 wipememory (pnew2, sizeof (pnew2));
818 wipememory (pnew, sizeof (pnew));
819 msg_box (dlg, _("Passphrases do not match. Please try again."),
820 _("Card Edit"), MB_ERR);
821 return TRUE;
822 }
823
824 ce = new GpgCardEdit ();
825 if (!ce)
826 BUG (0);
827 if (which == CARD_ADMIN_PIN)
828 ce->setAdminPIN (pold);
829 else
830 ce->setPIN (pold);
831 ce->setNewPIN (pnew);
832 err = ce->changePIN (which == CARD_ADMIN_PIN? GPG_EDITCARD_CHAPIN :
833 GPG_EDITCARD_CHUPIN);
834 if (err)
835 msg_box (dlg, gpgme_strerror (err), _("Card Edit"), MB_ERR);
836 else {
837 msg_box (dlg, _("PIN successfully changed."),
838 _("Card Edit"), MB_OK);
839 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN, "");
840 SetDlgItemText (dlg, IDC_CHPIN_OLDPIN, "");
841 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN2, "");
842 }
843 wipememory (pold, sizeof (pold));
844 wipememory (pnew, sizeof (pnew));
845 wipememory (pnew2, sizeof (pnew2));
846 delete ce;
847 break;
848
849 case IDCANCEL:
850 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN, "");
851 SetDlgItemText (dlg, IDC_CHPIN_OLDPIN, "");
852 SetDlgItemText (dlg, IDC_CHPIN_NEWPIN2, "");
853 EndDialog (dlg, FALSE);
854 break;
855 }
856 break;
857 }
858
859 return FALSE;
860 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26