Exemplo n.º 1
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);
}
Exemplo n.º 2
0
gpgme_assuan_result_t
gpgme_op_assuan_result (gpgme_ctx_t ctx)
{
  gpgme_error_t err;
  void *hook;
  op_data_t opd;

  TRACE_BEG (DEBUG_CTX, "gpgme_op_assuan_result", ctx);

  err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL);
  opd = hook;
  /* Check in case this function is used without having run a command
     before.  */
  if (err || !opd)
    {
      TRACE_SUC0 ("result=(null)");
      return NULL;
    }

  /* All of this is a hack for the old style interface.  The new style
     interface returns op errors directly.  */
  opd->result.err = _gpgme_engine_assuan_last_op_err (ctx->engine->engine);
  if (opd->result.err)
    {
      TRACE_LOG1 ("err = %s", gpg_strerror (0));
    }
  else
    {
      TRACE_LOG2 ("err = %s <%s>", gpg_strerror (opd->result.err),
		  gpg_strsource (opd->result.err));
    }

  TRACE_SUC1 ("result=%p", &opd->result);
  return &opd->result;
}
Exemplo n.º 3
0
int
_gpgme_io_set_nonblocking (int fd)
{
  GIOChannel *chan;
  GIOStatus status;
 
  TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_nonblocking", fd);

  chan = find_channel (fd);
  if (!chan)
    {
      errno = EIO;
      return TRACE_SYSRES (-1);
    }

  status = g_io_channel_set_flags (chan,
				   g_io_channel_get_flags (chan) |
				   G_IO_FLAG_NONBLOCK, NULL);

  if (status != G_IO_STATUS_NORMAL)
    {
#if 0
      /* glib 1.9.2 does not implement set_flags and returns an
	 error.  */
      errno = EIO;
      return TRACE_SYSRES (-1);
#else
      TRACE_LOG1 ("g_io_channel_set_flags failed: status=%d (ignored)",
		  status);
#endif
    }

  return TRACE_SYSRES (0);
}
Exemplo n.º 4
0
int
_gpgme_io_dup (int fd)
{
  int newfd;
  GIOChannel *chan;

  TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_dup", fd);

  if (fd < 0 || fd >= MAX_SLAFD || !giochannel_table[fd].used)
    {
      errno = EINVAL;
      return TRACE_SYSRES (-1);
    }

  for (newfd = 0; newfd < MAX_SLAFD; newfd++)
    if (! giochannel_table[newfd].used)
      break;
  if (newfd == MAX_SLAFD)
    {
      errno = EIO;
      return TRACE_SYSRES (-1);
    }
  
  chan = giochannel_table[fd].chan;
  g_io_channel_ref (chan);
  giochannel_table[newfd].used = 1;
  giochannel_table[newfd].chan = chan;
  giochannel_table[newfd].fd = -1;
  giochannel_table[newfd].socket = INVALID_SOCKET;
  giochannel_table[newfd].primary = 0;

  return TRACE_SYSRES (newfd);
}
Exemplo n.º 5
0
gpgme_error_t
gpgme_op_trustlist_next (gpgme_ctx_t ctx, gpgme_trust_item_t *r_item)
{
  gpgme_error_t err;
  void *hook;
  op_data_t opd;
  struct trust_queue_item_s *q;

  TRACE_BEG (DEBUG_CTX, "gpgme_op_trustlist_next", ctx);

  if (!r_item)
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
  *r_item = NULL;
  if (!ctx)
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));

  err = _gpgme_op_data_lookup (ctx, OPDATA_TRUSTLIST, &hook, -1, NULL);
  opd = hook;
  if (err)
    return TRACE_ERR (err);
  if (opd == NULL)
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));

  if (!opd->trust_queue)
    {
      err = _gpgme_wait_on_condition (ctx, &opd->trust_cond, NULL);
      if (err)
	return TRACE_ERR (err);
      if (!opd->trust_cond)
	return TRACE_ERR (gpg_error (GPG_ERR_EOF));
      opd->trust_cond = 0; 
      assert (opd->trust_queue);
    }
  q = opd->trust_queue;
  opd->trust_queue = q->next;

  *r_item = q->item;
  free (q);
  if ((*r_item)->type == 1)
    {
      TRACE_SUC5 ("trust_item=%p: %s: owner trust %s with level %i "
		  "and validity 0x%x", *r_item, (*r_item)->keyid,
		  (*r_item)->owner_trust, (*r_item)->level,
		  (*r_item)->validity);
    }
  else if ((*r_item)->type == 2)
    {
      TRACE_SUC5 ("trust_item=%p: %s: UID %s with level %i "
		  "and validity 0x%x", *r_item, (*r_item)->keyid,
		  (*r_item)->name, (*r_item)->level, (*r_item)->validity);
    }
  else
    {
      TRACE_SUC5 ("trust_item=%p: %s: unknown type %i with level %i "
		  "and validity 0x%x", *r_item, (*r_item)->keyid,
		  (*r_item)->type, (*r_item)->level, (*r_item)->validity);
    }
  return 0;
}
Exemplo n.º 6
0
gpgme_error_t
gpgme_data_rewind (gpgme_data_t dh)
{
  gpgme_error_t err;
  TRACE_BEG (DEBUG_DATA, "gpgme_data_rewind", dh);

  err = (gpgme_data_seek (dh, 0, SEEK_SET) == -1)
    ? gpg_error_from_errno (errno) : 0;

  return TRACE_ERR (err);
}
Exemplo n.º 7
0
Arquivo: data-mem.c Projeto: gpg/gpgme
/* Create a new data buffer and return it in R_DH.  */
gpgme_error_t
gpgme_data_new (gpgme_data_t *r_dh)
{
  gpgme_error_t err;
  TRACE_BEG (DEBUG_DATA, "gpgme_data_new", r_dh);

  err = _gpgme_data_new (r_dh, &mem_cbs);

  if (err)
    return TRACE_ERR (err);

  return TRACE_SUC1 ("dh=%p", *r_dh);
}
Exemplo n.º 8
0
gpgme_verify_result_t
gpgme_op_verify_result (gpgme_ctx_t ctx)
{
  void *hook;
  op_data_t opd;
  gpgme_error_t err;

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

  if (_gpgme_debug_trace ())
    {
      gpgme_signature_t sig = opd->result.signatures;
      int i = 0;

      while (sig)
	{
	  TRACE_LOG4 ("sig[%i] = fpr %s, summary 0x%x, status %s",
		      i, sig->fpr, sig->summary, gpg_strerror (sig->status));
	  TRACE_LOG6 ("sig[%i] = timestamps 0x%x/0x%x flags:%s%s%s",
		      i, sig->timestamp, sig->exp_timestamp,
		      sig->wrong_key_usage ? "wrong key usage" : "",
		      sig->pka_trust == 1 ? "pka bad"
		      : (sig->pka_trust == 2 ? "pka_okay" : "pka RFU"),
		      sig->chain_model ? "chain model" : "");
	  TRACE_LOG5 ("sig[%i] = validity 0x%x (%s), algos %s/%s",
		      i, sig->validity, gpg_strerror (sig->validity_reason),
		      gpgme_pubkey_algo_name (sig->pubkey_algo),
		      gpgme_hash_algo_name (sig->hash_algo));
	  if (sig->pka_address)
	    {
	      TRACE_LOG2 ("sig[%i] = PKA address %s", i, sig->pka_address);
	    }
	  if (sig->notations)
	    {
	      TRACE_LOG1 ("sig[%i] = has notations (not shown)", i);
	    }	  
	  sig = sig->next;
	  i++;
	}
    }

  TRACE_SUC1 ("result=%p", &opd->result);
  return &opd->result;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
/* Cancel a pending asynchronous operation.  */
gpgme_error_t
gpgme_cancel (gpgme_ctx_t ctx)
{
  gpg_error_t err;

  TRACE_BEG (DEBUG_CTX, "gpgme_cancel", ctx);

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

  err = _gpgme_cancel_with_err (ctx, gpg_error (GPG_ERR_CANCELED), 0);

  return TRACE_ERR (err);
}
Exemplo n.º 11
0
/* Cancel a pending operation asynchronously.  */
gpgme_error_t
gpgme_cancel_async (gpgme_ctx_t ctx)
{
  TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx);

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

  LOCK (ctx->lock);
  ctx->canceled = 1;
  UNLOCK (ctx->lock);

  return TRACE_ERR (0);
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
int
_gpgme_io_close (int fd)
{
  TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd);

  if (fd < 0 || fd >= MAX_SLAFD)
    {
      errno = EBADF;
      return TRACE_SYSRES (-1);
    }

  assert (giochannel_table[fd].used);

  /* First call the notify handler.  */
  if (notify_table[fd].handler)
    {
      notify_table[fd].handler (fd, notify_table[fd].value);
      notify_table[fd].handler = NULL;
      notify_table[fd].value = NULL;
    }

  /* Then do the close.  */
  if (giochannel_table[fd].chan)
    {
      if (giochannel_table[fd].primary)
	g_io_channel_shutdown (giochannel_table[fd].chan, 1, NULL);
      
      g_io_channel_unref (giochannel_table[fd].chan);
    }
  else
    {
      /* Dummy entry, just close.  */
      assert (giochannel_table[fd].fd != -1);
      _close (giochannel_table[fd].fd);
    }
	
  giochannel_table[fd].used = 0;
  giochannel_table[fd].fd = -1;
  giochannel_table[fd].socket = INVALID_SOCKET;
  giochannel_table[fd].chan = NULL;
  giochannel_table[fd].primary = 0;

  TRACE_SUC ();
  return 0;
}
Exemplo n.º 14
0
int
_gpgme_io_close (int fd)
{
  int i;
  _gpgme_close_notify_handler_t handler = NULL;
  void *value = NULL;
  TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd);

  if (fd == -1)
    {
      errno = EBADF;
      return TRACE_SYSRES (-1);
    }

  kill_reader (fd);
  kill_writer (fd);
  LOCK (notify_table_lock);
  for (i = 0; i < DIM (notify_table); i++)
    {
      if (notify_table[i].inuse && notify_table[i].fd == fd)
	{
	  handler = notify_table[i].handler;
	  value   = notify_table[i].value;
	  notify_table[i].handler = NULL;
	  notify_table[i].value = NULL;
	  notify_table[i].inuse = 0;
	  break;
	}
    }
  UNLOCK (notify_table_lock);
  if (handler)
    handler (fd, value);

  if (!CloseHandle (fd_to_handle (fd)))
    { 
      TRACE_LOG1 ("CloseHandle failed: ec=%d", (int) GetLastError ());
      /* FIXME: Should translate the error code.  */
      errno = EIO;
      return TRACE_SYSRES (-1);
    }

  return TRACE_SYSRES (0);
}
Exemplo n.º 15
0
/* This actually is a int file descriptor (and not assuan_fd_t) as
   _get_osfhandle is called on W32 systems.  */
