Fix signal handling race condition.
[gnupg.git] / g10 / card-util.c
blobe25427f51b60cd4c0cb063146fbc450a77bf2748
1 /* card-util.c - Utility functions for the OpenPGP card.
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG 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 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG 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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <assert.h>
27 #if GNUPG_MAJOR_VERSION != 1
28 # include "gpg.h"
29 #endif /*GNUPG_MAJOR_VERSION != 1*/
30 #include "util.h"
31 #include "i18n.h"
32 #include "ttyio.h"
33 #include "status.h"
34 #include "options.h"
35 #include "main.h"
36 #include "keyserver-internal.h"
37 #if GNUPG_MAJOR_VERSION == 1
38 # ifdef HAVE_LIBREADLINE
39 # define GNUPG_LIBREADLINE_H_INCLUDED
40 # include <stdio.h>
41 # include <readline/readline.h>
42 # endif /*HAVE_LIBREADLINE*/
43 # include "cardglue.h"
44 #else /*GNUPG_MAJOR_VERSION!=1*/
45 # include "call-agent.h"
46 #endif /*GNUPG_MAJOR_VERSION!=1*/
48 #define CONTROL_D ('D' - 'A' + 1)
51 /* Change the PIN of a an OpenPGP card. This is an interactive
52 function. */
53 void
54 change_pin (int unblock_v2, int allow_admin)
56 struct agent_card_info_s info;
57 int rc;
59 rc = agent_learn (&info);
60 if (rc)
62 log_error (_("OpenPGP card not available: %s\n"),
63 gpg_strerror (rc));
64 return;
67 log_info (_("OpenPGP card no. %s detected\n"),
68 info.serialno? info.serialno : "[none]");
70 agent_clear_pin_cache (info.serialno);
72 if (opt.batch)
74 agent_release_card_info (&info);
75 log_error (_("can't do this in batch mode\n"));
76 return;
80 if (unblock_v2)
82 if (!info.is_v2)
83 log_error (_("This command is only available for version 2 cards\n"));
84 else if (!info.chvretry[1])
85 log_error (_("Reset Code not or not anymore available\n"));
86 else
88 rc = agent_scd_change_pin (2, info.serialno);
89 if (rc)
90 tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
91 else
93 write_status (STATUS_SC_OP_SUCCESS);
94 tty_printf ("PIN changed.\n");
98 else if (!allow_admin)
100 rc = agent_scd_change_pin (1, info.serialno);
101 if (rc)
102 tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
103 else
105 write_status (STATUS_SC_OP_SUCCESS);
106 tty_printf ("PIN changed.\n");
109 else
110 for (;;)
112 char *answer;
114 tty_printf ("\n");
115 tty_printf ("1 - change PIN\n"
116 "2 - unblock PIN\n"
117 "3 - change Admin PIN\n"
118 "4 - set the Reset Code\n"
119 "Q - quit\n");
120 tty_printf ("\n");
122 answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
123 cpr_kill_prompt();
124 if (strlen (answer) != 1)
125 continue;
127 rc = 0;
128 if (*answer == '1')
130 /* Change PIN. */
131 rc = agent_scd_change_pin (1, info.serialno);
132 if (rc)
133 tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
134 else
136 write_status (STATUS_SC_OP_SUCCESS);
137 tty_printf ("PIN changed.\n");
140 else if (*answer == '2')
142 /* Unblock PIN. */
143 rc = agent_scd_change_pin (101, info.serialno);
144 if (rc)
145 tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
146 else
148 write_status (STATUS_SC_OP_SUCCESS);
149 tty_printf ("PIN unblocked and new PIN set.\n");
152 else if (*answer == '3')
154 /* Change Admin PIN. */
155 rc = agent_scd_change_pin (3, info.serialno);
156 if (rc)
157 tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
158 else
160 write_status (STATUS_SC_OP_SUCCESS);
161 tty_printf ("PIN changed.\n");
164 else if (*answer == '4')
166 /* Set a new Reset Code. */
167 rc = agent_scd_change_pin (102, info.serialno);
168 if (rc)
169 tty_printf ("Error setting the Reset Code: %s\n",
170 gpg_strerror (rc));
171 else
173 write_status (STATUS_SC_OP_SUCCESS);
174 tty_printf ("Reset Code set.\n");
177 else if (*answer == 'q' || *answer == 'Q')
179 break;
183 agent_release_card_info (&info);
186 static const char *
187 get_manufacturer (unsigned int no)
189 /* Note: Make sure that there is no colon or linefeed in the string. */
190 switch (no)
192 case 0x0001: return "PPC Card Systems";
193 case 0x0002: return "Prism";
194 case 0x0003: return "OpenFortress";
195 case 0x0004: return "Wewid AB";
197 /* 0x00000 and 0xFFFF are defined as test cards per spec,
198 0xFFF00 to 0xFFFE are assigned for use with randomly created
199 serial numbers. */
200 case 0x0000:
201 case 0xffff: return "test card";
202 default: return (no & 0xff00) == 0xff00? "unmanaged S/N range":"unknown";
207 static void
208 print_sha1_fpr (FILE *fp, const unsigned char *fpr)
210 int i;
212 if (fpr)
214 for (i=0; i < 20 ; i+=2, fpr += 2 )
216 if (i == 10 )
217 tty_fprintf (fp, " ");
218 tty_fprintf (fp, " %02X%02X", *fpr, fpr[1]);
221 else
222 tty_fprintf (fp, " [none]");
223 tty_fprintf (fp, "\n");
227 static void
228 print_sha1_fpr_colon (FILE *fp, const unsigned char *fpr)
230 int i;
232 if (fpr)
234 for (i=0; i < 20 ; i++, fpr++)
235 fprintf (fp, "%02X", *fpr);
237 putc (':', fp);
241 static void
242 print_name (FILE *fp, const char *text, const char *name)
244 tty_fprintf (fp, "%s", text);
246 /* FIXME: tty_printf_utf8_string2 eats everything after and
247 including an @ - e.g. when printing an url. */
248 if (name && *name)
250 if (fp)
251 print_utf8_string2 (fp, name, strlen (name), '\n');
252 else
253 tty_print_utf8_string2 (name, strlen (name), 0);
255 else
256 tty_fprintf (fp, _("[not set]"));
257 tty_fprintf (fp, "\n");
260 static void
261 print_isoname (FILE *fp, const char *text, const char *tag, const char *name)
263 if (opt.with_colons)
264 fprintf (fp, "%s:", tag);
265 else
266 tty_fprintf (fp, "%s", text);
268 if (name && *name)
270 char *p, *given, *buf = xstrdup (name);
272 given = strstr (buf, "<<");
273 for (p=buf; *p; p++)
274 if (*p == '<')
275 *p = ' ';
276 if (given && given[2])
278 *given = 0;
279 given += 2;
280 if (opt.with_colons)
281 print_string (fp, given, strlen (given), ':');
282 else if (fp)
283 print_utf8_string2 (fp, given, strlen (given), '\n');
284 else
285 tty_print_utf8_string2 (given, strlen (given), 0);
287 if (opt.with_colons)
288 putc (':', fp);
289 else if (*buf)
290 tty_fprintf (fp, " ");
293 if (opt.with_colons)
294 print_string (fp, buf, strlen (buf), ':');
295 else if (fp)
296 print_utf8_string2 (fp, buf, strlen (buf), '\n');
297 else
298 tty_print_utf8_string2 (buf, strlen (buf), 0);
299 xfree (buf);
301 else
303 if (opt.with_colons)
304 putc (':', fp);
305 else
306 tty_fprintf (fp, _("[not set]"));
309 if (opt.with_colons)
310 fputs (":\n", fp);
311 else
312 tty_fprintf (fp, "\n");
315 /* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
316 static int
317 fpr_is_zero (const char *fpr)
319 int i;
321 for (i=0; i < 20 && !fpr[i]; i++)
323 return (i == 20);
327 /* Return true if the SHA1 fingerprint FPR consists only of 0xFF. */
328 static int
329 fpr_is_ff (const char *fpr)
331 int i;
333 for (i=0; i < 20 && fpr[i] == '\xff'; i++)
335 return (i == 20);
339 /* Print all available information about the current card. */
340 void
341 card_status (FILE *fp, char *serialno, size_t serialnobuflen)
343 struct agent_card_info_s info;
344 PKT_public_key *pk = xcalloc (1, sizeof *pk);
345 int rc;
346 unsigned int uval;
347 const unsigned char *thefpr;
348 int i;
350 if (serialno && serialnobuflen)
351 *serialno = 0;
353 rc = agent_learn (&info);
354 if (rc)
356 if (opt.with_colons)
357 fputs ("AID:::\n", fp);
358 log_error (_("OpenPGP card not available: %s\n"),
359 gpg_strerror (rc));
360 xfree (pk);
361 return;
364 if (opt.with_colons)
365 fprintf (fp, "AID:%s:", info.serialno? info.serialno : "");
366 else
367 tty_fprintf (fp, "Application ID ...: %s\n",
368 info.serialno? info.serialno : "[none]");
369 if (!info.serialno || strncmp (info.serialno, "D27600012401", 12)
370 || strlen (info.serialno) != 32 )
372 if (opt.with_colons)
373 fputs ("unknown:\n", fp);
374 log_info ("not an OpenPGP card\n");
375 agent_release_card_info (&info);
376 xfree (pk);
377 return;
380 if (!serialno)
382 else if (strlen (serialno)+1 > serialnobuflen)
383 log_error ("serial number longer than expected\n");
384 else
385 strcpy (serialno, info.serialno);
387 if (opt.with_colons)
388 fputs ("openpgp-card:\n", fp);
391 if (opt.with_colons)
393 fprintf (fp, "version:%.4s:\n", info.serialno+12);
394 uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18);
395 fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval));
396 fprintf (fp, "serial:%.8s:\n", info.serialno+20);
398 print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
400 fputs ("lang:", fp);
401 if (info.disp_lang)
402 print_string (fp, info.disp_lang, strlen (info.disp_lang), ':');
403 fputs (":\n", fp);
405 fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm':
406 info.disp_sex == 2? 'f' : 'u'));
408 fputs ("url:", fp);
409 if (info.pubkey_url)
410 print_string (fp, info.pubkey_url, strlen (info.pubkey_url), ':');
411 fputs (":\n", fp);
413 fputs ("login:", fp);
414 if (info.login_data)
415 print_string (fp, info.login_data, strlen (info.login_data), ':');
416 fputs (":\n", fp);
418 fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
419 fprintf (fp, "maxpinlen:%d:%d:%d:\n",
420 info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
421 fprintf (fp, "pinretry:%d:%d:%d:\n",
422 info.chvretry[0], info.chvretry[1], info.chvretry[2]);
423 fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
425 for (i=0; i < 4; i++)
427 if (info.private_do[i])
429 fprintf (fp, "private_do:%d:", i+1);
430 print_string (fp, info.private_do[i],
431 strlen (info.private_do[i]), ':');
432 fputs (":\n", fp);
436 fputs ("cafpr:", fp);
437 print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
438 print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
439 print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL);
440 putc ('\n', fp);
441 fputs ("fpr:", fp);
442 print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
443 print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
444 print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
445 putc ('\n', fp);
446 fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
447 (unsigned long)info.fpr1time, (unsigned long)info.fpr2time,
448 (unsigned long)info.fpr3time);
450 else
452 tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n",
453 info.serialno[12] == '0'?"":info.serialno+12,
454 info.serialno[13],
455 info.serialno[14] == '0'?"":info.serialno+14,
456 info.serialno[15]);
457 tty_fprintf (fp, "Manufacturer .....: %s\n",
458 get_manufacturer (xtoi_2(info.serialno+16)*256
459 + xtoi_2 (info.serialno+18)));
460 tty_fprintf (fp, "Serial number ....: %.8s\n", info.serialno+20);
462 print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
463 print_name (fp, "Language prefs ...: ", info.disp_lang);
464 tty_fprintf (fp, "Sex ..............: %s\n",
465 info.disp_sex == 1? _("male"):
466 info.disp_sex == 2? _("female") : _("unspecified"));
467 print_name (fp, "URL of public key : ", info.pubkey_url);
468 print_name (fp, "Login data .......: ", info.login_data);
469 if (info.private_do[0])
470 print_name (fp, "Private DO 1 .....: ", info.private_do[0]);
471 if (info.private_do[1])
472 print_name (fp, "Private DO 2 .....: ", info.private_do[1]);
473 if (info.private_do[2])
474 print_name (fp, "Private DO 3 .....: ", info.private_do[2]);
475 if (info.private_do[3])
476 print_name (fp, "Private DO 4 .....: ", info.private_do[3]);
477 if (info.cafpr1valid)
479 tty_fprintf (fp, "CA fingerprint %d .:", 1);
480 print_sha1_fpr (fp, info.cafpr1);
482 if (info.cafpr2valid)
484 tty_fprintf (fp, "CA fingerprint %d .:", 2);
485 print_sha1_fpr (fp, info.cafpr2);
487 if (info.cafpr3valid)
489 tty_fprintf (fp, "CA fingerprint %d .:", 3);
490 print_sha1_fpr (fp, info.cafpr3);
492 tty_fprintf (fp, "Signature PIN ....: %s\n",
493 info.chv1_cached? _("not forced"): _("forced"));
494 tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
495 info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
496 tty_fprintf (fp, "PIN retry counter : %d %d %d\n",
497 info.chvretry[0], info.chvretry[1], info.chvretry[2]);
498 tty_fprintf (fp, "Signature counter : %lu\n", info.sig_counter);
499 tty_fprintf (fp, "Signature key ....:");
500 print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
501 if (info.fpr1valid && info.fpr1time)
502 tty_fprintf (fp, " created ....: %s\n",
503 isotimestamp (info.fpr1time));
504 tty_fprintf (fp, "Encryption key....:");
505 print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
506 if (info.fpr2valid && info.fpr2time)
507 tty_fprintf (fp, " created ....: %s\n",
508 isotimestamp (info.fpr2time));
509 tty_fprintf (fp, "Authentication key:");
510 print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
511 if (info.fpr3valid && info.fpr3time)
512 tty_fprintf (fp, " created ....: %s\n",
513 isotimestamp (info.fpr3time));
514 tty_fprintf (fp, "General key info..: ");
516 thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 :
517 info.fpr3valid? info.fpr3 : NULL);
518 /* If the fingerprint is all 0xff, the key has no asssociated
519 OpenPGP certificate. */
520 if ( thefpr && !fpr_is_ff (thefpr)
521 && !get_pubkey_byfprint (pk, thefpr, 20))
523 KBNODE keyblock = NULL;
525 print_pubkey_info (fp, pk);
527 if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
528 print_card_key_info (fp, keyblock);
529 else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
531 release_kbnode (keyblock);
532 keyblock = NULL;
534 if (!auto_create_card_key_stub (info.serialno,
535 info.fpr1valid? info.fpr1:NULL,
536 info.fpr2valid? info.fpr2:NULL,
537 info.fpr3valid? info.fpr3:NULL))
539 if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
540 print_card_key_info (fp, keyblock);
544 release_kbnode (keyblock);
546 else
547 tty_fprintf (fp, "[none]\n");
550 free_public_key (pk);
551 agent_release_card_info (&info);
555 static char *
556 get_one_name (const char *prompt1, const char *prompt2)
558 char *name;
559 int i;
561 for (;;)
563 name = cpr_get (prompt1, prompt2);
564 if (!name)
565 return NULL;
566 trim_spaces (name);
567 cpr_kill_prompt ();
568 for (i=0; name[i] && name[i] >= ' ' && name[i] <= 126; i++)
571 /* The name must be in Latin-1 and not UTF-8 - lacking the code
572 to ensure this we restrict it to ASCII. */
573 if (name[i])
574 tty_printf (_("Error: Only plain ASCII is currently allowed.\n"));
575 else if (strchr (name, '<'))
576 tty_printf (_("Error: The \"<\" character may not be used.\n"));
577 else if (strstr (name, " "))
578 tty_printf (_("Error: Double spaces are not allowed.\n"));
579 else
580 return name;
581 xfree (name);
587 static int
588 change_name (void)
590 char *surname = NULL, *givenname = NULL;
591 char *isoname, *p;
592 int rc;
594 surname = get_one_name ("keygen.smartcard.surname",
595 _("Cardholder's surname: "));
596 givenname = get_one_name ("keygen.smartcard.givenname",
597 _("Cardholder's given name: "));
598 if (!surname || !givenname || (!*surname && !*givenname))
600 xfree (surname);
601 xfree (givenname);
602 return -1; /*canceled*/
605 isoname = xmalloc ( strlen (surname) + 2 + strlen (givenname) + 1);
606 strcpy (stpcpy (stpcpy (isoname, surname), "<<"), givenname);
607 xfree (surname);
608 xfree (givenname);
609 for (p=isoname; *p; p++)
610 if (*p == ' ')
611 *p = '<';
613 if (strlen (isoname) > 39 )
615 tty_printf (_("Error: Combined name too long "
616 "(limit is %d characters).\n"), 39);
617 xfree (isoname);
618 return -1;
621 rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL );
622 if (rc)
623 log_error ("error setting Name: %s\n", gpg_strerror (rc));
625 xfree (isoname);
626 return rc;
630 static int
631 change_url (void)
633 char *url;
634 int rc;
636 url = cpr_get ("cardedit.change_url", _("URL to retrieve public key: "));
637 if (!url)
638 return -1;
639 trim_spaces (url);
640 cpr_kill_prompt ();
642 if (strlen (url) > 254 )
644 tty_printf (_("Error: URL too long "
645 "(limit is %d characters).\n"), 254);
646 xfree (url);
647 return -1;
650 rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
651 if (rc)
652 log_error ("error setting URL: %s\n", gpg_strerror (rc));
653 xfree (url);
654 return rc;
658 /* Fetch the key from the URL given on the card or try to get it from
659 the default keyserver. */
660 static int
661 fetch_url(void)
663 #if GNUPG_MAJOR_VERSION == 1
664 int rc;
665 struct agent_card_info_s info;
667 memset(&info,0,sizeof(info));
669 rc=agent_scd_getattr("PUBKEY-URL",&info);
670 if(rc)
671 log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
672 else
674 struct keyserver_spec *spec=NULL;
676 rc=agent_scd_getattr("KEY-FPR",&info);
677 if(rc)
678 log_error("error retrieving key fingerprint from card: %s\n",
679 gpg_strerror(rc));
680 else if (info.pubkey_url && *info.pubkey_url)
682 spec=parse_keyserver_uri(info.pubkey_url,1,NULL,0);
683 if(spec && info.fpr1valid)
685 /* This is not perfectly right. Currently, all card
686 fingerprints are 20 digits, but what about
687 fingerprints for a future v5 key? We should get the
688 length from somewhere lower in the code. In any
689 event, the fpr/keyid is not meaningful for straight
690 HTTP fetches, but using it allows the card to point
691 to HKP and LDAP servers as well. */
692 rc=keyserver_import_fprint(info.fpr1,20,spec);
693 free_keyserver_spec(spec);
696 else if (info.fpr1valid)
698 rc = keyserver_import_fprint (info.fpr1, 20, opt.keyserver);
702 return rc;
703 #else
704 return 0;
705 #endif
709 /* Read data from file FNAME up to MAXLEN characters. On error return
710 -1 and store NULl at R_BUFFER; on success return the number of
711 bytes read and store the address of a newly allocated buffer at
712 R_BUFFER. */
713 static int
714 get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
716 FILE *fp;
717 char *data;
718 int n;
720 *r_buffer = NULL;
722 fp = fopen (fname, "rb");
723 #if GNUPG_MAJOR_VERSION == 1
724 if (fp && is_secured_file (fileno (fp)))
726 fclose (fp);
727 fp = NULL;
728 errno = EPERM;
730 #endif
731 if (!fp)
733 tty_printf (_("can't open `%s': %s\n"), fname, strerror (errno));
734 return -1;
737 data = xtrymalloc (maxlen? maxlen:1);
738 if (!data)
740 tty_printf (_("error allocating enough memory: %s\n"), strerror (errno));
741 fclose (fp);
742 return -1;
745 if (maxlen)
746 n = fread (data, 1, maxlen, fp);
747 else
748 n = 0;
749 fclose (fp);
750 if (n < 0)
752 tty_printf (_("error reading `%s': %s\n"), fname, strerror (errno));
753 xfree (data);
754 return -1;
756 *r_buffer = data;
757 return n;
761 static int
762 change_login (const char *args)
764 char *data;
765 int n;
766 int rc;
768 if (args && *args == '<') /* Read it from a file */
770 for (args++; spacep (args); args++)
772 n = get_data_from_file (args, 254, &data);
773 if (n < 0)
774 return -1;
776 else
778 data = cpr_get ("cardedit.change_login",
779 _("Login data (account name): "));
780 if (!data)
781 return -1;
782 trim_spaces (data);
783 cpr_kill_prompt ();
784 n = strlen (data);
787 if (n > 254 )
789 tty_printf (_("Error: Login data too long "
790 "(limit is %d characters).\n"), 254);
791 xfree (data);
792 return -1;
795 rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
796 if (rc)
797 log_error ("error setting login data: %s\n", gpg_strerror (rc));
798 xfree (data);
799 return rc;
802 static int
803 change_private_do (const char *args, int nr)
805 char do_name[] = "PRIVATE-DO-X";
806 char *data;
807 int n;
808 int rc;
810 assert (nr >= 1 && nr <= 4);
811 do_name[11] = '0' + nr;
813 if (args && (args = strchr (args, '<'))) /* Read it from a file */
815 for (args++; spacep (args); args++)
817 n = get_data_from_file (args, 254, &data);
818 if (n < 0)
819 return -1;
821 else
823 data = cpr_get ("cardedit.change_private_do",
824 _("Private DO data: "));
825 if (!data)
826 return -1;
827 trim_spaces (data);
828 cpr_kill_prompt ();
829 n = strlen (data);
832 if (n > 254 )
834 tty_printf (_("Error: Private DO too long "
835 "(limit is %d characters).\n"), 254);
836 xfree (data);
837 return -1;
840 rc = agent_scd_setattr (do_name, data, n, NULL );
841 if (rc)
842 log_error ("error setting private DO: %s\n", gpg_strerror (rc));
843 xfree (data);
844 return rc;
848 static int
849 change_cert (const char *args)
851 char *data;
852 int n;
853 int rc;
855 if (args && *args == '<') /* Read it from a file */
857 for (args++; spacep (args); args++)
859 n = get_data_from_file (args, 16384, &data);
860 if (n < 0)
861 return -1;
863 else
865 tty_printf ("usage error: redirectrion to file required\n");
866 return -1;
869 rc = agent_scd_writecert ("OPENPGP.3", data, n);
870 if (rc)
871 log_error ("error writing certificate to card: %s\n", gpg_strerror (rc));
872 xfree (data);
873 return rc;
877 static int
878 change_lang (void)
880 char *data, *p;
881 int rc;
883 data = cpr_get ("cardedit.change_lang",
884 _("Language preferences: "));
885 if (!data)
886 return -1;
887 trim_spaces (data);
888 cpr_kill_prompt ();
890 if (strlen (data) > 8 || (strlen (data) & 1))
892 tty_printf (_("Error: invalid length of preference string.\n"));
893 xfree (data);
894 return -1;
897 for (p=data; *p && *p >= 'a' && *p <= 'z'; p++)
899 if (*p)
901 tty_printf (_("Error: invalid characters in preference string.\n"));
902 xfree (data);
903 return -1;
906 rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL );
907 if (rc)
908 log_error ("error setting lang: %s\n", gpg_strerror (rc));
909 xfree (data);
910 return rc;
914 static int
915 change_sex (void)
917 char *data;
918 const char *str;
919 int rc;
921 data = cpr_get ("cardedit.change_sex",
922 _("Sex ((M)ale, (F)emale or space): "));
923 if (!data)
924 return -1;
925 trim_spaces (data);
926 cpr_kill_prompt ();
928 if (!*data)
929 str = "9";
930 else if ((*data == 'M' || *data == 'm') && !data[1])
931 str = "1";
932 else if ((*data == 'F' || *data == 'f') && !data[1])
933 str = "2";
934 else
936 tty_printf (_("Error: invalid response.\n"));
937 xfree (data);
938 return -1;
941 rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
942 if (rc)
943 log_error ("error setting sex: %s\n", gpg_strerror (rc));
944 xfree (data);
945 return rc;
949 static int
950 change_cafpr (int fprno)
952 char *data;
953 const char *s;
954 int i, c, rc;
955 unsigned char fpr[20];
957 data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
958 if (!data)
959 return -1;
960 trim_spaces (data);
961 cpr_kill_prompt ();
963 for (i=0, s=data; i < 20 && *s; )
965 while (spacep(s))
966 s++;
967 if (*s == ':')
968 s++;
969 while (spacep(s))
970 s++;
971 c = hextobyte (s);
972 if (c == -1)
973 break;
974 fpr[i++] = c;
975 s += 2;
977 xfree (data);
978 if (i != 20 || *s)
980 tty_printf (_("Error: invalid formatted fingerprint.\n"));
981 return -1;
984 rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
985 fprno==2?"CA-FPR-2":
986 fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
987 if (rc)
988 log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
989 return rc;
994 static void
995 toggle_forcesig (void)
997 struct agent_card_info_s info;
998 int rc;
999 int newstate;
1001 memset (&info, 0, sizeof info);
1002 rc = agent_scd_getattr ("CHV-STATUS", &info);
1003 if (rc)
1005 log_error ("error getting current status: %s\n", gpg_strerror (rc));
1006 return;
1008 newstate = !info.chv1_cached;
1009 agent_release_card_info (&info);
1011 rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL);
1012 if (rc)
1013 log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
1017 /* Helper for the key generation/edit functions. */
1018 static int
1019 get_info_for_key_operation (struct agent_card_info_s *info)
1021 int rc;
1023 memset (info, 0, sizeof *info);
1024 rc = agent_scd_getattr ("SERIALNO", info);
1025 if (rc || !info->serialno || strncmp (info->serialno, "D27600012401", 12)
1026 || strlen (info->serialno) != 32 )
1028 log_error (_("key operation not possible: %s\n"),
1029 rc ? gpg_strerror (rc) : _("not an OpenPGP card"));
1030 return rc? rc: -1;
1032 rc = agent_scd_getattr ("KEY-FPR", info);
1033 if (!rc)
1034 rc = agent_scd_getattr ("CHV-STATUS", info);
1035 if (!rc)
1036 rc = agent_scd_getattr ("DISP-NAME", info);
1037 if (rc)
1038 log_error (_("error getting current key info: %s\n"), gpg_strerror (rc));
1039 return rc;
1043 /* Helper for the key generation/edit functions. */
1044 static int
1045 check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
1047 int rc = 0;
1049 agent_clear_pin_cache (info->serialno);
1051 *forced_chv1 = !info->chv1_cached;
1052 if (*forced_chv1)
1053 { /* Switch of the forced mode so that during key generation we
1054 don't get bothered with PIN queries for each
1055 self-signature. */
1056 rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
1057 if (rc)
1059 log_error ("error clearing forced signature PIN flag: %s\n",
1060 gpg_strerror (rc));
1061 *forced_chv1 = 0;
1065 if (!rc)
1067 /* Check the PIN now, so that we won't get asked later for each
1068 binding signature. */
1069 rc = agent_scd_checkpin (info->serialno);
1070 if (rc)
1071 log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
1073 return rc;
1076 /* Helper for the key generation/edit functions. */
1077 static void
1078 restore_forced_chv1 (int *forced_chv1)
1080 int rc;
1082 if (*forced_chv1)
1083 { /* Switch back to forced state. */
1084 rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL);
1085 if (rc)
1087 log_error ("error setting forced signature PIN flag: %s\n",
1088 gpg_strerror (rc));
1094 /* Helper for the key generation/edit functions. */
1095 static void
1096 show_card_key_info (struct agent_card_info_s *info)
1098 tty_fprintf (NULL, "Signature key ....:");
1099 print_sha1_fpr (NULL, info->fpr1valid? info->fpr1:NULL);
1100 tty_fprintf (NULL, "Encryption key....:");
1101 print_sha1_fpr (NULL, info->fpr2valid? info->fpr2:NULL);
1102 tty_fprintf (NULL, "Authentication key:");
1103 print_sha1_fpr (NULL, info->fpr3valid? info->fpr3:NULL);
1104 tty_printf ("\n");
1108 /* Helper for the key generation/edit functions. */
1109 static int
1110 replace_existing_key_p (struct agent_card_info_s *info, int keyno)
1112 assert (keyno >= 0 && keyno <= 3);
1114 if ((keyno == 1 && info->fpr1valid)
1115 || (keyno == 2 && info->fpr2valid)
1116 || (keyno == 3 && info->fpr3valid))
1118 tty_printf ("\n");
1119 log_info ("WARNING: such a key has already been stored on the card!\n");
1120 tty_printf ("\n");
1121 if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_key",
1122 _("Replace existing key? (y/N) ")))
1123 return -1;
1125 return 0;
1129 static void
1130 generate_card_keys (void)
1132 struct agent_card_info_s info;
1133 int forced_chv1;
1134 int want_backup;
1136 if (get_info_for_key_operation (&info))
1137 return;
1139 #if GNUPG_MAJOR_VERSION == 1
1141 char *answer=cpr_get("cardedit.genkeys.backup_enc",
1142 _("Make off-card backup of encryption key? (Y/n) "));
1144 want_backup=answer_is_yes_no_default(answer,1);
1145 cpr_kill_prompt();
1146 xfree(answer);
1148 #else
1149 want_backup = cpr_get_answer_is_yes
1150 ( "cardedit.genkeys.backup_enc",
1151 _("Make off-card backup of encryption key? (Y/n) "));
1152 /*FIXME: we need answer_is_yes_no_default()*/
1153 #endif
1155 if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
1156 || (info.fpr2valid && !fpr_is_zero (info.fpr2))
1157 || (info.fpr3valid && !fpr_is_zero (info.fpr3)))
1159 tty_printf ("\n");
1160 log_info ("NOTE: keys are already stored on the card!\n");
1161 tty_printf ("\n");
1162 if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_keys",
1163 _("Replace existing keys? (y/N) ")))
1165 agent_release_card_info (&info);
1166 return;
1169 else if (!info.disp_name || !*info.disp_name)
1171 tty_printf ("\n");
1172 tty_printf (_("Please note that the factory settings of the PINs are\n"
1173 " PIN = `%s' Admin PIN = `%s'\n"
1174 "You should change them using the command --change-pin\n"),
1175 "123456", "12345678");
1176 tty_printf ("\n");
1179 if (check_pin_for_key_operation (&info, &forced_chv1))
1180 goto leave;
1182 generate_keypair (NULL, info.serialno,
1183 want_backup? opt.homedir:NULL);
1185 leave:
1186 agent_release_card_info (&info);
1187 restore_forced_chv1 (&forced_chv1);
1191 /* This function is used by the key edit menu to generate an arbitrary
1192 subkey. */
1194 card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
1196 struct agent_card_info_s info;
1197 int okay = 0;
1198 int forced_chv1 = 0;
1199 int keyno;
1201 if (get_info_for_key_operation (&info))
1202 return 0;
1204 show_card_key_info (&info);
1206 tty_printf (_("Please select the type of key to generate:\n"));
1208 tty_printf (_(" (1) Signature key\n"));
1209 tty_printf (_(" (2) Encryption key\n"));
1210 tty_printf (_(" (3) Authentication key\n"));
1212 for (;;)
1214 char *answer = cpr_get ("cardedit.genkeys.subkeytype",
1215 _("Your selection? "));
1216 cpr_kill_prompt();
1217 if (*answer == CONTROL_D)
1219 xfree (answer);
1220 goto leave;
1222 keyno = *answer? atoi(answer): 0;
1223 xfree(answer);
1224 if (keyno >= 1 && keyno <= 3)
1225 break; /* Okay. */
1226 tty_printf(_("Invalid selection.\n"));
1229 if (replace_existing_key_p (&info, keyno))
1230 goto leave;
1232 if (check_pin_for_key_operation (&info, &forced_chv1))
1233 goto leave;
1235 okay = generate_card_subkeypair (pub_keyblock, sec_keyblock,
1236 keyno, info.serialno);
1238 leave:
1239 agent_release_card_info (&info);
1240 restore_forced_chv1 (&forced_chv1);
1241 return okay;
1245 /* Store the key at NODE into the smartcard and modify NODE to
1246 carry the serialno stuff instead of the actual secret key
1247 parameters. USE is the usage for that key; 0 means any
1248 usage. */
1249 int
1250 card_store_subkey (KBNODE node, int use)
1252 struct agent_card_info_s info;
1253 int okay = 0;
1254 int rc;
1255 int keyno, i;
1256 PKT_secret_key *copied_sk = NULL;
1257 PKT_secret_key *sk;
1258 size_t n;
1259 const char *s;
1260 int allow_keyno[3];
1262 assert (node->pkt->pkttype == PKT_SECRET_KEY
1263 || node->pkt->pkttype == PKT_SECRET_SUBKEY);
1264 sk = node->pkt->pkt.secret_key;
1266 if (get_info_for_key_operation (&info))
1267 return 0;
1269 show_card_key_info (&info);
1271 if (!is_RSA (sk->pubkey_algo) || nbits_from_sk (sk) != 1024 )
1273 tty_printf ("You may only store a 1024 bit RSA key on the card\n");
1274 tty_printf ("\n");
1275 goto leave;
1278 allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG)));
1279 allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC)));
1280 allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)));
1282 tty_printf (_("Please select where to store the key:\n"));
1284 if (allow_keyno[0])
1285 tty_printf (_(" (1) Signature key\n"));
1286 if (allow_keyno[1])
1287 tty_printf (_(" (2) Encryption key\n"));
1288 if (allow_keyno[2])
1289 tty_printf (_(" (3) Authentication key\n"));
1291 for (;;)
1293 char *answer = cpr_get ("cardedit.genkeys.storekeytype",
1294 _("Your selection? "));
1295 cpr_kill_prompt();
1296 if (*answer == CONTROL_D || !*answer)
1298 xfree (answer);
1299 goto leave;
1301 keyno = *answer? atoi(answer): 0;
1302 xfree(answer);
1303 if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1])
1304 break; /* Okay. */
1305 tty_printf(_("Invalid selection.\n"));
1308 if (replace_existing_key_p (&info, keyno))
1309 goto leave;
1311 /* Unprotect key. */
1312 switch (is_secret_key_protected (sk) )
1314 case 0: /* Not protected. */
1315 break;
1316 case -1:
1317 log_error (_("unknown key protection algorithm\n"));
1318 goto leave;
1319 default:
1320 if (sk->protect.s2k.mode == 1001)
1322 log_error (_("secret parts of key are not available\n"));
1323 goto leave;
1325 if (sk->protect.s2k.mode == 1002)
1327 log_error (_("secret key already stored on a card\n"));
1328 goto leave;
1330 /* We better copy the key before we unprotect it. */
1331 copied_sk = sk = copy_secret_key (NULL, sk);
1332 rc = check_secret_key (sk, 0);
1333 if (rc)
1334 goto leave;
1337 rc = save_unprotected_key_to_card (sk, keyno);
1338 if (rc)
1339 goto leave;
1341 /* Get back to the maybe protected original secret key. */
1342 if (copied_sk)
1344 free_secret_key (copied_sk);
1345 copied_sk = NULL;
1347 sk = node->pkt->pkt.secret_key;
1349 /* Get rid of the secret key parameters and store the serial numer. */
1350 n = pubkey_get_nskey (sk->pubkey_algo);
1351 for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++)
1353 gcry_mpi_release (sk->skey[i]);
1354 sk->skey[i] = NULL;
1356 i = pubkey_get_npkey (sk->pubkey_algo);
1357 sk->skey[i] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
1358 sk->is_protected = 1;
1359 sk->protect.s2k.mode = 1002;
1360 s = info.serialno;
1361 for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
1362 sk->protect.ivlen++, s += 2)
1363 sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
1365 okay = 1;
1367 leave:
1368 if (copied_sk)
1369 free_secret_key (copied_sk);
1370 agent_release_card_info (&info);
1371 return okay;
1376 /* Data used by the command parser. This needs to be outside of the
1377 function scope to allow readline based command completion. */
1378 enum cmdids
1380 cmdNOP = 0,
1381 cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
1382 cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
1383 cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
1384 cmdUNBLOCK,
1385 cmdINVCMD
1388 static struct
1390 const char *name;
1391 enum cmdids id;
1392 int admin_only;
1393 const char *desc;
1394 } cmds[] =
1396 { "quit" , cmdQUIT , 0, N_("quit this menu")},
1397 { "q" , cmdQUIT , 0, NULL },
1398 { "admin" , cmdADMIN , 0, N_("show admin commands")},
1399 { "help" , cmdHELP , 0, N_("show this help")},
1400 { "?" , cmdHELP , 0, NULL },
1401 { "list" , cmdLIST , 0, N_("list all available data")},
1402 { "l" , cmdLIST , 0, NULL },
1403 { "debug" , cmdDEBUG , 0, NULL },
1404 { "name" , cmdNAME , 1, N_("change card holder's name")},
1405 { "url" , cmdURL , 1, N_("change URL to retrieve key")},
1406 { "fetch" , cmdFETCH , 0, N_("fetch the key specified in the card URL")},
1407 { "login" , cmdLOGIN , 1, N_("change the login name")},
1408 { "lang" , cmdLANG , 1, N_("change the language preferences")},
1409 { "sex" , cmdSEX , 1, N_("change card holder's sex")},
1410 { "cafpr" , cmdCAFPR , 1, N_("change a CA fingerprint")},
1411 { "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")},
1412 { "generate", cmdGENERATE, 1, N_("generate new keys")},
1413 { "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
1414 { "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
1415 { "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") },
1416 /* Note, that we do not announce these command yet. */
1417 { "privatedo", cmdPRIVATEDO, 0, NULL },
1418 { "writecert", cmdWRITECERT, 1, NULL },
1419 { NULL, cmdINVCMD, 0, NULL }
1423 #if GNUPG_MAJOR_VERSION == 1 && defined (HAVE_LIBREADLINE)
1425 /* These two functions are used by readline for command completion. */
1427 static char *
1428 command_generator(const char *text,int state)
1430 static int list_index,len;
1431 const char *name;
1433 /* If this is a new word to complete, initialize now. This includes
1434 saving the length of TEXT for efficiency, and initializing the
1435 index variable to 0. */
1436 if(!state)
1438 list_index=0;
1439 len=strlen(text);
1442 /* Return the next partial match */
1443 while((name=cmds[list_index].name))
1445 /* Only complete commands that have help text */
1446 if(cmds[list_index++].desc && strncmp(name,text,len)==0)
1447 return strdup(name);
1450 return NULL;
1453 static char **
1454 card_edit_completion(const char *text, int start, int end)
1456 /* If we are at the start of a line, we try and command-complete.
1457 If not, just do nothing for now. */
1459 if(start==0)
1460 return rl_completion_matches(text,command_generator);
1462 rl_attempted_completion_over=1;
1464 return NULL;
1466 #endif /* GNUPG_MAJOR_VERSION == 1 && HAVE_LIBREADLINE */
1468 /* Menu to edit all user changeable values on an OpenPGP card. Only
1469 Key creation is not handled here. */
1470 void
1471 card_edit (strlist_t commands)
1473 enum cmdids cmd = cmdNOP;
1474 int have_commands = !!commands;
1475 int redisplay = 1;
1476 char *answer = NULL;
1477 int did_checkpin = 0, allow_admin=0;
1478 char serialnobuf[50];
1481 if (opt.command_fd != -1)
1483 else if (opt.batch && !have_commands)
1485 log_error(_("can't do this in batch mode\n"));
1486 goto leave;
1489 for (;;)
1491 int arg_number;
1492 const char *arg_string = "";
1493 const char *arg_rest = "";
1494 char *p;
1495 int i;
1496 int cmd_admin_only;
1498 tty_printf("\n");
1499 if (redisplay )
1501 if (opt.with_colons)
1503 card_status (stdout, serialnobuf, DIM (serialnobuf));
1504 fflush (stdout);
1506 else
1508 card_status (NULL, serialnobuf, DIM (serialnobuf));
1509 tty_printf("\n");
1511 redisplay = 0;
1516 xfree (answer);
1517 if (have_commands)
1519 if (commands)
1521 answer = xstrdup (commands->d);
1522 commands = commands->next;
1524 else if (opt.batch)
1526 answer = xstrdup ("quit");
1528 else
1529 have_commands = 0;
1532 if (!have_commands)
1534 #if GNUPG_MAJOR_VERSION == 1
1535 tty_enable_completion (card_edit_completion);
1536 #endif
1537 answer = cpr_get_no_help("cardedit.prompt", _("Command> "));
1538 cpr_kill_prompt();
1539 #if GNUPG_MAJOR_VERSION == 1
1540 tty_disable_completion ();
1541 #endif
1543 trim_spaces(answer);
1545 while ( *answer == '#' );
1547 arg_number = 0; /* Yes, here is the init which egcc complains about */
1548 cmd_admin_only = 0;
1549 if (!*answer)
1550 cmd = cmdLIST; /* Default to the list command */
1551 else if (*answer == CONTROL_D)
1552 cmd = cmdQUIT;
1553 else
1555 if ((p=strchr (answer,' ')))
1557 *p++ = 0;
1558 trim_spaces (answer);
1559 trim_spaces (p);
1560 arg_number = atoi(p);
1561 arg_string = p;
1562 arg_rest = p;
1563 while (digitp (arg_rest))
1564 arg_rest++;
1565 while (spacep (arg_rest))
1566 arg_rest++;
1569 for (i=0; cmds[i].name; i++ )
1570 if (!ascii_strcasecmp (answer, cmds[i].name ))
1571 break;
1573 cmd = cmds[i].id;
1574 cmd_admin_only = cmds[i].admin_only;
1577 if (!allow_admin && cmd_admin_only)
1579 tty_printf ("\n");
1580 tty_printf (_("Admin-only command\n"));
1581 continue;
1584 switch (cmd)
1586 case cmdHELP:
1587 for (i=0; cmds[i].name; i++ )
1588 if(cmds[i].desc
1589 && (!cmds[i].admin_only || (cmds[i].admin_only && allow_admin)))
1590 tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1591 break;
1593 case cmdADMIN:
1594 if ( !strcmp (arg_string, "on") )
1595 allow_admin = 1;
1596 else if ( !strcmp (arg_string, "off") )
1597 allow_admin = 0;
1598 else if ( !strcmp (arg_string, "verify") )
1600 /* Force verification of the Admin Command. However,
1601 this is only done if the retry counter is at initial
1602 state. */
1603 char *tmp = xmalloc (strlen (serialnobuf) + 6 + 1);
1604 strcpy (stpcpy (tmp, serialnobuf), "[CHV3]");
1605 allow_admin = !agent_scd_checkpin (tmp);
1606 xfree (tmp);
1608 else /* Toggle. */
1609 allow_admin=!allow_admin;
1610 if(allow_admin)
1611 tty_printf(_("Admin commands are allowed\n"));
1612 else
1613 tty_printf(_("Admin commands are not allowed\n"));
1614 break;
1616 case cmdVERIFY:
1617 agent_scd_checkpin (serialnobuf);
1618 redisplay = 1;
1619 break;
1621 case cmdLIST:
1622 redisplay = 1;
1623 break;
1625 case cmdNAME:
1626 change_name ();
1627 break;
1629 case cmdURL:
1630 change_url ();
1631 break;
1633 case cmdFETCH:
1634 fetch_url();
1635 break;
1637 case cmdLOGIN:
1638 change_login (arg_string);
1639 break;
1641 case cmdLANG:
1642 change_lang ();
1643 break;
1645 case cmdSEX:
1646 change_sex ();
1647 break;
1649 case cmdCAFPR:
1650 if ( arg_number < 1 || arg_number > 3 )
1651 tty_printf ("usage: cafpr N\n"
1652 " 1 <= N <= 3\n");
1653 else
1654 change_cafpr (arg_number);
1655 break;
1657 case cmdPRIVATEDO:
1658 if ( arg_number < 1 || arg_number > 4 )
1659 tty_printf ("usage: privatedo N\n"
1660 " 1 <= N <= 4\n");
1661 else
1662 change_private_do (arg_string, arg_number);
1663 break;
1665 case cmdWRITECERT:
1666 if ( arg_number != 3 )
1667 tty_printf ("usage: writecert 3 < FILE\n");
1668 else
1669 change_cert (arg_rest);
1670 break;
1672 case cmdFORCESIG:
1673 toggle_forcesig ();
1674 break;
1676 case cmdGENERATE:
1677 generate_card_keys ();
1678 break;
1680 case cmdPASSWD:
1681 change_pin (0, allow_admin);
1682 did_checkpin = 0; /* Need to reset it of course. */
1683 break;
1685 case cmdUNBLOCK:
1686 change_pin (1, allow_admin);
1687 did_checkpin = 0; /* Need to reset it of course. */
1688 break;
1690 case cmdQUIT:
1691 goto leave;
1693 case cmdNOP:
1694 break;
1696 case cmdINVCMD:
1697 default:
1698 tty_printf ("\n");
1699 tty_printf (_("Invalid command (try \"help\")\n"));
1700 break;
1701 } /* End command switch. */
1702 } /* End of main menu loop. */
1704 leave:
1705 xfree (answer);