Пример #1
0
/* FIXME: Missing a way to specify --silent.  */
static gpgme_error_t
uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
	      gpgme_data_t plaintext)
{
  engine_uiserver_t uiserver = engine;
  gpgme_error_t err;
  const char *protocol;
  char *cmd;

  if (!uiserver)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (uiserver->protocol == GPGME_PROTOCOL_DEFAULT)
    protocol = "";
  else if (uiserver->protocol == GPGME_PROTOCOL_OpenPGP)
    protocol = " --protocol=OpenPGP";
  else if (uiserver->protocol == GPGME_PROTOCOL_CMS)
    protocol = " --protocol=CMS";
  else
    return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);

  if (asprintf (&cmd, "VERIFY%s", protocol) < 0)
    return gpg_error_from_errno (errno);

  uiserver->input_cb.data = sig;
  err = uiserver_set_fd (uiserver, INPUT_FD,
			 map_data_enc (uiserver->input_cb.data));
  if (err)
    {
      free (cmd);
      return err;
    }
  if (plaintext)
    {
      /* Normal or cleartext signature.  */
      uiserver->output_cb.data = plaintext;
      err = uiserver_set_fd (uiserver, OUTPUT_FD, 0);
    }
  else
    {
      /* Detached signature.  */
      uiserver->message_cb.data = signed_text;
      err = uiserver_set_fd (uiserver, MESSAGE_FD, 0);
    }
  uiserver->inline_data = NULL;

  if (!err)
    err = start (uiserver, cmd);

  free (cmd);
  return err;
}
Пример #2
0
gpgme_error_t EventLoopInteractor::Private::registerIOCb(void *, int fd, int dir,
        gpgme_io_cb_t fnc, void *fnc_data,
        void **r_tag)
{
    assert(instance()); assert(instance()->d);
    bool ok = false;
    void *etag = instance()->registerWatcher(fd, dir ? Read : Write, ok);
    if (!ok) {
        return gpgme_error(GPG_ERR_GENERAL);
    }
    instance()->d->mCallbacks.push_back(new OneFD(fd, dir, fnc, fnc_data, etag));
    if (r_tag) {
        *r_tag = instance()->d->mCallbacks.back();
    }
    return GPG_ERR_NO_ERROR;
}
Пример #3
0
static gpgme_error_t
_uiserver_decrypt (void *engine, int verify,
		   gpgme_data_t ciph, gpgme_data_t plain)
{
  engine_uiserver_t uiserver = engine;
  gpgme_error_t err;
  const char *protocol;
  char *cmd;

  if (!uiserver)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (uiserver->protocol == GPGME_PROTOCOL_DEFAULT)
    protocol = "";
  else if (uiserver->protocol == GPGME_PROTOCOL_OpenPGP)
    protocol = " --protocol=OpenPGP";
  else if (uiserver->protocol == GPGME_PROTOCOL_CMS)
    protocol = " --protocol=CMS";
  else
    return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);

  if (asprintf (&cmd, "DECRYPT%s%s", protocol,
		verify ? "" : " --no-verify") < 0)
    return gpg_error_from_errno (errno);

  uiserver->input_cb.data = ciph;
  err = uiserver_set_fd (uiserver, INPUT_FD,
			 map_data_enc (uiserver->input_cb.data));
  if (err)
    {
      free (cmd);
      return gpg_error (GPG_ERR_GENERAL);	/* FIXME */
    }
  uiserver->output_cb.data = plain;
  err = uiserver_set_fd (uiserver, OUTPUT_FD, 0);
  if (err)
    {
      free (cmd);
      return gpg_error (GPG_ERR_GENERAL);	/* FIXME */
    }
  uiserver->inline_data = NULL;

  err = start (engine, cmd);
  free (cmd);
  return err;
}
Пример #4
0
/* Create a new data buffer filled with the content of file FNAME.
   COPY must be non-zero (delayed reads are not supported yet).  */
