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