From a1f76b3b54b75a150fe272b804d85ffd40a507a6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 17 Apr 2018 08:33:44 +0200 Subject: core: Add extended versions of the encrypt functions. * src/gpgme.h.in (gpgme_op_encrypt_ext_start) New. (gpgme_op_encrypt_ext): New. (gpgme_op_encrypt_sign_ext_start): New. (gpgme_op_encrypt_sign_ext): New. * src/libgpgme.vers, tests/run-encrypt.c: Add them. * src/encrypt.c (encrypt_start): Add arg recpstring. (gpgme_op_encrypt): Factor code out to ... (gpgme_op_encrypt_ext): new function with new arg recpstring. (gpgme_op_encrypt_start): Factor code out to ... (gpgme_op_encrypt_ext_start): new function with new arg recpstring. * src/encrypt-sign.c (encrypt_sign_start): Add arg recpstring. (gpgme_op_encrypt_sign): Factor code out to ... (gpgme_op_encrypt_sign_ext): new function with new arg recpstring. (gpgme_op_encrypt_sign_start): Factor code out to ... (gpgme_op_encrypt_sign_ext_start): new function with new arg recpstring. * src/engine-backend.h (struct engine_ops): Change fields encrypt and encrypt_sign. * src/engine.c (_gpgme_engine_op_encrypt): Add arg recpstring and pass to engine. (_gpgme_engine_op_encrypt_sign): Ditto. * src/engine-gpg.c (append_args_from_recipients_string): New. (gpg_encrypt): Add arg recpstring and call new function as needed. (gpg_encrypt_sign): Ditto. * src/engine-gpgsm.c (set_recipients_from_string): New. (gpgsm_encrypt): Add arg recpstring and call new function as needed. * src/engine-uiserver.c (set_recipients_from_string): New. (uiserver_encrypt): Add arg recpstring and call new function as needed. * tests/run-encrypt.c (xstrdup): New. (main): Add option --keystring. * src/gpgme-json.c (get_keys): Simplify. (op_encrypt): Modify to make use of the extended encrypt function. -- This new feature can be used to avoid the need for a key lookup and thus several extra calls to the backend. Note that run-test uses a semicolon as delimiter because that make testing the feature on the command line much easier. Signed-off-by: Werner Koch --- src/engine-uiserver.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'src/engine-uiserver.c') diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index fd5ac174..d8f4fce3 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -1075,8 +1075,58 @@ set_recipients (engine_uiserver_t uiserver, gpgme_key_t recp[]) } +/* Take recipients from the LF delimited STRING and send RECIPIENT + * commands to gpgsm. */ static gpgme_error_t -uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, +set_recipients_from_string (engine_uiserver_t uiserver, const char *string) +{ + gpg_error_t err = 0; + char *line = NULL; + int no_pubkey = 0; + const char *s; + int n; + + for (;;) + { + while (*string == ' ' || *string == '\t') + string++; + if (!*string) + break; + + s = strchr (string, '\n'); + if (s) + n = s - string; + else + n = strlen (string); + while (n && (string[n-1] == ' ' || string[n-1] == '\t')) + n--; + + gpgrt_free (line); + if (gpgrt_asprintf (&line, "RECIPIENT %.*s", n, string) < 0) + { + err = gpg_error_from_syserror (); + break; + } + string += n + !!s; + + err = uiserver_assuan_simple_command (uiserver, line, + uiserver->status.fnc, + uiserver->status.fnc_value); + + /* Fixme: Improve error reporting. */ + if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY) + no_pubkey++; + else if (err) + break; + } + gpgrt_free (line); + return err? err : no_pubkey? gpg_error (GPG_ERR_NO_PUBKEY) : 0; +} + + +static gpgme_error_t +uiserver_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring, + gpgme_encrypt_flags_t flags, gpgme_data_t plain, gpgme_data_t ciph, int use_armor) { engine_uiserver_t uiserver = engine; @@ -1140,9 +1190,12 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags, uiserver->inline_data = NULL; - if (recp) + if (recp || recpstring) { - err = set_recipients (uiserver, recp); + if (recp) + err = set_recipients (uiserver, recp); + else + err = set_recipients_from_string (uiserver, recpstring); if (err) { gpgrt_free (cmd); -- cgit v1.2.3