diff options
author | NIIBE Yutaka <[email protected]> | 2025-08-29 00:28:06 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2025-08-29 00:28:06 +0000 |
commit | 52bde50b879c2b9318c87eb9f377bed6557366e2 (patch) | |
tree | 630cbec58ff4b14839348fb94921a96fe83cf1a1 | |
parent | w32: gpgme-w32spawn now appends to the debug log if enabled. (diff) | |
download | gpgme-52bde50b879c2b9318c87eb9f377bed6557366e2.tar.gz gpgme-52bde50b879c2b9318c87eb9f377bed6557366e2.zip |
gpgsm: Introduce two phase interactions to consume diag output.
* src/engine-gpgsm.c (prepare): Move the first part from...
(start): ... here.
(gpgsm_decrypt, gpgsm_delete, gpgsm_encrypt)
(gpgsm_export, gpgsm_export_ext, gpgsm_genkey)
(gpgsm_import, gpgsm_keylist, gpgsm_keylist_ext)
(gpgsm_sign, gpgsm_verify, gpgsm_getauditlog)
(gpgsm_passwd): Follow the change.
--
GnuPG-bug-id: 7759
Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r-- | src/engine-gpgsm.c | 113 |
1 files changed, 89 insertions, 24 deletions
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index e9d69d7a..37236bc2 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -1166,34 +1166,15 @@ add_io_cb (engine_gpgsm_t gpgsm, iocb_data_t *iocbd, gpgme_io_cb_t handler) static gpgme_error_t -start (engine_gpgsm_t gpgsm, const char *command) +prepare (engine_gpgsm_t gpgsm) { - gpgme_error_t err; + gpgme_error_t err = 0; assuan_fd_t afdlist[5]; + /* FIXME: the type int and assuan_fd_t may be incompatible. */ int fdlist[5]; int nfds; int i; - if (*gpgsm->request_origin) - { - char *cmd; - - cmd = _gpgme_strconcat ("OPTION request-origin=", - gpgsm->request_origin, NULL); - if (!cmd) - return gpg_error_from_syserror (); - err = gpgsm_assuan_simple_command (gpgsm, cmd, NULL, NULL); - free (cmd); - if (err && gpg_err_code (err) != GPG_ERR_UNKNOWN_OPTION) - return err; - } - - gpgsm_assuan_simple_command (gpgsm, - gpgsm->flags.offline ? - "OPTION offline=1": - "OPTION offline=0" , - NULL, NULL); - /* We need to know the fd used by assuan for reads. We do this by using the assumption that the first returned fd from assuan_get_active_fds() is always this one. */ @@ -1217,7 +1198,36 @@ start (engine_gpgsm_t gpgsm, const char *command) gpgsm->status_cb.fd = _gpgme_io_dup (fdlist[0]); if (gpgsm->status_cb.fd < 0) - return gpg_error_from_syserror (); + err = gpg_error_from_syserror (); + + return err; +} + + +static gpgme_error_t +start (engine_gpgsm_t gpgsm, const char *command) +{ + gpgme_error_t err; + + if (*gpgsm->request_origin) + { + char *cmd; + + cmd = _gpgme_strconcat ("OPTION request-origin=", + gpgsm->request_origin, NULL); + if (!cmd) + return gpg_error_from_syserror (); + err = gpgsm_assuan_simple_command (gpgsm, cmd, NULL, NULL); + free (cmd); + if (err && gpg_err_code (err) != GPG_ERR_UNKNOWN_OPTION) + return err; + } + + gpgsm_assuan_simple_command (gpgsm, + gpgsm->flags.offline ? + "OPTION offline=1": + "OPTION offline=0" , + NULL, NULL); if (_gpgme_io_set_close_notify (gpgsm->status_cb.fd, close_notify_handler, gpgsm)) @@ -1319,6 +1329,10 @@ gpgsm_decrypt (void *engine, if (!gpgsm) return gpg_error (GPG_ERR_INV_VALUE); + err = prepare (gpgsm); + if (err) + return err; + err = send_input_size_hint (gpgsm, ciph); if (err) return err; @@ -1334,7 +1348,7 @@ gpgsm_decrypt (void *engine, gpgsm_clear_fd (gpgsm, MESSAGE_FD); gpgsm->inline_data = NULL; - err = start (engine, "DECRYPT"); + err = start (gpgsm, "DECRYPT"); return err; } @@ -1397,12 +1411,17 @@ gpgsm_delete (void *engine, gpgme_key_t key, unsigned int flags) } *linep = '\0'; + err = prepare (gpgsm); + if (err) + goto leave; + gpgsm_clear_fd (gpgsm, OUTPUT_FD); gpgsm_clear_fd (gpgsm, INPUT_FD); gpgsm_clear_fd (gpgsm, MESSAGE_FD); gpgsm->inline_data = NULL; err = start (gpgsm, line); + leave: free (line); return err; @@ -1539,6 +1558,10 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring, if (flags & (GPGME_ENCRYPT_ARCHIVE | GPGME_ENCRYPT_FILE)) return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + err = prepare (gpgsm); + if (err) + return err; + if ((flags & GPGME_ENCRYPT_NO_ENCRYPT_TO)) { err = gpgsm_assuan_simple_command (gpgsm, @@ -1621,6 +1644,10 @@ gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode, } strcat (cmd, pattern); + err = prepare (gpgsm); + if (err) + goto leave; + gpgsm->output_cb.data = keydata; err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : map_data_enc (gpgsm->output_cb.data)); @@ -1631,6 +1658,7 @@ gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode, gpgsm->inline_data = NULL; err = start (gpgsm, cmd); + leave: free (cmd); return err; } @@ -1728,6 +1756,10 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode, } *linep = '\0'; + err = prepare (gpgsm); + if (err) + goto leave; + gpgsm->output_cb.data = keydata; err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" : map_data_enc (gpgsm->output_cb.data)); @@ -1738,6 +1770,7 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode, gpgsm->inline_data = NULL; err = start (gpgsm, line); + leave: free (line); return err; } @@ -1764,6 +1797,10 @@ gpgsm_genkey (void *engine, if (!pubkey || seckey) return gpg_error (GPG_ERR_INV_VALUE); + err = prepare (gpgsm); + if (err) + return err; + gpgsm->input_cb.data = help_data; err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data)); if (err) @@ -1815,6 +1852,10 @@ gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray, if (keydata && keyarray) return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ + err = prepare (gpgsm); + if (err) + return err; + dataenc = gpgme_data_get_encoding (keydata); if (keyarray) @@ -1918,6 +1959,10 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only, if (!pattern) pattern = ""; + err = prepare (gpgsm); + if (err) + return err; + /* Hack to make sure that the agent is started. Only if the agent has been started an application may connect to the agent via GPGME_PROTOCOL_ASSUAN - for example to look for smartcards. We @@ -2007,6 +2052,10 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only, if (mode & GPGME_KEYLIST_MODE_EXTERN) list_mode |= 2; + err = prepare (gpgsm); + if (err) + return err; + /* Always send list-mode option because RESET does not reset it. */ if (gpgrt_asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0) return gpg_error_from_syserror (); @@ -2134,6 +2183,10 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out, | GPGME_SIG_MODE_FILE)) return gpg_error (GPG_ERR_INV_VALUE); + err = prepare (gpgsm); + if (err) + return err; + /* FIXME: This does not work as RESET does not reset it so we can't revert back to default. */ if (include_certs != GPGME_INCLUDE_CERTS_DEFAULT) @@ -2208,6 +2261,10 @@ gpgsm_verify (void *engine, gpgme_verify_flags_t flags, gpgme_data_t sig, if (flags & GPGME_VERIFY_ARCHIVE) return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + err = prepare (gpgsm); + if (err) + return err; + gpgsm->input_cb.data = sig; err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data)); if (err) @@ -2293,6 +2350,10 @@ gpgsm_getauditlog (void *engine, gpgme_data_t output, unsigned int flags) if (!gpgsm->assuan_ctx) return gpg_error (GPG_ERR_INV_VALUE); + err = prepare (gpgsm); + if (err) + return err; + #if USE_DESCRIPTOR_PASSING gpgsm->output_cb.data = output; err = gpgsm_set_fd (gpgsm, OUTPUT_FD, 0); @@ -2386,6 +2447,10 @@ gpgsm_passwd (void *engine, gpgme_key_t key, unsigned int flags) if (!key || !key->subkeys || !key->subkeys->fpr) return gpg_error (GPG_ERR_INV_CERT_OBJ); + err = prepare (gpgsm); + if (err) + return err; + if (gpgrt_asprintf (&line, "PASSWD -- %s", key->subkeys->fpr) < 0) return gpg_error_from_syserror (); |