diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 7 | ||||
-rw-r--r-- | src/engine-gpg.c | 2 | ||||
-rw-r--r-- | src/engine-gpgsm.c | 82 |
3 files changed, 85 insertions, 6 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index eca549aa..feebbdc9 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,12 @@ 2009-07-07 Werner Koch <[email protected]> + * engine-gpgsm.c (struct engine_gpgsm): Add fields + input_helper_data and input_helper_memory. + (close_notify_handler): Release these new fields. + (gpgsm_import): Implement the keyarray feature. + + * engine-gpg.c (gpg_import): Actually return GPG_ERR_INV_VALUE. + * engine-gpgsm.c (gpgsm_import): Return an error for unknown data encodings. diff --git a/src/engine-gpg.c b/src/engine-gpg.c index a3b94677..dba49a9c 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1914,7 +1914,7 @@ gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray) gpgme_data_encoding_t dataenc; if (keydata && keyarray) - gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ + return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ dataenc = gpgme_data_get_encoding (keydata); diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index 52915d36..4067b99b 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -70,6 +70,8 @@ struct engine_gpgsm /* Input, output etc are from the servers perspective. */ iocb_data_t input_cb; + gpgme_data_t input_helper_data; /* Input helper data object. */ + void *input_helper_memory; /* Input helper memory block. */ iocb_data_t output_cb; @@ -141,6 +143,16 @@ close_notify_handler (int fd, void *opaque) (*gpgsm->io_cbs.remove) (gpgsm->input_cb.tag); gpgsm->input_cb.fd = -1; gpgsm->input_cb.tag = NULL; + if (gpgsm->input_helper_data) + { + gpgme_data_release (gpgsm->input_helper_data); + gpgsm->input_helper_data = NULL; + } + if (gpgsm->input_helper_memory) + { + free (gpgsm->input_helper_memory); + gpgsm->input_helper_memory = NULL; + } } else if (gpgsm->output_cb.fd == fd) { @@ -1545,18 +1557,79 @@ gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray) engine_gpgsm_t gpgsm = engine; gpgme_error_t err; gpgme_data_encoding_t dataenc; + int idx; if (!gpgsm) return gpg_error (GPG_ERR_INV_VALUE); if (keydata && keyarray) - gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ + return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ dataenc = gpgme_data_get_encoding (keydata); if (keyarray) { - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + size_t buflen; + char *buffer, *p; + + /* Fist check whether the engine already features the + --re-import option. */ + err = gpgsm_assuan_simple_command + (gpgsm->assuan_ctx, + "GETINFO cmd_has_option IMPORT re-import", NULL, NULL); + if (err) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + /* Create an internal data object with a list of all + fingerprints. The data object and its memory (to avoid an + extra copy by gpgme_data_new_from_mem) are stored in two + variables which are released by the close_notify_handler. */ + for (idx=0, buflen=0; keyarray[idx]; idx++) + { + if (keyarray[idx]->protocol == GPGME_PROTOCOL_CMS + && keyarray[idx]->subkeys + && keyarray[idx]->subkeys->fpr + && *keyarray[idx]->subkeys->fpr) + buflen += strlen (keyarray[idx]->subkeys->fpr) + 1; + } + /* Allocate a bufer with extra space for the trailing Nul + introduced by the use of stpcpy. */ + buffer = malloc (buflen+1); + if (!buffer) + return gpg_error_from_syserror (); + for (idx=0, p = buffer; keyarray[idx]; idx++) + { + if (keyarray[idx]->protocol == GPGME_PROTOCOL_CMS + && keyarray[idx]->subkeys + && keyarray[idx]->subkeys->fpr + && *keyarray[idx]->subkeys->fpr) + p = stpcpy (stpcpy (p, keyarray[idx]->subkeys->fpr), "\n"); + } + + err = gpgme_data_new_from_mem (&gpgsm->input_helper_data, + buffer, buflen, 0); + if (err) + { + free (buffer); + return err; + } + gpgsm->input_helper_memory = buffer; + + gpgsm->input_cb.data = gpgsm->input_helper_data; + err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data)); + if (err) + { + gpgme_data_release (gpgsm->input_helper_data); + gpgsm->input_helper_data = NULL; + free (gpgsm->input_helper_memory); + gpgsm->input_helper_memory = NULL; + return err; + } + gpgsm_clear_fd (gpgsm, OUTPUT_FD); + gpgsm_clear_fd (gpgsm, MESSAGE_FD); + gpgsm->inline_data = NULL; + + return start (gpgsm, "IMPORT --re-import"); } else if (dataenc == GPGME_DATA_ENCODING_URL || dataenc == GPGME_DATA_ENCODING_URL0 @@ -1573,10 +1646,9 @@ gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray) gpgsm_clear_fd (gpgsm, OUTPUT_FD); gpgsm_clear_fd (gpgsm, MESSAGE_FD); gpgsm->inline_data = NULL; - } - err = start (gpgsm, "IMPORT"); - return err; + return start (gpgsm, "IMPORT"); + } } |