Example #1
0
gpgme_error_t
gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
		      const char *container_file, unsigned int flags,
		      gpgme_error_t *op_err)
{
  gpg_error_t err;

  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_vfs_create", ctx,
	      "container_file=%s, flags=0x%x, op_err=%p",
	      container_file, flags, op_err);

  if (!ctx)
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));

  if (_gpgme_debug_trace () && recp)
    {
      int i = 0;
      
      while (recp[i])
	{
	  TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
		      (recp[i]->subkeys && recp[i]->subkeys->fpr) ? 
		      recp[i]->subkeys->fpr : "invalid");
	  i++;
	}
    }

  err = _gpgme_op_vfs_create (ctx, recp, container_file, flags, op_err);
  return TRACE_ERR (err);
}
Example #2
0
gpgme_error_t
gpgme_op_export_keys (gpgme_ctx_t ctx,
                      gpgme_key_t keys[],
                      gpgme_export_mode_t mode,
                      gpgme_data_t keydata)
{
  gpgme_error_t err;

  TRACE_BEG2 (DEBUG_CTX, "gpgme_op_export_keys", ctx,
	      "mode=0x%x, keydata=%p", mode, keydata);
  
  if (_gpgme_debug_trace () && keys)
    {
      int i = 0;

      while (keys[i])
	{
	  TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i],
		      (keys[i]->subkeys && keys[i]->subkeys->fpr) ? 
		      keys[i]->subkeys->fpr : "invalid");
	  i++;
	}
    }

  err = export_keys_start (ctx, 1, keys, mode, keydata);
  if (!err)
    err = _gpgme_wait_one (ctx);
  return TRACE_ERR (err);
}
Example #3
0
/* Import the keys from the array KEYS into the keyring.  This
   function allows to move a key from one engine to another as long as
   they are compatible.  In particular it is used to actually import
   keys retrieved from an external source (i.e. using
   GPGME_KEYLIST_MODE_EXTERN).  It replaces the old workaround of
   exporting and then importing a key as used to make an X.509 key
   permanent.  This function automagically does the right thing.

   KEYS is a NULL terminated array of gpgme key objects.  The result
   is the usual import result structure.  Only keys matching the
   current protocol are imported; other keys are ignored.  */
gpgme_error_t
gpgme_op_import_keys (gpgme_ctx_t ctx, gpgme_key_t *keys)
{
  gpgme_error_t err;

  TRACE_BEG (DEBUG_CTX, "gpgme_op_import_keys", ctx);

  if (!ctx)
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));

  if (_gpgme_debug_trace () && keys)
    {
      int i = 0;

      while (keys[i])
	{
	  TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i],
		      (keys[i]->subkeys && keys[i]->subkeys->fpr) ?
		      keys[i]->subkeys->fpr : "invalid");
	  i++;
	}
    }

  err = _gpgme_op_import_keys_start (ctx, 1, keys);
  if (!err)
    err = _gpgme_wait_one (ctx);
  return TRACE_ERR (err);
}
Example #4
0
/* Encrypt plaintext PLAIN within CTX for the recipients RECP and
   store the resulting ciphertext in CIPHER.  Also sign the ciphertext
   with the signers in CTX.  */