gpg_error_t
assuan_init_pipe_server (assuan_context_t ctx, assuan_fd_t filedes[2])
{
  const char *s;
  unsigned long ul;
  gpg_error_t rc;
  assuan_fd_t infd = ASSUAN_INVALID_FD;
  assuan_fd_t outfd = ASSUAN_INVALID_FD;
  int is_usd = 0;
  TRACE_BEG (ctx, ASSUAN_LOG_CTX, "assuan_init_pipe_server", ctx);
  if (filedes)
    {
      TRACE_LOG2 ("fd[0]=0x%x, fd[1]=0x%x", filedes[0], filedes[1]);
    }
  
  rc = _assuan_register_std_commands (ctx);
  if (rc)
    return TRACE_ERR (rc);

#ifdef HAVE_W32_SYSTEM
  infd  = filedes[0];
  outfd = filedes[1];
#else
  s = getenv ("_assuan_connection_fd");
  if (s && *s && is_valid_socket (s))
    {
      /* Well, we are called with an bi-directional file descriptor.
	 Prepare for using sendmsg/recvmsg.  In this case we ignore
	 the passed file descriptors. */
      infd = atoi (s);
      outfd = atoi (s);
      is_usd = 1;

    }
  else if (filedes && filedes[0] != ASSUAN_INVALID_FD 
	   && filedes[1] != ASSUAN_INVALID_FD )
    {
      /* Standard pipe server. */
      infd = filedes[0];
      outfd = filedes[1];
    }
  else
    {
      rc = _assuan_error (ctx, GPG_ERR_ASS_SERVER_START);
      return TRACE_ERR (rc);
    }
#endif

  ctx->is_server = 1;
  ctx->engine.release = _assuan_server_release;
  ctx->engine.readfnc = _assuan_simple_read;
  ctx->engine.writefnc = _assuan_simple_write;
  ctx->engine.sendfd = NULL;
  ctx->engine.receivefd = NULL;
  ctx->max_accepts = 1;

  s = getenv ("_assuan_pipe_connect_pid");
  if (s && (ul=strtoul (s, NULL, 10)) && ul)
    ctx->pid = (pid_t)ul;
  else
    ctx->pid = (pid_t)-1;
  ctx->accept_handler = NULL;
  ctx->finish_handler = _assuan_server_finish;
  ctx->inbound.fd = infd;
  ctx->outbound.fd = outfd;

  if (is_usd)
    _assuan_init_uds_io (ctx);

  return TRACE_SUC();
}
Exemplo n.º 16
0
/* Create a new context as an environment for GPGME crypto
   operations.  */
