~ubuntu-branches/ubuntu/oneiric/gnupg2/oneiric-updates

« back to all changes in this revision

Viewing changes to g10/card-util.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* card-util.c - Utility functions for the OpenPGP card.
2
 
 *      Copyright (C) 2003 Free Software Foundation, Inc.
 
2
 *      Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3
3
 *
4
4
 * This file is part of GnuPG.
5
5
 *
6
6
 * GnuPG is free software; you can redistribute it and/or modify
7
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
 
8
 * the Free Software Foundation; either version 3 of the License, or
9
9
 * (at your option) any later version.
10
10
 *
11
11
 * GnuPG is distributed in the hope that it will be useful,
14
14
 * GNU General Public License for more details.
15
15
 *
16
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19
18
 */
20
19
 
21
20
#include <config.h>
26
25
#include <assert.h>
27
26
 
28
27
#if GNUPG_MAJOR_VERSION != 1
29
 
#include "gpg.h"
30
 
#endif
 
28
# include "gpg.h"
 
29
#endif /*GNUPG_MAJOR_VERSION != 1*/
31
30
#include "util.h"
32
31
#include "i18n.h"
33
32
#include "ttyio.h"
36
35
#include "main.h"
37
36
#include "keyserver-internal.h"
38
37
#if GNUPG_MAJOR_VERSION == 1
39
 
#include "cardglue.h"
40
 
#else
41
 
#include "call-agent.h"
42
 
#endif
 
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*/
43
47
 
44
48
#define CONTROL_D ('D' - 'A' + 1)
45
49
 
63
67
  log_info (_("OpenPGP card no. %s detected\n"),
64
68
              info.serialno? info.serialno : "[none]");
65
69
 
66
 
  agent_release_card_info (&info);
 
70
  agent_clear_pin_cache (info.serialno);
67
71
 
68
72
  if (opt.batch)
69
73
    {
70
 
      log_error (_("sorry, can't do this in batch mode\n"));
 
74
      agent_release_card_info (&info);
 
75
      log_error (_("can't do this in batch mode\n"));
71
76
      return;
72
77
    }
73
78
 
74
79
  if(!allow_admin)
75
80
    {
76
 
      rc = agent_scd_change_pin (1);
 
81
      rc = agent_scd_change_pin (1, info.serialno);
77
82
      if (rc)
78
83
        tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
79
84
      else
80
 
        tty_printf ("PIN changed.\n");
 
85
        {
 
86
          write_status (STATUS_SC_OP_SUCCESS);
 
87
          tty_printf ("PIN changed.\n");
 
88
        }
81
89
    }
82
90
  else
83
91
    for (;;)
99
107
        rc = 0;
100
108
        if (*answer == '1')
101
109
          {
102
 
            rc = agent_scd_change_pin (1);
 
110
            rc = agent_scd_change_pin (1, info.serialno);
103
111
            if (rc)
104
112
              tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
105
113
            else
106
 
              tty_printf ("PIN changed.\n");
 
114
              {
 
115
                write_status (STATUS_SC_OP_SUCCESS);
 
116
                tty_printf ("PIN changed.\n");
 
117
              }
107
118
          }
108
119
        else if (*answer == '2')
109
120
          {
110
 
            rc = agent_scd_change_pin (101);
 
121
            rc = agent_scd_change_pin (101, info.serialno);
111
122
            if (rc)
112
123
              tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
113
124
            else
114
 
              tty_printf ("PIN unblocked and new PIN set.\n");
115
 
          }
 
125
              {
 
126
                write_status (STATUS_SC_OP_SUCCESS);
 
127
                tty_printf ("PIN unblocked and new PIN set.\n");
 
128
              }
 
129
          }
116
130
        else if (*answer == '3')
117
131
          {
118
 
            rc = agent_scd_change_pin (3);
 
132
            rc = agent_scd_change_pin (3, info.serialno);
119
133
            if (rc)
120
134
              tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
121
135
            else
122
 
              tty_printf ("PIN changed.\n");
 
136
              {
 
137
                write_status (STATUS_SC_OP_SUCCESS);
 
138
                tty_printf ("PIN changed.\n");
 
139
              }
123
140
          }
124
141
        else if (*answer == 'q' || *answer == 'Q')
125
142
          {
126
143
            break;
127
144
          }
128
145
      }
 
146
 
 
147
  agent_release_card_info (&info);
