/* 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; }
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; }
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; }
/* 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 }
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; }
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; }
/* 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 }
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; }
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; }