Improve some comments.
[gnupg.git] / g13 / server.c
index 31c961d..0c4563e 100644 (file)
@@ -14,7 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include "i18n.h"
 #include "keyblob.h"
 #include "server.h"
-#include "mount.h"
 #include "create.h"
+#include "mount.h"
+#include "suspend.h"
+#include "../common/server-help.h"
+#include "../common/call-gpg.h"
 
 
 /* The filepointer for status message used in non-server mode */
@@ -45,8 +48,6 @@ struct server_local_s
   assuan_context_t assuan_ctx;
 
   char *containername;  /* Malloced active containername.  */
-
-  strlist_t recipients; /* List of recipients.  */
 };
 
 
@@ -66,37 +67,6 @@ static int command_has_option (const char *cmd, const char *cmdopt);
 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
 
 
-/* Skip over options.  Blanks after the options are also removed.  */
-static char *
-skip_options (const char *line)
-{
-  while (spacep (line))
-    line++;
-  while ( *line == '-' && line[1] == '-' )
-    {
-      while (*line && !spacep (line))
-        line++;
-      while (spacep (line))
-        line++;
-    }
-  return (char*)line;
-}
-
-
-/* Check whether the option NAME appears in LINE.  */
-/* static int */
-/* has_option (const char *line, const char *name) */
-/* { */
-/*   const char *s; */
-/*   int n = strlen (name); */
-
-/*   s = strstr (line, name); */
-/*   if (s && s >= skip_options (line)) */
-/*     return 0; */
-/*   return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); */
-/* } */
-
-
 /* Helper to print a message while leaving a command.  */
 static gpg_error_t
 leave_cmd (assuan_context_t ctx, gpg_error_t err)
@@ -194,7 +164,7 @@ reset_notify (assuan_context_t ctx, char *line)
   xfree (ctrl->server_local->containername);
   ctrl->server_local->containername = NULL;
 
-  FREE_STRLIST (ctrl->server_local->recipients);
+  FREE_STRLIST (ctrl->recipients);
 
   assuan_close_input_fd (ctx);
   assuan_close_output_fd (ctx);
@@ -358,6 +328,56 @@ cmd_umount (assuan_context_t ctx, char *line)
 }
 
 
+static const char hlp_suspend[] =
+  "SUSPEND\n"
+  "\n"
+  "Suspend the currently set device.";
+static gpg_error_t
+cmd_suspend (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+
+  line = skip_options (line);
+  if (*line)
+    {
+      err = gpg_error (GPG_ERR_ASS_SYNTAX);
+      goto leave;
+    }
+
+  /* Perform the suspend operation.  */
+  err = g13_suspend_container (ctrl, ctrl->server_local->containername);
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
+static const char hlp_resume[] =
+  "RESUME\n"
+  "\n"
+  "Resume the currently set device.";
+static gpg_error_t
+cmd_resume (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+
+  line = skip_options (line);
+  if (*line)
+    {
+      err = gpg_error (GPG_ERR_ASS_SYNTAX);
+      goto leave;
+    }
+
+  /* Perform the suspend operation.  */
+  err = g13_resume_container (ctrl, ctrl->server_local->containername);
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
 static const char hlp_recipient[] =
   "RECIPIENT <userID>\n"
   "\n"
@@ -372,7 +392,7 @@ cmd_recipient (assuan_context_t ctx, char *line)
 
   line = skip_options (line);
 
-  if (!add_to_strlist_try (&ctrl->server_local->recipients, line))
+  if (!add_to_strlist_try (&ctrl->recipients, line))
     err = gpg_error_from_syserror ();
 
   return leave_cmd (ctx, err);
@@ -438,11 +458,11 @@ cmd_create (assuan_context_t ctx, char *line)
     }
 
   /* Create container.  */
-  err = g13_create_container (ctrl, line, ctrl->server_local->recipients);
+  err = g13_create_container (ctrl, line);
 
   if (!err)
     {
-      FREE_STRLIST (ctrl->server_local->recipients);
+      FREE_STRLIST (ctrl->recipients);
 
       /* Store the filename.  */
       ctrl->server_local->containername = xtrystrdup (line);
@@ -545,6 +565,8 @@ register_commands (assuan_context_t ctx)
     { "OPEN",          cmd_open,   hlp_open },
     { "MOUNT",         cmd_mount,  hlp_mount},
     { "UMOUNT",        cmd_umount, hlp_umount },
+    { "SUSPEND",       cmd_suspend, hlp_suspend },
+    { "RESUME",        cmd_resume,  hlp_resume },
     { "RECIPIENT",     cmd_recipient, hlp_recipient },
     { "SIGNER",        cmd_signer, hlp_signer },
     { "CREATE",        cmd_create, hlp_create },
@@ -611,16 +633,13 @@ g13_server (ctrl_t ctrl)
 
   if (opt.verbose || opt.debug)
     {
-      char *tmp = NULL;
-      const char *s1 = getenv ("GPG_AGENT_INFO");
+      char *tmp;
 
       tmp = xtryasprintf ("Home: %s\n"
                           "Config: %s\n"
-                          "AgentInfo: %s\n"
                           "%s",
-                          opt.homedir,
+                          gnupg_homedir (),
                           opt.config_filename,
-                          s1?s1:"[not set]",
                           hello);
       if (tmp)
         {
@@ -752,3 +771,28 @@ g13_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line)
     return 0;
   return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
 }
+
+
+/*
+ * Decrypt the keyblob (ENCKEYBLOB,ENCKEYBLOBLEN) and store the result
+ * at (R_KEYBLOB, R_KEYBLOBLEN).  Returns 0 on success or an error
+ * code.  On error R_KEYBLOB is set to NULL.
+ *
+ * This actually does not belong here but for that simple wrapper it
+ * does not make sense to add another source file.  Note that we do
+ * not want to have this in keyblob.c, because that code is also used
+ * by the syshelp.
+ */
+gpg_error_t
+g13_keyblob_decrypt (ctrl_t ctrl, const void *enckeyblob, size_t enckeybloblen,
+                     void **r_keyblob, size_t *r_keybloblen)
+{
+  gpg_error_t err;
+
+  /* FIXME:  For now we only implement OpenPGP.  */
+  err = gpg_decrypt_blob (ctrl, opt.gpg_program, opt.gpg_arguments,
+                          enckeyblob, enckeybloblen,
+                          r_keyblob, r_keybloblen);
+
+  return err;
+}