Changed to GPLv3.
[gnupg.git] / g10 / card-util.c
1 /* card-util.c - Utility functions for the OpenPGP card.
2  *      Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <assert.h>
26
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*/
47
48 #define CONTROL_D ('D' - 'A' + 1)
49
50
51 /* Change the PIN of a an OpenPGP card.  This is an interactive
52    function. */
53 void
54 change_pin (int chvno, int allow_admin)
55 {
56   struct agent_card_info_s info;
57   int rc;
58
59   rc = agent_learn (&info);
60   if (rc)
61     {
62       log_error (_("OpenPGP card not available: %s\n"),
63                   gpg_strerror (rc));
64       return;
65     }
66   
67   log_info (_("OpenPGP card no. %s detected\n"),
68               info.serialno? info.serialno : "[none]");
69
70   agent_clear_pin_cache (info.serialno);
71
72   if (opt.batch)
73     {
74       agent_release_card_info (&info);
75       log_error (_("can't do this in batch mode\n"));
76       return;
77     }
78
79   if(!allow_admin)
80     {
81       rc = agent_scd_change_pin (1, info.serialno);
82       if (rc)
83         tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
84       else
85         {
86           write_status (STATUS_SC_OP_SUCCESS);
87           tty_printf ("PIN changed.\n");
88         }
89     }
90   else
91     for (;;)
92       {
93         char *answer;
94
95         tty_printf ("\n");
96         tty_printf ("1 - change PIN\n"
97                     "2 - unblock PIN\n"
98                     "3 - change Admin PIN\n"
99                     "Q - quit\n");
100         tty_printf ("\n");
101
102         answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
103         cpr_kill_prompt();
104         if (strlen (answer) != 1)
105           continue;
106
107         rc = 0;
108         if (*answer == '1')
109           {
110             rc = agent_scd_change_pin (1, info.serialno);
111             if (rc)
112               tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
113             else
114               {
115                 write_status (STATUS_SC_OP_SUCCESS);
116                 tty_printf ("PIN changed.\n");
117               }
118           }
119         else if (*answer == '2')
120           {
121             rc = agent_scd_change_pin (101, info.serialno);
122             if (rc)
123               tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
124             else
125               {
126                 write_status (STATUS_SC_OP_SUCCESS);
127                 tty_printf ("PIN unblocked and new PIN set.\n");
128               }
129           }
130         else if (*answer == '3')
131           {
132             rc = agent_scd_change_pin (3, info.serialno);
133             if (rc)
134               tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
135             else
136               {
137                 write_status (STATUS_SC_OP_SUCCESS);
138                 tty_printf ("PIN changed.\n");
139               }
140           }
141         else if (*answer == 'q' || *answer == 'Q')
142           {
143             break;
144           }
145       }
146
147   agent_release_card_info (&info);
148 }
149
150 static const char *
151 get_manufacturer (unsigned int no)
152 {
153   /* Note:  Make sure that there is no colon or linefeed in the string. */
154   switch (no)
155     {
156     case 0:
157     case 0xffff: return "test card";
158     case 0x0001: return "PPC Card Systems";
159     case 0x0002: return "Prism";
160     case 0x0003: return "OpenFortress";
161     default: return "unknown";
162     }
163 }
164
165
166 static void
167 print_sha1_fpr (FILE *fp, const unsigned char *fpr)
168 {
169   int i;
170
171   if (fpr)
172     {
173       for (i=0; i < 20 ; i+=2, fpr += 2 )
174         {
175           if (i == 10 )
176             tty_fprintf (fp, " ");
177           tty_fprintf (fp, " %02X%02X", *fpr, fpr[1]);
178         }
179     }
180   else
181     tty_fprintf (fp, " [none]");
182   tty_fprintf (fp, "\n");
183 }
184
185
186 static void
187 print_sha1_fpr_colon (FILE *fp, const unsigned char *fpr)
188 {
189   int i;
190
191   if (fpr)
192     {
193       for (i=0; i < 20 ; i++, fpr++)
194         fprintf (fp, "%02X", *fpr);
195     }
196   putc (':', fp);
197 }
198
199
200 static void
201 print_name (FILE *fp, const char *text, const char *name)
202 {
203   tty_fprintf (fp, "%s", text);
204
205   /* FIXME: tty_printf_utf8_string2 eats everything after and
206      including an @ - e.g. when printing an url. */
207   if (name && *name)
208     {
209       if (fp)
210         print_utf8_string2 (fp, name, strlen (name), '\n');
211       else
212         tty_print_utf8_string2 (name, strlen (name), 0);
213     }
214   else
215     tty_fprintf (fp, _("[not set]"));
216   tty_fprintf (fp, "\n");
217 }
218
219 static void
220 print_isoname (FILE *fp, const char *text, const char *tag, const char *name)
221 {
222   if (opt.with_colons)
223     fprintf (fp, "%s:", tag);
224   else
225     tty_fprintf (fp, "%s", text);
226
227   if (name && *name)
228     {
229       char *p, *given, *buf = xstrdup (name);
230
231       given = strstr (buf, "<<");
232       for (p=buf; *p; p++)
233         if (*p == '<')
234           *p = ' ';
235       if (given && given[2])
236         {
237           *given = 0;
238           given += 2;
239           if (opt.with_colons)
240             print_string (fp, given, strlen (given), ':');
241           else if (fp)
242             print_utf8_string2 (fp, given, strlen (given), '\n');
243           else
244             tty_print_utf8_string2 (given, strlen (given), 0);
245
246           if (opt.with_colons)
247             putc (':', fp);
248           else if (*buf)
249             tty_fprintf (fp, " ");
250         }
251
252       if (opt.with_colons)
253         print_string (fp, buf, strlen (buf), ':');
254       else if (fp)
255         print_utf8_string2 (fp, buf, strlen (buf), '\n');
256       else
257         tty_print_utf8_string2 (buf, strlen (buf), 0);
258       xfree (buf);
259     }
260   else
261     {
262       if (opt.with_colons)
263         putc (':', fp);
264       else
265         tty_fprintf (fp, _("[not set]"));
266     }
267
268   if (opt.with_colons)
269     fputs (":\n", fp);
270   else
271     tty_fprintf (fp, "\n");
272 }
273
274 /* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
275 static int
276 fpr_is_zero (const char *fpr)
277 {
278   int i;
279
280   for (i=0; i < 20 && !fpr[i]; i++)
281     ;
282   return (i == 20);
283 }
284
285
286 /* Print all available information about the current card. */
287 void
288 card_status (FILE *fp, char *serialno, size_t serialnobuflen)
289 {
290   struct agent_card_info_s info;
291   PKT_public_key *pk = xcalloc (1, sizeof *pk);
292   int rc;
293   unsigned int uval;
294   const unsigned char *thefpr;
295   int i;
296
297   if (serialno && serialnobuflen)
298     *serialno = 0;
299
300   rc = agent_learn (&info);
301   if (rc)
302     {
303       if (opt.with_colons)
304         fputs ("AID:::\n", fp);
305       log_error (_("OpenPGP card not available: %s\n"),
306                   gpg_strerror (rc));
307       xfree (pk);
308       return;
309     }
310
311   if (opt.with_colons)
312     fprintf (fp, "AID:%s:", info.serialno? info.serialno : "");
313   else
314     tty_fprintf (fp, "Application ID ...: %s\n",
315                  info.serialno? info.serialno : "[none]");
316   if (!info.serialno || strncmp (info.serialno, "D27600012401", 12) 
317       || strlen (info.serialno) != 32 )
318     {
319       if (opt.with_colons)
320         fputs ("unknown:\n", fp);
321       log_info ("not an OpenPGP card\n");
322       agent_release_card_info (&info);
323       xfree (pk);
324       return;
325     }
326
327   if (!serialno)
328     ;
329   else if (strlen (serialno)+1 > serialnobuflen)
330     log_error ("serial number longer than expected\n");
331   else 
332     strcpy (serialno, info.serialno);
333
334   if (opt.with_colons)
335     fputs ("openpgp-card:\n", fp);
336
337
338   if (opt.with_colons)
339     {
340       fprintf (fp, "version:%.4s:\n", info.serialno+12);
341       uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18);
342       fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval));
343       fprintf (fp, "serial:%.8s:\n", info.serialno+20);
344       
345       print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
346
347       fputs ("lang:", fp);
348       if (info.disp_lang)
349         print_string (fp, info.disp_lang, strlen (info.disp_lang), ':');
350       fputs (":\n", fp);
351
352       fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm':
353                                  info.disp_sex == 2? 'f' : 'u'));
354
355       fputs ("url:", fp);
356       if (info.pubkey_url)
357         print_string (fp, info.pubkey_url, strlen (info.pubkey_url), ':');
358       fputs (":\n", fp);
359
360       fputs ("login:", fp);
361       if (info.login_data)
362         print_string (fp, info.login_data, strlen (info.login_data), ':');
363       fputs (":\n", fp);
364
365       fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
366       fprintf (fp, "maxpinlen:%d:%d:%d:\n",
367                    info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
368       fprintf (fp, "pinretry:%d:%d:%d:\n",
369                    info.chvretry[0], info.chvretry[1], info.chvretry[2]);
370       fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
371
372       for (i=0; i < 4; i++)
373         {
374           if (info.private_do[i])
375             {
376               fprintf (fp, "private_do:%d:", i+1);
377               print_string (fp, info.private_do[i],
378                             strlen (info.private_do[i]), ':');
379               fputs (":\n", fp);
380             }
381         }
382
383       fputs ("cafpr:", fp);
384       print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
385       print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
386       print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL);
387       putc ('\n', fp);
388       fputs ("fpr:", fp);
389       print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
390       print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
391       print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
392       putc ('\n', fp);
393       fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
394                (unsigned long)info.fpr1time, (unsigned long)info.fpr2time,
395                (unsigned long)info.fpr3time);
396     }
397   else 
398     {
399       tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n",
400                    info.serialno[12] == '0'?"":info.serialno+12,
401                    info.serialno[13],
402                    info.serialno[14] == '0'?"":info.serialno+14,
403                    info.serialno[15]);
404       tty_fprintf (fp, "Manufacturer .....: %s\n", 
405                    get_manufacturer (xtoi_2(info.serialno+16)*256
406                                      + xtoi_2 (info.serialno+18)));
407       tty_fprintf (fp, "Serial number ....: %.8s\n", info.serialno+20);
408       
409       print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
410       print_name (fp, "Language prefs ...: ", info.disp_lang);
411       tty_fprintf (fp,    "Sex ..............: %s\n",
412                    info.disp_sex == 1? _("male"):
413                    info.disp_sex == 2? _("female") : _("unspecified"));
414       print_name (fp, "URL of public key : ", info.pubkey_url);
415       print_name (fp, "Login data .......: ", info.login_data);
416       if (info.private_do[0])
417         print_name (fp, "Private DO 1 .....: ", info.private_do[0]);
418       if (info.private_do[1])
419         print_name (fp, "Private DO 2 .....: ", info.private_do[1]);
420       if (info.private_do[2])
421         print_name (fp, "Private DO 3 .....: ", info.private_do[2]);
422       if (info.private_do[3])
423         print_name (fp, "Private DO 4 .....: ", info.private_do[3]);
424       if (info.cafpr1valid)
425         {
426           tty_fprintf (fp, "CA fingerprint %d .:", 1);
427           print_sha1_fpr (fp, info.cafpr1);
428         }
429       if (info.cafpr2valid)
430         {
431           tty_fprintf (fp, "CA fingerprint %d .:", 2);
432           print_sha1_fpr (fp, info.cafpr2);
433         }
434       if (info.cafpr3valid)
435         {
436           tty_fprintf (fp, "CA fingerprint %d .:", 3);
437           print_sha1_fpr (fp, info.cafpr3);
438         }
439       tty_fprintf (fp,    "Signature PIN ....: %s\n",
440                    info.chv1_cached? _("not forced"): _("forced"));
441       tty_fprintf (fp,    "Max. PIN lengths .: %d %d %d\n",
442                    info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
443       tty_fprintf (fp,    "PIN retry counter : %d %d %d\n",
444                    info.chvretry[0], info.chvretry[1], info.chvretry[2]);
445       tty_fprintf (fp,    "Signature counter : %lu\n", info.sig_counter);
446       tty_fprintf (fp, "Signature key ....:");
447       print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
448       if (info.fpr1valid && info.fpr1time)
449         tty_fprintf (fp, "      created ....: %s\n",
450                      isotimestamp (info.fpr1time));
451       tty_fprintf (fp, "Encryption key....:");
452       print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
453       if (info.fpr2valid && info.fpr2time)
454         tty_fprintf (fp, "      created ....: %s\n",
455                      isotimestamp (info.fpr2time));
456       tty_fprintf (fp, "Authentication key:");
457       print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
458       if (info.fpr3valid && info.fpr3time)
459         tty_fprintf (fp, "      created ....: %s\n",
460                      isotimestamp (info.fpr3time));
461       tty_fprintf (fp, "General key info..: "); 
462
463       thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 : 
464                 info.fpr3valid? info.fpr3 : NULL);
465       if ( thefpr && !get_pubkey_byfprint (pk, thefpr, 20))
466         {
467           KBNODE keyblock = NULL;
468
469           print_pubkey_info (fp, pk);
470
471           if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
472             print_card_key_info (fp, keyblock);
473           else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
474             {
475               release_kbnode (keyblock);
476               keyblock = NULL;
477               
478               if (!auto_create_card_key_stub (info.serialno,
479                                               info.fpr1valid? info.fpr1:NULL,
480                                               info.fpr2valid? info.fpr2:NULL,
481                                               info.fpr3valid? info.fpr3:NULL))
482                 {
483                   if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
484                     print_card_key_info (fp, keyblock);
485                 }
486             }
487
488           release_kbnode (keyblock);
489         }
490       else
491         tty_fprintf (fp, "[none]\n");
492     }
493       
494   free_public_key (pk);
495   agent_release_card_info (&info);
496 }
497
498
499 static char *
500 get_one_name (const char *prompt1, const char *prompt2)
501 {
502   char *name;
503   int i;
504
505   for (;;)
506     {
507       name = cpr_get (prompt1, prompt2);
508       if (!name)
509         return NULL;
510       trim_spaces (name);
511       cpr_kill_prompt ();
512       for (i=0; name[i] && name[i] >= ' ' && name[i] <= 126; i++)
513         ;
514
515       /* The name must be in Latin-1 and not UTF-8 - lacking the code
516          to ensure this we restrict it to ASCII. */
517       if (name[i])
518         tty_printf (_("Error: Only plain ASCII is currently allowed.\n"));
519       else if (strchr (name, '<'))
520         tty_printf (_("Error: The \"<\" character may not be used.\n"));
521       else if (strstr (name, "  "))
522         tty_printf (_("Error: Double spaces are not allowed.\n"));    
523       else
524         return name;
525       xfree (name);
526     }
527 }
528
529
530
531 static int
532 change_name (void)
533 {
534   char *surname = NULL, *givenname = NULL;
535   char *isoname, *p;
536   int rc;
537
538   surname = get_one_name ("keygen.smartcard.surname",
539                                     _("Cardholder's surname: "));
540   givenname = get_one_name ("keygen.smartcard.givenname",
541                                        _("Cardholder's given name: "));
542   if (!surname || !givenname || (!*surname && !*givenname))
543     {
544       xfree (surname);
545       xfree (givenname);
546       return -1; /*canceled*/
547     }
548
549   isoname = xmalloc ( strlen (surname) + 2 + strlen (givenname) + 1);
550   strcpy (stpcpy (stpcpy (isoname, surname), "<<"), givenname);
551   xfree (surname);
552   xfree (givenname);
553   for (p=isoname; *p; p++)
554     if (*p == ' ')
555       *p = '<';
556
557   if (strlen (isoname) > 39 )
558     {
559       tty_printf (_("Error: Combined name too long "
560                     "(limit is %d characters).\n"), 39);    
561       xfree (isoname);
562       return -1;
563     }
564
565   rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL );
566   if (rc)
567     log_error ("error setting Name: %s\n", gpg_strerror (rc));
568
569   xfree (isoname);
570   return rc;
571 }
572
573
574 static int
575 change_url (void)
576 {
577   char *url;
578   int rc;
579
580   url = cpr_get ("cardedit.change_url", _("URL to retrieve public key: "));
581   if (!url)
582     return -1;
583   trim_spaces (url);
584   cpr_kill_prompt ();
585
586   if (strlen (url) > 254 )
587     {
588       tty_printf (_("Error: URL too long "
589                     "(limit is %d characters).\n"), 254);    
590       xfree (url);
591       return -1;
592     }
593
594   rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
595   if (rc)
596     log_error ("error setting URL: %s\n", gpg_strerror (rc));
597   xfree (url);
598   return rc;
599 }
600
601
602 /* Fetch the key from the URL given on the card or try to get it from
603    the default keyserver.  */
604 static int
605 fetch_url(void)
606 {
607 #if GNUPG_MAJOR_VERSION == 1
608   int rc;
609   struct agent_card_info_s info;
610
611   memset(&info,0,sizeof(info));
612
613   rc=agent_scd_getattr("PUBKEY-URL",&info);
614   if(rc)
615     log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
616   else
617     {
618       struct keyserver_spec *spec=NULL;
619
620       rc=agent_scd_getattr("KEY-FPR",&info);
621       if(rc)
622         log_error("error retrieving key fingerprint from card: %s\n",
623                   gpg_strerror(rc));
624       else if (info.pubkey_url && *info.pubkey_url)
625         {
626           spec=parse_keyserver_uri(info.pubkey_url,1,NULL,0);
627           if(spec && info.fpr1valid)
628             {
629               /* This is not perfectly right.  Currently, all card
630                  fingerprints are 20 digits, but what about
631                  fingerprints for a future v5 key?  We should get the
632                  length from somewhere lower in the code.  In any
633                  event, the fpr/keyid is not meaningful for straight
634                  HTTP fetches, but using it allows the card to point
635                  to HKP and LDAP servers as well. */
636               rc=keyserver_import_fprint(info.fpr1,20,spec);
637               free_keyserver_spec(spec);
638             }
639         }
640       else if (info.fpr1valid)
641         {
642           rc = keyserver_import_fprint (info.fpr1, 20, opt.keyserver);
643         }
644     }
645
646   return rc;
647 #else
648   return 0;
649 #endif
650 }
651
652
653 static int
654 change_login (const char *args)
655 {
656   char *data;
657   int n;
658   int rc;
659
660   if (args && *args == '<')  /* Read it from a file */
661     {
662       FILE *fp;
663
664       for (args++; spacep (args); args++)
665         ;
666       fp = fopen (args, "rb");
667 #if GNUPG_MAJOR_VERSION == 1
668       if (fp && is_secured_file (fileno (fp)))
669         {
670           fclose (fp);
671           fp = NULL;
672           errno = EPERM;
673         }
674 #endif
675       if (!fp)
676         {
677           tty_printf (_("can't open `%s': %s\n"), args, strerror (errno));
678           return -1;
679         }
680           
681       data = xmalloc (254);
682       n = fread (data, 1, 254, fp);
683       fclose (fp);
684       if (n < 0)
685         {
686           tty_printf (_("error reading `%s': %s\n"), args, strerror (errno));
687           xfree (data);
688           return -1;
689         }
690     }
691   else
692     {
693       data = cpr_get ("cardedit.change_login",
694                       _("Login data (account name): "));
695       if (!data)
696         return -1;
697       trim_spaces (data);
698       cpr_kill_prompt ();
699       n = strlen (data);
700     }
701
702   if (n > 254 )
703     {
704       tty_printf (_("Error: Login data too long "
705                     "(limit is %d characters).\n"), 254);    
706       xfree (data);
707       return -1;
708     }
709
710   rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
711   if (rc)
712     log_error ("error setting login data: %s\n", gpg_strerror (rc));
713   xfree (data);
714   return rc;
715 }
716
717 static int
718 change_private_do (const char *args, int nr)
719 {
720   char do_name[] = "PRIVATE-DO-X";
721   char *data;
722   int n;
723   int rc; 
724
725   assert (nr >= 1 && nr <= 4);
726   do_name[11] = '0' + nr;
727
728   if (args && (args = strchr (args, '<')))  /* Read it from a file */
729     {
730       FILE *fp;
731
732       /* Fixme: Factor this duplicated code out. */
733       for (args++; spacep (args); args++)
734         ;
735       fp = fopen (args, "rb");
736 #if GNUPG_MAJOR_VERSION == 1
737       if (fp && is_secured_file (fileno (fp)))
738         {
739           fclose (fp);
740           fp = NULL;
741           errno = EPERM;
742         }
743 #endif
744       if (!fp)
745         {
746           tty_printf (_("can't open `%s': %s\n"), args, strerror (errno));
747           return -1;
748         }
749           
750       data = xmalloc (254);
751       n = fread (data, 1, 254, fp);
752       fclose (fp);
753       if (n < 0)
754         {
755           tty_printf (_("error reading `%s': %s\n"), args, strerror (errno));
756           xfree (data);
757           return -1;
758         }
759     }
760   else
761     {
762       data = cpr_get ("cardedit.change_private_do",
763                       _("Private DO data: "));
764       if (!data)
765         return -1;
766       trim_spaces (data);
767       cpr_kill_prompt ();
768       n = strlen (data);
769     }
770
771   if (n > 254 )
772     {
773       tty_printf (_("Error: Private DO too long "
774                     "(limit is %d characters).\n"), 254);    
775       xfree (data);
776       return -1;
777     }
778
779   rc = agent_scd_setattr (do_name, data, n, NULL );
780   if (rc)
781     log_error ("error setting private DO: %s\n", gpg_strerror (rc));
782   xfree (data);
783   return rc;
784 }
785
786 static int
787 change_lang (void)
788 {
789   char *data, *p;
790   int rc;
791
792   data = cpr_get ("cardedit.change_lang",
793                   _("Language preferences: "));
794   if (!data)
795     return -1;
796   trim_spaces (data);
797   cpr_kill_prompt ();
798
799   if (strlen (data) > 8 || (strlen (data) & 1))
800     {
801       tty_printf (_("Error: invalid length of preference string.\n"));
802       xfree (data);
803       return -1;
804     }
805
806   for (p=data; *p && *p >= 'a' && *p <= 'z'; p++)
807     ;
808   if (*p)
809     {
810       tty_printf (_("Error: invalid characters in preference string.\n"));
811       xfree (data);
812       return -1;
813     }
814
815   rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL );
816   if (rc)
817     log_error ("error setting lang: %s\n", gpg_strerror (rc));
818   xfree (data);
819   return rc;
820 }
821
822
823 static int
824 change_sex (void)
825 {
826   char *data;
827   const char *str;
828   int rc;
829
830   data = cpr_get ("cardedit.change_sex",
831                   _("Sex ((M)ale, (F)emale or space): "));
832   if (!data)
833     return -1;
834   trim_spaces (data);
835   cpr_kill_prompt ();
836
837   if (!*data)
838     str = "9";
839   else if ((*data == 'M' || *data == 'm') && !data[1])
840     str = "1";
841   else if ((*data == 'F' || *data == 'f') && !data[1])
842     str = "2";
843   else 
844     {
845       tty_printf (_("Error: invalid response.\n"));
846       xfree (data);
847       return -1;
848     }
849      
850   rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
851   if (rc)
852     log_error ("error setting sex: %s\n", gpg_strerror (rc));
853   xfree (data);
854   return rc;
855 }
856
857
858 static int
859 change_cafpr (int fprno)
860 {
861   char *data;
862   const char *s;
863   int i, c, rc;
864   unsigned char fpr[20];
865
866   data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
867   if (!data)
868     return -1;
869   trim_spaces (data);
870   cpr_kill_prompt ();
871
872   for (i=0, s=data; i < 20 && *s; )
873     {
874       while (spacep(s))
875         s++;
876       if (*s == ':')
877         s++;
878       while (spacep(s))
879         s++;
880       c = hextobyte (s);
881       if (c == -1)
882         break;
883       fpr[i++] = c;
884       s += 2;
885     }
886   xfree (data);
887   if (i != 20 || *s)
888     {
889       tty_printf (_("Error: invalid formatted fingerprint.\n"));
890       return -1;
891     }
892
893   rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
894                           fprno==2?"CA-FPR-2":
895                           fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
896   if (rc)
897     log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
898   return rc;
899 }
900
901
902
903 static void
904 toggle_forcesig (void)
905 {
906   struct agent_card_info_s info;
907   int rc;
908   int newstate;
909
910   memset (&info, 0, sizeof info);
911   rc = agent_scd_getattr ("CHV-STATUS", &info);
912   if (rc)
913     {
914       log_error ("error getting current status: %s\n", gpg_strerror (rc));
915       return;
916     }
917   newstate = !info.chv1_cached;
918   agent_release_card_info (&info);
919
920   rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL);
921   if (rc)
922     log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
923 }
924
925
926 /* Helper for the key generation/edit functions.  */
927 static int
928 get_info_for_key_operation (struct agent_card_info_s *info)
929 {
930   int rc;
931
932   memset (info, 0, sizeof *info);
933   rc = agent_scd_getattr ("SERIALNO", info);
934   if (rc || !info->serialno || strncmp (info->serialno, "D27600012401", 12) 
935       || strlen (info->serialno) != 32 )
936     {
937       log_error (_("key operation not possible: %s\n"),
938                  rc ? gpg_strerror (rc) : _("not an OpenPGP card"));
939       return rc? rc: -1;
940     }
941   rc = agent_scd_getattr ("KEY-FPR", info);
942   if (!rc)
943     rc = agent_scd_getattr ("CHV-STATUS", info);
944   if (!rc)
945     rc = agent_scd_getattr ("DISP-NAME", info);
946   if (rc)
947     log_error (_("error getting current key info: %s\n"), gpg_strerror (rc));
948   return rc;
949 }
950
951
952 /* Helper for the key generation/edit functions.  */
953 static int
954 check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
955 {     
956   int rc = 0;
957
958   agent_clear_pin_cache (info->serialno);
959
960   *forced_chv1 = !info->chv1_cached;
961   if (*forced_chv1)
962     { /* Switch of the forced mode so that during key generation we
963          don't get bothered with PIN queries for each
964          self-signature. */
965       rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
966       if (rc)
967         {
968           log_error ("error clearing forced signature PIN flag: %s\n",
969                      gpg_strerror (rc));
970           *forced_chv1 = 0;
971         }
972     }
973
974   if (!rc)
975     {
976       /* Check the PIN now, so that we won't get asked later for each
977          binding signature. */
978       rc = agent_scd_checkpin (info->serialno);
979       if (rc)
980         log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
981     }
982   return rc;
983 }
984
985 /* Helper for the key generation/edit functions.  */
986 static void 
987 restore_forced_chv1 (int *forced_chv1)
988 {
989   int rc;
990
991   if (*forced_chv1)
992     { /* Switch back to forced state. */
993       rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL);
994       if (rc)
995         {
996           log_error ("error setting forced signature PIN flag: %s\n",
997                      gpg_strerror (rc));
998         }
999     }
1000 }
1001
1002 #if GNUPG_MAJOR_VERSION == 1
1003 /* Helper for the key generation/edit functions.  */
1004 static void
1005 show_card_key_info (struct agent_card_info_s *info)
1006 {
1007   tty_fprintf (NULL, "Signature key ....:");
1008   print_sha1_fpr (NULL, info->fpr1valid? info->fpr1:NULL);
1009   tty_fprintf (NULL, "Encryption key....:");
1010   print_sha1_fpr (NULL, info->fpr2valid? info->fpr2:NULL);
1011   tty_fprintf (NULL, "Authentication key:");
1012   print_sha1_fpr (NULL, info->fpr3valid? info->fpr3:NULL);
1013   tty_printf ("\n");
1014 }
1015 #endif
1016
1017 #if GNUPG_MAJOR_VERSION == 1
1018 /* Helper for the key generation/edit functions.  */
1019 static int
1020 replace_existing_key_p (struct agent_card_info_s *info, int keyno)
1021 {
1022   assert (keyno >= 0 && keyno <= 3);
1023
1024   if ((keyno == 1 && info->fpr1valid)
1025       || (keyno == 2 && info->fpr2valid)
1026       || (keyno == 3 && info->fpr3valid))
1027     {
1028       tty_printf ("\n");
1029       log_info ("WARNING: such a key has already been stored on the card!\n");
1030       tty_printf ("\n");
1031       if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_key",
1032                                   _("Replace existing key? (y/N) ")))
1033         return -1;
1034     }
1035   return 0;
1036 }
1037 #endif
1038
1039
1040 static void
1041 generate_card_keys (const char *serialno)
1042 {
1043   struct agent_card_info_s info;
1044   int forced_chv1;
1045   int want_backup;
1046
1047   if (get_info_for_key_operation (&info))
1048     return;
1049
1050 #if GNUPG_MAJOR_VERSION == 1
1051   {
1052     char *answer=cpr_get("cardedit.genkeys.backup_enc",
1053                          _("Make off-card backup of encryption key? (Y/n) "));
1054
1055     want_backup=answer_is_yes_no_default(answer,1);
1056     cpr_kill_prompt();
1057     xfree(answer);
1058   }
1059 #else
1060   want_backup = cpr_get_answer_is_yes 
1061                   ( "cardedit.genkeys.backup_enc",
1062                     _("Make off-card backup of encryption key? (Y/n) "));
1063   /*FIXME: we need answer_is_yes_no_default()*/
1064 #endif
1065
1066   if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
1067        || (info.fpr2valid && !fpr_is_zero (info.fpr2))
1068        || (info.fpr3valid && !fpr_is_zero (info.fpr3)))
1069     {
1070       tty_printf ("\n");
1071       log_info ("NOTE: keys are already stored on the card!\n");
1072       tty_printf ("\n");
1073       if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_keys",
1074                                   _("Replace existing keys? (y/N) ")))
1075         {
1076           agent_release_card_info (&info);
1077           return;
1078         }
1079     }
1080   else if (!info.disp_name || !*info.disp_name)
1081     {
1082       tty_printf ("\n");
1083       tty_printf (_("Please note that the factory settings of the PINs are\n"
1084                     "   PIN = `%s'     Admin PIN = `%s'\n"
1085                     "You should change them using the command --change-pin\n"),
1086                   "123456", "12345678");
1087       tty_printf ("\n");
1088     }
1089
1090   if (check_pin_for_key_operation (&info, &forced_chv1))
1091     goto leave;
1092   
1093   generate_keypair (NULL, info.serialno,
1094                     want_backup? opt.homedir:NULL);
1095
1096  leave:
1097   agent_release_card_info (&info);
1098   restore_forced_chv1 (&forced_chv1);
1099 }
1100
1101
1102 /* This function is used by the key edit menu to generate an arbitrary
1103    subkey. */
1104 int
1105 card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
1106 {
1107 #if GNUPG_MAJOR_VERSION == 1
1108   struct agent_card_info_s info;
1109   int okay = 0;
1110   int forced_chv1 = 0;
1111   int keyno;
1112
1113   if (get_info_for_key_operation (&info))
1114     return 0;
1115
1116   show_card_key_info (&info);
1117
1118   tty_printf (_("Please select the type of key to generate:\n"));
1119
1120   tty_printf (_("   (1) Signature key\n"));
1121   tty_printf (_("   (2) Encryption key\n"));
1122   tty_printf (_("   (3) Authentication key\n"));
1123
1124   for (;;) 
1125     {
1126       char *answer = cpr_get ("cardedit.genkeys.subkeytype",
1127                               _("Your selection? "));
1128       cpr_kill_prompt();
1129       if (*answer == CONTROL_D)
1130         {
1131           xfree (answer);
1132           goto leave;
1133         }
1134       keyno = *answer? atoi(answer): 0;
1135       xfree(answer);
1136       if (keyno >= 1 && keyno <= 3)
1137         break; /* Okay. */
1138       tty_printf(_("Invalid selection.\n"));
1139     }
1140
1141   if (replace_existing_key_p (&info, keyno))
1142     goto leave;
1143
1144   if (check_pin_for_key_operation (&info, &forced_chv1))
1145     goto leave;
1146
1147   okay = generate_card_subkeypair (pub_keyblock, sec_keyblock,
1148                                    keyno, info.serialno);
1149
1150  leave:
1151   agent_release_card_info (&info);
1152   restore_forced_chv1 (&forced_chv1);
1153   return okay;
1154 #else
1155   return 0;
1156 #endif
1157 }
1158
1159
1160 /* Store the key at NODE into the smartcard and modify NODE to
1161    carry the serialno stuff instead of the actual secret key
1162    parameters.  USE is the usage for that key; 0 means any
1163    usage. */
1164 int 
1165 card_store_subkey (KBNODE node, int use)
1166 {
1167 #if GNUPG_MAJOR_VERSION == 1
1168   struct agent_card_info_s info;
1169   int okay = 0;
1170   int rc;
1171   int keyno, i;
1172   PKT_secret_key *copied_sk = NULL;
1173   PKT_secret_key *sk;
1174   size_t n;
1175   const char *s;
1176   int allow_keyno[3];
1177
1178   assert (node->pkt->pkttype == PKT_SECRET_KEY
1179           || node->pkt->pkttype == PKT_SECRET_SUBKEY);
1180   sk = node->pkt->pkt.secret_key;
1181
1182   if (get_info_for_key_operation (&info))
1183     return 0;
1184
1185   show_card_key_info (&info);
1186
1187   if (!is_RSA (sk->pubkey_algo) || nbits_from_sk (sk) != 1024 )
1188     {
1189       tty_printf ("You may only store a 1024 bit RSA key on the card\n");
1190       tty_printf ("\n");
1191       goto leave;
1192     }
1193
1194   allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG)));
1195   allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC)));
1196   allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)));
1197
1198   tty_printf (_("Please select where to store the key:\n"));
1199
1200   if (allow_keyno[0])
1201     tty_printf (_("   (1) Signature key\n"));
1202   if (allow_keyno[1])
1203     tty_printf (_("   (2) Encryption key\n"));
1204   if (allow_keyno[2])
1205     tty_printf (_("   (3) Authentication key\n"));
1206
1207   for (;;) 
1208     {
1209       char *answer = cpr_get ("cardedit.genkeys.storekeytype",
1210                               _("Your selection? "));
1211       cpr_kill_prompt();
1212       if (*answer == CONTROL_D || !*answer)
1213         {
1214           xfree (answer);
1215           goto leave;
1216         }
1217       keyno = *answer? atoi(answer): 0;
1218       xfree(answer);
1219       if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1])
1220         break; /* Okay. */
1221       tty_printf(_("Invalid selection.\n"));
1222     }
1223
1224   if (replace_existing_key_p (&info, keyno))
1225     goto leave;
1226
1227   /* Unprotect key.  */
1228   switch (is_secret_key_protected (sk) )
1229     {
1230     case 0: /* Not protected. */
1231       break;
1232     case -1:
1233       log_error (_("unknown key protection algorithm\n"));
1234       goto leave;
1235     default:
1236       if (sk->protect.s2k.mode == 1001)
1237         {
1238           log_error (_("secret parts of key are not available\n"));
1239           goto leave;
1240         }
1241       if (sk->protect.s2k.mode == 1002)
1242         {
1243           log_error (_("secret key already stored on a card\n"));
1244           goto leave;
1245         }
1246       /* We better copy the key before we unprotect it.  */
1247       copied_sk = sk = copy_secret_key (NULL, sk);
1248       rc = check_secret_key (sk, 0);
1249       if (rc)
1250         goto leave;
1251     }
1252
1253   rc = save_unprotected_key_to_card (sk, keyno);
1254   if (rc)
1255     goto leave;
1256
1257   /* Get back to the maybe protected original secret key.  */
1258   if (copied_sk)
1259     {
1260       free_secret_key (copied_sk);
1261       copied_sk = NULL; 
1262     }
1263   sk = node->pkt->pkt.secret_key;
1264
1265   /* Get rid of the secret key parameters and store the serial numer. */
1266   n = pubkey_get_nskey (sk->pubkey_algo);
1267   for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++)
1268     {
1269       mpi_free (sk->skey[i]);
1270       sk->skey[i] = NULL;
1271     }
1272   i = pubkey_get_npkey (sk->pubkey_algo);
1273   sk->skey[i] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
1274   sk->is_protected = 1;
1275   sk->protect.s2k.mode = 1002;
1276   s = info.serialno;
1277   for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
1278        sk->protect.ivlen++, s += 2)
1279     sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
1280
1281   okay = 1;
1282
1283  leave:
1284   if (copied_sk)
1285     free_secret_key (copied_sk);
1286   agent_release_card_info (&info);
1287   return okay;
1288 #else
1289   return 0;
1290 #endif
1291 }
1292
1293
1294 \f
1295 /* Data used by the command parser.  This needs to be outside of the
1296    function scope to allow readline based command completion.  */
1297 enum cmdids
1298   {
1299     cmdNOP = 0,
1300     cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
1301     cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
1302     cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO,
1303     cmdINVCMD
1304   };
1305
1306 static struct
1307 {
1308   const char *name;
1309   enum cmdids id;
1310   int admin_only;
1311   const char *desc;
1312 } cmds[] =
1313   {
1314     { "quit"    , cmdQUIT  , 0, N_("quit this menu")},
1315     { "q"       , cmdQUIT  , 0, NULL },
1316     { "admin"   , cmdADMIN , 0, N_("show admin commands")},
1317     { "help"    , cmdHELP  , 0, N_("show this help")},
1318     { "?"       , cmdHELP  , 0, NULL },
1319     { "list"    , cmdLIST  , 0, N_("list all available data")},
1320     { "l"       , cmdLIST  , 0, NULL },
1321     { "debug"   , cmdDEBUG , 0, NULL },
1322     { "name"    , cmdNAME  , 1, N_("change card holder's name")},
1323     { "url"     , cmdURL   , 1, N_("change URL to retrieve key")},
1324     { "fetch"   , cmdFETCH , 0, N_("fetch the key specified in the card URL")},
1325     { "login"   , cmdLOGIN , 1, N_("change the login name")},
1326     { "lang"    , cmdLANG  , 1, N_("change the language preferences")},
1327     { "sex"     , cmdSEX   , 1, N_("change card holder's sex")},
1328     { "cafpr"   , cmdCAFPR , 1, N_("change a CA fingerprint")},
1329     { "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")},
1330     { "generate", cmdGENERATE, 1, N_("generate new keys")},
1331     { "passwd"  , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
1332     { "verify"  , cmdVERIFY, 0, N_("verify the PIN and list all data")},
1333     /* Note, that we do not announce this command yet. */
1334     { "privatedo", cmdPRIVATEDO, 0, NULL },
1335     { NULL, cmdINVCMD, 0, NULL } 
1336   };
1337
1338
1339 #if GNUPG_MAJOR_VERSION == 1 && defined (HAVE_LIBREADLINE)
1340
1341 /* These two functions are used by readline for command completion. */
1342
1343 static char *
1344 command_generator(const char *text,int state)
1345 {
1346   static int list_index,len;
1347   const char *name;
1348
1349   /* If this is a new word to complete, initialize now.  This includes
1350      saving the length of TEXT for efficiency, and initializing the
1351      index variable to 0. */
1352   if(!state)
1353     {
1354       list_index=0;
1355       len=strlen(text);
1356     }
1357
1358   /* Return the next partial match */
1359   while((name=cmds[list_index].name))
1360     {
1361       /* Only complete commands that have help text */
1362       if(cmds[list_index++].desc && strncmp(name,text,len)==0)
1363         return strdup(name);
1364     }
1365
1366   return NULL;
1367 }
1368
1369 static char **
1370 card_edit_completion(const char *text, int start, int end)
1371 {
1372   /* If we are at the start of a line, we try and command-complete.
1373      If not, just do nothing for now. */
1374
1375   if(start==0)
1376     return rl_completion_matches(text,command_generator);
1377
1378   rl_attempted_completion_over=1;
1379
1380   return NULL;
1381 }
1382 #endif /* GNUPG_MAJOR_VERSION == 1 && HAVE_LIBREADLINE */
1383
1384 /* Menu to edit all user changeable values on an OpenPGP card.  Only
1385    Key creation is not handled here. */
1386 void
1387 card_edit (strlist_t commands)
1388 {
1389   enum cmdids cmd = cmdNOP;
1390   int have_commands = !!commands;
1391   int redisplay = 1;
1392   char *answer = NULL;
1393   int did_checkpin = 0, allow_admin=0;
1394   char serialnobuf[50];
1395
1396
1397   if (opt.command_fd != -1)
1398     ;
1399   else if (opt.batch && !have_commands)
1400     {
1401       log_error(_("can't do this in batch mode\n"));
1402       goto leave;
1403     }
1404
1405   for (;;)
1406     {
1407       int arg_number;
1408       const char *arg_string = "";
1409       char *p;
1410       int i;
1411       int cmd_admin_only;
1412       
1413       tty_printf("\n");
1414       if (redisplay )
1415         {
1416           if (opt.with_colons)
1417             {
1418               card_status (stdout, serialnobuf, DIM (serialnobuf));
1419               fflush (stdout);
1420             }
1421           else
1422             {
1423               card_status (NULL, serialnobuf, DIM (serialnobuf));
1424               tty_printf("\n");
1425             }
1426           redisplay = 0;
1427         }
1428
1429       do
1430         {
1431           xfree (answer);
1432           if (have_commands)
1433             {
1434               if (commands)
1435                 {
1436                   answer = xstrdup (commands->d);
1437                   commands = commands->next;
1438                 }
1439               else if (opt.batch)
1440                 {
1441                   answer = xstrdup ("quit");
1442                 }
1443               else
1444                 have_commands = 0;
1445             }
1446
1447             if (!have_commands)
1448               {
1449 #if GNUPG_MAJOR_VERSION == 1
1450                 tty_enable_completion (card_edit_completion);
1451 #endif
1452                 answer = cpr_get_no_help("cardedit.prompt", _("Command> "));
1453                 cpr_kill_prompt();
1454 #if GNUPG_MAJOR_VERSION == 1
1455                 tty_disable_completion ();
1456 #endif
1457             }
1458             trim_spaces(answer);
1459         }
1460       while ( *answer == '#' );
1461
1462       arg_number = 0; /* Yes, here is the init which egcc complains about */
1463       cmd_admin_only = 0;
1464       if (!*answer)
1465         cmd = cmdLIST; /* Default to the list command */
1466       else if (*answer == CONTROL_D)
1467         cmd = cmdQUIT;
1468       else 
1469         {
1470           if ((p=strchr (answer,' ')))
1471             {
1472               *p++ = 0;
1473               trim_spaces (answer);
1474               trim_spaces (p);
1475               arg_number = atoi(p);
1476               arg_string = p;
1477             }
1478           
1479           for (i=0; cmds[i].name; i++ )
1480             if (!ascii_strcasecmp (answer, cmds[i].name ))
1481               break;
1482
1483           cmd = cmds[i].id;
1484           cmd_admin_only = cmds[i].admin_only;
1485         }
1486
1487       if (!allow_admin && cmd_admin_only)
1488         {
1489           tty_printf ("\n");
1490           tty_printf (_("Admin-only command\n"));
1491           continue;
1492         }
1493
1494       switch (cmd)
1495         {
1496         case cmdHELP:
1497           for (i=0; cmds[i].name; i++ )
1498             if(cmds[i].desc
1499                && (!cmds[i].admin_only || (cmds[i].admin_only && allow_admin)))
1500               tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1501           break;
1502
1503         case cmdADMIN:
1504           if ( !strcmp (arg_string, "on") )
1505             allow_admin = 1;
1506           else if ( !strcmp (arg_string, "off") )
1507             allow_admin = 0;
1508           else if ( !strcmp (arg_string, "verify") )
1509             {
1510               /* Force verification of the Admin Command.  However,
1511                  this is only done if the retry counter is at initial
1512                  state.  */
1513               char *tmp = xmalloc (strlen (serialnobuf) + 6 + 1);
1514               strcpy (stpcpy (tmp, serialnobuf), "[CHV3]");
1515               allow_admin = !agent_scd_checkpin (tmp);
1516               xfree (tmp);
1517             }
1518           else /* Toggle. */
1519             allow_admin=!allow_admin;
1520           if(allow_admin)
1521             tty_printf(_("Admin commands are allowed\n"));
1522           else
1523             tty_printf(_("Admin commands are not allowed\n"));
1524           break;
1525
1526         case cmdVERIFY:
1527           agent_scd_checkpin (serialnobuf);
1528           redisplay = 1;
1529           break;
1530
1531         case cmdLIST:
1532           redisplay = 1;
1533           break;
1534
1535         case cmdNAME:
1536           change_name ();
1537           break;
1538
1539         case cmdURL:
1540           change_url ();
1541           break;
1542
1543         case cmdFETCH:
1544           fetch_url();
1545           break;
1546
1547         case cmdLOGIN:
1548           change_login (arg_string);
1549           break;
1550
1551         case cmdLANG:
1552           change_lang ();
1553           break;
1554
1555         case cmdSEX:
1556           change_sex ();
1557           break;
1558
1559         case cmdCAFPR:
1560           if ( arg_number < 1 || arg_number > 3 )
1561             tty_printf ("usage: cafpr N\n"
1562                         "       1 <= N <= 3\n");
1563           else
1564             change_cafpr (arg_number);
1565           break;
1566
1567         case cmdPRIVATEDO:
1568           if ( arg_number < 1 || arg_number > 4 )
1569             tty_printf ("usage: privatedo N\n"
1570                         "       1 <= N <= 4\n");
1571           else
1572             change_private_do (arg_string, arg_number);
1573           break;
1574
1575         case cmdFORCESIG:
1576           toggle_forcesig ();
1577           break;
1578
1579         case cmdGENERATE:
1580           generate_card_keys (serialnobuf);
1581           break;
1582
1583         case cmdPASSWD:
1584           change_pin (0, allow_admin);
1585           did_checkpin = 0; /* Need to reset it of course. */
1586           break;
1587
1588         case cmdQUIT:
1589           goto leave;
1590
1591         case cmdNOP:
1592           break;
1593
1594         case cmdINVCMD:
1595         default:
1596           tty_printf ("\n");
1597           tty_printf (_("Invalid command  (try \"help\")\n"));
1598           break;
1599         } /* End command switch. */
1600     } /* End of main menu loop. */
1601
1602  leave:
1603   xfree (answer);
1604 }
1605