aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2025-08-29 00:28:06 +0000
committerNIIBE Yutaka <[email protected]>2025-08-29 00:28:06 +0000
commit52bde50b879c2b9318c87eb9f377bed6557366e2 (patch)
tree630cbec58ff4b14839348fb94921a96fe83cf1a1
parentw32: gpgme-w32spawn now appends to the debug log if enabled. (diff)
downloadgpgme-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.c113
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 ();