* card-util.c (change_login): Kludge to allow reading data from a
authorWerner Koch <wk@gnupg.org>
Thu, 1 Jul 2004 17:42:09 +0000 (17:42 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 1 Jul 2004 17:42:09 +0000 (17:42 +0000)
file.
(card_edit): Pass ARG_STRING to change_login.
(card_status): Print CA fingerprints.
(change_cafpr): New.
(card_edit): New command CAFPR.

* call-agent.h: Add members for CA fingerprints.
* call-agent.c (agent_release_card_info): Invalid them.
(learn_status_cb): Store them.

g10/ChangeLog
g10/call-agent.c
g10/call-agent.h
g10/card-util.c

index 0e87c2f..7a8ccd5 100644 (file)
@@ -1,3 +1,16 @@
+2004-07-01  Werner Koch  <wk@gnupg.org>
+
+       * card-util.c (change_login): Kludge to allow reading data from a
+       file.
+       (card_edit): Pass ARG_STRING to change_login.
+       (card_status): Print CA fingerprints.
+       (change_cafpr): New.
+       (card_edit): New command CAFPR.
+
+       * call-agent.h: Add members for CA fingerprints.
+       * call-agent.c (agent_release_card_info): Invalid them.
+       (learn_status_cb): Store them.
+
 2004-04-30  Werner Koch  <wk@gnupg.org>
 
        * g10.c (main) <gpgconf>: Use gpg.conf and not /dev/null as
index de157d4..f93132f 100644 (file)
@@ -461,6 +461,7 @@ agent_release_card_info (struct agent_card_info_s *info)
   xfree (info->disp_lang); info->disp_lang = NULL;
   xfree (info->pubkey_url); info->pubkey_url = NULL;
   xfree (info->login_data); info->login_data = NULL;
+  info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
   info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
 }
 
@@ -557,6 +558,20 @@ learn_status_cb (void *opaque, const char *line)
       else if (no == 3)
         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
     }
+  else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
+    {
+      int no = atoi (line);
+      while (*line && !spacep (line))
+        line++;
+      while (spacep (line))
+        line++;
+      if (no == 1)
+        parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
+      else if (no == 2)
+        parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
+      else if (no == 3)
+        parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
+    }
   
   return 0;
 }
index 8751101..3d9f4f9 100644 (file)
@@ -29,6 +29,12 @@ struct agent_card_info_s {
   int  disp_sex;     /* 0 = unspecified, 1 = male, 2 = female */
   char *pubkey_url;  /* malloced. */
   char *login_data;  /* malloced. */
+  char cafpr1valid;
+  char cafpr2valid;
+  char cafpr3valid;
+  char cafpr1[20];
+  char cafpr2[20];
+  char cafpr3[20];
   char fpr1valid;
   char fpr2valid;
   char fpr3valid;
index c93d028..2d7f008 100644 (file)
@@ -336,6 +336,11 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
                    info.chvretry[0], info.chvretry[1], info.chvretry[2]);
       fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
 
+      fputs ("cafpr:", fp);
+      print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
+      print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
+      print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL);
+      putc ('\n', fp);
       fputs ("fpr:", fp);
       print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
       print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
@@ -362,6 +367,21 @@ card_status (FILE *fp, char *serialno, size_t serialnobuflen)
                    info.disp_sex == 2? _("female") : _("unspecified"));
       print_name (fp, "URL of public key : ", info.pubkey_url);
       print_name (fp, "Login data .......: ", info.login_data);
+      if (info.cafpr1valid)
+        {
+          tty_fprintf (fp, "CA fingerprint %d .:", 1);
+          print_sha1_fpr (fp, info.cafpr1);
+        }
+      if (info.cafpr2valid)
+        {
+          tty_fprintf (fp, "CA fingerprint %d .:", 2);
+          print_sha1_fpr (fp, info.cafpr2);
+        }
+      if (info.cafpr3valid)
+        {
+          tty_fprintf (fp, "CA fingerprint %d .:", 3);
+          print_sha1_fpr (fp, info.cafpr3);
+        }
       tty_fprintf (fp,    "Signature PIN ....: %s\n",
                    info.chv1_cached? _("not forced"): _("forced"));
       tty_fprintf (fp,    "Max. PIN lengths .: %d %d %d\n",
@@ -491,19 +511,46 @@ change_url (void)
 }
 
 static int