gpgme_error_t
gpgme_data_new_from_file (gpgme_data_t *r_dh, const char *fname, int copy)
{
#if defined (HAVE_W32CE_SYSTEM) && defined (_MSC_VER)
  return gpgme_error (GPG_ERR_NOT_IMPLEMENTED);
#else
  gpgme_error_t err;
  struct stat statbuf;
  TRACE_BEG3 (DEBUG_DATA, "gpgme_data_new_from_filepart", r_dh,
	      "file_name=%s, copy=%i (%s)", fname, copy, copy ? "yes" : "no");

  if (!fname || !copy)
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));

  if (stat (fname, &statbuf) < 0)
    return TRACE_ERR (gpg_error_from_errno (errno));

  err = gpgme_data_new_from_filepart (r_dh, fname, NULL, 0, statbuf.st_size);
  return TRACE_ERR (err);
#endif
}
Пример #5
0
static gpgme_error_t
uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
	       gpgme_sig_mode_t mode, int use_armor, int use_textmode,
	       int include_certs, gpgme_ctx_t ctx /* FIXME */)
{
  engine_uiserver_t uiserver = engine;
  gpgme_error_t err = 0;
  const char *protocol;
  char *cmd;
  gpgme_key_t key;

  if (!uiserver || !in || !out)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (uiserver->protocol == GPGME_PROTOCOL_DEFAULT)
    protocol = "";
  else if (uiserver->protocol == GPGME_PROTOCOL_OpenPGP)
    protocol = " --protocol=OpenPGP";
  else if (uiserver->protocol == GPGME_PROTOCOL_CMS)
    protocol = " --protocol=CMS";
  else
    return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);

  if (asprintf (&cmd, "SIGN%s%s", protocol,
		(mode == GPGME_SIG_MODE_DETACH) ? " --detached" : "") < 0)
    return gpg_error_from_errno (errno);

  key = gpgme_signers_enum (ctx, 0);
  if (key)
    {
      const char *s = NULL;

      if (key && key->uids)
        s = key->uids->email;

      if (s && strlen (s) < 80)
        {
          char buf[100];

          strcpy (stpcpy (buf, "SENDER --info "), s);
          err = uiserver_assuan_simple_command (uiserver->assuan_ctx, buf,
                                                uiserver->status.fnc,
                                                uiserver->status.fnc_value);
        }
      else
        err = gpg_error (GPG_ERR_INV_VALUE);
      gpgme_key_unref (key);
      if (err)
      {
	free (cmd);
	return err;
      }
  }

  uiserver->input_cb.data = in;
  err = uiserver_set_fd (uiserver, INPUT_FD,
			 map_data_enc (uiserver->input_cb.data));
  if (err)
    {
      free (cmd);
      return err;
    }
  uiserver->output_cb.data = out;
  err = uiserver_set_fd (uiserver, OUTPUT_FD, use_armor ? "--armor"
			 : map_data_enc (uiserver->output_cb.data));
  if (err)
    {
      free (cmd);
      return err;
    }
  uiserver->inline_data = NULL;

  err = start (uiserver, cmd);
  free (cmd);
  return err;
}
Пример #6
0
static gpgme_error_t
uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
		  gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
{
  engine_uiserver_t uiserver = engine;
  gpgme_error_t err;
  const char *protocol;
  char *cmd;

  if (!uiserver)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (uiserver->protocol == GPGME_PROTOCOL_DEFAULT)
    protocol = "";
  else if (uiserver->protocol == GPGME_PROTOCOL_OpenPGP)
    protocol = " --protocol=OpenPGP";
  else if (uiserver->protocol == GPGME_PROTOCOL_CMS)
    protocol = " --protocol=CMS";
  else
    return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);

  if (flags & GPGME_ENCRYPT_PREPARE)
    {
      if (!recp || plain || ciph)
	return gpg_error (GPG_ERR_INV_VALUE);

      if (asprintf (&cmd, "PREP_ENCRYPT%s%s", protocol,
		    (flags & GPGME_ENCRYPT_EXPECT_SIGN)
		    ? " --expect-sign" : "") < 0)
	return gpg_error_from_errno (errno);
    }
  else
    {
      if (!plain || !ciph)
	return gpg_error (GPG_ERR_INV_VALUE);

      if (asprintf (&cmd, "ENCRYPT%s", protocol) < 0)
	return gpg_error_from_errno (errno);
    }

  if (plain)
    {
      uiserver->input_cb.data = plain;
      err = uiserver_set_fd (uiserver, INPUT_FD,
			     map_data_enc (uiserver->input_cb.data));
      if (err)
	{
	  free (cmd);
	  return err;
	}
    }

  if (ciph)
    {
      uiserver->output_cb.data = ciph;
      err = uiserver_set_fd (uiserver, OUTPUT_FD, use_armor ? "--armor"
			     : map_data_enc (uiserver->output_cb.data));
      if (err)
	{
	  free (cmd);
	  return err;
	}
    }

  uiserver->inline_data = NULL;

  if (recp)
    {
      err = set_recipients (uiserver, recp);
      if (err)
	{
	  free (cmd);
	  return err;
	}
    }

  err = start (uiserver, cmd);
  free (cmd);
  return err;
}
Пример #7
0
/* Create a new data buffer filled with LENGTH bytes starting from
   OFFSET within the file FNAME or stream STREAM (exactly one must be
   non-zero).  */
