* command.c (cmd_marktrusted): Implemented.
authorWerner Koch <wk@gnupg.org>
Mon, 18 Feb 2002 20:44:48 +0000 (20:44 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 18 Feb 2002 20:44:48 +0000 (20:44 +0000)
* trustlist.c (agent_marktrusted): New.
(open_list): Add APPEND arg.

* query.c (agent_get_confirmation): New.

agent/ChangeLog
agent/agent.h
agent/command.c
agent/query.c
agent/trustlist.c

index 18f02f7..9a398f5 100644 (file)
@@ -1,3 +1,11 @@
+2002-02-18  Werner Koch  <wk@gnupg.org>
+
+       * command.c (cmd_marktrusted): Implemented.
+       * trustlist.c (agent_marktrusted): New.
+       (open_list): Add APPEND arg.
+
+       * query.c (agent_get_confirmation): New.
+
 2002-02-06  Werner Koch  <wk@gnupg.org>
 
        * cache.c (housekeeping): Fixed linking in the remove case.
 2002-02-06  Werner Koch  <wk@gnupg.org>
 
        * cache.c (housekeeping): Fixed linking in the remove case.
index 9236ef0..a4cf862 100644 (file)
@@ -110,6 +110,7 @@ int agent_askpin (const char *desc_text, const char *err_text,
 int agent_get_passphrase (char **retpass,
                           const char *desc, const char *prompt,
                           const char *errtext);
 int agent_get_passphrase (char **retpass,
                           const char *desc, const char *prompt,
                           const char *errtext);
+int agent_get_confirmation (const char *desc, const char *prompt);
 
 /*-- cache.c --*/
 int agent_put_cache (const char *key, const char *data, int ttl);
 
 /*-- cache.c --*/
 int agent_put_cache (const char *key, const char *data, int ttl);
@@ -139,7 +140,7 @@ int agent_private_key_type (const unsigned char *privatekey);
 /*-- trustlist.c --*/
 int agent_istrusted (const char *fpr);
 int agent_listtrusted (void *assuan_context);
 /*-- trustlist.c --*/
 int agent_istrusted (const char *fpr);
 int agent_listtrusted (void *assuan_context);
-
+int agent_marktrusted (const char *name, const char *fpr, int flag);
 
 
 #endif /*AGENT_H*/
 
 
 #endif /*AGENT_H*/
index bbcab8e..0a32962 100644 (file)
@@ -108,13 +108,42 @@ cmd_listtrusted (ASSUAN_CONTEXT ctx, char *line)
 }
 
 
 }
 
 
-/* MARKTRUSTED <hexstring_with_fingerprint> <flag>
+/* MARKTRUSTED <hexstring_with_fingerprint> <flag> <display_name>
 
    Store a new key in into the trustlist*/
 static int
 cmd_marktrusted (ASSUAN_CONTEXT ctx, char *line)
 {
 
    Store a new key in into the trustlist*/
 static int
 cmd_marktrusted (ASSUAN_CONTEXT ctx, char *line)
 {
-  return ASSUAN_Not_Implemented;
+  int rc, n, i;
+  char *p;
+  char fpr[41];
+  int flag;
+
+  /* parse the fingerprint value */
+  for (p=line,n=0; hexdigitp (p); p++, n++)
+    ;
+  if (!spacep (p) || !(n == 40 || n == 32))
+    return set_error (Parameter_Error, "invalid fingerprint");
+  i = 0;
+  if (n==32)
+    {
+      strcpy (fpr, "00000000");
+      i += 8;
+    }
+  for (p=line; i < 40; p++, i++)
+    fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
+  fpr[i] = 0;
+  
+  while (spacep (p))
+    p++;
+  flag = *p++;
+  if ( (flag != 'S' && flag != 'P') || !spacep (p) )
+    return set_error (Parameter_Error, "invalid flag - must be P or S");
+  while (spacep (p))
+    p++;
+
+  rc = agent_marktrusted (p, fpr, flag);
+  return map_to_assuan_status (rc);
 }
 
 
 }
 
 
@@ -476,7 +505,7 @@ register_commands (ASSUAN_CONTEXT ctx)
 }
 
 
 }
 
 
-/* Startup the server.  If LISTEN_FD is given as -1, this is simple
+/* Startup the server.  If LISTEN_FD is given as -1, this is simple
    piper server, otherwise it is a regular server */
 void
 start_command_handler (int listen_fd)
    piper server, otherwise it is a regular server */
 void
 start_command_handler (int listen_fd)
index 3b8cd08..1abfefc 100644 (file)
@@ -297,6 +297,42 @@ agent_get_passphrase (char **retpass, const char *desc, const char *prompt,
 }
 
 
 }
 
 
+\f
+/* Pop up the PIN-entry, display the text and the prompt and ask the
+   user to confirm this.  We return 0 for success, ie. the used
+   confirmed it, GNUPG_Not_Confirmed for what the text says or an
+   other error. */
+int 
+agent_get_confirmation (const char *desc, const char *prompt)
+{
+  int rc;
+  char line[ASSUAN_LINELENGTH];
+
+  rc = start_pinentry ();
+  if (rc)
+    return rc;
+
+  if (desc)
+    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
+  else
+    snprintf (line, DIM(line)-1, "RESET");
+  line[DIM(line)-1] = 0;
+  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL);
+  if (rc)
+    return map_assuan_err (rc);
+
+  if (prompt)
+    {
+      snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
+      line[DIM(line)-1] = 0;
+      rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL);
+      if (rc)
+        return map_assuan_err (rc);
+    }
+
+  rc = assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL);
+  return map_assuan_err (rc);
+}
 
 
 
 
 
 
index 222d2dc..15208ce 100644 (file)
@@ -40,7 +40,7 @@ static const char headerblurb[] =
 "# length limit but this is not serious limitation as the format of the\n"
 "# entries is fixed and checked by gpg-agent: A non-comment line starts\n"
 "# with optional white spaces, followed by exactly 40 hex character,\n"
 "# length limit but this is not serious limitation as the format of the\n"
 "# entries is fixed and checked by gpg-agent: A non-comment line starts\n"
 "# with optional white spaces, followed by exactly 40 hex character,\n"