129
148
}
130
149
 
131
150
static const char *
134
153
  /* Note:  Make sure that there is no colon or linefeed in the string. */
135
154
  switch (no)
136
155
    {
137
 
    case 0:
 
156
    case 0x0001: return "PPC Card Systems";
 
157
    case 0x0002: return "Prism";
 
158
    case 0x0003: return "OpenFortress";
 
159
    case 0x0004: return "Wewid AB";
 
160
 
 
161
      /* 0x00000 and 0xFFFF are defined as test cards per spec,
 
162
         0xFFF00 to 0xFFFE are assigned for use with randomly created
 
163
         serial numbers.  */
 
164
    case 0x0000:
138
165
    case 0xffff: return "test card";
139
 
    case 0x0001: return "PPC Card Systems";
140
 
    default: return "unknown";
 
166
    default: return (no & 0xff00) == 0xff00? "unmanaged S/N range":"unknown";
141
167
    }
142
168
}
143
169
 
270
296
  PKT_public_key *pk = xcalloc (1, sizeof *pk);
271
297
  int rc;
272
298
  unsigned int uval;
 
299
  const unsigned char *thefpr;
 
300
  int i;
273
301
 
274
302
  if (serialno && serialnobuflen)
275
303
    *serialno = 0;
346
374
                   info.chvretry[0], info.chvretry[1], info.chvretry[2]);
347
375
      fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
348
376
 
 
377
      for (i=0; i < 4; i++)
 
378
        {
 
379
          if (info.private_do[i])
 
380
            {
 
381
              fprintf (fp, "private_do:%d:", i+1);
 
382
              print_string (fp, info.private_do[i],
 
383
                            strlen (info.private_do[i]), ':');
 
384
              fputs (":\n", fp);
 
385
            }
 
386
        }
 
387
 
349
388
      fputs ("cafpr:", fp);
350
389
      print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
351
390
      print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
356
395
      print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
357
396
      print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
358
397
      putc ('\n', fp);
359
 
 
 
398
      fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
 
399
               (unsigned long)info.fpr1time, (unsigned long)info.fpr2time,
 
400
               (unsigned long)info.fpr3time);
360
401
    }
361
402
  else 
362
403
    {
377
418
                   info.disp_sex == 2? _("female") : _("unspecified"));
378
419
      print_name (fp, "URL of public key : ", info.pubkey_url);
379
420
      print_name (fp, "Login data .......: ", info.login_data);
 
421
      if (info.private_do[0])
 
422
        print_name (fp, "Private DO 1 .....: ", info.private_do[0]);
 
423
      if (info.private_do[1])
 
424
        print_name (fp, "Private DO 2 .....: ", info.private_do[1]);
 
425
      if (info.private_do[2])
 
426
        print_name (fp, "Private DO 3 .....: ", info.private_do[2]);
 
427
      if (info.private_do[3])
 
428
        print_name (fp, "Private DO 4 .....: ", info.private_do[3]);
380
429
      if (info.cafpr1valid)
381
430
        {
382
431
          tty_fprintf (fp, "CA fingerprint %d .:", 1);
401
450
      tty_fprintf (fp,    "Signature counter : %lu\n", info.sig_counter);
402
451
      tty_fprintf (fp, "Signature key ....:");
403
452
      print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
 
453
      if (info.fpr1valid && info.fpr1time)
 
454
        tty_fprintf (fp, "      created ....: %s\n",
 
455
                     isotimestamp (info.fpr1time));
404
456
      tty_fprintf (fp, "Encryption key....:");
405
457
      print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
 
458
      if (info.fpr2valid && info.fpr2time)
 
459
        tty_fprintf (fp, "      created ....: %s\n",
 
460
                     isotimestamp (info.fpr2time));
406
461
      tty_fprintf (fp, "Authentication key:");
407
462
      print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
 
463
      if (info.fpr3valid && info.fpr3time)
 
464
        tty_fprintf (fp, "      created ....: %s\n",
 
465
                     isotimestamp (info.fpr3time));
408
466
      tty_fprintf (fp, "General key info..: "); 
409
 
      if (info.fpr1valid && !get_pubkey_byfprint (pk, info.fpr1, 20))
410
 
        print_pubkey_info (fp, pk);
 
467
 
 
468
      thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 : 
 
469
                info.fpr3valid? info.fpr3 : NULL);
 
470
      if ( thefpr && !get_pubkey_byfprint (pk, thefpr, 20))
 
