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