-"# optioanlly followed by a flag charcter which my either be 'P', 'S'\n"
+"# optioanlly followed by a flag character which my either be 'P', 'S'\n"
 "# or '*'. Additional data delimited with by a white space is ignored.\n"
 "\n";
 
 "# or '*'. Additional data delimited with by a white space is ignored.\n"
 "\n";
 
@@ -49,12 +49,12 @@ static FILE *trustfp;
 
 
 static int
 
 
 static int
-open_list (void)
+open_list (int append)
 {
   char *fname;
 
   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
 {
   char *fname;
 
   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
-  trustfp = fopen (fname, "r");
+  trustfp = fopen (fname, append? "a+":"r");
   if (!trustfp && errno == ENOENT)
     {
       trustfp = fopen (fname, "wx");
   if (!trustfp && errno == ENOENT)
     {
       trustfp = fopen (fname, "wx");
@@ -66,7 +66,7 @@ open_list (void)
         }
       fputs (headerblurb, trustfp);
       fclose (trustfp);
         }
       fputs (headerblurb, trustfp);
       fclose (trustfp);
-      trustfp = fopen (fname, "r");
+      trustfp = fopen (fname, append? "a+":"r");
     }
 
   if (!trustfp)
     }
 
   if (!trustfp)
@@ -98,7 +98,7 @@ read_list (char *key, int *keyflag)
   
   if (!trustfp)
     {
   
   if (!trustfp)
     {
-      rc = open_list ();
+      rc = open_list (0);
       if (rc)
         return rc;
     }
       if (rc)
         return rc;
     }
@@ -162,7 +162,7 @@ read_list (char *key, int *keyflag)
   return 0;
 }
 
   return 0;
 }
 
-/* check whether the given fr is in our trustdb.  We expect FPR to be
+/* check whether the given fpr is in our trustdb.  We expect FPR to be
    an all uppercase hexstring of 40 characters. */
 int 
 agent_istrusted (const char *fpr)
    an all uppercase hexstring of 40 characters. */
 int 
 agent_istrusted (const char *fpr)
@@ -220,8 +220,85 @@ agent_listtrusted (void *assuan_context)
 }
 
 
 }
 
 
+/* Insert the given fpr into our trustdb.  We expect FPR to be an all
+   uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'.
+   This function does first check whether that key has alreay ben put
+   into the trustdb and returns success in this case.  Before a FPR
+   actually gets inserted, the user is asked by means of the pin-entry
+   whether this is actual wants he want to do.
+*/
+int 
+agent_marktrusted (const char *name, const char *fpr, int flag)
+{
+  int rc;
+  static char key[41];
+  int keyflag;
+  char *desc;
 
 
+  if (trustfp)
+    rewind (trustfp);
+  while (!(rc=read_list (key, &keyflag)))
+    {
+      if (!strcmp (key, fpr))
+        return 0;
+    }
+  fclose (trustfp);
+  trustfp = NULL;
+  if (rc != -1)
+    return rc;   /* error in the trustdb */
 
 
+  /* insert a new one */
+  if (asprintf (&desc,
+                "Please verify that the certificate identified as:%%0A"
+                "  \"%s\"%%0A"
+                "has the fingerprint:%%0A"
+                "  %s", name, fpr) < 0 )
+    return GNUPG_Out_Of_Core;
+  rc = agent_get_confirmation (desc, "Correct|No");
+  free (desc);
+  if (rc)
+    return rc;
 
 
+  if (asprintf (&desc,
+                "Do you ultimately trust%%0A"
+                "  \"%s\"%%0A"
+                "to correctly certify user certificates?",
+                name) < 0 )
+    return GNUPG_Out_Of_Core;
+  rc = agent_get_confirmation (desc, "Yes|No");
+  free (desc);
+  if (rc)
+    return rc;
 
 
+  /* now check again to avoid duplicates.  Also open in append mode now */
+  rc = open_list (1);
+  if (rc)
+    return rc;
+  rewind (trustfp);
+  while (!(rc=read_list (key, &keyflag)))
+    {
+      if (!strcmp (key, fpr))
+        return 0;
+    }
+  if (rc != -1)
+    {
+      fclose (trustfp);
+      trustfp = NULL;
+      return rc;   /* error in the trustdb */
+    }
+  rc = 0;
 
 
+  /* append the key */
+  fflush (trustfp);
+  fputs ("\n# ", trustfp);
+  print_sanitized_string (trustfp, name, 0);
+  fprintf (trustfp, "\n%s %c\n", fpr, flag);
+  if (ferror (trustfp))
+    rc = GNUPG_Write_Error;
+  
+  /* close because we are in append mode */
+  if (fclose (trustfp))
+    rc = GNUPG_File_Error;
+  trustfp = NULL;
+  return rc;
+}