Forgot to commit this:
[gnupg.git] / sm / server.c
index 5ebd547..0e30ae8 100644 (file)
@@ -40,6 +40,8 @@ static FILE *statusfp;
 struct server_local_s {
   ASSUAN_CONTEXT assuan_ctx;
   int message_fd;
+  int list_internal;
+  int list_external;
   CERTLIST recplist;
 };
 
@@ -144,6 +146,27 @@ option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
       if (!opt.lc_messages)
         return ASSUAN_Out_Of_Core;
     }
+  else if (!strcmp (key, "list-mode"))
+    {
+      int i = *value? atoi (value) : 0;
+      if (!i || i == 1) /* default and mode 1 */
+        {
+          ctrl->server_local->list_internal = 1;
+          ctrl->server_local->list_external = 0;
+        }
+      else if (i == 2)
+        {
+          ctrl->server_local->list_internal = 0;
+          ctrl->server_local->list_external = 1;
+        }
+      else if (i == 3)
+        {
+          ctrl->server_local->list_internal = 1;
+          ctrl->server_local->list_external = 1;
+        }
+      else
+        return ASSUAN_Parameter_Error;
+    }
   else
     return ASSUAN_Invalid_Option;
 
@@ -216,11 +239,18 @@ cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
   CTRL ctrl = assuan_get_pointer (ctx);
   int rc;
 
-  rc = gpgsm_add_to_certlist (line, &ctrl->server_local->recplist);
+  rc = gpgsm_add_to_certlist (ctrl, line, &ctrl->server_local->recplist);
   if (rc)
     gpgsm_status2 (ctrl, STATUS_INV_RECP,
                    rc == -1? "1":
-                   rc == GNUPG_Ambiguous_Name? "2 ": "0 ",
+                   rc == GNUPG_Ambiguous_Name?      "2":
+                   rc == GNUPG_Wrong_Key_Usage?     "3":
+                   rc == GNUPG_Certificate_Revoked? "4":
+                   rc == GNUPG_Certificate_Expired? "5":
+                   rc == GNUPG_No_CRL_Known?        "6":
+                   rc == GNUPG_CRL_Too_Old?         "7":
+                   rc == GNUPG_No_Policy_Match?     "8":
+                   "0",
                    line, NULL);
 
   return map_to_assuan_status (rc);
@@ -420,12 +450,13 @@ static int
 cmd_export (ASSUAN_CONTEXT ctx, char *line)
 {
   CTRL ctrl = assuan_get_pointer (ctx);
-  FILE *fp = assuan_get_data_fp (ctx);
+  int fd = assuan_get_output_fd (ctx);
+  FILE *out_fp;
   char *p;
   STRLIST list, sl;
 
-  if (!fp)
-    return set_error (General_Error, "no data stream");
+  if (fd == -1)
+    return set_error (No_Output, NULL);
   
   /* break the line down into an STRLIST */
   list = NULL;
@@ -450,12 +481,67 @@ cmd_export (ASSUAN_CONTEXT ctx, char *line)
         }
     }
 
-  gpgsm_export (ctrl, list, fp);
+  out_fp = fdopen ( dup(fd), "w");
+  if (!out_fp)
+    {
+      free_strlist (list);
+      return set_error (General_Error, "fdopen() failed");
+    }
+
+  gpgsm_export (ctrl, list, out_fp);
+  fclose (out_fp);
   free_strlist (list);
+  /* close and reset the fd */
+  close_message_fd (ctrl);
+  assuan_close_input_fd (ctx);
+  assuan_close_output_fd (ctx);
   return 0;
 }
 
 