471
        {
 
472
          KBNODE keyblock = NULL;
 
473
 
 
474
          print_pubkey_info (fp, pk);
 
475
 
 
476
          if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
 
477
            print_card_key_info (fp, keyblock);
 
478
          else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
 
479
            {
 
480
              release_kbnode (keyblock);
 
481
              keyblock = NULL;
 
482
              
 
483
              if (!auto_create_card_key_stub (info.serialno,
 
484
                                              info.fpr1valid? info.fpr1:NULL,
 
485
                                              info.fpr2valid? info.fpr2:NULL,
 
486
                                              info.fpr3valid? info.fpr3:NULL))
 
487
                {
 
488
                  if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
 
489
                    print_card_key_info (fp, keyblock);
 
490
                }
 
491
            }
 
492
 
 
493
          release_kbnode (keyblock);
 
494
        }
411
495
      else
412
496
        tty_fprintf (fp, "[none]\n");
413
497
    }
483
567
      return -1;
484
568
    }
485
569
 
486
 
  log_debug ("setting Name to `%s'\n", isoname);
487
 
  rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname) );
 
570
  rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL );
488
571
  if (rc)
489
572
    log_error ("error setting Name: %s\n", gpg_strerror (rc));
490
573
 
513
596
      return -1;
514
597
    }
515
598
 
516
 
  rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url) );
 
599
  rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
517
600
  if (rc)
518
601
    log_error ("error setting URL: %s\n", gpg_strerror (rc));
519
602
  xfree (url);
520
603
  return rc;
521
604
}
522
605
 
 
606
 
 
607
/* Fetch the key from the URL given on the card or try to get it from
 
608
   the default keyserver.  */
523
609
static int
524
610
fetch_url(void)
525
611
{
532
618
  rc=agent_scd_getattr("PUBKEY-URL",&info);
533
619
  if(rc)
534
620
    log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
535
 
  else if(info.pubkey_url)
 
621
  else
536
622
    {
537
623
      struct keyserver_spec *spec=NULL;
538
624
 
540
626
      if(rc)
541
627
        log_error("error retrieving key fingerprint from card: %s\n",
542
628
                  gpg_strerror(rc));
543
 
      else
 
629
      else if (info.pubkey_url && *info.pubkey_url)
544
630
        {
545
 
          spec=parse_keyserver_uri(info.pubkey_url,0,NULL,0);
 
631
          spec=parse_keyserver_uri(info.pubkey_url,1,NULL,0);
546
632
          if(spec && info.fpr1valid)
547
633
            {
548
634
              /* This is not perfectly right.  Currently, all card
556
642
              free_keyserver_spec(spec);
557
643
            }
558
644
        }
 
645
      else if (info.fpr1valid)
 
646
        {
 
647
          rc = keyserver_import_fprint (info.fpr1, 20, opt.keyserver);
 
648
        }
559
649
    }
560
 
  else
561
 
    log_error("no URL set on card\n");
562
650
 
563
651
  return rc;
564
652
#else
624
712
      return -1;
625
713
    }
626
714
 
627
 
  rc = agent_scd_setattr ("LOGIN-DATA", data, n );
 
715
  rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
628
716
  if (rc)
629
717
    log_error ("error setting login data: %s\n", gpg_strerror (rc));
630
718
  xfree (data);
632
720
}
633
721
 
634
722
static int
 
723
change_private_do (const char *args, int nr)
 
724
{
 
725
  char do_name[] = "PRIVATE-DO-X";
 
726
  char *data;
 
727
  int n;
 
728
  int rc; 
 
729
 
 
730
  assert (nr >= 1 && nr <= 4);
 
731
  do_name[11] = '0' + nr;
 
732
 
 
733
  if (args && (args = strchr (args, '<')))  /* Read it from a file */
 
734
    {
 
735
      FILE *fp;
 
736
 
 
737
      /* Fixme: Factor this duplicated code out. */
 
738
      for (args++; spacep (args); args++)
 
739
        ;
 
740
      fp = fopen (args, "rb");
 
741
#if GNUPG_MAJOR_VERSION == 1
 
742
      if (fp && is_secured_file (fileno (fp)))
 
743
        {
 
744
          fclose (fp);
 
745
          fp = NULL;
 
746
          errno = EPERM;
 
747
        }
 
748
#endif
 
749
      if (!fp)
 
750
        {
 
751
          tty_printf (_("can't open `%s': %s\n"), args, strerror (errno));
 
752
          return -1;
 
753
        }
 
754
          
 
755
      data = xmalloc (254);
 
756
      n = fread (data, 1, 254, fp);
 
757
      fclose (fp);
 
758
      if (n < 0)
 
759
        {
 
760
          tty_printf (_("error reading `%s': %s\n"), args, strerror (errno));
 
761
          xfree (data);
 
762
          return -1;
 
763
        }
 
764
    }
 
765
  else
 
766
    {
 
767
      data = cpr_get ("cardedit.change_private_do",
 
768
                      _("Private DO data: "));
 
769
      if (!data)
 
770
        return -1;
 
771
      trim_spaces (data);
 
772
      cpr_kill_prompt ();
 
773
      n = strlen (data);
 
774
    }
 
775
 
 
776
  if (n > 254 )
 
777
    {
 
778
      tty_printf (_("Error: Private DO too long "
 
779
                    "(limit is %d characters).\n"), 254);    
 
780
      xfree (data);
 
781
      return -1;
 
782
    }
 
783
 
 
784
  rc = agent_scd_setattr (do_name, data, n, NULL );
 
785
  if (rc)
 
786
    log_error ("error setting private DO: %s\n", gpg_strerror (rc));
 
787
  xfree (data);
 
788
  return rc;
 
789
}
 
790
 
 
791
static int
635
792
change_lang (void)
636
793
{
637
794
  char *data, *p;
660
817
      return -1;
661
818
    }
662
819
 
663
 
  rc = agent_scd_setattr ("DISP-LANG", data, strlen (data) );
 
820
  rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL );
664
821
  if (rc)
665
822
    log_error ("error setting lang: %s\n", gpg_strerror (rc));
666
823
  xfree (data);
695
852
      return -1;
696
853
    }
697
854
     
698
 
  rc = agent_scd_setattr ("DISP-SEX", str, 1 );
 
855
  rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
699
856
  if (rc)
700
857
    log_error ("error setting sex: %s\n", gpg_strerror (rc));
701
858
  xfree (data);
740
897
 
741
898
  rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
742
899
                          fprno==2?"CA-FPR-2":
743
 
                          fprno==3?"CA-FPR-3":"x", fpr, 20 );
 
