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

Annotation of /trunk/Src/wptCardDlg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 193 - (hide annotations)
Sat Apr 1 12:36:35 2006 UTC (18 years, 11 months ago) by twoaday
File size: 23169 byte(s)
2006-03-31  Timo Schulz  <ts@g10code.de>
 
        * wptCommonDlg.cpp (nls_load_langlist): New.
        (nsl_set_language): New.
        (nls_dlg_proc): New.
        (select_language): New. Allow user to select the language.
        * wptNLS.c (get_gettext_langid): Updated available languages.
        * WinPT.cpp (WinMain): Allow to select the languag on first
        start in non-installer environments.
        * wptVerifyList.cpp (verlist_build): Simplified.
        (verlist_add_sig_log): Likewise.
        * wptListview.cpp (listview_set_column_width,
        listview_get_selected_item): New.
        * wptKeyManager.cpp (gpg_clip_export): Merged into..
        (km_clip_export): ..this function.


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26