gpgme_error_t
gpgme_data_new_from_filepart (gpgme_data_t *r_dh, const char *fname,
			      FILE *stream, off_t offset, size_t length)
{
#if defined (HAVE_W32CE_SYSTEM) && defined (_MSC_VER)
  return gpgme_error (GPG_ERR_NOT_IMPLEMENTED);
#else
  gpgme_error_t err;
  char *buf = NULL;
  int res;

  TRACE_BEG4 (DEBUG_DATA, "gpgme_data_new_from_filepart", r_dh,
	      "file_name=%s, stream=%p, offset=%lli, length=%u",
	      fname, stream, offset, length);

  if (stream && fname)
    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));

  if (fname)
    stream = fopen (fname, "rb");
  if (!stream)
    return TRACE_ERR (gpg_error_from_errno (errno));

#ifdef HAVE_FSEEKO
  res = fseeko (stream, offset, SEEK_SET);
#else
  /* FIXME: Check for overflow, or at least bail at compilation.  */
  res = fseek (stream, offset, SEEK_SET);
#endif

  if (res)
    {
      int saved_errno = errno;
      if (fname)
	fclose (stream);
      return TRACE_ERR (gpg_error_from_errno (saved_errno));
    }

  buf = malloc (length);
  if (!buf)
    {
      int saved_errno = errno;
      if (fname)
	fclose (stream);
      return TRACE_ERR (gpg_error_from_errno (saved_errno));
    }

  while (fread (buf, length, 1, stream) < 1
	 && ferror (stream) && errno == EINTR);
  if (ferror (stream))
    {
      int saved_errno = errno;
      if (buf)
	free (buf);
      if (fname)
	fclose (stream);
      return TRACE_ERR (gpg_error_from_errno (saved_errno));
    }

  if (fname)
    fclose (stream);

  err = gpgme_data_new (r_dh);
  if (err)
    {
      if (buf)
	free (buf);
      return err;
    }

  (*r_dh)->data.mem.buffer = buf;
  (*r_dh)->data.mem.size = length;
  (*r_dh)->data.mem.length = length;

  return TRACE_SUC1 ("r_dh=%p", *r_dh);