gpgme_error_t
gpgme_new (gpgme_ctx_t *r_ctx)
{
  gpgme_error_t err;
  gpgme_ctx_t ctx;
  TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);

  if (_gpgme_selftest)
    return TRACE_ERR (_gpgme_selftest);

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

  ctx = calloc (1, sizeof *ctx);
  if (!ctx)
    return TRACE_ERR (gpg_error_from_syserror ());

  INIT_LOCK (ctx->lock);

  err = _gpgme_engine_info_copy (&ctx->engine_info);
  if (!err && !ctx->engine_info)
    err = gpg_error (GPG_ERR_NO_ENGINE);
  if (err)
    {
      free (ctx);
      return TRACE_ERR (err);
    }

  ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
  ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT;
  ctx->protocol = GPGME_PROTOCOL_OpenPGP;
  ctx->sub_protocol = GPGME_PROTOCOL_DEFAULT;
  _gpgme_fd_table_init (&ctx->fdt);

  LOCK (def_lc_lock);
  if (def_lc_ctype)
    {
      ctx->lc_ctype = strdup (def_lc_ctype);
      if (!ctx->lc_ctype)
	{
          int saved_err = gpg_error_from_syserror ();
	  UNLOCK (def_lc_lock);
	  _gpgme_engine_info_release (ctx->engine_info);
	  free (ctx);
	  return TRACE_ERR (saved_err);
	}
    }
  else
    def_lc_ctype = NULL;

  if (def_lc_messages)
    {
      ctx->lc_messages = strdup (def_lc_messages);
      if (!ctx->lc_messages)
	{
          int saved_err = gpg_error_from_syserror ();
	  UNLOCK (def_lc_lock);
	  if (ctx->lc_ctype)
	    free (ctx->lc_ctype);
	  _gpgme_engine_info_release (ctx->engine_info);
	  free (ctx);
	  return TRACE_ERR (saved_err);
	}
    }
  else
    def_lc_messages = NULL;
  UNLOCK (def_lc_lock);

  *r_ctx = ctx;

  return TRACE_SUC1 ("ctx=%p", ctx);
}
Exemplo n.º 17
0
int
_gpgme_io_dup (int fd)
{
  HANDLE handle = fd_to_handle (fd);
  HANDLE new_handle = fd_to_handle (fd);
  int i;
  struct reader_context_s *rd_ctx;
  struct writer_context_s *wt_ctx;

  TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_dup", fd);

  if (!DuplicateHandle (GetCurrentProcess(), handle,
			GetCurrentProcess(), &new_handle,
			0, FALSE, DUPLICATE_SAME_ACCESS))
    {
      TRACE_LOG1 ("DuplicateHandle failed: ec=%d\n", (int) GetLastError ());
      /* FIXME: Translate error code.  */
      errno = EIO;
      return TRACE_SYSRES (-1);
    }

  rd_ctx = find_reader (fd, 0);
  if (rd_ctx)
    {
      /* No need for locking, as the only races are against the reader
	 thread itself, which doesn't touch refcount.  */
      rd_ctx->refcount++;

      LOCK (reader_table_lock);
      for (i = 0; i < reader_table_size; i++)
	if (!reader_table[i].used)
	  break;
      /* FIXME.  */
      assert (i != reader_table_size);
      reader_table[i].fd = handle_to_fd (new_handle);
      reader_table[i].context = rd_ctx;
      reader_table[i].used = 1;
      UNLOCK (reader_table_lock);
    }

  wt_ctx = find_writer (fd, 0);
  if (wt_ctx)
    {
      /* No need for locking, as the only races are against the writer
	 thread itself, which doesn't touch refcount.  */
      wt_ctx->refcount++;

      LOCK (writer_table_lock);
      for (i = 0; i < writer_table_size; i++)
	if (!writer_table[i].used)
	  break;
      /* FIXME.  */
      assert (i != writer_table_size);
      writer_table[i].fd = handle_to_fd (new_handle);
      writer_table[i].context = wt_ctx;
      writer_table[i].used = 1;
      UNLOCK (writer_table_lock);
    }

  return TRACE_SYSRES (handle_to_fd (new_handle));
}
Exemplo n.º 18
0
static struct writer_context_s *
create_writer (HANDLE fd)
{
  struct writer_context_s *ctx;
  SECURITY_ATTRIBUTES sec_attr;
  DWORD tid;

  TRACE_BEG (DEBUG_SYSIO, "gpgme:create_writer", fd);

  memset (&sec_attr, 0, sizeof sec_attr);
  sec_attr.nLength = sizeof sec_attr;
  sec_attr.bInheritHandle = FALSE;

  ctx = calloc (1, sizeof *ctx);
  if (!ctx)
    {
      TRACE_SYSERR (errno);
      return NULL;
    }
  
  ctx->file_hd = fd;
  ctx->refcount = 1;
  ctx->have_data = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
  if (ctx->have_data)
    ctx->is_empty  = CreateEvent (&sec_attr, TRUE, TRUE, NULL);
  if (ctx->is_empty)
    ctx->stopped = CreateEvent (&sec_attr, TRUE, FALSE, NULL);
  if (!ctx->have_data || !ctx->is_empty || !ctx->stopped)
    {
      TRACE_LOG1 ("CreateEvent failed: ec=%d", (int) GetLastError ());
      if (ctx->have_data)
	CloseHandle (ctx->have_data);
      if (ctx->is_empty)
	CloseHandle (ctx->is_empty);
      if (ctx->stopped)
	CloseHandle (ctx->stopped);
      free (ctx);
      /* FIXME: Translate the error code.  */
      TRACE_SYSERR (EIO);
      return NULL;
    }

  ctx->is_empty = set_synchronize (ctx->is_empty);
  INIT_LOCK (ctx->mutex);

  ctx->thread_hd = CreateThread (&sec_attr, 0, writer, ctx, 0, &tid );
  if (!ctx->thread_hd)
    {
      TRACE_LOG1 ("CreateThread failed: ec=%d", (int) GetLastError ());
      DESTROY_LOCK (ctx->mutex);
      if (ctx->have_data)
	CloseHandle (ctx->have_data);
      if (ctx->is_empty)
	CloseHandle (ctx->is_empty);
      if (ctx->stopped)
	CloseHandle (ctx->stopped);
      free (ctx);
      TRACE_SYSERR (EIO);
      return NULL;
    }    
  else
    {
      /* We set the priority of the thread higher because we know
	 that it only runs for a short time.  This greatly helps to
	 increase the performance of the I/O.  */
      SetThreadPriority (ctx->thread_hd, get_desired_thread_priority ());
    }

  TRACE_SUC ();
  return ctx;
}
Exemplo n.º 19
0
Arquivo: verify.c Projeto: gpg/gpgme
gpgme_verify_result_t
gpgme_op_verify_result (gpgme_ctx_t ctx)
{
  void *hook;
  op_data_t opd;
  gpgme_error_t err;
  gpgme_signature_t sig;

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

  /* It is possible that we saw a new signature only followed by an
     ERROR line for that.  In particular a missing X.509 key triggers
     this.  In this case it is surprising that the summary field has
     not been updated.  We fix it here by explicitly looking for this
     case.  The real fix would be to have GPGME emit ERRSIG.  */
  for (sig = opd->result.signatures; sig; sig = sig->next)
    {
      if (!sig->summary)
        {
          switch (gpg_err_code (sig->status))
            {
            case GPG_ERR_KEY_EXPIRED:
              sig->summary |= GPGME_SIGSUM_KEY_EXPIRED;
              break;

            case GPG_ERR_NO_PUBKEY:
              sig->summary |= GPGME_SIGSUM_KEY_MISSING;
              break;

            default:
              break;
            }
        }
    }

  /* Now for some tracing stuff. */
  if (_gpgme_debug_trace ())
    {
      int i;

      for (sig = opd->result.signatures, i = 0; sig; sig = sig->next, i++)
	{
	  TRACE_LOG4 ("sig[%i] = fpr %s, summary 0x%x, status %s",
		      i, sig->fpr, sig->summary, gpg_strerror (sig->status));
	  TRACE_LOG6 ("sig[%i] = timestamps 0x%x/0x%x flags:%s%s%s",
		      i, sig->timestamp, sig->exp_timestamp,
		      sig->wrong_key_usage ? "wrong key usage" : "",
		      sig->pka_trust == 1 ? "pka bad"
		      : (sig->pka_trust == 2 ? "pka_okay" : "pka RFU"),
		      sig->chain_model ? "chain model" : "");
	  TRACE_LOG5 ("sig[%i] = validity 0x%x (%s), algos %s/%s",
		      i, sig->validity, gpg_strerror (sig->validity_reason),
		      gpgme_pubkey_algo_name (sig->pubkey_algo),
		      gpgme_hash_algo_name (sig->hash_algo));
	  if (sig->pka_address)
	    {
	      TRACE_LOG2 ("sig[%i] = PKA address %s", i, sig->pka_address);
	    }
	  if (sig->notations)
	    {
	      TRACE_LOG1 ("sig[%i] = has notations (not shown)", i);
	    }
	}
    }

  TRACE_SUC1 ("result=%p", &opd->result);
  return &opd->result;
}