diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 31 | ||||
| -rw-r--r-- | src/engine-backend.h | 7 | ||||
| -rw-r--r-- | src/engine-gpg.c | 90 | ||||
| -rw-r--r-- | src/engine-gpgsm.c | 40 | ||||
| -rw-r--r-- | src/engine.c | 9 | ||||
| -rw-r--r-- | src/engine.h | 7 | ||||
| -rw-r--r-- | src/export.c | 148 | ||||
| -rw-r--r-- | src/gpgme.def | 5 | ||||
| -rw-r--r-- | src/gpgme.h.in | 31 | ||||
| -rw-r--r-- | src/import.c | 80 | ||||
| -rw-r--r-- | src/libgpgme.vers | 5 | 
11 files changed, 377 insertions, 76 deletions
| diff --git a/src/ChangeLog b/src/ChangeLog index 35622ee6..dc1e1164 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,34 @@ +2009-06-16  Werner Koch  <[email protected]> + +	* gpgme.h.in (gpgme_op_export_keys_start, gpgme_op_export_keys): New. +	* gpgme.def, libgpgme.vers: Add them. +	* export.c (gpgme_op_export_keys_start, gpgme_op_export_keys): New. +	(export_keys_start): New. + +	* gpgme.h.in (gpgme_export_mode_t, GPGME_EXPORT_MODE_EXTERN): New. +	(gpgme_op_export_start, gpgme_op_export, gpgme_op_export_ext_start) +	(gpgme_op_export_ext): Change arg RESERVED to MODE of new +	compatible type. +	* export.c (gpgme_export_ext_start, gpgme_op_export) +	(gpgme_op_export_ext_start, gpgme_op_export_ext): Ditto. +	(export_start): Ditto. +	* engine.c (_gpgme_engine_op_export): Ditto. +	* engine-backend.h (struct engine_ops): Ditto. +	* engine-gpgsm.c (gpgsm_export, gpgsm_export_ext): Ditto. +	* engine-gpg.c (gpg_export, gpg_export_ext): Ditto.  Implement +	mode EXTERN. +	(gpg_export, gpg_export_ext): Factor common code out to .. +	(export_common): .. this. + +	* gpgme.h.in (gpgme_op_import_keys_start, gpgme_op_import_keys): New. +	* gpgme.def, libgpgme.vers: Add them. +	* import.c (gpgme_op_import_keys_start, gpgme_op_import_keys): New. +	(_gpgme_op_import_keys_start): New. +	* engine.c (_gpgme_engine_op_import): Add arg KEYARRAY. +	* engine-backend.h (struct engine_ops): Ditto. +	* engine-gpgsm.c (gpgsm_import): Ditto.  Not functional. +	* engine-gpg.c (gpg_import): Ditto.  Implement it. +  2009-06-15  Marcus Brinkmann  <[email protected]>  	* gpgme.h.in (gpgme_result_ref, gpgme_result_unref): Add diff --git a/src/engine-backend.h b/src/engine-backend.h index d656d9d6..1fe600d0 100644 --- a/src/engine-backend.h +++ b/src/engine-backend.h @@ -77,14 +77,15 @@ struct engine_ops  				 gpgme_data_t plain, gpgme_data_t ciph,  				 int use_armor, gpgme_ctx_t ctx /* FIXME */);    gpgme_error_t (*export) (void *engine, const char *pattern, -			   unsigned int reserved, gpgme_data_t keydata, +			   gpgme_export_mode_t mode, gpgme_data_t keydata,  			   int use_armor);    gpgme_error_t (*export_ext) (void *engine, const char *pattern[], -			       unsigned int reserved, gpgme_data_t keydata, +			       gpgme_export_mode_t mode, gpgme_data_t keydata,  			       int use_armor);    gpgme_error_t (*genkey) (void *engine, gpgme_data_t help_data, int use_armor,  			   gpgme_data_t pubkey, gpgme_data_t seckey); -  gpgme_error_t (*import) (void *engine, gpgme_data_t keydata); +  gpgme_error_t (*import) (void *engine, gpgme_data_t keydata, +                           gpgme_key_t *keyarray);    gpgme_error_t (*keylist) (void *engine, const char *pattern,  			    int secret_only, gpgme_keylist_mode_t mode);    gpgme_error_t (*keylist_ext) (void *engine, const char *pattern[], diff --git a/src/engine-gpg.c b/src/engine-gpg.c index eec3fa67..3c06edf8 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -678,7 +678,7 @@ command_handler (void *opaque, int fd)  /* The Fnc will be called to get a value for one of the commands with -   a key KEY.  If the Code pssed to FNC is 0, the function may release +   a key KEY.  If the Code passed to FNC is 0, the function may release     resources associated with the returned value from another call.  To     match such a second call to a first call, the returned value from     the first call is passed as keyword.  */ @@ -1704,23 +1704,42 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],  static gpgme_error_t -gpg_export (void *engine, const char *pattern, unsigned int reserved, -	    gpgme_data_t keydata, int use_armor) +export_common (engine_gpg_t gpg, gpgme_export_mode_t mode, +               gpgme_data_t keydata, int use_armor)  { -  engine_gpg_t gpg = engine;    gpgme_error_t err; -  if (reserved) -    return gpg_error (GPG_ERR_INV_VALUE); +  if ((mode & ~GPGME_EXPORT_MODE_EXTERN)) +    return gpg_error (GPG_ERR_NOT_SUPPORTED); -  err = add_arg (gpg, "--export"); -  if (!err && use_armor) -    err = add_arg (gpg, "--armor"); -  if (!err) -    err = add_data (gpg, keydata, 1, 1); +  if ((mode & GPGME_EXPORT_MODE_EXTERN)) +    { +      err = add_arg (gpg, "--send-keys"); +    } +  else +    { +      err = add_arg (gpg, "--export"); +      if (!err && use_armor) +        err = add_arg (gpg, "--armor"); +      if (!err) +        err = add_data (gpg, keydata, 1, 1); +    }    if (!err)      err = add_arg (gpg, "--"); +  return err; +} + + +static gpgme_error_t +gpg_export (void *engine, const char *pattern, gpgme_export_mode_t mode, +	    gpgme_data_t keydata, int use_armor) +{ +  engine_gpg_t gpg = engine; +  gpgme_error_t err; + +  err = export_common (gpg, mode, keydata, use_armor); +    if (!err && pattern && *pattern)      err = add_arg (gpg, pattern); @@ -1732,22 +1751,13 @@ gpg_export (void *engine, const char *pattern, unsigned int reserved,  static gpgme_error_t -gpg_export_ext (void *engine, const char *pattern[], unsigned int reserved, +gpg_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,  		gpgme_data_t keydata, int use_armor)  {    engine_gpg_t gpg = engine;    gpgme_error_t err; -  if (reserved) -    return gpg_error (GPG_ERR_INV_VALUE); - -  err = add_arg (gpg, "--export"); -  if (!err && use_armor) -    err = add_arg (gpg, "--armor"); -  if (!err) -    err = add_data (gpg, keydata, 1, 1); -  if (!err) -    err = add_arg (gpg, "--"); +  err = export_common (gpg, mode, keydata, use_armor);    if (pattern)      { @@ -1795,16 +1805,40 @@ gpg_genkey (void *engine, gpgme_data_t help_data, int use_armor,  static gpgme_error_t -gpg_import (void *engine, gpgme_data_t keydata) +gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)  {    engine_gpg_t gpg = engine;    gpgme_error_t err; +  int idx; -  err = add_arg (gpg, "--import"); -  if (!err) -    err = add_arg (gpg, "--"); -  if (!err) -    err = add_data (gpg, keydata, -1, 0); +  if (keydata && keyarray) +    gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */ + +  if (keyarray) +    { +      err = add_arg (gpg, "--recv-keys"); +      if (!err) +        err = add_arg (gpg, "--"); +      for (idx=0; !err && keyarray[idx]; idx++) +        { +          if (keyarray[idx]->protocol != GPGME_PROTOCOL_OpenPGP) +            ; +          else if (!keyarray[idx]->subkeys) +            ; +          else if (keyarray[idx]->subkeys->fpr && *keyarray[idx]->subkeys->fpr) +            err = add_arg (gpg, keyarray[idx]->subkeys->fpr); +          else if (*keyarray[idx]->subkeys->keyid) +            err = add_arg (gpg, keyarray[idx]->subkeys->keyid); +        } +    } +  else +    { +      err = add_arg (gpg, "--import"); +      if (!err) +        err = add_arg (gpg, "--"); +      if (!err) +        err = add_data (gpg, keydata, -1, 0); +    }    if (!err)      err = start (gpg); diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index 2d92732c..71ef221b 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -1379,15 +1379,18 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,  static gpgme_error_t -gpgsm_export (void *engine, const char *pattern, unsigned int reserved, +gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode,  	      gpgme_data_t keydata, int use_armor)  {    engine_gpgsm_t gpgsm = engine;    gpgme_error_t err = 0;    char *cmd; -  if (!gpgsm || reserved) +  if (!gpgsm)      return gpg_error (GPG_ERR_INV_VALUE); +   +  if (mode) +    return gpg_error (GPG_ERR_NOT_SUPPORTED);    if (!pattern)      pattern = ""; @@ -1414,7 +1417,7 @@ gpgsm_export (void *engine, const char *pattern, unsigned int reserved,  static gpgme_error_t -gpgsm_export_ext (void *engine, const char *pattern[], unsigned int reserved, +gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,  		  gpgme_data_t keydata, int use_armor)  {    engine_gpgsm_t gpgsm = engine; @@ -1424,9 +1427,12 @@ gpgsm_export_ext (void *engine, const char *pattern[], unsigned int reserved,    int length = 7 + 1;    char *linep; -  if (!gpgsm || reserved) +  if (!gpgsm)      return gpg_error (GPG_ERR_INV_VALUE); +  if (mode) +    return gpg_error (GPG_ERR_NOT_SUPPORTED); +    if (pattern && *pattern)      {        const char **pat = pattern; @@ -1534,7 +1540,7 @@ gpgsm_genkey (void *engine, gpgme_data_t help_data, int use_armor,  static gpgme_error_t -gpgsm_import (void *engine, gpgme_data_t keydata) +gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)  {    engine_gpgsm_t gpgsm = engine;    gpgme_error_t err; @@ -1542,13 +1548,23 @@ gpgsm_import (void *engine, gpgme_data_t keydata)    if (!gpgsm)      return gpg_error (GPG_ERR_INV_VALUE); -  gpgsm->input_cb.data = keydata; -  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data)); -  if (err) -    return err; -  gpgsm_clear_fd (gpgsm, OUTPUT_FD); -  gpgsm_clear_fd (gpgsm, MESSAGE_FD); -  gpgsm->inline_data = NULL; +  if (keydata && keyarray) +    gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */ + +  if (keyarray) +    { +      return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +    } +  else +    { +      gpgsm->input_cb.data = keydata; +      err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data)); +      if (err) +        return err; +      gpgsm_clear_fd (gpgsm, OUTPUT_FD); +      gpgsm_clear_fd (gpgsm, MESSAGE_FD); +      gpgsm->inline_data = NULL; +    }    err = start (gpgsm, "IMPORT");    return err; diff --git a/src/engine.c b/src/engine.c index 87d39392..c8ff012b 100644 --- a/src/engine.c +++ b/src/engine.c @@ -620,7 +620,7 @@ _gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],  gpgme_error_t  _gpgme_engine_op_export (engine_t engine, const char *pattern, -			 unsigned int reserved, gpgme_data_t keydata, +			 gpgme_export_mode_t mode, gpgme_data_t keydata,  			 int use_armor)  {    if (!engine) @@ -629,7 +629,7 @@ _gpgme_engine_op_export (engine_t engine, const char *pattern,    if (!engine->ops->export)      return gpg_error (GPG_ERR_NOT_IMPLEMENTED); -  return (*engine->ops->export) (engine->engine, pattern, reserved, +  return (*engine->ops->export) (engine->engine, pattern, mode,  				 keydata, use_armor);  } @@ -667,7 +667,8 @@ _gpgme_engine_op_genkey (engine_t engine, gpgme_data_t help_data,  gpgme_error_t -_gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata) +_gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata, +                         gpgme_key_t *keyarray)  {    if (!engine)      return gpg_error (GPG_ERR_INV_VALUE); @@ -675,7 +676,7 @@ _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata)    if (!engine->ops->import)      return gpg_error (GPG_ERR_NOT_IMPLEMENTED); -  return (*engine->ops->import) (engine->engine, keydata); +  return (*engine->ops->import) (engine->engine, keydata, keyarray);  } diff --git a/src/engine.h b/src/engine.h index a043b3e2..ca746c8a 100644 --- a/src/engine.h +++ b/src/engine.h @@ -93,11 +93,11 @@ gpgme_error_t _gpgme_engine_op_encrypt_sign (engine_t engine,  					     int use_armor,  					     gpgme_ctx_t ctx /* FIXME */);  gpgme_error_t _gpgme_engine_op_export (engine_t engine, const char *pattern, -				       unsigned int reserved, +				       gpgme_export_mode_t mode,  				       gpgme_data_t keydata, int use_armor);  gpgme_error_t _gpgme_engine_op_export_ext (engine_t engine,  					   const char *pattern[], -					   unsigned int reserved, +					   gpgme_export_mode_t mode,  					   gpgme_data_t keydata,  					   int use_armor);  gpgme_error_t _gpgme_engine_op_genkey (engine_t engine, @@ -105,7 +105,8 @@ gpgme_error_t _gpgme_engine_op_genkey (engine_t engine,  				       int use_armor, gpgme_data_t pubkey,  				       gpgme_data_t seckey);  gpgme_error_t _gpgme_engine_op_import (engine_t engine, -				       gpgme_data_t keydata); +				       gpgme_data_t keydata, +                                       gpgme_key_t *keyarray);  gpgme_error_t _gpgme_engine_op_keylist (engine_t engine,  					const char *pattern,  					int secret_only, diff --git a/src/export.c b/src/export.c index 079a7e0e..1e294391 100644 --- a/src/export.c +++ b/src/export.c @@ -22,6 +22,8 @@  #if HAVE_CONFIG_H  #include <config.h>  #endif +#include <stdlib.h> +#include <string.h>  #include "gpgme.h"  #include "context.h" @@ -37,12 +39,24 @@ export_status_handler (void *priv, gpgme_status_code_t code, char *args)  static gpgme_error_t  export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern, -	      unsigned int reserved, gpgme_data_t keydata) +	      gpgme_export_mode_t mode, gpgme_data_t keydata)  {    gpgme_error_t err; -  if (!keydata) -    return gpg_error (GPG_ERR_INV_VALUE); +  if ((mode & ~(GPGME_EXPORT_MODE_EXTERN))) +    return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */ + +   +  if ((mode & GPGME_EXPORT_MODE_EXTERN)) +    { +      if (keydata) +        return gpg_error (GPG_ERR_INV_VALUE); +    } +  else +    { +      if (!keydata) +        return gpg_error (GPG_ERR_INV_VALUE); +    }    err = _gpgme_op_reset (ctx, synchronous);    if (err) @@ -50,26 +64,26 @@ export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,    _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx); -  return _gpgme_engine_op_export (ctx->engine, pattern, reserved, keydata, +  return _gpgme_engine_op_export (ctx->engine, pattern, mode, keydata,  				  ctx->use_armor);  } -/* Export the keys listed in RECP into KEYDATA.  */ +/* Export the keys listed in PATTERN into KEYDATA.  */  gpgme_error_t  gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern, -		       unsigned int reserved, gpgme_data_t keydata) +		       gpgme_export_mode_t mode, gpgme_data_t keydata)  { -  return export_start (ctx, 0, pattern, reserved, keydata); +  return export_start (ctx, 0, pattern, mode, keydata);  } -/* Export the keys listed in RECP into KEYDATA.  */ +/* Export the keys listed in PATTERN into KEYDATA.  */  gpgme_error_t -gpgme_op_export (gpgme_ctx_t ctx, const char *pattern, unsigned int reserved, -		 gpgme_data_t keydata) +gpgme_op_export (gpgme_ctx_t ctx, const char *pattern, +		 gpgme_export_mode_t mode, gpgme_data_t keydata)  { -  gpgme_error_t err = export_start (ctx, 1, pattern, reserved, keydata); +  gpgme_error_t err = export_start (ctx, 1, pattern, mode, keydata);    if (!err)      err = _gpgme_wait_one (ctx);    return err; @@ -78,12 +92,23 @@ gpgme_op_export (gpgme_ctx_t ctx, const char *pattern, unsigned int reserved,  static gpgme_error_t  export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[], -		  unsigned int reserved, gpgme_data_t keydata) +		  gpgme_export_mode_t mode, gpgme_data_t keydata)  {    gpgme_error_t err; -  if (!keydata) -    return gpg_error (GPG_ERR_INV_VALUE); +  if ((mode & ~(GPGME_EXPORT_MODE_EXTERN))) +    return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */ + +  if ((mode & GPGME_EXPORT_MODE_EXTERN)) +    { +      if (keydata) +        return gpg_error (GPG_ERR_INV_VALUE); +    } +  else +    { +      if (!keydata) +        return gpg_error (GPG_ERR_INV_VALUE); +    }    err = _gpgme_op_reset (ctx, synchronous);    if (err) @@ -91,27 +116,108 @@ export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],    _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx); -  return _gpgme_engine_op_export_ext (ctx->engine, pattern, reserved, keydata, +  return _gpgme_engine_op_export_ext (ctx->engine, pattern, mode, keydata,  				      ctx->use_armor);  } -/* Export the keys listed in RECP into KEYDATA.  */ +/* Export the keys listed in PATTERN into KEYDATA.  */  gpgme_error_t  gpgme_op_export_ext_start (gpgme_ctx_t ctx, const char *pattern[], -			   unsigned int reserved, gpgme_data_t keydata) +			   gpgme_export_mode_t mode, gpgme_data_t keydata)  { -  return export_ext_start (ctx, 0, pattern, reserved, keydata); +  return export_ext_start (ctx, 0, pattern, mode, keydata);  } -/* Export the keys listed in RECP into KEYDATA.  */ +/* Export the keys listed in PATTERN into KEYDATA.  */  gpgme_error_t  gpgme_op_export_ext (gpgme_ctx_t ctx, const char *pattern[], -		     unsigned int reserved, gpgme_data_t keydata) +		     gpgme_export_mode_t mode, gpgme_data_t keydata) +{ +  gpgme_error_t err = export_ext_start (ctx, 1, pattern, mode, keydata); +  if (!err) +    err = _gpgme_wait_one (ctx); +  return err; +} + + + + + +static gpgme_error_t +export_keys_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t keys[], +                   gpgme_export_mode_t mode, gpgme_data_t keydata) +{ +  gpgme_error_t err; +  int nkeys, idx; +  char **pattern; + +  if (!keys) +    return gpg_error (GPG_ERR_INV_VALUE); + +  /* Create a list of pattern from the keys.  */ +  for (idx=nkeys=0; keys[idx]; idx++) +    if (keys[idx]->protocol == ctx->protocol) +      nkeys++; +  if (!nkeys) +    return gpg_error (GPG_ERR_NO_DATA); +   +  pattern = calloc (nkeys+1, sizeof *pattern); +  if (!pattern) +    return gpg_error_from_syserror (); + +  for (idx=nkeys=0; keys[idx]; idx++) +    if (keys[idx]->protocol == ctx->protocol +        && keys[idx]->subkeys +        && keys[idx]->subkeys->fpr +        && *keys[idx]->subkeys->fpr) +      { +        pattern[nkeys] = strdup (keys[idx]->subkeys->fpr); +        if (!pattern[nkeys]) +          { +            err = gpg_error_from_syserror (); +            goto leave; +          } +        nkeys++; +      } + + +  /* Pass on to the regular function.  */ +  err = export_ext_start (ctx, synchronous, (const char**)pattern, +                          mode, keydata); + + leave: +  for (idx=0; pattern[idx]; idx++) +    free (pattern[idx]); +  free (pattern); + +  return err; +} + + +/* Export the keys from the array KEYS into KEYDATA.  Only keys of the +   current protocol are exported and only those which have a +   fingerprint set; that is keys received with some external search +   methods are silently skipped.  */ +gpgme_error_t +gpgme_op_export_keys_start (gpgme_ctx_t ctx, +                            gpgme_key_t keys[], +                            gpgme_export_mode_t mode, +                            gpgme_data_t keydata)  { -  gpgme_error_t err = export_ext_start (ctx, 1, pattern, reserved, keydata); +  return export_keys_start (ctx, 0, keys, mode, keydata); +} + +gpgme_error_t +gpgme_op_export_keys (gpgme_ctx_t ctx, +                      gpgme_key_t keys[], +                      gpgme_export_mode_t mode, +                      gpgme_data_t keydata) +{ +  gpgme_error_t err = export_keys_start (ctx, 1, keys, mode, keydata);    if (!err)      err = _gpgme_wait_one (ctx);    return err;  } + diff --git a/src/gpgme.def b/src/gpgme.def index 9bc95d00..ac0fe9a2 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -180,5 +180,10 @@ EXPORTS      gpgme_release_ref                     @138      gpgme_release_unref                   @139 +    gpgme_op_import_keys                  @140 +    gpgme_op_import_keys_start            @141 +    gpgme_op_export_keys                  @142 +    gpgme_op_export_keys_start            @143 +  ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 8e224a47..ff9bba06 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -329,6 +329,12 @@ gpgme_protocol_t;  typedef unsigned int gpgme_keylist_mode_t; +/* The available export mode flags.  */ +#define GPGME_EXPORT_MODE_EXTERN                2 + +typedef unsigned int gpgme_export_mode_t; + +  /* Flags for the audit log functions.  */  #define GPGME_AUDITLOG_HTML      1   #define GPGME_AUDITLOG_WITH_HELP 128 @@ -1497,22 +1503,39 @@ gpgme_error_t gpgme_op_import (gpgme_ctx_t ctx, gpgme_data_t keydata);  gpgme_error_t gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata,  				   int *nr) _GPGME_DEPRECATED; +/* Import the keys from the array KEYS into the keyring.  */ +gpgme_error_t gpgme_op_import_keys_start (gpgme_ctx_t ctx, gpgme_key_t keys[]); +gpgme_error_t gpgme_op_import_keys (gpgme_ctx_t ctx, gpgme_key_t keys[]); + +  /* Export the keys found by PATTERN into KEYDATA.  */  gpgme_error_t gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern, -				     unsigned int reserved, +				     gpgme_export_mode_t mode,  				     gpgme_data_t keydata);  gpgme_error_t gpgme_op_export (gpgme_ctx_t ctx, const char *pattern, -			       unsigned int reserved, gpgme_data_t keydata); +			       gpgme_export_mode_t mode, +                               gpgme_data_t keydata);  gpgme_error_t gpgme_op_export_ext_start (gpgme_ctx_t ctx,  					 const char *pattern[], -					 unsigned int reserved, +					 gpgme_export_mode_t mode,  					 gpgme_data_t keydata);  gpgme_error_t gpgme_op_export_ext (gpgme_ctx_t ctx, const char *pattern[], -				   unsigned int reserved, +				   gpgme_export_mode_t mode,  				   gpgme_data_t keydata); +/* Export the keys from the array KEYS into KEYDATA.  */ +gpgme_error_t gpgme_op_export_keys_start (gpgme_ctx_t ctx, +                                          gpgme_key_t keys[], +                                          gpgme_export_mode_t mode, +                                          gpgme_data_t keydata); +gpgme_error_t gpgme_op_export_keys (gpgme_ctx_t ctx, +                                    gpgme_key_t keys[], +                                    gpgme_export_mode_t mode, +                                    gpgme_data_t keydata); + +  /* Key generation.  */  struct _gpgme_op_genkey_result diff --git a/src/import.c b/src/import.c index ad6b776b..8212a25e 100644 --- a/src/import.c +++ b/src/import.c @@ -238,7 +238,7 @@ _gpgme_op_import_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t keydata)    _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx); -  return _gpgme_engine_op_import (ctx->engine, keydata); +  return _gpgme_engine_op_import (ctx->engine, keydata, NULL);  } @@ -260,6 +260,84 @@ gpgme_op_import (gpgme_ctx_t ctx, gpgme_data_t keydata)  } + +static gpgme_error_t +_gpgme_op_import_keys_start (gpgme_ctx_t ctx, int synchronous,  +                             gpgme_key_t *keys) +{ +  gpgme_error_t err; +  void *hook; +  op_data_t opd; +  int idx, firstidx, nkeys; + +  err = _gpgme_op_reset (ctx, synchronous); +  if (err) +    return err; + +  err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, +			       sizeof (*opd), release_op_data); +  opd = hook; +  if (err) +    return err; +  opd->lastp = &opd->result.imports; + +  if (!keys) +    return gpg_error (GPG_ERR_NO_DATA); + +  for (idx=nkeys=0, firstidx=-1; keys[idx]; idx++) +    { +      /* We only consider keys of the current protocol.  */ +      if (keys[idx]->protocol != ctx->protocol) +        continue; +      if (firstidx == -1) +        firstidx = idx; +      /* If a key has been found using a different key listing mode, +         we bail out.  This makes the processing easier.  Fixme: To +         allow a mix of keys we would need to sort them by key listing +         mode and start two import operations one after the other.  */ +      if (keys[idx]->keylist_mode != keys[firstidx]->keylist_mode) +        return gpg_error (GPG_ERR_CONFLICT); +      nkeys++; +    } +  if (!nkeys) +    return gpg_error (GPG_ERR_NO_DATA); + +  _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx); + +  return _gpgme_engine_op_import (ctx->engine, NULL, keys); +} + + +/* Asynchronous version of gpgme_op_import_key.  */ +gpgme_error_t +gpgme_op_import_keys_start (gpgme_ctx_t ctx, gpgme_key_t *keys) +{ +  return _gpgme_op_import_keys_start (ctx, 0, keys); +} + + +/* Import the keys from the array KEYS into the keyring.  This +   function allows to move a key from one engine to another as long as +   they are compatible.  In particular it is used to actually import +   keys retrieved from an external source (i.e. using +   GPGME_KEYLIST_MODE_EXTERN).  It replaces the old workaround of +   exporting and then importing a key as used to make an X.509 key +   permanent.  This function automagically does the right thing. + +   KEYS is a NULL terminated array of gpgme key objects.  The result +   is the usual import result structure.  Only keys matching the +   current protocol are imported; other keys are ignored.  */ +gpgme_error_t +gpgme_op_import_keys (gpgme_ctx_t ctx, gpgme_key_t *keys) +{ +  gpgme_error_t err = _gpgme_op_import_keys_start (ctx, 1, keys); +  if (!err) +    err = _gpgme_wait_one (ctx); +  return err; +} + + +/* Deprecated interface.  */  gpgme_error_t  gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata, int *nr)  { diff --git a/src/libgpgme.vers b/src/libgpgme.vers index 44f61760..41fa1be9 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -59,6 +59,11 @@ GPGME_1.1 {      gpgme_result_ref;      gpgme_result_unref; + +    gpgme_op_import_keys; +    gpgme_op_import_keys_start; +    gpgme_op_export_keys; +    gpgme_op_export_keys_start;  }; | 