900
                          fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
744
901
  if (rc)
745
902
    log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
746
903
  return rc;
765
922
  newstate = !info.chv1_cached;
766
923
  agent_release_card_info (&info);
767
924
 
768
 
  rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1);
 
925
  rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL);
769
926
  if (rc)
770
927
    log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
771
928
}
803
960
{     
804
961
  int rc = 0;
805
962
 
 
963
  agent_clear_pin_cache (info->serialno);
 
964
 
806
965
  *forced_chv1 = !info->chv1_cached;
807
966
  if (*forced_chv1)
808
967
    { /* Switch of the forced mode so that during key generation we
809
968
         don't get bothered with PIN queries for each
810
969
         self-signature. */
811
 
      rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1);
 
970
      rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
812
971
      if (rc)
813
972
        {
814
973
          log_error ("error clearing forced signature PIN flag: %s\n",
836
995
 
837
996
  if (*forced_chv1)
838
997
    { /* Switch back to forced state. */
839
 
      rc = agent_scd_setattr ("CHV-STATUS-1", "", 1);
 
998
      rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL);
840
999
      if (rc)
841
1000
        {
842
1001
          log_error ("error setting forced signature PIN flag: %s\n",
845
1004
    }
846
1005
}
847
1006
 
848
 
#if GNUPG_MAJOR_VERSION == 1
 
1007
 
849
1008
/* Helper for the key generation/edit functions.  */
850
1009
static void
851
1010
show_card_key_info (struct agent_card_info_s *info)
858
1017
  print_sha1_fpr (NULL, info->fpr3valid? info->fpr3:NULL);
859
1018
  tty_printf ("\n");
860
1019
}
861
 
#endif
862
 
 
863
 
#if GNUPG_MAJOR_VERSION == 1
 
1020
 
 
1021
 
864
1022
/* Helper for the key generation/edit functions.  */
865
1023
static int
866
1024
replace_existing_key_p (struct agent_card_info_s *info, int keyno)
880
1038
    }
881
1039
  return 0;
882
1040
}
883
 
#endif
884
1041
 