#endif
}
Пример #8
0
gpgme_error_t
seahorse_passphrase_get (gconstpointer dummy, const gchar *passphrase_hint,
                         const char* passphrase_info, int flags, int fd)
{
	gchar **split_uid = NULL;
	gchar *label = NULL;
	gchar *errmsg = NULL;
	const gchar *pass;
	GcrPrompt *prompt;
	SyncClosure sync;
	GError *error = NULL;
	gchar *msg;

	sync.result = NULL;
	sync.loop = g_main_loop_new (NULL, FALSE);

	gcr_system_prompt_open_async (-1, NULL, on_sync_complete, &sync);

	g_main_loop_run (sync.loop);
	g_assert (sync.result != NULL);

	prompt = gcr_system_prompt_open_finish (sync.result, &error);

	g_main_loop_unref (sync.loop);
	g_object_unref (sync.result);

	if (error != NULL) {
		g_message ("Couldn't open system prompt: %s", error->message);
		g_error_free (error);
		return gpgme_error (GPG_ERR_CANCELED);
	}

	if (passphrase_info && strlen(passphrase_info) < 16)
		flags |= SEAHORSE_PASS_NEW;

	if (passphrase_hint)
		split_uid = g_strsplit (passphrase_hint, " ", 2);

	if (flags & SEAHORSE_PASS_BAD)
		errmsg = g_strdup_printf (_("Wrong passphrase."));

	if (split_uid && split_uid[0] && split_uid[1]) {
		if (flags & SEAHORSE_PASS_NEW)
			label = g_strdup_printf (_("Enter new passphrase for “%s”"), split_uid[1]);
		else
			label = g_strdup_printf (_("Enter passphrase for “%s”"), split_uid[1]);
	} else {
		if (flags & SEAHORSE_PASS_NEW)
			label = g_strdup (_("Enter new passphrase"));
		else
			label = g_strdup (_("Enter passphrase"));
	}

	g_strfreev (split_uid);

	gcr_prompt_set_message (prompt, _("Passphrase"));

	msg = utf8_validate (errmsg ? errmsg : label);
	gcr_prompt_set_description (prompt, msg);
	g_free (msg);

	gcr_prompt_set_password_new (prompt, flags & SEAHORSE_PASS_NEW);

	gcr_prompt_set_continue_label (prompt, _("OK"));
	gcr_prompt_set_cancel_label (prompt, _("Cancel"));

	g_free (label);
	g_free (errmsg);

	pass = gcr_prompt_password_run (prompt, NULL, &error);
	if (pass != NULL)
		seahorse_util_printf_fd (fd, "%s\n", pass);

	gcr_system_prompt_close_async (GCR_SYSTEM_PROMPT (prompt), NULL, NULL, NULL);
	g_object_unref (prompt);

	if (error != NULL) {
		g_message ("Couldn't prompt for password: %s", error->message);
		g_error_free (error);
		return gpgme_error (GPG_ERR_CANCELED);
	}

	return 0;
}
Пример #9
0
static gpgme_key_t*
prompt_recipients (gpgme_key_t *signkey)
{
    gpgme_error_t gerr = 0;
    CryptUIKeyset *keyset;
    gpgme_ctx_t ctx;
    gpgme_key_t key;
    GArray *keys;
    gchar **recips;
    gchar *signer;

    *signkey = NULL;

    keyset = cryptui_keyset_new ("openpgp", TRUE);

    if (cryptui_keyset_get_count (keyset) == 0) {
        cryptui_need_to_get_keys ();
    } else {
        recips = cryptui_prompt_recipients (keyset, _("Choose Recipients"), &signer);

        if (recips) {
            gpgme_check_version (NULL);
            gerr = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP);
            g_return_val_if_fail (gerr == 0, NULL);

            gerr = gpgme_new (&ctx);
            g_return_val_if_fail (gerr == 0, NULL);

            if (signer) {
                /* Load up the GPGME secret key */
                gchar *id = cryptui_keyset_key_raw_keyid (keyset, signer);
                gerr = gpgme_get_key (ctx, id, signkey, 1);
                g_free (id);

                /* A more descriptive error message */
                if (GPG_ERR_EOF == gpgme_err_code (gerr))
                    gerr = gpgme_error (GPG_ERR_NOT_FOUND);
            }

            if (gerr == 0) {
                gchar **ids;
                guint num;

                /* Load up the GPGME keys */
                ids = cryptui_keyset_keys_raw_keyids (keyset, (const gchar**)recips);
                num = g_strv_length (ids);
                keys = g_array_new (TRUE, TRUE, sizeof (gpgme_key_t));
                gerr = gpgme_op_keylist_ext_start (ctx, (const gchar**)ids, 0, 0);
                g_free (ids);

                if (gerr == 0) {
                    while ((gerr = gpgme_op_keylist_next (ctx, &key)) == 0)
                        g_array_append_val (keys, key);
                    gpgme_op_keylist_end (ctx);
                }

                /* Ignore EOF error */
                if (GPG_ERR_EOF == gpgme_err_code (gerr))
                    gerr = 0;

                if (gerr == 0 && num != keys->len)
                    g_warning ("couldn't load all the keys (%d/%d) from GPGME", keys->len, num);
            }

            gpgme_release (ctx);
        }

        g_object_unref (keyset);

        if (!recips)
            return NULL;

        g_strfreev (recips);
        g_free (signer);

        if (gerr == 0 && keys->len)
            return (gpgme_key_t*)g_array_free (keys, FALSE);

        /* When failure, free all our return values */
        seahorse_util_free_keys ((gpgme_key_t*)g_array_free (keys, FALSE));
        if (*signkey)
            gpgme_key_unref (*signkey);

        seahorse_util_handle_gpgme (gerr, _("Couldn't load keys"));
    }

    return NULL;
}