gpgme_error_t
gpgme_op_encrypt_sign_start (gpgme_ctx_t ctx, gpgme_key_t recp[],
			     gpgme_encrypt_flags_t flags,
			     gpgme_data_t plain, gpgme_data_t cipher)
{
  gpgme_error_t err;

  TRACE_BEG3 (DEBUG_CTX, "gpgme_op_encrypt_sign_start", ctx,
	      "flags=0x%x, plain=%p, cipher=%p", flags, plain, cipher);

  if (!ctx)
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
  
  if (_gpgme_debug_trace () && recp)
    {
      int i = 0;

      while (recp[i])
	{
	  TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
		      (recp[i]->subkeys && recp[i]->subkeys->fpr) ? 
		      recp[i]->subkeys->fpr : "invalid");
	  i++;
	}
    }

  err = encrypt_sign_start (ctx, 0, recp, flags, plain, cipher);
  return err;
}
Example #5
0
gpgme_import_result_t
gpgme_op_import_result (gpgme_ctx_t ctx)
{
  void *hook;
  op_data_t opd;
  gpgme_error_t err;

  TRACE_BEG (DEBUG_CTX, "gpgme_op_import_result", ctx);

  err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, -1, NULL);
  opd = hook;
  if (err || !opd)
    {
      TRACE_SUC0 ("result=(null)");
      return NULL;
    }

  
  if (_gpgme_debug_trace ())
    {
      gpgme_import_status_t impstat;
      int i;

      TRACE_LOG5 ("%i considered, %i no UID, %i imported, %i imported RSA, "
		  "%i unchanged", opd->result.considered,
		  opd->result.no_user_id, opd->result.imported,
		  opd->result.imported_rsa, opd->result.unchanged);
      TRACE_LOG4 ("%i new UIDs, %i new sub keys, %i new signatures, "
		  "%i new revocations", opd->result.new_user_ids,
		  opd->result.new_sub_keys, opd->result.new_signatures,
		  opd->result.new_revocations);
      TRACE_LOG3 ("%i secret keys, %i imported, %i unchanged",
		  opd->result.secret_read, opd->result.secret_imported,
		  opd->result.secret_unchanged);
      TRACE_LOG2 ("%i skipped new keys, %i not imported",
		  opd->result.skipped_new_keys, opd->result.not_imported);

      impstat = opd->result.imports;
      i = 0;
      while (impstat)
	{
	  TRACE_LOG4 ("import[%i] for %s = 0x%x (%s)",
		      i, impstat->fpr, impstat->status, impstat->result);
	  impstat = impstat->next;
	  i++;
	}
    }

  TRACE_SUC1 ("result=%p", &opd->result);
  return &opd->result;
}
Example #6
0
gpgme_decrypt_result_t
gpgme_op_decrypt_result (gpgme_ctx_t ctx)
{
  void *hook;
  op_data_t opd;
  gpgme_error_t err;

  TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx);

  err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL);
  opd = hook;
  if (err || !opd)
    {
      TRACE_SUC0 ("result=(null)");
      return NULL;
    }

  if (_gpgme_debug_trace ())
    {
      gpgme_recipient_t rcp;

      if (opd->result.unsupported_algorithm)
	{
	  TRACE_LOG1 ("result: unsupported_algorithm: %s",
		      opd->result.unsupported_algorithm);
	}
      if (opd->result.wrong_key_usage)
	{
	  TRACE_LOG ("result: wrong key usage");
	}
      rcp = opd->result.recipients;
      while (rcp)
	{
	  TRACE_LOG3 ("result: recipient: keyid=%s, pubkey_algo=%i, "
		      "status=%s", rcp->keyid, rcp->pubkey_algo,
		      gpg_strerror (rcp->status));
	  rcp = rcp->next;
	}
      if (opd->result.file_name)
	{
	  TRACE_LOG1 ("result: original file name: %s", opd->result.file_name);
	}
    }

  TRACE_SUC1 ("result=%p", &opd->result);
  return &opd->result;
}
Example #7
0
int
_gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
		 struct spawn_fd_item_s *fd_list,
		 void (*atfork) (void *opaque, int reserved),
		 void *atforkvalue, pid_t *r_pid)
{
  SECURITY_ATTRIBUTES sec_attr;
  PROCESS_INFORMATION pi =
    {
      NULL,      /* returns process handle */
      0,         /* returns primary thread handle */
      0,         /* returns pid */
      0          /* returns tid */
    };
  STARTUPINFO si;
  int cr_flags = (CREATE_DEFAULT_ERROR_MODE
                  | GetPriorityClass (GetCurrentProcess ()));
  int i;
  char **args;
  char *arg_string;
  /* FIXME.  */
  int debug_me = 0;
  int tmp_fd;
  char *tmp_name;

  TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_spawn", path,
	      "path=%s", path);
  i = 0;
  while (argv[i])
    {
      TRACE_LOG2 ("argv[%2i] = %s", i, argv[i]);
      i++;
    }
  
  /* We do not inherit any handles by default, and just insert those
     handles we want the child to have afterwards.  But some handle
     values occur on the command line, and we need to move
     stdin/out/err to the right location.  So we use a wrapper program
     which gets the information from a temporary file.  */
  if (_gpgme_mkstemp (&tmp_fd, &tmp_name) < 0)
    {
      TRACE_LOG1 ("_gpgme_mkstemp failed: %s", strerror (errno));
      return TRACE_SYSRES (-1);
    }
  TRACE_LOG1 ("tmp_name = %s", tmp_name);

  args = calloc (2 + i + 1, sizeof (*args));
  args[0] = (char *) _gpgme_get_w32spawn_path ();
  args[1] = tmp_name;
  args[2] = path;
  memcpy (&args[3], &argv[1], i * sizeof (*args));

  memset (&sec_attr, 0, sizeof sec_attr);
  sec_attr.nLength = sizeof sec_attr;
  sec_attr.bInheritHandle = FALSE;
  
  arg_string = build_commandline (args);
  free (args);
  if (!arg_string)
    {
      close (tmp_fd);
      DeleteFile (tmp_name);
      return TRACE_SYSRES (-1);
    }

  memset (&si, 0, sizeof si);
  si.cb = sizeof (si);
  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  si.wShowWindow = debug_me ? SW_SHOW : SW_HIDE;
  si.hStdInput = INVALID_HANDLE_VALUE;
  si.hStdOutput = INVALID_HANDLE_VALUE;
  si.hStdError = INVALID_HANDLE_VALUE;

  cr_flags |= CREATE_SUSPENDED;
  cr_flags |= DETACHED_PROCESS;
  if (!CreateProcessA (_gpgme_get_w32spawn_path (),
		       arg_string,
		       &sec_attr,     /* process security attributes */
		       &sec_attr,     /* thread security attributes */
		       FALSE,         /* inherit handles */
		       cr_flags,      /* creation flags */
		       NULL,          /* environment */
		       NULL,          /* use current drive/directory */
		       &si,           /* startup information */
		       &pi))          /* returns process information */
    {
      TRACE_LOG1 ("CreateProcess failed: ec=%d", (int) GetLastError ());
      free (arg_string);
      close (tmp_fd);
      DeleteFile (tmp_name);

      /* FIXME: Should translate the error code.  */
      errno = EIO;
      return TRACE_SYSRES (-1);
    }

  free (arg_string);
  
  if (flags & IOSPAWN_FLAG_ALLOW_SET_FG)
    _gpgme_allow_set_foreground_window ((pid_t)pi.dwProcessId);

  /* Insert the inherited handles.  */
  for (i = 0; fd_list[i].fd != -1; i++)
    {
      HANDLE hd;

      /* Make it inheritable for the wrapper process.  */
      if (!DuplicateHandle (GetCurrentProcess(),
			    _get_osfhandle (giochannel_table[fd_list[i].fd].fd),
			    pi.hProcess, &hd, 0, TRUE, DUPLICATE_SAME_ACCESS))
	{
	  TRACE_LOG1 ("DuplicateHandle failed: ec=%d", (int) GetLastError ());
	  TerminateProcess (pi.hProcess, 0);
	  /* Just in case TerminateProcess didn't work, let the
	     process fail on its own.  */
	  ResumeThread (pi.hThread);
	  CloseHandle (pi.hThread);
	  CloseHandle (pi.hProcess);

	  close (tmp_fd);
	  DeleteFile (tmp_name);

	  /* FIXME: Should translate the error code.  */
	  errno = EIO;
	  return TRACE_SYSRES (-1);
        }
      /* Return the child name of this handle.  */
      fd_list[i].peer_name = (int) hd;
    }

  /* Write the handle translation information to the temporary
     file.  */
  {
    /* Hold roughly MAX_TRANS quadruplets of 64 bit numbers in hex
       notation: "0xFEDCBA9876543210" with an extra white space after
       every quadruplet.  10*(19*4 + 1) - 1 = 769.  This plans ahead
       for a time when a HANDLE is 64 bit.  */
#define BUFFER_MAX 800
    char line[BUFFER_MAX + 1];
    int res;
    int written;
    size_t len;

    if ((flags & IOSPAWN_FLAG_ALLOW_SET_FG))
      strcpy (line, "~1 \n");
    else
      strcpy (line, "\n");
    for (i = 0; fd_list[i].fd != -1; i++)
      {
	/* Strip the newline.  */
	len = strlen (line) - 1;
	
	/* Format is: Local name, stdin/stdout/stderr, peer name, argv idx.  */
	snprintf (&line[len], BUFFER_MAX - len, "0x%x %d 0x%x %d  \n",
		  fd_list[i].fd, fd_list[i].dup_to,
		  fd_list[i].peer_name, fd_list[i].arg_loc);
	/* Rather safe than sorry.  */
	line[BUFFER_MAX - 1] = '\n';
	line[BUFFER_MAX] = '\0';
      }
    len = strlen (line);
    written = 0;
    do
      {
	res = write (tmp_fd, &line[written], len - written);
	if (res > 0)
	  written += res;
      }
    while (res > 0 || (res < 0 && errno == EAGAIN));
  }
  close (tmp_fd);
  /* The temporary file is deleted by the gpgme-w32spawn process
     (hopefully).  */
    
  TRACE_LOG4 ("CreateProcess ready: hProcess=%p, hThread=%p, "
	      "dwProcessID=%d, dwThreadId=%d",
	      pi.hProcess, pi.hThread, 
	      (int) pi.dwProcessId, (int) pi.dwThreadId);
  
  if (r_pid)
    *r_pid = (pid_t)pi.dwProcessId;

  if (ResumeThread (pi.hThread) < 0)
    TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ());
  
  if (!CloseHandle (pi.hThread))
    TRACE_LOG1 ("CloseHandle of thread failed: ec=%d",
		(int) GetLastError ());

  TRACE_LOG1 ("process=%p", pi.hProcess);

  /* We don't need to wait for the process.  */
  if (!CloseHandle (pi.hProcess))
    TRACE_LOG1 ("CloseHandle of process failed: ec=%d",
		(int) GetLastError ());

  if (! (flags & IOSPAWN_FLAG_NOCLOSE))
    {
      for (i = 0; fd_list[i].fd != -1; i++)
	_gpgme_io_close (fd_list[i].fd);
    }

  for (i = 0; fd_list[i].fd != -1; i++)
    if (fd_list[i].dup_to == -1)
      TRACE_LOG3 ("fd[%i] = 0x%x -> 0x%x", i, fd_list[i].fd,
		  fd_list[i].peer_name);
    else
      TRACE_LOG4 ("fd[%i] = 0x%x -> 0x%x (std%s)", i, fd_list[i].fd,
		  fd_list[i].peer_name, (fd_list[i].dup_to == 0) ? "in" :
		  ((fd_list[i].dup_to == 1) ? "out" : "err"));

  return TRACE_SYSRES (0);
}