885
1042
 
886
1043
static void
900
1057
 
901
1058
    want_backup=answer_is_yes_no_default(answer,1);
902
1059
    cpr_kill_prompt();
903
 
    m_free(answer);
 
1060
    xfree(answer);
904
1061
  }
905
1062
#else
906
1063
  want_backup = cpr_get_answer_is_yes 
936
1093
  if (check_pin_for_key_operation (&info, &forced_chv1))
937
1094
    goto leave;
938
1095
  
939
 
#if GNUPG_MAJOR_VERSION == 1
940
1096
  generate_keypair (NULL, info.serialno,
941
1097
                    want_backup? opt.homedir:NULL);
942
 
#else
943
 
  generate_keypair (NULL, info.serialno);
944
 
#endif
945
1098
 
946
1099
 leave:
947
1100
  agent_release_card_info (&info);
949
1102
}
950
1103
 
951
1104
 
952
 
/* This fucntion is used by the key edit menu to generate an arbitrary
 
1105
/* This function is used by the key edit menu to generate an arbitrary
953
1106
   subkey. */
954
1107
int
955
1108
card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
956
1109
{
957
 
#if GNUPG_MAJOR_VERSION == 1
958
1110
  struct agent_card_info_s info;
959
1111
  int okay = 0;
960
1112
  int forced_chv1 = 0;
1001
1153
  agent_release_card_info (&info);
1002
1154
  restore_forced_chv1 (&forced_chv1);
1003
1155
  return okay;
1004
 
#else
1005
 
  return 0;
1006
 
#endif
1007
1156
}
1008
1157
 
1009
1158
 
1010
 
/* Store the subkey at NODE into the smartcard and modify NODE to
1011
 
   carry the serrialno stuff instead of the actual secret key
1012
 
   parameters. */
 
1159
/* Store the key at NODE into the smartcard and modify NODE to
 
1160
   carry the serialno stuff instead of the actual secret key
 
1161
   parameters.  USE is the usage for that key; 0 means any
 
1162
   usage. */
1013
1163
int 
1014
1164
card_store_subkey (KBNODE node, int use)
1015
1165
{
1016
 
#if GNUPG_MAJOR_VERSION == 1
1017
1166
  struct agent_card_info_s info;
1018
1167
  int okay = 0;
1019
1168
  int rc;
1115
1264
  n = pubkey_get_nskey (sk->pubkey_algo);
1116
1265
  for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++)
1117
1266
    {
1118
 
      mpi_free (sk->skey[i]);
 
1267
      gcry_mpi_release (sk->skey[i]);
1119
1268
      sk->skey[i] = NULL;
1120
1269
    }
1121
1270
  i = pubkey_get_npkey (sk->pubkey_algo);
1122
 
  sk->skey[i] = mpi_set_opaque (NULL, xstrdup ("dummydata"), 10);
 
1271
  sk->skey[i] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
1123
1272
  sk->is_protected = 1;
1124
1273
  sk->protect.s2k.mode = 1002;
1125
1274
  s = info.serialno;
1134
1283
    free_secret_key (copied_sk);
1135
1284
  agent_release_card_info (&info);
1136
1285
  return okay;
1137
 
#else
1138
 
  return 0;
1139
 
#endif
1140
1286
}
1141
1287
 
1142
1288
 
1143
 
/* Menu to edit all user changeable values on an OpenPGP card.  Only
1144
 
   Key creation is not handled here. */
1145
 
void
1146
 
card_edit (STRLIST commands)
1147
 