+static int 
+cmd_delkeys (ASSUAN_CONTEXT ctx, char *line)
+{
+  CTRL ctrl = assuan_get_pointer (ctx);
+  char *p;
+  STRLIST list, sl;
+  int rc;
+
+  /* break the line down into an STRLIST */
+  list = NULL;
+  for (p=line; *p; line = p)
+    {
+      while (*p && *p != ' ')
+        p++;
+      if (*p)
+        *p++ = 0;
+      if (*line)
+        {
+          sl = xtrymalloc (sizeof *sl + strlen (line));
+          if (!sl)
+            {
+              free_strlist (list);
+              return ASSUAN_Out_Of_Core;
+            }
+          sl->flags = 0;
+          strcpy_escaped_plus (sl->d, line);
+          sl->next = list;
+          list = sl;
+        }
+    }
+
+  rc = gpgsm_delete (ctrl, list);
+  free_strlist (list);
+
+  /* close and reset the fd */
+  close_message_fd (ctrl);
+  assuan_close_input_fd (ctx);
+  assuan_close_output_fd (ctx);
+
+  return map_to_assuan_status (rc);
+}
+
+
 
 /* MESSAGE FD=<n>
 
@@ -491,6 +577,7 @@ do_listkeys (ASSUAN_CONTEXT ctx, char *line, int mode)
   FILE *fp = assuan_get_data_fp (ctx);
   char *p;
   STRLIST list, sl;
+  unsigned int listmode;
 
   if (!fp)
     return set_error (General_Error, "no data stream");
@@ -519,7 +606,12 @@ do_listkeys (ASSUAN_CONTEXT ctx, char *line, int mode)
     }
 
   ctrl->with_colons = 1;
-  gpgsm_list_keys (assuan_get_pointer (ctx), list, fp, 3);
+  listmode = mode; 
+  if (ctrl->server_local->list_internal)
+    listmode |= (1<<6);
+  if (ctrl->server_local->list_external)
+    listmode |= (1<<7);
+  gpgsm_list_keys (assuan_get_pointer (ctx), list, fp, listmode);
   free_strlist (list);
   return 0;
 }
@@ -596,6 +688,7 @@ register_commands (ASSUAN_CONTEXT ctx)
     { "LISTKEYS",   0,  cmd_listkeys },
     { "LISTSECRETKEYS",  0,  cmd_listsecretkeys },
     { "GENKEY",     0,  cmd_genkey },
+    { "DELKEYS",    0,  cmd_delkeys },
     { NULL }
   };
   int i, j, rc;
@@ -654,6 +747,8 @@ gpgsm_server (void)
   ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
   ctrl.server_local->assuan_ctx = ctx;
   ctrl.server_local->message_fd = -1;
+  ctrl.server_local->list_internal = 1;
+  ctrl.server_local->list_external = 0;
 
   if (DBG_ASSUAN)
     assuan_set_log_stream (ctx, log_get_stream ());
@@ -755,6 +850,10 @@ get_status_string ( int no )
     case STATUS_INV_RECP       : s = "INV_RECP"; break;
     case STATUS_NO_RECP        : s = "NO_RECP"; break;
     case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break;
+    case STATUS_EXPSIG         : s = "EXPSIG"; break;
+    case STATUS_EXPKEYSIG      : s = "EXPKEYSIG"; break;
+    case STATUS_TRUNCATED      : s = "TRUNCATED"; break;
+    case STATUS_ERROR          : s = "ERROR"; break;
     default: s = "?"; break;
     }
   return s;
@@ -818,7 +917,12 @@ gpgsm_status2 (CTRL ctrl, int no, ...)
       n = 0;
       while ( (text = va_arg (arg_ptr, const char *)) )
         {
-          for ( ; *text && n < DIM (buf)-1; n++)
+          if (n)
+            {
+              *p++ = ' ';
+              n++;
+            }
+          for ( ; *text && n < DIM (buf)-2; n++)
             *p++ = *text++;
         }
       *p = 0;
@@ -900,10 +1004,3 @@ write_status_text_and_buffer ( int no, const char *string,
     fflush (statusfp);
 }
 #endif
-
-
-
-
-
-
-