signal cleanup fix
[gnupg.git] / g10 / card-util.c
blob7d36ebf9c1511196b57bbb6b9235fd278da896ef
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 (info.apptype && !strcmp (info.apptype, "NKS"))
374 if (opt.with_colons)
375 fputs ("netkey-card:\n", fp);
376 log_info ("this is a NetKey card\n");
378 else if (info.apptype && !strcmp (info.apptype, "DINSIG"))
380 if (opt.with_colons)
381 fputs ("dinsig-card:\n", fp);
382 log_info ("this is a DINSIG compliant card\n");
384 else if (info.apptype && !strcmp (info.apptype, "P15"))
386 if (opt.with_colons)
387 fputs ("pkcs15-card:\n", fp);
388 log_info ("this is a PKCS#15 compliant card\n");
390 else if (info.apptype && !strcmp (info.apptype, "GELDKARTE"))
392 if (opt.with_colons)
393 fputs ("geldkarte-card:\n", fp);
394 log_info ("this is a Geldkarte compliant card\n");
396 else
398 if (opt.with_colons)
399 fputs ("unknown:\n", fp);
401 log_info ("not an OpenPGP card\n");
402 agent_release_card_info (&info);
403 xfree (pk);
404 return;
407 if (!serialno)
409 else if (strlen (serialno)+1 > serialnobuflen)
410 log_error ("serial number longer than expected\n");
411 else
412 strcpy (serialno, info.serialno);
414 if (opt.with_colons)
415 fputs ("openpgp-card:\n", fp);
418 if (opt.with_colons)
420 fprintf (fp, "version:%.4s:\n", info.serialno+12);
421 uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18);
422 fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval));
423 fprintf (fp, "serial:%.8s:\n", info.serialno+20);
425 print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
427 fputs ("lang:", fp);
428 if (info.disp_lang)
429 print_string (fp, info.disp_lang, strlen (info.disp_lang), ':');
430 fputs (":\n", fp);
432 fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm':
433 info.disp_sex == 2? 'f' : 'u'));
435 fputs ("url:", fp);
436 if (info.pubkey_url)
437 print_string (fp, info.pubkey_url, strlen (info.pubkey_url), ':');
438 fputs (":\n", fp);
440 fputs ("login:", fp);
441 if (info.login_data)
442 print_string (fp, info.login_data, strlen (info.login_data), ':');
443 fputs (":\n", fp);
445 fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
446 for (i=0; i < DIM (info.key_attr); i++)
447 if (info.key_attr[0].algo)
448 fprintf (fp, "keyattr:%d:%d:%u:\n", i+1,
449 info.key_attr[i].algo, info.key_attr[i].nbits);
450 fprintf (fp, "maxpinlen:%d:%d:%d:\n",
451 info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
452 fprintf (fp, "pinretry:%d:%d:%d:\n",
453 info.chvretry[0], info.chvretry[1], info.chvretry[2]);
454 fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
456 for (i=0; i < 4; i++)
458 if (info.private_do[i])
460 fprintf (fp, "private_do:%d:", i+1);
461 print_string (fp, info.private_do[i],
462 strlen (info.private_do[i]), ':');
463 fputs (":\n", fp);
467 fputs ("cafpr:", fp);
468 print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
469 print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
470 print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL);
471 putc ('\n', fp);
472 fputs ("fpr:", fp);
473 print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
474 print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
475 print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
476 putc ('\n', fp);
477 fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
478 (unsigned long)info.fpr1time, (unsigned long)info.fpr2time,
479 (unsigned long)info.fpr3time);
481 else
483 tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n",
484 info.serialno[12] == '0'?"":info.serialno+12,
485 info.serialno[13],
486 info.serialno[14] == '0'?"":info.serialno+14,
487 info.serialno[15]);
488 tty_fprintf (fp, "Manufacturer .....: %s\n",
489 get_manufacturer (xtoi_2(info.serialno+16)*256
490 + xtoi_2 (info.serialno+18)));
491 tty_fprintf (fp, "Serial number ....: %.8s\n", info.serialno+20);
493 print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
494 print_name (fp, "Language prefs ...: ", info.disp_lang);
495 tty_fprintf (fp, "Sex ..............: %s\n",
496 info.disp_sex == 1? _("male"):
497 info.disp_sex == 2? _("female") : _("unspecified"));
498 print_name (fp, "URL of public key : ", info.pubkey_url);
499 print_name (fp, "Login data .......: ", info.login_data);
500 if (info.private_do[0])
501 print_name (fp, "Private DO 1 .....: ", info.private_do[0]);
502 if (info.private_do[1])
503 print_name (fp, "Private DO 2 .....: ", info.private_do[1]);
504 if (info.private_do[2])
505 print_name (fp, "Private DO 3 .....: ", info.private_do[2]);
506 if (info.private_do[3])
507 print_name (fp, "Private DO 4 .....: ", info.private_do[3]);
508 if (info.cafpr1valid)
510 tty_fprintf (fp, "CA fingerprint %d .:", 1);
511 print_sha1_fpr (fp, info.cafpr1);
513 if (info.cafpr2valid)
515 tty_fprintf (fp, "CA fingerprint %d .:", 2);
516 print_sha1_fpr (fp, info.cafpr2);
518 if (info.cafpr3valid)
520 tty_fprintf (fp, "CA fingerprint %d .:", 3);
521 print_sha1_fpr (fp, info.cafpr3);
523 tty_fprintf (fp, "Signature PIN ....: %s\n",
524 info.chv1_cached? _("not forced"): _("forced"));
525 if (info.key_attr[0].algo)
527 tty_fprintf (fp, "Key attributes ...:");
528 for (i=0; i < DIM (info.key_attr); i++)
529 tty_fprintf (fp, " %u%c",
530 info.key_attr[i].nbits,
531 info.key_attr[i].algo == 1? 'R':
532 info.key_attr[i].algo == 17? 'D': '?');
533 tty_fprintf (fp, "\n");
535 tty_fprintf (fp, "Max. PIN lengths .: %d %d %d\n",
536 info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
537 tty_fprintf (fp, "PIN retry counter : %d %d %d\n",
538 info.chvretry[0], info.chvretry[1], info.chvretry[2]);
539 tty_fprintf (fp, "Signature counter : %lu\n", info.sig_counter);
540 tty_fprintf (fp, "Signature key ....:");
541 print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
542 if (info.fpr1valid && info.fpr1time)
543 tty_fprintf (fp, " created ....: %s\n",
544 isotimestamp (info.fpr1time));
545 tty_fprintf (fp, "Encryption key....:");
546 print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
547 if (info.fpr2valid && info.fpr2time)
548 tty_fprintf (fp, " created ....: %s\n",
549 isotimestamp (info.fpr2time));
550 tty_fprintf (fp, "Authentication key:");
551 print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
552 if (info.fpr3valid && info.fpr3time)
553 tty_fprintf (fp, " created ....: %s\n",
554 isotimestamp (info.fpr3time));
555 tty_fprintf (fp, "General key info..: ");
557 thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 :
558 info.fpr3valid? info.fpr3 : NULL);
559 /* If the fingerprint is all 0xff, the key has no asssociated
560 OpenPGP certificate. */
561 if ( thefpr && !fpr_is_ff (thefpr)
562 && !get_pubkey_byfprint (pk, thefpr, 20))
564 KBNODE keyblock = NULL;
566 print_pubkey_info (fp, pk);
568 if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
569 print_card_key_info (fp, keyblock);
570 else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
572 release_kbnode (keyblock);
573 keyblock = NULL;
575 if (!auto_create_card_key_stub (info.serialno,
576 info.fpr1valid? info.fpr1:NULL,
577 info.fpr2valid? info.fpr2:NULL,
578 info.fpr3valid? info.fpr3:NULL))
580 if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
581 print_card_key_info (fp, keyblock);
585 release_kbnode (keyblock);
587 else
588 tty_fprintf (fp, "[none]\n");
591 free_public_key (pk);
592 agent_release_card_info (&info);
596 static char *
597 get_one_name (const char *prompt1, const char *prompt2)
599 char *name;
600 int i;
602 for (;;)
604 name = cpr_get (prompt1, prompt2);
605 if (!name)
606 return NULL;
607 trim_spaces (name);
608 cpr_kill_prompt ();
609 for (i=0; name[i] && name[i] >= ' ' && name[i] <= 126; i++)
612 /* The name must be in Latin-1 and not UTF-8 - lacking the code
613 to ensure this we restrict it to ASCII. */
614 if (name[i])
615 tty_printf (_("Error: Only plain ASCII is currently allowed.\n"));
616 else if (strchr (name, '<'))
617 tty_printf (_("Error: The \"<\" character may not be used.\n"));
618 else if (strstr (name, " "))
619 tty_printf (_("Error: Double spaces are not allowed.\n"));
620 else
621 return name;
622 xfree (name);
628 static int
629 change_name (void)
631 char *surname = NULL, *givenname = NULL;
632 char *isoname, *p;
633 int rc;
635 surname = get_one_name ("keygen.smartcard.surname",
636 _("Cardholder's surname: "));
637 givenname = get_one_name ("keygen.smartcard.givenname",
638 _("Cardholder's given name: "));
639 if (!surname || !givenname || (!*surname && !*givenname))
641 xfree (surname);
642 xfree (givenname);
643 return -1; /*canceled*/
646 isoname = xmalloc ( strlen (surname) + 2 + strlen (givenname) + 1);
647 strcpy (stpcpy (stpcpy (isoname, surname), "<<"), givenname);
648 xfree (surname);
649 xfree (givenname);
650 for (p=isoname; *p; p++)
651 if (*p == ' ')
652 *p = '<';
654 if (strlen (isoname) > 39 )
656 tty_printf (_("Error: Combined name too long "
657 "(limit is %d characters).\n"), 39);
658 xfree (isoname);
659 return -1;
662 rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL );
663 if (rc)
664 log_error ("error setting Name: %s\n", gpg_strerror (rc));
666 xfree (isoname);
667 return rc;
671 static int
672 change_url (void)
674 char *url;
675 int rc;
677 url = cpr_get ("cardedit.change_url", _("URL to retrieve public key: "));
678 if (!url)
679 return -1;
680 trim_spaces (url);
681 cpr_kill_prompt ();
683 if (strlen (url) > 254 )
685 tty_printf (_("Error: URL too long "
686 "(limit is %d characters).\n"), 254);
687 xfree (url);
688 return -1;
691 rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
692 if (rc)
693 log_error ("error setting URL: %s\n", gpg_strerror (rc));
694 xfree (url);
695 return rc;
699 /* Fetch the key from the URL given on the card or try to get it from
700 the default keyserver. */
701 static int
702 fetch_url(void)
704 #if GNUPG_MAJOR_VERSION == 1
705 int rc;
706 struct agent_card_info_s info;
708 memset(&info,0,sizeof(info));
710 rc=agent_scd_getattr("PUBKEY-URL",&info);
711 if(rc)
712 log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
713 else
715 struct keyserver_spec *spec=NULL;
717 rc=agent_scd_getattr("KEY-FPR",&info);
718 if(rc)
719 log_error("error retrieving key fingerprint from card: %s\n",
720 gpg_strerror(rc));
721 else if (info.pubkey_url && *info.pubkey_url)
723 spec=parse_keyserver_uri(info.pubkey_url,1,NULL,0);
724 if(spec && info.fpr1valid)
726 /* This is not perfectly right. Currently, all card
727 fingerprints are 20 digits, but what about
728 fingerprints for a future v5 key? We should get the
729 length from somewhere lower in the code. In any
730 event, the fpr/keyid is not meaningful for straight
731 HTTP fetches, but using it allows the card to point
732 to HKP and LDAP servers as well. */
733 rc=keyserver_import_fprint(info.fpr1,20,spec);
734 free_keyserver_spec(spec);
737 else if (info.fpr1valid)
739 rc = keyserver_import_fprint (info.fpr1, 20, opt.keyserver);
743 return rc;
744 #else
745 return 0;
746 #endif
750 /* Read data from file FNAME up to MAXLEN characters. On error return
751 -1 and store NULl at R_BUFFER; on success return the number of
752 bytes read and store the address of a newly allocated buffer at
753 R_BUFFER. */
754 static int
755 get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
757 FILE *fp;
758 char *data;
759 int n;
761 *r_buffer = NULL;
763 fp = fopen (fname, "rb");
764 #if GNUPG_MAJOR_VERSION == 1
765 if (fp && is_secured_file (fileno (fp)))
767 fclose (fp);
768 fp = NULL;
769 errno = EPERM;
771 #endif
772 if (!fp)
774 tty_printf (_("can't open `%s': %s\n"), fname, strerror (errno));
775 return -1;
778 data = xtrymalloc (maxlen? maxlen:1);
779 if (!data)
781 tty_printf (_("error allocating enough memory: %s\n"), strerror (errno));
782 fclose (fp);
783 return -1;
786 if (maxlen)
787 n = fread (data, 1, maxlen, fp);
788 else
789 n = 0;
790 fclose (fp);
791 if (n < 0)
793 tty_printf (_("error reading `%s': %s\n"), fname, strerror (errno));
794 xfree (data);
795 return -1;
797 *r_buffer = data;
798 return n;
802 static int
803 change_login (const char *args)
805 char *data;
806 int n;
807 int rc;
809 if (args && *args == '<') /* Read it from a file */
811 for (args++; spacep (args); args++)
813 n = get_data_from_file (args, 254, &data);
814 if (n < 0)
815 return -1;
817 else
819 data = cpr_get ("cardedit.change_login",
820 _("Login data (account name): "));
821 if (!data)
822 return -1;
823 trim_spaces (data);
824 cpr_kill_prompt ();
825 n = strlen (data);
828 if (n > 254 )
830 tty_printf (_("Error: Login data too long "
831 "(limit is %d characters).\n"), 254);
832 xfree (data);
833 return -1;
836 rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
837 if (rc)
838 log_error ("error setting login data: %s\n", gpg_strerror (rc));
839 xfree (data);
840 return rc;
843 static int
844 change_private_do (const char *args, int nr)
846 char do_name[] = "PRIVATE-DO-X";
847 char *data;
848 int n;
849 int rc;
851 assert (nr >= 1 && nr <= 4);
852 do_name[11] = '0' + nr;
854 if (args && (args = strchr (args, '<'))) /* Read it from a file */
856 for (args++; spacep (args); args++)
858 n = get_data_from_file (args, 254, &data);
859 if (n < 0)
860 return -1;
862 else
864 data = cpr_get ("cardedit.change_private_do",
865 _("Private DO data: "));
866 if (!data)
867 return -1;
868 trim_spaces (data);
869 cpr_kill_prompt ();
870 n = strlen (data);
873 if (n > 254 )
875 tty_printf (_("Error: Private DO too long "
876 "(limit is %d characters).\n"), 254);
877 xfree (data);
878 return -1;
881 rc = agent_scd_setattr (do_name, data, n, NULL );
882 if (rc)
883 log_error ("error setting private DO: %s\n", gpg_strerror (rc));
884 xfree (data);
885 return rc;
889 static int
890 change_cert (const char *args)
892 char *data;
893 int n;
894 int rc;
896 if (args && *args == '<') /* Read it from a file */
898 for (args++; spacep (args); args++)
900 n = get_data_from_file (args, 16384, &data);
901 if (n < 0)
902 return -1;
904 else
906 tty_printf ("usage error: redirectrion to file required\n");
907 return -1;
910 rc = agent_scd_writecert ("OPENPGP.3", data, n);
911 if (rc)
912 log_error ("error writing certificate to card: %s\n", gpg_strerror (rc));
913 xfree (data);
914 return rc;
918 static int
919 change_lang (void)
921 char *data, *p;
922 int rc;
924 data = cpr_get ("cardedit.change_lang",
925 _("Language preferences: "));
926 if (!data)
927 return -1;
928 trim_spaces (data);
929 cpr_kill_prompt ();
931 if (strlen (data) > 8 || (strlen (data) & 1))
933 tty_printf (_("Error: invalid length of preference string.\n"));
934 xfree (data);
935 return -1;
938 for (p=data; *p && *p >= 'a' && *p <= 'z'; p++)
940 if (*p)
942 tty_printf (_("Error: invalid characters in preference string.\n"));
943 xfree (data);
944 return -1;
947 rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL );
948 if (rc)
949 log_error ("error setting lang: %s\n", gpg_strerror (rc));
950 xfree (data);
951 return rc;
955 static int
956 change_sex (void)
958 char *data;
959 const char *str;
960 int rc;
962 data = cpr_get ("cardedit.change_sex",
963 _("Sex ((M)ale, (F)emale or space): "));
964 if (!data)
965 return -1;
966 trim_spaces (data);
967 cpr_kill_prompt ();
969 if (!*data)
970 str = "9";
971 else if ((*data == 'M' || *data == 'm') && !data[1])
972 str = "1";
973 else if ((*data == 'F' || *data == 'f') && !data[1])
974 str = "2";
975 else
977 tty_printf (_("Error: invalid response.\n"));
978 xfree (data);
979 return -1;
982 rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
983 if (rc)
984 log_error ("error setting sex: %s\n", gpg_strerror (rc));
985 xfree (data);
986 return rc;
990 static int
991 change_cafpr (int fprno)
993 char *data;
994 const char *s;
995 int i, c, rc;
996 unsigned char fpr[20];
998 data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
999 if (!data)
1000 return -1;
1001 trim_spaces (data);
1002 cpr_kill_prompt ();
1004 for (i=0, s=data; i < 20 && *s; )
1006 while (spacep(s))
1007 s++;
1008 if (*s == ':')
1009 s++;
1010 while (spacep(s))
1011 s++;
1012 c = hextobyte (s);
1013 if (c == -1)
1014 break;
1015 fpr[i++] = c;
1016 s += 2;
1018 xfree (data);
1019 if (i != 20 || *s)
1021 tty_printf (_("Error: invalid formatted fingerprint.\n"));
1022 return -1;
1025 rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
1026 fprno==2?"CA-FPR-2":
1027 fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
1028 if (rc)
1029 log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
1030 return rc;
1035 static void
1036 toggle_forcesig (void)
1038 struct agent_card_info_s info;
1039 int rc;
1040 int newstate;
1042 memset (&info, 0, sizeof info);
1043 rc = agent_scd_getattr ("CHV-STATUS", &info);
1044 if (rc)
1046 log_error ("error getting current status: %s\n", gpg_strerror (rc));
1047 return;
1049 newstate = !info.chv1_cached;
1050 agent_release_card_info (&info);
1052 rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL);
1053 if (rc)
1054 log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
1058 /* Helper for the key generation/edit functions. */
1059 static int
1060 get_info_for_key_operation (struct agent_card_info_s *info)
1062 int rc;
1064 memset (info, 0, sizeof *info);
1065 rc = agent_scd_getattr ("SERIALNO", info);
1066 if (rc || !info->serialno || strncmp (info->serialno, "D27600012401", 12)
1067 || strlen (info->serialno) != 32 )
1069 log_error (_("key operation not possible: %s\n"),
1070 rc ? gpg_strerror (rc) : _("not an OpenPGP card"));
1071 return rc? rc: -1;
1073 rc = agent_scd_getattr ("KEY-FPR", info);
1074 if (!rc)
1075 rc = agent_scd_getattr ("CHV-STATUS", info);
1076 if (!rc)
1077 rc = agent_scd_getattr ("DISP-NAME", info);
1078 if (rc)
1079 log_error (_("error getting current key info: %s\n"), gpg_strerror (rc));
1080 return rc;
1084 /* Helper for the key generation/edit functions. */
1085 static int
1086 check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
1088 int rc = 0;
1090 agent_clear_pin_cache (info->serialno);
1092 *forced_chv1 = !info->chv1_cached;
1093 if (*forced_chv1)
1094 { /* Switch off the forced mode so that during key generation we
1095 don't get bothered with PIN queries for each
1096 self-signature. */
1097 rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
1098 if (rc)
1100 log_error ("error clearing forced signature PIN flag: %s\n",
1101 gpg_strerror (rc));
1102 *forced_chv1 = 0;
1106 if (!rc)
1108 /* Check the PIN now, so that we won't get asked later for each
1109 binding signature. */
1110 rc = agent_scd_checkpin (info->serialno);
1111 if (rc)
1112 log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
1114 return rc;
1117 /* Helper for the key generation/edit functions. */
1118 static void
1119 restore_forced_chv1 (int *forced_chv1)
1121 int rc;
1123 if (*forced_chv1)
1124 { /* Switch back to forced state. */
1125 rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL);
1126 if (rc)
1128 log_error ("error setting forced signature PIN flag: %s\n",
1129 gpg_strerror (rc));
1135 /* Helper for the key generation/edit functions. */
1136 static void
1137 show_card_key_info (struct agent_card_info_s *info)
1139 tty_fprintf (NULL, "Signature key ....:");
1140 print_sha1_fpr (NULL, info->fpr1valid? info->fpr1:NULL);
1141 tty_fprintf (NULL, "Encryption key....:");
1142 print_sha1_fpr (NULL, info->fpr2valid? info->fpr2:NULL);
1143 tty_fprintf (NULL, "Authentication key:");
1144 print_sha1_fpr (NULL, info->fpr3valid? info->fpr3:NULL);
1145 tty_printf ("\n");
1149 /* Helper for the key generation/edit functions. */
1150 static int
1151 replace_existing_key_p (struct agent_card_info_s *info, int keyno)
1153 assert (keyno >= 0 && keyno <= 3);
1155 if ((keyno == 1 && info->fpr1valid)
1156 || (keyno == 2 && info->fpr2valid)
1157 || (keyno == 3 && info->fpr3valid))
1159 tty_printf ("\n");
1160 log_info ("WARNING: such a key has already been stored on the card!\n");
1161 tty_printf ("\n");
1162 if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_key",
1163 _("Replace existing key? (y/N) ")))
1164 return -1;
1166 return 0;
1170 static void
1171 generate_card_keys (void)
1173 struct agent_card_info_s info;
1174 int forced_chv1;
1175 int want_backup;
1177 if (get_info_for_key_operation (&info))
1178 return;
1180 #if GNUPG_MAJOR_VERSION == 1
1182 char *answer=cpr_get("cardedit.genkeys.backup_enc",
1183 _("Make off-card backup of encryption key? (Y/n) "));
1185 want_backup=answer_is_yes_no_default(answer,1);
1186 cpr_kill_prompt();
1187 xfree(answer);
1189 #else
1190 want_backup = cpr_get_answer_is_yes
1191 ( "cardedit.genkeys.backup_enc",
1192 _("Make off-card backup of encryption key? (Y/n) "));
1193 /*FIXME: we need answer_is_yes_no_default()*/
1194 #endif
1196 if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
1197 || (info.fpr2valid && !fpr_is_zero (info.fpr2))
1198 || (info.fpr3valid && !fpr_is_zero (info.fpr3)))
1200 tty_printf ("\n");
1201 log_info ("NOTE: keys are already stored on the card!\n");
1202 tty_printf ("\n");
1203 if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_keys",
1204 _("Replace existing keys? (y/N) ")))
1206 agent_release_card_info (&info);
1207 return;
1210 else if (!info.disp_name || !*info.disp_name)
1212 tty_printf ("\n");
1213 tty_printf (_("Please note that the factory settings of the PINs are\n"
1214 " PIN = `%s' Admin PIN = `%s'\n"
1215 "You should change them using the command --change-pin\n"),
1216 "123456", "12345678");
1217 tty_printf ("\n");
1220 if (check_pin_for_key_operation (&info, &forced_chv1))
1221 goto leave;
1223 generate_keypair (NULL, info.serialno,
1224 want_backup? opt.homedir:NULL);
1226 leave:
1227 agent_release_card_info (&info);
1228 restore_forced_chv1 (&forced_chv1);
1232 /* This function is used by the key edit menu to generate an arbitrary
1233 subkey. */
1235 card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
1237 struct agent_card_info_s info;
1238 int okay = 0;
1239 int forced_chv1 = 0;
1240 int keyno;
1242 if (get_info_for_key_operation (&info))
1243 return 0;
1245 show_card_key_info (&info);
1247 tty_printf (_("Please select the type of key to generate:\n"));
1249 tty_printf (_(" (1) Signature key\n"));
1250 tty_printf (_(" (2) Encryption key\n"));
1251 tty_printf (_(" (3) Authentication key\n"));
1253 for (;;)
1255 char *answer = cpr_get ("cardedit.genkeys.subkeytype",
1256 _("Your selection? "));
1257 cpr_kill_prompt();
1258 if (*answer == CONTROL_D)
1260 xfree (answer);
1261 goto leave;
1263 keyno = *answer? atoi(answer): 0;
1264 xfree(answer);
1265 if (keyno >= 1 && keyno <= 3)
1266 break; /* Okay. */
1267 tty_printf(_("Invalid selection.\n"));
1270 if (replace_existing_key_p (&info, keyno))
1271 goto leave;
1273 if (check_pin_for_key_operation (&info, &forced_chv1))
1274 goto leave;
1276 okay = generate_card_subkeypair (pub_keyblock, sec_keyblock,
1277 keyno, info.serialno);
1279 leave:
1280 agent_release_card_info (&info);
1281 restore_forced_chv1 (&forced_chv1);
1282 return okay;
1286 /* Store the key at NODE into the smartcard and modify NODE to
1287 carry the serialno stuff instead of the actual secret key
1288 parameters. USE is the usage for that key; 0 means any
1289 usage. */
1290 int
1291 card_store_subkey (KBNODE node, int use)
1293 struct agent_card_info_s info;
1294 int okay = 0;
1295 int rc;
1296 int keyno, i;
1297 PKT_secret_key *copied_sk = NULL;
1298 PKT_secret_key *sk;
1299 size_t n;
1300 const char *s;
1301 int allow_keyno[3];
1303 assert (node->pkt->pkttype == PKT_SECRET_KEY
1304 || node->pkt->pkttype == PKT_SECRET_SUBKEY);
1305 sk = node->pkt->pkt.secret_key;
1307 if (get_info_for_key_operation (&info))
1308 return 0;
1310 show_card_key_info (&info);
1312 if (!is_RSA (sk->pubkey_algo) || nbits_from_sk (sk) != 1024 )
1314 tty_printf ("You may only store a 1024 bit RSA key on the card\n");
1315 tty_printf ("\n");
1316 goto leave;
1319 allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG)));
1320 allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC)));
1321 allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)));
1323 tty_printf (_("Please select where to store the key:\n"));
1325 if (allow_keyno[0])
1326 tty_printf (_(" (1) Signature key\n"));
1327 if (allow_keyno[1])
1328 tty_printf (_(" (2) Encryption key\n"));
1329 if (allow_keyno[2])
1330 tty_printf (_(" (3) Authentication key\n"));
1332 for (;;)
1334 char *answer = cpr_get ("cardedit.genkeys.storekeytype",
1335 _("Your selection? "));
1336 cpr_kill_prompt();
1337 if (*answer == CONTROL_D || !*answer)
1339 xfree (answer);
1340 goto leave;
1342 keyno = *answer? atoi(answer): 0;
1343 xfree(answer);
1344 if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1])
1345 break; /* Okay. */
1346 tty_printf(_("Invalid selection.\n"));
1349 if (replace_existing_key_p (&info, keyno))
1350 goto leave;
1352 /* Unprotect key. */
1353 switch (is_secret_key_protected (sk) )
1355 case 0: /* Not protected. */
1356 break;
1357 case -1:
1358 log_error (_("unknown key protection algorithm\n"));
1359 goto leave;
1360 default:
1361 if (sk->protect.s2k.mode == 1001)
1363 log_error (_("secret parts of key are not available\n"));
1364 goto leave;
1366 if (sk->protect.s2k.mode == 1002)
1368 log_error (_("secret key already stored on a card\n"));
1369 goto leave;
1371 /* We better copy the key before we unprotect it. */
1372 copied_sk = sk = copy_secret_key (NULL, sk);
1373 rc = check_secret_key (sk, 0);
1374 if (rc)
1375 goto leave;
1378 rc = save_unprotected_key_to_card (sk, keyno);
1379 if (rc)
1380 goto leave;
1382 /* Get back to the maybe protected original secret key. */
1383 if (copied_sk)
1385 free_secret_key (copied_sk);
1386 copied_sk = NULL;
1388 sk = node->pkt->pkt.secret_key;
1390 /* Get rid of the secret key parameters and store the serial numer. */
1391 n = pubkey_get_nskey (sk->pubkey_algo);
1392 for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++)
1394 gcry_mpi_release (sk->skey[i]);
1395 sk->skey[i] = NULL;
1397 i = pubkey_get_npkey (sk->pubkey_algo);
1398 sk->skey[i] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
1399 sk->is_protected = 1;
1400 sk->protect.s2k.mode = 1002;
1401 s = info.serialno;
1402 for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
1403 sk->protect.ivlen++, s += 2)
1404 sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
1406 okay = 1;
1408 leave:
1409 if (copied_sk)
1410 free_secret_key (copied_sk);
1411 agent_release_card_info (&info);
1412 return okay;
1417 /* Data used by the command parser. This needs to be outside of the
1418 function scope to allow readline based command completion. */
1419 enum cmdids
1421 cmdNOP = 0,
1422 cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
1423 cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
1424 cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
1425 cmdUNBLOCK,
1426 cmdINVCMD
1429 static struct
1431 const char *name;
1432 enum cmdids id;
1433 int admin_only;
1434 const char *desc;
1435 } cmds[] =
1437 { "quit" , cmdQUIT , 0, N_("quit this menu")},
1438 { "q" , cmdQUIT , 0, NULL },
1439 { "admin" , cmdADMIN , 0, N_("show admin commands")},
1440 { "help" , cmdHELP , 0, N_("show this help")},
1441 { "?" , cmdHELP , 0, NULL },
1442 { "list" , cmdLIST , 0, N_("list all available data")},
1443 { "l" , cmdLIST , 0, NULL },
1444 { "debug" , cmdDEBUG , 0, NULL },
1445 { "name" , cmdNAME , 1, N_("change card holder's name")},
1446 { "url" , cmdURL , 1, N_("change URL to retrieve key")},
1447 { "fetch" , cmdFETCH , 0, N_("fetch the key specified in the card URL")},
1448 { "login" , cmdLOGIN , 1, N_("change the login name")},
1449 { "lang" , cmdLANG , 1, N_("change the language preferences")},
1450 { "sex" , cmdSEX , 1, N_("change card holder's sex")},
1451 { "cafpr" , cmdCAFPR , 1, N_("change a CA fingerprint")},
1452 { "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")},
1453 { "generate", cmdGENERATE, 1, N_("generate new keys")},
1454 { "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
1455 { "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
1456 { "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") },
1457 /* Note, that we do not announce these command yet. */
1458 { "privatedo", cmdPRIVATEDO, 0, NULL },
1459 { "writecert", cmdWRITECERT, 1, NULL },
1460 { NULL, cmdINVCMD, 0, NULL }
1464 #if GNUPG_MAJOR_VERSION == 1 && defined (HAVE_LIBREADLINE)
1466 /* These two functions are used by readline for command completion. */
1468 static char *
1469 command_generator(const char *text,int state)
1471 static int list_index,len;
1472 const char *name;
1474 /* If this is a new word to complete, initialize now. This includes
1475 saving the length of TEXT for efficiency, and initializing the
1476 index variable to 0. */
1477 if(!state)
1479 list_index=0;
1480 len=strlen(text);
1483 /* Return the next partial match */
1484 while((name=cmds[list_index].name))
1486 /* Only complete commands that have help text */
1487 if(cmds[list_index++].desc && strncmp(name,text,len)==0)
1488 return strdup(name);
1491 return NULL;
1494 static char **
1495 card_edit_completion(const char *text, int start, int end)
1497 /* If we are at the start of a line, we try and command-complete.
1498 If not, just do nothing for now. */
1500 if(start==0)
1501 return rl_completion_matches(text,command_generator);
1503 rl_attempted_completion_over=1;
1505 return NULL;
1507 #endif /* GNUPG_MAJOR_VERSION == 1 && HAVE_LIBREADLINE */
1509 /* Menu to edit all user changeable values on an OpenPGP card. Only
1510 Key creation is not handled here. */
1511 void
1512 card_edit (strlist_t commands)
1514 enum cmdids cmd = cmdNOP;
1515 int have_commands = !!commands;
1516 int redisplay = 1;
1517 char *answer = NULL;
1518 int did_checkpin = 0, allow_admin=0;
1519 char serialnobuf[50];
1522 if (opt.command_fd != -1)
1524 else if (opt.batch && !have_commands)
1526 log_error(_("can't do this in batch mode\n"));
1527 goto leave;
1530 for (;;)
1532 int arg_number;
1533 const char *arg_string = "";
1534 const char *arg_rest = "";
1535 char *p;
1536 int i;
1537 int cmd_admin_only;
1539 tty_printf("\n");
1540 if (redisplay )
1542 if (opt.with_colons)
1544 card_status (stdout, serialnobuf, DIM (serialnobuf));
1545 fflush (stdout);
1547 else
1549 card_status (NULL, serialnobuf, DIM (serialnobuf));
1550 tty_printf("\n");
1552 redisplay = 0;
1557 xfree (answer);
1558 if (have_commands)
1560 if (commands)
1562 answer = xstrdup (commands->d);
1563 commands = commands->next;
1565 else if (opt.batch)
1567 answer = xstrdup ("quit");
1569 else
1570 have_commands = 0;
1573 if (!have_commands)
1575 #if GNUPG_MAJOR_VERSION == 1
1576 tty_enable_completion (card_edit_completion);
1577 #endif
1578 answer = cpr_get_no_help("cardedit.prompt", _("Command> "));
1579 cpr_kill_prompt();
1580 #if GNUPG_MAJOR_VERSION == 1
1581 tty_disable_completion ();
1582 #endif
1584 trim_spaces(answer);
1586 while ( *answer == '#' );
1588 arg_number = 0; /* Yes, here is the init which egcc complains about */
1589 cmd_admin_only = 0;
1590 if (!*answer)
1591 cmd = cmdLIST; /* Default to the list command */
1592 else if (*answer == CONTROL_D)
1593 cmd = cmdQUIT;
1594 else
1596 if ((p=strchr (answer,' ')))
1598 *p++ = 0;
1599 trim_spaces (answer);
1600 trim_spaces (p);
1601 arg_number = atoi(p);
1602 arg_string = p;
1603 arg_rest = p;
1604 while (digitp (arg_rest))
1605 arg_rest++;
1606 while (spacep (arg_rest))
1607 arg_rest++;
1610 for (i=0; cmds[i].name; i++ )
1611 if (!ascii_strcasecmp (answer, cmds[i].name ))
1612 break;
1614 cmd = cmds[i].id;
1615 cmd_admin_only = cmds[i].admin_only;
1618 if (!allow_admin && cmd_admin_only)
1620 tty_printf ("\n");
1621 tty_printf (_("Admin-only command\n"));
1622 continue;
1625 switch (cmd)
1627 case cmdHELP:
1628 for (i=0; cmds[i].name; i++ )
1629 if(cmds[i].desc
1630 && (!cmds[i].admin_only || (cmds[i].admin_only && allow_admin)))
1631 tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1632 break;
1634 case cmdADMIN:
1635 if ( !strcmp (arg_string, "on") )
1636 allow_admin = 1;
1637 else if ( !strcmp (arg_string, "off") )
1638 allow_admin = 0;
1639 else if ( !strcmp (arg_string, "verify") )
1641 /* Force verification of the Admin Command. However,
1642 this is only done if the retry counter is at initial
1643 state. */
1644 char *tmp = xmalloc (strlen (serialnobuf) + 6 + 1);
1645 strcpy (stpcpy (tmp, serialnobuf), "[CHV3]");
1646 allow_admin = !agent_scd_checkpin (tmp);
1647 xfree (tmp);
1649 else /* Toggle. */
1650 allow_admin=!allow_admin;
1651 if(allow_admin)
1652 tty_printf(_("Admin commands are allowed\n"));
1653 else
1654 tty_printf(_("Admin commands are not allowed\n"));
1655 break;
1657 case cmdVERIFY:
1658 agent_scd_checkpin (serialnobuf);
1659 redisplay = 1;
1660 break;
1662 case cmdLIST:
1663 redisplay = 1;
1664 break;
1666 case cmdNAME:
1667 change_name ();
1668 break;
1670 case cmdURL:
1671 change_url ();
1672 break;
1674 case cmdFETCH:
1675 fetch_url();
1676 break;
1678 case cmdLOGIN:
1679 change_login (arg_string);
1680 break;
1682 case cmdLANG:
1683 change_lang ();
1684 break;
1686 case cmdSEX:
1687 change_sex ();
1688 break;
1690 case cmdCAFPR:
1691 if ( arg_number < 1 || arg_number > 3 )
1692 tty_printf ("usage: cafpr N\n"
1693 " 1 <= N <= 3\n");
1694 else
1695 change_cafpr (arg_number);
1696 break;
1698 case cmdPRIVATEDO:
1699 if ( arg_number < 1 || arg_number > 4 )
1700 tty_printf ("usage: privatedo N\n"
1701 " 1 <= N <= 4\n");
1702 else
1703 change_private_do (arg_string, arg_number);
1704 break;
1706 case cmdWRITECERT:
1707 if ( arg_number != 3 )
1708 tty_printf ("usage: writecert 3 < FILE\n");
1709 else
1710 change_cert (arg_rest);
1711 break;
1713 case cmdFORCESIG:
1714 toggle_forcesig ();
1715 break;
1717 case cmdGENERATE:
1718 generate_card_keys ();
1719 break;
1721 case cmdPASSWD:
1722 change_pin (0, allow_admin);
1723 did_checkpin = 0; /* Need to reset it of course. */
1724 break;
1726 case cmdUNBLOCK:
1727 change_pin (1, allow_admin);
1728 did_checkpin = 0; /* Need to reset it of course. */
1729 break;
1731 case cmdQUIT:
1732 goto leave;
1734 case cmdNOP:
1735 break;
1737 case cmdINVCMD:
1738 default:
1739 tty_printf ("\n");
1740 tty_printf (_("Invalid command (try \"help\")\n"));
1741 break;
1742 } /* End command switch. */
1743 } /* End of main menu loop. */
1745 leave:
1746 xfree (answer);