diff options
| -rw-r--r-- | NEWS | 3 | ||||
| -rw-r--r-- | doc/gpgme.texi | 34 | ||||
| -rw-r--r-- | src/engine-assuan.c | 1 | ||||
| -rw-r--r-- | src/engine-backend.h | 1 | ||||
| -rw-r--r-- | src/engine-g13.c | 1 | ||||
| -rw-r--r-- | src/engine-gpg.c | 33 | ||||
| -rw-r--r-- | src/engine-gpgconf.c | 1 | ||||
| -rw-r--r-- | src/engine-gpgsm.c | 1 | ||||
| -rw-r--r-- | src/engine-spawn.c | 1 | ||||
| -rw-r--r-- | src/engine-uiserver.c | 1 | ||||
| -rw-r--r-- | src/engine.c | 13 | ||||
| -rw-r--r-- | src/engine.h | 2 | ||||
| -rw-r--r-- | src/gpgme.def | 7 | ||||
| -rw-r--r-- | src/gpgme.h.in | 15 | ||||
| -rw-r--r-- | src/keylist.c | 36 | ||||
| -rw-r--r-- | src/libgpgme.vers | 1 | ||||
| -rw-r--r-- | tests/run-keylist.c | 24 | 
17 files changed, 167 insertions, 8 deletions
| @@ -11,6 +11,8 @@ Noteworthy changes in version 1.8.1 (unreleased)   gpgme_op_createsubkey       CHANGED: Meaning of 'expire' parameter.   GPGME_CREATE_NOEXPIRE       NEW.   gpgme_subkey_t              EXTENDED: New field is_de_vs. + gpgme_op_keylist_from_data_start NEW. + gpgme_data_rewind                UN-DEPRECATE.   cpp: Context::revUid(const Key&, const char*)      NEW.   cpp: Context::startRevUid(const Key&, const char*) NEW.   cpp: Context::addUid(const Key&, const char*)      NEW. @@ -22,7 +24,6 @@ Noteworthy changes in version 1.8.1 (unreleased)   cpp: Subkey::keyGrip                               NEW.   cpp: Subkey::isDeVs                                NEW.   qt: CryptoConfig::stringValueList()                NEW. - gpgme_data_rewind                                  UN-DEPRECATE.   py: Context.__init__        EXTENDED: New keyword arg home_dir.   py: Context.home_dir        NEW.   py: Context.keylist         EXTENDED: New keyword arg mode. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 337053fb..edcbb98c 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3342,6 +3342,7 @@ This is a linked list with the notation data and policy URLs.  @cindex key ring, search  @deftypefun gpgme_error_t gpgme_op_keylist_start (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{pattern}}, @w{int @var{secret_only}}) +  The function @code{gpgme_op_keylist_start} initiates a key listing  operation inside the context @var{ctx}.  It sets everything up so that  subsequent invocations of @code{gpgme_op_keylist_next} return the keys @@ -3369,6 +3370,7 @@ are reported by the crypto engine support routines.  @end deftypefun  @deftypefun gpgme_error_t gpgme_op_keylist_ext_start (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{pattern}[]}, @w{int @var{secret_only}}, @w{int @var{reserved}}) +  The function @code{gpgme_op_keylist_ext_start} initiates an extended  key listing operation inside the context @var{ctx}.  It sets  everything up so that subsequent invocations of @@ -3399,7 +3401,36 @@ The function returns the error code @code{GPG_ERR_INV_VALUE} if  are reported by the crypto engine support routines.  @end deftypefun +@deftypefun gpgme_error_t gpgme_op_keylist_from_data @ +            (@w{gpgme_ctx_t @var{ctx}}, @ +             @w{gpgme_data_t @var{data}}, @ +             @w{int @var{reserved}}) + +The function @code{gpgme_op_keylist_from_data_start} initiates a key +listing operation inside the context @var{ctx}.  In contrast to the +other key listing operation the keys are read from the supplied +@var{data} and not from the local key database.  The keys are also not +imported into the local ley database. The function sets everything up +so that subsequent invocations of @code{gpgme_op_keylist_next} return +the keys from @var{data}. + +The value of @var{reserved} must be @code{0}. + +This function requires at least GnuPG version 2.1.14 and currently +works only with OpenPGP keys. + +The context will be busy until either all keys are received (and +@code{gpgme_op_keylist_next} returns @code{GPG_ERR_EOF}), or +@code{gpgme_op_keylist_end} is called to finish the operation. +While the context is busy @var{data} may not be released. + +The function returns the error code @code{GPG_ERR_INV_VALUE} if +@var{ctx} is not a valid pointer, and passes through any errors that +are reported by the crypto engine support routines. +@end deftypefun +  @deftypefun gpgme_error_t gpgme_op_keylist_next (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t *@var{r_key}}) +  The function @code{gpgme_op_keylist_next} returns the next key in the  list created by a previous @code{gpgme_op_keylist_start} operation in  the context @var{ctx}.  The key will have one reference for the user. @@ -3417,6 +3448,7 @@ The function returns the error code @code{GPG_ERR_INV_VALUE} if  @end deftypefun  @deftypefun gpgme_error_t gpgme_op_keylist_end (@w{gpgme_ctx_t @var{ctx}}) +  The function @code{gpgme_op_keylist_end} ends a pending key list  operation in the context @var{ctx}. @@ -3431,7 +3463,7 @@ time during the operation there was not enough memory available.  The following example illustrates how all keys containing a certain  string (@code{g10code}) can be listed with their key ID and the name -and e-mail address of the main user ID: +and email address of the main user ID:  @example  gpgme_ctx_t ctx; diff --git a/src/engine-assuan.c b/src/engine-assuan.c index 78efb4cb..4beb41d7 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -787,6 +787,7 @@ struct engine_ops _gpgme_engine_ops_assuan =      NULL,               /* import */      NULL,               /* keylist */      NULL,               /* keylist_ext */ +    NULL,               /* keylist_data */      NULL,               /* keysign */      NULL,               /* tofu_policy */      NULL,               /* sign */ diff --git a/src/engine-backend.h b/src/engine-backend.h index a8457afd..635acb06 100644 --- a/src/engine-backend.h +++ b/src/engine-backend.h @@ -100,6 +100,7 @@ struct engine_ops  				int secret_only, int reserved,  				gpgme_keylist_mode_t mode,  				int engine_flags); +  gpgme_error_t (*keylist_data) (void *engine, gpgme_data_t data);    gpgme_error_t (*keysign) (void *engine,                              gpgme_key_t key, const char *userid,                              unsigned long expires, unsigned int flags, diff --git a/src/engine-g13.c b/src/engine-g13.c index bb06d356..593177c2 100644 --- a/src/engine-g13.c +++ b/src/engine-g13.c @@ -802,6 +802,7 @@ struct engine_ops _gpgme_engine_ops_g13 =      NULL,               /* import */      NULL,               /* keylist */      NULL,               /* keylist_ext */ +    NULL,               /* keylist_data */      NULL,               /* keysign */      NULL,               /* tofu_policy */      NULL,               /* sign */ diff --git a/src/engine-gpg.c b/src/engine-gpg.c index 59cf405a..4b87a8a0 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2731,6 +2731,38 @@ gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,  static gpgme_error_t +gpg_keylist_data (void *engine, gpgme_data_t data) +{ +  engine_gpg_t gpg = engine; +  gpgme_error_t err; + +  if (!have_gpg_version (gpg, "2.1.14")) +    return gpg_error (GPG_ERR_NOT_SUPPORTED); + +  err = add_arg (gpg, "--with-colons"); +  if (!err) +    err = add_arg (gpg, "--with-fingerprint"); +  if (!err) +    err = add_arg (gpg, "--import-options"); +  if (!err) +    err = add_arg (gpg, "import-show"); +  if (!err) +    err = add_arg (gpg, "--dry-run"); +  if (!err) +    err = add_arg (gpg, "--import"); +  if (!err) +    err = add_arg (gpg, "--"); +  if (!err) +    err = add_data (gpg, data, -1, 0); + +  if (!err) +    err = start (gpg); + +  return err; +} + + +static gpgme_error_t  gpg_keysign (void *engine, gpgme_key_t key, const char *userid,               unsigned long expire, unsigned int flags,               gpgme_ctx_t ctx) @@ -3013,6 +3045,7 @@ struct engine_ops _gpgme_engine_ops_gpg =      gpg_import,      gpg_keylist,      gpg_keylist_ext, +    gpg_keylist_data,      gpg_keysign,      gpg_tofu_policy,    /* tofu_policy */      gpg_sign, diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c index 3e463105..48919775 100644 --- a/src/engine-gpgconf.c +++ b/src/engine-gpgconf.c @@ -1244,6 +1244,7 @@ struct engine_ops _gpgme_engine_ops_gpgconf =      NULL,		/* import */      NULL,		/* keylist */      NULL,		/* keylist_ext */ +    NULL,               /* keylist_data */      NULL,               /* keysign */      NULL,               /* tofu_policy */      NULL,		/* sign */ diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index d5d29010..7652363a 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -2106,6 +2106,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm =      gpgsm_import,      gpgsm_keylist,      gpgsm_keylist_ext, +    NULL,               /* keylist_data */      NULL,               /* keysign */      NULL,               /* tofu_policy */      gpgsm_sign, diff --git a/src/engine-spawn.c b/src/engine-spawn.c index 1cd4421e..fa406d4c 100644 --- a/src/engine-spawn.c +++ b/src/engine-spawn.c @@ -460,6 +460,7 @@ struct engine_ops _gpgme_engine_ops_spawn =      NULL,		/* import */      NULL,		/* keylist */      NULL,		/* keylist_ext */ +    NULL,               /* keylist_data */      NULL,               /* keysign */      NULL,               /* tofu_policy */      NULL,		/* sign */ diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index ff5227ee..12efd270 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -1394,6 +1394,7 @@ struct engine_ops _gpgme_engine_ops_uiserver =      NULL,		/* import */      NULL,		/* keylist */      NULL,		/* keylist_ext */ +    NULL,               /* keylist_data */      NULL,               /* keysign */      NULL,               /* tofu_policy */      uiserver_sign, diff --git a/src/engine.c b/src/engine.c index 75d9ff7b..a918a50d 100644 --- a/src/engine.c +++ b/src/engine.c @@ -876,6 +876,19 @@ _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],  gpgme_error_t +_gpgme_engine_op_keylist_data (engine_t engine, gpgme_data_t data) +{ +  if (!engine) +    return gpg_error (GPG_ERR_INV_VALUE); + +  if (!engine->ops->keylist_data) +    return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + +  return (*engine->ops->keylist_data) (engine->engine, data); +} + + +gpgme_error_t  _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,  		       gpgme_sig_mode_t mode, int use_armor,  		       int use_textmode, int include_certs, diff --git a/src/engine.h b/src/engine.h index 29d2f259..f456812e 100644 --- a/src/engine.h +++ b/src/engine.h @@ -148,6 +148,8 @@ gpgme_error_t _gpgme_engine_op_keylist_ext (engine_t engine,  					    int reserved,  					    gpgme_keylist_mode_t mode,  					    int engine_flags); +gpgme_error_t _gpgme_engine_op_keylist_data (engine_t engine, +					     gpgme_data_t data);  gpgme_error_t _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in,  				     gpgme_data_t out, gpgme_sig_mode_t mode,  				     int use_armor, int use_textmode, diff --git a/src/gpgme.def b/src/gpgme.def index 0d3ce74f..ddd57d35 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -177,8 +177,8 @@ EXPORTS      gpgme_io_read                         @136      gpgme_io_write                        @137 -    gpgme_result_ref                     @138 -    gpgme_result_unref                   @139 +    gpgme_result_ref                      @138 +    gpgme_result_unref                    @139      gpgme_op_import_keys                  @140      gpgme_op_import_keys_start            @141 @@ -253,5 +253,8 @@ EXPORTS      gpgme_op_query_swdb_result            @190      gpgme_get_ctx_flag                    @191 + +    gpgme_op_keylist_from_data_start      @192 +  ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index b660cb51..2cf096b6 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1817,20 +1817,31 @@ typedef struct _gpgme_op_keylist_result *gpgme_keylist_result_t;  gpgme_keylist_result_t gpgme_op_keylist_result (gpgme_ctx_t ctx);  /* Start a keylist operation within CTX, searching for keys which -   match PATTERN.  If SECRET_ONLY is true, only secret keys are -   returned.  */ + * match PATTERN.  If SECRET_ONLY is true, only secret keys are + * returned.  */  gpgme_error_t gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern,  				      int secret_only);  gpgme_error_t gpgme_op_keylist_ext_start (gpgme_ctx_t ctx,  					  const char *pattern[],  					  int secret_only, int reserved); +/* List the keys contained in DATA.  */ +gpgme_error_t gpgme_op_keylist_from_data_start (gpgme_ctx_t ctx, +                                                gpgme_data_t data, +                                                int reserved); +  /* Return the next key from the keylist in R_KEY.  */  gpgme_error_t gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key);  /* Terminate a pending keylist operation within CTX.  */  gpgme_error_t gpgme_op_keylist_end (gpgme_ctx_t ctx); + + +/* + * Protecting keys + */ +  /* Change the passphrase for KEY.  FLAGS is reserved for future use     and must be passed as 0.  */  gpgme_error_t gpgme_op_passwd_start (gpgme_ctx_t ctx, gpgme_key_t key, diff --git a/src/keylist.c b/src/keylist.c index de9bbb2f..c88a7ca5 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -1142,6 +1142,42 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[],  } +/* Start a keylist operation within CTX to show keys contained + * in DATA.  */ +gpgme_error_t +gpgme_op_keylist_from_data_start (gpgme_ctx_t ctx, gpgme_data_t data, +                                  int reserved) +{ +  gpgme_error_t err; +  void *hook; +  op_data_t opd; + +  TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_from_data_start", ctx); + +  if (!ctx || !data || reserved) +    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); + +  err = _gpgme_op_reset (ctx, 2); +  if (err) +    return TRACE_ERR (err); + +  err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, +                               sizeof (*opd), release_op_data); +  opd = hook; +  if (err) +    return TRACE_ERR (err); + +  _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx); +  err = _gpgme_engine_set_colon_line_handler (ctx->engine, +                                              keylist_colon_handler, ctx); +  if (err) +    return TRACE_ERR (err); + +  err = _gpgme_engine_op_keylist_data (ctx->engine, data); +  return TRACE_ERR (err); +} + +  /* Return the next key from the keylist in R_KEY.  */  gpgme_error_t  gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key) diff --git a/src/libgpgme.vers b/src/libgpgme.vers index a55cd10a..9344a752 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -223,6 +223,7 @@ GPGME_1.0 {      gpgme_op_import_start;      gpgme_op_keylist_end;      gpgme_op_keylist_ext_start; +    gpgme_op_keylist_from_data_start;      gpgme_op_keylist_next;      gpgme_op_keylist_result;      gpgme_op_keylist_start; diff --git a/tests/run-keylist.c b/tests/run-keylist.c index fd9c7c20..aab4bb64 100644 --- a/tests/run-keylist.c +++ b/tests/run-keylist.c @@ -41,7 +41,7 @@ static int verbose;  static int  show_usage (int ex)  { -  fputs ("usage: " PGM " [options] [USERID]\n\n" +  fputs ("usage: " PGM " [options] [USERID_or_FILE]\n\n"           "Options:\n"           "  --verbose        run in verbose mode\n"           "  --openpgp        use the OpenPGP protocol (default)\n" @@ -56,6 +56,7 @@ show_usage (int ex)           "  --validate       use GPGME_KEYLIST_MODE_VALIDATE\n"           "  --import         import all keys\n"           "  --offline        use offline mode\n" +         "  --from-file      list all keys in the given file\n"           "  --require-gnupg  required at least the given GnuPG version\n"           , stderr);    exit (ex); @@ -98,6 +99,9 @@ main (int argc, char **argv)    gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;    int only_secret = 0;    int offline = 0; +  int from_file = 0; +  gpgme_data_t data = NULL; +    if (argc)      { argc--; argv++; } @@ -177,6 +181,11 @@ main (int argc, char **argv)            offline = 1;            argc--; argv++;          } +      else if (!strcmp (*argv, "--from-file")) +        { +          from_file = 1; +          argc--; argv++; +        }        else if (!strcmp (*argv, "--require-gnupg"))          {            argc--; argv++; @@ -191,6 +200,8 @@ main (int argc, char **argv)    if (argc > 1)      show_usage (1); +  else if (from_file && !argc) +    show_usage (1);    init_gpgme (protocol); @@ -202,7 +213,15 @@ main (int argc, char **argv)    gpgme_set_offline (ctx, offline); -  err = gpgme_op_keylist_start (ctx, argc? argv[0]:NULL, only_secret); +  if (from_file) +    { +      err = gpgme_data_new_from_file (&data, *argv, 1); +      fail_if_err (err); + +      err = gpgme_op_keylist_from_data_start (ctx, data, 0); +    } +  else +    err = gpgme_op_keylist_start (ctx, argc? argv[0]:NULL, only_secret);    fail_if_err (err);    while (!(err = gpgme_op_keylist_next (ctx, &key))) @@ -322,6 +341,7 @@ main (int argc, char **argv)    err = gpgme_op_keylist_end (ctx);    fail_if_err (err);    keyarray[keyidx] = NULL; +  gpgme_data_release (data);    result = gpgme_op_keylist_result (ctx);    if (result->truncated) | 