{
1148
 
  enum cmdids {
 
1289
 
 
1290
/* Data used by the command parser.  This needs to be outside of the
 
1291
   function scope to allow readline based command completion.  */
 
1292
enum cmdids
 
1293
  {
1149
1294
    cmdNOP = 0,
1150
 
    cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG,
 
1295
    cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
1151
1296
    cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
1152
 
    cmdFORCESIG, cmdGENERATE, cmdPASSWD,
 
1297
    cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO,
1153
1298
    cmdINVCMD
1154
1299
  };
1155
1300
 
1156
 
  static struct {
1157
 
    const char *name;
1158
 
    enum cmdids id;
1159
 
    int admin_only;
1160
 
    const char *desc;
1161
 
  } cmds[] = {
1162
 
    { N_("quit")  , cmdQUIT  , 0, N_("quit this menu") },
1163
 
    { N_("q")     , cmdQUIT  , 0, NULL   },
1164
 
    { N_("admin") , cmdADMIN , 0, N_("show admin commands") },
1165
 
    { N_("help")  , cmdHELP  , 0, N_("show this help") },
1166
 
    {    "?"      , cmdHELP  , 0, NULL   },
1167
 
    { N_("list")  , cmdLIST  , 0, N_("list all available data") },
1168
 
    { N_("l")     , cmdLIST  , 0, NULL   },
1169
 
    { N_("debug") , cmdDEBUG , 0, NULL },
1170
 
    { N_("name")  , cmdNAME  , 1, N_("change card holder's name") },
1171
 
    { N_("url")   , cmdURL   , 1, N_("change URL to retrieve key") },
1172
 
    { N_("fetch") , cmdFETCH , 0,
1173
 
                               N_("fetch the key specified in the card URL") },
1174
 
    { N_("login") , cmdLOGIN , 1, N_("change the login name") },
1175
 
    { N_("lang")  , cmdLANG  , 1, N_("change the language preferences") },
1176
 
    { N_("sex")   , cmdSEX   , 1, N_("change card holder's sex") },
1177
 
    { N_("cafpr"),  cmdCAFPR,  1, N_("change a CA fingerprint") },
1178
 
    { N_("forcesig"),
1179
 
                  cmdFORCESIG, 1, N_("toggle the signature force PIN flag") },
1180
 
    { N_("generate"),
1181
 
                  cmdGENERATE, 1, N_("generate new keys") },
1182
 
    { N_("passwd"), cmdPASSWD, 0, N_("menu to change or unblock the PIN") },
 
1301
static struct
 
1302
{
 
1303
  const char *name;
 
1304
  enum cmdids id;
 
1305
  int admin_only;
 
1306
  const char *desc;
 
1307
} cmds[] =
 
1308
  {
 
1309
    { "quit"    , cmdQUIT  , 0, N_("quit this menu")},
 
1310
    { "q"       , cmdQUIT  , 0, NULL },
 
1311
    { "admin"   , cmdADMIN , 0, N_("show admin commands")},
 
1312
    { "help"    , cmdHELP  , 0, N_("show this help")},
 
1313
    { "?"       , cmdHELP  , 0, NULL },
 
1314
    { "list"    , cmdLIST  , 0, N_("list all available data")},
 
1315
    { "l"       , cmdLIST  , 0, NULL },
 
1316
    { "debug"   , cmdDEBUG , 0, NULL },
 
1317
    { "name"    , cmdNAME  , 1, N_("change card holder's name")},
 
1318
    { "url"     , cmdURL   , 1, N_("change URL to retrieve key")},
 
1319
    { "fetch"   , cmdFETCH , 0, N_("fetch the key specified in the card URL")},
 
1320
    { "login"   , cmdLOGIN , 1, N_("change the login name")},
 
1321
    { "lang"    , cmdLANG  , 1, N_("change the language preferences")},
 
1322
    { "sex"     , cmdSEX   , 1, N_("change card holder's sex")},
 
1323
    { "cafpr"   , cmdCAFPR , 1, N_("change a CA fingerprint")},
 
1324
    { "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")},
 
1325
    { "generate", cmdGENERATE, 1, N_("generate new keys")},
 
1326
    { "passwd"  , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
 
1327
    { "verify"  , cmdVERIFY, 0, N_("verify the PIN and list all data")},
 
1328
    /* Note, that we do not announce this command yet. */
 
1329
    { "privatedo", cmdPRIVATEDO, 0, NULL },
1183
1330
    { NULL, cmdINVCMD, 0, NULL } 
1184
1331
  };
1185
 
 
 
1332
 
 
1333
 
 
1334
#if GNUPG_MAJOR_VERSION == 1 && defined (HAVE_LIBREADLINE)
 
1335
 
 
1336
/* These two functions are used by readline for command completion. */
 
1337
 
 
1338
static char *
 
1339
command_generator(const char *text,int state)
 
1340
{
 
1341
  static int list_index,len;
 
1342
  const char *name;
 
1343
 
 
1344
  /* If this is a new word to complete, initialize now.  This includes
 
1345
     saving the length of TEXT for efficiency, and initializing the
 
1346
     index variable to 0. */
 
1347
  if(!state)
 
1348
    {
 
1349
      list_index=0;
 
1350
      len=strlen(text);
 
1351
    }
 
1352
 
 
1353
  /* Return the next partial match */
 
1354
  while((name=cmds[list_index].name))
 
1355
    {
 
1356
      /* Only complete commands that have help text */
 
1357
      if(cmds[list_index++].desc && strncmp(name,text,len)==0)
 
1358
        return strdup(name);
 
1359
    }
 
1360
 
 
1361
  return NULL;
 
1362
}
 
1363
 
 
1364
static char **
 
1365
card_edit_completion(const char *text, int start, int end)
 
1366
{
 
1367
  /* If we are at the start of a line, we try and command-complete.
 
1368
     If not, just do nothing for now. */
 
1369
 
 
1370
  if(start==0)
 
1371
    return rl_completion_matches(text,command_generator);
 
1372
 
 
1373
  rl_attempted_completion_over=1;
 
1374
 
 
1375
  return NULL;
 
1376
}
 
1377
#endif /* GNUPG_MAJOR_VERSION == 1 && HAVE_LIBREADLINE */
 
1378
 
 
1379
/* Menu to edit all user changeable values on an OpenPGP card.  Only
 
1380
   Key creation is not handled here. */
 
1381
void
 
1382
card_edit (strlist_t commands)
 
1383
{
1186
1384
  enum cmdids cmd = cmdNOP;
1187
1385
  int have_commands = !!commands;
1188
1386
  int redisplay = 1;
1195
1393
    ;
1196
1394
  else if (opt.batch && !have_commands)
1197
1395
    {
1198
 
      log_error(_("can't do that in batchmode\n"));
 
1396
      log_error(_("can't do this in batch mode\n"));
1199
1397
      goto leave;
1200
1398
    }
1201
1399
 
1243
1441
 
1244
1442
            if (!have_commands)
1245
1443
              {
 
1444
#if GNUPG_MAJOR_VERSION == 1
 
1445
                tty_enable_completion (card_edit_completion);
 
1446
#endif
1246
1447
                answer = cpr_get_no_help("cardedit.prompt", _("Command> "));
1247
1448
                cpr_kill_prompt();
 
1449
#if GNUPG_MAJOR_VERSION == 1
 
1450
                tty_disable_completion ();
 
1451
#endif
1248
1452
            }
1249
1453
            trim_spaces(answer);
1250
1454
        }
1292
1496
          break;
1293
1497
 
1294
1498
        case cmdADMIN:
1295
 
          allow_admin=!allow_admin;
 
1499
          if ( !strcmp (arg_string, "on") )
 
1500
            allow_admin = 1;
 
1501
          else if ( !strcmp (arg_string, "off") )
 
1502
            allow_admin = 0;
 
1503
          else if ( !strcmp (arg_string, "verify") )
 
1504
            {
 
1505
              /* Force verification of the Admin Command.  However,
 
1506
                 this is only done if the retry counter is at initial
 
1507
                 state.  */
 
1508
              char *tmp = xmalloc (strlen (serialnobuf) + 6 + 1);
 
1509
              strcpy (stpcpy (tmp, serialnobuf), "[CHV3]");
 
1510
              allow_admin = !agent_scd_checkpin (tmp);
 
1511
              xfree (tmp);
 
1512
            }
 
1513
          else /* Toggle. */
 
1514
            allow_admin=!allow_admin;
 
1515
          if(allow_admin)
 
1516
            tty_printf(_("Admin commands are allowed\n"));
 
1517
          else
 
1518
            tty_printf(_("Admin commands are not allowed\n"));
1296
1519
          break;
1297
1520
 
 
1521
        case cmdVERIFY:
 
1522
          agent_scd_checkpin (serialnobuf);
 
1523
          redisplay = 1;
 
1524
          break;
 
1525
 
1298
1526
        case cmdLIST:
1299
1527
          redisplay = 1;
1300
1528
          break;
1331
1559
            change_cafpr (arg_number);
1332
1560
          break;
1333
1561
 
 
1562
        case cmdPRIVATEDO:
 
1563
          if ( arg_number < 1 || arg_number > 4 )
 
1564
            tty_printf ("usage: privatedo N\n"
 
1565
                        "       1 <= N <= 4\n");
 
1566
          else
 
1567
            change_private_do (arg_string, arg_number);
 
1568
          break;
 
1569
 
1334
1570
        case cmdFORCESIG:
1335
1571
          toggle_forcesig ();
1336
1572
          break;