-change_login (void)
+change_login (const char *args)
 {
   char *data;
+  int n;
   int rc;
 
-  data = cpr_get ("cardedit.change_login",
-                  _("Login data (account name): "));
-  if (!data)
-    return -1;
-  trim_spaces (data);
-  cpr_kill_prompt ();
+  if (args && *args == '<')  /* Read it from a file */
+    {
+      FILE *fp;
 
-  if (strlen (data) > 254 )
+      for (args++; spacep (args); args++)
+        ;
+      fp = fopen (args, "rb");
+      if (!fp)
+        {
+          tty_printf ("can't open `%s': %s\n", args, strerror (errno));
+          return -1;
+        }
+      data = xmalloc (254);
+      n = fread (data, 1, 254, fp);
+      fclose (fp);
+      if (n < 0)
+        {
+          tty_printf ("error reading `%s': %s\n", args, strerror (errno));
+          xfree (data);
+          return -1;
+        }
+    }
+  else
+    {
+      data = cpr_get ("cardedit.change_login",
+                      _("Login data (account name): "));
+      if (!data)
+        return -1;
+      trim_spaces (data);
+      cpr_kill_prompt ();
+      n = strlen (data);
+    }
+
+  if (n > 254 )
     {
       tty_printf (_("Error: Login data too long "
                     "(limit is %d characters).\n"), 254);    
@@ -511,7 +558,7 @@ change_login (void)
       return -1;
     }
 
-  rc = agent_scd_setattr ("LOGIN-DATA", data, strlen (data) );
+  rc = agent_scd_setattr ("LOGIN-DATA", data, n );
   if (rc)
     log_error ("error setting login data: %s\n", gpg_strerror (rc));
   xfree (data);
@@ -590,6 +637,51 @@ change_sex (void)
 }
 
 
+static int
+change_cafpr (int fprno)
+{
+  char *data;
+  const char *s;
+  int i, c, rc;
+  unsigned char fpr[20];
+
+  data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
+  if (!data)
+    return -1;
+  trim_spaces (data);
+  cpr_kill_prompt ();
+
+  for (i=0, s=data; i < 20 && *s; )
+    {
+      while (spacep(s))
+        s++;
+      if (*s == ':')
+        s++;
+      while (spacep(s))
+        s++;
+      c = hextobyte (s);
+      if (c == -1)
+        break;
+      fpr[i++] = c;
+      s += 2;
+    }
+  xfree (data);
+  if (i != 20 || *s)
+    {
+      tty_printf (_("Error: invalid formatted fingerprint.\n"));
+      return -1;
+    }
+
+  rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
+                          fprno==2?"CA-FPR-2":
+                          fprno==3?"CA-FPR-3":"x", fpr, 20 );
+  if (rc)
+    log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
+  return rc;
+}
+
+
+
 static void
 toggle_forcesig (void)
 {
@@ -700,7 +792,7 @@ card_edit (STRLIST commands)
   enum cmdids {
     cmdNOP = 0,
     cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
-    cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX,
+    cmdNAME, cmdURL, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
     cmdFORCESIG, cmdGENERATE, cmdPASSWD,
     cmdINVCMD
   };
@@ -722,6 +814,7 @@ card_edit (STRLIST commands)
     { N_("login") , cmdLOGIN , N_("change the login name") },
     { N_("lang")  , cmdLANG  , N_("change the language preferences") },
     { N_("sex")   , cmdSEX   , N_("change card holder's sex") },
+    { N_("cafpr"),  cmdCAFPR,  N_("change a CA fingerprint") },
     { N_("forcesig"),
                   cmdFORCESIG, N_("toggle the signature force PIN flag") },
     { N_("generate"),
@@ -840,7 +933,7 @@ card_edit (STRLIST commands)
           break;
 
         case cmdLOGIN:
-          change_login ();
+          change_login (arg_string);
           break;
 
         case cmdLANG:
@@ -851,6 +944,14 @@ card_edit (STRLIST commands)
           change_sex ();
           break;
 
+        case cmdCAFPR:
+          if ( arg_number < 1 || arg_number > 3 )
+            tty_printf ("usage: cafpr N\n"
+                        "       1 <= N <= 3\n");
+          else
+            change_cafpr (arg_number);
+          break;
+
         case cmdFORCESIG:
           toggle_forcesig ();
           break;