summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1593
-rw-r--r--Makefile.in4
-rw-r--r--NEWS82
-rw-r--r--README10
-rw-r--r--VERSION2
-rw-r--r--aclocal.m4236
-rw-r--r--config.h.in26
-rwxr-xr-xconfigure284
-rw-r--r--configure.ac101
-rw-r--r--doc/Makefile.in4
-rw-r--r--doc/gpgme.info252
-rw-r--r--doc/gpgme.info-1270
-rw-r--r--doc/gpgme.info-2173
-rw-r--r--doc/gpgme.texi283
-rw-r--r--gpgme.spec2
-rw-r--r--lang/Makefile.in4
-rw-r--r--lang/cl/Makefile.in4
-rw-r--r--lang/cl/gpgme.asd2
-rw-r--r--lang/cpp/Makefile.in4
-rw-r--r--lang/cpp/src/GpgmeppConfig.cmake.in.in4
-rw-r--r--lang/cpp/src/Makefile.am11
-rw-r--r--lang/cpp/src/Makefile.in16
-rw-r--r--lang/cpp/src/context.cpp70
-rw-r--r--lang/cpp/src/context.h28
-rw-r--r--lang/cpp/src/context_p.h1
-rw-r--r--lang/cpp/src/data.cpp24
-rw-r--r--lang/cpp/src/data.h5
-rw-r--r--lang/cpp/src/editinteractor.cpp2
-rw-r--r--lang/cpp/src/gpggencardkeyinteractor.cpp332
-rw-r--r--lang/cpp/src/gpggencardkeyinteractor.h71
-rw-r--r--lang/cpp/src/key.cpp59
-rw-r--r--lang/cpp/src/key.h22
-rw-r--r--lang/cpp/src/verificationresult.cpp3
-rw-r--r--lang/python/Makefile.am59
-rw-r--r--lang/python/Makefile.in64
-rw-r--r--lang/python/gpg/constants/__init__.py8
-rw-r--r--lang/python/gpg/constants/create.py25
-rw-r--r--lang/python/gpg/constants/keysign.py25
-rw-r--r--lang/python/gpg/constants/tofu/__init__.py24
-rw-r--r--lang/python/gpg/constants/tofu/policy.py25
-rw-r--r--lang/python/gpg/core.py350
-rw-r--r--lang/python/gpg/gpgme.py126
-rw-r--r--lang/python/gpg/results.py6
-rw-r--r--lang/python/gpg/version.py2
-rw-r--r--lang/python/gpgme.i138
-rw-r--r--lang/python/helpers.c22
-rwxr-xr-xlang/python/setup.py.in16
-rw-r--r--lang/python/tests/Makefile.am12
-rw-r--r--lang/python/tests/Makefile.in16
-rwxr-xr-xlang/python/tests/initial.py3
-rw-r--r--lang/python/tests/run-tests.py34
-rw-r--r--lang/python/tests/support.py65
-rwxr-xr-xlang/python/tests/t-callbacks.py2
-rwxr-xr-xlang/python/tests/t-decrypt-verify.py1
-rwxr-xr-xlang/python/tests/t-decrypt.py1
-rwxr-xr-xlang/python/tests/t-edit.py4
-rwxr-xr-xlang/python/tests/t-encrypt-large.py1
-rwxr-xr-xlang/python/tests/t-encrypt-sign.py1
-rwxr-xr-xlang/python/tests/t-encrypt-sym.py2
-rwxr-xr-xlang/python/tests/t-encrypt.py16
-rwxr-xr-xlang/python/tests/t-export.py1
-rwxr-xr-xlang/python/tests/t-file-name.py1
-rwxr-xr-xlang/python/tests/t-idiomatic.py2
-rwxr-xr-xlang/python/tests/t-import.py1
-rwxr-xr-xlang/python/tests/t-keylist-from-data.py213
-rwxr-xr-xlang/python/tests/t-keylist.py13
-rwxr-xr-xlang/python/tests/t-protocol-assuan.py9
-rwxr-xr-xlang/python/tests/t-quick-key-creation.py140
-rwxr-xr-xlang/python/tests/t-quick-key-manipulation.py125
-rwxr-xr-xlang/python/tests/t-quick-key-signing.py121
-rwxr-xr-xlang/python/tests/t-quick-subkey-creation.py112
-rwxr-xr-xlang/python/tests/t-sig-notation.py2
-rwxr-xr-xlang/python/tests/t-sign.py2
-rwxr-xr-xlang/python/tests/t-signers.py2
-rwxr-xr-xlang/python/tests/t-trustlist.py1
-rwxr-xr-xlang/python/tests/t-verify.py2
-rwxr-xr-xlang/python/tests/t-wait.py1
-rw-r--r--lang/qt/Makefile.in4
-rw-r--r--lang/qt/doc/Makefile.in4
-rw-r--r--lang/qt/src/Makefile.am9
-rw-r--r--lang/qt/src/Makefile.in13
-rw-r--r--lang/qt/src/QGpgmeConfig.cmake.in.in2
-rw-r--r--lang/qt/src/cryptoconfig.cpp44
-rw-r--r--lang/qt/src/cryptoconfig.h14
-rw-r--r--lang/qt/src/defaultkeygenerationjob.cpp11
-rw-r--r--lang/qt/src/dn.cpp4
-rw-r--r--lang/qt/src/qgpgmenewcryptoconfig.cpp26
-rw-r--r--lang/qt/src/qgpgmenewcryptoconfig.h2
-rw-r--r--lang/qt/src/threadedjobmixin.h1
-rw-r--r--lang/qt/tests/Makefile.am11
-rw-r--r--lang/qt/tests/Makefile.in51
-rw-r--r--lang/qt/tests/t-config.cpp94
-rw-r--r--lang/qt/tests/t-encrypt.cpp125
-rw-r--r--lang/qt/tests/t-keylist.cpp18
-rw-r--r--lang/qt/tests/t-keylocate.cpp26
-rw-r--r--lang/qt/tests/t-ownertrust.cpp18
-rw-r--r--lang/qt/tests/t-support.cpp2
-rw-r--r--lang/qt/tests/t-support.h10
-rw-r--r--lang/qt/tests/t-tofuinfo.cpp291
-rw-r--r--lang/qt/tests/t-various.cpp167
-rw-r--r--lang/qt/tests/t-verify.cpp8
-rw-r--r--lang/qt/tests/t-wkspublish.cpp52
-rw-r--r--m4/ax_python_devel.m47
-rw-r--r--m4/python.m4241
-rw-r--r--m4/qt.m46
-rw-r--r--src/Makefile.in10
-rw-r--r--src/context.h6
-rw-r--r--src/conversion.c19
-rw-r--r--src/data-compat.c13
-rw-r--r--src/data.c14
-rw-r--r--src/debug.c14
-rw-r--r--src/decrypt-verify.c67
-rw-r--r--src/decrypt.c18
-rw-r--r--src/dirinfo.c12
-rw-r--r--src/engine-assuan.c18
-rw-r--r--src/engine-backend.h8
-rw-r--r--src/engine-g13.c18
-rw-r--r--src/engine-gpg.c108
-rw-r--r--src/engine-gpgconf.c71
-rw-r--r--src/engine-gpgsm.c52
-rw-r--r--src/engine-spawn.c2
-rw-r--r--src/engine-uiserver.c87
-rw-r--r--src/engine.c36
-rw-r--r--src/engine.h17
-rw-r--r--src/funopen.c63
-rw-r--r--src/genkey.c62
-rw-r--r--src/gpgme.c8
-rw-r--r--src/gpgme.def13
-rw-r--r--src/gpgme.h.in785
-rw-r--r--src/import.c4
-rw-r--r--src/key.c39
-rw-r--r--src/keylist.c84
-rw-r--r--src/libgpgme.vers7
-rw-r--r--src/op-support.c1
-rw-r--r--src/ops.h3
-rw-r--r--src/posix-io.c116
-rw-r--r--src/progress.c8
-rw-r--r--src/util.h14
-rw-r--r--src/vasprintf.c206
-rw-r--r--src/verify.c39
-rw-r--r--src/versioninfo.rc.in2
-rw-r--r--src/vfs-create.c8
-rw-r--r--src/vfs-mount.c10
-rw-r--r--src/w32-io.c14
-rw-r--r--src/w32-util.c5
-rw-r--r--tests/Makefile.in4
-rw-r--r--tests/gpg/Makefile.am3
-rw-r--r--tests/gpg/Makefile.in7
-rw-r--r--tests/gpg/t-gpgconf.c161
-rw-r--r--tests/gpg/t-support.h28
-rw-r--r--tests/gpg/t-thread-keylist-verify.c2
-rw-r--r--tests/gpg/t-thread-keylist.c2
-rw-r--r--tests/gpgsm/Makefile.in4
-rw-r--r--tests/opassuan/Makefile.in4
-rw-r--r--tests/run-decrypt.c18
-rw-r--r--tests/run-encrypt.c12
-rw-r--r--tests/run-genkey.c69
-rw-r--r--tests/run-keylist.c36
-rw-r--r--tests/run-sign.c4
-rwxr-xr-xtests/start-stop-agent21
-rw-r--r--tests/t-engine-info.c4
161 files changed, 7105 insertions, 2396 deletions
diff --git a/ChangeLog b/ChangeLog
index 161b7b4..40c0b4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,10 +1,950 @@
+2017-03-28 Werner Koch <wk@gnupg.org>
+
+ Release 1.9.0.
+ + commit aa0390ec3b910bbbc323a15ec3c3351e77785a9a
+ * configure.ac <c>: Bump LT version to C29/A18/R0.
+ <cpp>: Bump LT version to C10/A4/R0.
+ <qt>: Bump LT version to C9/A2/R0.
+
+ core: Prepare for new key listing data send by gpg.
+ + commit 813ae5fa2d712aa9679b791c67c9c1c43d36ffe4
+ * src/gpgme.h.in (gpgme_user_id_t): New fields 'origin' and
+ 'last_update'.
+ (gpgme_key_t): New fields 'origin' and 'last_update'.
+ * src/conversion.c (_gpgme_parse_timestamp_ul): New.
+ * src/keylist.c (keylist_colon_handler): Parse fields 19 and 20.
+
+ * tests/run-keylist.c (main): Print new fields.
+
+2017-03-27 Andre Heinecke <aheinecke@intevation.de>
+
+ qt: Disable testEncryptDecryptNowrap.
+ + commit 57d60b20f16dd5f1bccbbcaa0a6ed75a554a6414
+ * lang/qt/tests/t-encrypt.cpp (EncryptTest::testEncryptDecryptNowrap):
+ Disable test.
+
+2017-03-27 Justus Winter <justus@g10code.com>
+
+ python: Skip tests if running with GnuPG < 2.1.12.
+ + commit 348da58fe0c3656e6177c98fef6b4c4331326c8e
+ * lang/python/tests/support.py (assert_gpg_version): Fix error
+ message. Skip all tests when we use GnuPG older than 2.1.12.
+
+2017-03-24 Andre Heinecke <aheinecke@intevation.de>
+
+ cpp: Respect decrypt flags in new functions.
+ + commit 18b7906078cf08962c54c1e711cf2d91a24fd4e5
+ * lang/cpp/src/context.cpp: Respect directly provided flags
+ in the new decrypt functions.
+
+ qt: Add unittest for decrypt unwrap.
+ + commit 5493164f8665fabf795f3b34a7084770a38ae940
+ * lang/qt/tests/t-encrypt.cpp
+ (EncryptTest::testEncryptDecryptNowrap): New.
+
+ cpp: Use gpgme_op_decrypt_ex and add new flags.
+ + commit 8ad37ecc297f208d0a63783c1ffae33ad4c3c81a
+ * lang/cpp/src/context.cpp: New decrypt and decryptVerify functions
+ that take flags as arguments. Use new variants in old functions.
+ (Context::setDecryptionFlags): New helper.
+ (Context::Private::Private): Initialize new member.
+ * lang/cpp/src/context_p.h (Context::Private::decryptFlags): New.
+ * lang/cpp/src/context.h (Context::DecryptFlags): New enum.
+ (Context::EncryptionFlags): Extend for EncryptWrap.
+
+2017-03-24 Werner Koch <wk@gnupg.org>
+
+ core: New flags GPGME_DECRYPT_UNWRAP and GPGME_ENCRYPT_WRAP.
+ + commit 6ac1f2cdedb085b4ac9372c1e591497e2e618de4
+ * src/gpgme.h.in (GPGME_ENCRYPT_WRAP): New const.
+ (gpgme_decrypt_flags_t): New enum.
+ (GPGME_DECRYPT_VERIFY): New const
+ (GPGME_DECRYPT_UNWRAP): New const
+ (gpgme_op_decrypt_ext_start): New func.
+ (gpgme_op_decrypt_ext): New func.
+ * src/decrypt-verify.c (gpgme_op_decrypt_ext_start): New.
+ (gpgme_op_decrypt_ext): New.
+ (decrypt_verify_start): Add arg FLAGS. Replace call to
+ engine_op_decrypt_verify by the plain decrypt with the flag set.
+ (gpgme_op_decrypt_verify_start): Pass the flag.
+ (gpgme_op_decrypt_verify): Pass the flag.
+ * src/decrypt.c (decrypt_start): Rename to ...
+ (_gpgme_decrypt_start): this. Add arg FLAGS. Pass FLAGS to
+ engine_op_decrypt.
+ (gpgme_op_decrypt_start): Adjust for chnage pass 0 for FLAG.
+ (gpgme_op_decrypt_start): Ditto.
+ * src/engine.c (_gpgme_engine_op_decrypt_verify): Remove.
+ (_gpgme_engine_op_decrypt): Add arg FLAGS.
+ * src/gpgme.def, src/libgpgme.vers: Add new functions.
+ * src/engine-backend.h (struct engine_ops): Remove member
+ 'decrypt_verify'. Add FLAGS to 'decrypt'. Adjust all initialization.
+ * src/engine-uiserver.c (uiserver_decrypt): Remove.
+ (uiserver_decrypt_verify): Remove.
+ (_uiserver_decrypt): Rename to ...
+ (uiserver_decrypt): this. Replace arg VERIFY by new arg FLAGS.
+ * src/engine-gpg.c (gpg_decrypt): Support GPGME_DECRYPT_UNWRAP.
+ (gpg_encrypt): Support GPGME_ENCRYPT_WRAP.
+
+ * tests/run-decrypt.c (main): New option --unwrap.
+ * tests/run-encrypt.c (main): New option --wrap.
+
+2017-03-22 Andre Heinecke <aheinecke@intevation.de>
+
+ qt: Add test for Data::toKeys.
+ + commit 66c334650bd64fdb72c4bd5975e25b8659d320ec
+ * lang/qt/tests/t-various.cpp (TestVarious::testKeyFromFile): New.
+
+ cpp: Wrap keylist_from_data.
+ + commit 8ddb42ada46f00d8393f6c2df7d6b79a4a5878f0
+ * lang/cpp/data.h, lang/cpp/data.cpp (GpgME::Data::toKeys): New.
+
+ qt: Initialize library first in tests.
+ + commit 121873b821636052c10d9e0bd885eb9013c52096
+ * lang/qt/tests/t-support.cpp (QGpgMETest::initTestCase): Initialize
+ library.
+
+2017-03-22 Justus Winter <justus@g10code.com>
+
+ python: Improve Python detection.
+ + commit 104635eb503ec764146731888a6975b4329660fd
+ * m4/python.m4 (_AM_PYTHON_INTERPRETER_LIST): Prefer the generic
+ 'pythonX' over 'pythonX.Y'. This way we select the users preferred
+ version for both flavors. Prefer 'python' over 'python3' but not over
+ 'python2' so that the algorithm still finds a 'python2' even if
+ 'python' is a Python3.
+
+2017-03-21 Werner Koch <wk@gnupg.org>
+
+ core: New API gpgme_op_set_uid_flag.
+ + commit 421ddd1e6706046c5062417fd69a87e10c9fc0a9
+ * src/gpgme.h.in (gpgme_op_set_uid_flag_start): New.
+ (gpgme_op_set_uid_flag_start): New.
+ * src/gpgme.def, src/libgpgme.vers: Add them.
+ * src/genkey.c (addrevuid_start): Change arg revoke to a flag.
+ (gpgme_op_revuid_start): Pass GENKEY_EXTRAFLAG_REVOKE for the fomer
+ revoke parameter.
+ (gpgme_op_revuid): Ditto.
+ (set_uid_flag): New.
+ (gpgme_op_set_uid_flag_start): New.
+ (gpgme_op_set_uid_flag): New.
+ * src/engine.h (GENKEY_EXTRAFLAG_SETPRIMARY): new.
+ * src/engine-gpg.c (gpg_adduid): Implement that flag.
+
+ * tests/run-genkey.c (main): New command --set-primary.
+
+2017-03-21 Justus Winter <justus@g10code.com>
+
+ python: Wrap 'gpgme_op_keylist_from_data_start'.
+ + commit f3e8d8a4518de2768692e0b392262d0da6d0fd84
+ * NEWS: Update.
+ * lang/python/gpg/core.py (Context.keylist): New keyword argument
+ 'source'. If given, list keys from 'source'.
+ * lang/python/gpgme.i: Wrap the argument to
+ 'gpgme_op_keylist_from_data_start'.
+ * lang/python/tests/Makefile.am (py_tests): Add new test.
+ * lang/python/tests/support.py (EphemeralContext): Do not throw an
+ error if no agent has been started in the context.
+ * lang/python/tests/t-keylist-from-data.py: New file.
+
+2017-03-21 Werner Koch <wk@gnupg.org>
+
+ core: Extend gpgme_get_dirinfo to return the gpg-wks-client name.
+ + commit 55ac5eed9f59081283d34098a9e0ada753d61d59
+ * src/dirinfo.c (WANT_GPG_WKS_CLIENT_NAME): New const.
+ (struct dirinfo): New field 'gpg_wks_client_name'.
+ (get_gpgconf_item): Build it on demand.
+ (gpgme_get_dirinfo): New value "gpg-wks-client-name" for WHAT.
+
+ core: New encryption flag GPGME_ENCRYPT_THROW_KEYIDS.
+ + commit fab8b1a166fff7265d8a7a7acbbf5f30d26cc93c
+ * src/gpgme.h.in (GPGME_ENCRYPT_THROW_KEYIDS): New flag.
+ * src/engine-gpg.c (gpg_encrypt): Implement flag
+ (gpg_encrypt_sign): Implement flag.
+
+ * tests/run-encrypt.c (main): New option --throw-keyids.
+
+2017-03-21 Andre Heinecke <aheinecke@intevation.de>
+ Werner Koch <wk@gnupg.org>
+
+ core: New public API gpgme_op_keylist_from_data_start.
+ + commit 35023f313622fb1b34108dd934e84831c58b81aa
+ * src/gpgme.h.in: New API gpgme_op_keylist_from_data_start.
+ * src/libgpgme.vers, src/gpgme.def: Add it.
+ * src/keylist.c (gpgme_op_keylist_from_data_start): New.
+ * src/engine-backend.h (engine_ops): Add field 'keylist_data'. Change
+ all engines to pass NULL for it.
+ * src/engine.c (_gpgme_engine_op_keylist_data): New.
+ * src/engine-gpg.c (gpg_keylist_data): New.
+ (_gpgme_engine_ops_gpg): Register gpg_keylist_data.
+
+ * tests/run-keylist.c (main): New option --from-file.
+
+2017-03-20 Werner Koch <wk@gnupg.org>
+
+ core,cpp: New key flag 'is_de_vs'.
+ + commit ea9686ec71a2dd2225ce2b6d6d4038821d36205f
+ * src/gpgme.h.in (_gpgme_subkey): New flag is_de_vs.
+ * tests/run-keylist.c (main): Print that flag.
+ * src/keylist.c (parse_pub_field18): New.
+ (keylist_colon_handler): Parse compliance flags.
+ * lang/cpp/src/key.cpp (Key::isDeVs): New.
+ (Subkey::isDeVs): New.
+
+ * lang/cpp/src/key.h (class Key): New method isDeVs.
+ (class Subkey): New method isDeVs.
+
+2017-03-20 Justus Winter <justus@g10code.com>
+
+ tests: Fix distcheck.
+ + commit 392e51dd1181d035c19918222da65d08fdb2ee6d
+ * tests/start-stop-agent: Do not create 'gpg-agent.conf' if it does
+ not exist.
+
+ python: Fix version check.
+ + commit 57e64d019d993fdeb4323def5352f8ecc98c6fd9
+ * lang/python/tests/support.py (assert_gpg_version): Cope with
+ non-released versions.
+
+ tests: Use 'gpg-agent --allow-loopback-pinentry' if applicable.
+ + commit 16b202d9999591b71fb8bb49f6db10ef96d4cbe8
+ * lang/python/tests/Makefile.am (gpg-agent.conf): Do not hard-code the
+ option. This breaks gpg-agent from GnuPG 2.0.
+ * tests/start-stop-agent: Rather, check if the option is supported and
+ add it to the configuration if it is.
+
+ python: Skip tests if GnuPG is too old.
+ + commit e1cf8bab319ba1dea41ba5d711dbb66ffd8e6fd6
+ * lang/python/tests/support.py (assert_gpg_version): New function.
+ * lang/python/tests/t-callbacks.py: Use the new function to skip the
+ test if GnuPG is too old.
+ * lang/python/tests/t-edit.py: Likewise.
+ * lang/python/tests/t-encrypt-sym.py: Likewise.
+ * lang/python/tests/t-quick-key-creation.py: Likewise.
+ * lang/python/tests/t-quick-key-manipulation.py: Likewise.
+ * lang/python/tests/t-quick-key-signing.py: Likewise.
+
+ python: Remove superfluous initialization.
+ + commit 4572e8d2ac1d3b45e75ce71265c99e591fbf0e28
+ * lang/python/tests/support.py (init_gpgme): Remove. This is an
+ remnant from the c tests. Nowadays, the Python bindings initialize
+ GPGME automagically.
+ * lang/python/tests/initial.py: Remove call to 'support.init_gpgme'.
+ * lang/python/tests/t-callbacks.py: Likewise.
+ * lang/python/tests/t-decrypt-verify.py: Likewise.
+ * lang/python/tests/t-decrypt.py: Likewise.
+ * lang/python/tests/t-edit.py: Likewise.
+ * lang/python/tests/t-encrypt-large.py: Likewise.
+ * lang/python/tests/t-encrypt-sign.py: Likewise.
+ * lang/python/tests/t-encrypt-sym.py: Likewise.
+ * lang/python/tests/t-encrypt.py: Likewise.
+ * lang/python/tests/t-export.py: Likewise.
+ * lang/python/tests/t-file-name.py: Likewise.
+ * lang/python/tests/t-idiomatic.py: Likewise.
+ * lang/python/tests/t-import.py: Likewise.
+ * lang/python/tests/t-keylist.py: Likewise.
+ * lang/python/tests/t-sig-notation.py: Likewise.
+ * lang/python/tests/t-sign.py: Likewise.
+ * lang/python/tests/t-signers.py: Likewise.
+ * lang/python/tests/t-trustlist.py: Likewise.
+ * lang/python/tests/t-verify.py: Likewise.
+ * lang/python/tests/t-wait.py: Likewise.
+
+2017-03-14 Justus Winter <justus@g10code.com>
+
+ python: Make error message more helpful.
+ + commit 9d6825be092f1590f28b5bab462eeb944d9b800c
+ * lang/python/tests/run-tests.py: Make the error message shown when we
+ cannot locate the python module in the build tree more helpful.
+
+ python: Make tests more robust.
+ + commit ac4849953860547b06a167ca9612c4de369d02b6
+ * lang/python/tests/support.py (TemporaryDirectory): Always use our
+ own version even if 'tempfile.TemporaryDirectory' is provided, because
+ we need to use 'shutil.rmtree(..., ignore_errors=True)' to avoid it
+ tripping over gpg-agent deleting its own sockets.
+
+ python: Improve build system integration.
+ + commit a4201035fdc050f337a6b9f520c8ddbb569e2eb4
+ * lang/python/Makefile.am: Use 'set -e' when chaining shell commands
+ together in rules.
+
+ build: Improve Python detection.
+ + commit 6a371663886a7ba6073f385a3ab5f5a03de8e008
+ * configure.ac: Do not error out too early if we don't find a matching
+ Python version. We handle this case later.
+
+ build: Tune M4 macros for our needs.
+ + commit 5189c08af9468cdeb6f16a6ecd0fee53e1e3aa0e
+ * m4/ax_python_devel.m4: Do not emit 'HAVE_PYTHON'.
+ * m4/python.m4 (_AM_PYTHON_INTERPRETER_LIST): Add newer Python
+ versions, drop older ones. Also, sort the list with older versions at
+ the front, newer and generic versions towards the end. This makes the
+ algorithm pick the lowest version that meets the version requirement.
+
+ build: Add M4 macros for python.
+ + commit 067da472f919e78c95a0a01b68e79a8b7dff173b
+ * m4/python.m4: New file.
+
+2017-03-13 Andre Heinecke <aheinecke@intevation.de>
+
+ qt: Add test for DN parser.
+ + commit 43aa3eed15dcc4f848915ceabeff35c29c1c57e4
+ * qt/tests/t-various.cpp (testDN): New.
+
+ qt: Use gpgrt_asprintf instead of qstrdup.
+ + commit 9d5048d47446450a34cae4f27eb81c02ea5d4afc
+ * lang/qt/src/dn.cpp (parse_dn_part): Use gpgrt_asprintf instead
+ of qstrdup.
+
+2017-03-09 Werner Koch <wk@gnupg.org>
+
+ core: Fix status error return for gpgsm.
+ + commit d2240a2a1819874929bdab820bcbd3bee7f94407
+ * src/engine-gpgsm.c (gpgsm_assuan_simple_command): Make sure CB_ERR
+ is returned.
+ * src/import.c (parse_import_res): Do not return an error for the last
+ field.
+ (import_status_handler): Actually return the error from
+ parse_import_res.
+
+2017-03-02 Justus Winter <justus@g10code.com>
+
+ python: Print path of the Python module used during tests.
+ + commit 41398779abbcb1ec2d7491e141469a752fc706ff
+ * lang/python/tests/initial.py: Print path of the Python module used
+ during tests. Useful to detect if by any mistake the wrong module is
+ picked up.
+
+2017-03-02 Werner Koch <wk@gnupg.org>
+
+ core: Fix minor code style thing.
+ + commit ef035f079fb067f207e5477d5ed6c5a68fb41f59
+ * src/engine-gpg.c (gpg_add_algo_usage_expire): Use double parenthesis
+ for bit tests.
+
+2017-03-02 Andre Heinecke <aheinecke@intevation.de>
+
+ cpp: Add subkey keygrip to API.
+ + commit 8071a6b2ca33c2a46ed1d50ae7283241daaafcd3
+ * lang/cpp/src/key.cpp (Subkey::keyGrip): New.
+ * lang/cpp/src/key.h: Update accordingly.
+
+2017-03-01 Andre Heinecke <aheinecke@intevation.de>
+
+ cpp: Add interactor to generate keys on smartcard.
+ + commit d63258066d008de113ed1170f1b0e787a5bdaba1
+ * lang/cpp/src/editinteractor.cpp (EditInteractor::needsNoResponse):
+ Handle new states.
+ * lang/cpp/src/gpggencardkeyinteractor.cpp,
+ lang/cpp/src/gpggencardkeyinteractor.h: New.
+ * lang/cpp/src/Makefile.am: Update accordingly.
+
+ qt: Allow creation of default keys without name.
+ + commit fbafb5474d8898ba1b267f4b4dfbefe39f04e72f
+ * lang/qt/src/defaultkeygenerationjob.cpp
+ (DefaultKeyGenerationJob::start): Handle empty name and email.
+
+2017-02-26 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+
+ doc: Correct documentation for recp arg of gpgme_op_encrypt_sign_start.
+ + commit 5b49095b89b07591c69827df3973ffabfb3e97b8
+ * doc/gpgme.texi (gpgme_op_encrypt_sign_start): recp is an array of
+ gpgme_key_t, not a single element.
+
+2017-02-20 Justus Winter <justus@g10code.com>
+
+ python: Fix test.
+ + commit a7c6353edab57b67180aa127ec77d9353c2366fb
+ * lang/python/tests/t-quick-key-manipulation.py: Modify the
+ configuration file in the ephemeral home directory, not the one used
+ by all the tests.
+
+2017-02-17 Justus Winter <justus@g10code.com>
+
+ python: Support manipulating the TOFU policy.
+ + commit 15fbac9e72a4d1bff9a3b9e9822f9175b09fbcd5
+ * NEWS: Update.
+ * doc/gpgme.texi: Fix typos.
+ * lang/python/gpg/constants/__init__.py: Import new files.
+ * lang/python/gpg/constants/tofu/__init__.py: New file.
+ * lang/python/gpg/constants/tofu/policy.py: New file.
+ * lang/python/gpg/core.py (Context.key_tofu_policy): New function.
+ * lang/python/gpgme.i: Nice reprs for gpgme_tofu_info_t.
+ * lang/python/setup.py.in: Install new package.
+ * lang/python/tests/t-quick-key-manipulation.py: Extend test.
+
+ python: Support quick key signing.
+ + commit 48634e651fcd02431c0518d42ada1f3b402feb2c
+ * NEWS: Update.
+ * doc/gpgme.texi (gpgme_op_keysign): Fix the description of the
+ 'expire' argument.
+ * lang/python/gpg/constants/__init__.py: Import new file.
+ * lang/python/gpg/constants/keysign.py: New file.
+ * lang/python/gpg/core.py (Context.key_sign): New function.
+ * lang/python/tests/Makefile.am (py_tests): Add new test.
+ * lang/python/tests/t-quick-key-signing.py: New test.
+
+ python: Fix teardown of ephemeral contexts.
+ + commit de8494b16bc50c60a8438f2cae1f8c88e8949f7a
+ * lang/python/tests/support.py (EphemeralContext): New function.
+ * lang/python/tests/t-quick-key-creation.py: Use the new function to
+ manage ephemeral contexts.
+ * lang/python/tests/t-quick-key-manipulation.py: Likewise.
+ * lang/python/tests/t-quick-subkey-creation.py: Likewise.
+
+ python: Fix using strings as commands in the assuan protocol.
+ + commit 9350168a1eed3f055040d7cc8a9bf4cdf745b23a
+ * lang/python/gpg/core.py (Context.assuan_transact): Fix testing
+ whether the command is a string on Python2.
+ * lang/python/tests/t-protocol-assuan.py: Improve the test to detect
+ this problem.
+
+2017-02-16 Justus Winter <justus@g10code.com>
+
+ python: Support adding and revoking UIDs.
+ + commit 7641b7b5f2c9d5b38c60cd9326bcb4810c37dae5
+ * NEWS: Update.
+ * lang/python/gpg/core.py (Context.key_add_uid): New function.
+ (Context.key_revoke_uid): Likewise.
+ * lang/python/tests/Makefile.am (XTESTS): Add new test.
+ * lang/python/tests/t-quick-key-manipulation.py: New file.
+
+ python: Support quick subkey creation.
+ + commit 13bace25e3d8422f93fd24919994be36042fd220
+ * NEWS: Update.
+ * lang/python/gpg/core.py (Context.create_subkey): New function.
+ * lang/python/tests/Makefile.am (XTESTS): Add new test.
+ * lang/python/tests/t-quick-subkey-creation.py: New file.
+
+ python: Support quick key creation.
+ + commit 476b97822b169c30cc246c1de2ff94cf89084706
+ * NEWS: Update.
+ * lang/python/gpg/constants/__init__.py: Import new file.
+ * lang/python/gpg/constants/create.py: New file.
+ * lang/python/gpg/core.py (Context.create_key): New function.
+ * lang/python/tests/Makefile.am (XTESTS): Add new test.
+ * lang/python/tests/support.py (TemporaryDirectory): New class.
+ * lang/python/tests/t-quick-key-creation.py: New file.
+
+ python: Fix passphrase callback wrapping.
+ + commit 3bdce4aa3ddd4a3f55b24678faf978d61daa8909
+ * lang/python/helpers.c (pyPassphraseCb): Cope with 'passphrase_info'
+ being NULL.
+
+ python: Fix error handling.
+ + commit 048c5f74b61d5e4fa7617ce7c9111c6754bd4409
+ * lang/python/gpgme.i (typemap gpgme_key_t[]): Set an error if a
+ non-key element is discovered.
+
+2017-02-15 Justus Winter <justus@g10code.com>
+
+ core: Fix expiration time handling when creating keys.
+ + commit de708e5934cda380dbc3ae51f587c09041de7562
+ * NEWS: Update.
+ * doc/gpgme.texi (gpgme_op_createkey): Clarify the meaning of the
+ 'expire' parameter.
+ (GPGME_CREATE_NOEXPIRE): Document new flag.
+ (gpgme_op_createsubkey): Clarify the meaning of the 'expire'
+ parameter.
+ * src/engine-gpg.c (gpg_add_algo_usage_expire): Fix handling of the
+ expiration time.
+ * src/gpgme.h.in (GPGME_CREATE_NOEXPIRE): New macro.
+
+ python: Fix build system integration.
+ + commit 27544d0a74267ab6057dc816ea3311bc9149a200
+ * lang/python/Makefile.am (copystamp): Also copy the setup script, and
+ link the header files.
+ (all-local): Use local setup script.
+ (sdist): Fix Python source distribution creation.
+ (CLEANFILES): Remove now obsolete files.
+ (install-exec-local): Use local setup script.
+ * lang/python/setup.py.in: Adjust relative paths to in-tree files.
+
+ python: Update lists of functions returning gpgme_error_t.
+ + commit 25f0435a0022a70af77660d72d33f17bec2d4e51
+ * lang/python/gpg/core.py (Context._errorcheck): Add instructions how
+ to update the list. Update list.
+ (Data._errorcheck): Likewise.
+ (Context.set_engine_info): Simplify.
+
+ core: Fix error types.
+ + commit 6df6e01ed5a581765d245bf7303cda4497d0eb22
+ * NEWS: Update.
+ * src/data.c (gpgme_data_set_flag): Return a 'gpgme_error_t'.
+ * src/error.c (gpgme_strerror_r): Fix type of first argument.
+ * src/gpgme.h.in (gpgme_strerror_r): Adapt.
+ (gpgme_data_set_flag): Likewise.
+
+2017-02-14 Justus Winter <justus@g10code.com>
+
+ python: Wrap utility functions.
+ + commit 92adc9bbf640eb5d9177d3ba0189e0f6cee4e995
+ * NEWS: Update.
+ * lang/python/gpg/core.py (pubkey_algo_string): New function.
+ (pubkey_algo_name): Add docstring.
+ (hash_algo_name): Likewise.
+ (get_protocol_name): Likewise.
+ (addrspec_from_uid): New function.
+ * lang/python/gpgme.i (gpgme_pubkey_algo_string): Result must be
+ freed.
+ (gpgme_addrspec_from_uid): Likewise.
+
+ python: Use the correct function to free buffers.
+ + commit 9fc9533c2835ec53c4fd4f822b09e9fec14626d0
+ * lang/python/gpgme.i (char *): Free using 'gpgme_free'.
+
+ python: Add keylist mode parameter.
+ + commit fdc4e33dc3f6c84fe9d7bf9795c603ae3cf5f28d
+ * NEWS: Update.
+ * lang/python/gpg/core.py (Context.keylist): Add 'mode' parameter.
+
+ python: Nicer repr for user ids.
+ + commit e17ab84129045512cf60c221ee43aa877507662f
+ * lang/python/gpgme.i (_gpgme_user_id): Provide a nicer repr() for
+ user ids.
+
+ python: Add convenience functions for the home directory.
+ + commit 99b7f4f34dd595579181a696ae976a678fe00d49
+ * NEWS: Update.
+ * lang/python/gpg/core.py (Context.__init__): Add 'home_dir' argument.
+ (__repr__): Include 'home_dir'.
+ (Context.home_dir): New property.
+
+ qt: Make sure to remove the tofu.db on clean.
+ + commit 30a603580e0f196c721fa4bd44d24077d9bc06c3
+ * lang/qt/tests/Makefile.am (CLEANFILES): Add 'tofu.db'.
+
+2017-02-14 Tobias Mueller <muelli@cryptobitch.de>
+
+ python: Extend SWIG gpgme_{sub,}key with a __repr__ method.
+ + commit 01d5c17587578c729bbbb60f8a65635975e35592
+ * lang/python/gpgme.i: Added a genericrepr macro and use it for
+ gpgme_key, gpgme_subkey, and gpgme_key_sig.
+
+ python: Remove the -builtin flag for SWIG.
+ + commit aa49be1ab80c200ab6b62d33bf5d0f5aa334fc56
+ * lang/python/setup.py.in: Call SWIG without the builtin flag.
+
+ python: Call SWIG_NewPointerObj rather than SWIG_Python_NewPointerObj.
+ + commit d35651917097ae2eee7d52396d53d010bc34df19
+ * lang/python/gpgme.i (pygpgme_wrap_gpgme_data_t): Provide a "self"
+ variable for SWIG_NewPointerObj and call SWIG_NewPointerObj rather than
+ SWIG_Python_NewPointerObj.
+
+ python: Conditionally provide py3 argument to SWIG.
+ + commit d184dbbba8987d9f387feb25791ed891e108dabc
+ * lang/python/setup.py.in: Only call with -py3 when we run under python3
+ or higher.
+
+2017-02-13 Justus Winter <justus@g10code.com>
+
+ python: Use one copy of the source tree per Python version.
+ + commit fe65a26ab584bd70fad45c7c4d44330e30a748a4
+ * lang/python/Makefile.am (copystamp): Create one copy per Python
+ version.
+ (all-local): Adapt.
+ (clean-local): Likewise.
+ (install-exec-local): Likewise.
+ * lang/python/tests/run-tests.py: Likewise.
+
+ build: Use macOS' compatibility macros to enable all features.
+ + commit 60273e8b2c11d42215a5707bc55e3e0d8f350e07
+ * configure.ac: On macOS, use the compatibility macros to expose every
+ feature of the libc. This is the equivalent of _GNU_SOURCE on GNU
+ libc.
+
+ Revert "Disable fd-passing for Apple."
+ + commit f8db658f8b4c3c7941d0029273fb23fbe1ba74ad
+ The actual bug has been located, so this can be reverted.
+
+ This reverts commit ef5b4ae37d13142e89a051908dc080cda3d24baa.
+
+2017-02-13 Igor Gnatenko <ignatenkobrain@fedoraproject.org>
+
+ qt: Add missing #include <functional>
+ + commit 60064c665ec98a2a994fc6c8ad701e60b963ce7e
+ * lang/qt/src/qgpgmenewcryptoconfig.cpp,
+ lang/qt/src/threadedjobmixin.h: Include functional.
+
+2017-02-07 Andre Heinecke <aheinecke@intevation.de>
+
+ qt: Don't rely on implicit include in t-verify.
+ + commit 903bf16a416b1bf608b1e647937c9b06864b0141
+ * lang/qt/tests/t-various.cpp: Include QTemporaryDir
+
+2017-02-06 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
+
+ doc: Document that gpgme_op_genkey() parms parameter is not XML.
+ + commit ad22bee5387b1e9a40e8c822a081db3228bb9def
+ * doc/gpgme.texi (GnupgKeyParms): document that input format is not
+ true XML.
+
+2017-02-03 Werner Koch <wk@gnupg.org>
+
+ core: Optimize fork/exec for *BSD and Solaris.
+ + commit 51bd69f216a9e2930eeba4b5f6c20e952a381720
+ * configure.ac (closefrom): Add to ac_check_funcs.
+ * src/posix-io.c (_gpgme_io_spawn): Use closefrom.
+
+ core: Fix possible deadlock due to get_max_fds.
+ + commit 93a59070c699d569d1eac7ba22355fe3f5d10882
+ * src/posix-io.c (get_max_fds): Do not use the Linux optimization.
+
+ core: Minor cleanup of commit 195c735.
+ + commit afc308598d1ddaf20d54b4eab30b959066a4e5e6
+ * src/verify.c (parse_tofu_user): For cleanness use gpg_error ...
+ (_gpgme_verify_status_handler): ... and gpg_err_code.
+
+2017-02-02 Andre Heinecke <aheinecke@intevation.de>
+
+ qt: Add test for tofu conflict.
+ + commit 43160a39f27f6c3507447620666c85af00b3499c
+ * lang/qt/tests/t-tofuinfo.cpp (TofuInfoTest::testTofuConflict): New.
+
+ core: Handle multiple TOFU_USER lines in verify.
+ + commit 195c73589232160f45d00f4901c9bb2b0162f0e5
+ * src/verify.c (op_data_t): Add conflict_user_seen.
+ (parse_tofu_user): Return ERR_DUP_VALUE for mutltiple TOFU_USERS.
+ (_gpgme_verify_status_handler): Handle ERR_DUP_VALUE from
+ parse_tofu_user to ignore the next TOFU_STATS.
+
+2017-02-02 Werner Koch <wk@gnupg.org>
+
+ core: Replace all calls to *sprintf by gpgrt_*sprintf.
+ + commit 15050ce5fce4ed815503db7c029abb38d08970d6
+ * configure.ac (vasprintf): Remove check.
+ * src/vasprintf.c: Remove file.
+ * src/util.h (vasprintf, asprintf): Remove prototypes. Replace all
+ calls to vasprintf and asprintf by gpgrt_vasprintf or gpgrt_asprintf.
+ Also take care to use gpgrt_free on the returned value.
+ * src/w32-util.c (_gpgme_get_gpgconf_path): Replace a gpgrt_asprintf
+ by _gpgme_strconcat.
+ (snprintf): New macro to use gpgrt_snprintf instead of the system's
+ standard snprintf.
+
+ core: Remove unused check for funopen/fopencookie.
+ + commit 563420a88f8a4f561a2faea4d2b4a1c58b375fd8
+ * configure.ac (funopen): Remove check.
+ * src/funopen.c: Remove file.
+
+ core: Un-deprecate gpgme_data_rewind.
+ + commit d19bea52afe6efb66a46af6aa4d09928c5d05ee5
+ * src/gpgme.h.in (gpgme_data_rewind): Un-deprecate.
+ * src/data-compat.c (gpgme_data_rewind): Move to ...
+ * src/data.c (gpgme_data_rewind): here.
+
+ core: Move all deprecated stuff to the end of gpgme.h.
+ + commit 9b7d81998b734fabeb4fbc697f08fc7795eaa90a
+
+
+2017-02-01 Andre Heinecke <aheinecke@intevation.de>
+
+ core: Cleanup gpgme_key_unref frees.
+ + commit 8ede86795a1d419c01b4910ec2fd1fb18b629452
+ * src/key.c (gpgme_key_unref): Nowadays we assume free(NULL) is ok.
+
+ core: Fix leakage of address for mail only uids.
+ + commit b5075030bec9b21bf4e515bc1686df3fa43eced2
+ * src/key.c (gpgme_key_unref): Always free address if set.
+ (_gpgme_key_append_name): Remove memory optimization for address.
+
+ core: Improve mailbox only uid handling.
+ + commit a28d31fdb623f2ee30e8094d09f1a0d1ae446a9b
+ * src/key.c (_gpgme_key_append_name): Set email and remove name
+ for uid only keys.
+
+2017-01-31 Justus Winter <justus@g10code.com>
+
+ qt: Increase timeout when waiting for signals.
+ + commit ba594d85e35e63301755977234d3af88a167a215
+ * lang/qt/tests/t-support.h (QSIGNALSPY_TIMEOUT): New macro.
+ * lang/qt/tests/t-encrypt.cpp: Use the new macro as timeout when
+ waiting for signals.
+ * lang/qt/tests/t-keylist.cpp: Likewise.
+ * lang/qt/tests/t-keylocate.cpp: Likewise.
+ * lang/qt/tests/t-ownertrust.cpp: Likewise.
+ * lang/qt/tests/t-wkspublish.cpp: Likewise.
+
+2017-01-31 Werner Koch <wk@gnupg.org>
+
+ core: Add new context flag "redraw".
+ + commit 752d3597ef02a95efd693373132bf1e246f0edb0
+ * src/context.h (struct gpgme_context): New field 'redraw_suggested'.
+ * src/op-support.c (_gpgme_op_reset): Clear REDRAW_SUGGESTED.
+ * src/progress.c (_gpgme_progress_status_handler): Set REDRAW_SUGGESTED.
+ * src/gpgme.c (gpgme_set_ctx_flag, gpgme_get_ctx_flag): Add "redraw".
+ * tests/run-sign.c (main): Use it.
+
+2017-01-30 Andre Heinecke <aheinecke@intevation.de>
+
+ tests: Reduce iterations / threads.
+ + commit 7bd6ab4a91d43d7cbf5d347c0c12e0e4f9f7e3bf
+ * tests/gpg/t-gpgconf.c (main): Reduce iterations to 10.
+ * tests/gpg/t-thread-keylist-verify.c,
+ tests/gpg/t-thread-keylist.c (THREAD_COUNT): Reduce to 10.
+
+2017-01-26 Andre Heinecke <aheinecke@intevation.de>
+
+ python: Ensure quick-random is used if gpg is gpg2.
+ + commit f3ca2c9ce9fd4a03e293065f10b92589a7e642d6
+ * lang/python/tests/Makefile.am (gpg.conf): Configure
+ agent-program accordingly.
+
+2017-01-25 Tobias Mueller <muelli@cryptobitch.de>
+
+ python: default op_keylist_start parameters.
+ + commit 9291ebaa4151a1f6c8c0601095ec45809b963383
+ * lang/python/gpgme.i: Added gpgme_op_keylist_start with defaults
+ * lang/python/tests/t-keylist.py: Added tests for default parameters
+
+2017-01-25 Andre Heinecke <aheinecke@intevation.de>
+
+ tests: Use --debug-quick-random for tests.
+ + commit a98951a30a6ae603ffac4ec8c5168aa6d1019933
+ * tests/start-stop-agent: Don't autostart agent on --stop and
+ running check. Use --debug-quick-random when starting.
+
+2017-01-23 Justus Winter <justus@g10code.com>
+
+ w32: Fix closing file descriptors.
+ + commit 6f02133bb07726afa6950e5b4685e75621276e60
+ * src/w32-io.c (writer): Only stop once the buffer is drained.
+ (destroy_writer): Wait for the writers buffer to be drained. This
+ aligns '_gpgme_io_close's behavior with close(2) and fclose(3).
+
+2017-01-17 Andre Heinecke <aheinecke@intevation.de>
+
+ tests: Add safeguards against nullptr deref.
+ + commit ca69df8c8d3f044340aee2a118cc20d33cd600a1
+ * t-gpgconf.c (main): Test some values before dereferencing them.
+
+2017-01-16 Andre Heinecke <aheinecke@intevation.de>
+
+ qt: Use QVERIFY instead of Q_ASSERT in conf test.
+ + commit abfd241d1a1ae8e30e18b7c5e0658b8c54d89544
+ * lang/qt/tests/t-config.cpp: Use QVERIFY instead of Q_ASSERT.
+
+ qt: Add test for CryptoConfig.
+ + commit 8aba08d1d0871f439fb7193adc4a2f43a81ee216
+ * lang/qt/tests/t-config.cpp: New.
+ * lang/qt/tests/Makefile.am: Update accordingly.
+
+2017-01-16 Justus Winter <justus@g10code.com>
+
+ tests: Fix distcheck.
+ + commit 92543da94cbf8e807b1b33070d273f995cdd5c62
+ * tests/gpg/Makefile.am (CLEANFILES): Remove gpgconf backups.
+
+ Fix changing options with gpgconf.
+ + commit 0e242278dfaa64ce31a45b72f5fa0806a3dba898
+ * src/engine-gpgconf.c (gpgconf_write): Connect a pipe to the child's
+ stderr, and wait for it to be closed as an indication that gpgconf has
+ exited. Also improve error handling.
+
+2017-01-12 Justus Winter <justus@g10code.com>
+
+ tests: Improve the gpgconf test.
+ + commit 186dcd3494eda7383de57a530fd15776410531a5
+ * tests/gpg/t-gpgconf.c: Include support functions.
+ (fail_if_err): Remove macro.
+ (init_gpgme): Remove function.
+ (lookup): New function.
+ (main): Update some values and verify that the changes are applied.
+ * tests/gpg/t-support.h (test): New assert-like macro.
+
+2017-01-12 Andre Heinecke <aheinecke@intevation.de>
+
+ qt: Add support for stringValueList in CryptoConf.
+ + commit 9640dc58e498966b482dcded6990cf4b47c556ac
+ * lang/qt/src/Makefile.am (qgpgme_sources): Add cryptoconfig.cpp
+ * lang/qt/src/cryptoconfig.cpp: New.
+ * lang/qt/src/cryptoconfig.h (CryptoConfigEntry::stringValueList):
+ New.
+ * lang/qt/src/qgpgmenewcryptoconfig.cpp
+ (QGpgMENewCryptoConfigEntry::stringValueList): New.
+ * lang/qt/src/qgpgmenewcryptoconfig.h: Update accordingly.
+
+ qt: Don't use qstrdup in test passphrase cb.
+ + commit a09ed3f26a1fab54079c37c49df5c440cc792f78
+ * lang/qt/tests/t-support.h (TestPassphraseProvider::getPassphrase):
+ Use gpgrt_asprintf instead of strdup.
+
+2017-01-11 Andre Heinecke <aheinecke@intevation.de>
+
+ qt: Clean up test dirs on failure.
+ + commit 56926c9b5012e8135541a933af1d69c5a81f02b3
+ * t-encrypt.cpp,
+ t-keylist.cpp,
+ t-keylocate.cpp,
+ t-ownertrust.cpp,
+ t-tofuinfo.cpp,
+ t-various.cpp,
+ t-verify.cpp,
+ t-wkspublish.cpp: Use QVERIFY instead of Q_ASSERT
+
+ qt: Add test for uid functions.
+ + commit 9e643ab67168dfbd189ccc0bfed8fb59253ee79c
+ * lang/qt/tests/t-various.cpp: New.
+ * lang/qt/tests/Makefile.am: Update accordingly.
+
+ cpp: Add revuid and adduid support.
+ + commit e416f9961837039f259558edf41fccbc181ad128
+ * lang/cpp/src/context.cpp
+ (Context::revUid, Context::startRevUid),
+ (Context::addUid, Context::startAddUid): New.
+ * lang/cpp/src/context.h: Declare new functions.
+ * lang/cpp/src/key.cpp (Key::UserID::revoke)
+ (Key::addUid): Idomatic helpers.
+ lang/cpp/src/key.h: Declare new functions.
+ * NEWS: Update accordingly.
+
+ Fix Qgpgme build for macos.
+ + commit efe58fe011f195d98adb4f03b1e1068a26ba287b
+ * lang/qt/src/dn.cpp: Include string.h
+ (parse_dn_part): Use qstrdup.
+ * lang/qt/tests/t-support.h (getPassphrase): Use qstrdup.
+
+ Fix cmake configuration files for MacOS.
+ + commit 2e661b9e1a9b50656a5c9646d7444a98477010c1
+ * configure.ac: Set HAVE_MACOS_SYSTEM conditional.
+ * lang/qt/src/Makefile.am,
+ lang/cpp/src/Makefile.am,
+ lang/qt/src/QGpgmeConfig.cmake.in.in,
+ lang/cpp/src/GpgmeConfig.cmake.in.in: Use libsuffix again to
+ distinguish between macos .dylib
+
+2017-01-03 Justus Winter <justus@g10code.com>
+
+ python: Improve compatibility with Scheme tests.
+ + commit b14419f68b3aaa90025e0e97151de7c3da7806fb
+ * lang/python/tests/run-tests.py: Add stub --parallel option.
+
+ python: Add a switch '--quiet' to the test runner.
+ + commit d0e91d28f63b74e53673902e675be8a54b6b90d3
+ * lang/python/tests/run-tests.py: Add and honor a switch '--quiet'.
+ This way we can use this script to run Python tests one by one without
+ the noise, and the script will setup the necessary environment for us.
+
+2017-01-02 Andre Heinecke <aheinecke@intevation.de>
+
+ qt: Update config sync doc / comment.
+ + commit ececfd5de81f1851943be7b284b672d5b02aceb4
+ * lang/qt/src/cryptoconfig.h (CryptoConfig::sync): Document
+ that runtime option is always set.
+ * lang/qt/Src/qgpgmenewcryptoconfig.cpp
+ (QGpgMENewCryptoConfigComponent::sync): Remove outdated comment
+ and warn on error.
+
+ core: Always use runtime for gpgconf changes.
+ + commit 7103315829847163f1c6f52cad25d1ddb33358f0
+ * src/engine-gpgconf.c (gpgconf_write): Add --runtime.
+ * src/gpgme.h.in (gpgme_conf_opt_change): Document this
+ behavior.
+
+2017-01-01 Ben Kibbey <bjk@luxsci.net>
+
+ Fix gpg_addkey() to work with GPGME_CREATE_NOPASSWD as well.
+ + commit a4b9f1a2b404fd8627d5ac567617510abd55d980
+ * src/engine-gpg.c (gpg_addkey): Pass --batch to gpg when
+ GPGME_CREATE_NOPASSWD is set to fix pinentry without loopback mode.
+
+2016-12-27 Ben Kibbey <bjk@luxsci.net>
+
+ Fix GPGME_CREATE_NOPASSWD without pinentry loopback.
+ + commit d83b8f0dc84d6cf7fe2e091bd1b103ceedfa3d6c
+ * src/engine-gpg.c(gpg_createkey): Pass --batch to gpg when
+ GPGME_CREATE_NOPASSWD is set.
+
+2016-12-19 Raphael Kubo da Costa <rakuco@FreeBSD.org>
+
+ Qt: Make sure extended grep is used with '|'.
+ + commit 211844f049d714cd4d5aab96347705cb0c209c5d
+ * m4/qt.m4: Use grep -E when using the alternation character.
+
+2016-12-16 Andre Heinecke <aheinecke@intevation.de>
+
+ cpp: Ensure that hasSecret is correct after update.
+ + commit da5343a9d2c8c0ca6431162aac4bd5c73b4ae6dd
+ * lang/cpp/src/key.cpp (Key::update): Check for
+ a secret key first before listing public keys.
+
+2016-12-15 Andre Heinecke <aheinecke@intevation.de>
+
+ cpp: Fix addrSpec for keys without email.
+ + commit 85e05537e15346896a271d3f62bead9dd7e3f180
+ * lang/cpp/src/key.cpp (UserID::addrSpec): Use uid->address instead
+ of normalizing again.
+ (&operator<<(std::ostream &, const UserID &): Print it.
+
+ cpp: Fix update of partial key in verifyresult.
+ + commit 5673f3e54af535155893290a685b3afb44c7f58d
+ * lang/cpp/src/verificationresult.cpp
+ (Signature::key(bool,bool)): Don't update the returned copy
+ but the actual key of the signature.
+
+2016-12-07 Andre Heinecke <aheinecke@intevation.de>
+
+ Clarify what "checking on bit" means.
+ + commit 7880335273382f05cbbe38aa965a566c4127ba6a
+ * doc/gpgme.texi (gpgme_sigsum_t summary): Clarify what "you
+ can check one bit means"
+
+2016-12-05 Tobias Mueller <muelli@cryptobitch.de>
+
+ python: Try to be more helpful when given a string to encrypt().
+ + commit 05896c210f7fa9ce7b97784a75e49dc4489e9252
+ * lang/python/helpers.c (_gpg_obj2gpgme_data_t): Extended error
+ message.
+ * lang/python/tests/t-encrypt.py: Test for "encode" in error message.
+
+ python: Define a macro for wrapping fragile result objects.
+ + commit fb7f4cb973abc9f5eb05eb240607be35c1be986c
+ * lang/python/gpgme.i (wrapresult): New Macro.
+
+2016-12-01 Tobias Mueller <muelli@cryptobitch.de>
+
+ python: Check "buffer" when writing to sys.stdout for python2 compat.
+ + commit ae21d2705fc46725e1f9af1651b68d16155d1501
+ * lang/python/tests/support.py (print_data): Add check for buffer.
+
+ python: Make Context have a repr method.
+ + commit 154389f2a5e4c13081cf0624222aad29ee480b56
+ * lang/python/gpg/core.py (Context.__repr__): New function.
+
+ python: Make Results have a nicer __repr__.
+ + commit db2f6c1ca3d2ef228f4ca6653d594537622c8588
+ * lang/python/gpg/results.py (Result.__str__): Renamed to '__repr__'
+ ...
+ * lang/python/gpg/results.py (Result.__repr__): ... and added fields.
+
+2016-11-25 Justus Winter <justus@g10code.com>
+
+ python: Fix removing the TOFU database.
+ + commit fd4d476214ae06e33f4a6dac534d3deca5cc6cd3
+ * lang/python/Makefile.am (CLEANFILES): Move 'tofu.db'...
+ * lang/python/tests/Makefile.am (CLEANFILES): ... here.
+
+ tests: Remove tofu.db.
+ + commit 9b22f82afc5518961e4bea1fc516b79800e379a2
+ * lang/python/Makefile.am (CLEANFILES): Add 'tofu.db'.
+ * tests/gpg/Makefile.am (CLEANFILES): Likewise.
+
+2016-11-17 Heiko Becker <heirecka@exherbo.org>
+
+ Remove a forgotten instance of @libsuffix@
+ + commit 572c1aac107125ce62230251713349348373db5a
+ * lang/cpp/src/GpgmeppConfig.cmake.in.in: Remove a forgotten
+ instance of @libsuffix@.
+
2016-11-16 Werner Koch <wk@gnupg.org>
Release 1.8.0.
+ + commit f06220b691e9711afdabaa19886244ae7724eed5
* configure.ac: Set version to 1.8.0. Set LT version C28/A17/RO.
Set CPP LT version to C9/A3/R0. Set Qt LT version to C8/A1/R0.
core: Do not leak the override session key to ps(1).
+ + commit 9fc92a15bd0a30437a39d0eb28b6f40edc22e6e8
* src/engine-gpg.c (struct engine_gpg): New field
override_session_key.
(gpg_release): Free that field.
@@ -15,6 +955,7 @@
2016-11-16 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
doc,tests: Require use of ctx_flag before use of session_key.
+ + commit 573064742145aa5f9bf04baa88af918c0c4d5e12
* doc/gpgme.texi: Document requirements of verifying that it is OK to
use session_key.
* tests/run-decrypt.c: Ensure that we fail if we're unable to access
@@ -39,6 +980,7 @@
2016-11-15 Andre Heinecke <aheinecke@intevation.de>
qt, cpp: Add cmake config files for w32.
+ + commit b2c07bd47bd608afa5cc819b60a7b5bb8c9dd96a
* lang/cpp/src/GpgmeppConfig-w32.cmake.in.in
lang/qt/src/QGpgmeConfig-w32.cmake.in.in: New.
* lang/cpp/src/GpgmeppConfig.cmake.in.in,
@@ -48,12 +990,14 @@
* configure.ac: Configure them.
qt: Use new style connect in th..mixin.
+ + commit 45abe6d142e314ba7099ad80b6365af171b06fec
* lang/qt/src/threadedjobmixin.h
(ThreadedJobMixin::lateInitialization): Use new style connect.
2016-11-15 Werner Koch <wk@gnupg.org>
core: Implement context flag "override-session-key".
+ + commit 7659d42468b604db2936b021425683f407eba4a7
* src/gpgme.c (gpgme_set_ctx_flag): Add flags "export-session-key" and
"override-session-key".
(gpgme_get_ctx_flag): Ditto.
@@ -82,6 +1026,7 @@
(main): Add options --export-session-key and --override-session-key.
core: Add public function gpgme_get_ctx_flag.
+ + commit 3234b1bf1d6939772677d64f6c1e1820ec98e3cd
* src/gpgme.h.in (gpgme_get_ctx_flag): New.
* src/gpgme.c (gpgme_set_ctx_flag): Move down the file and add a trace
statement.
@@ -91,6 +1036,7 @@
2016-11-15 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
core: Enable extraction of session keys.
+ + commit cad1210fb8a7402cb29e607f8f9680005314120d
* src/gpgme.c (gpgme_set_export_session_keys): New function.
(gpgme_get_export_session_keys): New function.
* src/gpgme.h.in (struct _gpgme_op_decrypt_result): Add session_key
@@ -127,6 +1073,7 @@
2016-11-14 Andre Heinecke <aheinecke@intevation.de>
qt: Add API to get the context for a Job.
+ + commit 9451faa2ee333904cff59f92ab62918e13ab4b87
* lang/qt/src/job.cpp,
lang/qt/src/job.h (Job::context): New.
* lang/qt/src/threadedjobmixin.cpp
@@ -135,14 +1082,17 @@
* NEWS: Update for cpp and qt.
cpp: Add get / set Sender API.
+ + commit d09a84eaf1e4f8c6c2e462995fa15c1a5690a6ce
* cpp/src/context.cpp, cpp/src/context.h (Context::setSender),
(Context::getSender): Add simple wrappers.
qt, cpp: Enable dll build for windows.
+ + commit f3790ddf56558fb0a08af95fdbae979cd6589aad
* lang/cpp/src/Makefile.am,
lang/qt/src/Makefile.am: Add -no-undefined to LDFLAGS.
w32: Fix build of w32-glib.
+ + commit b91c383386fe9eadd90afdb9bb1f8ec6c528173b
* src/Makefile.am (main_sources): Remove system_components_not_extra.
(libgpgme_la_SOURCES): Add system_components_not_extra.
(libgpgme_glib_la_SOURCES): Remove duplicated ath files.
@@ -150,14 +1100,17 @@
2016-11-11 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
doc: Correct deftypefun for gpgme_op_decrypt_verify_start.
+ + commit 16a30205064914eef578d84d07141b5d51d82838
* doc/gpgme.texi: Documentationabout gpgme_op_decrypt_verify_start was
stored under the name gpgme_op_decrypt_verify instead.
doc: Correct text about gpgme_cancel_async.
+ + commit d50bdb269e86db36a443958e3bfc6816a44d468e
* doc/gpgme.texi: Documentation about gpgme_cancel_async should refer
to the correct name.
core: Non-zero values should set _armor, _textmode, and _online.
+ + commit da035768bd9a880becee5d0d553dfe12299f96eb
* src/gpgme.c (gpgme_set_armor, gpgme_set_textmode,
gpgme_set_offline): Ensure that non-zero values actually set the
appropriate internal bit.
@@ -165,6 +1118,7 @@
2016-11-11 Alon Bar-Lev <alon.barlev@gmail.com>
tests,python: Atomic directory creation.
+ + commit 41d8c7e51a8989be633b9ada124c58a01fae7d54
* lang/python/tests/Makefile.am: Use MIDIR_P.
* tests/gpg/Makefile.am: Ditto.
* tests/gpgsm/Makefile.am: Ditto.
@@ -172,17 +1126,20 @@
2016-11-10 Werner Koch <wk@gnupg.org>
core: Use better error code when using select with a too high fd.
+ + commit 6e57379c8e37c0863f7d12819a5a7d0781bd76d2
* src/posix-io.c (_gpgme_io_select): Return EMFILE instead of EBADF.
2016-11-10 Andre Heinecke <aheinecke@intevation.de>
tests: Reduce thread count in new thread tests.
+ + commit ddd0a3cf90ac4b0a27ea610ebd7b9b8016ff43c4
* gpg/t-thread-keylist-verify.c,
gpg/t-thread-keylist.c: Reduce threads to 100
2016-11-10 Werner Koch <wk@gnupg.org>
core: Detect unreadable keyrings.
+ + commit 2a39bd6c30d21c43c86645a7908ce6c57dad5e20
* src/keylist.c (op_data_t): Add field keydb_search_err.
(keylist_status_handler): Parse STATUS_ERROR into that var.
(gpgme_op_keylist_next): Use that err instead of GPG_ERR_EOF.
@@ -190,12 +1147,14 @@
2016-11-10 Andre Heinecke <aheinecke@intevation.de>
tests: Fix additional memleaks in thread tests.
+ + commit d0030efb45ec8436dd84a9623d2f66b80c6b9e10
* tests/gpg/t-thread-keylist-verify.c (start_verify): Release
data.
(start_keylist): Unref keys.
* tests/gpg/t-thread-keylist.c (start_keylist): Unref keys.
tests: Improve new thread tests.
+ + commit 4d5174e4a83dcd524f8085f6646145f81b50a02a
* tests/gpg/t-thread-keylist-verify.c (start_keylist): Mark
arg as unused. Release context.
(start_verify): Ditto.
@@ -205,6 +1164,7 @@
(main): Mark args as unused.
core: Use gpgrt locking for thread safeness.
+ + commit 09b64554328445e99a8cc78fc34ea49c2ea2e7f9
* configure.ac: Require libgpg-error 1.17. No longer
check for pthread.
* doc/gpgme.texi: Document removed neccessity for thread
@@ -230,11 +1190,13 @@
2016-11-09 Justus Winter <justus@g10code.com>
python: Require at least GPGME 1.7 for out-of-tree builds.
+ + commit f1f341062e24724e26928d893dd5769d3ccf5fa2
* lang/python/setup.py.in: Bump required version to 1.7.
2016-11-09 Werner Koch <wk@gnupg.org>
w32: Better protect the IO-system's fd_table.
+ + commit 10f2e1c30be651e74a03f4563a9f212d7416adb3
* src/w32-io.c (fd_table_lock): New.
(new_fd): Lock allocation of a new slot.
(release_fd): Lock deallocation of a slot.
@@ -242,25 +1204,30 @@
2016-11-04 Andre Heinecke <aheinecke@intevation.de>
cpp: Add API for swdb queries.
+ + commit 3509cf2f9846360848b6c08d36cbca18373c935e
* lang/cpp/src/swdbresult.cpp,
lang/cpp/src/swdbresult.h (SwdbResult): New.
* lang/cpp/src/Makefile.am: Update accordingly.
cpp: Add more EngineInfo::Version ctors.
+ + commit 512de91f9a8da8f491e09653eb4b5bdd0a027198
* lang/cpp/src/engineinfo.h
(EngineInfo::Version::Version(const char*)),
(EngineInfo::Version::Version()): New.
cpp: Don't include gpgme.h in tofuinfo header.
+ + commit 4d3f33d0e9d960df2c34fb4d215987ab4d36111c
* lang/cpp/src/tofuinfo.h: Don't include gpgme.h
cpp: Extend gpgmefw for tofuinfo and swdb query.
+ + commit 23979b9be5a6028e3e9cafc3aff632bc720b81f2
* lang/cpp/src/gpgmefw.h (gpgme_tofu_info_t)
(gpgme_query_swdb_result_t): New forwards.
2016-11-04 Werner Koch <wk@gnupg.org>
w32: Fix locating gpgconf on 64 bit systems.
+ + commit df08a0ca3f029b06b7e3a6bd63330df5cb96585a
* src/w32-util.c (find_program_at_standard_place): Use access to check
whether the binary is at CSIDL_PROGRAM_FILES before testing
CSIDL_PROGRAM_FILESX86.
@@ -268,6 +1235,7 @@
2016-11-03 Werner Koch <wk@gnupg.org>
core: Add gpgme_op_query_swdb and helper.
+ + commit aad94cb7c313d4501bed748f48830cbb93c67e20
* src/gpgme.h.in (gpgme_query_swdb_result_t): New.
(gpgme_op_query_swdb): New.
(gpgme_op_query_swdb_result): New.
@@ -291,12 +1259,14 @@
2016-11-03 Andre Heinecke <aheinecke@intevation.de>
qt: Change license of export / version header.
+ + commit 34a4e8017be452e8ead6b9c2da84be1ec7929cae
* lang/qt/src/qgpgme_export.h,
lang/qt/src/qgpgme_version.h: Change license to GPLv2+
2016-11-03 Werner Koch <wk@gnupg.org>
core: Make use of --homedir in gpgconf.
+ + commit 0c2038c0043c1e79547b55e79c3d3e267dae801c
* src/engine-gpgconf.c (struct engine_gpgconf): Add field 'version'.
(have_gpgconf_version): New.
(gpgconf_release): Free VERSION.
@@ -306,6 +1276,7 @@
2016-11-02 Andras Mantia <andras@kdab.com>
qt: Fix build with g++ 4.8.x.
+ + commit b4658f6a1110bb0b54bd5dfc9df8e8b390e38d61
* lang/qt/src/defaultkeygenerationjob.cpp
(DefaultKeyGenerationJob::start): Explicitly connect pointer
in the QPointer.
@@ -313,6 +1284,7 @@
2016-11-02 Andre Heinecke <aheinecke@intevation.de>
qt, cpp: Fix versioning in cmake config and header.
+ + commit bf9aa0ccf7b0165aa3a1af2bdb18daca7c02ce74
* configure.ac (VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO): New
subst variables for the version header.
* lang/cpp/src/GpgmeppConfigVersion.cmake.in,
@@ -321,12 +1293,15 @@
lang/qt/src/qgpgme_version.h.in: Use new variables.
qt: Install cmake config into qgpgme subdir.
+ + commit b5c4d56cfdcafade3467be100fca6f1c89ecab73
* lang/qt/src/Makefile.am: Install cmake config file in qgpgme subdir.
qt: Require gpgmepp from cmake config script.
+ + commit 4149194d2e2f2f4d142926ba4d4efbd336b543f2
* lang/qt/src/QGpgmeConfig.cmake.in.in: Require cpp.
qt, cpp: Add all generated files to cleanfiles.
+ + commit 8486f213423311174ebff5cba74127cbd9bb3c2a
* cpp/src/Makefile.am (CLEANFILES),
qt/src/Makefile.am (CLEANFILES): Add all generated files
to cleanfiles.
@@ -334,11 +1309,13 @@
2016-11-01 Andre Heinecke <aheinecke@intevation.de>
qt: Add Distinguished Name parser from libkleo.
+ + commit 627c5deed84b4481710b6c0de06b26e886679bbe
* lang/qt/src/dn.cpp (DN, DN::Attribute): New public API.
* lang/qt/src/dn.h: New.
* lang/qt/src/Makefile.am: Update accordingly.
qt, cpp: Install version headers in subdirs.
+ + commit 567123de21247cab05762d799400739a12eb67ae
* lang/cpp/src/Makefile.am,
lang/qt/src/Makefile.am: Install version headers in include
subdirs.
@@ -346,6 +1323,7 @@
2016-10-31 Justus Winter <justus@g10code.com>
python: Use vanity modules for constants in tests and examples.
+ + commit 4b3264345084a0c9bf9f97fb233df700d7608e66
* lang/python/gpg/constants/sig/notation.py: New file.
* lang/python/gpg/constants/sig/__init__.py: Import new module.
@@ -375,6 +1353,7 @@
* lang/python/tests/t-wait.py: Likewise.
python: Import the topmost module in tests and examples.
+ + commit 20dc37a0e7e1531b0e568a6ec29b1c2d18de59c3
* examples/verifydetails.py: Only import the topmost module 'gpg' and
update the code accordingly.
* tests/support.py: Likewise.
@@ -400,6 +1379,7 @@
* tests/t-wrapper.py: Likewise.
python: Improve constants module.
+ + commit 70b7064e5c4f3eff9c296c00156724bc0cdaa64f
* lang/python/gpg/constants/__init__.py: Import all modules below
'constants/'. Interface hygiene: delete 'util'.
* lang/python/gpg/constants/data/encoding.py: Delete 'util'.
@@ -417,6 +1397,7 @@
2016-10-31 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
python: Rename Python module from PyME to gpg.
+ + commit 2fac017618a76882605125b05ff1f7393fe99860
This follows weeks of discussion on the gnupg-devel mailing list.
Hopefully it will make it easier for people using Python to use GnuPG
in the future.
@@ -424,6 +1405,7 @@
2016-10-25 Werner Koch <wk@gnupg.org>
core: New API functions gpgme_set_sender, gpgme_get_sender.
+ + commit b8159eadb5636cd9d93ee60c41e75d5978927870
* src/context.h (struct gpgme_context): Add field 'sender'.
* src/gpgme.c: Include mbox-util.h.
(gpgme_release): Free SENDER.
@@ -446,31 +1428,37 @@
2016-10-19 Andre Heinecke <aheinecke@intevation.de>
qt: Improve WKSPublishJob apidoc.
+ + commit 26cbba3c9cb04a68b95f3a6000ac9bd93fe76dd7
* lang/qt/src/wkspublishjob.h: Improve doc.
2016-10-18 Werner Koch <wk@gnupg.org>
Release 1.7.1.
+ + commit 2c490cdb3e50761c498357982445ebb01f18dc1e
* configure.ac: Set LT version to C27/A16/R0. Note that the LT
versions for cpp and Qt have already been updated.
2016-10-14 Werner Koch <wk@gnupg.org>
tests: Make t-cancel more portable.
+ + commit 05e8e1260baa5cbc6f1d6e387e642c1f6c188d44
* tests/gpg/t-cancel.c: Include sys/time.h and protect sys/select.h.
python: Call ln(1) in a portable way.
+ + commit c6cab5a2bd6e7ed226c6c3f0b78b3f48b47db74c
* lang/python/Makefile.am: Specify target dir for ln.
2016-10-14 Andre Heinecke <aheinecke@intevation.de>
cpp: Fix init of string from null.
+ + commit 1e8c34a9192956bb2fe96a7a6a76ff59de8d1c0c
* lang/cpp/src/key.cpp (UserID::addrSpecFromString): Check return
value before creating the string.
2016-10-13 Justus Winter <justus@g10code.com>
python: Make 'get_key' more idiomatic.
+ + commit f526d0e22e8b881ccbca66b46a0e1b68bbc4cd6b
* lang/python/pyme/core.py (Context.get_key): Raise errors.KeyNotFound
if the key is not found. This error is both a KeyError for idiomatic
error handling as well as a GPGMEError so we don't break existing
@@ -480,50 +1468,55 @@
* lang/python/tests/t-keylist.py: Test the new behavior.
python: Return public keys by default.
+ + commit 1e6073ffa98db2c265adbcf0dbbe70c067a910f0
* lang/python/pyme/core.py (Core.get_key): Return public keys by
default, improve docstring.
* lang/python/examples/testCMSgetkey.py: Update example.
* lang/python/examples/verifydetails.py: Likewise.
- GnuPG-bug-id: 2751
-
python: Fix example.
+ + commit cabd4c74e52c8983d624b6877cddc7f8912eff04
* lang/python/examples/inter-edit.py: Fix example.
- Fixes-commit: a458e7fe
-
2016-10-13 Andre Heinecke <aheinecke@intevation.de>
cpp: Fix version number.
+ + commit 56302e7bb6a694a7c570f389f9a7883efdfdaf42
* configure.ac (LIBGPGMEPP_LT_CURRENT): Bump.
qt, cpp: Fix permissions of Config files.
+ + commit a274c7590aa0e38d682d5177904983632f471cb0
* lang/cpp/src/Makefile.am,
lang/qt/src/Makefile.am: Do not install config files as executable.
qt: Install SpecialJob.
+ + commit 2538c12fa0728f4113f83f69f8c8ec9efb163872
* lang/qt/src/Makefile.am: Install SpecialJob
* NEWS: mention it.
qt, cpp: Fix expected targets in Config files.
+ + commit a3cf30f89418c8a6bc9456533d95ba7fc2a33a4c
* lang/cpp/src/GpgmeppConfig.cmake.in.in,
lang/qt/src/QGpgmeConfig.cmake.in.in: Remove KF5 variants.
2016-10-11 Daniel Vrátil <dvratil@kde.org>
qt: Add missing implementation of MultiDeleteJob.
+ + commit e5a35af5573651b96a90ef4a537b040333595472
* lang/qt/src/multideletejob.h: Fix include, cryptobackend.h is now
called protocol.h
* lang/qt/src/multideletejob.cpp: New file.
* lang/qt/src/Makefile.am: Add multideletejob.cpp.
qt: Install abstractimportjob.h.
+ + commit ce7385caabb57e5435695cc912acffe2815770b7
* lang/cpp/src/Makefile.am: Install abstractimportjob.h since it's
included from importjob.h
2016-10-11 Andre Heinecke <aheinecke@intevation.de>
cpp: Add API for gpgme_addrspec_from_uid.
+ + commit 54f94b14e2bb9b38ffd89f509406bfbd012da632
* lang/cpp/src/key.cpp (UserID::addrSpecFromString): New static
function to expose addrspec from uid.
(UserID::addrSpec): New. Get addrSpec from Userid.
@@ -532,29 +1525,35 @@
2016-10-10 Andre Heinecke <aheinecke@intevation.de>
Add NEWS for cpp and qt, bump cpp version.
+ + commit e7ceb83a5969581f5e1b0b6a69d18a93b594f6d4
* NEWS: Add entries for cpp and qt changes.
* configure.ac: Bump cpp version because of added API.
Add convenience function to get key from sig.
+ + commit b6b820bff14a9aa8fa67755b246c90062ffdba14
* lang/cpp/src/verificationresult.cpp (Signature::key(bool, bool)):
New. Can be used to search / update the key associcated with this
signature.
cpp: Return null key if the signature had no key.
+ + commit 34e9dfee81958160f6604849b63369ae4de67417
* lang/cpp/src/verificationresult.cpp (Private): Add null key
to list when there is no key associated with the signature.
qt: Add simple verify test.
+ + commit f131a5e72b0881cafcc3b0a91da8f050af2684a6
* lang/qt/tests/t-verify.cpp: New. Small test if a signature
returns a key with fingerprint.
* lang/qt/tests/Makefile.am: Add new test.
core: Fix w32 crash in find_program_in_dir.
+ + commit 098a2da15b1b46b145add623dec0488abd39bd74
* src/w32-util.c (find_program_in_dir): Fix call to _gpgme_strconcat.
2016-10-08 Werner Koch <wk@gnupg.org>
core: New helper function gpgme_addrspec_from_uid.
+ + commit 0ea2ff67900c243fff9f689658dcb23d1c0961cd
* src/gpgme.h.in: Add gpgme_addrspec_from_uid.
* src/gpgme.def, src/libgpgme.vers: Ditto.
* src/mbox-util.c (gpgme_addrspec_from_uid): New.
@@ -562,6 +1561,7 @@
2016-10-06 Justus Winter <justus@g10code.com>
Add missing includes.
+ + commit 857592041b8355cd58a7068c9f2446cf8dc0968f
* lang/cpp/src/key.cpp: Include <strings.h> for 'strcasecmp'.
* tests/gpg/t-cancel.c: Include <sys/select.h> for 'fd_set' and
friends.
@@ -569,9 +1569,11 @@
2016-10-05 Andre Heinecke <aheinecke@intevation.de>
cpp: Bump Revision.
+ + commit 8033cff441e9ea185531290273ec343f3402703c
* configure.ac (LIBGPGMEPP_LT_REVISION): Bump revision.
qt: Fix spelling error in WKSPublishJob.
+ + commit 88c7e84ede4b6017cac3a396e8c87c2bd3a2bf58
* src/qgpgmewkspublishjob.cpp,
src/qgpgmewkspublishjob.h,
src/wkspublishjob.h,
@@ -580,13 +1582,16 @@
accordingly.
qt: Disable tests that require a password for 2.0.
+ + commit 24779c9e2301bd17fd328d65b0383e1cbc944119
* lang/qt/tests/t-encrypt.cpp: Disable tests that require
a password for 2.0.
Add warning flags for c++ compiler, too.
+ + commit 4984cc93db6b55f2420a9abd844c074a5fb4ed0c
* configure.ac (CXXFLAGS): Add Wall and Wextra.
qt: Fix unused variable warnings.
+ + commit 9d1df990386010e0581b542a76a4f5d85d8d11b5
* qt/src/qgpgmenewcryptoconfig.cpp,
qt/src/threadedjobmixin.h,
qt/tests/t-encrypt.cpp,
@@ -594,30 +1599,36 @@
qt/tests/t-wkspublish.cpp: Mark additional variables as unused.
cpp: Add support for URL Data encodings.
+ + commit 370ee1aa802ec6a4030a39b2df7d24a0c47e5ac7
* lang/cpp/src/data.h (Data::Encoding): Extend enum.
* lang/cpp/src/data.cpp (Data::encoding),
Data::setEncoding): Support new values.
cpp: Fix gcc diagnostic push / pop.
+ + commit 39dd7585f5a7d801942efcb375d6dd46d01d2968
* lang/cpp/src/context.cpp: Fix pragmas.
qt: Disable t-wkspublish test.
+ + commit 52a91ccc6a25425d4374b77040e30efb6816940f
* lang/qt/tests/Makefile.am (TESTS): Remove t-wkspublish.
2016-09-30 Alon Bar-Lev <alon.barlev@gmail.com>
python: Link 'data.h' and 'config.h' into the builddir.
+ + commit 453ab9d24ca48c9e01d21e1454d6b08de1938b76
* lang/python/Makefile.am: Link to the files.
* lang/python/gpgme.i: Update path.
* lang/python/setup.py.in: Do not add the top builddir to the include
path.
python: Add 'prepare' target.
+ + commit 68fb8371a1dd5f4e05e50b1733f9996d139cbf38
* lang/python/Makefile.am: Add 'prepare' target.
2016-09-29 Andre Heinecke <aheinecke@intevation.de>
cpp, qt: Handle modified includedir installation.
+ + commit 7302791c0d308c3284ac24a743035d27a0c0b6ba
* lang/cpp/src/Makefile.am,
lang/qt/src/Makefile.am: Replace resolved_includedir.
* lang/cpp/src/GpgmeppConfig.cmake.in.in,
@@ -627,6 +1638,7 @@
2016-09-27 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Clarify licensing.
+ + commit 145392f07f42ef23ebcb83a917b4d8e2964e7aa8
* src/b64dec.c, src/mbox-util.c, src/mbox-util.h: These three files
are explicitly licensed under LGPL, but their comments suggest that
details about the warranty can be found in the GPL. Adjust comments
@@ -635,19 +1647,23 @@
2016-09-27 Justus Winter <justus@g10code.com>
tests: Fix check for gpg versions not reporting the critical flag.
+ + commit a423603f80d9eb653ce9c171662db2175d7456f5
* lang/python/tests/t-sig-notation.py: Also blacklist 2.0.x.
* tests/gpg/t-sig-notation.c: Likewise.
2016-09-26 Justus Winter <justus@g10code.com>
python: Correctly translate to size_t.
+ + commit c38fabfea0601ed5f61e27e0bf43f8e74c67ce2a
* lang/python/gpgme.i: Correctly translate Python number to size_t.
python: Correctly translate off_t.
+ + commit 1d80e7374aa3150306c86afe7acdc8e8eb05143f
* lang/python/gpgme.i: Improve int/long translations, correctly handle
off_t with large file support.
python: Include 'config.h'.
+ + commit 3703a4723899d7563937b4b99f5bbe4dd8d3dfed
* lang/python/Makefile.am: Pass 'top_builddir' to 'setup.py'.
* lang/python/gpgme.i: Include 'config.h'.
* lang/python/helpers.c: Likewise.
@@ -657,11 +1673,13 @@
2016-09-23 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Fix spelling.
+ + commit 95f38652f696476b38a040644eac40b4511d2b32
* lang/cpp/src/context.h, lang/qt/src/protocol.h,
lang/qt/src/wkspublishjob.h, src/data-identify.c, src/engine-gpg.c:
minor spelling cleanup.
move some file encodings to UTF-8.
+ + commit a11450eb048df79a3f2b00ebef6d7cab07ad5054
* THANKS, doc/ChangeLog-2011, tests/ChangeLog-2011,
tests/gpg/geheim.txt: convert from iso 8859-1 to utf-8.
* lang/qt/src/dataprovider.cpp, lang/qt/src/qgpgmerefreshkeysjob.cpp,
@@ -671,10 +1689,12 @@
2016-09-23 Andre Heinecke <aheinecke@intevation.de>
tests: Check data after decryption.
+ + commit 9b38817968b90caf73f123255fe427691e82fec4
* tests/gpgsm/t-decrypt.c (main): Check data matches expected.
Only print result if it does not.
cpp, qt: Include config.h.
+ + commit a142f187b7ddb2728ec3e1743da4a0c4538ab40a
lang/cpp/src/callbacks.cpp,
lang/cpp/src/configuration.cpp,
lang/cpp/src/context.cpp,
@@ -748,14 +1768,17 @@
2016-09-22 Werner Koch <wk@gnupg.org>
w32: Silence some warnings about unused parameters.
+ + commit 583aafdd6870a7fb12a34d90993fd0f46928592c
* src/assuan-support.c (my_recvmsg, my_sendmsg, my_waitpid)
(my_socketpair) [W32]: Mark unused parameters.
core: Fix error checking in _gpgme_mkstemp.
+ + commit c447b64d5989845a2ae2cf8fb30a92d2a0bd05af
* src/w32-util.c (_gpgme_mkstemp): Fix error checking.
(dlopen): Mark FLAGS as unused.
core: New helper function _gpgme_strconcat.
+ + commit dc39552d01094eff2bef5f9fcd1c16928909d20e
* src/conversion.c: Include stdarg.h.
(do_strconcat): New.
(_gpgme_strconcat): New.
@@ -773,6 +1796,7 @@
2016-09-22 Daiki Ueno <ueno@gnu.org>
tests: Add test for cancellation.
+ + commit 7a6543c2dfeef874a34086c8f3eeb1dbdf1ce822
* tests/gpg/t-cancel.c: New file.
* tests/gpg/Makefile.am (tests_skipped): New variable, default to
t-genkey and t-cancel.
@@ -780,19 +1804,23 @@
* tests/gpg/.gitignore: Add t-cancel.
gpg: Add option --exit-on-status-write-error.
+ + commit dee56820cabde60c43c9bf8281b8d411cb2ad644
* src/engine-gpg.c (gpg_new): Add --exit-on-status-write-error if the
engine version is latest enough to expect progress output from gpg.
tests: Fix select usage in t-eventloop.
+ + commit d0cf6b15121c9b42dbcef243e5ce30c9996a449c
* tests/gpg/t-eventloop.c (do_select): Supply timeout value to select.
doc: Fix minor errors in I/O callback example.
+ + commit 0aaf1dedd629446ab991fff76581b4b58e4872a0
* gpgme.texi (I/O Callback Example): Fix typos, add timeout to select,
and initialize mutex as recursive.
2016-09-21 Andreas Stieger <astieger@suse.com>
cpp: Avoid missing returns in non-void functions.
+ + commit ae324b51ffa338b891387bff2657d60c1fd3ae40
* lang/cpp/src/context.cpp
(Context::signaturePolicyURL): return nullptr on default
(to_tofu_policy_t): add default case for unknown
@@ -804,14 +1832,17 @@
2016-09-21 Werner Koch <wk@gnupg.org>
Release 1.7.0.
+ + commit e7ab75379feadcc2894d9d4cde0f16ad0044780d
* configure.ac: Bump LT vesion to C26/A15/R0.
python: Create install dir.
+ + commit 936928632b02d7cc2ac645543bb03e4c94285f05
* lang/python/Makefile.am (install-exec-local): Create dir.
2016-09-20 Werner Koch <wk@gnupg.org>
tests: Make "make -j distcheck" work in Python.
+ + commit 0763357e39d140b068ee9838a5da08be75426d9f
* lang/python/Makefile.am (SUBDIRS): Make current dir fist.
* lang/python/tests/Makefile.am (xcheck): Depend on pubring-stamp.
(CLEANFILES): Remove private-keys-v1.d/gpg-sample.stamp.
@@ -822,47 +1853,54 @@
basename.
tests: Use --batch for gpg import.
+ + commit bfb6890ded99f040fe8ecf910f927a136e4acfda
* lang/python/tests/Makefile.am (./pubring-stamp): Use --batch with
GPG to avoid Pinentries during import when using GnuPG >= 2.1.
Replace touch by echo.
* tests/gpg/Makefile.am (./pubring-stamp): Ditto.
tests: Improve portability.
+ + commit 29207bcd3bf4de7264197db6758130375b16d9bb
* lang/qt/tests/Makefile.am (clean-local): Avoid non-portable "--"
* lang/python/Makefile.am (copystamp): Use well defined cp -R instead
of cp -r.
build: Create swdb file.
+ + commit df7e92b4d585b7dce919c5a3aab9524f6e183cbe
* Makefile.am (distcheck-hook): New.
(dist-hook): s/VERSION/PACKAGE_VERSION/ for future compatibility.
2016-09-20 Justus Winter <justus@g10code.com>
python: Fix detection of Python available versions.
+ + commit ef99b74eb12463db7da5806a316e3b55f8097c5c
* configure.ac: Test for 'PYTHON_VERSION' as 'AX_PYTHON_DEVEL' sets
'PYTHON' but clears the former.
- Fixes-commit: 99db3512
-
2016-09-19 Andre Heinecke <aheinecke@intevation.de>
core: Remove moc artifact.
+ + commit e3c35147d6adb754d4eb0781a54af2a8f0803663
* src/moc_kdpipeiodevice.cpp: Removed.
* src/Makefile.am (EXTRA_DIST): Remove moc_kdpipeiodevice.cpp.
qt: Improve README.
+ + commit 3f92253e0e476d77aa11463bc51ade367985855f
* lang/qt/README: Add more content. Clearly note license difference.
cpp: Improve README.
+ + commit 66febf9942c321d30b8770f6aa6cd6ce2315d34f
* lang/cpp/README: Add more content, move license to bottom.
qt: Add debug output for testTofuPolicy.
+ + commit d438cb59a068b6f076e6bd70d3a2c46bc05ccb5c
* lang/qt/tests/t-tofuinfo.cpp (testTofuPolicy): Add
debug output.
2016-09-19 Ben Kibbey <bjk@luxsci.net>
core: Check for GPG_TTY as well as DISPLAY.
+ + commit 9d62bacac7826cb73bb18fac7268f3d2df662d7b
* src/engine-assuan.c (llass_new): Update --ttyname from GPG_TTY.
* src/engine-g13.c (g13_new): Ditto.
* src/engine-gpg.c (gpg_new): Ditto.
@@ -872,9 +1910,11 @@
2016-09-16 Andre Heinecke <aheinecke@intevation.de>
qt: Add test for setting tofu policy.
+ + commit a8ff34fc3025af4079cede7f8f9fdf40189b8638
* lang/qt/tests/t-tofuinfo.cpp (testTofuPolicy): New.
qt: Add job for tofupolicy.
+ + commit 77aecfb5c97cea1a99f1ff627748cf71767bac5c
* lang/qt/src/job.cpp, lang/qt/src/protocol.h,
lang/qt/src/protocol_p.h: Register job.
* lang/qt/src/qgpgmetofupolicyjob.cpp,
@@ -883,24 +1923,29 @@
* lang/qt/src/Makefile.am: Update accordingly.
cpp: Add support for gpgme_op_tofu_policy.
+ + commit 4d384d7bfef044094695271576ca233625bb520a
* src/context.cpp, src/context.h (setTofuPolicy, setTofuPolicyStart):
New.
cpp: Declare sizes of tofu-info enums.
+ + commit 32baac8cdec6fee51bdfc3c55cb2ee141e086df4
* lang/cpp/src/tofuinfo.h (Policy, Validity): Declare sizes.
2016-09-16 Werner Koch <wk@gnupg.org>
cpp: Silence use of deprecated function warning.
+ + commit bd24db313d860ae46d37776dcf1067455d1b9880
* lang/cpp/src/context.cpp (GpgME): Use pragma to silence wardning.
core: Document the version a function has been deprecated.
+ + commit b615316168f4d33311909d4056b236d13c69488f
* src/gpgme.h.in (_GPGME_DEPRECATED): Change to take versio numbers
for documentation. Change all places.
(_GPGME_DEPRECATED_OUTSIDE_GPGME): Ditto.
* lang/python/gpgme-h-clean.py: Adjust RE.
core: Map GPGME_STATUS_EOF to the empty string.
+ + commit 3d6340e8c59ee11a95e03fb213ad9b228be47833
* src/status-table.c (_gpgme_status_to_string): Return "" for EOF.
* src/engine-gpg.c (read_status): Ditto. The old code accidently used
GPGME_STATUS_EOF which is the integer 0 and neiteyr NULL nor a string.
@@ -909,6 +1954,7 @@
Kai Michaelis <kai@gnupg.org>
python: Release the GIL during calls into GPGME.
+ + commit 6af7bee076bacbc0cdfe7de342bce43ca5671b3b
* lang/python/helpers.c (pyme_raise_callback_exception): Re-acquire
the Global Interpreter Lock.
(pyPassphraseCb, pyme_set_passphrase_cb, pyProgressCb,
@@ -922,6 +1968,7 @@
2016-09-16 Justus Winter <justus@g10code.com>
python: Adapt to 'gpgme_op_interact'.
+ + commit a458e7fe2006d92bd5a838e2747fb66bbac4b1b8
* lang/python/examples/inter-edit.py: Update example.
* lang/python/gpgme.i (gpgme_edit_cb_t): Turn into
'gpgme_interact_cb_t'.
@@ -939,16 +1986,19 @@
2016-09-16 Werner Koch <wk@gnupg.org>
core: Remove stub to try implementing gpg < 2.1 support for createkey.
+ + commit 268e251b802cc7c19831722d7e3a52777a0f412f
* src/engine-gpg.c (gpg_createkey_legacy): Remove.
(gpg_genkey): Remove call.
core: Fix setting og the verification result.
+ + commit 1f9641dd0fb08e4a3df3b507b974a3f78887920f
* src/verify.c (parse_new_sig): Proberly handle the RC in an ERRSIG
status.
2016-09-15 Werner Koch <wk@gnupg.org>
core: New function gpgme_op_interact, deprecate gpgme_op_edit.
+ + commit ed1f2700a73060e2615697491ea9e49ded4293e6
* src/gpgme.h.in (gpgme_interact_cb_t): New.
(GPGME_INTERACT_CARD): New.
(gpgme_op_interact_start, gpgme_op_interact): New.
@@ -966,6 +2016,7 @@
(main): s/gpgme_op_edit/gpgme_op_interact/.
core: Minor change of the gpgme_op_edit semantics.
+ + commit d2b72d3cc19fe2a7d548dac38d55e069e0c9a904
* src/edit.c (command_handler): Handle special error code.
* src/engine-gpg.c (read_status): Ditto.
* src/engine-gpgsm.c (status_handler): Ditto.
@@ -975,6 +2026,7 @@
2016-09-14 Werner Koch <wk@gnupg.org>
core: New function gpgme_op_tofu_policy.
+ + commit 7c37719d79345a665ec2f4570e3f257033b58c62
* src/gpgme.h.in (gpgme_op_tofu_policy_start): New function.
(gpgme_op_tofu_policy): New function.
* src/libgpgme.vers, src/gpgme.def: Add new functions.
@@ -991,9 +2043,11 @@
* tests/Makefile.am (noinst_PROGRAMS): Add it.
core: Defer implementation of gpgme_op_createkey with gpg < 2.1.
+ + commit d79dcb78d867aaf55b85aea117c4ae6035a1531a
* src/engine-gpg.c (gpg_createkey_legacy): Mark unused variables.
core: New function gpgme_op_keysign.
+ + commit bfd2bd0ccc9fed8284ef932ac788d4ca0dba0336
* src/gpgme.h.in (gpgme_op_keysign_start, gpgme_op_keysign): New.
(GPGME_KEYSIGN_LOCAL): New.
(GPGME_KEYSIGN_LFSEP): New.
@@ -1017,30 +2071,36 @@
2016-09-14 Justus Winter <justus@g10code.com>
python: Clarify that we support Python 2.7 too.
+ + commit 594c3b8b052e60b6be77ed532fe46549133a9726
* lang/python/README: Use 'Python' instead of 'Python 3'.
* lang/python/pyme/version.py.in: Likewise.
* lang/python/setup.py.in: Add classifier for 2.7, drop 3 only.
python: Trim imports.
+ + commit 4011b2b2a1050f0837e989da3db9b5459e71ccd6
* lang/python/examples/encrypt-to-all.py: Drop unused import of 'os'.
* lang/python/examples/signverify.py: Likewise.
* lang/python/examples/simple.py: Likewise.
* lang/python/examples/verifydetails.py: Likewise.
python: Improve error handling.
+ + commit 44d18200d5ffe8691e18d93ce6c534660702b982
* lang/python/gpgme.i (gpgme_engine_info_t): Improve error handling.
python: Adapt to TOFU changes.
+ + commit f6cd560ca74248dd719a37cfb34386148727a92d
* lang/python/pyme/results.py (TofuInfo): Drop.
(Signature): The TOFU information moved to the key.
python: Improve build system integration.
+ + commit 99db351288d5bb075f124ef10e540e25bc36b70a
* configure.ac: Try to compile a Python module for each version.
* m4/m4_ax_swig_python.m4: Drop unused file.
2016-09-14 Werner Koch <wk@gnupg.org>
core: New function gpgme_op_revuid.
+ + commit c943380b7a2cc9b32f81c22224fc6f92e8ea8469
* src/engine.h (GENKEY_EXTRAFLAG_REVOKE): New.
* src/genkey.c (adduid_start): Rename to addrevuid_start. Add arg
REVOKE and pass it as extraflags. Remove useless ARMOR extraflag.
@@ -1051,6 +2111,7 @@
* tests/run-genkey.c: Add option --revuid.
core: Change a parameter for the engine's genkey function.
+ + commit c22f5884c50557f54704f4becc5a8c1ee0749547
* src/engine.h (GENKEY_EXTRAFLAG_ARMOR): New.
* src/engine-backend.h (engine_ops): Rename USE_ARMOR in genkey to
EXTRAFLAGS.
@@ -1065,6 +2126,7 @@
2016-09-14 Justus Winter <justus@g10code.com>
python: Build for both Python2 and Python3.
+ + commit 24b4162d908b48a92660020be0b776c2874fb05a
* NEWS: Update.
* configure.ac: Check for multiple Python versions.
* lang/python/Makefile.am: Build and install for both Python versions.
@@ -1074,6 +2136,7 @@
2016-09-14 Werner Koch <wk@gnupg.org>
core: New function gpgme_op_adduid.
+ + commit 3210f3e4725afc5ee2810b9a1361918ec9c42ca4
* src/genkey.c: Replace most error codes GPG_ERR_INV_VALUE by
GPG_ERR_INV_ARG.
(struct op_data_t): Add field UIDMODE.
@@ -1084,6 +2147,7 @@
* tests/run-genkey.c: Add option --adduid.
core: New function gpgme_op_createsubkey.
+ + commit cc353701b0fde4c811ddc1e9a91b852dfe9f4e06
* src/genkey.c (createsubkey_start): New.
(gpgme_op_createsubkey_start, gpgme_op_createsubkey): New.
* src/gpgme.def, src/libgpgme.vers: Add them.
@@ -1095,28 +2159,41 @@
2016-09-13 Werner Koch <wk@gnupg.org>
core: Use const char * where appropriate.
+ + commit 51f9acbca935c5287d9a28205037b0923e9a65f5
+
core: Cast away the common const problem with spawn and argv.
+ + commit 686a065f639ef006e33c164e282d787bcd169754
* src/dirinfo.c (read_gpgconf_dirs): Use a cast to assignd to ARGV.
core: Fix condition-always-true warning in trace macro.
+ + commit 3009e6162eaa39adaaf45f06fc4f88c7153360ee
* src/data-compat.c (old_user_read): Cast AMT.
core: Mark unused function args.
+ + commit 4a200146b602349eebb4eac2e102357748d7ba5b
+
tests: Mark lots of unused vars and fix const mismatches.
+ + commit 9064eebdc05e7149c2c8cc899fbd7874622fb769
+
tests: Use gpgme_io_write in passhrase callbacks.
+ + commit 4491ef0a9a15d3b307d1ade37ff620ef9fcb2478
* tests/gpg/t-support.h (passphrase_cb): Use gpgme_io_write.
* tests/gpgsm/t-support.h (passphrase_cb): Ditto.
* tests/run-support.h (passphrase_cb): Ditto.
core: Do not pass const char* to functions taking a char*.
+ + commit 3972f476e00f27d41a0aeabcb66600905b6737bd
+
build: Use more compiler warnings.
+ + commit 0510591c36591816a6ff3f87a04451001b7ed46f
* configure.ac: Add useful compiler warnings.
core: New function gpgme_op_create_key.
+ + commit 00c501d296da287bec2fd6a0e3912abfbde90a98
* src/engine-backend.h (engine_ops): Change prototype of genkey.
* src/engine-gpgsm.c (gpgsm_genkey): Change accordingly.
* src/engine-gpg.c (gpg_genkey): Change it to a dispatcher.
@@ -1153,6 +2230,7 @@
2016-09-13 Justus Winter <justus@g10code.com>
python: Handle slight differences between Python 2 and 3.
+ + commit 70a3be27a509a1b5ea7372bee93d83c5019427ff
* lang/python/helpers.c (pyDataWriteCb): Handle Python integers being
returned on Python 2.
(pyDataSeekCb): Likewise.
@@ -1169,12 +2247,14 @@
using bytestrings in Python 3 would be very inconvenient.
python: Fix types and error handling.
+ + commit 4abff7d750a1abf5b388a4c87ec321fc3e4aed10
* lang/python/helpers.c (_pyme_edit_cb): Drop the const.
(_pyme_assuan_{data,inquire,status}_cb): Fix error handling.
2016-09-12 Justus Winter <justus@g10code.com>
python: Avoid Python3-only form of super().
+ + commit c0c50318bd8ef6c8119ad9fdc53ad9087ded4c32
* lang/python/pyme/core.py (GpgmeWrapper.__repr__): Use more
compatible form of super.
(GpgmeWrapper.__setattr__): Likewise.
@@ -1182,30 +2262,32 @@
(Data.__init__): Likewise.
python: Make type translation compatible with Python 2.7.
+ + commit 1d5bbbf1185a0d1f82750f10b69dad3999f7ef4c
* lang/python/gpgme.i: Avoid functions not available in Python 2.7.
* lang/python/helpers.c: Likewise.
python: Avoid hardcoding the interpreter.
+ + commit 70999d81618b3d3ae6b61a43be2ce703ad284275
* lang/python/setup.py.in: Avoid hardcoding the interpreter.
python: Do not rely on subprocess.DEVNULL.
+ + commit b48b852a846129914d6c63ec7b47388cdcf6acca
* lang/python/setup.py.in: Do not rely on subprocess.DEVNULL.
tests: Fix version comparison.
+ + commit dfd99ab50c3bc1d6745b6f682791e4885e8d8a9a
* tests/gpg/t-sig-notation.c: Fix version comparison.
- Fixes-commit: a0263ad2
-
tests: Make signature notation test compatible with older GnuPGs.
+ + commit a0263ad282d350b548cbbc27e96f196d9217d040
* lang/python/tests/t-sig-notation.py: Only check the critical flag
when GnuPG >= 2.1.13 is used.
* tests/gpg/t-sig-notation.c: Likewise.
- Fixes-commit: c88c9ef3
-
2016-09-12 Andre Heinecke <aheinecke@intevation.de>
qt: Fix some includes.
+ + commit d480f6b701894f78f3f4016d69c0e3b87939930b
* lang/qt/src/qgpgmekeyformailboxjob.cpp: Explicitly include
QStringList.
* lang/qt/tests/t-support.h, lang/qt/tests/t-support.cpp: Move
@@ -1214,13 +2296,13 @@
2016-09-12 Justus Winter <justus@g10code.com>
qt: Fix tofu test.
+ + commit 7b9e6ea376d04fb4694ed22369abaae92ce3ec86
* lang/qt/tests/t-tofuinfo.cpp: Adjust member names.
- Fixes-commit: 120b1478
-
2016-09-07 Werner Koch <wk@gnupg.org>
core,cpp: Extend the TOFU information.
+ + commit 120b14783c0312d782dc08ce4949a6209d5ccc7b
* src/gpgme.h.in (struct _gpeme_tofu_info): Rename FIRSTSEEN to
SIGNFIRST and LASTSEEN to SIGNLAST. Add ENCRFIST and ENCRLAST.
* src/keylist.c (parse_tfs_record): Parse to ENCRFIRST and ENCRLAST.
@@ -1235,83 +2317,102 @@
2016-09-06 Andre Heinecke <aheinecke@intevation.de>
tests: Set passphrase cb in t-encrypt-mixed.
+ + commit 151da95470f174dc770b2111890ad650a1697276
* tests/gpg/t-encrypt-mixed.c (main): Set passphrase cb.
core: Check for gpg version for loopback mode.
+ + commit e8cb143c8337b122a6790f769ddb0a97c4baccd3
* src/engine-gpg.c (build_argv): Check for version 2.1.0
before adding pinentry-mode.
core: Fix passphrase cb for mixed sym encrypt.
+ + commit efe7e11dfa2ff911b477ce748292e53e7a50347e
* src/encrypt.c (encrypt_start): Handle SYMMETRIC flag.
* src/encrypt-sign.c (encrypt_sign_start): Ditto.
2016-09-05 Andre Heinecke <aheinecke@intevation.de>
qt: Clarify comment and strings in tofuinfo test.
+ + commit ab3fbdbd05cfd1b039bb5b1eb3941fbb4bcf6307
* lang/qt/tests/t-tofuinfo.cpp (testTofuSignCount)
(testTofuKeyList): Ensure distinct messages. Clarify comment.
qt: Enable signcount checks in tofuinfo test.
+ + commit 965b842fad6ec6fbd8902f3a32119abcd0728fe4
* lang/qt/tests/t-tofuinfo.cpp: Enable checks for signcount.
cpp: Add convenience update function to a key.
+ + commit 79439e76cc5b302222874a1f9e93665cb12801ac
* lang/cpp/src/key.cpp (Key::update): New.
* lang/cpp/src/key.h: Update accordingly.
cpp: Add ostream operators for key and uid.
+ + commit 444d85ace0dddff5c511961927052d9946035b00
* lang/cpp/src/key.cpp (Key, UserID): Add ostream operator.
* lang/cpp/src/key.h: Update accordingly.
qt: Add missing header redirection.
+ + commit 8a39a595eb802b80a6ad756b0ee8939e9733e86f
* lang/qt/src/keyformailboxjob.h,
lang/qt/src/qgpgmekeyformailboxjob.h: Fix includes.
qt: Include cpp before core directory.
+ + commit e3a4697894cc5a93c295e84bb10c743bc7fdc87e
* lang/qt/src/Makefile.am (AM_CPPFLAGS): Include cpp before core.
2016-08-25 Andre Heinecke <aheinecke@intevation.de>
qt: Fix 2.1 t-support copy.
+ + commit 05570bd3d05fb3d7934c1122f0d5ef5fdbaa7974
* lang/qt/src/t-support.cpp (copyKeyring): Fix seckey copy.
qt: Fix and extend TofuInfo test.
+ + commit 9fc72e928bf2cf239bd3b0facdf33ceb1acc975b
* lang/qt/tests/t-tofuinfo.cpp: Delete executed jobs.
(testTofuKeyList): New.
(testSupported): Activate for 2.1.16
(signAndVerify): Disable sigcount tests.
qt: Fix keyring copy in tests.
+ + commit c875f07e559a7c53fc173b4c3f9f5715f3fbb8f8
* lang/qt/test/t-encrypt.cpp,
lang/qt/test/t-tofuinfo.cpp: Assert on copy failure.
* lang/qt/test/t-support.cpp (copyKeyrings): Fix path.
qt: Add generic flag support for keylistjobs.
+ + commit 4e37d0bb1255558ce20e1a5ac83a2d06a37f8b0b
* lang/qt/src/keylistjob.h (addMode): New.
* lang/qt/src/qgpgmekeylistjob.h (addMode): New.
* lang/qt/src/qgpgmekeylistjob.cpp (addMode: New.
qt: Ensure that current src dir is included first.
+ + commit 5a92cc96da183ebb19867a2a910f53ba41e76ae9
* lang/qt/src/Makefile.am: Reorder include directives.
cpp: Add WithTofu Keylist Mode.
+ + commit f311b92ceaedb12c9e00a722b6b47bbe6b50871e
* lang/cpp/src/context.cpp: Handle WithTofu.
* lang/cpp/src/global.h (KeyListMode): Add WithTofu.
* lang/cpp/src/util.h (add_to_gpgme_keylist_mode_t): Handle WithTofu.
qt: Fix tofuinfo test when gpg is gpg2.
+ + commit 053e6e0a7b8ea38ad9d4160c84814867bbb9fcf6
* lang/qt/tests/t-support.cpp (QGpgMETest::copyKeyrings): New helper.
* lang/qt/tests/t-support.h: Declare.
* lang/qt/tests/t-encrypt.cpp: use it
* lang/qt/tests/t-tofuinbo.cpp: ditto.
qt: Remove unused variable in test.
+ + commit f08904b810d77d87c66d9c7875c4e7f2bde5dd92
* t-wkspublish.cpp (testWKSPublishCreate): Remove context.
qt: Add test for wkspublishjob.
+ + commit df04b232b8897f030534f8c3fbc87064edf8ae7d
* lang/qt/tests/t-wkspublish.cpp: New.
* lang/qt/tests/Makefile.am: Update accordingly.
qt: Add WKSPublishJob.
+ + commit 94420b05775122b25885c66ac67f77c59d01644d
* lang/qt/src/Makefile.am: Add new files.
* lang/qt/src/job.cpp: Include moc / subclass stub.
* lang/qt/src/protocol.h: Add virtual for new job.
@@ -1321,15 +2422,18 @@
lang/qt/src/qgpgmewkspublishjob.h: New.
Cpp: Change firstSeen / lastSeen return values.
+ + commit de7b67f9b2e6bd43a036fa0bcc6a8ca4f5b10986
* lang/cpp/src/tofuinfo.cpp,
lang/cpp/src/tofuinfo.h (TofuInfo::firstSeen, TofuInfo::lastSeen):
Change return values to unsigned long and update doc.
Cpp: Add wrapper for gpgme_get_dirinfo.
+ + commit abcd9a283ee8f81870622c8e1dbdc7aad38c0358
* lang/cpp/src/context.cpp (dirInfo): New.
* lang/cpp/src/global.h (dirInfo): New.
Cpp: Add support for spawn engine.
+ + commit ece8b02a839d6fc566fea7b6e59fabff164f6cf5
* lang/cpp/src/context.cpp (Context::spawn, Context::spawnAsync): New.
* lang/cpp/src/context.h: Add prototypes.
(SpawnFlags): New.
@@ -1338,6 +2442,7 @@
2016-08-25 Werner Koch <wk@gnupg.org>
core: Add GPGME_KEYLIST_MODE_WITH_TOFU.
+ + commit 9ee103957e4136337b92d238283f8ef30fd4a7c5
* src/gpgme.h.in (GPGME_KEYLIST_MODE_WITH_TOFU): New.
* src/engine-gpg.c (gpg_keylist_build_options): Use that.
* src/keylist.c: Include limits.h.
@@ -1353,14 +2458,17 @@
2016-08-24 Werner Koch <wk@gnupg.org>
core: Adjust for TOFU_STATS change in gnupg 2.1.16.
+ + commit 38798fee5b539d6153a8a7856152959412ee59b5
* src/gpgme.h.in (_gpgme_tofu_info): Change 'firstseen' and 'lastseen'
to a timestamp value.
* src/verify.c (parse_tofu_stats): Do not cap these values at UINT_MAX.
core: Set the 'encrcount' field in gpgme_tofu_info_t.
+ + commit 1eefc2d43c0adb2ce516f8e3509ace2fb562e401
* src/verify.c (parse_tofu_stats): Set ENCRCOUNT field.
cpp: Get rid of AssuanResult due to its deprecation.
+ + commit e20b0f0201543834f15c5d50cd3b2ece69a35d70
* lang/cpp/src/assuanresult.cpp: Remove.
* lang/cpp/src/assuanresult.h: Remove.
* lang/cpp/src/Makefile.am: Remove these files.
@@ -1374,19 +2482,23 @@
2016-08-24 Andre Heinecke <aheinecke@intevation.de>
Qt: Adapt (disabled) tofuinfo test to new API.
+ + commit d2e40fb7adf667f3e2d2457ee4c646ea4d4d88b3
* lang/qt/tests/t-tofuinfo.cpp: Switch to UID based API.
Cpp: Add Key to signature.
+ + commit 7c5a4974b71c30e824cbfcb3a0a70064e5ed5adb
* lang/cpp/src/verificationresult.cpp,
lang/cpp/src/verificationresult.h (Signature::key): New.
Cpp: Use fpr field for primaryFingerprint.
+ + commit 40ea1c85773cbe324557c34b3a4282f609fcdaf6
* lang/cpp/src/key.cpp (Key::primaryFingerprint): Return
fpr value if available.
2016-08-23 Andre Heinecke <aheinecke@intevation.de>
Cpp: Move tofuinfo from signature to userid.
+ + commit 799b168243e6499ac01bf59e0656547f353a2589
* lang/cpp/src/key.cpp (UserID::tofuInfo): New.
* lang/cpp/src/key.h: Update accordingly.
* lang/cpp/src/tofuinfo.cpp: Remove dropped fields.
@@ -1398,11 +2510,13 @@
2016-08-23 Werner Koch <wk@gnupg.org>
core: Put the protocol into a TOFU created key object.
+ + commit 2972c44bd7e97b2169dea9c4a49d9754afdae3f0
* src/verify.c (parse_tofu_user): Add arg 'protocol' and store it in
the KEY.
(_gpgme_verify_status_handler): Pass protocol.
core: Change the way TOFU information are represented.
+ + commit be4ff75d7d5ac6ed15feb245ef3cec59b4bad561
* src/gpgme.h.in (struct _gpgme_signature): Remove field 'tofu'. Add
field 'key'.
(struct _gpgme_key): Add field 'fpr'.
@@ -1420,6 +2534,7 @@
* tests/run-keylist.c (main): Print more fields.
core: Extend gpgme_user_id_t with 'address'.
+ + commit 3955dce06e9d056599e5ec7d40301e66b9305195
* src/mbox-util.c, src/mbox-util.h: Adjust for use in gpgme.
* src/Makefile.am (main_sources): Add mbox-util.
* src/key.c (_gpgme_key_append_name): Set 'address' field of uid.
@@ -1428,10 +2543,12 @@
2016-08-22 Werner Koch <wk@gnupg.org>
core: New code for parsing mail addresses.
+ + commit 26c5ba528ce1411d96655952ec48359105695c0f
* src/mbox-util.c: New.
* src/mbox-util.h: New.
core: Add new items for gpgme_get_dirinfo.
+ + commit 24e61984c9532924135c57b8ff98489a2d3bd4a3
* src/dirinfo.c (WANT_SYSCONFDIR, WANT_LIBEXECDIR, WANT_LIBDIR): New.
(WANT_DATADIR, WANT_LCOALEDIR, WANT_AGENT_SSH_SOCKET): New
(WANT_DIRMNGR_SOCKET): New.
@@ -1442,12 +2559,14 @@
(gpgme_get_dirinfo): Likewise.
core: Base gpgme_get_dirinfo(uiserver-socket) on the socket dir.
+ + commit c9e7dcb100d807583d8e312da459561138231376
* src/dirinfo.c (dirname_len): New.
(parse_output): Change computation of UISRV_SOCKET.
2016-08-21 Werner Koch <wk@gnupg.org>
core: New commands --lang and --have-lang for gpgme-config.
+ + commit 3e60788810f93cfcd7f08e5882aff32ed7b6f831
* configure.ac (GPGME_CONFIG_AVAIL_LANG): New ac_subst.
* src/gpgme-config.in (avail_lang): Add commands --lang and
--have-lang.
@@ -1455,16 +2574,19 @@
2016-08-18 Andre Heinecke <aheinecke@intevation.de>
core: Remove (now) useless diagnostic.
+ + commit 30f156280f18500ee522db58aecd40711c8af685
* src/w32-io.c(_gpgme_io_spawn): Remove spawnhelper not found
diagnostic.
core: Fail loudly in case w32 spawner not found.
+ + commit 9cf983b0199950c8f8cccee2cb8e45aafcba9fd1
* src/w32-io.c (_gpgme_io_spawn): Show a message box in
case gpgme-w32spawn.exe not found.
2016-08-17 Andre Heinecke <aheinecke@intevation.de>
Cpp: Fix some pedantic warnings.
+ + commit 64194b0f8df1afe6135cd119fd3216fc8db68033
* lang/cpp/src/context.cpp,
lang/cpp/src/context.h (Context::getKeysFromRecipients): Remove
ignored / invalid const qualifier.
@@ -1473,6 +2595,7 @@
2016-08-16 Werner Koch <wk@gnupg.org>
core: New global flag "require-gnupg".
+ + commit 8c09dd9989bcd434a8cb5997770cb8414b96bd5c
* src/gpgme.c (gpgme_set_global_flag): Add flag.
* src/engine.c (engine_minimal_version): New variable.
(_gpgme_set_engine_minimal_version): New function.
@@ -1481,6 +2604,7 @@
* tests/run-keylist.c (main): New option --require-gnupg.
core: Simplify setting of dummy versions.
+ + commit b7b0e7b5bfefd51c8092ea54f262b18aebf78128
* src/engine.c (_gpgme_engine_info_release): Do not assert but free
FILE_NAME.
(gpgme_get_engine_info): Provide default for VERSION and REQ_VERSION.
@@ -1496,15 +2620,18 @@
2016-08-12 Andre Heinecke <aheinecke@intevation.de>
Qt: Add test for progress signal of encryptjob.
+ + commit 391e55411cda11446ca9de4dd0dc2b54d3e6fff5
* lang/qt/tests/t-encrypt.cpp (testProgress): New.
Cpp: Provide size-hint for seekable and mem data.
+ + commit df7bbf5a66576a5a320b54c8f6ad52bc84f0e833
* lang/cpp/src/data.cpp (GpgME::Data::Data): Set size-hint for
mem and DataProvider based Data.
2016-08-12 Werner Koch <wk@gnupg.org>
core: Make use of the "size-hint" in engine-gpg.
+ + commit fe1e8e71aa18b4ac6471292b2894b8859f42f7c8
* src/engine-gpg.c: Include data.h.
(add_input_size_hint): New.
(gpg_decrypt, gpg_encrypt, gpg_encrypt_sign, gpg_sign)
@@ -1516,6 +2643,7 @@
size for the input data.
core: Add gpgme_data_set_flag to add more meta data to data objects.
+ + commit 293d1736911fd5e77b8cec305168b35b2420c612
* src/gpgme.h.in (gpgme_data_set_flag): New public function.
* src/data.c (gpgme_data_set_flag): New.
(_gpgme_data_get_size_hint): New.
@@ -1526,16 +2654,19 @@
2016-08-12 Andre Heinecke <aheinecke@intevation.de>
Qt: Fix defaultkeygenerationjob build.
+ + commit 75c974c4e0a31981325f7d151bd13f2523f5df20
* lang/qt/src/defaultkeygenerationjob.cpp: Include moc.
2016-08-11 Andre Heinecke <aheinecke@intevation.de>
Qt: Add DefaultKeyGenerationJob.
+ + commit 105f5446e69db00291164397cf0d8e68374cf420
* lang/qt/src/defaultkeygenerationjob.cpp,
lang/qt/src/defaultkeygenerationjob.h: New.
* lang/qt/src/Makefile.am: Update accordingly.
Qt: Ensure all public classes are exported.
+ + commit 59e2251a083b0ed61b3ab6d47015cef7cc6ceb05
* src/abstractimportjob.h,
src/cryptoconfig.h,
src/deletejob.h,
@@ -1551,6 +2682,7 @@
src/verifydetachedjob.h: Export classes.
Qt: Add KeyForMailboxJob.
+ + commit 8c5abc8d932affab4bc79a85e3f98f6f6b982ae8
* lang/qt/src/job.cpp: Include moc and make subclass.
* lang/qt/src/keyformailboxjob.h,
lang/qt/src/qgpgmekeyformailboxjob.cpp,
@@ -1564,6 +2696,7 @@
2016-08-10 Werner Koch <wk@gnupg.org>
doc: Get rid of version.texi.
+ + commit b7d99e02188b7907b09fec3032fc1fd82fc2668a
* configure.ac (CC_FOR_BUILD): New.
* doc/mkdefsinc.c: New. Taken from GnuPG and modified for gpgme.
* doc/Makefile.am (EXTRA_DIST): Add defsincdate and mkdefsinc.c
@@ -1574,14 +2707,17 @@
* doc/gpgme.texi: Include defs.inc. Remove version.texi.
build: Declare all languages for make dist.
+ + commit 48691db97b759d67aa7b49c36bb704b5806ade2e
* lang/Makefile.am (DIST_SUBDIRS): New.
core: Do not identify PNG files as PGP signatures.
+ + commit a9168185ba97aa1d827315cd8017899bf904aded
* src/data-identify.c (next_openpgp_packet): Blacklist PNG files.
2016-08-10 Andre Heinecke <aheinecke@intevation.de>
Cpp: Handle empty recipients consistently.
+ + commit 09667a6006986a782af98ca1de4d6521e1b8f353
* lang/cpp/src/context.cpp (Context::getKeysFromRecipients):
New helper.
(Context::encrypt, Context::startEncryption, Context::signAndEncrypt)
@@ -1590,41 +2726,50 @@
as private helper.
core: Handle ENCRYPT_SYMMETRIC also for sig & enc.
+ + commit b602d8bc7bd726afb52dc60cc07e4609e88d4511
* src/engine-gpg.c (gpg_encrypt_sign): Handle ENCRYPT_SYMMETRIC
flag.
Qt: Remove unused variable.
+ + commit d467018ce36f5be36751267c3b6079e8c1ee5d8a
* lang/qt/src/qgpgmerefreshkeysjob.cpp (slotStatus): Remove
unused variable typ.
Qt: Create TestPassphraseProvider on stack.
+ + commit a27d7755d071aad42efc2aa4ea3899ba7b17f8bf
* lang/qt/tests/t-encrypt.cpp, lang/qt/tests/t-tofuinfo.cpp: Create
TestPassphraseProvider on stack.
Cpp: Clarify ownership of provider classes.
+ + commit 21d5e71d486da8e37cf53f2b968646b39a6daa72
* lang/cpp/src/context.h: Note that the context does not take
ownership of providers.
2016-08-10 Justus Winter <justus@g10code.com>
tests: Fix memory leak.
+ + commit 04f994d5db6db0575dc73c2356c7d51424e2d9fe
* tests/gpg/t-encrypt-mixed.c (main): Free 'text2'.
2016-08-10 Andre Heinecke <aheinecke@intevation.de>
core: Ensure err is initalized in gpg_encrypt.
+ + commit 270887309f4b673b13e58c29ea3989c56989590e
* src/engine-gpg.c (gpg_encrypt): Initialize err.
Qt: Fix t-keylist moc include.
+ + commit 0c222e1b3cabe1a8b84a2877420cdd5df56171b5
* lang/qt/tests/t-keylist.cpp: Don't include t-support.moc
2016-08-09 Andre Heinecke <aheinecke@intevation.de>
Qt: Clean up debug output in tests.
+ + commit 969f223d8de21d7c8b0f7646bbf8dbb5864e8d03
* lang/qt/tests/t-support.cpp: Remove accidentally commited
debug output.
Qt: Add encryption test and refactor testsuite.
+ + commit f209ec8f581ae597b37f2e3a5e452e4b53b2d4c7
* lang/qt/tests/Makefile.am: Add t-encrypt and t-support.
* lang/qt/tests/t-support.cpp, lang/qt/tests/t-support.c (QGpgMETest):
New. Class to handle common cleanup / init.
@@ -1636,6 +2781,7 @@
encryption. Mixed encryption test is disabled.
Qt: Add support for EncryptJobs with generic flags.
+ + commit 34b456c3fb9e59788b07a75441da482bb28bda87
* lang/qt/src/encryptjob.h, lang/qt/src/signencryptjob.h,
lang/qt/src/qgpgmeencryptjob.h, lang/qt/src/qgpgmeencryptjob.cpp,
lang/qt/src/qgpgmesignencryptjob.cpp,
@@ -1643,14 +2789,17 @@
that accept generic EncryptFlags.
Cpp: Add support for all EncryptionFlags.
+ + commit 17372393798ea5e2d6838f3dd1e001dd4a66c941
* lang/cpp/src/context.h (EncryptionFlags): Extend.
* lang/cpp/src/context.cpp (encryptflags2encryptflags): Ditto.
Cpp: Fix simple symmetric encryption.
+ + commit bf776ce94cf454f1b3f1645b1cde09cd1c54324b
* lang/cpp/src/context.cpp (Context::encrypt): If no recipients
are provided encrypt with NULL and not an empty array.
core: Add support for mixed symmetric and asym enc.
+ + commit 3d2f027d0f40e7ec4ab48cee89ff0ee10b423566
* src/gpgme.h.in (gpgme_encrypt_flags_t): New flag
GPGME_ENCRYPT_SYMMETRIC.
* src/engine-gpg.c (gpg_encrypt): Also add --symmetric if the flag
@@ -1667,17 +2816,20 @@
2016-08-08 Werner Koch <wk@gnupg.org>
core: Let GPGME_PROTOCOL_ASSUAN pass Assuan comments through.
+ + commit b5e16b036f0045524a583d8a366d8a3366fc0005
* src/engine-assuan.c (llass_new): Set ASSUAN_CONVEY_COMMENTS,
2016-08-08 Andre Heinecke <aheinecke@intevation.de>
Prepend LD_LIBRARY_PATH for python tests.
+ + commit ab6f66d676581cb497e581e4af40e2fe5bff507b
* lang/python/tests/Makefile.am (TESTS_ENVIRONMENT): Prepend path
instead of setting the value.
2016-08-05 Justus Winter <justus@g10code.com>
python: Clean up and modernize examples.
+ + commit 2a613e87156b23c4aa6aa5ce38505cb285de6a18
* lang/python/examples/Examples.rst: Delete file.
* lang/python/examples/t-edit.py: Likewise. This is actually a test
case and has been moved to 'tests'.
@@ -1697,6 +2849,7 @@
2016-08-04 Werner Koch <wk@gnupg.org>
core: Extend gpgme_subkey_t to carry the keygrip.
+ + commit 6f3dc66634e30d86aa6250c4ac22f9b8f7ec1be9
* src/gpgme.h.in (struct _gpgme_subkey): Add file 'keygrip'.
* src/key.c (gpgme_key_unref): Free KEYGRIP.
* src/keylist.c (keylist_colon_handler): Parse GRP records.
@@ -1708,12 +2861,14 @@
2016-08-03 Justus Winter <justus@g10code.com>
python: Add a nicer interface to list keys.
+ + commit 56e26b54da9f16961209275d7a61883d3ea898ca
* lang/python/pyme/core.py (Context.keylist): New method.
* lang/python/tests/t-keylist.py: Test new method.
2016-08-02 Justus Winter <justus@g10code.com>
python: Add a flag identifying in-tree builds.
+ + commit 4c8265d32ddff5960a464b8d4e8d7d2258495b2e
* lang/python/helpers.c (pyme_in_tree_build): New variable.
* lang/python/helpers.h (pyme_in_tree_build): New declaration.
* lang/python/pyme/version.py.in (in_tree_build): New variable.
@@ -1721,27 +2876,28 @@
as appropriate.
python: Fix build system integration.
+ + commit 0bd7d8c1977183abc414e11aafa26a4f834ca2a5
* lang/python/Makefile.am: Be more careful when cleaning the build
directory, we must not delete the generated file 'pyme/version.py'.
doc: Document the Assuan protocol.
+ + commit 135185b7ef2225aa5e8c54a6cf1265d3e6cbbe48
* doc/gpgme.texi: Document the Assuan protocol.
- GnuPG-bug-id: 2407
-
2016-07-28 Justus Winter <justus@g10code.com>
python: Fix out-of-tree build.
+ + commit 4e728de8421e2ade2061786aaebcdae3f60da3b8
* lang/python/MANIFEST.in: Add 'private.h'.
- Fixes-commit: 3d4dc3f0
-
python: Improve error handling.
+ + commit 5a7c7a86f7e8eaf10e37138617a2d838f9d4466f
* lang/python/pyme/core.py (Context.protocol): Check that the engine
is usable before setting the protocol.
(Context._errorcheck): Add missing functions.
src: Fix dummy engine versions.
+ + commit b9e6eacd06ffeb36854c208aa4325cff3e3dfbbe
Previously, 'gpgme_engine_check_version' failed for these protocols
because the version parser failed to parse the dummy versions.
@@ -1754,6 +2910,7 @@
(uiserver_get_req_version): Likewise.
python: Drop superfluous imports and trim public interface.
+ + commit 2ff58fcbd5c060dac3a7feec478819d2c5a164ec
* lang/python/pyme/__init__.py: Avoid leaking low-level 'gpgme', make
sure the main module looks nice and tidy, appease pyflakes.
* lang/python/pyme/errors.py: Appease pyflakes.
@@ -1766,6 +2923,7 @@
* lang/python/tests/t-signers.py: Likewise.
python: Rename compiled SWIG module.
+ + commit 2f754440f28e8f81babdf7efa6186edbc8ad99fd
Avoid the name pygpgme, as this is the name of another popular Python
binding for GPGME.
@@ -1780,6 +2938,7 @@
* lang/python/setup.py.in: Likewise.
python: Rename exported functions.
+ + commit b5aa05c3b261c3846ebbcf76e7505cff5459f918
Avoid the name pygpgme, as this is the name of another popular Python
binding for GPGME.
@@ -1791,6 +2950,7 @@
* lang/python/pyme/core.py: Likewise.
python: Rename private functions.
+ + commit 1d2f22aae668ce136cacd254875e118dc1faa6a2
Avoid the name pygpgme, as this is the name of another popular Python
binding for GPGME.
@@ -1804,6 +2964,7 @@
prototypes here.
python: Support the Assuan engine.
+ + commit de69fa496c09386d5e99747670d6887cf52dd09e
* lang/python/gpgme.i: Add typemaps for the Assuan protocol callbacks.
* lang/python/helpers.c (_pyme_assuan_{data,inquire,status}_cb): New
functions.
@@ -1815,17 +2976,20 @@
* lang/python/tests/t-protocol-assuan.py: New file.
python: Improve engine information handling.
+ + commit 355d7072863ac1f0f725e77141a59f3ed8a5e4af
* lang/python/gpgme.i (gpgme_engine_info_t): Wrap engine infos.
* lang/python/pyme/core.py (Context.engine_info): New property.
(Context.{g,s}et_engine_info): Improve docstrings.
* lang/python/pyme/results.py (EngineInfo): New class.
python: Add accessors for the protocol.
+ + commit 78f7bf4dcf75206faae5776c2ee4166628313532
* lang/python/pyme/core.py (Context.__init__): Add 'protocol'
parameter.
(Context.protocol): New accessors.
python: Expose less functions to the Python world.
+ + commit 3d4dc3f0218234a27103bdb6f93b17c0703b71a2
* lang/python/Makefile.am (EXTRA_DIST, COPY_FILES): Add new file.
* lang/python/gpgme.i: Include new file and add comments.
* lang/python/helpers.c: Include new file.
@@ -1835,14 +2999,17 @@
2016-07-19 Ben Kibbey <bjk@luxsci.net>
Fix including nil bytes in keylist output.
+ + commit 6a7ee33abd5059f5ae2f70a7dd9f610c16552f8e
* src/gpgme-tool.c (cmd_keylist,gt_result): use strlen().
2016-07-15 Justus Winter <justus@g10code.com>
python: Make GPGME's version easily accessible.
+ + commit e545ca3f682b615ce447c186a2c73489a32b0592
* lang/python/pyme/version.py.in (gpgme_versionstr): New variable.
python: Add an idiomatic interface.
+ + commit 1f318b7aaaa77672fab117d54fe75221780df83c
* configure.ac: Bump required Python version.
* lang/python/pyme/__init__.py: Update docstring. Import Context and
Data.
@@ -1877,33 +3044,40 @@
2016-07-14 Andre Heinecke <aheinecke@intevation.de>
Qt: Disable keylocate test for gnupg < 2.0.10.
+ + commit d2f2cbd297c4d2f2c3264ecc3ffb7a2b3a70bd55
* lang/qt/tests/t-keylocate.cpp: Disable test for gnupg < 2.0.10
Cpp: Add EngineInfo::Version class.
+ + commit 41de1ab904eaddffb2de17b1de8ef41e462daabe
* lang/cpp/src/engineinfo.cpp (EngineInfo::engineVersion): New.
* lang/cpp/src/engineinfo.h (EngineInfo::engineVersion): Declare.
(EngineInfo::Version): Small helper to work with versions.
Qt: Fix usage of ignore-invalid-option in tests.
+ + commit e7f4c364732660c6cda25720b7dbc5b1c917e368
* Makefile.am (pubring-stamp): Fix config.
Qt: Fix tests if gpg2 is gpg.
+ + commit e4c0645c1eea9380d80a20895eb83c9dd7228776
* lang/qt/tests/Makefile.am (pubring-stamp): Loopback and provide
passphrase on command line when importing.
2016-07-14 Justus Winter <justus@g10code.com>
python: Fix test.
+ + commit fddcc62abd57cb04e84861abd3991c7d529c2464
* lang/python/tests/t-keylist.py: Do not assume key alpha is trusted
yet.
2016-07-13 Werner Koch <wk@gnupg.org>
build: Update config.{guess,sub} to {2016-05-15,2016-06-20}.
+ + commit a9670d152a4598aef1ae0960a79fb6f5d8db55ad
* build-aux/config.guess: Update.
* build-aux/config.sub: Update.
core: New GPGME_DATA_ENCODING_MIME.
+ + commit d8d5f5a16712244fe6eff860b6ac5f007b1bf870
* src/gpgme.h.in (GPGME_DATA_ENCODING_MIME): New.
* src/data.c (gpgme_data_set_encoding): Adjust check.
* src/engine-gpg.c (have_gpg_version): New.
@@ -1916,6 +3090,7 @@
* src/gpgme-tool.c (server_data_encoding): Add flag --mime.
core: Pass the engine's version string to the engine's new function.
+ + commit 2095b1573a8196ba3efdf817324d1b3ee05cbb93
* src/engine-backend.h (engine_ops): Add arg 'version' to NEW.
* src/engine-assuan.c (llass_new): Add dummy arg 'version'.
* src/engine-g13.c (g13_new): Ditto.
@@ -1932,6 +3107,7 @@
2016-07-13 Andre Heinecke <aheinecke@intevation.de>
Cpp: Add feature enum for new identify.
+ + commit 537cb871fd59f3a20c697a046715e6339ff6633b
* lang/cpp/src/context.cpp (supported_features2): Add
BinaryAndFineGrainedIdentify
* lang/cpp/src/global.h (Feature2): ditto.
@@ -1939,6 +3115,7 @@
2016-07-12 Justus Winter <justus@g10code.com>
python: Port more tests.
+ + commit 1bff47ee58bcf9d0016fb7ac7e37cbf075abd059
* lang/python/pyme/core.py (Context.op_keylist_all): Add missing
'op_keylist_end'.
(Context.op_trustlist_all): Fix function. Add missing
@@ -1949,52 +3126,63 @@
* lang/python/tests/t-trustlist.py: Check alternate interface.
python: Improve python packaging.
+ + commit 57b51685528153f5a50ab0999feec25c83190501
* lang/python/Makefile.am: Sign source releases, and upload them.
* lang/python/setup.py.in: Add categories.
2016-07-12 Andre Heinecke <aheinecke@intevation.de>
m4: Don't set fpic for qt on windows.
+ + commit 938f7e9c8b466594d05c0347fe627b225263a6a6
* m4/qt.m4 (FIND_QT): Do not set fpic for windows.
m4: Use LIBS instead of LDFLAGS for Qt libs.
+ + commit 744978cce8f9dfb2363b9d274ee99f25cfcf0e40
* m4/qt.m4: Modify LIBS instead of LDFLAGS for link test.
Bump version to 1.7.0.
+ + commit bf742fb88545689addfca18192baf2f56a1895e1
* configure.ac(mym4_version_minor),
(mym4_version_micro): Next release will be 1.7.0
Qt: Install CamelCase forward includes.
+ + commit fd87c4679c4bfe19390fa2047dff23bb213a4b18
* lang/qt/src/Makefile.am (camelcase_headers): New. Create and install
CamelCase headers.
Qt: Export VerifyDetachedJob.
+ + commit 86ab2ee2d603111d24500b8d64a9a1dd82f8bdc0
* lang/qt/src/verifydetachedjob.h (VerifyDetachedJob): Export it.
Qt/Cpp: Add version headers.
+ + commit b03c48cfb06faae7d7033a0532f319cbcf13f18a
* lang/cpp/src/gpgmepp_version.h.in,
lang/qt/src/qgpgme_version.h.in: New. Version information.
* lang/qt/src/Makefile.am, lang/cpp/src/Makefile.am: Add them.
* configure.ac: Configure them.
Qt/Cpp: Add license blurb to export headers.
+ + commit 362b8cdf4e0d5cd54ec2b325508dcdefac686f2c
* lang/cpp/src/gpgmepp_export.h,
lang/qt/src/qgpgme_export.h: Add license blurb.
2016-07-11 Justus Winter <justus@g10code.com>
python: Fix distcheck.
+ + commit ce662891373eba6cce1cf8df516cb2370970737e
* lang/python/Makefile.am (EXTRA_DIST): Add missing files.
2016-07-11 Andre Heinecke <aheinecke@intevation.de>
m4: Add compile / link check for qt.
+ + commit ed070313155a1c79a57ba69f4299f2aefc65fad7
* m4/qt.m4 (FIND_QT): Check if a qt application can be compiled and
linked.
2016-07-11 Justus Winter <justus@g10code.com>
python: Enable out-of-tree build of pyme bindings.
+ + commit 007382ce94a6318557370c440f7d609a030a119e
* lang/python/MANIFEST.in: Update manifest template.
* lang/python/Makefile.am: Copy more files, move generation of files
to Python build script, add 'sdist' target to build a Python source
@@ -2003,16 +3191,19 @@
* lang/python/setup.py.in: Generate files, enable out-of-tree builds.
python: Do not depend on access to internal data structures.
+ + commit 98cba522c906115efcba1f8cc0bec7e5edb51ecd
* lang/python/gpgme.i (gpgme_data_t): Rework so that it works without
access to the definition of 'struct gpgme_data'.
* lang/python/helpers.c (object_to_gpgme_data_t): Add assertion.
python: Make result wrapping backwards compatible.
+ + commit c53f87c5f9ca63119152f41dcebfb175d4df2cef
* lang/python/pyme/results.py (Result.__init__): Skip missing fields.
2016-07-11 Andre Heinecke <aheinecke@intevation.de>
Qt: Fix memleaks in tests.
+ + commit bfa8ac7e02c16790ee5bd3b42c26699f4821d72e
* lang/qt/tests/t-keylist.cpp(cleanupTestCase): Ensure that
posted events are handled for autodeletion.
(testSingleKeylistSync): delete job.
@@ -2022,18 +3213,22 @@
* lang/qt/tests/t-keylocate.cpp(cleanupTestCase): Ditto
Qt: Add some general Protocol documentation.
+ + commit b1f42e8f25ada220ec8e4762cfebc3a49b1f7d56
* lang/qt/src/protocol.h (Protocol): Add doc.
Qt: Disable t-tofuinfo tests.
+ + commit 02babb29612d554c37b63a49f78acc45653b557e
* lang/qt/tests/t-tofuinfo.cpp: Disable tests.
2016-07-08 Justus Winter <justus@g10code.com>
src: Fix error handling.
+ + commit de74fe59feef9adc858ac04004880bfd44315d0d
* src/encrypt.c (encrypt_status_handler): Fix error handling, ||
conflates errors.
python: Fix raising stashed exceptions.
+ + commit 8a93f345b701332270c9829a4d0a93537f98a8d8
Fixes an issue with newer versions of Python.
* lang/python/helpers.c (pygpgme_raise_callback_exception): Be more
@@ -2042,6 +3237,7 @@
2016-07-07 Justus Winter <justus@g10code.com>
python: Fix distcheck.
+ + commit 52efcf1ee9fc8ba4c6bd23d8fe4f5f7993ba9fb1
* lang/python/INSTALL: Drop obsolete file.
* lang/python/Makefile.am (EXTRA_DIST): Add missing files.
(CLEANFILES): Remove generated files.
@@ -2053,80 +3249,96 @@
* lang/python/tests/initial.py: Likewise.
qt: Fix distcheck.
+ + commit 38c408560c6ebc3ea5eeeade01d38750bf5799e5
* lang/qt/src/Makefile.am (qgpgme_headers): Add missing file.
(CLEANFILES): Add generated file.
* lang/qt/tests/Makefile.am (clean-local): Remove private keys.
cpp: Fix distcheck.
+ + commit 49286ac1c82c480e2c718f828c57da9778ccd0b9
* lang/cpp/src/Makefile.am (CLEANFILES): Remove generated file.
2016-07-06 Andre Heinecke <aheinecke@intevation.de>
Qt: Add test for publicKeyAlgorithmAsString.
+ + commit fc0267233239b42e9fb74a8acd7511503e287a9e
* lang/qt/tests/t-keylist.cpp (testPubkeyAlgoAsString): New.
Cpp: Expose gpgme_pubkey_algo_name.
+ + commit e41ae4db9e70d9aebf80ebbd4ce03977435c2ccf
* lang/cpp/src/key.cpp (Subkey::publicKeyAlgorithmAsString): New
static variant.
* lang/cpp/src/key.h: Declare function. Clarify comment about name
mismatch.
Qt: Add check for pubkeyAlgo in t-keylist.
+ + commit 9f93346d21271b916f15d80420669f5d659a40de
* lang/qt/tests/t-keylist.cpp (testSingleKeyListSync): Check
pubkeyAlgo.
Cpp: Add PubkeyAlgo enum.
+ + commit c28007d0407bcc3621b8266d6d77eb0d069aec35
* lang/cpp/src/key.h (Subkey::PubkeyAlgo): New enum.
(Subkey::publicKeyAlgorithm): Change return type.
* lang/cpp/src/key.cpp (Subkey::publicKeyAlgorithm): Use enum.
Qt: Fix include order when buildin test.
+ + commit 4934893e27a50f5715dcd4d2907ecbe629921b32
* lang/qt/tests/Makefile.am (AM_CPPFLAGS): Include cpp before
gpgme src directory.
Revert "Qt: More robust lookup of Cpp's context.h"
+ + commit 7a8c04f66d382dc49d962ad18c46d7ad332ccc0f
* lang/qt/src/threadedjobmixin.h: Revert using full path
for context.h
2016-07-05 Andre Heinecke <aheinecke@intevation.de>
Qt: Fix test build with Qt < 5.4.0.
+ + commit 49a6ee50587c9d4b6f07e60ce1a939c863e7f15c
* lang/qt/tests/t-keylist.cpp,
lang/qt/tests/t-keylocate.cpp,
lang/qt/tests/t-ownertrust.cpp: Use old style SIGNAl syntax for
QSignalSpy
Qt: More robust lookup of Cpp's context.h.
+ + commit 47bfbc9026b49b9918359af5fcc1621aab0d1065
* lang/qt/src/threadedjobmixin.h: When building qgpgme look for
context.h in the full cpp subdirectory.
w32: Fallback to 2.1 reg key for gpgconf search.
+ + commit 72b83ffc4d7581f4efef3bd7c261d7d7424bcf0e
* src/w32-util.c (_gpgme_get_gpgconf_path): Fallback to 2.1 installer
registry key.
2016-07-04 Andre Heinecke <aheinecke@intevation.de>
Doc: Document pinentry mode.
+ + commit 329ab93f7ed862d7f4c0501fca5355936a74ac52
* doc/gpgme.texi (Passphrase Callback): Document as context
attribute.
(gpgme_set_passphrase_cb): Note that this requires LOOPBACK mode
with GnuPG 2.1.
Qt: Add testTofuSignCount.
+ + commit 8fa9b5696ca9f8386971e6f36646536f9579ceaa
* src/lang/qt/tests/t-tofuinfo.cpp(testTofuSignCount): New.
(initTestCase): Set gpg-agent loopback pinentry config.
(signAndVerify): Helper for tofuTestSignCount.
Qt: Add test passphrase provider.
+ + commit efb5059b9b6e81db7b0c016aa9fb70abe98308ea
* lang/qt/tests/t-support.h (TestPassphraseProvider): New.
* lang/qt/tests/Makefile.am (t_tofuinfo_SOURCES): Add t-support.h
Cpp: Add support for TOFU_CONFLICT sigsum.
+ + commit 80498ab662238a31325e78c0037ea6752f680a37
* lang/cpp/src/verificationresult.cpp (GpgME::Signature::Summary):
Handle TOFU_CONFLICT.
* lang/cpp/src/verificationresult.h (Summary): Add TofuConflict.
Cpp: Add support for pinentry_mode.
+ + commit d75c118aae18e20f08dbbb69c7998e1f3694ccd0
* lang/cpp/src/context.cpp (Context::pinentryMode): Return mode.
(Context::setPinentryMode): Set mode.
* lang/cpp/src/context.h (PinentryMode): Add enum.
@@ -2134,10 +3346,12 @@
2016-07-01 Andre Heinecke <aheinecke@intevation.de>
Qt: Add test for TofuInfo.
+ + commit fbd6ac4655ebf56d91ebd9a4ff499c8319fcd087
* lang/qt/tests/t-tofuinfo.cpp: New.
* lang/qt/tests/Makefile.am: Update accordingly.
Cpp: Add TofuInfo to signatures.
+ + commit 93c5d420fcfe275aeff2b3d5ce99629edbe6625d
* lang/cpp/src/tofuinfo.cpp, lang/cpp/src/tofuinfo.h: New class.
* lang/cpp/src/verificationresult.cpp (Signature::tofuInfo): New.
(VerificationResult::Private): Handle tofu info.
@@ -2149,36 +3363,43 @@
* configure.ac (LIBGPGMEPP_LT_REVISION): Bump for new API.
core: Clarify documentation of tofu_stats address.
+ + commit 948ce7d1edf12ecb5080a4816ca15f495d6393f5
* src/gpgme.h.in: Mention that Address is not always in addr-spec.
core: Fix identify for armored detached sigs.
+ + commit 570bf2a648f14b34c4c45d3890b7300529a82d37
* src/data-identify.c (basic_detection): Return signature for
signature.
2016-06-27 Andre Heinecke <aheinecke@intevation.de>
Cpp: Expose new data_identify values.
+ + commit 15fc5c34c88ecbb61272705af60f7054b41c57f7
* lang/cpp/src/data.cpp (GpgME::Data::type): Handle PGP Encrypted
and Signature.
* lang/cpp/src/data.h: Add values accordingly.
Cpp: Do not treat KEYEXPIRED as error.
+ + commit 82d484c852d07958ac93efb3d2d7b7726fbb5231
* lang/cpp/src/editinteractor.cpp (status_to_error): No error
for KEYEXPIRED.
2016-06-24 Andre Heinecke <aheinecke@intevation.de>
tests: Add new test tool run-decrypt.
+ + commit 3364549c19682f56d4d9c52ab7f76862c5a456cf
* tests/run-decrypt.c: New.
* tests/Makefile.am (noinst_PROGRAMS): Add run-decrypt.
2016-06-23 Werner Koch <wk@gnupg.org>
core: Add closer inspection of "PGP MESSAGE".
+ + commit cf37a57d28c43ec36277e84ca44458b7287b940b
* src/data-identify.c (inspect_pgp_message): New.
(basic_detection): Un-const arg DATA. Call inspect_pgp_message.
core: Add a base 64 decoder.
+ + commit f8b8027ae63c957557ed6bdc7e5a30ef1bdd8e77
* src/b64dec.c: New. Taken from gnupg. Prefix function names with
_gpgme_ and change to use standard C malloc functions.
* src/util.h.h (struct b64state): New.
@@ -2187,17 +3408,20 @@
2016-06-22 Werner Koch <wk@gnupg.org>
core: Detect compressed signed OpenPGP data.
+ + commit bb8cf6236582fc9eb6564046599989af52779a26
* src/data-identify.c (next_openpgp_packet): Allow partial encoding.
(pgp_binary_detection): Handle compressed packets.
2016-06-21 Werner Koch <wk@gnupg.org>
tests: Add new test tool run-identify.
+ + commit 5905e8bbd809c1408edad4fa4eb0527fa51cbea3
* src/gpgme-tool.c (gt_identify): Add new strings.
* tests/run-identify.c: New.
* tests/Makefile.am (noinst_PROGRAMS): Add run-identify.
core: Enhance gpgme_data_identify to detect binary PGP messages.
+ + commit 32d4bbf5e3e5f88e4a6852d72a35ee30df9d5279
* src/gpgme.h.in (GPGME_DATA_TYPE_PGP_ENCRYPTED): New.
(GPGME_DATA_TYPE_PGP_SIGNATURE): New.
* src/data-identify.c: Add enum for OpenPGP packet types.
@@ -2211,11 +3435,13 @@
2016-06-16 Justus Winter <justus@g10code.com>
python: Improve autmatically generated docstrings.
+ + commit 8997d88bf97d1784706becbf8e9dc74e4656e311
* lang/python/gpgme.i: Add comment.
* lang/python/pyme/core.py (__getattr__): Rewrite automatically
generated doctrings for the wrapper methods.
python: Make result objects more robust.
+ + commit a324d0cffe93cab955698c2c065b2f2227e379e4
Results returned by the GPGME are fragile, i.e. they are only valid
until the next operation is performed in the context.
@@ -2229,16 +3455,19 @@
* lang/python/pyme/results.py: New file.
python: Avoid creating SWIG proxy classes.
+ + commit 856bcfe2934237011984fab0bc69800a7c25c34b
* lang/python/Makefile.am (gpgme_wrap.c): Use '-builtin' to make SWIG
generate builtin types for c types.
* lang/python/gpgme.i (pygpgme_wrap_gpgme_data_t): Adapt slightly.
python: Simplify wrapping glue.
+ + commit 6641c7814b30e3e8f18105b2636545cc1bd07552
* lang/python/pyme/core.py: Rename '_getctype' to '_ctype' and turn it
into a string. Likewise rename '_getnameprepend' to '_cprefix'.
* lang/python/helpers.c: Adapt accordingly.
python: Rework callbacks.
+ + commit f3618bc615e3eff1f52fb5849cbf0f0b95515a61
Simplify how the lifetime of callback arguments is managed.
* lang/python/gpgme.i (gpgme_edit_cb_t): Check arguments.
@@ -2262,6 +3491,7 @@
* lang/python/pyme/core.py (Context, Data): Update callsites.
python: Wrap objects implementing the buffer protocol.
+ + commit 616929b6edf00b4a774b727385d39b785a112b90
* lang/python/Makefile.am: Add the toplevel source directory to CFLAGS
when compiling the bindings so that we can use private header files.
* lang/python/gpgme.i (gpgme_data_t): Rework the object wrapping. Do
@@ -2276,6 +3506,7 @@
* lang/python/tests/t-idiomatic.py: Demonstrate this.
python: Add properties to wrapped object.
+ + commit 5464060baef2da8f5ea377118758e451c55e3787
* lang/python/pyme/core.py (GpgmeWrapper.__repr__): Saner
representation.
(GpgmeWrapper.__str__): Construct a nicer human readable string.
@@ -2290,6 +3521,7 @@
them.
python: Improve the documentation.
+ + commit 5492853d7b84b4e1d0b11b234e32252ba8d1608d
* lang/python/Makefile.am: Copy the README file.
* lang/python/README: Rename, convert to org, and update.
* lang/python/pyme/__init__.py: Move license out of the docstring,
@@ -2297,6 +3529,7 @@
* lang/python/pyme/core.py: Add and update docstrings.
python: Get version information from the build system.
+ + commit 7eef399d89d4c3877cb795ed5ba45ecb241e67be
* configure.ac: Generate 'setup.py' and 'version.py'.
* lang/python/Makefile.am: Use generated setup script.
* lang/python/pyme/version.py: Turn it into a template, and get
@@ -2305,9 +3538,11 @@
version module, which is frowned upon and actually caused a problem.
python: Fix exception leak.
+ + commit a852f99a0ac9dc7f7493b403f811f5f7518fae40
* lang/python/helpers.c (pygpgme_stash_callback_exception): Fix leak.
python: Fix license.
+ + commit 3bacce03e60dc45cc2da99a2f5c504612202e802
Other parts of the build system are also LGPLed.
* lang/python/Makefile.am: Fix license.
@@ -2315,27 +3550,33 @@
2016-06-14 Werner Koch <wk@gnupg.org>
core: Make sure FD_SET is not used with an out of range fd.
+ + commit 8173c4f1f8a145c4b1d454f6f05e26950e23d675
* src/posix-io.c (_gpgme_io_select): Check for FD out of range.
2016-06-08 Justus Winter <justus@g10code.com>
python: Improve error handling.
+ + commit 77d149e8614c381458e07808a7930ce3fb92cdc3
* lang/python/helpers.c (pyPassphraseCb): Handle write errors.
(pyEditCb): Likewise.
python: Add function to raise exceptions from c.
+ + commit 5ebc205439cac266685d2532466df8b3457dea23
* lang/python/helpers.c (pygpgme_raise_exception): New function.
python: Fix stripping deprecated functionality.
+ + commit 8426304b67a0b0a5630db500abf740b0e0b9e43c
* lang/python/Makefile.am (gpgme.h): Add script as input.
* lang/python/gpgme-h-clean.py (deprec_func): Also match struct
members.
(line_break): Fix matching on struct members.
python: Fix type.
+ + commit 990492ea4f7dafbb75de15ea91c30cbf090034b5
* lang/python/gpgme.i: Use correct Python type for size.
python: Implement the context manager protocol.
+ + commit e3c5913a33edcbd7329b8d154c669f95ce782038
* lang/python/pyme/core.py (Context.__del__): Make function
idemptotent.
(Context.{__enter__,__exit__}): Implement the context manager
@@ -2348,6 +3589,7 @@
2016-06-07 Justus Winter <justus@g10code.com>
python: Fix error handling.
+ + commit f8f9bf06bc3190968ba6613032d60a3bf2c8a6d9
* lang/python/gpgme.i: Fix freeing an uninitialized pointer in the
error handling of generated wrapper functions by explicitly storing
the pointer in a local variable which can be initialized.
@@ -2355,6 +3597,7 @@
2016-06-06 Justus Winter <justus@g10code.com>
python: Wrap file-like objects on demand.
+ + commit 8196edf9ca5c8f2f02553e7f22d9c79dbd229882
* lang/python/gpgme.i (gpgme_data_t): Use new function to create
wrapper objects if necessary, and deallocate them after the function
call.
@@ -2364,25 +3607,30 @@
* lang/python/tests/t-idiomatic.py: New file.
python: Move helper function.
+ + commit 26c3accc95ab77ddbe60db822e2938ad5f480d41
* lang/python/gpgme.i (object_to_gpgme_t): Move...
* lang/python/helpers.c: ... here.
* lang/python/helpers.h (object_to_gpgme_t): New prototype.
python: Fix error handling.
+ + commit 89eb0cd4d65bc033ed6342810b26232797482d64
* lang/python/gpgme.i (object_to_gpgme_t): Properly propagate
exceptions.
python: Initialize GPGME for the user.
+ + commit ae06f7c2fe0e49baeab5a827dc38ba8c57a6404c
* lang/python/pyme/core.py: Call 'check_version' and explain why.
* lang/python/tests/support.py (init_gpgme): Drop call here.
2016-06-01 Justus Winter <justus@g10code.com>
python: Fix test suite with GnuPG prior to 2.1.12.
+ + commit bbf19124bbec9eb6298cef2914baae7ac74382fe
* lang/python/tests/Makefile.am (gpg-agent.conf): Use
'allow-loopback-pinentry'.
python: Make Python detection more robust.
+ + commit 1607aa7fe5dd686ba3bfb6de4a2b602d6a458c86
Previously, missing Python development packages made configure fail
instead of merely disabling the bindings.
@@ -2390,6 +3638,7 @@
* m4/ax_python_devel.m4: Make test non-fatal.
python: Improve build system integration, fix warnings.
+ + commit 73c47535b631a55687ecc5eff1d1d9a9fd71021e
* lang/python/Makefile.am: Pass CFLAGS to python build system.
* lang/python/helpers.c (pyPassphraseCb): Use correct type for length.
(pygpgme_data_new_from_cbs): Drop unused variable.
@@ -2397,25 +3646,27 @@
2016-06-01 Andre Heinecke <aheinecke@intevation.de>
Cpp: Use whitelist for status messages.
+ + commit 54314a9c7d7ad52981c836ca742644a1fa69b518
* lang/cpp/src/editinteractor.cpp (EditInteractor::needsNoResponse):
Use whitelist instead of blacklist.
Qt: Fix debug output in t-ownertrust.
+ + commit 9d6f85bd25e51445f1776b498875e77b529311b1
* lang/qt/tests/t-ownertrust.cpp (testChangeOwnerTrust): Remove
general debug of trust level. Add debug output for error.
2016-06-01 Justus Winter <justus@gnupg.org>
tests: Fix notation tests.
+ + commit c88c9ef384b6f7bda9a61b58f26c2f89ae25f684
* lang/python/tests/t-sig-notation.py (check_result): Check critical
flag.
* tests/gpg/t-sig-notation.c (check_result): Likewise.
- Fixes-commit: 1cacd7d0
-
2016-06-01 Werner Koch <wk@gnupg.org>
core: Set notation flags for verify.
+ + commit 1cacd7d00a7b3de4a5e11ccce5ee6c50e0a5516d
* src/gpgme.h.in (GPGME_STATUS_NOTATION_FLAGS): New.
* src/status-table.c (status_table): Add new status.
* src/verify.c (parse_notation): Handle flags. Also fix NOTATION_DATA
@@ -2426,6 +3677,7 @@
2016-05-31 Tobias Mueller <muelli@cryptobitch.de>
python: use GPG_ERROR_CONFIG variable.
+ + commit 8ad17f402f6420880dcf06a13a54feadb52c0208
instead of calling gpg-error-config.
This is useful when configuring with --with-gpgerror-prefix
because then GPG_ERROR_CONFIG contains the correct
@@ -2436,6 +3688,7 @@
2016-05-31 Justus Winter <justus@gnupg.org>
python: Port more tests.
+ + commit afa0dd56e1cce64fe08bff3c64b12aecce54fd2d
* lang/python/gpgme.i: Hide length fields of notations.
* lang/python/tests/Makefile.am (pytests): Add new tests.
* lang/python/tests/t-decrypt-verify.py: New file.
@@ -2445,12 +3698,14 @@
2016-05-27 Werner Koch <wk@gnupg.org>
Speedup closing of fds before exec.
+ + commit 89d22f9229f2ecd559ac6ea91dae60eeff940fa5
* src/posix-io.c [__linux__]: Include dirent.h.
(get_max_fds) [__linux__]: Try to figure out the highest used fd.
2016-05-27 Justus Winter <justus@gnupg.org>
python: Port more tests.
+ + commit 3915842657f0849a038752fd7445f96081a89dd9
* lang/python/pyme/core.py (Data._error_check): Add
'gpgme_data_get_file_name' to the list of functions not returning an
error code.
@@ -2462,6 +3717,7 @@
* lang/python/tests/t-trustlist.py: Likewise.
python: Implement data callbacks.
+ + commit 2ae847c02731994d99e69d3d025ff01f41406452
* lang/python/gpgme.i (object_to_gpgme_t): Set exception on error.
* lang/python/helpers.c (pyDataReadCb): New function.
(pyDataWriteCb): Likewise.
@@ -2481,6 +3737,7 @@
* lang/python/tests/t-data.py: Likewise.
python: Fix object deallocation.
+ + commit ebfe2300c33a3bad311e9ac1530e6c92636a08a4
Handing a reference to the wrapper object created a non-trivial
circular reference that Pythons garbage collector is unable to break.
Explicitly break it by using a weak reference.
@@ -2494,11 +3751,13 @@
(Context.op_edit): Likewise.
Improve comments.
+ + commit e74cd9fb80f12b764d5e4561e73d55644147e9e7
* src/gpgme.h.in (gpgme_data_seek_cb_t, gpgme_data_seek): Clarify that
these functions return the new offset.
(gpgme_data_release_cb_t): Fix name of parameter.
python: Fix reading data from existing files.
+ + commit bf188e280b8b4fc775f33c47e2e1e275ed044004
* lang/python/pyme/core.py (Data.__init__): Add 'copy' kwargument, and
pass it to functions supporting it. PEP8 fix.
(Data.new_from_fd): PEP8 fix.
@@ -2511,11 +3770,13 @@
2016-05-25 Justus Winter <justus@gnupg.org>
src: Fix trace string.
+ + commit ce73ae9d0cbf782cd3a1949fc4f568f0d1da60d9
* src/data-compat.c (gpgme_data_new_from_file): Fix trace string.
2016-05-24 Justus Winter <justus@gnupg.org>
python: Improve and test Context.wait.
+ + commit 00ff6d07330028da370c869e3ec442eb76f8cbb8
* lang/python/pyme/core.py (Context.wait): Improve docstring. As the
context passed to 'gpgme_wait' is never NULL, it is pointless to look
at the returned context. Always raise exceptions.
@@ -2523,15 +3784,18 @@
* lang/python/tests/t-wait.py: New file.
python: Make all GnuPG errors available.
+ + commit 7bc9cc717e428f48d4b27016f44c9f3900b1fba6
* lang/python/Makefile.am (errors.i): Generate file.
* lang/python/gpgme.i: Include generated file.
* lang/python/pyme/errors.py: Pull in all errors and error sources.
python: Move the base wrapper class.
+ + commit 0ebd6a1b43a96bffa78da89dc8629edac0a74d35
* python/lang/pyme/util.py (GpgmeWrapper): Move...
* python/lang/pyme/core.py: ... here.
python: Support status callbacks.
+ + commit 8b57f06e0c04f5c9b87a3c76618230d757412076
* lang/python/helpers.c (pyStatusCb): New function.
(pygpgme_set_status_cb): Likewise.
* lang/python/helpers.h (pygpgme_set_status_cb): New prototype.
@@ -2542,21 +3806,25 @@
* lang/python/tests/t-callbacks.py: Test status callbacks.
python: Improve docstring.
+ + commit 72afb68f8c2f0cb326f20b289215402fd849339d
* lang/python/pyme/core.py (Context.set_progress_cb): Improve
docstring.
2016-05-24 Andre Heinecke <aheinecke@intevation.de>
Qt: Fix test build with clang.
+ + commit 00e93b2cae0585ff10425421d9097a846943b21c
* lang/qt/tests/Makefile.am (LDADD): Explicitly add -lstdc++
Cpp: Set -std=c++11 also if CXXCPP is already set.
+ + commit b107fc8a92bd16bc0d868c771b6334d6594e6395
* m4/ax_cxx_compile_stdxx.m4 (AX_CXX_COMPILE_STDCXX): Set CXXCPP if
neccessary.
2016-05-24 Justus Winter <justus@gnupg.org>
python: Improve support for edit callbacks.
+ + commit 09803c4a81b9431fd4c8f30abb1c60c4c735f0cb
* lang/python/helpers.c (pyEditCb): Stash exceptions.
* lang/python/pyme/core.py (Context.op_edit): Hand in 'self'.
* lang/python/tests/Makefile.am (py_tests): Add new test.
@@ -2566,15 +3834,18 @@
2016-05-23 Justus Winter <justus@gnupg.org>
python: Fix hook.
+ + commit 283f0bdc3d32624dac93d02ba3df516e69d8d4ba
* lang/python/helpers.c (pyProgressCb): Fix getting hook data.
* lang/python/tests/t-callbacks.py: Show that this works.
python: Move edit callback function.
+ + commit 5476ca6813fc9d8833d5224f19d4bb7515380ab5
* lang/python/gpgme.i (pyEditCb): Move...
* lang/python/helpers.c: ... here.
* lang/python/helpers.h (pyEditCb): New prototype.
python: Port more tests.
+ + commit a42d814a65fdc29a3be6efa97433997495696a88
* lang/python/tests/Makefile.am (TESTS_ENVIRONMENT): Set
LD_LIBRARY_PATH.
(pytests): Add new tests.
@@ -2584,11 +3855,13 @@
* lang/python/tests/t-signers.py: Likewise.
python: Translate list of strings.
+ + commit c9cc0412e940c78c3e9bacb6ff1459b5bb5bb9ad
* lang/python/gpgme.i: Add typemap translating list of strings.
2016-05-21 Werner Koch <wk@gnupg.org>
api: Return Tofu info for signatures.
+ + commit 10df06ee8f9192309bf124872438f7c32457e1c6
* src/gpgme.h.in (gpgme_tofu_policy_t): New.
(gpgme_status_code_t): Add status codes for TOFU.
(struct _gpgme_tofu_info, gpgme_tofu_info_t): New.
@@ -2606,26 +3879,31 @@
(print_result): print tofu info.
api: Add new context flag "raw-description".
+ + commit dac2c5441d418536632f014c8b0e1359580279d1
* src/context.h (struct gpgme_context): Add field raw_description.
* src/gpgme.c (gpgme_set_ctx_flag): New flag.
core: New functions to help parsing of status lines.
+ + commit a92946a8cacc44f655249d84b316deae59e62671
* src/conversion.c (_gpgme_split_fields): New.
(_gpgme_strtoul_field): New.
2016-05-20 Andre Heinecke <aheinecke@intevation.de>
Qt: Add test for changeownertrust.
+ + commit eaf2d018e63c15cd9a81e5c1fd2fedbf8829f7b9
* lang/qt/tests/t-ownertrust.cpp: New test.
* lang/qt/tests/Makefile.am: Add test.
Cpp: Ignore STATUS_KEY_CONSIDERED when editing.
+ + commit 5df858cbf196b2a53d600b7f45655f7b35c1fe93
* lang/cpp/src/editinteractor.cpp (EditInteractor::needsNoResponse):
Handle GPGME_STATUS_KEY_CONSIDERED.
2016-05-19 Werner Koch <wk@gnupg.org>
api: Add new function gpgme_set_ctx_flag.
+ + commit 88f2c1c0d16eee6bb36a901623ea65ac69499f03
* src/gpgme.h.in (gpgme_set_ctx_flag): New prototype.
* src/gpgme.c (gpgme_set_ctx_flag): New.
* src/gpgme.def, src/libgpgme.vers: Add new function.
@@ -2664,18 +3942,21 @@
(main): Add option --status.
api: Remove arbitrary restriction from gpgme_op_verify.
+ + commit 5aa8e588e166abeef2e3d677ab6830f2d7af1b5d
* src/verify.c (verify_start): Do not return GPG_ERR_INV_VALUES when
when SIGNED_TEXT is not given.
2016-05-19 Justus Winter <justus@gnupg.org>
python: Improve progress callbacks.
+ + commit 0d4e95621e05d50cd454049a424bb9ee098a5db6
* lang/python/helpers.c (pyProgressCb): Stash python errors, convert
'what' to Unicode object.
* lang/python/pyme/core.py (Context.set_progress_cb): Hand in 'self'.
* lang/python/tests/t-callbacks.py: Test progress callbacks.
python: Robust exception handling in callbacks.
+ + commit d90857a08c4fe5b73b6d6d46fd6200efdd72db44
* lang/python/helpers.c (pygpgme_stash_callback_exception): New
function.
(pygpgme_raise_callback_exception): Likewise.
@@ -2693,12 +3974,14 @@
2016-05-19 Andre Heinecke <aheinecke@intevation.de>
Qt: Check for graphviz and set HAVE_DOT correctly.
+ + commit 2f748b5a2d162be4f23b18782219771ead54cb51
* configure.ac: Check for graphviz and define HAVE_DOT.
* lang/qt/doc/Doxyfile.in (HAVE_DOT): Use variable.
2016-05-19 Justus Winter <justus@gnupg.org>
python: Add more tests.
+ + commit 464d404c8816fc93baf945816c93e86bdeb0ea39
* lang/python/tests/Makefile.am (py_tests): Add new tests.
* lang/python/tests/support.py (print_data): New function.
* lang/python/tests/t-decrypt.py: Use new function.
@@ -2707,37 +3990,44 @@
* lang/python/tests/t-encrypt-sym.py: Likewise.
python: More type conversion fixes.
+ + commit c1c893e3384a07ff864507902fbac4a7fee4d6f1
* lang/python/helpers.c (pyPassphraseCb): Cope with 'uid_hint' being
NULL, convert it to an Unicode object, and cope with the callback
returning both Unicode and bytes objects.
python: Fix import.
+ + commit 07f71cd17706093ca6b1507c41609356d479ae9f
* lang/python/helpers.c (pygpgme_exception_init): Make module import
relative.
2016-05-19 Andre Heinecke <aheinecke@intevation.de>
Qt: Fix compilation of unit tests.
+ + commit 375523ead3a749d77d286c56f10d403c07f2b014
* lang/qt/tests/Makefile.am (AM_CPPFLAGS): Add -DBUILDING_QGPGME.
2016-05-18 Justus Winter <justus@gnupg.org>
python: Various fixes.
+ + commit 2c3a5d93e78cfca22785e51c5a65184a47da4bff
* configure.ac: Fix SWIG detection, bump required Python version.
* lang/python/Makefile.am: Portability fix.
2016-05-18 Andre Heinecke <aheinecke@intevation.de>
Fix typo in compatibility declaration.
+ + commit f0dca0ab92ed18d80e30d7d39db1596b4112794f
* src/op-support.c (GPG_ERR_SUBKEYS_EXP_REV): Change to
GPG_ERR_SUBKEYS_EXP_OR_REV.
2016-05-17 Werner Koch <wk@gnupg.org>
tests: New maintenance helper run-encrypt.
+ + commit 30b447fcfe0e4f362c2575e1b9388e8144b5b2fd
* tests/run-encrypt.c: New.
Return dedicated error code for all subkeys expired or revoked.
+ + commit 315fb73d4a774e2c699ac1804f5377559b4d0027
* src/gpgme.h.in (GPGME_STATUS_KEY_CONSIDERED): New.
(GPGME_SIGSUM_TOFU_CONFLICT): New.
* src/status-table.c (KEY_CONSIDERED): New.
@@ -2754,6 +4044,7 @@
2016-05-17 Andre Heinecke <aheinecke@intevation.de>
Qt / Cpp: Port auto_ptr to unique_ptr.
+ + commit 9b36ebf37a3b889c955ba68038bd5b3d9c5cde4e
* lang/cpp/src/context.cpp,
lang/cpp/src/context.h,
lang/cpp/src/context_p.h (Context::createForEngine),
@@ -2771,9 +4062,11 @@
2016-05-17 Justus Winter <justus@gnupg.org>
build: Add python autoconf macro.
+ + commit 4711a1e181153a2395e5f523047595abd47965db
* m4/ax_python_devel.m4: New file.
python: Clean up examples.
+ + commit 10328324c8fc9725cd0c885eaebfc80dc32c1ff6
* lang/python/examples/delkey.py: Clean up example.
* lang/python/examples/encrypt-to-all.py: Likewise.
* lang/python/examples/genkey.py: Likewise.
@@ -2786,11 +4079,13 @@
* lang/python/pyme/__init__.py: Likewise.
python: Import GPGMEError.
+ + commit 64e5fe767f45e9ccb0fb3fe919171c222132a54c
* pyme/core.py: Import GPGMEError.
Fixes c5d118b2.
python: Port more tests.
+ + commit 9ceaec25918c6c5f2dfafe4e20181b83ce78f6ce
* lang/python/Makefile.am: Add bits from the c test suite.
* lang/python/support.py: New file.
* lang/python/t-decrypt.py: Likewise.
@@ -2799,6 +4094,7 @@
2016-05-13 Andre Heinecke <aheinecke@intevation.de>
Qt: Add keyLocateJob and test for it.
+ + commit 52f2295d528029a36a3e0a89c777297762b3fc9b
* configure.ac (LIBQGPGME_LT_REVISION): Bump.
* lang/qt/src/protocol.h (locateKeysJob): Add Job.
* lang/qt/src/protocol_p.h (locateKeysJob): Implement.
@@ -2806,55 +4102,66 @@
* lang/qt/tests/t-keylocate.cpp: New.
Qt: Add missing copyright header in test.
+ + commit 66ded1a5ce7236254f8541addecd4c3bc7b2878e
* lang/qt/tests/t-keylist.cpp: Add copyright header.
2016-05-12 Justus Winter <justus@gnupg.org>
python: Share generated methods between objects.
+ + commit 11314f0db6e57597e3f56351a86fdb36a7a17dd7
* lang/python/pyme/util.py (GpgmeWrapper.__getattr__): Monkey-patch
the class.
* lang/python/tests/t-wrapper.py: Demonstrate the sharing.
python: Raise exceptions on write errors.
+ + commit c5d118b2a76e9528df780d11da9566ff7c22e4f5
* lang/python/pyme/core.py (Data.write): Handle errors.
* lang/python/pyme/errors.py (GPGMEError.fromSyserror): New function.
python: Fix writing to data buffers.
+ + commit f7094d8358e933f3ce074eade7a40b2a7d291180
* lang/python/gpgme.i: Add typemap for buffers.
* lang/python/pyme/core.py (Data.write): Fix function.
* lang/python/tests/Makefile.am: Add new test.
* lang/python/tests/t-data.py: New file.
python: Add a test suite.
+ + commit e64bffe0307d14204b00a177a472cd4f99c07561
* configure.ac: Add new Makefile.
* lang/python/Makefile.am: Add subdirectory.
* lang/python/tests/Makefile.am: New file.
* lang/python/tests/t-wrapper.py: Likewise.
python: Cache generated wrapper functions.
+ + commit ed0ce84fbd2904bf59ac66ae7422716db3624efa
* lang/python/util.py (GpgmeWrap.__getattr__): Cache generated wrapper
functions.
python: Fix function invocation.
+ + commit e3d3d366bd1a1aea8a38ae5dcbf71ea3c784e920
* lang/python/pyme/core.py (Data.new_from_fd): Fix function
invocation.
python: Fix name of exception, make slot methods explicit.
+ + commit af9371eb63664c92fb67e8e7e03cc984e7d38a7f
* lang/python/pyme/util.py (GpgmeWrapper._getctype): Fix exception,
add docstring.
(GpgmeWrapper._getnameprepend): New function.
(GpgmeWrapper._errorcheck): Likewise.
python: Handle interpreter shutdown.
+ + commit ce5121ad53b0e17fbf9150b354c80da73f7fe190
* lang/python/pyme/core.py: Avoid races at interpreter shutdown. This
silences the most annoying occurrences, however this problem also
affects the SWIG generated code, which might indicate that the real
problem is somewhere else. If so, this change can be easily reverted.
python: Make test case more robust.
+ + commit c89d3a71ad20ff02755539a44f254b1e59054c4a
* lang/python/examples/t-edit.py: Check if key is found.
python: Fix type translation.
+ + commit d60deb8a127fb35c01acc729f33b014840af0e7b
* lang/python/gpgme.i: Adjust to Python3's string type being
'Unicode', not 'bytes'. Fix type checking.
* lang/python/core.py (Data.write): Add docstring mentioning the
@@ -2866,15 +4173,18 @@
2016-05-11 Andre Heinecke <aheinecke@intevation.de>
Cpp: Ensure gpgme.h is taken from current build.
+ + commit b8de79160b2e05ac84d8feb61ff7ed1f7015a623
* lang/cpp/src/Makefile.am (AM_CPPFLAGS): Add gpgme.h location.
2016-05-11 Justus Winter <justus@gnupg.org>
python: Fix simple example.
+ + commit bbeee5e1a060f2d1e37a08220eb552cf4673a058
* lang/python/examples/simple.py: Flush stdout, encode name as
UTF-8 before passing it to GPGME.
python: Integrate into the build system.
+ + commit a29babd07cf9f9625d2b5aa2eb6b7bc9d1828359
* configure.ac: Make Python bindings configurable, add new Makefile.
* lang/python/Makefile.am: New file.
* lang/python/setup.py: Integrate into the build system.
@@ -2884,6 +4194,7 @@
2016-05-10 Andre Heinecke <aheinecke@intevation.de>
Qt / Cpp: Fix make dist.
+ + commit c303292aca26c43b6efe98719edb3ff7b2d6665d
* lang/cpp/src/Makefile.am (EXTRA_DIST): Fix typo.
(private_gpgmepp_headers): New. Private headers.
(libgpgmepp_la_SOURCES): Add private headers.
@@ -2893,11 +4204,13 @@
2016-05-10 Justus Winter <justus@gnupg.org>
python: PEP8 fixes.
+ + commit 11392a80d9a85bcd8718b105e6d58038e61beaac
Cherry picked from 0267c151.
2016-05-10 Andre Heinecke <aheinecke@intevation.de>
Qt: Make Protocol class public API.
+ + commit 56c4d9ea9520c95612e525b2fa1359db6fa88f4a
* lang/qt/src/Makefile.am (qgpgme_headers): Add protocol.h
(private_qgpgme_headers): Add protocol_p.h
* lang/qt/src/protocol.h: New. From QGpgMEBackend.
@@ -2906,58 +4219,72 @@
lang/qt/src/qgpgmebackend.cpp (Protocol): Removed.
Qt: Make doxygen quieter.
+ + commit 97225bb01cd2ffa1d84c7fedbc577275de4a4893
* lang/qt/doc/Doxyfile.in: Quiet and no undocumented warnings.
Qt: Only install public headers.
+ + commit 740f92a7b83389ee9bde98b7bd25556793500b8b
* lang/qt/src/Makefile.am: Do not install all headers.
Qt: Add test for async keylisting.
+ + commit 0e3195948ddaba3af07d2415bb496491076edc17
* src/lang/qt/tests/t-keylist.cpp(KeyListTest::testKeyListAsync): New.
2016-05-10 Werner Koch <wk@gnupg.org>
Allow cc to detect missing cases in a switch.
+ + commit fc38c15136c87ce971a8381fa87399088dd5a3cc
* src/delete.c (delete_status_handler): Remove default case from a
switch so that cc can check the use of all enum values.
2016-05-06 Andre Heinecke <aheinecke@intevation.de>
Use common error message style for qt lang checks.
+ + commit a579be82c84f0b9732ee3d52ff2142a3decf95d7
* configure.ac: Use common error highliting for qt lang options.
Qt: Fix license mentioned in README.
+ + commit 11ff8d5964bf66f905818514f6a51fc881ea1a56
* lang/qt/README: License is GPLv2+ and not LGPL.
Add maybe mode for langs and default to it.
+ + commit cd267791e9bd73505a2a1ea90c85df988e153c19
* configure.ac (languages): Warn and disable langs for which
requirements are not met.
Cpp: Handle PINENTRY_LAUNCHED status line.
+ + commit 3fad1216770f446a89801d842aa8667356a5ec95
* lang/cpp/src/editinteractor.cpp (EditInteractor::needsNoResponse):
Add GPGME_STATUS_PINENTRY_LAUNCHED.
2016-04-12 Andre Heinecke <aheinecke@intevation.de>
Cpp: Add support for pubkey_algo_name.
+ + commit 5489532ad6ccf3a9b59405686b8a17352f1ecf06
* lang/cpp/src/key.cpp (Subkey::algoName): New.
* lang/cpp/src/key.h: Declare.
Cpp: Add support for gpgme_data_identify.
+ + commit d949d711dc1d944a9d627d39a89af74943a5a8c1
* lang/cpp/src/data.cpp (Data::type): New.
* lang/cpp/src/data.h (Data::Type): New enum mapping.
Fix configuration without Qt language.
+ + commit 6dba47c3a2c32d7c1e1d91a96030f99f606433ea
* configure.ac: Define HAVE_DOXYGEN also if qt should not be built.
2016-04-11 Andre Heinecke <aheinecke@intevation.de>
Qt/Cpp: Bump so version to 6.
+ + commit 8e7074dbb8093cc342e330bcd6b172b4f769a0c6
* configure.ac (LIBGPGMEPP_LT_CURRENT, LIBQGPGME_LT_CURRENT): Bump.
Qt / Cpp: Mention coding style in READMES.
+ + commit d2b55101195efe9702e855a48fc6e21839fb98cc
* src/lang/cpp/README, src/lang/qt/README: Add hacking note.
Qt: Add doc generation with doxygen.
+ + commit a1e95f36ce1895cd9894f6d3ca76640c42c2f9fc
* configure.ac: Look for doxygen if qt is built.
Configure new files.
* lang/qt/doc/Doxyfile.in: New.
@@ -2965,11 +4292,13 @@
* lang/qt/README: Update.
Qt: Fix unit test by adding initial.test dep.
+ + commit d9f7a18ed88127e7f05d770d55118d1e928f3b3f
* lang/qt/tests/t-keylist.cpp: Verify that GNUPGHOME is set.
* lang/qt/tests/initial.test: New dummy test.
* lang/qt/tests/Makefile.am: Add dependency to initial.test
Qt: Remove remaining boost usage.
+ + commit afd8fad6e275e2f74b2ad045dce05d826986e2ec
* lang/qt/src/dataprovider.h,
lang/qt/src/decryptjob.h,
lang/qt/src/decryptverifyjob.h,
@@ -3003,18 +4332,22 @@
lang/qt/src/verifyopaquejob.h: Remove boost usage.
Qt: Remove predicates.h and stl_util.h.
+ + commit e18256fc5f613da9406da60c3ef2f84f2be04ef0
* src/lang/qt/predicates.h, src/lang/qt/stl_util.h: Removed.
Qt: Remove usage of stl_util.h and predicates.h.
+ + commit d293bd32293929eeb3f6ec35f916a4678fb51729
* src/lang/qt/qgpgmelistallkeysjob.cpp: Use comperators from
gpgmepp instead of detail. Remove boost usage.
Cpp: Add string comparators for keys.
+ + commit 1bb162a54ba480413c4da07f2578efe6860494c0
* lang/cpp/src/global.h (GPGMEPP_MAKE_STRCMP): New.
(_gpgmepp_strcmp): NULL save wrapper around std::strcmp.
* lang/cpp/src/key.h: Add comparators for various attributes.
Cpp: Remove last usages of boost.
+ + commit 691950e18cf08a3f9bbc2004501834cd47bea579
* lang/cpp/src/configuration.cpp: Use std::remove_pointer.
(Configuration::operator<<): std::for_each.
* lang/cpp/src/context.cpp: Delete manually instead of scoped ptr.
@@ -3024,11 +4357,13 @@
2016-04-04 Andre Heinecke <aheinecke@intevation.de>
Add pthread in gpgmepp config.
+ + commit cc68ff5f7210ac879fbdf719fcd5944f9ae5602b
* lang/cpp/src/GpgmeppConfig.cmake.in.in: Add pthread.
2016-04-03 Andre Heinecke <aheinecke@intevation.de>
Cpp / Qt: Reduce boost usage (memory and tuple)
+ + commit f98898ab1a6952e0c3a5d235963a27eba2e19e46
* cpp/src/assuanresult.h,
cpp/src/configuration.cpp,
cpp/src/configuration.h,
@@ -3100,22 +4435,26 @@
qt/src/verifyopaquejob.h: Reduce boost usage.
Cpp: Require c++ 11 if cpp binding requested.
+ + commit c07aaef6eb8a9b5e623479f27d562fd1570bf4bb
* configure.ac: Call ax_cxx_compile_stdcxx
* m4/ax_cxx_compile_stdcxx.m4
Qt: Add static factor methods for protocol.
+ + commit 0991485170ca4ef90fd566540522027d0fc59a72
* lang/qt/src/qgpgmebackend.cpp (QGpgME::openpgp, QGpgME::smime): New.
* lang/qt/src/qgpgmebackend.h: Declare.
* lang/qt/tests/t-keylist.cpp (KeyListTest::testSingleKeyListSync):
Use new functions.
Qt: Add a unit test for qgpgme.
+ + commit faf987dd62893955251378a2a715edd2892a540c
* configure.ac: Configure test Makefile.
* m4/qt.m4: Look up Qt5Test flags.
* lang/qt/tests/t-keylist.cpp: New. Simple keylist check.
* lang/qt/tests/Makefile.am: New. General test framework.
Qt: Add missing MOC includes.
+ + commit b7b9e38399a572cb61a297db552026eac5b2a5e1
* qgpgmeadduseridjob.cpp,
qgpgmechangeexpiryjob.cpp,
qgpgmechangeownertrustjob.cpp,
@@ -3140,13 +4479,16 @@
qgpgmeverifyopaquejob.cpp: Add missing MOC includes.
Qt: Declare pure virtuals as such.
+ + commit 0cc9006dbc59d87c6bcda88b36d59dcb69ac35cb
* lang/qt/src/qgpgmebackend.h (Protocol): Make all functions
pure virtual.
Qt: Don't declare showErrorDialog anymore.
+ + commit 3e38cc6fc67c420dec3e9e8afd072b4c8a157c85
* cpp/qt/src/job.h: Remove showErrorDialog.
Qt: Only use GpgME based config class.
+ + commit 7071b2a9c00b85d434d01b6166269ebf48b01b81
* lang/qt/src/qgpgmecryptoconfig.cpp,
lang/qt/src/qgpgmecryptoconfig.h: Removed.
* lang/qt/src/qgpgmebackend.cpp: Return newcryptoconfig.
@@ -3154,19 +4496,23 @@
2016-04-02 Andre Heinecke <aheinecke@intevation.de>
Add additional include path in config files.
+ + commit 63c115b067400e1b02c7d849c99f54dc9f394d68
* lang/cpp/src/GpgmeppConfig.cmake.in.in
lang/qt/src/QGpgmeConfig.cmake.in.in: Include directory above headers.
Qt: Fix library name in nodist variable.
+ + commit 576be46f34b42e896a5e3be65560a4b518a758be
* lang/qt/Makefile.am (nodist_qgpgme_SOURCES): Change to real name.
Add missing files to QGpgME.
+ + commit a440050fc2c11e4867da9d4707616fa23ac52141
* lang/qt/src/gpgme_backend_debug.cpp,
lang/qt/src/gpgme_backend_debug.h,
lang/qt/src/predicates.h,
lang/qt/src/stl_util.h: New.
Add QGpgME code from libkleo.
+ + commit 226e51052ae73efa8d9f30729b28de68d35231af
* lang/qt/src/Makefile.am,
lang/qt/src/abstractimportjob.h,
lang/qt/src/adduseridjob.h,
@@ -3253,6 +4599,7 @@
2016-03-08 Andre Heinecke <aheinecke@intevation.de>
Add qgpgme as qt language binding.
+ + commit 8347f3d5fc3e476aa767fbbaf09a1310a6154280
* configure.ac: Add version defines. Check for qt if neccessary.
* lang/README: Mention qt
* lang/cpp/src/GpgmeppConfig.cmake.in.in: Remove comment. Find qgpgme.
@@ -3269,6 +4616,7 @@
lang/cpp/src/Makefile.am: Fix generated config file.
Remove obsolete w32-qt code.
+ + commit 58ed9c17f00f420035ecc6973a6c6ed948757a9a
* configure.ac (w32-qt): Remove option and Qt checks.
* src/Makefile.am: Remove BUILD_W32_QT handling.
* src/kdpipeiodevice.cpp,
@@ -3279,21 +4627,26 @@
2016-03-02 Andre Heinecke <aheinecke@intevation.de>
Add version info for gpgmepp.
+ + commit a06603d75e80aba58df58f9a41770c56b6a1f0b8
* lang/cpp/src/Makefile.am (libgpgmepp_la_LDFLAGS): Add version info.
Add cmake configuration files.
+ + commit 77c3fb450c7adf36804a55d76ff49a06a71d22a0
* configure.ac: Add libgpgmepp version. Configure cmake files.
* lang/cpp/src/Makefile.am: Add targets for cmake files.
(EXTRA_DIST): Add cmake files.
Fix export header and windows export macros.
+ + commit 98e5b672422ca1e38ca38ff0357cee6cc936aee0
* lang/cpp/src/gpgme_export.h: Fix variable name. Add Windows ifdefs.
Add header installation.
+ + commit c5291a88913ace8f2115021b69c7aeb59b4f79d4
* lang/cpp/src/Makefile.am: Add headers as deps and install them.
(AM_CPPFLAGS): Add BUILDING_GPGMEPP to be used in export macros.
Add enable-languages build option.
+ + commit a313b3e28cc42785365822519b25d6a87dfdf0c9
* acinclude.m4 (LIST_MEMBER): New macro.
* configure.ac (enable-languages): New option. Add info output.
* lang/Makefile.am: Only add enabled language subdirs.
@@ -3301,16 +4654,19 @@
2016-02-22 Andre Heinecke <aheinecke@intevation.de>
Add README for gpgmepp.
+ + commit 7286fc7f3d51d475f82c7c9821d031290f5b0066
* lang/README: Note down cpp.
* cpp/README: Add README based on original repo version.
Add buildsystem for Gpgmepp.
+ + commit f5fd787b5b45cb14d539b5c26f44066eb9ac0f75
* configure.ac: Configure Makefiles.
* lang/Makefile.am: Add cpp subdir
* lang/cpp/Makefile.am: New. Add src subdir.
* lang/cpp/src/Makefile.am: New. Basic buildsystem.
Remove feature check ifdefs.
+ + commit 433bb8e84b2d1e50b5c5b9f7f2006b60cd7d7785
* lang/cpp/src/assuanresult.cpp,
lang/cpp/src/callbacks.cpp,
lang/cpp/src/configuration.cpp,
@@ -3340,6 +4696,7 @@
lang/cpp/src/vfsmountresult.cpp: Remove feature checks.
Initial checkin of gpgmepp sources.
+ + commit 0855a1296a1908016f011eb5e6552854ac53e63a
Based on git.kde.org/pim/gpgmepp rev. 0e3ebc02
* lang/cpp/src/assuanresult.cpp,
@@ -3415,41 +4772,49 @@
2016-01-15 Werner Koch <wk@gnupg.org>
Fix possible _SC_OPEN_MAX max problem on AIX.
+ + commit e79199468ac54ce4fe919603ff7bada97267174f
* src/posix-io.c [HAVE_STDINT_H]: Include stdint.h.
(get_max_fds): Limit returned value for too high values.
2015-12-09 Werner Koch <wk@gnupg.org>
w32: Avoid conflict with Mingw-w64 version 4.0.4-1.
+ + commit 83415dffaea53611dbce77b50d8ddfb2a50aed2e
* src/w32-util.c (mkstemp): Rename to my_mkstemp. Change caller.
2015-12-04 Daiki Ueno <ueno@gnu.org>
Return on user cancellation of delete operation.
+ + commit 67d7f7a9383763b01daf877c846bf3e32f647fa5
* src/delete.c (delete_status_handler): Return on ERROR status, if the
error location is set to "delete_key.secret" and the code is either
CANCELED or FULLY_CANCELED, which indicates a situation that the user
selected "No" on the confirmation dialog.
doc: Fix minor errors.
+ + commit 3b6e9a3d0afcdd3c2f1de19f15924c3404c7140a
* doc/gpgme.texi: Fix errors and typos in the cancellation and
gpgme_import_result_t documentation.
2015-10-29 Ben Kibbey <bjk@luxsci.net>
Make use of user passphrase handler during passwd.
+ + commit dfa79f9300b837b0f7f2ea44afa589bfcda1dbd9
* src/passwd.c (passwd_start): set engine passphrase command handler.
2015-10-28 Werner Koch <wk@gnupg.org>
w32: Add extra diagnostic about possible missing gpgme-w32spawn.exe.
+ + commit bb2d11c1eebd4bcfb0f2cfce728026a7420dca47
* src/w32-io.c (_gpgme_io_spawn): Add a new diagnostic.
w32: Improve locating gpgconf on 64 bit systems.
+ + commit a82e9b182f62966207cad0972be6fa284329a5a1
* src/w32-util.c (find_program_at_standard_place): Fallback to
CSIDL_PROGRAM_FILESX86.
w32: Add new global flag "w32-inst-dir".
+ + commit bb600aa8fd2f9575ee7afc64c978e3e7523b1173
* src/gpgme.c (gpgme_set_global_flag): Add flag "w32-inst-dir";
* src/posix-util.c (_gpgme_set_override_inst_dir): New stub.
* src/w32-util.c (override_inst_dir): New var.
@@ -3459,6 +4824,7 @@
2015-10-16 NIIBE Yutaka <gniibe@fsij.org>
cleanup: Fix type mismatch around gpgme_error_t.
+ + commit 0d9d0a6b5b0c6f474a079bbaef11078c5df5f3b5
* src/data-compat.c (gpgme_error_to_errno): Use gpg_err_code
to get error code from gpgme_error_t.
* src/gpgme.c (gpgme_new): Don't use gpgme_error.
@@ -3466,6 +4832,7 @@
2015-08-31 Werner Koch <wk@gnupg.org>
gpgme-tool: Switch to argparse.c for option parsing.
+ + commit f0ccce855bd99fca7cfbbcafe3544e3113fedc67
* src/argparse.c, src/argparse.h: New. Taken from current gnupg.
* src/Makefile.am (gpgme_tool_SOURCES): New.
* src/gpgme-tool.c: Remove all argp.h stuff.
@@ -3475,6 +4842,7 @@
2015-08-30 Werner Koch <wk@gnupg.org>
Add gpgme_pubkey_algo_string.
+ + commit c4b6b35bfa98e478f1d13f4ce3e664771f2604c2
* src/gpgme.h.in (GPGME_PK_EDDSA): New.
(gpgme_pubkey_algo_string): New.
* src/conversion.c (_gpgme_map_pk_algo): Add new algo.
@@ -3484,9 +4852,11 @@
2015-08-26 Werner Koch <wk@gnupg.org>
Release 1.6.0.
+ + commit 107bff70edb611309f627058dd4777a5da084b1a
* configure.ac: Set LT version to C25/A14/R0.
Make use of GPGRT macros is available.
+ + commit c4f4b5c0a6fc172f7ceedc1a0021169e7f31b941
* src/gpgme.h.in (_GPGME_INLINE): Define using GPGRT_INLINE if
possible. Fix problem with -Wundef by adding an extra "defined()".
(_GPGME_GCC_VERSION): Define using GPGRT_ macro if possible.
@@ -3494,15 +4864,18 @@
2015-08-25 Werner Koch <wk@gnupg.org>
Avoid -Wundef warnings if gpgme.h is used by g++.
+ + commit 3f53d3d5d9e73a053b1e89073ef8f7cf01bfc8e6
* src/gpgme.h.in (_GPGME_INLINE): Move definition into the
extern-C-scope.
Add configure option --enable-build-timestamp.
+ + commit ff91e699f7c14ea6cbc27b487cb40e9f6bd58901
* configure.ac (BUILD_TIMESTAMP): Set to "<none>" by default.
2015-08-25 Daiki Ueno <ueno@gnu.org>
Relax ttyname_r error checks.
+ + commit 028a0ef3336c5180797fb247448683195376c007
* src/engine-assuan.c (llass_new): Don't treat ttyname_r error as
fatal.
* src/engine-g13.c (g13_new): Likewise.
@@ -3513,9 +4886,11 @@
2015-08-25 Werner Koch <wk@gnupg.org>
Cleanup layout of gpgme.h.
+ + commit 97f1f3e883808743da5ee144abab25de062f34ac
* src/gpgme.h.in: Reorder prototypes. Chnage some comments.
Improve error return by checking the FAILURE status.
+ + commit 8ddc5801ade02297924447df5745c8877a96e5e3
* src/gpgme.h.in (GPGME_STATUS_FAILURE): New.
* src/status-table.c (FAILURE): New.
* src/op-support.c (_gpgme_parse_failure): New.
@@ -3536,27 +4911,33 @@
(_gpgme_verify_status_handler): Parse that code and act upon it on EOF.
tests: Allow using run-sign to test loopback pinentry problems.
+ + commit 491fcd91b84564232d5d061942baa50b99e166c0
* tests/run-sign.c: Add options --status and --loopback.
2015-08-24 Werner Koch <wk@gnupg.org>
Call status_cb for an ERROR status seen in the passphrase handler.
+ + commit ad46f4f655e653580343c15f1b0b365b7d307d1b
* src/passphrase.c (_gpgme_passphrase_status_handler): Call status_cb.
w32: Look for gpgconf in the new GnuPG 2.1 install dir.
+ + commit a7dbab23ea4976d106d649aa515ffb2968a085ed
* src/w32-util.c (_gpgme_get_gpgconf_path): Try another location of
gpgconf.exe.
w32: Expect gpgme-w32spawn.exe only in the gpgme installation dir.
+ + commit 06d6fd8ca01354c8f7cfc847c4ac1b868268cbaa
* src/w32-util.c (find_program_at_standard_place): Remove.
(_gpgme_get_gpg_path): Make the search order more explicit.
(_gpgme_get_gpgconf_path): Ditto.
(_gpgme_get_w32spawn_path): Search only in the inst_dir.
w32: Print the installation directory in debug mode.
+ + commit df098d6a437109c57516db75addf3764a6dfda81
* src/debug.c (debug_init) [W32]: Show libgpgme installation dir.
Add an export secret key feature.
+ + commit 2b632bbb78eee2b94c122f66d171a7c80e9c4fb0
* src/gpgme.h.in (GPGME_EXPORT_MODE_SECRET): New.
(GPGME_EXPORT_MODE_RAW): New.
(GPGME_EXPORT_MODE_PKCS12): New.
@@ -3571,17 +4952,20 @@
2015-08-16 Ben Kibbey <bjk@luxsci.net>
Parse INQUIRE_MAXLEN in the passphrase callback.
+ + commit ccbaccbf2e0ba582d181b9ee4d8543d7c1248b2c
* src/passphrase.c (_gpgme_passphrase_status_handler): Parse
GPGME_STATUS_INQUIRE_MAXLEN.
* src/passphrase.c (_gpgme_passphrase_command_handler): Send the
INQUIRE_MAXLEN status message.
Fix gpgme_{get,set}_status_cb to match documentation.
+ + commit 70b3e5964ea0592bd09d1877d720b2c63f501970
* doc/gpgme.texi: Minor fixes.
* src/gpgme.c (gpgme_get_status_cb): Set return variables to NULL and
check for a valid ctx pointer.
Parse the INQUIRE_MAXLEN status message.
+ + commit 6dd24c3c6133ec54f75abd056191a8027fe01de0
* src/gpgme.h.in: (gpgme_status_code_t): Add INQUIRE_MAXLEN.
* src/status-table.c (status_table_s): Ditto.
* src/genkey.c (genkey_status_handler): Parse INQUIRE_MAXLEN.
@@ -3593,6 +4977,7 @@
gpgme_status_cb_t.
Add gpgme_set/get_status_cb().
+ + commit 4fadcf06ec8b0ebfb05c7622dbc3b73fd3c1bad9
* src/gpgme.h.in (gpgme_set_status_cb): New.
(gpgme_get_status_cb): New.
(gpgme_status_cb_t): New.
@@ -3605,26 +4990,31 @@
* doc/gpgme.texi: Document these new functions.
Make use of user passphrase handler during genkey.
+ + commit 2b6ae3dadf4432f7a72fd119144b835f7b1adcc4
* src/genkey.c (genkey_start): set engine passphrase command handler.
2015-08-12 Ben Kibbey <bjk@luxsci.net>
Also check the return code in gpg_sign().
+ + commit e07d38f5f9f3b94e403f1265ff7fd3d7009dd557
* src/engine-gpg.c (gpg_sign): Check return value from start().
2015-08-11 Ben Kibbey <bjk@luxsci.net>
Check the return value when starting gpg.
+ + commit 8f28e3caf95d7bc99e9271bfc2b44080166af31f
* src/engine-gpg.c (gpg_decrypt, gpg_delete, gpg_passwd): Check return
value of start().
2015-08-02 Ben McGinnes <ben@adversary.org>
More GTK2 removal.
+ + commit a7fbd5293ed0ba2c179837a4a2b859376d30e35e
* Missed a couple of files, these 2 go for the same reason as the
previous 3.
Removed GUI examples.
+ + commit 1cd0aef0afb196094d90673002d4c210a04911c9
* GUI examples written with pygtk, which has not been ported to Python
3 and won't be as it is for GTK2 and GNOME is moving to GTK3.
* New GUI examples may be required in future using any of several GUI
@@ -3633,6 +5023,7 @@
2015-07-31 Andre Heinecke <aheinecke@intevation.de>
Add offline mode support for CMS keylisting.
+ + commit 08086dd6901740e155e4361212b4e9cff8a47296
* doc/gpgme.texi: Document offline mode.
* src/context.h (gpgme_context): Add offline.
* src/engine-backend.h (keylist, keylist_ext): Add engine_flags.
@@ -3653,12 +5044,14 @@
2015-07-23 Peter Wu <peter@lekensteyn.nl>
build: ignore scissor line for the commit-msg hook.
+ + commit 157c8be183153ff588f98874a3205aa483d0fd23
* build-aux/git-hooks/commit-msg: Stop processing more lines when the
scissor line is encountered.
2015-07-23 Werner Koch <wk@gnupg.org>
Add option --lib-version to gpgme-tool.
+ + commit c23f8897105ce2bb6e62d9c44ca0779fcc08a919
* src/gpgme-tool.c (options, parse_options): Add --lib-version
(CMD_LIBVERSION): New.
(main): Implement.
@@ -3666,20 +5059,27 @@
2015-06-08 Werner Koch <wk@gnupg.org>
Release 1.5.5.
+ + commit 052a9e3c5671d1ab69551f7b0abd0bbf859d4aba
+
Fix regression with gpgsm 2.0 due to "OPTION with-secret".
+ + commit ddbd54ef881bd2c3481d62b89bef7241667b64ee
* src/engine-gpgsm.c (gpgsm_assuan_simple_command): Do not terminate
on a status lines.
tests: Add option --secret to run-keylist.
+ + commit 7addffc0826e7f36afcc7f66268e9ee2a37e2042
+
Fix compiler warnings about unused value in TRACE macros.
+ + commit 8b9f84828cd04a7dab37e219123edc1905da8e6b
* src/debug.h: Change macros to not have a literal 0 as last
expression of the comma operator.
* src/debug.c (_gpgme_debug_frame_end): Return 0.
(_gpgme_debug): Return 0.
Fix test suite for GnuPG 2.1 which uses pubring.kbx.
+ + commit a5b040cc57c65b3d105666b90c7eb59ee6ff3882
* tests/gpgsm/final.test: New.
* tests/gpgsm/initial.test: New.
* tests/gpg/start-stop-agent: Move to ../.
@@ -3697,17 +5097,20 @@
2015-06-05 Matthew Barnes <mbarnes@redhat.com>
Set GPGME_SIGSUM_KEY_REVOKED also for gpg.
+ + commit 87d713ff41454bd08a345c63605f6fc7ac854dd4
* src/verify.c (calc_sig_summary): Handle GPG_ERR_CERT_REVOKED.
2015-06-05 Werner Koch <wk@gnupg.org>
Fix segv for userids with a backslash.
+ + commit 0d28a696163677d6b34a802b6beddecd805d0fc7
* src/engine-gpg.c (gpg_keylist_preprocess): Increment SRC for a
backslash.
2015-05-16 Ben McGinnes <ben@adversary.org>
Python 3 port of PyME.
+ + commit 90405ac84b78ba7e5458ea09986749594a01195a
* Port of PyME 0.9.0 for Python 2 to Python 3 along with most of the
example scripts.
* Intended to be developed in parallel with the original Python 2
@@ -3720,6 +5123,7 @@
reference with git commit signatures.
Explaining why not all scripts work.
+ + commit 29887c9b28c0db14bf75e227a8082d23a2c151d2
* Some of them cannot be properly tested on OS X, especially with GTK in
the mix (it works on OS X, but is unlikely to be as easily accessible
as Cocoa or Qt).
@@ -3727,16 +5131,21 @@
false positives of error messages, at least on OS X.
Byte encoding.
+ + commit c39cea7a07cec9ab34cd2026f47b6fba80fea3c8
* More string updates.
* verifydetails.py still fails, but as Bernhard is still contactable, it
might be worth him checking on it instead.
No change, note added to explain why.
+ + commit 0e6e6689ef1aea36c1cb3cb47e94f1f2ebbd97cb
+
Strings vs. Bytes.
+ + commit 40290507bcdc63ab9023393d071167d455d70737
* CLI input must be byte encoded.
More byte changes and passphrase changes.
+ + commit 325b0ca341ae3ac8c3232f557ea2c381b4843969
* exportimport works, but will still segfault for an as yet unknown
reason.
* genkey produces a traceback error, but does create the key as
@@ -3744,23 +5153,28 @@
* matched passphrase in signverify.
More bytes good.
+ + commit ba3c9f2617955dc828309a4800e4f5b3f1c3a949
* Another string to byte change.
Updated encrypt-to-all.
+ + commit 1c87ecb86ae364b18f69bca726021271fefaa1c1
* Changed plaintext string to byte literal.
* Nested key selection in a try/except statement in case of
UnicodeEncodeError instances.
* Tested successfully on over 9,000 keys.
Passphrase update.
+ + commit 24c738f5bb5c253a17962c62867d6c847250b41e
* Changed example passphrase to something that meets the current minimum
requirements.
example email.
+ + commit 8345bf6f43c4f671124eaa1b713a7f5ac5780cbd
* changed joe@foo.bar to joe@example.org as it is only a matter of time
before ICANN actually creates bar as a gTLD, if they haven't already.
Updated string and key data.
+ + commit 4fc123981514c7087114e08ee8ca63de1a1db59f
* Text changed to byte literals.
* Changed key type to RSA/RSA.
* Changed expiry to the future (2020).
@@ -3768,12 +5182,14 @@
2015-05-08 Ben McGinnes <ben@adversary.org>
String type.
+ + commit 90079786c5cde4dd8ceb2e0fcda7605b08ccd021
* the plain text string must be bytes and not unicode.
* Expect most of the example code to have similar issues at present.
2015-05-05 Ben McGinnes <ben@adversary.org>
Python 3 port of PyME.
+ + commit ebd8734ad705afa4edc409787a00d4968d25e018
* The entirety of the Python 3 port of PyME up to commit
2145348ec54c6027f2ea20f695de0277e2871405
* The old commit log has been saved as
@@ -3787,8 +5203,11 @@
2015-04-13 Werner Koch <wk@gnupg.org>
Release 1.5.4.
+ + commit d2712d9f6f086911184453219a096c61f6829d3b
+
w32: Use -static-libgcc to avoid linking to libgcc_s_sjlj-1.dll.
+ + commit 524dacfbb6bb131f05a4ecab3d7bcd91c1b43d33
* src/Makefile.am (extra_ltoptions): New.
(libgpgme_la_LDFLAGS): Use it.
(libgpgme_pthread_la_LDFLAGS): Ditto.
@@ -3797,26 +5216,32 @@
2015-03-16 Werner Koch <wk@gnupg.org>
Fix potential crash in trace macro.
+ + commit 8cfcdfe5564f87362e5ec1bfdca5c14aed9c45f0
* src/signers.c (gpgme_signers_add): Avoid deref of a NULL KEY in the
trace macro.
* src/engine-spawn.c (engspawn_release): Remove always true condition.
* src/engine-gpg.c (gpg_release): Ditto.
Fix one byte too short malloc.
+ + commit 119f27032b822ace8c012b96f9e41bcf23251a54
* src/engine-spawn.c (add_data): Fix malloc
2015-01-30 Werner Koch <wk@gnupg.org>
Switch to automake 1.14 and update build-aux files.
+ + commit 428ea7696585bc24d127b903840554ca659069b6
+
2014-12-11 Werner Koch <wk@gnupg.org>
Release 1.5.3.
+ + commit 37d927a9706fff6d8ef8d45073984ea2f92afb31
* configure.ac: Set LT version to C24/A13/R2.
2014-12-08 Werner Koch <wk@gnupg.org>
Return an error for some export key operations.
+ + commit 05258d427513a933f01d4df13aca834d797f91e7
* src/context.h (OPDATA_EXPORT): New.
* src/export.c (op_data_t): New.
(release_op_data): New.
@@ -3829,26 +5254,31 @@
2014-11-21 Werner Koch <wk@gnupg.org>
Release 1.5.2.
+ + commit c62ce32b9c01ee9ceb1d69e7344fb79a9162d232
* configure.ac: Set LT version to C24/A13/R1.
Update the previous commit.
+ + commit 81ce87111f5a3f966188629abb07a4d0702e6db0
* src/sign.c (gpgme_op_sign_result): Reformat and take care of failed
malloc.
2014-11-21 Ben Kibbey <bjk@luxsci.net>
Fix returning new signatures when there are none.
+ + commit 5942b0c7e0593b82b4c4a142c214d7a2649de104
* src/sign.c (gpgme_op_sign_result): Test that invalid and valid
signatures add up to gpgme_signers_count().
2014-11-06 Werner Koch <wk@gnupg.org>
Improve the debug output a bit.
+ + commit 8031341283f4fcb1f226aa6f66bc5a6042586815
* src/debug.h (TRACE_ERR): Include the line number in the output.
2014-10-02 Werner Koch <wk@gnupg.org>
build: Implement SYSROOT feature.
+ + commit 4027a0a89724df3aeef8a964c529548d724b6a5a
* configure.ac: Document SYSROOT.
* m4/gpg-error.m4: Update from libgpg-error master.
* src/gpgme.m4: Implement SYSROOT stuff.
@@ -3856,53 +5286,64 @@
2014-09-24 Werner Koch <wk@gnupg.org>
tests: Delay some test file extraction until "make check".
+ + commit 2e8ecc24cf74f918c303c315da3bb18636a5e288
* tests/gpg/Makefile.am (all-local): Change to check-local.
* tests/gpgsm/Makefile.am (all-local): Ditto.
2014-09-24 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Clean up gpgme's tests/gpg when gpg2.1 is available.
+ + commit 36997e0f746ce2d38de997055141542583cc0f52
* tests/gpg/Makefile.am: Clean up .gpg-v21-migrated
2014-08-12 Werner Koch <wk@gnupg.org>
gpgme-tool: Print fingerprint and keyid with keyservers.
+ + commit 4160ef90a1b1b778c735f31f98a6966ba3b3ea90
* src/gpgme-tool.c (cmd_keylist): Print keyid. Print FPR only if
available.
Handle modern keyserver output which may emit the fingerprint.
+ + commit 3450bff52baef2c14118958cf79ead46940d58f0
* src/engine-gpg.c (read_colon_line): Split preprocessed lines.
(gpg_keylist_preprocess): Limit keyid field and print fingerprint.
gpgme-tool: Install gpgme-tool.
+ + commit 488e44cdb531035fa8813b95b212f9728abc7e62
* src/Makefile.am (bin_PROGRAMS): New. Add gpgme-tools.
(noinst_PROGRAMS): Remove.
gpgme-tool: Fix segv for external key listing.
+ + commit e5ab11607281b9838da2728268a8f9f0daa2b04d
* src/gpgme-tool.c (result_xml_escape): Allow for DATA being NULL.
2014-07-30 Werner Koch <wk@gnupg.org>
Release 1.5.1.
+ + commit 16835c3b5d1cea18512b2c93e884d8ca513a2ee7
* configure.ac: Change LT version to C24/A13/R0.
Fix possible realloc overflow for gpgsm and uiserver engines.
+ + commit 2cbd76f7911fc215845e89b50d6af5ff4a83dd77
* src/engine-gpgsm.c (status_handler):
* src/engine-uiserver.c (status_handler):
2014-06-26 Werner Koch <wk@gnupg.org>
w32: Get IOSPAWN flag back in sync with spawn helper.
+ + commit 68116fa5f67238a60bb8be375cc959262fa021d3
* src/gpgme-w32spawn.c: Include priv-io.h.
2014-06-10 Werner Koch <wk@gnupg.org>
Add new reason codes to the INV_RECP status code.
+ + commit 86260b47c9e306e325103d1af767842357647e60
* src/op-support.c (_gpgme_parse_inv_recp): Add codes 13 and 14.
2014-06-04 Werner Koch <wk@gnupg.org>
Add new keylist mode GPGME_KEYLIST_MODE_WITH_SECRET.
+ + commit 4dc9af24156b4fd52c7b76e7522b9b7a64e5386a
* src/gpgme.h.in (GPGME_KEYLIST_MODE_WITH_SECRET): New.
* src/engine-gpg.c (gpg_keylist_build_options): Handle new mode.
* src/engine-gpgsm.c (gpgsm_keylist, gpgsm_keylist_ext): Ditto.
@@ -3915,16 +5356,19 @@
2014-05-21 Werner Koch <wk@gnupg.org>
Release 1.5.0.
+ + commit 0eca21113c1d1ab2aea58e1ea21075f472f99c23
* configure.ac: Change LT version to C22/A11/R0.
2014-05-13 Werner Koch <wk@gnupg.org>
Add 6 new GPGME_STATUS_ codes.
+ + commit de6caeed6d6432101c673c35717f152d5facf823
* src/status-table.c: Also add missing DECRYPTION_INFO entry.
2014-05-08 Werner Koch <wk@gnupg.org>
Add field CURVE to the key info.
+ + commit 88f15336ec0eadde68ff2618349efb9006b8e801
* src/gpgme.h.in (struct _gpgme_subkey): Add field CURVE.
* src/key.c (gpgme_key_unref): Free CURVE.
* src/keylist.c (keylist_colon_handler): Set CURVE.
@@ -3933,11 +5377,13 @@
engine info after freeing.
Fix a memory access and a double slash bug.
+ + commit de4a1ea684e1591975feb801e7651309e1ee2c49
* src/engine-spawn.c (engspawn_start): Allocate space for list
terminator.
* src/posix-util.c (walk_path): Fix trailing slash detection.
Map public key algos returned by gpg to gpgme values.
+ + commit d5fb92cdaed21eea2f1a921e4f11df72635a8462
* src/conversion.c (_gpgme_map_pk_algo): New.
* src/decrypt.c (parse_enc_to): Add arg PROTOCOL and map pubkey algo.
(_gpgme_decrypt_status_handler): Map pubkey algo.
@@ -3953,6 +5399,7 @@
(gpgme_hash_algo_name): Add GPGME_MD_SHA224.
Add GPGME_ENCRYPT_NO_COMPRESS flag.
+ + commit 991cde9e79fec70aad093ded383c5574d30f9388
* src/gpgme.h.in (GPGME_ENCRYPT_NO_COMPRESS): New.
* src/engine-gpg.c (gpg_encrypt, gpg_encrypt_sign): Implement it.
* src/gpgme-tool.c (_cmd_sign_encrypt): Add option --no-compress.
@@ -3960,16 +5407,19 @@
2014-04-16 Werner Koch <wk@gnupg.org>
w32: Fix another memleak on error.
+ + commit 62711e5614e44e65a7c7bb7d21493d09d3081271
* src/w32-io.c (create_reader): free CTX.
2014-04-15 Werner Koch <wk@gnupg.org>
w32: Fix memleak in an error code paths.
+ + commit 85a07ca7e3dffdefc8ae74beebb59e47a6e6bd1b
* src/w32-io.c (create_writer): Free CTX in cased of bad FD.
* src/w32-util.c (_gpgme_mkstemp): Free TMPNAME in case of a failed
mkstemp.
Fix possible zombie processes.
+ + commit 2bb26185e3b9a048033c559517d6ba7d2eb47066
* src/posix-io.c (_gpgme_io_waitpid): Protect waitpid agains EINTR.
(_gpgme_io_dup): Likewise.
(_gpgme_io_connect): Likewise.
@@ -3977,12 +5427,14 @@
2014-04-10 Werner Koch <wk@gnupg.org>
Actually implement flags for gpgme_op_spawn.
+ + commit d3bd8fff863f62b6d0e228aea754efbbde861e9a
* src/spawn.c (gpgme_op_spawn_start, gpgme_op_spawn): Pass FLAGS dow
to spawn_start and add FLAGS args along the call path.
* src/engine-spawn.c (engspawn_start): Hack to automagically provide
argv[0].
Add GPGME_PROTOCOL_SPAWN and gpgme_op_spawn.
+ + commit 4f2d652e60700e03809307a10015ff9003ac3579
* src/gpgme.h.in (GPGME_PROTOCOL_SPAWN): New.
(GPGME_SPAWN_DETACHED, GPGME_SPAWN_ALLOW_SET_FG): New.
* src/gpgme.c (gpgme_set_protocol): Add new protocol.
@@ -4000,10 +5452,12 @@
(gt_spawn, cmd_spawn): New.
Add gpgme_get_dirinfo.
+ + commit 77931a9a1468b0cfbaafd4153867d90764a6d258
* src/dirinfo.c (gpgme_get_dirinfo): New.
* tests/t-engine-info.c (main): Print results from that function.
Make use of internal iospawn flags more flexible.
+ + commit 443f6b76a964b77e2e61c03592a83ffa0a6da4b1
* src/priv-io.h (IOSPAWN_FLAG_DETACHED): New. Renumber the others.
* src/w32-io.c (_gpgme_io_spawn): Use DETACHED_PROCESS process only if
IOSPAWN_FLAG_DETACHED is given.
@@ -4016,12 +5470,14 @@
* src/version.c (_gpgme_get_program_version): Ditto.
Make sure a spawned process has all standard fds connected.
+ + commit 617d3be629229cbebfdc2d26a4e854bc4fe38a68
* src/posix-io.c (_gpgme_io_spawn): dup /dev/null also to unsued
stdout.
2014-03-13 Werner Koch <wk@gnupg.org>
Add configure option --enable-fixed-path.
+ + commit 766355b5d4f63261c428531fdbdafb8b67de9369
* configure.ac: Add option --enable-fixed-path.
(FIXED_SEARCH_PATH): New ac_define.
* src/posix-util.c (walk_path): Make use of the option. Remove
@@ -4030,15 +5486,18 @@
2014-03-11 Werner Koch <wk@gnupg.org>
Avoid pointer arithmetic on void pointer.
+ + commit dd9c8c56719db093b8daa23aa40b2be71bbd1526
* src/gpgme.c (gpgme_io_writen): Use new var buffer.
Change implementation return type to match the definition.
+ + commit 75a6255935f450d56f3637cbb2b6c8161ace57ab
* src/gpgme.c (gpgme_get_sub_protocol): Change return type to
gpgme_protocol_t.
2014-03-05 Daiki Ueno <ueno@gnu.org>
doc: Fix documentation of struct data types.
+ + commit 40938feb3f3393b0cdc6ec61ca2e77ff0b82c69a
* gpgme.texi (Key Management): Document is_cardkey and card_number
members of gpgme_subkey_t.
(Decrypt): Remove description of the non-existent wrong_key_usage
@@ -4051,6 +5510,7 @@
2014-02-21 Werner Koch <wk@gnupg.org>
Always pass correct name to argv[0]. Ignore GPG_AGENT_INFO for gpg2.
+ + commit 651d9e1c6bc1cab248024c3850ef64698247588f
* src/dirinfo.c (WANT_GPG_ONE_MODE): New.
(struct dirinfo): Add field "gpg_one_mode".
(get_gpgconf_item): Set that field and return it if requested.
@@ -4067,11 +5527,13 @@
2014-02-12 Werner Koch <wk@gnupg.org>
Fix type inconsistency between gpgme.h and gpgme.c.
+ + commit f916ab753b7d17210cd455666870038949f72851
* src/gpgme.c (gpgme_set_pinentry_mode): Fix type of MODE.
2014-01-10 Werner Koch <wk@gnupg.org>
Use the generic autogen.sh script.
+ + commit 1a504aab384947c1a6e949affd14bc696297fc8d
* autogen.rc: New.
* Makefile.am (EXTRA_DIST): Add it.
* autogen.sh: Update from GnuPG.
@@ -4081,20 +5543,24 @@
2014-01-07 Werner Koch <wk@gnupg.org>
Make gpgconf engine work again - fixes 02ba35c1.
+ + commit ab6e718327451e418782990c5a0a4e72588e3f0b
* src/gpgconf.c: Remove ENABLE_GPGCONF and move prototypes to ...
* src/engine-backend.h: ... here.
Make gpgme_new return a proper error if no engines are installed.
+ + commit 121efcc5618374a1b4450b1d6a18bb3c35edb1fd
* src/engine.c (gpgme_get_engine_info): Improve error handling.
(_gpgme_engine_info_copy): Ditto.
* src/gpgme.c (gpgme_new): Return error GPG_ERR_NO_ENGINE.
Print the full PATH in the log if gpg was not found.
+ + commit d63058b852b83515e7715103c04a684ecf59838a
* src/posix-util.c (walk_path): Keep a copy of PATH.
2014-01-06 Werner Koch <wk@gnupg.org>
Add global flags disable-gpgconf, gpgconf-name, and gpg-name.
+ + commit 6564e5e78e8c6e5a120675a5699b5b75248cfbc7
* src/gpgme.c (gpgme_set_global_flag): Add names "disable-gpgconf",
"gpgconf-name", and "gpg-name".
* src/dirinfo.c (_gpgme_dirinfo_disable_gpgconf): New.
@@ -4117,6 +5583,7 @@
2013-12-27 Werner Koch <wk@gnupg.org>
Locate engine names only at runtime and prefer GnuPG-2.
+ + commit 02ba35c1b6a2cbb3361b2f2ad507c53564b2be0b
* configure.ac (NEED_GPG_VERSION, NEED_GPGSM_VERSION)
(NEED_G13_VERSION, NEED_GPGCONF_VERSION): Remove vars and all related
checks. Do not check for any engine version.
@@ -4151,23 +5618,28 @@
2013-08-19 Werner Koch <wk@gnupg.org>
Document API change for GPGME_EVENT_DONE from 2009.
+ + commit b0aaa3f9aef36634b5c391812362f016114f02ba
* doc/gpgme.texi (I/O Callback Interface): Fix description for the
event arg.
Fix possible segv in the gpgme_op_card_edit.
+ + commit 372bd439834c69d502668007c8c683233d676bd5
* src/edit.c (gpgme_op_edit_start, gpgme_op_card_edit_start): Do not
deref a NULL KEY in TRACE_BEG.
tests: Fix NULL ptr deref in gpgsm/t-verify.
+ + commit eae9c32bd9c80ca4a4ecf794808211808f2ebbdd
* tests/gpgsm/t-verify.c (check_result): Do not dereference a sig or
sig->fpr if NULL.
2013-08-12 Werner Koch <wk@gnupg.org>
Release 1.4.3.
+ + commit d788c35e19df9eade8eb0b880ca1dc47ae7928ad
* configure.ac: Change LT version to C22/A11/R0.
Make test suite workable with GnuPG 2.1.
+ + commit 3ca7e96e384d5872c71ceb3b2e2a05b0c1b7e1a0
* tests/gpg/start-stop-agent: New.
* tests/gpg/initial.test: New.
* tests/gpg/final.test: New.
@@ -4186,12 +5658,14 @@
* tests/gpg/A0747D5F9425E6664F4FFBEED20FBCA79FDED2BD: New.
Improve detection of default gpg by configure.
+ + commit 069ac580373923f5635b7172ecff79eb189f6944
* configure.ac: Move test for gpgconf before test for gpg.
(GPG, GPGSM, G13): Use gpgconf instead of AC_PATH_PROG if possible.
2013-08-09 Werner Koch <wk@gnupg.org>
Add function gpgme_data_identify.
+ + commit 8579091c4f6a36e6bb06fcfbd147a776166fd3ea
* src/gpgme.h.in (gpgme_data_type_t): New.
(gpgme_data_identify): New prototype.
* src/data-identify.c: New.
@@ -4206,6 +5680,7 @@
2013-08-02 Werner Koch <wk@gnupg.org>
Prefer GnuPG-2 engines over GnuPG-1.
+ + commit a4c80126ae4754c8478c69a8a24a6ffd975485fc
* src/util.h: Move some prototypes to ...
* src/sys-util.h: New.
* src/Makefile.am (main_sources): Add sys-util.h.
@@ -4232,6 +5707,7 @@
(_gpgme_get_uiserver_socket_path): Remove.
w32: Try to locate gpg in the gpgme installation dir.
+ + commit 3881ea4e83d1533ef497b7332398fc1850e29205
* src/w32-util.c (my_hmodule): New.
(wchar_to_utf8): New.
(DllMain): New.
@@ -4246,10 +5722,13 @@
2013-07-31 Werner Koch <wk@gnupg.org>
doc: Add --binary option for the OUTPUT command of an uiserver.
+ + commit 393a9471f2f3ac0a5b14f3534a5bfc7ffe948567
+
2013-06-18 Werner Koch <wk@gnupg.org>
Add function gpgme_signers_count.
+ + commit f2eeccbdfaf855a81abb92abe5ab4c702712bac7
* src/signers.c (gpgme_signers_count): New.
* src/libgpgme.vers, src/gpgme.def: Add as external symbol.
* src/gpgme.h.in: Add prototype.
@@ -4257,17 +5736,21 @@
2013-05-28 Werner Koch <wk@gnupg.org>
Release 1.4.2.
+ + commit 009e26a989f8a251563303f155c51fe012af52a4
* configure.ac: Set LT version to C21/A10/R0.
Add convenience macro GPGME_PROTOCOL_OPENPGP.
+ + commit 2e8feb6016dede400053f76fc3a418e1dd567bef
* src/gpgme.h.in (GPGME_PROTOCOL_OPENPGP): New.
2013-05-23 Werner Koch <wk@gnupg.org>
w32: Fix installing of .def file.
+ + commit c29dad2315406bed75b9547103650bef642e6aa7
* src/Makefile.am (install-def-file): Create libdir first.
Fix libtool 2.4.2 to correctly detect .def files.
+ + commit d739d4d8cf9c873b0f3bb7836aaf3d0ba31a7b7f
* build-aux/ltmain.sh (sed_uncomment_deffile): New.
(orig_export_symbols): Uncomment def file before testing for EXPORTS.
* m4/libtool.m4: Do the same for the generated code.
@@ -4275,6 +5758,7 @@
2013-05-22 Werner Koch <wk@gnupg.org>
Support --no-encrypt-to also with gpgme_op_encrypt_sign.
+ + commit d4371ed30da2e8b3d9f440613af299a952bde2b1
* src/engine-gpg.c (gpg_encrypt_sign): Support the
GPGME_ENCRYPT_NO_ENCRYPT_TO flag.
@@ -4282,6 +5766,7 @@
Kyle L. Huff <g10bts@curetheitch.com>
Allow symmetric encryption with gpgme_op_encrypt_sign.
+ + commit 567e6481d767af60390d649897b897a8b0e7e9a5
* src/encrypt-sign.c (encrypt_sym_status_handler): New.
(encrypt_sign_start): Handle recp == NULL case.
* src/engine-gpg.c (gpg_encrypt_sign): Implement symmetric encryption.
@@ -4290,21 +5775,25 @@
2013-05-22 Werner Koch <wk@gnupg.org>
gpgme-tool: Allow for symmetric encryption.
+ + commit 0c1de7abd57b677998792e6cd5df5ddfb6e451b7
* src/gpgme-tool.c (gt_sign_encrypt): Pass NULL for recp if no
recipients are given.
tests: Print auditlog in plain text format.
+ + commit 18254f88f82da7542a986dca60917fb48d5bccd3
* tests/gpgsm/t-verify.c (show_auditlog): Use plain text format.
2013-05-18 Werner Koch <wk@gnupg.org>
Improve C++ compatibility of previous patch.
+ + commit e99356306d7bda61802530ebeb07d9ba73c4dec0
* src/gpgme.h.in: Move gpgme_sssize_t and gpgme_off_t typedefs into
the extern "C" scope.
2013-05-16 Werner Koch <wk@gnupg.org>
Make definition of off_t robust against misbehaving w32 toolchains.
+ + commit 6d0d8e7ba0bb989c251545fa8af35b97d1a703ba
* configure.ac (NEED__FILE_OFFSET_BITS): Change to define gpgme_off_t
and gpgme_ssize_t.
(API__OFF_T, API__SSIZE_T): New ac_subst.
@@ -4319,6 +5808,7 @@
2013-05-11 Werner Koch <wk@gnupg.org>
w32: Change the way the I/O threads are cleaned up.
+ + commit 9e7df9aa6d81f0abbabb03a2346d80eb5d375f81
* src/w32-io.c (reader_context_s, create_reader)
(writer_context_s, create_writer): Rename STOPPED to CLOSE_EV.
(reader, writer): Remove setting of STOPPED. Wait for CLOSE_EV and
@@ -4330,46 +5820,56 @@
2013-05-08 Werner Koch <wk@gnupg.org>
Fix hang in socket closing.
+ + commit 9f330be8210d2498fe93d4166b6f6c02fca76475
* src/w32-io.c (destroy_reader): Call shutdown.
(reader): Do not print an error in the shutdown case.
Improve debug output of the I/O reader and writer.
+ + commit 2118f497010a9a41c29d062a7605ff2e136f8f4e
* src/w32-io.c (reader, writer): Also print file_sock.
2013-05-06 Werner Koch <wk@gnupg.org>
Simplify a debug code function.
+ + commit a7e5f1096f02af7bfb678b0bea8da6ccfc28cc79
* src/debug.c (_gpgme_debug): Remove static space string.
2013-05-01 Werner Koch <wk@gnupg.org>
Release 1.4.1.
+ + commit 5075c0da7c464af2a45cd36db134ed7e88f155af
* configure.ac: Bump LT version to C20/A9/R1.
Disable fd-passing for Apple.
+ + commit ef5b4ae37d13142e89a051908dc080cda3d24baa
* configure.ac: Disable fd-passing by default for Apple.
2013-04-30 Werner Koch <wk@gnupg.org>
Allow reading of long gpgconf output lines.
+ + commit f623a6b94c527795d0b6f7e66a3966e5d9e1c454
* src/engine-gpgconf.c (gpgconf_read): Rewrite to allow for line
lengths up to 64k.
2013-04-29 Werner Koch <wk@gnupg.org>
Fix for i686-w64-mingw32.
+ + commit 867b950b9306904a0ff522d0ef4a43789393cfc4
* configure.ac (NEED__FILE_OFFSET_BITS): Do not define under Windows.
2013-02-26 Werner Koch <wk@gnupg.org>
Release 1.4.0.
+ + commit ef5cd38123dfbef7843f374ee697b0b5e8730c46
* configure.ac: Bump LT version to C20/A9/R0.
Enable FD passing and thus building of the UI-server.
+ + commit 5090f6f246bfad2eb80f3cc222963f73996d8028
* configure.ac: Make --enable-fd-passing the default.
* src/engine-uiserver.c (_gpgme_engine_ops_uiserver): Syntax fix.
w32: Hacks for building with 32 bit mingw64.
+ + commit cdae524b282ef0ea67c3880b3e0f852c84c351ce
* configure.ac (INSERT__TYPEDEFS_FOR_GPGME_H): Add hacks for 32 bit
mingw64.
* src/util.h [W32]: Include winsock2.h before windows to make mingw64
@@ -4377,10 +5877,12 @@
* src/w32-util.c (_WIN32_IE): Need to use 5.1 for mingw64.
Improve missing libgpg-error reporting in configure.
+ + commit 787b5f14b933e5cee2624f79a23a60947f8134c8
* configure.ac (NEED_GPG_ERROR_VERSION): New. Improve reporting for
missing libgpg-error.
Change the various version numbers to the new scheme.
+ + commit d8b46c919f45666af0d541e00dcedf57e6c4b66f
* configure.ac: Rename my_foo variables to mym4_foo variables to make
clear that they are processed by m4.
(VERSION_NUMBER): New ac_subst.
@@ -4395,10 +5897,12 @@
* tests/t-version.c (main): Add option --verbose.
Update GnuPG related m4 files.
+ + commit 863c0f2a3eaf2a5d46c5518e5ac3486cc1a49bd3
* m4/gpg-error.m4: Update from libgpg-error.
* m4/libassuan.m4: Update from libassuan.
Update helper scripts.
+ + commit fdcd5736e610cd64e47da73dcafe8bc4a6a67666
* configure.ac: Use AC_CONFIG_AUX_DIR. Remove args from
AM_INIT_AUTOMAKE. Replace AM_CONFIG_HEADER by AC_CONFIG_HEADER.
* compile, config.guess, config.sub, depcomp, install-sh, ltmain.sh
@@ -4412,6 +5916,7 @@
2013-02-25 Werner Koch <wk@gnupg.org>
Remove included gitlog-to-changelog.
+ + commit 967e043ac42330ee692f23d05ce3a0dd457f2119
* build-aux/gitlog-to-changelog: Remove.
* configure.ac (GITLOG_TO_CHANGELOG): Default to just
gitlog-to-changelog.
@@ -4419,6 +5924,7 @@
2013-02-12 Werner Koch <wk@gnupg.org>
Add macro GPGME_VERSION_NUMBER.
+ + commit f48f75b1e812d33b76e439412efffa8277ab9abe
* src/gpgme.h.in (GPGME_VERSION_NUMBER): New.
* configure.ac (my_version_major, my_version_minor)
(my_version_micro): New m4 macros.
@@ -4426,11 +5932,13 @@
(VERSION_NUMBER): New ac_subst.
Add public function gpgme_get_pinentry_mode.
+ + commit 4f381554411ef019d79492f1751543f145604bcf
* src/gpgme.c (gpgme_get_pinentry_mode): New.
2013-02-07 Werner Koch <wk@gnupg.org>
gpgme_tool: Support GPG's new pinentry-mode.
+ + commit 02a2cf0ccb4d01700adf6d18316d7705d519a048
* src/gpgme-tool.c (log_error): Do not always print the error source.
(gt_set_pinentry_mode): New.
(server_passphrase_cb): New.
@@ -4441,6 +5949,7 @@
(parse_options, main): Implement that option.
Add public function gpgme_set_pinentry_mode.
+ + commit 61a0d92b679f248505f1bf16386bc41a5bf2ba1d
* src/gpgme.c (gpgme_set_pinentry_mode): New.
* src/gpgme.h.in (gpgme_pinentry_t): New.
(gpgme_set_pinentry_mode): New.
@@ -4453,61 +5962,73 @@
(_gpgme_engine_ops_gpg): Register gpg_set_pinentry_mode.
Add public function gpgme_io_writen.
+ + commit 29eced50687dd8a39dafe704102ae09ea8e8533a
* src/gpgme.c (gpgme_io_read): New.
2012-11-16 Werner Koch <wk@gnupg.org>
Improve parsing of the GIT revision number.
+ + commit 322552a88db47896881e55c00ca301137cd160c6
* configure.ac (git_revision): Use git rev-parse.
Fix non-portable use of chmod in autogen.sh.
+ + commit cd6de92f42cb6e5b85bc376d5544496cb4d6a88a
* autogen.sh: Remove option -c from chmod.
2012-11-15 Werner Koch <wk@gnupg.org>
Make _gpgme_encode_percent_string work for memory buffers.
+ + commit 1a17acd8e9b7c0ef924f98bfb1502fe12e83c363
* src/conversion.c (D_gpgme_encode_percent_string): Remove stray
semicolon. Reported by Xi Wang.
2012-10-24 Werner Koch <wk@gnupg.org>
Make local variables configure hack more robust.
+ + commit c97d067f27899d890a99036fcbed9263f4f68875
* configure.ac (emacs_local_vars_begin): Use extra m4 quoting so that
newer Emscasen won't take it up as Local Variables for this file.
Fix ttyname problem on Android.
+ + commit 12a0c93433a0b1d7e8019fc35a63476db39327fa
* configure.ac: Define macro and conditional HAVE_ANDROID_SYSTEM.
* m4/gnupg-ttyname.m4: Force use of replacement on Android.
* src/ttyname_r.c: Ditto.
tests: Adhere to the docs and call gpgme_check_version.
+ + commit cc59b75b21516198b39a56950afbcec140d8ba48
* tests/t-engine-info.c: Call gpgme_check_version.
2012-10-19 Werner Koch <wk@gnupg.org>
Trace the use of GPG_ERR_INV_ENGINE.
+ + commit bd24feaa86f8154e550107990392ac9ac05e60d4
* src/debug.h: Include "gpgme.h"
(_gpgme_trace_gpgme_error): New.
(trace_gpg_error): New macro. Use it in all files where we return
GPG_ERR_INV_ENGINE; also "include debug.h" as needed.
Avoid warning about initialized but not used variable.
+ + commit 14a8fd4eec126cad282a85c5aa336a6b55229b52
* src/engine-gpgsm.c (gpgsm_set_fd): Do not set DIR if not needed.
2012-10-11 Werner Koch <wk@gnupg.org>
gpgme-tool: Use membuf functions to build up strings.
+ + commit e11e7fc5586613525035c3358e15ae24accb96ea
* src/gpgme-tool.c (clear_membuf, init_membuf, put_membuf)
(put_membuf_str, get_membuf, peek_membuf): Add membuf functions.
Take from GnuPG master's common/membuf.[ch] and patch for our use.
(result_xml_escape): Rewrite using new functions.
gpgme-tool: Change license from LPGLv2+ to GPLv3+
+ + commit aa30b47aa010bf46876f2335e288f8bd8718e396
* src/gpgme-tool.c: Change license notice.
2012-10-11 W. Trevor King <wking@tremily.us>
gpgme-tool: escape special characters in output XML data (<, >, and &).
+ + commit 3f1329e1c9b99b1632cc4c4eec2e4399676fd93d
src/gpgme-tool.c (result_xml_escape_replacement, result_xml_escape):
New.
@@ -4515,12 +6036,14 @@
(result_add_error): Use unescaped < and >.
gpgme-tool: Fix chain_id -> chain-id in KEYLIST XML.
+ + commit c28ebca9f2e21344d68e9fdcec60553f225c2e54
src/gpgme-tool.c (cmd_keylist): Use <chain-id> instead of <chain_id>.
2012-09-28 W. Trevor King <wking@tremily.us>
gpgme-tool: Return more detailed XML from KEYLIST.
+ + commit 3d69b51f7f083193db28f364da4590c33b5e44e6
src/gpgme-tool.c (cmd_keylist): Convert output from a list of
to more detailed XML.
(xml_preamble1, xml_preamble2, xml_end): Make global.
@@ -4531,11 +6054,13 @@
value returned by gpgme_get_protocol_name directly.
gpgme-tool: Initialize input_fd and output_fd.
+ + commit dda3702a9024a08da7bb949e15b63a47d23d59f5
* src/gpgme-tool.c (gpgme_server): Initialize input_fd and output_fd.
2012-09-26 Werner Koch <wk@gnupg.org>
gpgme-tool: Fix handling of file descriptors.
+ + commit 193eb62538b9413e0dfbd04c075f871d5aa9130b
* src/gpgme-tool.c (server_reset_fds): Use close/CloseHandle instead
of the assuan close functions.
(_cmd_decrypt_verify, _cmd_sign_encrypt, cmd_verify, cmd_import)
@@ -4545,11 +6070,13 @@
2012-09-25 Werner Koch <wk@gnupg.org>
Document contribution rules.
+ + commit db33945ab3b8c173a3fc2dd1a0d22d7fc15d8730
* doc/HACKING (License policy): New.
* doc/DCO: New.
* AUTHORS: Change maintainer address.
Add gpgme_set_global_flag to help debugging.
+ + commit c62b79a1d6e576d94e08cb81c2f5dbcb42ecf8cf
* src/gpgme.c (gpgme_set_global_flag): New.
* src/gpgme.h.in (gpgme_set_global_flag): New.
* src/gpgme.def, src/libgpgme.vers: Add new public function.
@@ -4560,55 +6087,69 @@
2012-07-28 Marcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
Add two recent contributors.
+ + commit 83e74202cd7c4c975d149c49e2507fdb0e60ef32
+
Fix sign error in position calculation for mem_seek.
+ + commit 8384ccbd1a51447dccbd608fc5df3c24cb8999b1
* data-mem.c (mem_seek): Fix sign error in position calculation.
Allow null context on gpgme_set_locale.
+ + commit 434735f71e6969248651ac01c6bd6f6789a6305d
* gpgme.c (gpgme_set_locale): Allow CTX to be a null pointer.
2012-07-13 Werner Koch <wk@gnupg.org>
Do not include the removed file status-table.h.
+ + commit e7aeaebb01395b170c91f290bf3ff5021023420f
* src/engine-uiserver.c: Remove status-table.h which is not anymore
built. Fixes bug#1412.
Make handling of new conf values more robust (bug#1413).
+ + commit 9f081da7356288a96e8ea4d81a74ff706c00b0cd
* src/engine-gpgconf.c (arg_to_data): Allow for NULL as value.string.
2012-05-02 Werner Koch <wk@gnupg.org>
Release 1.3.2.
+ + commit 9c8608f702ec0f44ae55cd7f33bd8df0a2d48508
* configure.ac: Bump LT version to C19/A8/R1.
* configure.ac (GITLOG_TO_CHANGELOG): Define.
* Makefile.am (gen-ChangeLog): Use it.
Remove unused pth stuff from gpgme-config.
+ + commit 295dd3f238fa656493d34e8a718958d62226b56c
* src/gpgme-config.in: Remove unused pth stuff.
Update signature summary for the case of missing X.509 keys.
+ + commit d6402b888fd00b883bbfc00c91a2aa9706e4377e
* src/verify.c (gpgme_op_verify_result): Update summary field.
2012-04-30 Werner Koch <wk@gnupg.org>
Fix timestamp parsing for y2038 hack.
+ + commit 1a21574b48ee91eedbf95251ee600648b377d1e7
* src/conversion.c (_gpgme_parse_timestamp): Set ENDP before year 2038
check.
2012-04-20 W. Trevor King <wking@drexel.edu>
.gitignore: flesh out rules and add subdirectory-.gitignores.
+ + commit 4cb408d33efe80e7d102049dea244d22907d8395
+
2012-04-13 W. Trevor King <wking@drexel.edu>
status-table.c: include string.h for strcmp.
+ + commit 62bbe58280737d73badbe518f140e40480205176
* status-table.c: include string.h to avoid `warning: implicit
declaration of function 'strcmp'`.
2012-04-03 W. Trevor King <wking@drexel.edu>
gpgme-tool: add help messages for a number of commands.
+ + commit c318e69d8fa5f9e92d4aac3dd44fae5adcaade72
* src/gpgme-tool.c (hlp_engine, hlp_sub_protocol, hlp_armor, hlp_textmode,
hlp_include_certs, hlp_keylist_mode, hlp_input, hlp_output, hlp_message,
hlp_recipient, hlp_signer, hlp_signers_clear, hlp_decrypt, hlp_decrypt_verify,
@@ -4618,22 +6159,27 @@
(doc): Mention Assuan.
uiserver.texi: fix decryption -> encryption typo in PREP_ENCRYPT discussion.
+ + commit bb62104adf78e8416b3c56b8b2621edd723b56cd
* doc/uiserver.texi (PREP_ENCRYPT): Fix documentation.
Update Werner Koch's distribution signing key in the README.
+ + commit 6ec9e21dd1ea2f8509700bce018aef6ad7e9a927
* README: Update signing key.
2012-03-12 Marcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
Do not rely on glibc name of syscall.
+ + commit ff0a640a18e7b7457e6c2edfdc8307bf44628b60
* src/ath.c (ath_self): Use __NR_gettid, not SYS_gettid.
Update config.guess and config.sub to latest version.
+ + commit ced1ad01aed32d1e4c5000f3b901db018ef7bf1e
* config.guess, config.sub: Update to latest version.
2012-02-14 Marcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
Rework status table to be less dynamically generated.
+ + commit 885243e05467e79e2375b3febe7904053ab45dfc
* src/Makefile.am (EXTRA_DIST): Remove mkstatus.
(BUILT_SOURCE, MOSTLYCLEANFILES): Remove.
(main_sources): Remove status-table.h, extra-stati.h.
@@ -4660,6 +6206,7 @@
2012-02-08 Marcus Brinkmann <mb@g10code.com>
Use gpgme interface for error handling to avoid linking with gpg-error.
+ + commit dae3073aaa8b7feb1c844fdaf711f79141b9cc65
* tests/t-data.c, tests/run-export.c, tests/run-keylist.c,
tests/run-support.h, tests/run-verify.c, tests/gpg/t-decrypt-verify.c,
tests/gpg/t-edit.c, tests/gpg/t-eventloop.c, tests/gpg/t-keylist-sig.c,
@@ -4670,17 +6217,21 @@
tests/opassuan/t-command.c: Use gpgme interface for gpg-error functions.
Link the thread test to pthread.
+ + commit 0052a72f89c6830818e354358fdd84702d3494c8
* tests/gpg/Makefile.am (t_thread1_LDADD): Add -lpthread.
Link gpgme-tool directly to libassuan, as it uses its interface.
+ + commit 3f03897cbd223d4a75eb62c3b7bdfeb800661641
* src/Makefile.am (gpgme_tool_LDADD): Add @LIBASSUAN_LIBS@.
2012-01-19 Werner Koch <wk@gnupg.org>
Support the mingw-w64 toolchain.
+ + commit 24a10a4af948ebb1c767b69a92fa5bbe933a417c
* autogen.sh (build-w32): Add i686-w64-mingw32 to the toolprefix.
Fix Solaris problems with ttyname_r.
+ + commit 2f304957f5122a5d9da643dc9951ee67ece06eaf
* m4/gnupg-ttyname.m4: New. Based on ttyname_r from gnulib.
* src/ttyname_r.c (_gpgme_ttyname_r): Rename from ttyname_r.
Implement hacks required for Solaris and possible other non-fully
@@ -4689,9 +6240,11 @@
REPLACE_TTYNAME_R and put it into the gpgme name space.
Try to make configure.ac a bit smaller.
+ + commit c96778297f5477448a676fcf0c61044bdbccc86d
* configure.ac: Move header checks.
For W32 use a build number instead of abbreviated commit id.
+ + commit 574b087e84f5652cf9d8eba8aa16b8d6bb988035
We would need to use a shortened commit id so that it fits into an 16
bit Windows variable. Further it is a random number and not something
increasing. Thus a build number made up from the day of the year and
@@ -4701,18 +6254,22 @@
* src/versioninfo.rc.in: Ditto.
Adjust configure.ac for modern autoconf.
+ + commit a0149630ce6d3e17a7475e20e8b2e31ed5ba57fd
* configure.ac: Minor cleanups.
Update to libtool 2.4.2.
+ + commit 4cfddadcd0a569f0b204dccea3c975ce0bdfb232
* ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4,
* m4/lt~obsolete.m4: Update.
Add ttyname_r check macro from gnulib.
+ + commit 3ef528b63679df912551d5d21fc36e465cf50c40
* m4/gnupg-ttyname.m4: New. Taken from current gnulib.
2011-12-02 Werner Koch <wk@gnupg.org>
Generate the ChangeLog from commit logs.
+ + commit a4c4ee1aaea4359432bdf60dd572f549ef8dee83
* build-aux/gitlog-to-changelog: New script. Taken from gnulib.
* build-aux/git-log-fix: New file.
* build-aux/git-log-footer: New file.
diff --git a/Makefile.in b/Makefile.in
index 0dd976e..ec5f752 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -123,8 +123,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
diff --git a/NEWS b/NEWS
index bbafdeb..f1c3290 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,85 @@
+Noteworthy changes in version 1.9.0 (2017-03-28)
+------------------------------------------------
+
+ * Clarified meaning of the 'expire' parameter of gpgme_op_createkey
+ and gpgme_op_createsubkey. New flag to force a key without an
+ expiration date.
+
+ * New function gpgme_op_keylist_from_data_start to list keys from
+ data objects without importing them.
+
+ * New function gpgme_op_set_uid_flag to flag a key as primary.
+
+ * New function gpgme_op_decrypt_ext to run decryption with special
+ flags. This can for example be used to unwrap keys (remove only
+ the encryption layer).
+
+ * New encryption flags to wrap a key (adding an encryption layer to
+ an OpenPGP message) or to create anonymously encrypted messages.
+
+ * Support for adduid and revuid operations in the C++ bindings.
+
+ * Support for smartcard key generation in the C++ bindings.
+
+ * Several new functions for the Python binding.
+
+ * Many smaller bug fixes.
+
+
+ * Interface changes relative to the 1.8.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gpgme_op_createkey CHANGED: Meaning of 'expire' parameter.
+ gpgme_op_createsubkey CHANGED: Meaning of 'expire' parameter.
+ GPGME_CREATE_NOEXPIRE NEW.
+ gpgme_key_t EXTENDED: New field 'origin'.
+ gpgme_key_t EXTENDED: New field 'last_update'.
+ gpgme_subkey_t EXTENDED: New field 'is_de_vs'.
+ gpgme_user_id_t EXTENDED: New field 'origin'.
+ gpgme_user_id_t EXTENDED: New field 'last_update'.
+ gpgme_op_keylist_from_data_start NEW.
+ gpgme_op_set_uid_flag_start NEW.
+ gpgme_op_set_uid_flag NEW.
+ gpgme_op_decrypt_ext_start NEW.
+ gpgme_op_decrypt_ext NEW.
+ GPGME_ENCRYPT_THROW_KEYIDS NEW.
+ GPGME_ENCRYPT_WRAP NEW.
+ GPGME_DECRYPT_VERIFY NEW.
+ GPGME_DECRYPT_UNWRAP 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.
+ cpp: Context::startAddUid(const Key&, const char*) NEW.
+ cpp: Key::UserID::revoke() NEW.
+ cpp: Key::addUid() NEW.
+ cpp: Key::isDeVs NEW.
+ cpp: GpgGenCardKeyInteractor NEW.
+ cpp: Subkey::keyGrip NEW.
+ cpp: Subkey::isDeVs NEW.
+ cpp: Data::toKeys NEW.
+ cpp: Context::setDecryptFlags NEW.
+ cpp: Context::decrypt EXTENDED: Flags added.
+ cpp: Context::startDecrypt EXTENDED: Flags added.
+ cpp: Context::decryptAndVerify EXTENDED: Flags added.
+ cpp: Context::startCombinedDecryptionAndVerification EXTENDED: Flags.
+ cpp: Context::encryptFlags EXTENDED: New flags.
+ qt: CryptoConfig::stringValueList() NEW.
+ py: Context.__init__ EXTENDED: New keyword arg home_dir.
+ py: Context.home_dir NEW.
+ py: Context.keylist EXTENDED: New keyword arg mode.
+ py: Context.keylist EXTENDED: New keyword arg source.
+ py: Context.create_key NEW.
+ py: Context.create_subkey NEW.
+ py: Context.key_add_uid NEW.
+ py: Context.key_revoke_uid NEW.
+ py: Context.key_sign NEW.
+ py: Context.key_tofu_policy NEW.
+ py: core.pubkey_algo_string NEW.
+ py: core.addrspec_from_uid NEW.
+
+ [c=C29/A18/R0 cpp=C10/A4/R0 qt=C9/A2/R0]
+
+
Noteworthy changes in version 1.8.0 (2016-11-16)
------------------------------------------------
diff --git a/README b/README
index b7483b2..214ea87 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
GPGME - GnuPG Made Easy
---------------------------
- Copyright 2001-2016 g10 Code GmbH
+Copyright 2001-2017 g10 Code GmbH
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
@@ -70,7 +70,7 @@ a) If you have a trusted Version of GnuPG installed, you can simply check
indeed a a signature of gpgme-x.y.z.tar.gz. The key used to create
this signature is either of:
- 2048R/4F25E3B6 2011-01-12 [expires: 2019-12-31]
+ rsa2048/4F25E3B6 2011-01-12 [expires: 2019-12-31]
Key fingerprint = D869 2123 C406 5DEA 5E0F 3AB5 249B 39D2 4F25 E3B6
Werner Koch (dist sig)
@@ -86,10 +86,14 @@ a) If you have a trusted Version of GnuPG installed, you can simply check
Key fingerprint = D238 EA65 D64C 67ED 4C30 73F2 8A86 1B1C 7EFD 60D9
Werner Koch (Release Signing Key)
+ rsa3072/4B092E28 2017-03-17 [expires: 2027-03-15]
+ Key fingerprint = 5B80 C575 4298 F0CB 55D8 ED6A BCEF 7E29 4B09 2E28
+ Andre Heinecke (Release Signing Key)
+
You may retrieve these files from the keyservers using this command
gpg --recv-keys 249B39D24F25E3B6 04376F3EE0856959 \
- 2071B08A33BD3F06 8A861B1C7EFD60D9
+ 2071B08A33BD3F06 8A861B1C7EFD60D9 BCEF7E294B092E28
The keys are also available at https://gnupg.org/signature_key.html
and in released GnuPG tarballs in the file g10/distsigkey.gpg .
diff --git a/VERSION b/VERSION
index 27f9cd3..f8e233b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.8.0
+1.9.0
diff --git a/aclocal.m4 b/aclocal.m4
index 16ee295..8c1c40d 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -882,241 +882,6 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-
-# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-# ---------------------------------------------------------------------------
-# Adds support for distributing Python modules and packages. To
-# install modules, copy them to $(pythondir), using the python_PYTHON
-# automake variable. To install a package with the same name as the
-# automake package, install to $(pkgpythondir), or use the
-# pkgpython_PYTHON automake variable.
-#
-# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
-# locations to install python extension modules (shared libraries).
-# Another macro is required to find the appropriate flags to compile
-# extension modules.
-#
-# If your package is configured with a different prefix to python,
-# users will have to add the install directory to the PYTHONPATH
-# environment variable, or create a .pth file (see the python
-# documentation for details).
-#
-# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will
-# cause an error if the version of python installed on the system
-# doesn't meet the requirement. MINIMUM-VERSION should consist of
-# numbers and dots only.
-AC_DEFUN([AM_PATH_PYTHON],
- [
- dnl Find a Python interpreter. Python versions prior to 2.0 are not
- dnl supported. (2.0 was released on October 16, 2000).
- m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
-[python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
- python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
-
- AC_ARG_VAR([PYTHON], [the Python interpreter])
-
- m4_if([$1],[],[
- dnl No version check is needed.
- # Find any Python interpreter.
- if test -z "$PYTHON"; then
- AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :)
- fi
- am_display_PYTHON=python
- ], [
- dnl A version check is needed.
- if test -n "$PYTHON"; then
- # If the user set $PYTHON, use it and don't search something else.
- AC_MSG_CHECKING([whether $PYTHON version is >= $1])
- AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
- [AC_MSG_RESULT([yes])],
- [AC_MSG_RESULT([no])
- AC_MSG_ERROR([Python interpreter is too old])])
- am_display_PYTHON=$PYTHON
- else
- # Otherwise, try each interpreter until we find one that satisfies
- # VERSION.
- AC_CACHE_CHECK([for a Python interpreter with version >= $1],
- [am_cv_pathless_PYTHON],[
- for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do
- test "$am_cv_pathless_PYTHON" = none && break
- AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break])
- done])
- # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
- if test "$am_cv_pathless_PYTHON" = none; then
- PYTHON=:
- else
- AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON])
- fi
- am_display_PYTHON=$am_cv_pathless_PYTHON
- fi
- ])
-
- if test "$PYTHON" = :; then
- dnl Run any user-specified action, or abort.
- m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
- else
-
- dnl Query Python for its version number. Getting [:3] seems to be
- dnl the best way to do this; it's what "site.py" does in the standard
- dnl library.
-
- AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
- [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
- AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
-
- dnl Use the values of $prefix and $exec_prefix for the corresponding
- dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made
- dnl distinct variables so they can be overridden if need be. However,
- dnl general consensus is that you shouldn't need this ability.
-
- AC_SUBST([PYTHON_PREFIX], ['${prefix}'])
- AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}'])
-
- dnl At times (like when building shared libraries) you may want
- dnl to know which OS platform Python thinks this is.
-
- AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform],
- [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
- AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
-
- # Just factor out some code duplication.
- am_python_setup_sysconfig="\
-import sys
-# Prefer sysconfig over distutils.sysconfig, for better compatibility
-# with python 3.x. See automake bug#10227.
-try:
- import sysconfig
-except ImportError:
- can_use_sysconfig = 0
-else:
- can_use_sysconfig = 1
-# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
-# <https://github.com/pypa/virtualenv/issues/118>
-try:
- from platform import python_implementation
- if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
- can_use_sysconfig = 0
-except ImportError:
- pass"
-
- dnl Set up 4 directories:
-
- dnl pythondir -- where to install python scripts. This is the
- dnl site-packages directory, not the python standard library
- dnl directory like in previous automake betas. This behavior
- dnl is more consistent with lispdir.m4 for example.
- dnl Query distutils for this directory.
- AC_CACHE_CHECK([for $am_display_PYTHON script directory],
- [am_cv_python_pythondir],
- [if test "x$prefix" = xNONE
- then
- am_py_prefix=$ac_default_prefix
- else
- am_py_prefix=$prefix
- fi
- am_cv_python_pythondir=`$PYTHON -c "
-$am_python_setup_sysconfig
-if can_use_sysconfig:
- sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
-else:
- from distutils import sysconfig
- sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
-sys.stdout.write(sitedir)"`
- case $am_cv_python_pythondir in
- $am_py_prefix*)
- am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
- am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
- ;;
- *)
- case $am_py_prefix in
- /usr|/System*) ;;
- *)
- am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
- ;;
- esac
- ;;
- esac
- ])
- AC_SUBST([pythondir], [$am_cv_python_pythondir])
-
- dnl pkgpythondir -- $PACKAGE directory under pythondir. Was
- dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is
- dnl more consistent with the rest of automake.
-
- AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE])
-
- dnl pyexecdir -- directory for installing python extension modules
- dnl (shared libraries)
- dnl Query distutils for this directory.
- AC_CACHE_CHECK([for $am_display_PYTHON extension module directory],
- [am_cv_python_pyexecdir],
- [if test "x$exec_prefix" = xNONE
- then
- am_py_exec_prefix=$am_py_prefix
- else
- am_py_exec_prefix=$exec_prefix
- fi
- am_cv_python_pyexecdir=`$PYTHON -c "
-$am_python_setup_sysconfig
-if can_use_sysconfig:
- sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
-else:
- from distutils import sysconfig
- sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
-sys.stdout.write(sitedir)"`
- case $am_cv_python_pyexecdir in
- $am_py_exec_prefix*)
- am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
- am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
- ;;
- *)
- case $am_py_exec_prefix in
- /usr|/System*) ;;
- *)
- am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
- ;;
- esac
- ;;
- esac
- ])
- AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir])
-
- dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE)
-
- AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE])
-
- dnl Run any user-specified action.
- $2
- fi
-
-])
-
-
-# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
-# ---------------------------------------------------------------------------
-# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION.
-# Run ACTION-IF-FALSE otherwise.
-# This test uses sys.hexversion instead of the string equivalent (first
-# word of sys.version), in order to cope with versions such as 2.2c1.
-# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000).
-AC_DEFUN([AM_PYTHON_CHECK_VERSION],
- [prog="import sys
-# split strings by '.' and convert to numeric. Append some zeros
-# because we need at least 4 digits for the hex conversion.
-# map returns an iterator in Python 3.0 and a list in 2.x
-minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]]
-minverhex = 0
-# xrange is not present in Python 3.0 and range returns an iterator
-for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
-sys.exit(sys.hexversion < minverhex)"
- AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
-
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
@@ -1469,5 +1234,6 @@ m4_include([m4/ltsugar.m4])
m4_include([m4/ltversion.m4])
m4_include([m4/lt~obsolete.m4])
m4_include([m4/pkg.m4])
+m4_include([m4/python.m4])
m4_include([m4/qt.m4])
m4_include([acinclude.m4])
diff --git a/config.h.in b/config.h.in
index 8df7cbe..385c17d 100644
--- a/config.h.in
+++ b/config.h.in
@@ -27,6 +27,9 @@
/* Define if ttyname_r is does not work with small buffers */
#undef HAVE_BROKEN_TTYNAME_R
+/* Define to 1 if you have the `closefrom' function. */
+#undef HAVE_CLOSEFROM
+
/* define if the compiler supports basic C++11 syntax */
#undef HAVE_CXX11
@@ -44,15 +47,9 @@
/* Define to 1 if the system has the type `error_t'. */
#undef HAVE_ERROR_T
-/* Define to 1 if you have the `fopencookie' function. */
-#undef HAVE_FOPENCOOKIE
-
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#undef HAVE_FSEEKO
-/* Define to 1 if you have the `funopen' function. */
-#undef HAVE_FUNOPEN
-
/* Define to 1 if you have the `getegid' function. */
#undef HAVE_GETEGID
@@ -68,15 +65,15 @@
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
+/* Defined if we build for an MacOS system */
+#undef HAVE_MACOS_SYSTEM
+
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define if the ttyname_r function has a POSIX compliant declaration. */
#undef HAVE_POSIXDECL_TTYNAME_R
-/* If available, contains the Python version number currently in use. */
-#undef HAVE_PYTHON
-
/* Define to 1 if you have the `setenv' function. */
#undef HAVE_SETENV
@@ -131,9 +128,6 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
-/* Define to 1 if you have the `vasprintf' function. */
-#undef HAVE_VASPRINTF
-
/* Defined if we run on a W32 CE API based system */
#undef HAVE_W32CE_SYSTEM
@@ -147,9 +141,6 @@
*/
#undef LT_OBJDIR
-/* used to implement the va_copy macro */
-#undef MUST_COPY_VA_BYVAL
-
/* Name of this package */
#undef PACKAGE
@@ -221,6 +212,9 @@
/* Version of this package */
#undef VERSION
+/* Expose all libc features (__DARWIN_C_FULL). */
+#undef _DARWIN_C_SOURCE
+
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
@@ -284,5 +278,5 @@
#define GPG_ERR_ENABLE_ERRNO_MACROS 1
#define CRIGHTBLURB "Copyright (C) 2000 Werner Koch\n" \
- "Copyright (C) 2001--2016 g10 Code GmbH\n"
+ "Copyright (C) 2001--2017 g10 Code GmbH\n"
diff --git a/configure b/configure
index 8eb189d..bbf7a1a 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for gpgme 1.8.0.
+# Generated by GNU Autoconf 2.69 for gpgme 1.9.0.
#
# Report bugs to <http://bugs.gnupg.org>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='gpgme'
PACKAGE_TARNAME='gpgme'
-PACKAGE_VERSION='1.8.0'
-PACKAGE_STRING='gpgme 1.8.0'
+PACKAGE_VERSION='1.9.0'
+PACKAGE_STRING='gpgme 1.9.0'
PACKAGE_BUGREPORT='http://bugs.gnupg.org'
PACKAGE_URL=''
@@ -707,6 +707,8 @@ GPGME_QT_CFLAGS
HAVE_CXX11
BUILD_W32_GLIB_FALSE
BUILD_W32_GLIB_TRUE
+HAVE_MACOS_SYSTEM_FALSE
+HAVE_MACOS_SYSTEM_TRUE
HAVE_ANDROID_SYSTEM_FALSE
HAVE_ANDROID_SYSTEM_TRUE
HAVE_W32CE_SYSTEM_FALSE
@@ -1455,7 +1457,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures gpgme 1.8.0 to adapt to many kinds of systems.
+\`configure' configures gpgme 1.9.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1525,7 +1527,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of gpgme 1.8.0:";;
+ short | recursive ) echo "Configuration of gpgme 1.9.0:";;
esac
cat <<\_ACEOF
@@ -1673,7 +1675,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-gpgme configure 1.8.0
+gpgme configure 1.9.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2503,7 +2505,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by gpgme $as_me 1.8.0, which was
+It was created by gpgme $as_me 1.9.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2866,19 +2868,19 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
# (Interfaces added: AGE++)
# (Interfaces removed/changed: AGE=0)
#
-LIBGPGME_LT_CURRENT=28
-LIBGPGME_LT_AGE=17
+LIBGPGME_LT_CURRENT=29
+LIBGPGME_LT_AGE=18
LIBGPGME_LT_REVISION=0
# If there is an ABI break in gpgmepp or qgpgme also bump the
# version in IMPORTED_LOCATION in the GpgmeppConfig-w32.cmake.in.in
-LIBGPGMEPP_LT_CURRENT=9
-LIBGPGMEPP_LT_AGE=3
+LIBGPGMEPP_LT_CURRENT=10
+LIBGPGMEPP_LT_AGE=4
LIBGPGMEPP_LT_REVISION=0
-LIBQGPGME_LT_CURRENT=8
-LIBQGPGME_LT_AGE=1
+LIBQGPGME_LT_CURRENT=9
+LIBQGPGME_LT_AGE=2
LIBQGPGME_LT_REVISION=0
# If the API is changed in an incompatible way: increment the next counter.
@@ -2894,7 +2896,7 @@ PACKAGE=$PACKAGE_NAME
VERSION=$PACKAGE_VERSION
VERSION_MAJOR=1
-VERSION_MINOR=8
+VERSION_MINOR=9
VERSION_MICRO=0
ac_aux_dir=
@@ -3416,7 +3418,7 @@ fi
# Define the identity of the package.
PACKAGE='gpgme'
- VERSION='1.8.0'
+ VERSION='1.9.0'
cat >>confdefs.h <<_ACEOF
@@ -6329,7 +6331,7 @@ cat >>confdefs.h <<_ACEOF
#define VERSION "$VERSION"
_ACEOF
-VERSION_NUMBER=0x010800
+VERSION_NUMBER=0x010900
# We need to compile and run a program on the build machine. A
@@ -17176,6 +17178,9 @@ case "${host}" in
;;
*-apple-darwin*)
+$as_echo "#define _DARWIN_C_SOURCE 900000L" >>confdefs.h
+
+
$as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h
;;
@@ -17199,6 +17204,7 @@ have_dosish_system=no
have_android_system=no
have_w32_system=no
have_w64_system=no
+have_macos_system=no
build_w32_glib=no
build_w32_qt=no
available_languages="cl cpp python python2 python3 qt"
@@ -17213,6 +17219,9 @@ case "${host}" in
*-linux-androideabi)
have_android_system=yes
;;
+ *-apple-darwin*)
+ have_macos_system=yes
+ ;;
esac
case "${host}" in
*-mingw32ce*|*-mingw32*)
@@ -17588,6 +17597,20 @@ else
fi
+if test "$have_macos_system" = yes; then
+
+$as_echo "#define HAVE_MACOS_SYSTEM 1" >>confdefs.h
+
+fi
+ if test "$have_macos_system" = yes; then
+ HAVE_MACOS_SYSTEM_TRUE=
+ HAVE_MACOS_SYSTEM_FALSE='#'
+else
+ HAVE_MACOS_SYSTEM_TRUE='#'
+ HAVE_MACOS_SYSTEM_FALSE=
+fi
+
+
if test "$build_w32_glib" = yes; then
BUILD_W32_GLIB_TRUE=
BUILD_W32_GLIB_FALSE='#'
@@ -18746,7 +18769,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking moc version" >&5
$as_echo_n "checking moc version... " >&6; }
mocversion=`$MOC -v 2>&1`
- mocversiongrep=`echo $mocversion | grep "Qt 5\|moc 5"`
+ mocversiongrep=`echo $mocversion | grep -E "Qt 5|moc 5"`
if test x"$mocversiongrep" != x"$mocversion"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
@@ -18844,7 +18867,7 @@ else
fi
mocversion=`$MOC2 -v 2>&1`
- mocversiongrep=`echo $mocversion | grep "Qt 5\|moc-qt5 5\|moc 5"`
+ mocversiongrep=`echo $mocversion | grep -E "Qt 5|moc-qt5 5|moc 5"`
if test x"$mocversiongrep" != x"$mocversion"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}qtchooser", so it can be a program name with args.
@@ -18940,7 +18963,7 @@ fi
qt5tooldir=`QT_SELECT=qt5 qtchooser -print-env | grep QTTOOLDIR | cut -d '=' -f 2 | cut -d \" -f 2`
mocversion=`$qt5tooldir/moc -v 2>&1`
- mocversiongrep=`echo $mocversion | grep "Qt 5\|moc 5"`
+ mocversiongrep=`echo $mocversion | grep -E "Qt 5|moc 5"`
if test x"$mocversiongrep" != x"$mocversion"; then
# no valid moc found
have_qt5_libs="no";
@@ -19347,7 +19370,7 @@ if ${am_cv_pathless_PYTHON+:} false; then :
$as_echo_n "(cached) " >&6
else
- for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
+ for am_cv_pathless_PYTHON in python2 python2.7 python python3 python3.0 python3.1 python3.2 python3.3 python3.4 python3.5 python3.6 python3.7 python3.8 none; do
test "$am_cv_pathless_PYTHON" = none && break
prog="import sys
# split strings by '.' and convert to numeric. Append some zeros
@@ -19419,7 +19442,7 @@ fi
if test "$PYTHON" = :; then
- as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5
+ :
else
@@ -19564,9 +19587,6 @@ $as_echo "$am_cv_python_pyexecdir" >&6; }
- fi
-
-
#
# Allow the use of a (user set) custom python version
@@ -19745,10 +19765,10 @@ EOD`
# Make the versioning information available to the compiler
-cat >>confdefs.h <<_ACEOF
-#define HAVE_PYTHON "$ac_python_version"
-_ACEOF
-
+ # JW: We don't need it and it interferes with the hack
+ # to detect multiple Pyhton versions
+ #AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
+ # [If available, contains the Python version number currently in use.])
# First, the library directory:
ac_python_libdir=`cat<<EOD | $PYTHON -
@@ -19918,10 +19938,14 @@ $as_echo "$as_me: WARNING:
# all done!
#
- if test "$PYTHON_VERSION"; then
- PYTHONS="$(echo $PYTHONS $PYTHON)"
- PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
- fi
+ if test "$PYTHON_VERSION"; then
+ PYTHONS="$(echo $PYTHONS $PYTHON)"
+ PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
+ fi
+
+ fi
+
+
fi
if test "$found_py" = "1" -o "$found_py3" = "1"; then
@@ -19980,7 +20004,7 @@ if ${am_cv_pathless_PYTHON+:} false; then :
$as_echo_n "(cached) " >&6
else
- for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do
+ for am_cv_pathless_PYTHON in python2 python2.7 python python3 python3.0 python3.1 python3.2 python3.3 python3.4 python3.5 python3.6 python3.7 python3.8 none; do
test "$am_cv_pathless_PYTHON" = none && break
prog="import sys
# split strings by '.' and convert to numeric. Append some zeros
@@ -20052,7 +20076,7 @@ fi
if test "$PYTHON" = :; then
- as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5
+ :
else
@@ -20197,9 +20221,6 @@ $as_echo "$am_cv_python_pyexecdir" >&6; }
- fi
-
-
#
# Allow the use of a (user set) custom python version
@@ -20378,10 +20399,10 @@ EOD`
# Make the versioning information available to the compiler
-cat >>confdefs.h <<_ACEOF
-#define HAVE_PYTHON "$ac_python_version"
-_ACEOF
-
+ # JW: We don't need it and it interferes with the hack
+ # to detect multiple Pyhton versions
+ #AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
+ # [If available, contains the Python version number currently in use.])
# First, the library directory:
ac_python_libdir=`cat<<EOD | $PYTHON -
@@ -20551,15 +20572,27 @@ $as_echo "$as_me: WARNING:
# all done!
#
- if test "$PYTHON_VERSION"; then
- PYTHONS="$(echo $PYTHONS $PYTHON)"
- PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
- fi
+ if test "$PYTHON_VERSION"; then
+ PYTHONS="$(echo $PYTHONS $PYTHON)"
+ PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
+ fi
+
+ fi
+
+
fi
+ # Recover some values lost in the second attempt to find Python.
+ PYTHON="$(echo $PYTHONS | cut -d ' ' -f 1)"
+ PYTHON_VERSION="$(echo $PYTHON_VERSIONS | cut -d ' ' -f 1)"
+
+ # Remove duplicates.
+ PYTHONS="$(echo $PYTHONS | tr '[:space:]' '\n' | sort | uniq | tr '\n' ' ' | sed -e 's/ $//')"
+ PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS | tr '[:space:]' '\n' | sort | uniq | tr '\n' ' ' | sed -e 's/ $//')"
+
if test "$PYTHON_VERSIONS"; then
- enabled_languages_v=$(echo $enabled_languages | sed "s/python\([23]\)\?/python ($PYTHON_VERSIONS)/")
- enabled_languages=$(echo $enabled_languages | sed "s/python\([23]\)\?/python/")
+ enabled_languages_v=$(echo $enabled_languages | sed -Ee "s/python[23]?/python ($PYTHON_VERSIONS)/")
+ enabled_languages=$(echo $enabled_languages | sed -Ee "s/python[23]?/python/")
else
if test "$explicit_languages" = "1"; then
as_fn_error $? "
@@ -20584,7 +20617,7 @@ ENABLED_LANGUAGES=$enabled_languages
#
# Provide information about the build.
#
-BUILD_REVISION="f06220b"
+BUILD_REVISION="aa0390e"
cat >>confdefs.h <<_ACEOF
@@ -20593,7 +20626,7 @@ _ACEOF
BUILD_FILEVERSION=`echo "$PACKAGE_VERSION"|sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
-BUILD_FILEVERSION="${BUILD_FILEVERSION}61538"
+BUILD_FILEVERSION="${BUILD_FILEVERSION}43523"
# Check whether --enable-build-timestamp was given.
@@ -21264,85 +21297,6 @@ $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
fi
-ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf"
-if test "x$ac_cv_func_vasprintf" = xyes; then :
- $as_echo "#define HAVE_VASPRINTF 1" >>confdefs.h
-
-else
- case " $LIBOBJS " in
- *" vasprintf.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS vasprintf.$ac_objext"
- ;;
-esac
-
-fi
-
-
-if test "$ac_cv_func_vasprintf" != yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether va_lists must be copied by value" >&5
-$as_echo_n "checking whether va_lists must be copied by value... " >&6; }
- if ${gnupg_cv_must_copy_va_byval+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
- if test "$cross_compiling" = yes; then
- gnupg_cv_must_copy_va_byval=no
- else
- gnupg_cv_must_copy_va_byval=no
- if test "$cross_compiling" = yes; then :
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run test program while cross compiling
-See \`config.log' for more details" "$LINENO" 5; }
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
- #include <stdarg.h>
- void f (int i, ...)
- {
- va_list args1, args2;
- va_start (args1, i);
- args2 = args1;
- if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
- exit (1);
- va_end (args1);
- va_end (args2);
- }
-
- int main()
- {
- f (0, 42);
- return 0;
- }
-
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
- gnupg_cv_must_copy_va_byval=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
- fi
-
-fi
-
- if test "$gnupg_cv_must_copy_va_byval" = yes; then
-
-$as_echo "#define MUST_COPY_VA_BYVAL 1" >>confdefs.h
-
- fi
- if test "$cross_compiling" = yes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming $gnupg_cv_must_copy_va_byval" >&5
-$as_echo "assuming $gnupg_cv_must_copy_va_byval" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_must_copy_va_byval" >&5
-$as_echo "$gnupg_cv_must_copy_va_byval" >&6; }
- fi
-
-fi
-
# Try to find a thread-safe version of ttyname().
ac_fn_c_check_decl "$LINENO" "ttyname_r" "ac_cv_have_decl_ttyname_r" "$ac_includes_default"
if test "x$ac_cv_have_decl_ttyname_r" = xyes; then :
@@ -22032,60 +21986,8 @@ fi
# Other checks
#
-# Check for funopen
-for ac_func in funopen
-do :
- ac_fn_c_check_func "$LINENO" "funopen" "ac_cv_func_funopen"
-if test "x$ac_cv_func_funopen" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_FUNOPEN 1
-_ACEOF
-
-fi
-done
-
-if test $ac_cv_func_funopen != yes; then
- # No funopen but we can implement that in terms of fopencookie.
- for ac_func in fopencookie
-do :
- ac_fn_c_check_func "$LINENO" "fopencookie" "ac_cv_func_fopencookie"
-if test "x$ac_cv_func_fopencookie" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_FOPENCOOKIE 1
-_ACEOF
-
-fi
-done
-
- if test $ac_cv_func_fopencookie = yes; then
- ac_fn_c_check_func "$LINENO" "funopen" "ac_cv_func_funopen"
-if test "x$ac_cv_func_funopen" = xyes; then :
- $as_echo "#define HAVE_FUNOPEN 1" >>confdefs.h
-
-else
- case " $LIBOBJS " in
- *" funopen.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS funopen.$ac_objext"
- ;;
-esac
-
-fi
-
-
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
-***
-*** No implementation of fopencookie or funopen available
-***" >&5
-$as_echo "$as_me: WARNING:
-***
-*** No implementation of fopencookie or funopen available
-***" >&2;}
- fi
-fi
-
# Check for getgid etc
-for ac_func in getgid getegid
+for ac_func in getgid getegid closefrom
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -22160,15 +22062,7 @@ $as_echo "$as_me: WARNING:
fi
-
-case "${host}" in
- *-apple-darwin*)
- use_descriptor_passing=no
- ;;
- *)
- use_descriptor_passing=yes
- ;;
-esac
+use_descriptor_passing=yes
# Check whether --enable-fd-passing was given.
if test "${enable_fd_passing+set}" = set; then :
enableval=$enable_fd_passing; use_descriptor_passing=$enableval
@@ -22519,6 +22413,10 @@ if test -z "${HAVE_ANDROID_SYSTEM_TRUE}" && test -z "${HAVE_ANDROID_SYSTEM_FALSE
as_fn_error $? "conditional \"HAVE_ANDROID_SYSTEM\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${HAVE_MACOS_SYSTEM_TRUE}" && test -z "${HAVE_MACOS_SYSTEM_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_MACOS_SYSTEM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${BUILD_W32_GLIB_TRUE}" && test -z "${BUILD_W32_GLIB_FALSE}"; then
as_fn_error $? "conditional \"BUILD_W32_GLIB\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -22948,7 +22846,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by gpgme $as_me 1.8.0, which was
+This file was extended by gpgme $as_me 1.9.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -23014,7 +22912,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-gpgme config.status 1.8.0
+gpgme config.status 1.9.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -25326,7 +25224,7 @@ fi
echo "
GPGME v${VERSION} has been configured as follows:
- Revision: f06220b (61538)
+ Revision: aa0390e (43523)
Platform: $host
UI Server: $uiserver
diff --git a/configure.ac b/configure.ac
index 0a67b48..0dac6ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,7 +28,7 @@ min_automake_version="1.14"
# commit and push so that the git magic is able to work. See below
# for the LT versions.
m4_define(mym4_version_major, [1])
-m4_define(mym4_version_minor, [8])
+m4_define(mym4_version_minor, [9])
m4_define(mym4_version_micro, [0])
# Below is m4 magic to extract and compute the revision number, the
@@ -55,19 +55,19 @@ AC_INIT([gpgme],[mym4_full_version],[http://bugs.gnupg.org])
# (Interfaces added: AGE++)
# (Interfaces removed/changed: AGE=0)
#
-LIBGPGME_LT_CURRENT=28
-LIBGPGME_LT_AGE=17
+LIBGPGME_LT_CURRENT=29
+LIBGPGME_LT_AGE=18
LIBGPGME_LT_REVISION=0
# If there is an ABI break in gpgmepp or qgpgme also bump the
# version in IMPORTED_LOCATION in the GpgmeppConfig-w32.cmake.in.in
-LIBGPGMEPP_LT_CURRENT=9
-LIBGPGMEPP_LT_AGE=3
+LIBGPGMEPP_LT_CURRENT=10
+LIBGPGMEPP_LT_AGE=4
LIBGPGMEPP_LT_REVISION=0
-LIBQGPGME_LT_CURRENT=8
-LIBQGPGME_LT_AGE=1
+LIBQGPGME_LT_CURRENT=9
+LIBQGPGME_LT_AGE=2
LIBQGPGME_LT_REVISION=0
# If the API is changed in an incompatible way: increment the next counter.
@@ -167,6 +167,8 @@ case "${host}" in
have_ld_version_script=yes
;;
*-apple-darwin*)
+ AC_DEFINE(_DARWIN_C_SOURCE, 900000L,
+ Expose all libc features (__DARWIN_C_FULL).)
AC_DEFINE(_XOPEN_SOURCE, 500, Activate POSIX interface on MacOS X)
;;
esac
@@ -182,6 +184,7 @@ have_dosish_system=no
have_android_system=no
have_w32_system=no
have_w64_system=no
+have_macos_system=no
build_w32_glib=no
build_w32_qt=no
available_languages="cl cpp python python2 python3 qt"
@@ -196,6 +199,9 @@ case "${host}" in
*-linux-androideabi)
have_android_system=yes
;;
+ *-apple-darwin*)
+ have_macos_system=yes
+ ;;
esac
case "${host}" in
*-mingw32ce*|*-mingw32*)
@@ -253,6 +259,12 @@ if test "$have_android_system" = yes; then
fi
AM_CONDITIONAL(HAVE_ANDROID_SYSTEM, test "$have_android_system" = yes)
+if test "$have_macos_system" = yes; then
+ AC_DEFINE(HAVE_MACOS_SYSTEM,1,
+ [Defined if we build for an MacOS system])
+fi
+AM_CONDITIONAL(HAVE_MACOS_SYSTEM, test "$have_macos_system" = yes)
+
AM_CONDITIONAL(BUILD_W32_GLIB, test "$build_w32_glib" = yes)
@@ -406,12 +418,13 @@ if test "$found_py" = "1" -o "$found_py2" = "1" -o "$found_py3" = "1"; then
unset am_cv_python_pyexecdir
if test "$found_py" = "1" -o "$found_py2" = "1"; then
- AM_PATH_PYTHON([2.7])
- AX_PYTHON_DEVEL
- if test "$PYTHON_VERSION"; then
- PYTHONS="$(echo $PYTHONS $PYTHON)"
- PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
- fi
+ AM_PATH_PYTHON([2.7], [
+ AX_PYTHON_DEVEL
+ if test "$PYTHON_VERSION"; then
+ PYTHONS="$(echo $PYTHONS $PYTHON)"
+ PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
+ fi
+ ], :)
fi
if test "$found_py" = "1" -o "$found_py3" = "1"; then
@@ -429,17 +442,26 @@ if test "$found_py" = "1" -o "$found_py2" = "1" -o "$found_py3" = "1"; then
unset am_cv_python_platform
unset am_cv_python_pythondir
unset am_cv_python_pyexecdir
- AM_PATH_PYTHON([3.4])
- AX_PYTHON_DEVEL
- if test "$PYTHON_VERSION"; then
- PYTHONS="$(echo $PYTHONS $PYTHON)"
- PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
- fi
+ AM_PATH_PYTHON([3.4], [
+ AX_PYTHON_DEVEL
+ if test "$PYTHON_VERSION"; then
+ PYTHONS="$(echo $PYTHONS $PYTHON)"
+ PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
+ fi
+ ], :)
fi
+ # Recover some values lost in the second attempt to find Python.
+ PYTHON="$(echo $PYTHONS | cut -d ' ' -f 1)"
+ PYTHON_VERSION="$(echo $PYTHON_VERSIONS | cut -d ' ' -f 1)"
+
+ # Remove duplicates.
+ PYTHONS="$(echo $PYTHONS | tr '[[:space:]]' '\n' | sort | uniq | tr '\n' ' ' | sed -e 's/ $//')"
+ PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS | tr '[[:space:]]' '\n' | sort | uniq | tr '\n' ' ' | sed -e 's/ $//')"
+
if test "$PYTHON_VERSIONS"; then
- enabled_languages_v=$(echo $enabled_languages | sed "s/python\([[23]]\)\?/python ($PYTHON_VERSIONS)/")
- enabled_languages=$(echo $enabled_languages | sed "s/python\([[23]]\)\?/python/")
+ enabled_languages_v=$(echo $enabled_languages | sed -Ee "s/python[[23]]?/python ($PYTHON_VERSIONS)/")
+ enabled_languages=$(echo $enabled_languages | sed -Ee "s/python[[23]]?/python/")
else
if test "$explicit_languages" = "1"; then
AC_MSG_ERROR([[
@@ -622,11 +644,6 @@ AC_MSG_NOTICE([checking for libraries])
AC_FUNC_FSEEKO
-AC_REPLACE_FUNCS(vasprintf)
-if test "$ac_cv_func_vasprintf" != yes; then
- GNUPG_CHECK_VA_COPY
-fi
-
# Try to find a thread-safe version of ttyname().
gnupg_REPLACE_TTYNAME_R
if test "$ac_cv_func_ttyname_r" != yes; then
@@ -688,23 +705,8 @@ fi
# Other checks
#
-# Check for funopen
-AC_CHECK_FUNCS(funopen)
-if test $ac_cv_func_funopen != yes; then
- # No funopen but we can implement that in terms of fopencookie.
- AC_CHECK_FUNCS(fopencookie)
- if test $ac_cv_func_fopencookie = yes; then
- AC_REPLACE_FUNCS(funopen)
- else
- AC_MSG_WARN([
-***
-*** No implementation of fopencookie or funopen available
-***])
- fi
-fi
-
# Check for getgid etc
-AC_CHECK_FUNCS(getgid getegid)
+AC_CHECK_FUNCS(getgid getegid closefrom)
# Replacement functions.
@@ -732,18 +734,7 @@ AC_CHECK_MEMBER(struct cmsghdr.cmsg_len,
#include <unistd.h>
])
-
-dnl There seems to be a problem with Apple and decriptor passing.
-dnl Until we found a solution we change the default to no.
-dnl See bug 1483.
-case "${host}" in
- *-apple-darwin*)
- use_descriptor_passing=no
- ;;
- *)
- use_descriptor_passing=yes
- ;;
-esac
+use_descriptor_passing=yes
AC_ARG_ENABLE(fd-passing,
AC_HELP_STRING([--disable-fd-passing], [do not use FD passing]),
use_descriptor_passing=$enableval)
@@ -798,7 +789,7 @@ AH_BOTTOM([
#define GPG_ERR_ENABLE_ERRNO_MACROS 1
#define CRIGHTBLURB "Copyright (C) 2000 Werner Koch\n" \
- "Copyright (C) 2001--2016 g10 Code GmbH\n"
+ "Copyright (C) 2001--2017 g10 Code GmbH\n"
])
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 1fd44b6..2f628fc 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -110,8 +110,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
diff --git a/doc/gpgme.info b/doc/gpgme.info
index 801e07a..b6b6e44 100644
--- a/doc/gpgme.info
+++ b/doc/gpgme.info
@@ -1,6 +1,6 @@
-This is gpgme.info, produced by makeinfo version 5.2 from gpgme.texi.
+This is gpgme.info, produced by makeinfo version 6.3 from gpgme.texi.
-Copyright © 2002–2008, 2010, 2012–2016 g10 Code GmbH.
+Copyright © 2002–2008, 2010, 2012–2017 g10 Code GmbH.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License as
@@ -19,10 +19,10 @@ END-INFO-DIR-ENTRY
This file documents the GPGME library.
- This is Edition 1.8.0-beta50, last updated 16 November 2016, of ‘The
-‘GnuPG Made Easy’ Reference Manual’, for Version 1.8.0-beta50.
+ This is Edition 1.9.0, last updated 16 November 2016, of ‘The ‘GnuPG
+Made Easy’ Reference Manual’, for Version 1.9.0.
- Copyright © 2002–2008, 2010, 2012–2016 g10 Code GmbH.
+ Copyright © 2002–2008, 2010, 2012–2017 g10 Code GmbH.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License as
@@ -37,130 +37,130 @@ Public License for more details.

Indirect:
-gpgme.info-1: 1686
-gpgme.info-2: 314031
+gpgme.info-1: 1672
+gpgme.info-2: 321787

Tag Table:
(Indirect)
-Node: Top1686
-Node: Introduction9293
-Node: Getting Started10083
-Node: Features11544
-Node: Overview12856
-Node: Preparation13965
-Node: Header14962
-Node: Building the Source15709
-Node: Largefile Support (LFS)17853
-Node: Using Automake23267
-Node: Using Libtool25820
-Node: Library Version Check26182
-Node: Signal Handling32194
-Node: Multi-Threading33464
-Ref: Multi-Threading-Footnote-134880
-Node: Protocols and Engines35303
-Node: Engine Version Check37948
-Node: Engine Information40365
-Node: Engine Configuration44225
-Node: OpenPGP45509
-Node: Cryptographic Message Syntax45849
-Node: Assuan46162
-Node: Algorithms46536
-Ref: Algorithms-Footnote-147015
-Node: Public Key Algorithms47143
-Node: Hash Algorithms49630
-Node: Error Handling50820
-Node: Error Values52694
-Node: Error Sources57897
-Node: Error Codes60337
-Node: Error Strings65128
-Node: Exchanging Data66935
-Node: Creating Data Buffers68801
-Node: Memory Based Data Buffers69317
-Node: File Based Data Buffers72750
-Node: Callback Based Data Buffers74952
-Node: Destroying Data Buffers79143
-Node: Manipulating Data Buffers80631
-Node: Data Buffer I/O Operations81123
-Node: Data Buffer Meta-Data83496
-Node: Data Buffer Convenience87862
-Node: Contexts89839
-Node: Creating Contexts91025
-Node: Destroying Contexts91872
-Node: Result Management92211
-Node: Context Attributes93754
-Node: Protocol Selection94791
-Node: Crypto Engine95823
-Node: Setting the Sender97673
-Node: ASCII Armor99148
-Node: Text Mode99777
-Node: Offline Mode100711
-Node: Pinentry Mode101783
-Node: Included Certificates103468
-Node: Key Listing Mode104890
-Node: Passphrase Callback108982
-Node: Progress Meter Callback112369
-Node: Status Message Callback114354
-Node: Locale118175
-Node: Key Management119734
-Node: Key objects120962
-Node: Listing Keys131962
-Node: Information About Keys139408
-Node: Manipulating Keys140716
-Node: Generating Keys141286
-Node: Signing Keys156760
-Node: Exporting Keys160358
-Node: Importing Keys167051
-Ref: Importing Keys-Footnote-1173956
-Node: Deleting Keys174084
-Node: Changing Passphrases175529
-Node: Changing TOFU Data176818
-Node: Advanced Key Editing178869
-Node: Trust Item Management181518
-Node: Listing Trust Items182554
-Node: Manipulating Trust Items184915
-Node: Crypto Operations185558
-Node: Decrypt186822
-Node: Verify191524
-Node: Decrypt and Verify203484
-Node: Sign206320
-Node: Selecting Signers206884
-Node: Creating a Signature208271
-Node: Signature Notation Data213041
-Node: Encrypt215269
-Node: Encrypting a Plaintext215625
-Node: Miscellaneous222588
-Node: Running other Programs223000
-Node: Using the Assuan protocol225076
-Node: Checking for updates227798
-Node: Run Control232556
-Node: Waiting For Completion233300
-Node: Using External Event Loops235418
-Node: I/O Callback Interface237390
-Node: Registering I/O Callbacks242628
-Node: I/O Callback Example244666
-Node: I/O Callback Example GTK+251291
-Node: I/O Callback Example GDK253080
-Node: I/O Callback Example Qt254722
-Node: Cancellation257010
-Node: UI Server Protocol259280
-Ref: UI Server Protocol-Footnote-1260715
-Node: UI Server Encrypt260834
-Node: UI Server Sign266192
-Node: UI Server Decrypt268545
-Node: UI Server Verify270200
-Node: UI Server Set Input Files273772
-Node: UI Server Sign/Encrypt Files274842
-Node: UI Server Verify/Decrypt Files276650
-Node: UI Server Import/Export Keys278526
-Node: UI Server Checksum Files279588
-Node: Miscellaneous UI Server Commands281804
-Ref: command SENDER283735
-Node: Debugging285437
-Node: Deprecated Functions287186
-Node: Library Copying314031
-Node: Copying342247
-Node: Concept Index379997
-Node: Function and Data Index394776
+Node: Top1672
+Node: Introduction9265
+Node: Getting Started10055
+Node: Features11516
+Node: Overview12828
+Node: Preparation13937
+Node: Header14934
+Node: Building the Source15681
+Node: Largefile Support (LFS)17825
+Node: Using Automake23239
+Node: Using Libtool25792
+Node: Library Version Check26154
+Node: Signal Handling32166
+Node: Multi-Threading33436
+Ref: Multi-Threading-Footnote-134852
+Node: Protocols and Engines35275
+Node: Engine Version Check37920
+Node: Engine Information40424
+Node: Engine Configuration44284
+Node: OpenPGP45568
+Node: Cryptographic Message Syntax45908
+Node: Assuan46221
+Node: Algorithms46595
+Ref: Algorithms-Footnote-147074
+Node: Public Key Algorithms47202
+Node: Hash Algorithms49689
+Node: Error Handling50879
+Node: Error Values52753
+Node: Error Sources57956
+Node: Error Codes60396
+Node: Error Strings65187
+Node: Exchanging Data66994
+Node: Creating Data Buffers68860
+Node: Memory Based Data Buffers69376
+Node: File Based Data Buffers72809
+Node: Callback Based Data Buffers75011
+Node: Destroying Data Buffers79202
+Node: Manipulating Data Buffers80690
+Node: Data Buffer I/O Operations81182
+Node: Data Buffer Meta-Data83555
+Node: Data Buffer Convenience87921
+Node: Contexts89898
+Node: Creating Contexts91084
+Node: Destroying Contexts91931
+Node: Result Management92270
+Node: Context Attributes93813
+Node: Protocol Selection94850
+Node: Crypto Engine95882
+Node: Setting the Sender97732
+Node: ASCII Armor99207
+Node: Text Mode99836
+Node: Offline Mode100770
+Node: Pinentry Mode101842
+Node: Included Certificates103527
+Node: Key Listing Mode104949
+Node: Passphrase Callback109041
+Node: Progress Meter Callback112428
+Node: Status Message Callback114413
+Node: Locale119123
+Node: Key Management120682
+Node: Key objects121910
+Node: Listing Keys133583
+Node: Information About Keys142211
+Node: Manipulating Keys143519
+Node: Generating Keys144089
+Node: Signing Keys162005
+Node: Exporting Keys165552
+Node: Importing Keys172245
+Ref: Importing Keys-Footnote-1179150
+Node: Deleting Keys179278
+Node: Changing Passphrases180723
+Node: Changing TOFU Data182012
+Node: Advanced Key Editing184063
+Node: Trust Item Management186712
+Node: Listing Trust Items187748
+Node: Manipulating Trust Items190109
+Node: Crypto Operations190752
+Node: Decrypt192016
+Node: Verify198345
+Node: Decrypt and Verify210614
+Node: Sign213450
+Node: Selecting Signers214014
+Node: Creating a Signature215401
+Node: Signature Notation Data220171
+Node: Encrypt222399
+Node: Encrypting a Plaintext222755
+Node: Miscellaneous230358
+Node: Running other Programs230770
+Node: Using the Assuan protocol232846
+Node: Checking for updates235568
+Node: Run Control240326
+Node: Waiting For Completion241070
+Node: Using External Event Loops243188
+Node: I/O Callback Interface245160
+Node: Registering I/O Callbacks250398
+Node: I/O Callback Example252436
+Node: I/O Callback Example GTK+259061
+Node: I/O Callback Example GDK260850
+Node: I/O Callback Example Qt262492
+Node: Cancellation264780
+Node: UI Server Protocol267050
+Ref: UI Server Protocol-Footnote-1268485
+Node: UI Server Encrypt268604
+Node: UI Server Sign273962
+Node: UI Server Decrypt276315
+Node: UI Server Verify277970
+Node: UI Server Set Input Files281542
+Node: UI Server Sign/Encrypt Files282612
+Node: UI Server Verify/Decrypt Files284420
+Node: UI Server Import/Export Keys286296
+Node: UI Server Checksum Files287358
+Node: Miscellaneous UI Server Commands289574
+Ref: command SENDER291505
+Node: Debugging293207
+Node: Deprecated Functions294956
+Node: Library Copying321787
+Node: Copying350007
+Node: Concept Index387757
+Node: Function and Data Index402536

End Tag Table
diff --git a/doc/gpgme.info-1 b/doc/gpgme.info-1
index bc822a4..4b9ec87 100644
--- a/doc/gpgme.info-1
+++ b/doc/gpgme.info-1
@@ -1,6 +1,6 @@
-This is gpgme.info, produced by makeinfo version 5.2 from gpgme.texi.
+This is gpgme.info, produced by makeinfo version 6.3 from gpgme.texi.
-Copyright © 2002–2008, 2010, 2012–2016 g10 Code GmbH.
+Copyright © 2002–2008, 2010, 2012–2017 g10 Code GmbH.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License as
@@ -19,10 +19,10 @@ END-INFO-DIR-ENTRY
This file documents the GPGME library.
- This is Edition 1.8.0-beta50, last updated 16 November 2016, of ‘The
-‘GnuPG Made Easy’ Reference Manual’, for Version 1.8.0-beta50.
+ This is Edition 1.9.0, last updated 16 November 2016, of ‘The ‘GnuPG
+Made Easy’ Reference Manual’, for Version 1.9.0.
- Copyright © 2002–2008, 2010, 2012–2016 g10 Code GmbH.
+ Copyright © 2002–2008, 2010, 2012–2017 g10 Code GmbH.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License as
@@ -41,9 +41,8 @@ File: gpgme.info, Node: Top, Next: Introduction, Up: (dir)
Main Menu
*********
-This is Edition 1.8.0-beta50, last updated 16 November 2016, of ‘The
-‘GnuPG Made Easy’ Reference Manual’, for Version 1.8.0-beta50 of the
-GPGME library.
+This is Edition 1.9.0, last updated 16 November 2016, of ‘The ‘GnuPG
+Made Easy’ Reference Manual’, for Version 1.9.0 of the GPGME library.
* Menu:
@@ -899,6 +898,9 @@ File: gpgme.info, Node: Engine Version Check, Next: Engine Information, Up: P
‘g13-name’
Return the name of the file container encryption engine.
+ ‘gpg-wks-client-name’
+ Return the name of the Web Key Service tool.
+
-- Function: gpgme_error_t gpgme_engine_check_version
(gpgme_protocol_t PROTOCOL)
The function ‘gpgme_engine_check_version’ verifies that the engine
@@ -2689,6 +2691,26 @@ File: gpgme.info, Node: Status Message Callback, Next: Locale, Prev: Progress
set by this function. The properties are identified by the
following values for NAME:
+ ‘"redraw"’
+ This flag is normally not changed by the caller because GPGME
+ sets and clears it automatically: The flag is cleared before
+ an operation and set if an operation noticed that the engine
+ has launched a Pinentry. A Curses based application may use
+ this information to redraw the screen; for example:
+
+ err = gpgme_op_keylist_start (ctx, "foo@example.org", 0);
+ while (!err)
+ {
+ err = gpgme_op_keylist_next (ctx, &key);
+ if (err)
+ break;
+ show_key (key);
+ gpgme_key_release (key);
+ }
+ if ((s = gpgme_get_ctx_flag (ctx, "redraw")) && *s)
+ redraw_screen ();
+ gpgme_release (ctx);
+
‘"full-status"’
Using a VALUE of "1" the status callback set by
gpgme_set_status_cb returns all status lines with the
@@ -2850,6 +2872,9 @@ long as the key object itself is valid.
secret keys has been requested or if
‘GPGME_KEYLIST_MODE_WITH_SECRET’ is active.
+ ‘unsigned int origin : 5’
+ Reserved for the origin of this key.
+
‘gpgme_protocol_t protocol’
This is the protocol supported by this key.
@@ -2884,6 +2909,9 @@ long as the key object itself is valid.
a subkey may be missing but this field may be set
nevertheless.
+ ‘unsigned long last_update’
+ Reserved for the time of the last update of this key.
+
-- Data type: gpgme_subkey_t
The ‘gpgme_subkey_t’ type is a pointer to a subkey structure.
@@ -2929,6 +2957,12 @@ long as the key object itself is valid.
This is true if the subkey can be used for qualified
signatures according to local government regulations.
+ ‘unsigned int is_de_vs : 1’
+ This is true if the subkey complies with the rules for
+ classified information in Germany at the restricted level
+ (VS-NfD). This are currently RSA keys of at least 2048 bits or
+ ECDH/ECDSA keys using a Brainpool curve.
+
‘unsigned int secret : 1’
This is true if the subkey is a secret key. Note that it will
be false if the key is actually a stub key; i.e. a secret key
@@ -3016,6 +3050,12 @@ long as the key object itself is valid.
‘gpgme_key_sig_t signatures’
This is a linked list with the signatures on this user ID.
+ ‘unsigned int origin : 5’
+ Reserved for the origin of this user ID.
+
+ ‘unsigned long last_update’
+ Reserved for the time of the last update of this user ID.
+
-- Data type: gpgme_key_sig_t
The ‘gpgme_key_sig_t’ type is a pointer to a key signature
@@ -3098,6 +3138,7 @@ File: gpgme.info, Node: Listing Keys, Next: Information About Keys, Prev: Key
-- Function: gpgme_error_t gpgme_op_keylist_start (gpgme_ctx_t CTX,
const char *PATTERN, int SECRET_ONLY)
+
The function ‘gpgme_op_keylist_start’ initiates a key listing
operation inside the context CTX. It sets everything up so that
subsequent invocations of ‘gpgme_op_keylist_next’ return the keys
@@ -3125,6 +3166,7 @@ File: gpgme.info, Node: Listing Keys, Next: Information About Keys, Prev: Key
-- Function: gpgme_error_t gpgme_op_keylist_ext_start (gpgme_ctx_t CTX,
const char *PATTERN[], int SECRET_ONLY, int RESERVED)
+
The function ‘gpgme_op_keylist_ext_start’ initiates an extended key
listing operation inside the context CTX. It sets everything up so
that subsequent invocations of ‘gpgme_op_keylist_next’ return the
@@ -3154,8 +3196,34 @@ File: gpgme.info, Node: Listing Keys, Next: Information About Keys, Prev: Key
not a valid pointer, and passes through any errors that are
reported by the crypto engine support routines.
+ -- Function: gpgme_error_t gpgme_op_keylist_from_data (gpgme_ctx_t CTX,
+ gpgme_data_t DATA, int RESERVED)
+
+ The function ‘gpgme_op_keylist_from_data_start’ initiates a key
+ listing operation inside the context CTX. In contrast to the other
+ key listing operation the keys are read from the supplied DATA and
+ not from the local key database. The keys are also not imported
+ into the local key database. The function sets everything up so
+ that subsequent invocations of ‘gpgme_op_keylist_next’ return the
+ keys from DATA.
+
+ The value of RESERVED must be ‘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
+ ‘gpgme_op_keylist_next’ returns ‘GPG_ERR_EOF’), or
+ ‘gpgme_op_keylist_end’ is called to finish the operation. While
+ the context is busy DATA may not be released.
+
+ The function returns the error code ‘GPG_ERR_INV_VALUE’ if CTX is
+ not a valid pointer, and passes through any errors that are
+ reported by the crypto engine support routines.
+
-- Function: gpgme_error_t gpgme_op_keylist_next (gpgme_ctx_t CTX,
gpgme_key_t *R_KEY)
+
The function ‘gpgme_op_keylist_next’ returns the next key in the
list created by a previous ‘gpgme_op_keylist_start’ operation in
the context CTX. The key will have one reference for the user.
@@ -3171,6 +3239,7 @@ File: gpgme.info, Node: Listing Keys, Next: Information About Keys, Prev: Key
enough memory for the operation.
-- Function: gpgme_error_t gpgme_op_keylist_end (gpgme_ctx_t CTX)
+
The function ‘gpgme_op_keylist_end’ ends a pending key list
operation in the context CTX.
@@ -3183,7 +3252,7 @@ File: gpgme.info, Node: Listing Keys, Next: Information About Keys, Prev: Key
The following example illustrates how all keys containing a certain
string (‘g10code’) can be listed with their key ID and the name and
-e-mail address of the main user ID:
+email address of the main user ID:
gpgme_ctx_t ctx;
gpgme_key_t key;
@@ -3349,13 +3418,13 @@ provide a fallback to the old function if the error code
RESERVED must be set to zero.
- EXPIRES can be set to the number of seconds since Epoch of the
- desired expiration date in UTC for the new key. Using 0 does not
- set an expiration date. Note that this parameter takes an unsigned
- long value and not a ‘time_t’ to avoid problems on systems which
- use a signed 32 bit ‘time_t’. Note further that the OpenPGP
- protocol uses 32 bit values for timestamps and thus can only encode
- dates up to the year 2106.
+ EXPIRES specifies the expiration time in seconds. If you supply 0,
+ a reasonable expiration time is chosen. Use the flag
+ ‘GPGME_CREATE_NOEXPIRE’ to create keys that do not expire. Note
+ that this parameter takes an unsigned long value and not a ‘time_t’
+ to avoid problems on systems which use a signed 32 bit ‘time_t’.
+ Note further that the OpenPGP protocol uses 32 bit values for
+ timestamps and thus can only encode dates up to the year 2106.
EXTRAKEY is currently not used and must be set to ‘NULL’. A future
version of GPGME may use this parameter to create X.509 keys.
@@ -3397,6 +3466,9 @@ provide a fallback to the old function if the error code
already existing in the local key database. This flag can be
used to override this check.
+ ‘GPGME_CREATE_NOEXPIRE’
+ Request generation of keys that do not expire.
+
After the operation completed successfully, information about the
created key can be retrieved with ‘gpgme_op_genkey_result’.
@@ -3438,13 +3510,13 @@ provide a fallback to the old function if the error code
RESERVED must be set to zero.
- EXPIRES can be set to the number of seconds since Epoch of the
- desired expiration date in UTC for the new subkey. Using 0 does
- not set an expiration date. Note that this parameter takes an
- unsigned long value and not a ‘time_t’ to avoid problems on systems
- which use a signed 32 bit ‘time_t’. Note further that the OpenPGP
- protocol uses 32 bit values for timestamps and thus can only encode
- dates up to the year 2106.
+ EXPIRES specifies the expiration time in seconds. If you supply 0,
+ a reasonable expiration time is chosen. Use the flag
+ ‘GPGME_CREATE_NOEXPIRE’ to create keys that do not expire. Note
+ that this parameter takes an unsigned long value and not a ‘time_t’
+ to avoid problems on systems which use a signed 32 bit ‘time_t’.
+ Note further that the OpenPGP protocol uses 32 bit values for
+ timestamps and thus can only encode dates up to the year 2106.
FLAGS takes the same values as described above for
‘gpgme_op_createkey’.
@@ -3530,6 +3602,45 @@ provide a fallback to the old function if the error code
operation; see there for details. It must be completed by calling
‘gpgme_wait’ on the context. *Note Waiting For Completion::.
+ -- Function: gpgme_error_t gpgme_op_set_ui_flag (gpgme_ctx_t CTX,
+ gpgme_key_t KEY, const char *USERID, cons char * NAME,
+ cons char * VALUE);
+
+ The function ‘gpgme_op_set_uid_flag’ is used to set flags on a user
+ ID from the OpenPGP key given by KEY. Setting flags on user IDs
+ after key creation is a feature of the OpenPGP protocol and thus
+ the protocol for the context CTX must be set to OpenPGP.
+
+ KEY specifies the key to operate on. This parameters is required.
+
+ USERID is the user ID of the key to be manipulated. This user ID
+ must be given verbatim because the engine does an exact and case
+ sensitive match. Thus the ‘uid’ field from the user ID object
+ (‘gpgme_user_id_t’) is to be used. This is a required parameter.
+
+ NAME names the flag which is to be changed. The only currently
+ supported flag is:
+
+ ‘primary’
+ This sets the primary key flag on the given user ID. All other
+ primary key flag on other user IDs are removed. VALUE must be
+ given as NULL. For technical reasons this functions bumps the
+ creation timestamp of all affected self-signatures up by one
+ second. At least GnuPG version 2.1.20 is required.
+
+ The function returns zero on success, ‘GPG_ERR_NOT_SUPPORTED’ if
+ the engine does not support the command, or a bunch of other error
+ codes.
+
+ -- Function: gpgme_error_t gpgme_op_set_uid_flag_start
+ (gpgme_ctx_t CTX, gpgme_key_t KEY, const char *USERID,
+ cons char * NAME, cons char * VALUE);
+
+ The function ‘gpgme_op_set_uid_flag_start’ initiates a
+ ‘gpgme_op_set_uid_flag’ operation; see there for details. It must
+ be completed by calling ‘gpgme_wait’ on the context. *Note Waiting
+ For Completion::.
+
-- Function: gpgme_error_t gpgme_op_genkey (gpgme_ctx_t CTX,
const char *PARMS, gpgme_data_t PUBLIC, gpgme_data_t SECRET)
@@ -3548,11 +3659,17 @@ provide a fallback to the old function if the error code
signed by the certification authority and imported before it can be
used. GpgSM does not make the fingerprint available.
- The argument PARMS specifies parameters for the key in an XML
- string. The details about the format of PARMS are specific to the
- crypto engine used by CTX. Here is an example for GnuPG as the
- crypto engine (all parameters of OpenPGP key generation are
- documented in the GPG manual):
+ The argument PARMS specifies parameters for the key in an string
+ that looks something like XML. The details about the format of
+ PARMS are specific to the crypto engine used by CTX. The first
+ line of the parameters must be ‘<GnupgKeyParams format="internal">’
+ and the last line must be ‘</GnupgKeyParams>’. Every line in
+ between the first and last lines is treated as a Header: Value
+ pair. In particular, no XML escaping is necessary if you need to
+ include the characters ‘<’, ‘>’, or ‘&’.
+
+ Here is an example for GnuPG as the crypto engine (all parameters
+ of OpenPGP key generation are documented in the GPG manual):
<GnupgKeyParms format="internal">
Key-Type: default
@@ -3584,9 +3701,10 @@ provide a fallback to the old function if the error code
The function returns the error code ‘GPG_ERR_NO_ERROR’ if the
operation could be started successfully, ‘GPG_ERR_INV_VALUE’ if
- PARMS is not a valid XML string, ‘GPG_ERR_NOT_SUPPORTED’ if PUBLIC
- or SECRET is not valid, and ‘GPG_ERR_GENERAL’ if no key was created
- by the backend.
+ PARMS is not a well-formed string (e.g. does not have the expected
+ tag-like headers and footers), ‘GPG_ERR_NOT_SUPPORTED’ if PUBLIC or
+ SECRET is not valid, and ‘GPG_ERR_GENERAL’ if no key was created by
+ the backend.
-- Function: gpgme_error_t gpgme_op_genkey_start (gpgme_ctx_t CTX,
const char *PARMS, gpgme_data_t PUBLIC, gpgme_data_t SECRET)
@@ -3681,16 +3799,15 @@ to create key signatures when using modern GnuPG versions.
put them all into one string separated by linefeeds characters
(‘\n’) and set the flag ‘GPGME_KEYSIGN_LFSEP’.
- EXPIRES can be set to the number of seconds since Epoch of the
- desired expiration date in UTC for the new signature. The common
- case is to use 0 to not set an expiration date. However, if the
- configuration of the engine defines a default expiration for key
- signatures, that is still used unless the flag
- ‘GPGME_KEYSIGN_NOEXPIRE’ is used. Note that this parameter takes
- an unsigned long value and not a ‘time_t’ to avoid problems on
- systems which use a signed 32 bit ‘time_t’. Note further that the
- OpenPGP protocol uses 32 bit values for timestamps and thus can
- only encode dates up to the year 2106.
+ EXPIRES specifies the expiration time of the new signature in
+ seconds. The common case is to use 0 to not set an expiration
+ date. However, if the configuration of the engine defines a
+ default expiration for key signatures, that is still used unless
+ the flag ‘GPGME_KEYSIGN_NOEXPIRE’ is used. Note that this
+ parameter takes an unsigned long value and not a ‘time_t’ to avoid
+ problems on systems which use a signed 32 bit ‘time_t’. Note
+ further that the OpenPGP protocol uses 32 bit values for timestamps
+ and thus can only encode dates up to the year 2106.
FLAGS can be set to the bit-wise OR of the following flags:
@@ -4099,7 +4216,7 @@ File: gpgme.info, Node: Changing TOFU Data, Next: Advanced Key Editing, Prev:
-------------------------
The OpenPGP engine features a Trust-On-First-Use (TOFU) key validation
-model. For resolving clonflics it is necessary to declare the policy
+model. For resolving conflicts it is necessary to declare the policy
for a key. See the GnuPG manual for details on the TOFU implementation.
-- Data type: enum gpgme_tofu_policy_t
@@ -4109,7 +4226,7 @@ for a key. See the GnuPG manual for details on the TOFU implementation.
‘GPGME_TOFU_POLICY_AUTO’
Set the policy to “autoâ€.
‘GPGME_TOFU_POLICY_GOOD’
- Set the policy to “googâ€.
+ Set the policy to “goodâ€.
‘GPGME_TOFU_POLICY_BAD’
Set the policy to “badâ€.
‘GPGME_TOFU_POLICY_ASK’
@@ -4366,6 +4483,42 @@ File: gpgme.info, Node: Decrypt, Next: Verify, Up: Crypto Operations
operation could be started successfully, and ‘GPG_ERR_INV_VALUE’ if
CIPHER or PLAIN is not a valid pointer.
+ -- Function: gpgme_error_t gpgme_op_decrypt_ext ( gpgme_ctx_t CTX,
+ gpgme_decrypt_flags_t FLAGS, gpgme_data_t CIPHER,
+ gpgme_data_t PLAIN)
+
+ The function ‘gpgme_op_decrypt_ext’ is the same as
+ ‘gpgme_op_decrypt_ext’ but has an additional argument FLAGS. If
+ FLAGS is 0 both function behave identically.
+
+ The value in FLAGS is a bitwise-or combination of one or multiple
+ of the following bit values:
+
+ ‘GPGME_DECRYPT_VERIFY’
+ The ‘GPGME_DECRYPT_VERIFY’ symbol specifies that this function
+ shall exacty act as ‘gpgme_op_decrypt_verify’.
+
+ ‘GPGME_DECRYPT_UNWRAP’
+ The ‘GPGME_DECRYPT_UNWRAP’ symbol specifies that the output
+ shall be an OpenPGP message with only the encryption layer
+ removed. This requires GnuPG 2.1.12 and works only for
+ OpenPGP. This is the counterpart to ‘GPGME_ENCRYPT_WRAP’.
+
+ The function returns the error codes as descriped for
+ ‘gpgme_op_decrypt’ respective ‘gpgme_op_encrypt’.
+
+ -- Function: gpgme_error_t gpgme_op_decrypt_ext_start (
+ gpgme_ctx_t CTX, gpgme_decrypt_flags_t FLAGS,
+ gpgme_data_t CIPHER, gpgme_data_t PLAIN)
+
+ The function ‘gpgme_op_decrypt_ext_start’ initiates a
+ ‘gpgme_op_decrypt_ext’ operation. It can be completed by calling
+ ‘gpgme_wait’ on the context. *Note Waiting For Completion::.
+
+ The function returns the error code ‘GPG_ERR_NO_ERROR’ if the
+ operation could be started successfully, and ‘GPG_ERR_INV_VALUE’ if
+ CIPHER or PLAIN is not a valid pointer.
+
-- Data type: gpgme_recipient_t
This is a pointer to a structure used to store information about
the recipient of an encrypted text which is decrypted in a
@@ -4538,7 +4691,17 @@ File: gpgme.info, Node: Verify, Next: Decrypt and Verify, Prev: Decrypt, Up:
This is a bit vector giving a summary of the signature status.
It provides an easy interface to a defined semantic of the
signature status. Checking just one bit is sufficient to see
- whether a signature is valid without any restrictions.
+ whether a signature is valid without any restrictions. This
+ means that you can check for GPGME_SIGSUM_VALID like this:
+
+ if ((sig.summary & GPGME_SIGSUM_VALID))
+ {
+ ..do stuff if valid..
+ }
+ else
+ {
+ ..do stuff if not fully valid..
+ }
The defined bits are:
‘GPGME_SIGSUM_VALID’
@@ -5047,10 +5210,23 @@ File: gpgme.info, Node: Encrypting a Plaintext, Up: Encrypt
‘GPGME_ENCRYPT_SYMMETRIC’
The ‘GPGME_ENCRYPT_SYMMETRIC’ symbol specifies that the output
- should be additionally encrypted symmetically even if
+ should be additionally encrypted symmetrically even if
recipients are provided. This feature is only supported for
for the OpenPGP crypto engine.
+ ‘GPGME_ENCRYPT_THROW_KEYIDS’
+ The ‘GPGME_ENCRYPT_THROW_KEYIDS’ symbols requests that the
+ identifiers for the decrption keys are not included in the
+ ciphertext. On the receiving side, the use of this flag may
+ slow down the decryption process because all available secret
+ keys must be tried. This flag is only honored for OpenPGP
+ encryption.
+
+ ‘GPGME_ENCRYPT_WRAP’
+ The ‘GPGME_ENCRYPT_WRAP’ symbol specifies that the input is an
+ OpenPGP message and not a plain data. This is the counterpart
+ to ‘GPGME_DECRYPT_UNWRAP’.
+
If ‘GPG_ERR_UNUSABLE_PUBKEY’ is returned, some recipients in RECP
are invalid, but not all. In this case the plaintext might be
encrypted for all valid recipients and returned in CIPHER (if this
@@ -5121,7 +5297,7 @@ File: gpgme.info, Node: Encrypting a Plaintext, Up: Encrypt
for the OpenPGP crypto engine.
-- Function: gpgme_error_t gpgme_op_encrypt_sign_start
- (gpgme_ctx_t CTX, gpgme_key_t RECP,
+ (gpgme_ctx_t CTX, gpgme_key_t RECP[],
gpgme_encrypt_flags_t FLAGS, gpgme_data_t PLAIN,
gpgme_data_t CIPHER)
The function ‘gpgme_op_encrypt_sign_start’ initiates a
@@ -5879,7 +6055,7 @@ next. We only support waiting for the success of a single operation.
exit (1);
}
/* Evaluate verify result. */
- …
+ ...
return 0;
}
diff --git a/doc/gpgme.info-2 b/doc/gpgme.info-2
index 7c32470..3285b3b 100644
--- a/doc/gpgme.info-2
+++ b/doc/gpgme.info-2
@@ -1,6 +1,6 @@
-This is gpgme.info, produced by makeinfo version 5.2 from gpgme.texi.
+This is gpgme.info, produced by makeinfo version 6.3 from gpgme.texi.
-Copyright © 2002–2008, 2010, 2012–2016 g10 Code GmbH.
+Copyright © 2002–2008, 2010, 2012–2017 g10 Code GmbH.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License as
@@ -19,10 +19,10 @@ END-INFO-DIR-ENTRY
This file documents the GPGME library.
- This is Edition 1.8.0-beta50, last updated 16 November 2016, of ‘The
-‘GnuPG Made Easy’ Reference Manual’, for Version 1.8.0-beta50.
+ This is Edition 1.9.0, last updated 16 November 2016, of ‘The ‘GnuPG
+Made Easy’ Reference Manual’, for Version 1.9.0.
- Copyright © 2002–2008, 2010, 2012–2016 g10 Code GmbH.
+ Copyright © 2002–2008, 2010, 2012–2017 g10 Code GmbH.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU General Public License as
@@ -122,7 +122,7 @@ combination fits its criteria of freedom. The Lesser General Public
License permits more lax criteria for linking other code with the
library.
- We call this license the "Lesser" General Public License because it
+ We call this license the “Lesser†General Public License because it
does _Less_ to protect the user’s freedom than the ordinary General
Public License. It also provides other free software developers Less of
an advantage over competing non-free programs. These disadvantages are
@@ -1527,17 +1527,17 @@ Function and Data Index
* enum gpgme_sig_mode_t: Creating a Signature.
(line 6)
* enum gpgme_sig_stat_t: Deprecated Functions.
- (line 427)
+ (line 434)
* enum gpgme_tofu_policy_t: Changing TOFU Data. (line 10)
* FILE: UI Server Set Input Files.
(line 9)
* GETINFO: Miscellaneous UI Server Commands.
(line 9)
-* gpgme_addrspec_from_uid: Decrypt and Verify. (line 47)
+* gpgme_addrspec_from_uid: Decrypt and Verify. (line 48)
* gpgme_attr_t: Deprecated Functions.
- (line 136)
+ (line 137)
* gpgme_attr_t <1>: Deprecated Functions.
- (line 313)
+ (line 314)
* gpgme_cancel: Cancellation. (line 16)
* gpgme_cancel_async: Cancellation. (line 36)
* gpgme_check_version: Library Version Check.
@@ -1556,7 +1556,7 @@ Function and Data Index
* gpgme_data_new: Memory Based Data Buffers.
(line 12)
* gpgme_data_new_from_cbs: Callback Based Data Buffers.
- (line 81)
+ (line 80)
* gpgme_data_new_from_fd: File Based Data Buffers.
(line 10)
* gpgme_data_new_from_file: Memory Based Data Buffers.
@@ -1578,13 +1578,13 @@ Function and Data Index
* gpgme_data_release_and_get_mem: Destroying Data Buffers.
(line 11)
* gpgme_data_release_cb_t: Callback Based Data Buffers.
- (line 56)
+ (line 55)
* gpgme_data_rewind: Deprecated Functions.
- (line 130)
+ (line 131)
* gpgme_data_seek: Data Buffer I/O Operations.
- (line 25)
+ (line 26)
* gpgme_data_seek_cb_t: Callback Based Data Buffers.
- (line 47)
+ (line 46)
* gpgme_data_set_encoding: Data Buffer Meta-Data.
(line 75)
* gpgme_data_set_file_name: Data Buffer Meta-Data.
@@ -1597,24 +1597,24 @@ Function and Data Index
* gpgme_data_write: Data Buffer I/O Operations.
(line 16)
* gpgme_data_write_cb_t: Callback Based Data Buffers.
- (line 30)
-* gpgme_decrypt_result_t: Decrypt. (line 54)
+ (line 29)
+* gpgme_decrypt_result_t: Decrypt. (line 91)
* gpgme_edit_cb_t: Deprecated Functions.
- (line 36)
+ (line 35)
* gpgme_encrypt_result_t: Encrypting a Plaintext.
- (line 93)
+ (line 108)
* gpgme_engine_check_version: Engine Version Check.
- (line 62)
+ (line 65)
* gpgme_engine_info_t: Engine Information. (line 6)
* gpgme_error: Error Values. (line 65)
-* gpgme_error_from_errno: Error Values. (line 88)
+* gpgme_error_from_errno: Error Values. (line 89)
* gpgme_error_t: Error Values. (line 24)
* gpgme_error_t (*gpgme_assuan_data_cb_t) (void *OPAQUE, const void *DATA, size_t DATALEN): Using the Assuan protocol.
(line 15)
* gpgme_error_t (*gpgme_assuan_inquire_cb_t) (void *OPAQUE, const char *NAME, const char *ARGS, gpgme_data_t *R_DATA): Using the Assuan protocol.
- (line 23)
+ (line 22)
* gpgme_error_t (*gpgme_assuan_status_cb_t) (void *OPAQUE, const char *STATUS, const char *ARGS): Using the Assuan protocol.
- (line 35)
+ (line 34)
* gpgme_error_t (*gpgme_edit_cb_t) (void *HANDLE, gpgme_status_code_t STATUS, const char *ARGS, int FD): Deprecated Functions.
(line 33)
* gpgme_error_t (*gpgme_interact_cb_t) (void *HANDLE, const char *STATUS, const char *ARGS, int FD): Advanced Key Editing.
@@ -1628,11 +1628,11 @@ Function and Data Index
* gpgme_error_t (*gpgme_status_cb_t)(void *HOOK, const char *KEYWORD, const char *ARGS): Status Message Callback.
(line 6)
* gpgme_err_code: Error Values. (line 42)
-* gpgme_err_code_from_errno: Error Values. (line 97)
+* gpgme_err_code_from_errno: Error Values. (line 98)
* gpgme_err_code_t: Error Values. (line 6)
-* gpgme_err_code_to_errno: Error Values. (line 102)
+* gpgme_err_code_to_errno: Error Values. (line 103)
* gpgme_err_make: Error Values. (line 57)
-* gpgme_err_make_from_errno: Error Values. (line 82)
+* gpgme_err_make_from_errno: Error Values. (line 83)
* gpgme_err_source: Error Values. (line 49)
* gpgme_err_source_t: Error Values. (line 13)
* gpgme_event_io_t: I/O Callback Interface.
@@ -1641,18 +1641,18 @@ Function and Data Index
(line 7)
* gpgme_free: Destroying Data Buffers.
(line 25)
-* gpgme_genkey_result_t: Generating Keys. (line 295)
+* gpgme_genkey_result_t: Generating Keys. (line 347)
* gpgme_get_armor: ASCII Armor. (line 13)
* gpgme_get_ctx_flag: Status Message Callback.
- (line 73)
+ (line 93)
* gpgme_get_dirinfo: Engine Version Check.
(line 6)
* gpgme_get_engine_info: Engine Information. (line 46)
* gpgme_get_include_certs: Included Certificates.
- (line 34)
+ (line 35)
* gpgme_get_io_cbs: Registering I/O Callbacks.
(line 44)
-* gpgme_get_key: Listing Keys. (line 147)
+* gpgme_get_key: Listing Keys. (line 177)
* gpgme_get_keylist_mode: Key Listing Mode. (line 73)
* gpgme_get_offline: Offline Mode. (line 23)
* gpgme_get_passphrase_cb: Passphrase Callback. (line 59)
@@ -1662,15 +1662,15 @@ Function and Data Index
* gpgme_get_protocol: Protocol Selection. (line 21)
* gpgme_get_protocol_name: Protocols and Engines.
(line 51)
-* gpgme_get_sender: Setting the Sender. (line 26)
+* gpgme_get_sender: Setting the Sender. (line 27)
* gpgme_get_sig_key: Deprecated Functions.
- (line 626)
+ (line 634)
* gpgme_get_sig_status: Deprecated Functions.
- (line 475)
+ (line 482)
* gpgme_get_sig_string_attr: Deprecated Functions.
- (line 530)
+ (line 538)
* gpgme_get_sig_ulong_attr: Deprecated Functions.
- (line 564)
+ (line 572)
* gpgme_get_status_cb: Status Message Callback.
(line 29)
* gpgme_get_textmode: Text Mode. (line 20)
@@ -1679,73 +1679,75 @@ Function and Data Index
* gpgme_import_result_t: Importing Keys. (line 110)
* gpgme_import_status_t: Importing Keys. (line 72)
* gpgme_interact_cb_t: Advanced Key Editing.
- (line 9)
+ (line 8)
* gpgme_invalid_key_t: Crypto Operations. (line 10)
* gpgme_io_cb_t: I/O Callback Interface.
(line 7)
-* gpgme_keylist_result_t: Listing Keys. (line 124)
+* gpgme_keylist_result_t: Listing Keys. (line 154)
* gpgme_key_get_string_attr: Deprecated Functions.
- (line 278)
+ (line 279)
* gpgme_key_get_ulong_attr: Deprecated Functions.
- (line 292)
+ (line 293)
* gpgme_key_ref: Manipulating Keys. (line 6)
* gpgme_key_release: Deprecated Functions.
(line 14)
* gpgme_key_sig_get_string_attr: Deprecated Functions.
- (line 369)
+ (line 370)
* gpgme_key_sig_get_ulong_attr: Deprecated Functions.
- (line 383)
-* gpgme_key_sig_t: Key objects. (line 226)
+ (line 386)
+* gpgme_key_sig_t: Key objects. (line 244)
* gpgme_key_t: Key objects. (line 10)
* gpgme_key_unref: Manipulating Keys. (line 10)
* gpgme_new: Creating Contexts. (line 6)
* gpgme_new_signature_t: Creating a Signature.
(line 57)
* gpgme_off_t: Exchanging Data. (line 24)
-* gpgme_op_adduid: Generating Keys. (line 161)
-* gpgme_op_adduid_start: Generating Keys. (line 185)
+* gpgme_op_adduid: Generating Keys. (line 167)
+* gpgme_op_adduid_start: Generating Keys. (line 191)
* gpgme_op_assuan_transact_ext: Using the Assuan protocol.
(line 56)
* gpgme_op_assuan_transact_start: Using the Assuan protocol.
- (line 43)
+ (line 41)
* gpgme_op_card_edit: Deprecated Functions.
(line 82)
* gpgme_op_card_edit_start: Deprecated Functions.
(line 92)
* gpgme_op_createkey: Generating Keys. (line 14)
-* gpgme_op_createkey_start: Generating Keys. (line 99)
-* gpgme_op_createsubkey: Generating Keys. (line 109)
-* gpgme_op_createsubkey_start: Generating Keys. (line 151)
+* gpgme_op_createkey_start: Generating Keys. (line 103)
+* gpgme_op_createsubkey: Generating Keys. (line 114)
+* gpgme_op_createsubkey_start: Generating Keys. (line 156)
* gpgme_op_decrypt: Decrypt. (line 6)
-* gpgme_op_decrypt_result: Decrypt. (line 91)
+* gpgme_op_decrypt_ext: Decrypt. (line 30)
+* gpgme_op_decrypt_ext_start: Decrypt. (line 54)
+* gpgme_op_decrypt_result: Decrypt. (line 128)
* gpgme_op_decrypt_start: Decrypt. (line 20)
* gpgme_op_decrypt_verify: Decrypt and Verify. (line 6)
* gpgme_op_decrypt_verify_start: Decrypt and Verify. (line 30)
* gpgme_op_delete: Deleting Keys. (line 6)
* gpgme_op_delete_start: Deleting Keys. (line 20)
* gpgme_op_edit: Deprecated Functions.
- (line 47)
+ (line 46)
* gpgme_op_edit_start: Deprecated Functions.
(line 68)
* gpgme_op_encrypt: Encrypting a Plaintext.
(line 6)
* gpgme_op_encrypt_result: Encrypting a Plaintext.
- (line 104)
+ (line 119)
* gpgme_op_encrypt_sign: Encrypting a Plaintext.
- (line 115)
+ (line 130)
* gpgme_op_encrypt_sign_start: Encrypting a Plaintext.
- (line 125)
+ (line 141)
* gpgme_op_encrypt_start: Encrypting a Plaintext.
- (line 76)
+ (line 90)
* gpgme_op_export: Exporting Keys. (line 38)
-* gpgme_op_export_ext: Exporting Keys. (line 69)
-* gpgme_op_export_ext_start: Exporting Keys. (line 90)
-* gpgme_op_export_keys: Exporting Keys. (line 101)
-* gpgme_op_export_keys_start: Exporting Keys. (line 124)
-* gpgme_op_export_start: Exporting Keys. (line 58)
-* gpgme_op_genkey: Generating Keys. (line 225)
-* gpgme_op_genkey_result: Generating Keys. (line 328)
-* gpgme_op_genkey_start: Generating Keys. (line 283)
+* gpgme_op_export_ext: Exporting Keys. (line 71)
+* gpgme_op_export_ext_start: Exporting Keys. (line 93)
+* gpgme_op_export_keys: Exporting Keys. (line 105)
+* gpgme_op_export_keys_start: Exporting Keys. (line 130)
+* gpgme_op_export_start: Exporting Keys. (line 59)
+* gpgme_op_genkey: Generating Keys. (line 270)
+* gpgme_op_genkey_result: Generating Keys. (line 380)
+* gpgme_op_genkey_start: Generating Keys. (line 335)
* gpgme_op_import: Importing Keys. (line 9)
* gpgme_op_import_ext: Deprecated Functions.
(line 22)
@@ -1754,16 +1756,17 @@ Function and Data Index
* gpgme_op_import_result: Importing Keys. (line 160)
* gpgme_op_import_start: Importing Keys. (line 24)
* gpgme_op_interact: Advanced Key Editing.
- (line 21)
+ (line 20)
* gpgme_op_interact_start: Advanced Key Editing.
- (line 46)
-* gpgme_op_keylist_end: Listing Keys. (line 81)
-* gpgme_op_keylist_ext_start: Listing Keys. (line 33)
-* gpgme_op_keylist_next: Listing Keys. (line 65)
-* gpgme_op_keylist_result: Listing Keys. (line 135)
+ (line 45)
+* gpgme_op_keylist_end: Listing Keys. (line 110)
+* gpgme_op_keylist_ext_start: Listing Keys. (line 34)
+* gpgme_op_keylist_from_data: Listing Keys. (line 67)
+* gpgme_op_keylist_next: Listing Keys. (line 93)
+* gpgme_op_keylist_result: Listing Keys. (line 165)
* gpgme_op_keylist_start: Listing Keys. (line 6)
* gpgme_op_keysign: Signing Keys. (line 12)
-* gpgme_op_keysign_start: Signing Keys. (line 68)
+* gpgme_op_keysign_start: Signing Keys. (line 67)
* gpgme_op_passwd: Changing Passphrases.
(line 6)
* gpgme_op_passwd_start: Changing Passphrases.
@@ -1772,8 +1775,10 @@ Function and Data Index
(line 66)
* gpgme_op_query_swdb_result: Checking for updates.
(line 76)
-* gpgme_op_revuid: Generating Keys. (line 192)
-* gpgme_op_revuid_start: Generating Keys. (line 218)
+* gpgme_op_revuid: Generating Keys. (line 198)
+* gpgme_op_revuid_start: Generating Keys. (line 224)
+* gpgme_op_set_uid_flag_start: Generating Keys. (line 261)
+* gpgme_op_set_ui_flag: Generating Keys. (line 231)
* gpgme_op_sign: Creating a Signature.
(line 21)
* gpgme_op_sign_result: Creating a Signature.
@@ -1790,7 +1795,7 @@ Function and Data Index
* gpgme_op_trustlist_next: Listing Trust Items. (line 27)
* gpgme_op_trustlist_start: Listing Trust Items. (line 6)
* gpgme_op_verify: Verify. (line 6)
-* gpgme_op_verify_result: Verify. (line 262)
+* gpgme_op_verify_result: Verify. (line 272)
* gpgme_op_verify_start: Verify. (line 26)
* gpgme_passphrase_cb_t: Passphrase Callback. (line 10)
* gpgme_pinentry_mode_t: Pinentry Mode. (line 20)
@@ -1802,12 +1807,12 @@ Function and Data Index
* gpgme_pubkey_algo_name: Public Key Algorithms.
(line 50)
* gpgme_pubkey_algo_string: Public Key Algorithms.
- (line 59)
+ (line 60)
* gpgme_pubkey_algo_t: Public Key Algorithms.
(line 10)
* gpgme_query_swdb_result_t: Checking for updates.
(line 11)
-* gpgme_recipient_t: Decrypt. (line 30)
+* gpgme_recipient_t: Decrypt. (line 67)
* gpgme_register_io_cb_t: I/O Callback Interface.
(line 23)
* gpgme_release: Destroying Contexts. (line 6)
@@ -1819,7 +1824,7 @@ Function and Data Index
* gpgme_set_engine_info: Engine Configuration.
(line 11)
* gpgme_set_global_flag: Library Version Check.
- (line 42)
+ (line 43)
* gpgme_set_include_certs: Included Certificates.
(line 6)
* gpgme_set_io_cbs: Registering I/O Callbacks.
@@ -1853,19 +1858,19 @@ Function and Data Index
(line 41)
* gpgme_sig_notation_t: Verify. (line 38)
* gpgme_sig_stat_t: Deprecated Functions.
- (line 428)
+ (line 435)
* gpgme_ssize_t: Exchanging Data. (line 30)
* gpgme_status_cb_t: Status Message Callback.
(line 8)
* gpgme_strerror: Error Strings. (line 6)
* gpgme_strerror_r: Error Strings. (line 15)
* gpgme_strsource: Error Strings. (line 26)
-* gpgme_subkey_t: Key objects. (line 94)
+* gpgme_subkey_t: Key objects. (line 100)
* gpgme_tofu_policy_t: Changing TOFU Data. (line 11)
* gpgme_trust_item_get_int_attr: Deprecated Functions.
- (line 413)
+ (line 419)
* gpgme_trust_item_get_string_attr: Deprecated Functions.
- (line 399)
+ (line 404)
* gpgme_trust_item_ref: Manipulating Trust Items.
(line 6)
* gpgme_trust_item_release: Deprecated Functions.
@@ -1874,10 +1879,10 @@ Function and Data Index
(line 8)
* gpgme_trust_item_unref: Manipulating Trust Items.
(line 10)
-* gpgme_user_id_t: Key objects. (line 180)
+* gpgme_user_id_t: Key objects. (line 192)
* gpgme_validity_t: Information About Keys.
(line 9)
-* gpgme_verify_result_t: Verify. (line 247)
+* gpgme_verify_result_t: Verify. (line 257)
* gpgme_wait: Waiting For Completion.
(line 6)
* IMPORT_FILES: UI Server Import/Export Keys.
@@ -1889,7 +1894,7 @@ Function and Data Index
* MESSAGE: UI Server Verify. (line 10)
* MICALG: UI Server Sign. (line 43)
* off_t (*gpgme_data_seek_cb_t) (void *HANDLE, off_t OFFSET, int WHENCE): Callback Based Data Buffers.
- (line 44)
+ (line 43)
* OUTPUT: UI Server Encrypt. (line 36)
* OUTPUT <1>: UI Server Sign. (line 18)
* OUTPUT <2>: UI Server Decrypt. (line 19)
@@ -1914,14 +1919,14 @@ Function and Data Index
* START_KEYMANAGER: Miscellaneous UI Server Commands.
(line 31)
* struct gpgme_data_cbs: Callback Based Data Buffers.
- (line 60)
+ (line 59)
* struct gpgme_io_cbs: Registering I/O Callbacks.
(line 6)
* VERIFY: UI Server Verify. (line 31)
* VERIFY_FILES: UI Server Verify/Decrypt Files.
(line 10)
* void (*gpgme_data_release_cb_t) (void *HANDLE): Callback Based Data Buffers.
- (line 55)
+ (line 54)
* void (*gpgme_event_io_cb_t) (void *DATA, gpgme_event_io_t TYPE, void *TYPE_DATA): I/O Callback Interface.
(line 89)
* void (*gpgme_progress_cb_t)(void *HOOK, const char *WHAT, int TYPE, int CURRENT, int TOTAL): Progress Meter Callback.
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 32e0861..40423cf 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -14,7 +14,7 @@
@syncodeindex pg fn
@copying
-Copyright @copyright{} 2002--2008, 2010, 2012--2016 g10 Code GmbH.
+Copyright @copyright{} 2002--2008, 2010, 2012--2017 g10 Code GmbH.
@quotation
Permission is granted to copy, distribute and/or modify this document
@@ -979,6 +979,9 @@ Return the file name of the CMS engine.
@item g13-name
Return the name of the file container encryption engine.
+@item gpg-wks-client-name
+Return the name of the Web Key Service tool.
+
@end table
@end deftypefun
@@ -2888,6 +2891,29 @@ by this function. The properties are identified by the following
values for @var{name}:
@table @code
+@item "redraw"
+This flag is normally not changed by the caller because GPGME sets and
+clears it automatically: The flag is cleared before an operation and
+set if an operation noticed that the engine has launched a Pinentry.
+A Curses based application may use this information to redraw the
+screen; for example:
+
+@example
+ err = gpgme_op_keylist_start (ctx, "foo@@example.org", 0);
+ while (!err)
+ @{
+ err = gpgme_op_keylist_next (ctx, &key);
+ if (err)
+ break;
+ show_key (key);
+ gpgme_key_release (key);
+ @}
+ if ((s = gpgme_get_ctx_flag (ctx, "redraw")) && *s)
+ redraw_screen ();
+ gpgme_release (ctx);
+@end example
+
+
@item "full-status"
Using a @var{value} of "1" the status callback set by
gpgme_set_status_cb returns all status lines with the exception of
@@ -3052,6 +3078,9 @@ be true even if the corresponding subkey flag may be false
(offline/stub keys). This is only set if a listing of secret keys has
been requested or if @code{GPGME_KEYLIST_MODE_WITH_SECRET} is active.
+@item unsigned int origin : 5
+Reserved for the origin of this key.
+
@item gpgme_protocol_t protocol
This is the protocol supported by this key.
@@ -3085,6 +3114,9 @@ this is a copy of the fingerprint of the first subkey. For an
incomplete key (for example from a verification result) a subkey may
be missing but this field may be set nevertheless.
+@item unsigned long last_update
+Reserved for the time of the last update of this key.
+
@end table
@end deftp
@@ -3133,6 +3165,12 @@ This is true if the subkey can be used for authentication.
This is true if the subkey can be used for qualified signatures
according to local government regulations.
+@item unsigned int is_de_vs : 1
+This is true if the subkey complies with the rules for classified
+information in Germany at the restricted level (VS-NfD). This are
+currently RSA keys of at least 2048 bits or ECDH/ECDSA keys using a
+Brainpool curve.
+
@item unsigned int secret : 1
This is true if the subkey is a secret key. Note that it will be
false if the key is actually a stub key; i.e. a secret key operation
@@ -3223,6 +3261,13 @@ this user id.
@item gpgme_key_sig_t signatures
This is a linked list with the signatures on this user ID.
+
+@item unsigned int origin : 5
+Reserved for the origin of this user ID.
+
+@item unsigned long last_update
+Reserved for the time of the last update of this user ID.
+
@end table
@end deftp
@@ -3313,6 +3358,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
@@ -3340,6 +3386,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
@@ -3370,7 +3417,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 key 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.
@@ -3388,6 +3464,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}.
@@ -3402,7 +3479,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;
@@ -3589,13 +3666,14 @@ primary key plus a secondary key (subkey).
@var{reserved} must be set to zero.
-@var{expires} can be set to the number of seconds since Epoch of the
-desired expiration date in UTC for the new key. Using 0 does not
-set an expiration date. Note that this parameter takes an unsigned long
-value and not a @code{time_t} to avoid problems on systems which use a
-signed 32 bit @code{time_t}. Note further that the OpenPGP protocol
-uses 32 bit values for timestamps and thus can only encode dates up to
-the year 2106.
+@var{expires} specifies the expiration time in seconds. If you supply
+0, a reasonable expiration time is chosen. Use the flag
+@code{GPGME_CREATE_NOEXPIRE} to create keys that do not expire. Note
+that this parameter takes an unsigned long value and not a
+@code{time_t} to avoid problems on systems which use a signed 32 bit
+@code{time_t}. Note further that the OpenPGP protocol uses 32 bit
+values for timestamps and thus can only encode dates up to the year
+2106.
@var{extrakey} is currently not used and must be set to @code{NULL}.
A future version of GPGME may use this parameter to create X.509 keys.
@@ -3637,6 +3715,9 @@ The engine does not allow the creation of a key with a user ID
already existing in the local key database. This flag can be used to
override this check.
+@item GPGME_CREATE_NOEXPIRE
+Request generation of keys that do not expire.
+
@end table
After the operation completed successfully, information about the
@@ -3696,13 +3777,14 @@ able to already handle such future algorithms.
@var{reserved} must be set to zero.
-@var{expires} can be set to the number of seconds since Epoch of the
-desired expiration date in UTC for the new subkey. Using 0 does not
-set an expiration date. Note that this parameter takes an unsigned long
-value and not a @code{time_t} to avoid problems on systems which use a
-signed 32 bit @code{time_t}. Note further that the OpenPGP protocol
-uses 32 bit values for timestamps and thus can only encode dates up to
-the year 2106.
+@var{expires} specifies the expiration time in seconds. If you supply
+0, a reasonable expiration time is chosen. Use the flag
+@code{GPGME_CREATE_NOEXPIRE} to create keys that do not expire. Note
+that this parameter takes an unsigned long value and not a
+@code{time_t} to avoid problems on systems which use a signed 32 bit
+@code{time_t}. Note further that the OpenPGP protocol uses 32 bit
+values for timestamps and thus can only encode dates up to the year
+2106.
@var{flags} takes the same values as described above for
@code{gpgme_op_createkey}.
@@ -3828,6 +3910,61 @@ be completed by calling @code{gpgme_wait} on the context.
@c
+@c gpgme_op_set_uid_flag
+@c
+@deftypefun gpgme_error_t gpgme_op_set_ui_flag @
+ (@w{gpgme_ctx_t @var{ctx}}, @
+ @w{gpgme_key_t @var{key}}, @
+ @w{const char *@var{userid}}, @
+ @w{cons char * @var{name}}, @
+ @w{cons char * @var{value}});
+
+The function @code{gpgme_op_set_uid_flag} is used to set flags on a
+user ID from the OpenPGP key given by @var{KEY}. Setting flags on
+user IDs after key creation is a feature of the OpenPGP protocol and
+thus the protocol for the context @var{ctx} must be set to OpenPGP.
+
+@var{key} specifies the key to operate on. This parameters is required.
+
+@var{userid} is the user ID of the key to be manipulated. This user ID
+must be given verbatim because the engine does an exact and case
+sensitive match. Thus the @code{uid} field from the user ID object
+(@code{gpgme_user_id_t}) is to be used. This is a required parameter.
+
+@var{name} names the flag which is to be changed. The only currently
+supported flag is:
+
+@table @code
+@item primary
+This sets the primary key flag on the given user ID. All other
+primary key flag on other user IDs are removed. @var{value} must be
+given as NULL. For technical reasons this functions bumps the
+creation timestamp of all affected self-signatures up by one second.
+At least GnuPG version 2.1.20 is required.
+
+@end table
+
+The function returns zero on success, @code{GPG_ERR_NOT_SUPPORTED} if
+the engine does not support the command, or a bunch of other error
+codes.
+
+@end deftypefun
+
+@deftypefun gpgme_error_t gpgme_op_set_uid_flag_start @
+ (@w{gpgme_ctx_t @var{ctx}}, @
+ @w{gpgme_key_t @var{key}}, @
+ @w{const char *@var{userid}}, @
+ @w{cons char * @var{name}}, @
+ @w{cons char * @var{value}});
+
+The function @code{gpgme_op_set_uid_flag_start} initiates a
+@code{gpgme_op_set_uid_flag} operation; see there for details. It must
+be completed by calling @code{gpgme_wait} on the context.
+@xref{Waiting For Completion}.
+
+@end deftypefun
+
+@c
@c gpgme_op_genkey
@c
@deftypefun gpgme_error_t gpgme_op_genkey @
@@ -3851,11 +3988,18 @@ and return a certificate request in @var{public}, which then needs to
be signed by the certification authority and imported before it can be
used. GpgSM does not make the fingerprint available.
-The argument @var{parms} specifies parameters for the key in an XML
-string. The details about the format of @var{parms} are specific to
-the crypto engine used by @var{ctx}. Here is an example for GnuPG as
-the crypto engine (all parameters of OpenPGP key generation are
-documented in the GPG manual):
+The argument @var{parms} specifies parameters for the key in an string
+that looks something like XML. The details about the format of
+@var{parms} are specific to the crypto engine used by @var{ctx}. The
+first line of the parameters must be @code{<GnupgKeyParams
+format="internal">} and the last line must be
+@code{</GnupgKeyParams>}. Every line in between the first and last
+lines is treated as a Header: Value pair. In particular, no XML
+escaping is necessary if you need to include the characters @code{<},
+@code{>}, or @code{&}.
+
+Here is an example for GnuPG as the crypto engine (all parameters of
+OpenPGP key generation are documented in the GPG manual):
@example
<GnupgKeyParms format="internal">
@@ -3891,9 +4035,10 @@ retrieved with @code{gpgme_op_genkey_result}.
The function returns the error code @code{GPG_ERR_NO_ERROR} if the
operation could be started successfully, @code{GPG_ERR_INV_VALUE} if
-@var{parms} is not a valid XML string, @code{GPG_ERR_NOT_SUPPORTED} if
-@var{public} or @var{secret} is not valid, and @code{GPG_ERR_GENERAL}
-if no key was created by the backend.
+@var{parms} is not a well-formed string (e.g. does not have the
+expected tag-like headers and footers), @code{GPG_ERR_NOT_SUPPORTED}
+if @var{public} or @var{secret} is not valid, and
+@code{GPG_ERR_GENERAL} if no key was created by the backend.
@end deftypefun
@deftypefun gpgme_error_t gpgme_op_genkey_start (@w{gpgme_ctx_t @var{ctx}}, @w{const char *@var{parms}}, @w{gpgme_data_t @var{public}}, @w{gpgme_data_t @var{secret}})
@@ -4008,11 +4153,10 @@ object (@code{gpgme_user_id_t}) is to be used. To select more than
one user ID put them all into one string separated by linefeeds
characters (@code{\n}) and set the flag @code{GPGME_KEYSIGN_LFSEP}.
-@var{expires} can be set to the number of seconds since Epoch of the
-desired expiration date in UTC for the new signature. The common case
-is to use 0 to not set an expiration date. However, if the
-configuration of the engine defines a default expiration for key
-signatures, that is still used unless the flag
+@var{expires} specifies the expiration time of the new signature in
+seconds. The common case is to use 0 to not set an expiration date.
+However, if the configuration of the engine defines a default
+expiration for key signatures, that is still used unless the flag
@code{GPGME_KEYSIGN_NOEXPIRE} is used. Note that this parameter takes
an unsigned long value and not a @code{time_t} to avoid problems on
systems which use a signed 32 bit @code{time_t}. Note further that
@@ -4454,7 +4598,7 @@ could not be started.
@cindex validity, TOFU
The OpenPGP engine features a Trust-On-First-Use (TOFU) key validation
-model. For resolving clonflics it is necessary to declare the policy
+model. For resolving conflicts it is necessary to declare the policy
for a key. See the GnuPG manual for details on the TOFU
implementation.
@@ -4467,7 +4611,7 @@ policy values that are supported by @acronym{GPGME}:
@item GPGME_TOFU_POLICY_AUTO
Set the policy to ``auto''.
@item GPGME_TOFU_POLICY_GOOD
-Set the policy to ``goog''.
+Set the policy to ``good''.
@item GPGME_TOFU_POLICY_BAD
Set the policy to ``bad''.
@item GPGME_TOFU_POLICY_ASK
@@ -4759,6 +4903,53 @@ operation could be started successfully, and @code{GPG_ERR_INV_VALUE}
if @var{cipher} or @var{plain} is not a valid pointer.
@end deftypefun
+
+@deftypefun gpgme_error_t gpgme_op_decrypt_ext ( @
+ @w{gpgme_ctx_t @var{ctx}}, @
+ @w{gpgme_decrypt_flags_t @var{flags}}, @
+ @w{gpgme_data_t @var{cipher}}, @
+ @w{gpgme_data_t @var{plain}})
+
+The function @code{gpgme_op_decrypt_ext} is the same as
+@code{gpgme_op_decrypt_ext} but has an additional argument
+@var{flags}. If @var{flags} is 0 both function behave identically.
+
+The value in @var{flags} is a bitwise-or combination of one or
+multiple of the following bit values:
+
+@table @code
+@item GPGME_DECRYPT_VERIFY
+The @code{GPGME_DECRYPT_VERIFY} symbol specifies that this function
+shall exacty act as @code{gpgme_op_decrypt_verify}.
+
+@item GPGME_DECRYPT_UNWRAP
+The @code{GPGME_DECRYPT_UNWRAP} symbol specifies that the output shall
+be an OpenPGP message with only the encryption layer removed. This
+requires GnuPG 2.1.12 and works only for OpenPGP. This is the
+counterpart to @code{GPGME_ENCRYPT_WRAP}.
+
+@end table
+
+The function returns the error codes as descriped for
+@code{gpgme_op_decrypt} respective @code{gpgme_op_encrypt}.
+@end deftypefun
+
+@deftypefun gpgme_error_t gpgme_op_decrypt_ext_start ( @
+ @w{gpgme_ctx_t @var{ctx}}, @
+ @w{gpgme_decrypt_flags_t @var{flags}}, @
+ @w{gpgme_data_t @var{cipher}}, @
+ @w{gpgme_data_t @var{plain}})
+
+The function @code{gpgme_op_decrypt_ext_start} initiates a
+@code{gpgme_op_decrypt_ext} operation. It can be completed by calling
+@code{gpgme_wait} on the context. @xref{Waiting For Completion}.
+
+The function returns the error code @code{GPG_ERR_NO_ERROR} if the
+operation could be started successfully, and @code{GPG_ERR_INV_VALUE}
+if @var{cipher} or @var{plain} is not a valid pointer.
+@end deftypefun
+
+
@deftp {Data type} {gpgme_recipient_t}
This is a pointer to a structure used to store information about the
recipient of an encrypted text which is decrypted in a
@@ -4948,7 +5139,19 @@ list, or @code{NULL} if this is the last element.
This is a bit vector giving a summary of the signature status. It
provides an easy interface to a defined semantic of the signature
status. Checking just one bit is sufficient to see whether a
-signature is valid without any restrictions.
+signature is valid without any restrictions. This means that
+you can check for GPGME_SIGSUM_VALID like this:
+
+@example
+if ((sig.summary & GPGME_SIGSUM_VALID))
+@{
+ ..do stuff if valid..
+@}
+else
+@{
+ ..do stuff if not fully valid..
+@}
+@end example
The defined bits are:
@table @code
@@ -5480,10 +5683,22 @@ also expect a sign command.
@item GPGME_ENCRYPT_SYMMETRIC
The @code{GPGME_ENCRYPT_SYMMETRIC} symbol specifies that the
-output should be additionally encrypted symmetically even
+output should be additionally encrypted symmetrically even
if recipients are provided. This feature is only supported for
for the OpenPGP crypto engine.
+@item GPGME_ENCRYPT_THROW_KEYIDS
+The @code{GPGME_ENCRYPT_THROW_KEYIDS} symbols requests that the
+identifiers for the decrption keys are not included in the ciphertext.
+On the receiving side, the use of this flag may slow down the
+decryption process because all available secret keys must be tried.
+This flag is only honored for OpenPGP encryption.
+
+@item GPGME_ENCRYPT_WRAP
+The @code{GPGME_ENCRYPT_WRAP} symbol specifies that the input is an
+OpenPGP message and not a plain data. This is the counterpart to
+@code{GPGME_DECRYPT_UNWRAP}.
+
@end table
If @code{GPG_ERR_UNUSABLE_PUBKEY} is returned, some recipients in
@@ -5562,7 +5777,7 @@ The combined encrypt and sign operation is currently only available
for the OpenPGP crypto engine.
@end deftypefun
-@deftypefun gpgme_error_t gpgme_op_encrypt_sign_start (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{recp}}, @w{gpgme_encrypt_flags_t @var{flags}}, @w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
+@deftypefun gpgme_error_t gpgme_op_encrypt_sign_start (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{recp}[]}, @w{gpgme_encrypt_flags_t @var{flags}}, @w{gpgme_data_t @var{plain}}, @w{gpgme_data_t @var{cipher}})
The function @code{gpgme_op_encrypt_sign_start} initiates a
@code{gpgme_op_encrypt_sign} operation. It can be completed by
calling @code{gpgme_wait} on the context. @xref{Waiting For
diff --git a/gpgme.spec b/gpgme.spec
index afba50f..4077c19 100644
--- a/gpgme.spec
+++ b/gpgme.spec
@@ -1,7 +1,7 @@
# This is a template. The dist target uses it to create the real file.
Summary: GPGME - GnuPG Made Easy
Name: gpgme
-Version: 1.8.0
+Version: 1.9.0
Release: 1
URL: https://gnupg.org/gpgme.html
Source: ftp://ftp.gnupg.org/gcrypt/alpha/gpgme/%{name}-%{version}.tar.gz
diff --git a/lang/Makefile.in b/lang/Makefile.in
index 647734a..5ebbf14 100644
--- a/lang/Makefile.in
+++ b/lang/Makefile.in
@@ -109,8 +109,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
diff --git a/lang/cl/Makefile.in b/lang/cl/Makefile.in
index 31d9325..4737b80 100644
--- a/lang/cl/Makefile.in
+++ b/lang/cl/Makefile.in
@@ -112,8 +112,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
diff --git a/lang/cl/gpgme.asd b/lang/cl/gpgme.asd
index 5410fad..50046a6 100644
--- a/lang/cl/gpgme.asd
+++ b/lang/cl/gpgme.asd
@@ -27,7 +27,7 @@
(defsystem gpgme
:description "GnuPG Made Easy."
:author "g10 Code GmbH"
- :version "1.8.0"
+ :version "1.9.0"
:licence "GPL"
:depends-on ("cffi" "gpg-error")
:components ((:file "gpgme-package")
diff --git a/lang/cpp/Makefile.in b/lang/cpp/Makefile.in
index 30aef31..f49d1d0 100644
--- a/lang/cpp/Makefile.in
+++ b/lang/cpp/Makefile.in
@@ -110,8 +110,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
diff --git a/lang/cpp/src/GpgmeppConfig.cmake.in.in b/lang/cpp/src/GpgmeppConfig.cmake.in.in
index 928d19f..7f42f31 100644
--- a/lang/cpp/src/GpgmeppConfig.cmake.in.in
+++ b/lang/cpp/src/GpgmeppConfig.cmake.in.in
@@ -63,8 +63,8 @@ add_library(Gpgmepp SHARED IMPORTED)
set_target_properties(Gpgmepp PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "@resolved_includedir@/gpgme++;@resolved_includedir@"
- INTERFACE_LINK_LIBRARIES "pthread;@resolved_libdir@/libgpgme@libsuffix@;@LIBASSUAN_LIBS@"
- IMPORTED_LOCATION "@resolved_libdir@/libgpgmepp.so"
+ INTERFACE_LINK_LIBRARIES "pthread;@resolved_libdir@/libgpgme.so;@LIBASSUAN_LIBS@"
+ IMPORTED_LOCATION "@resolved_libdir@/libgpgmepp@libsuffix@"
)
if(CMAKE_VERSION VERSION_LESS 2.8.12)
diff --git a/lang/cpp/src/Makefile.am b/lang/cpp/src/Makefile.am
index 92ed784..4028b3d 100644
--- a/lang/cpp/src/Makefile.am
+++ b/lang/cpp/src/Makefile.am
@@ -31,7 +31,8 @@ main_sources = \
signingresult.cpp encryptionresult.cpp \
engineinfo.cpp gpgsetexpirytimeeditinteractor.cpp \
gpgsetownertrusteditinteractor.cpp gpgsignkeyeditinteractor.cpp \
- gpgadduserideditinteractor.cpp defaultassuantransaction.cpp \
+ gpgadduserideditinteractor.cpp gpggencardkeyinteractor.cpp \
+ defaultassuantransaction.cpp \
scdgetinfoassuantransaction.cpp gpgagentgetinfoassuantransaction.cpp \
vfsmountresult.cpp configuration.cpp tofuinfo.cpp swdbresult.cpp
@@ -42,6 +43,7 @@ gpgmepp_headers = \
gpgadduserideditinteractor.h gpgagentgetinfoassuantransaction.h \
gpgmefw.h gpgsetexpirytimeeditinteractor.h \
gpgsetownertrusteditinteractor.h gpgsignkeyeditinteractor.h \
+ gpggencardkeyinteractor.h \
importresult.h keygenerationresult.h key.h keylistresult.h \
notation.h result.h scdgetinfoassuantransaction.h signingresult.h \
trustitem.h verificationresult.h vfsmountresult.h gpgmepp_export.h \
@@ -69,6 +71,12 @@ libgpgmepp_la_LIBADD = ../../../src/libgpgme.la @LIBASSUAN_LIBS@
libgpgmepp_la_LDFLAGS = -no-undefined -version-info \
@LIBGPGMEPP_LT_CURRENT@:@LIBGPGMEPP_LT_REVISION@:@LIBGPGMEPP_LT_AGE@
+if HAVE_MACOS_SYSTEM
+libsuffix=.dylib
+else
+libsuffix=.so
+endif
+
if HAVE_W32_SYSTEM
GpgmeppConfig.cmake: GpgmeppConfig-w32.cmake.in
sed -e 's|[@]resolved_bindir@|$(bindir)|g' < "$<" | \
@@ -77,6 +85,7 @@ GpgmeppConfig.cmake: GpgmeppConfig-w32.cmake.in
else
GpgmeppConfig.cmake: GpgmeppConfig.cmake.in
sed -e 's|[@]resolved_libdir@|$(libdir)|g' < "$<" | \
+ sed -e 's|[@]libsuffix@|$(libsuffix)|g' | \
sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@
endif
install-cmake-files: GpgmeppConfig.cmake GpgmeppConfigVersion.cmake
diff --git a/lang/cpp/src/Makefile.in b/lang/cpp/src/Makefile.in
index 45f6219..27bf982 100644
--- a/lang/cpp/src/Makefile.in
+++ b/lang/cpp/src/Makefile.in
@@ -117,8 +117,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
@@ -166,8 +166,8 @@ am__objects_1 = exception.lo context.lo key.lo trustitem.lo data.lo \
encryptionresult.lo engineinfo.lo \
gpgsetexpirytimeeditinteractor.lo \
gpgsetownertrusteditinteractor.lo gpgsignkeyeditinteractor.lo \
- gpgadduserideditinteractor.lo defaultassuantransaction.lo \
- scdgetinfoassuantransaction.lo \
+ gpgadduserideditinteractor.lo gpggencardkeyinteractor.lo \
+ defaultassuantransaction.lo scdgetinfoassuantransaction.lo \
gpgagentgetinfoassuantransaction.lo vfsmountresult.lo \
configuration.lo tofuinfo.lo swdbresult.lo
am__objects_2 =
@@ -470,7 +470,8 @@ main_sources = \
signingresult.cpp encryptionresult.cpp \
engineinfo.cpp gpgsetexpirytimeeditinteractor.cpp \
gpgsetownertrusteditinteractor.cpp gpgsignkeyeditinteractor.cpp \
- gpgadduserideditinteractor.cpp defaultassuantransaction.cpp \
+ gpgadduserideditinteractor.cpp gpggencardkeyinteractor.cpp \
+ defaultassuantransaction.cpp \
scdgetinfoassuantransaction.cpp gpgagentgetinfoassuantransaction.cpp \
vfsmountresult.cpp configuration.cpp tofuinfo.cpp swdbresult.cpp
@@ -481,6 +482,7 @@ gpgmepp_headers = \
gpgadduserideditinteractor.h gpgagentgetinfoassuantransaction.h \
gpgmefw.h gpgsetexpirytimeeditinteractor.h \
gpgsetownertrusteditinteractor.h gpgsignkeyeditinteractor.h \
+ gpggencardkeyinteractor.h \
importresult.h keygenerationresult.h key.h keylistresult.h \
notation.h result.h scdgetinfoassuantransaction.h signingresult.h \
trustitem.h verificationresult.h vfsmountresult.h gpgmepp_export.h \
@@ -507,6 +509,8 @@ libgpgmepp_la_LIBADD = ../../../src/libgpgme.la @LIBASSUAN_LIBS@
libgpgmepp_la_LDFLAGS = -no-undefined -version-info \
@LIBGPGMEPP_LT_CURRENT@:@LIBGPGMEPP_LT_REVISION@:@LIBGPGMEPP_LT_AGE@
+@HAVE_MACOS_SYSTEM_FALSE@libsuffix = .so
+@HAVE_MACOS_SYSTEM_TRUE@libsuffix = .dylib
CLEANFILES = GpgmeppConfig.cmake GpgmeppConfigVersion.cmake \
gpgmepp_version.h GpgmeppConfig.cmake.in
@@ -611,6 +615,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exception.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgadduserideditinteractor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgagentgetinfoassuantransaction.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpggencardkeyinteractor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgsetexpirytimeeditinteractor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgsetownertrusteditinteractor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpgsignkeyeditinteractor.Plo@am__quote@
@@ -943,6 +948,7 @@ uninstall-am: uninstall-gpgmeppincludeHEADERS uninstall-libLTLIBRARIES \
@HAVE_W32_SYSTEM_TRUE@ sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@
@HAVE_W32_SYSTEM_FALSE@GpgmeppConfig.cmake: GpgmeppConfig.cmake.in
@HAVE_W32_SYSTEM_FALSE@ sed -e 's|[@]resolved_libdir@|$(libdir)|g' < "$<" | \
+@HAVE_W32_SYSTEM_FALSE@ sed -e 's|[@]libsuffix@|$(libsuffix)|g' | \
@HAVE_W32_SYSTEM_FALSE@ sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@
install-cmake-files: GpgmeppConfig.cmake GpgmeppConfigVersion.cmake
-$(INSTALL) -d $(DESTDIR)$(libdir)/cmake/Gpgmepp
diff --git a/lang/cpp/src/context.cpp b/lang/cpp/src/context.cpp
index ada7bea..77962d8 100644
--- a/lang/cpp/src/context.cpp
+++ b/lang/cpp/src/context.cpp
@@ -280,6 +280,11 @@ std::unique_ptr<Context> Context::createForEngine(Engine eng, Error *error)
return std::unique_ptr<Context>(new Context(ctx));
}
+void Context::setDecryptionFlags(DecryptionFlags flags)
+{
+ d->decryptFlags = flags;
+}
+
//
//
// Context::Private
@@ -294,7 +299,8 @@ Context::Private::Private(gpgme_ctx_t c)
lastAssuanInquireData(Data::null),
lastAssuanTransaction(),
lastEditInteractor(),
- lastCardEditInteractor()
+ lastCardEditInteractor(),
+ decryptFlags(DecryptNone)
{
}
@@ -904,21 +910,32 @@ std::unique_ptr<AssuanTransaction> Context::takeLastAssuanTransaction()
return std::move(d->lastAssuanTransaction);
}
-DecryptionResult Context::decrypt(const Data &cipherText, Data &plainText)
+DecryptionResult Context::decrypt(const Data &cipherText, Data &plainText, const DecryptionFlags flags)
{
d->lastop = Private::Decrypt;
const Data::Private *const cdp = cipherText.impl();
Data::Private *const pdp = plainText.impl();
- d->lasterr = gpgme_op_decrypt(d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0);
+ d->lasterr = gpgme_op_decrypt_ext(d->ctx, static_cast<gpgme_decrypt_flags_t> (d->decryptFlags | flags), cdp ? cdp->data : 0, pdp ? pdp->data : 0);
return DecryptionResult(d->ctx, Error(d->lasterr));
}
-Error Context::startDecryption(const Data &cipherText, Data &plainText)
+DecryptionResult Context::decrypt(const Data &cipherText, Data &plainText)
+{
+ return decrypt(cipherText, plainText, DecryptNone);
+}
+
+Error Context::startDecryption(const Data &cipherText, Data &plainText, const DecryptionFlags flags)
{
d->lastop = Private::Decrypt;
const Data::Private *const cdp = cipherText.impl();
Data::Private *const pdp = plainText.impl();
- return Error(d->lasterr = gpgme_op_decrypt_start(d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0));
+ return Error(d->lasterr = gpgme_op_decrypt_ext_start(d->ctx, static_cast<gpgme_decrypt_flags_t> (d->decryptFlags | flags),
+ cdp ? cdp->data : 0, pdp ? pdp->data : 0));
+}
+
+Error Context::startDecryption(const Data &cipherText, Data &plainText)
+{
+ return startDecryption(cipherText, plainText, DecryptNone);
}
DecryptionResult Context::decryptionResult() const
@@ -973,22 +990,33 @@ VerificationResult Context::verificationResult() const
}
}
-std::pair<DecryptionResult, VerificationResult> Context::decryptAndVerify(const Data &cipherText, Data &plainText)
+std::pair<DecryptionResult, VerificationResult> Context::decryptAndVerify(const Data &cipherText, Data &plainText, DecryptionFlags flags)
{
d->lastop = Private::DecryptAndVerify;
const Data::Private *const cdp = cipherText.impl();
Data::Private *const pdp = plainText.impl();
- d->lasterr = gpgme_op_decrypt_verify(d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0);
+ d->lasterr = gpgme_op_decrypt_ext(d->ctx, static_cast<gpgme_decrypt_flags_t> (d->decryptFlags | flags | DecryptVerify),
+ cdp ? cdp->data : 0, pdp ? pdp->data : 0);
return std::make_pair(DecryptionResult(d->ctx, Error(d->lasterr)),
VerificationResult(d->ctx, Error(d->lasterr)));
}
-Error Context::startCombinedDecryptionAndVerification(const Data &cipherText, Data &plainText)
+std::pair<DecryptionResult, VerificationResult> Context::decryptAndVerify(const Data &cipherText, Data &plainText)
+{
+ return decryptAndVerify(cipherText, plainText, DecryptNone);
+}
+
+Error Context::startCombinedDecryptionAndVerification(const Data &cipherText, Data &plainText, DecryptionFlags flags)
{
d->lastop = Private::DecryptAndVerify;
const Data::Private *const cdp = cipherText.impl();
Data::Private *const pdp = plainText.impl();
- return Error(d->lasterr = gpgme_op_decrypt_verify_start(d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0));
+ return Error(d->lasterr = gpgme_op_decrypt_ext_start(d->ctx, static_cast<gpgme_decrypt_flags_t> (d->decryptFlags | flags | DecryptVerify), cdp ? cdp->data : 0, pdp ? pdp->data : 0));
+}
+
+Error Context::startCombinedDecryptionAndVerification(const Data &cipherText, Data &plainText)
+{
+ return startCombinedDecryptionAndVerification(cipherText, plainText, DecryptNone);
}
unsigned int to_auditlog_flags(unsigned int flags)
@@ -1376,6 +1404,30 @@ Error Context::setTofuPolicyStart(const Key &k, unsigned int policy)
k.impl(), to_tofu_policy_t(policy)));
}
+Error Context::addUid(const Key &k, const char *userid)
+{
+ return Error(d->lasterr = gpgme_op_adduid(d->ctx,
+ k.impl(), userid, 0));
+}
+
+Error Context::startAddUid(const Key &k, const char *userid)
+{
+ return Error(d->lasterr = gpgme_op_adduid_start(d->ctx,
+ k.impl(), userid, 0));
+}
+
+Error Context::revUid(const Key &k, const char *userid)
+{
+ return Error(d->lasterr = gpgme_op_revuid(d->ctx,
+ k.impl(), userid, 0));
+}
+
+Error Context::startRevUid(const Key &k, const char *userid)
+{
+ return Error(d->lasterr = gpgme_op_revuid_start(d->ctx,
+ k.impl(), userid, 0));
+}
+
// Engine Spawn stuff
Error Context::spawn(const char *file, const char *argv[],
Data &input, Data &output, Data &err,
diff --git a/lang/cpp/src/context.h b/lang/cpp/src/context.h
index 2c205b0..bec4e39 100644
--- a/lang/cpp/src/context.h
+++ b/lang/cpp/src/context.h
@@ -214,6 +214,12 @@ public:
GpgME::Error edit(const Key &key, std::unique_ptr<EditInteractor> function, Data &out);
GpgME::Error startEditing(const Key &key, std::unique_ptr<EditInteractor> function, Data &out);
+ Error addUid(const Key &key, const char *userid);
+ Error startAddUid(const Key &key, const char *userid);
+
+ Error revUid(const Key &key, const char *userid);
+ Error startRevUid(const Key &key, const char *userid);
+
// using TofuInfo::Policy
Error setTofuPolicy(const Key &k, unsigned int policy);
Error setTofuPolicyStart(const Key &k, unsigned int policy);
@@ -255,14 +261,28 @@ public:
//
// Crypto Operations
//
- //
+
+ enum DecryptionFlags {
+ // Keep in line with core's flags
+ DecryptNone = 0,
+ DecryptVerify = 1,
+ DecryptUnwrap = 128,
+ DecryptMaxValue = 0x80000000
+ };
//
// Decryption
//
+ // Alternative way to set decryption flags as they were added only in
+ // 1.9.0 and so other API can still be used but with 1.9.0 additionally
+ // flags can be set.
+ void setDecryptionFlags (const DecryptionFlags flags);
+
DecryptionResult decrypt(const Data &cipherText, Data &plainText);
GpgME::Error startDecryption(const Data &cipherText, Data &plainText);
+ DecryptionResult decrypt(const Data &cipherText, Data &plainText, const DecryptionFlags flags);
+ GpgME::Error startDecryption(const Data &cipherText, Data &plainText, const DecryptionFlags flags);
DecryptionResult decryptionResult() const;
//
@@ -280,7 +300,9 @@ public:
//
std::pair<DecryptionResult, VerificationResult> decryptAndVerify(const Data &cipherText, Data &plainText);
+ std::pair<DecryptionResult, VerificationResult> decryptAndVerify(const Data &cipherText, Data &plainText, const DecryptionFlags flags);
GpgME::Error startCombinedDecryptionAndVerification(const Data &cipherText, Data &plainText);
+ GpgME::Error startCombinedDecryptionAndVerification(const Data &cipherText, Data &plainText, const DecryptionFlags flags);
// use verificationResult() and decryptionResult() to retrieve the result objects...
//
@@ -319,7 +341,9 @@ public:
Prepare = 4,
ExpectSign = 8,
NoCompress = 16,
- Symmetric = 32
+ Symmetric = 32,
+ ThrowKeyIds = 64,
+ EncryptWrap = 128
};
EncryptionResult encrypt(const std::vector<Key> &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags);
GpgME::Error encryptSymmetrically(const Data &plainText, Data &cipherText);
diff --git a/lang/cpp/src/context_p.h b/lang/cpp/src/context_p.h
index be34783..d53da0a 100644
--- a/lang/cpp/src/context_p.h
+++ b/lang/cpp/src/context_p.h
@@ -77,6 +77,7 @@ public:
Data lastAssuanInquireData;
std::unique_ptr<AssuanTransaction> lastAssuanTransaction;
std::unique_ptr<EditInteractor> lastEditInteractor, lastCardEditInteractor;
+ DecryptionFlags decryptFlags;
};
} // namespace GpgME
diff --git a/lang/cpp/src/data.cpp b/lang/cpp/src/data.cpp
index 2cb4fa8..32ca561 100644
--- a/lang/cpp/src/data.cpp
+++ b/lang/cpp/src/data.cpp
@@ -25,6 +25,7 @@
#endif
#include "data_p.h"
+#include "context_p.h"
#include <error.h>
#include <interfaces/dataprovider.h>
@@ -230,3 +231,26 @@ off_t GpgME::Data::seek(off_t offset, int whence)
{
return gpgme_data_seek(d->data, offset, whence);
}
+
+std::vector<GpgME::Key> GpgME::Data::toKeys(Protocol proto) const
+{
+ std::vector<GpgME::Key> ret;
+ if (isNull()) {
+ return ret;
+ }
+ auto ctx = GpgME::Context::createForProtocol(proto);
+ if (!ctx) {
+ return ret;
+ }
+
+ if (gpgme_op_keylist_from_data_start (ctx->impl()->ctx, d->data, 0)) {
+ return ret;
+ }
+
+ gpgme_key_t key;
+ while (!gpgme_op_keylist_next (ctx->impl()->ctx, &key)) {
+ ret.push_back(GpgME::Key(key, false));
+ }
+ delete ctx;
+ return ret;
+}
diff --git a/lang/cpp/src/data.h b/lang/cpp/src/data.h
index 50bdf62..cc7906f 100644
--- a/lang/cpp/src/data.h
+++ b/lang/cpp/src/data.h
@@ -24,6 +24,7 @@
#define __GPGMEPP_DATA_H__
#include "global.h"
+#include "key.h"
#include <sys/types.h> // for size_t, off_t
#include <cstdio> // FILE
@@ -109,6 +110,10 @@ public:
ssize_t write(const void *buffer, size_t length);
off_t seek(off_t offset, int whence);
+ /** Try to parse the data to a key object using the
+ * Protocol proto. Returns an empty list on error.*/
+ std::vector<Key> toKeys(const Protocol proto = Protocol::OpenPGP) const;
+
class Private;
Private *impl()
{
diff --git a/lang/cpp/src/editinteractor.cpp b/lang/cpp/src/editinteractor.cpp
index 31591fa..b652bda 100644
--- a/lang/cpp/src/editinteractor.cpp
+++ b/lang/cpp/src/editinteractor.cpp
@@ -212,6 +212,8 @@ bool EditInteractor::needsNoResponse(unsigned int status) const
case GPGME_STATUS_KEY_CREATED:
case GPGME_STATUS_NEED_PASSPHRASE_SYM:
case GPGME_STATUS_SC_OP_FAILURE:
+ case GPGME_STATUS_CARDCTRL:
+ case GPGME_STATUS_BACKUP_KEY_CREATED:
return false;
default:
return true;
diff --git a/lang/cpp/src/gpggencardkeyinteractor.cpp b/lang/cpp/src/gpggencardkeyinteractor.cpp
new file mode 100644
index 0000000..90329e2
--- /dev/null
+++ b/lang/cpp/src/gpggencardkeyinteractor.cpp
@@ -0,0 +1,332 @@
+/*
+ gpggencardkeyinteractor.cpp - Edit Interactor to generate a key on a card
+ Copyright (C) 2017 Intevation GmbH
+
+ This file is part of GPGME++.
+
+ GPGME++ is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ GPGME++ is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with GPGME++; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "gpggencardkeyinteractor.h"
+
+#include "error.h"
+
+#include <gpgme.h>
+
+using namespace GpgME;
+
+class GpgGenCardKeyInteractor::Private
+{
+public:
+ Private() : keysize(2048), backup(false)
+ {
+
+ }
+ std::string name, email, backupFileName, expiry, serial;
+ int keysize;
+ bool backup;
+};
+
+GpgGenCardKeyInteractor::~GpgGenCardKeyInteractor() {}
+
+GpgGenCardKeyInteractor::GpgGenCardKeyInteractor(const std::string &serial):
+ d(new Private)
+{
+ d->serial = serial;
+}
+
+void GpgGenCardKeyInteractor::setNameUtf8(const std::string &name)
+{
+ d->name = name;
+}
+
+void GpgGenCardKeyInteractor::setEmailUtf8(const std::string &email)
+{
+ d->email = email;
+}
+
+void GpgGenCardKeyInteractor::setDoBackup(bool value)
+{
+ d->backup = value;
+}
+
+void GpgGenCardKeyInteractor::setKeySize(int value)
+{
+ d->keysize = value;
+}
+
+void GpgGenCardKeyInteractor::setExpiry(const std::string &timeStr)
+{
+ d->expiry = timeStr;
+}
+
+std::string GpgGenCardKeyInteractor::backupFileName() const
+{
+ return d->backupFileName;
+}
+
+namespace GpgGenCardKeyInteractor_Private
+{
+enum {
+ START = EditInteractor::StartState,
+ DO_ADMIN,
+ EXPIRE,
+
+ GOT_SERIAL,
+ COMMAND,
+ NAME,
+ EMAIL,
+ COMMENT,
+ BACKUP,
+ REPLACE,
+ SIZE,
+ SIZE2,
+ SIZE3,
+ BACKUP_KEY_CREATED,
+ KEY_CREATED,
+ QUIT,
+ SAVE,
+
+ ERROR = EditInteractor::ErrorState
+};
+}
+
+const char *GpgGenCardKeyInteractor::action(Error &err) const
+{
+
+ using namespace GpgGenCardKeyInteractor_Private;
+
+ switch (state()) {
+ case DO_ADMIN:
+ return "admin";
+ case COMMAND:
+ return "generate";
+ case NAME:
+ return d->name.c_str();
+ case EMAIL:
+ return d->email.c_str();
+ case EXPIRE:
+ return d->expiry.c_str();
+ case BACKUP:
+ return d->backup ? "Y" : "N";
+ case REPLACE:
+ return "Y";
+ case SIZE:
+ case SIZE2:
+ case SIZE3:
+ return std::to_string(d->keysize).c_str();
+ case COMMENT:
+ return "";
+ case SAVE:
+ return "Y";
+ case QUIT:
+ return "quit";
+ case KEY_CREATED:
+ case START:
+ case GOT_SERIAL:
+ case BACKUP_KEY_CREATED:
+ case ERROR:
+ return 0;
+ default:
+ err = Error::fromCode(GPG_ERR_GENERAL);
+ return 0;
+ }
+}
+
+unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char *args, Error &err) const
+{
+
+ static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL);
+ static const Error INV_NAME_ERROR = Error::fromCode(GPG_ERR_INV_NAME);
+ static const Error INV_EMAIL_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID);
+ static const Error INV_COMMENT_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID);
+
+ if (needsNoResponse(status)) {
+ return state();
+ }
+
+ using namespace GpgGenCardKeyInteractor_Private;
+
+ switch (state()) {
+ case START:
+ if (status == GPGME_STATUS_CARDCTRL &&
+ !d->serial.empty()) {
+ const std::string sArgs = args;
+ if (sArgs.find(d->serial) == std::string::npos) {
+ // Wrong smartcard
+ err = Error::fromCode(GPG_ERR_WRONG_CARD);
+ return ERROR;
+ } else {
+ printf("EditInteractor: Confirmed S/N: %s %s\n",
+ d->serial.c_str(), sArgs.c_str());
+ }
+ return GOT_SERIAL;
+ } else if (d->serial.empty()) {
+ return GOT_SERIAL;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case GOT_SERIAL:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "cardedit.prompt") == 0) {
+ return DO_ADMIN;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case DO_ADMIN:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "cardedit.prompt") == 0) {
+ return COMMAND;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case COMMAND:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "cardedit.genkeys.backup_enc") == 0) {
+ return BACKUP;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case BACKUP:
+ if (status == GPGME_STATUS_GET_BOOL &&
+ strcmp(args, "cardedit.genkeys.replace_keys") == 0) {
+ return REPLACE;
+ }
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "cardedit.genkeys.size") == 0) {
+ return SIZE;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case REPLACE:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "cardedit.genkeys.size") == 0) {
+ printf("Moving to SIZE\n");
+ return SIZE;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case SIZE:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "cardedit.genkeys.size") == 0) {
+ return SIZE2;
+ }
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keygen.valid") == 0) {
+ return EXPIRE;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case SIZE2:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "cardedit.genkeys.size") == 0) {
+ return SIZE3;
+ }
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keygen.valid") == 0) {
+ return EXPIRE;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case SIZE3:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keygen.valid") == 0) {
+ return EXPIRE;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case EXPIRE:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keygen.name") == 0) {
+ return NAME;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case NAME:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keygen.email") == 0) {
+ return EMAIL;
+ }
+ err = GENERAL_ERROR;
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keygen.name") == 0) {
+ err = INV_NAME_ERROR;
+ }
+ return ERROR;
+ case EMAIL:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keygen.comment") == 0) {
+ return COMMENT;
+ }
+ err = GENERAL_ERROR;
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keygen.email") == 0) {
+ err = INV_EMAIL_ERROR;
+ }
+ return ERROR;
+ case COMMENT:
+ if (status == GPGME_STATUS_BACKUP_KEY_CREATED) {
+ std::string sArgs = args;
+ const auto pos = sArgs.rfind(" ");
+ if (pos != std::string::npos) {
+ d->backupFileName = sArgs.substr(pos + 1);
+ return BACKUP_KEY_CREATED;
+ }
+ }
+ if (status == GPGME_STATUS_KEY_CREATED) {
+ return KEY_CREATED;
+ }
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keyedit.prompt") == 0) {
+ return QUIT;
+ }
+ err = GENERAL_ERROR;
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keygen.comment") == 0) {
+ err = INV_COMMENT_ERROR;
+ }
+ return ERROR;
+ case BACKUP_KEY_CREATED:
+ if (status == GPGME_STATUS_KEY_CREATED) {
+ return KEY_CREATED;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case KEY_CREATED:
+ return QUIT;
+ case QUIT:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "cardedit.prompt") == 0) {
+ return QUIT;
+ }
+ err = GENERAL_ERROR;
+ return ERROR;
+ case ERROR:
+ if (status == GPGME_STATUS_GET_LINE &&
+ strcmp(args, "keyedit.prompt") == 0) {
+ return QUIT;
+ }
+ err = lastError();
+ return ERROR;
+ default:
+ err = GENERAL_ERROR;
+ return ERROR;
+ }
+}
diff --git a/lang/cpp/src/gpggencardkeyinteractor.h b/lang/cpp/src/gpggencardkeyinteractor.h
new file mode 100644
index 0000000..c6b17d1
--- /dev/null
+++ b/lang/cpp/src/gpggencardkeyinteractor.h
@@ -0,0 +1,71 @@
+/*
+ gpggencardkeyinteractor.h - Edit Interactor to generate a key on a card
+ Copyright (C) 2017 Intevation GmbH
+
+ This file is part of GPGME++.
+
+ GPGME++ is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ GPGME++ is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with GPGME++; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef __GPGMEPP_GPGGENCARDKEYEDITINTERACTOR_H__
+#define __GPGMEPP_GPGGENCARDKEYEDITINTERACTOR_H__
+
+#include <editinteractor.h>
+
+#include <string>
+#include <memory>
+
+namespace GpgME
+{
+
+class GPGMEPP_EXPORT GpgGenCardKeyInteractor: public EditInteractor
+{
+public:
+ /** Edit interactor to generate a key on a smartcard.
+ *
+ * The \a serialnumber argument is intended to safeguard
+ * against accidentally working on the wrong smartcard.
+ *
+ * The edit interactor will fail if the card did not match.
+ *
+ * @param serialnumber: Serialnumber of the intended card.
+ **/
+ explicit GpgGenCardKeyInteractor(const std::string &serialnumber);
+ ~GpgGenCardKeyInteractor();
+
+ /** Set the key sizes for the subkeys (default 2048) */
+ void setKeySize(int size);
+
+ void setNameUtf8(const std::string &name);
+ void setEmailUtf8(const std::string &email);
+
+ void setDoBackup(bool value);
+ void setExpiry(const std::string &timeString);
+
+ std::string backupFileName() const;
+
+private:
+ /* reimp */ const char *action(Error &err) const;
+ /* reimp */ unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const;
+
+private:
+ class Private;
+ std::shared_ptr<Private> d;
+};
+
+} // namespace GpgME
+
+#endif // __GPGMEPP_GPGGENCARDKEYEDITINTERACTOR_H__
diff --git a/lang/cpp/src/key.cpp b/lang/cpp/src/key.cpp
index 235a3c8..31e59e1 100644
--- a/lang/cpp/src/key.cpp
+++ b/lang/cpp/src/key.cpp
@@ -234,6 +234,11 @@ bool Key::isQualified() const
return key && key->is_qualified;
}
+bool Key::isDeVs() const
+{
+ return key && key->subkeys && key->subkeys->is_de_vs;
+}
+
const char *Key::issuerSerial() const
{
return key ? key->issuer_serial : 0 ;
@@ -341,7 +346,12 @@ void Key::update()
KeyListMode::Validate |
KeyListMode::WithTofu);
Error err;
- auto newKey = ctx->key(primaryFingerprint(), err, hasSecret());
+ auto newKey = ctx->key(primaryFingerprint(), err, true);
+ // Not secret so we get the information from the pubring.
+ if (newKey.isNull())
+ {
+ newKey = ctx->key(primaryFingerprint(), err, false);
+ }
delete ctx;
if (err) {
return;
@@ -464,6 +474,11 @@ bool Subkey::isQualified() const
return subkey && subkey->is_qualified;
}
+bool Subkey::isDeVs() const
+{
+ return subkey && subkey->is_de_vs;
+}
+
bool Subkey::isCardKey() const
{
return subkey && subkey->is_cardkey;
@@ -471,7 +486,12 @@ bool Subkey::isCardKey() const
const char *Subkey::cardSerialNumber() const
{
- return subkey ? subkey->card_number : 0 ;
+ return subkey ? subkey->card_number : nullptr;
+}
+
+const char *Subkey::keyGrip() const
+{
+ return subkey ? subkey->keygrip : nullptr;
}
bool Subkey::isSecret() const
@@ -894,7 +914,39 @@ std::string UserID::addrSpecFromString(const char *userid)
std::string UserID::addrSpec() const
{
- return addrSpecFromString(email());
+ if (!uid || !uid->address) {
+ return std::string();
+ }
+
+ return uid->address;
+}
+
+Error UserID::revoke()
+{
+ if (isNull()) {
+ return Error::fromCode(GPG_ERR_GENERAL);
+ }
+ auto ctx = Context::createForProtocol(parent().protocol());
+ if (!ctx) {
+ return Error::fromCode(GPG_ERR_INV_ENGINE);
+ }
+ Error ret = ctx->revUid(key, id());
+ delete ctx;
+ return ret;
+}
+
+Error Key::addUid(const char *uid)
+{
+ if (isNull()) {
+ return Error::fromCode(GPG_ERR_GENERAL);
+ }
+ auto ctx = Context::createForProtocol(protocol());
+ if (!ctx) {
+ return Error::fromCode(GPG_ERR_INV_ENGINE);
+ }
+ Error ret = ctx->addUid(key, uid);
+ delete ctx;
+ return ret;
}
std::ostream &operator<<(std::ostream &os, const UserID &uid)
@@ -903,6 +955,7 @@ std::ostream &operator<<(std::ostream &os, const UserID &uid)
if (!uid.isNull()) {
os << "\n name: " << protect(uid.name())
<< "\n email: " << protect(uid.email())
+ << "\n mbox: " << uid.addrSpec()
<< "\n comment: " << protect(uid.comment())
<< "\n validity: " << uid.validityAsString()
<< "\n revoked: " << uid.isRevoked()
diff --git a/lang/cpp/src/key.h b/lang/cpp/src/key.h
index 3f596a8..829bd26 100644
--- a/lang/cpp/src/key.h
+++ b/lang/cpp/src/key.h
@@ -112,6 +112,7 @@ public:
bool canCertify() const;
bool canAuthenticate() const;
bool isQualified() const;
+ bool isDeVs() const;
bool hasSecret() const;
GPGMEPP_DEPRECATED bool isSecret() const
@@ -152,6 +153,17 @@ public:
* how long the keylisting takes.*/
void update();
+ /**
+ * @brief Add a user id to this key.
+ *
+ * Needs gnupg 2.1.13 and the key needs to be updated
+ * afterwards to see the new uid.
+ *
+ * @param uid should be fully formated and UTF-8 encoded.
+ *
+ * @returns a possible error.
+ **/
+ Error addUid(const char *uid);
private:
gpgme_key_t impl() const
{
@@ -208,6 +220,7 @@ public:
bool canCertify() const;
bool canAuthenticate() const;
bool isQualified() const;
+ bool isDeVs() const;
bool isCardKey() const;
bool isSecret() const;
@@ -259,6 +272,8 @@ public:
const char *cardSerialNumber() const;
+ const char *keyGrip() const;
+
private:
shared_gpgme_key_t key;
gpgme_sub_key_t subkey;
@@ -335,6 +350,13 @@ public:
* @returns a normalized mail address for this userid
* or an empty string. */
std::string addrSpec() const;
+
+ /*! Revoke the user id.
+ *
+ * Key needs update afterwards.
+ *
+ * @returns an error on error.*/
+ Error revoke();
private:
shared_gpgme_key_t key;
gpgme_user_id_t uid;
diff --git a/lang/cpp/src/verificationresult.cpp b/lang/cpp/src/verificationresult.cpp
index 23c458e..42e483c 100644
--- a/lang/cpp/src/verificationresult.cpp
+++ b/lang/cpp/src/verificationresult.cpp
@@ -413,7 +413,8 @@ GpgME::Key GpgME::Signature::key(bool search, bool update) const
}
}
if (update) {
- ret.update();
+ d->keys[idx].update();
+ ret = d->keys[idx];
}
return ret;
}
diff --git a/lang/python/Makefile.am b/lang/python/Makefile.am
index e32fd12..d91ead9 100644
--- a/lang/python/Makefile.am
+++ b/lang/python/Makefile.am
@@ -46,42 +46,47 @@ COPY_FILES_GPG = \
# For VPATH builds we need to copy some files because Python's
# distutils are not VPATH-aware.
-copystamp: $(COPY_FILES) $(COPY_FILES_GPG) data.h config.h
- if test "$(srcdir)" != "$(builddir)" ; then \
- cp -R $(COPY_FILES) . ; \
- cp -R $(COPY_FILES_GPG) gpg ; \
- fi
+copystamp: $(COPY_FILES) $(COPY_FILES_GPG)
+ set -e ; for VERSION in $(PYTHON_VERSIONS); do \
+ $(MKDIR_P) python$${VERSION}-gpg/gpg ; \
+ cp -R $(COPY_FILES) python$${VERSION}-gpg ; \
+ cp setup.py python$${VERSION}-gpg ; \
+ cp gpg/version.py python$${VERSION}-gpg/gpg ; \
+ ln -sf "$(abs_top_srcdir)/src/data.h" python$${VERSION}-gpg ; \
+ ln -sf "$(abs_top_builddir)/config.h" python$${VERSION}-gpg ; \
+ cp -R $(COPY_FILES_GPG) python$${VERSION}-gpg/gpg ; \
+ done
touch $@
-data.h:
- ln -s "$(top_srcdir)/src/data.h" .
-
-config.h:
- ln -s "$(top_builddir)/config.h" .
-
all-local: copystamp
- for PYTHON in $(PYTHONS); do \
+ set -e ; set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \
+ PYTHON="$$1" ; shift ; \
+ cd python$${VERSION}-gpg && \
CFLAGS="$(CFLAGS)" \
$$PYTHON setup.py build --verbose ; \
+ cd .. ; \
done
-dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc: copystamp
+python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz \
+python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc: copystamp
+ cd python$(PYTHON_VERSION)-gpg && \
CFLAGS="$(CFLAGS)" \
$(PYTHON) setup.py sdist --verbose
- gpg2 --detach-sign --armor dist/gpg-$(VERSION).tar.gz
+ gpg2 --detach-sign --armor python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz
.PHONY: prepare
prepare: copystamp
.PHONY: sdist
-sdist: dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc
+sdist: python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz \
+ python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc
.PHONY: upload
-upload: dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc
+upload: python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz \
+ python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc
twine upload $^
-CLEANFILES = gpgme.h errors.i gpgme_wrap.c gpg/gpgme.py \
- data.h config.h copystamp
+CLEANFILES = copystamp
# Remove the rest.
#
@@ -89,23 +94,23 @@ CLEANFILES = gpgme.h errors.i gpgme_wrap.c gpg/gpgme.py \
# permissions.
clean-local:
rm -rf -- build
- if test "$(srcdir)" != "$(builddir)" ; then \
- find . -type d ! -perm -200 -exec chmod u+w {} ';' ; \
- for F in $(COPY_FILES); do rm -rf -- `basename $$F` ; done ; \
- for F in $(COPY_FILES_GPG); do \
- rm -rf -- gpg/`basename $$F` ; \
- done ; \
- fi
+ for VERSION in $(PYTHON_VERSIONS); do \
+ find python$${VERSION}-gpg -type d ! -perm -200 -exec chmod u+w {} ';' ; \
+ rm -rf -- python$${VERSION}-gpg ; \
+ done
install-exec-local:
rm -f install_files.txt
- for PYTHON in $(PYTHONS); do \
+ set -e ; set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \
+ PYTHON="$$1" ; shift ; \
+ cd python$${VERSION}-gpg ; \
$$PYTHON setup.py install \
--prefix $(DESTDIR)$(prefix) \
--record files.txt \
--verbose ; \
- cat files.txt >> install_files.txt ; \
+ cat files.txt >> ../install_files.txt ; \
rm files.txt ; \
+ cd .. ; \
done
$(MKDIR_P) $(DESTDIR)$(pythondir)/gpg
mv install_files.txt $(DESTDIR)$(pythondir)/gpg
diff --git a/lang/python/Makefile.in b/lang/python/Makefile.in
index 4168708..6c96f84 100644
--- a/lang/python/Makefile.in
+++ b/lang/python/Makefile.in
@@ -109,8 +109,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
@@ -420,9 +420,7 @@ COPY_FILES_GPG = \
$(srcdir)/gpg/results.py \
$(srcdir)/gpg/util.py
-CLEANFILES = gpgme.h errors.i gpgme_wrap.c gpg/gpgme.py \
- data.h config.h copystamp
-
+CLEANFILES = copystamp
all: all-recursive
.SUFFIXES:
@@ -740,38 +738,44 @@ uninstall-am: uninstall-local
# For VPATH builds we need to copy some files because Python's
# distutils are not VPATH-aware.
-copystamp: $(COPY_FILES) $(COPY_FILES_GPG) data.h config.h
- if test "$(srcdir)" != "$(builddir)" ; then \
- cp -R $(COPY_FILES) . ; \
- cp -R $(COPY_FILES_GPG) gpg ; \
- fi
+copystamp: $(COPY_FILES) $(COPY_FILES_GPG)
+ set -e ; for VERSION in $(PYTHON_VERSIONS); do \
+ $(MKDIR_P) python$${VERSION}-gpg/gpg ; \
+ cp -R $(COPY_FILES) python$${VERSION}-gpg ; \
+ cp setup.py python$${VERSION}-gpg ; \
+ cp gpg/version.py python$${VERSION}-gpg/gpg ; \
+ ln -sf "$(abs_top_srcdir)/src/data.h" python$${VERSION}-gpg ; \
+ ln -sf "$(abs_top_builddir)/config.h" python$${VERSION}-gpg ; \
+ cp -R $(COPY_FILES_GPG) python$${VERSION}-gpg/gpg ; \
+ done
touch $@
-data.h:
- ln -s "$(top_srcdir)/src/data.h" .
-
-config.h:
- ln -s "$(top_builddir)/config.h" .
-
all-local: copystamp
- for PYTHON in $(PYTHONS); do \
+ set -e ; set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \
+ PYTHON="$$1" ; shift ; \
+ cd python$${VERSION}-gpg && \
CFLAGS="$(CFLAGS)" \
$$PYTHON setup.py build --verbose ; \
+ cd .. ; \
done
-dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc: copystamp
+python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz \
+python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc: copystamp
+ cd python$(PYTHON_VERSION)-gpg && \
CFLAGS="$(CFLAGS)" \
$(PYTHON) setup.py sdist --verbose
- gpg2 --detach-sign --armor dist/gpg-$(VERSION).tar.gz
+ gpg2 --detach-sign --armor python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz
.PHONY: prepare
prepare: copystamp
.PHONY: sdist
-sdist: dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc
+sdist: python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz \
+ python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc
.PHONY: upload
-upload: dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc
+upload: python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz \
+ python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc
twine upload $^
# Remove the rest.
@@ -780,23 +784,23 @@ upload: dist/gpg-$(VERSION).tar.gz dist/gpg-$(VERSION).tar.gz.asc
# permissions.
clean-local:
rm -rf -- build
- if test "$(srcdir)" != "$(builddir)" ; then \
- find . -type d ! -perm -200 -exec chmod u+w {} ';' ; \
- for F in $(COPY_FILES); do rm -rf -- `basename $$F` ; done ; \
- for F in $(COPY_FILES_GPG); do \
- rm -rf -- gpg/`basename $$F` ; \
- done ; \
- fi
+ for VERSION in $(PYTHON_VERSIONS); do \
+ find python$${VERSION}-gpg -type d ! -perm -200 -exec chmod u+w {} ';' ; \
+ rm -rf -- python$${VERSION}-gpg ; \
+ done
install-exec-local:
rm -f install_files.txt
- for PYTHON in $(PYTHONS); do \
+ set -e ; set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \
+ PYTHON="$$1" ; shift ; \
+ cd python$${VERSION}-gpg ; \
$$PYTHON setup.py install \
--prefix $(DESTDIR)$(prefix) \
--record files.txt \
--verbose ; \
- cat files.txt >> install_files.txt ; \
+ cat files.txt >> ../install_files.txt ; \
rm files.txt ; \
+ cd .. ; \
done
$(MKDIR_P) $(DESTDIR)$(pythondir)/gpg
mv install_files.txt $(DESTDIR)$(pythondir)/gpg
diff --git a/lang/python/gpg/constants/__init__.py b/lang/python/gpg/constants/__init__.py
index 4fb3d6f..484ffd2 100644
--- a/lang/python/gpg/constants/__init__.py
+++ b/lang/python/gpg/constants/__init__.py
@@ -25,16 +25,16 @@ util.process_constants('GPGME_', globals())
del util
# For convenience, we import the modules here.
-from . import data, event, keylist, md, pk
-from . import protocol, sig, sigsum, status, validity
+from . import data, keylist, sig, tofu # The subdirs.
+from . import create, event, keysign, md, pk, protocol, sigsum, status, validity
# A complication arises because 'import' is a reserved keyword.
# Import it as 'Import' instead.
globals()['Import'] = getattr(__import__('', globals(), locals(),
[str('import')], 1), "import")
-__all__ = ['data', 'event', 'import', 'keylist', 'md', 'pk',
- 'protocol', 'sig', 'sigsum', 'status', 'validity']
+__all__ = ['data', 'event', 'import', 'keysign', 'keylist', 'md', 'pk',
+ 'protocol', 'sig', 'sigsum', 'status', 'tofu', 'validity', 'create']
# GPGME 1.7 replaced gpgme_op_edit with gpgme_op_interact. We
# implement gpg.Context.op_edit using gpgme_op_interact, so the
diff --git a/lang/python/gpg/constants/create.py b/lang/python/gpg/constants/create.py
new file mode 100644
index 0000000..132e96d
--- /dev/null
+++ b/lang/python/gpg/constants/create.py
@@ -0,0 +1,25 @@
+# Flags for key creation
+#
+# Copyright (C) 2017 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import, print_function, unicode_literals
+del absolute_import, print_function, unicode_literals
+
+from gpg import util
+util.process_constants('GPGME_CREATE_', globals())
+del util
diff --git a/lang/python/gpg/constants/keysign.py b/lang/python/gpg/constants/keysign.py
new file mode 100644
index 0000000..fccdbc4
--- /dev/null
+++ b/lang/python/gpg/constants/keysign.py
@@ -0,0 +1,25 @@
+# Flags for key signing
+#
+# Copyright (C) 2017 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import, print_function, unicode_literals
+del absolute_import, print_function, unicode_literals
+
+from gpg import util
+util.process_constants('GPGME_KEYSIGN_', globals())
+del util
diff --git a/lang/python/gpg/constants/tofu/__init__.py b/lang/python/gpg/constants/tofu/__init__.py
new file mode 100644
index 0000000..819a58b
--- /dev/null
+++ b/lang/python/gpg/constants/tofu/__init__.py
@@ -0,0 +1,24 @@
+# TOFU
+#
+# Copyright (C) 2017 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import, print_function, unicode_literals
+del absolute_import, print_function, unicode_literals
+
+from . import policy
+__all__ = ['policy']
diff --git a/lang/python/gpg/constants/tofu/policy.py b/lang/python/gpg/constants/tofu/policy.py
new file mode 100644
index 0000000..5a61f06
--- /dev/null
+++ b/lang/python/gpg/constants/tofu/policy.py
@@ -0,0 +1,25 @@
+# TOFU policies
+#
+# Copyright (C) 2017 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of the
+# License, or (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import, print_function, unicode_literals
+del absolute_import, print_function, unicode_literals
+
+from gpg import util
+util.process_constants('GPGME_TOFU_POLICY_', globals())
+del util
diff --git a/lang/python/gpg/core.py b/lang/python/gpg/core.py
index 748bcbb..632f4ca 100644
--- a/lang/python/gpg/core.py
+++ b/lang/python/gpg/core.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2016 g10 Code GmbH
+# Copyright (C) 2016-2017 g10 Code GmbH
# Copyright (C) 2004,2008 Igor Belyi <belyi@users.sourceforge.net>
# Copyright (C) 2002 John Goerzen <jgoerzen@complete.org>
#
@@ -176,7 +176,7 @@ class Context(GpgmeWrapper):
def __init__(self, armor=False, textmode=False, offline=False,
signers=[], pinentry_mode=constants.PINENTRY_MODE_DEFAULT,
protocol=constants.PROTOCOL_OpenPGP,
- wrapped=None):
+ wrapped=None, home_dir=None):
"""Construct a context object
Keyword arguments:
@@ -186,6 +186,7 @@ class Context(GpgmeWrapper):
signers -- list of keys used for signing (default [])
pinentry_mode -- pinentry mode (default PINENTRY_MODE_DEFAULT)
protocol -- protocol to use (default PROTOCOL_OpenPGP)
+ home_dir -- state directory (default is the engine default)
"""
if wrapped:
@@ -203,6 +204,15 @@ class Context(GpgmeWrapper):
self.signers = signers
self.pinentry_mode = pinentry_mode
self.protocol = protocol
+ self.home_dir = home_dir
+
+ def __repr__(self):
+ return (
+ "Context(armor={0.armor}, "
+ "textmode={0.textmode}, offline={0.offline}, "
+ "signers={0.signers}, pinentry_mode={0.pinentry_mode}, "
+ "protocol={0.protocol}, home_dir={0.home_dir}"
+ ")").format(self)
def encrypt(self, plaintext, recipients=[], sign=True, sink=None,
passphrase=None, always_trust=False, add_encrypt_to=False,
@@ -473,12 +483,17 @@ class Context(GpgmeWrapper):
plainbytes = data.read()
return plainbytes, result
- def keylist(self, pattern=None, secret=False):
+ def keylist(self, pattern=None, secret=False,
+ mode=constants.keylist.mode.LOCAL,
+ source=None):
"""List keys
Keyword arguments:
pattern -- return keys matching pattern (default: all keys)
- secret -- return only secret keys
+ secret -- return only secret keys (default: False)
+ mode -- keylist mode (default: list local keys)
+ source -- read keys from source instead from the keyring
+ (all other options are ignored in this case)
Returns:
-- an iterator returning key objects
@@ -486,7 +501,249 @@ class Context(GpgmeWrapper):
Raises:
GPGMEError -- as signaled by the underlying library
"""
- return self.op_keylist_all(pattern, secret)
+ if not source:
+ self.set_keylist_mode(mode)
+ self.op_keylist_start(pattern, secret)
+ else:
+ # Automatic wrapping of SOURCE is not possible here,
+ # because the object must not be deallocated until the
+ # iteration over the results ends.
+ if not isinstance(source, Data):
+ source = Data(file=source)
+ self.op_keylist_from_data_start(source, 0)
+
+ key = self.op_keylist_next()
+ while key:
+ yield key
+ key = self.op_keylist_next()
+ self.op_keylist_end()
+
+ def create_key(self, userid, algorithm=None, expires_in=0, expires=True,
+ sign=False, encrypt=False, certify=False, authenticate=False,
+ passphrase=None, force=False):
+ """Create a primary key
+
+ Create a primary key for the user id USERID.
+
+ ALGORITHM may be used to specify the public key encryption
+ algorithm for the new key. By default, a reasonable default
+ is chosen. You may use "future-default" to select an
+ algorithm that will be the default in a future implementation
+ of the engine. ALGORITHM may be a string like "rsa", or
+ "rsa2048" to explicitly request an algorithm and a key size.
+
+ EXPIRES_IN specifies the expiration time of the key in number
+ of seconds since the keys creation. By default, a reasonable
+ expiration time is chosen. If you want to create a key that
+ does not expire, use the keyword argument EXPIRES.
+
+ SIGN, ENCRYPT, CERTIFY, and AUTHENTICATE can be used to
+ request the capabilities of the new key. If you don't request
+ any, a reasonable set of capabilities is selected, and in case
+ of OpenPGP, a subkey with a reasonable set of capabilities is
+ created.
+
+ If PASSPHRASE is None (the default), then the key will not be
+ protected with a passphrase. If PASSPHRASE is a string, it
+ will be used to protect the key. If PASSPHRASE is True, the
+ passphrase must be supplied using a passphrase callback or
+ out-of-band with a pinentry.
+
+ Keyword arguments:
+ algorithm -- public key algorithm, see above (default: reasonable)
+ expires_in -- expiration time in seconds (default: reasonable)
+ expires -- whether or not the key should expire (default: True)
+ sign -- request the signing capability (see above)
+ encrypt -- request the encryption capability (see above)
+ certify -- request the certification capability (see above)
+ authenticate -- request the authentication capability (see above)
+ passphrase -- protect the key with a passphrase (default: no passphrase)
+ force -- force key creation even if a key with the same userid exists
+ (default: False)
+
+ Returns:
+ -- an object describing the result of the key creation
+
+ Raises:
+ GPGMEError -- as signaled by the underlying library
+
+ """
+ if util.is_a_string(passphrase):
+ old_pinentry_mode = self.pinentry_mode
+ old_passphrase_cb = getattr(self, '_passphrase_cb', None)
+ self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
+ def passphrase_cb(hint, desc, prev_bad, hook=None):
+ return passphrase
+ self.set_passphrase_cb(passphrase_cb)
+
+ try:
+ self.op_createkey(userid, algorithm,
+ 0, # reserved
+ expires_in,
+ None, # extrakey
+ ((constants.create.SIGN if sign else 0)
+ | (constants.create.ENCR if encrypt else 0)
+ | (constants.create.CERT if certify else 0)
+ | (constants.create.AUTH if authenticate else 0)
+ | (constants.create.NOPASSWD if passphrase == None else 0)
+ | (0 if expires else constants.create.NOEXPIRE)
+ | (constants.create.FORCE if force else 0)))
+ finally:
+ if util.is_a_string(passphrase):
+ self.pinentry_mode = old_pinentry_mode
+ if old_passphrase_cb:
+ self.set_passphrase_cb(*old_passphrase_cb[1:])
+
+ return self.op_genkey_result()
+
+ def create_subkey(self, key, algorithm=None, expires_in=0, expires=True,
+ sign=False, encrypt=False, authenticate=False, passphrase=None):
+ """Create a subkey
+
+ Create a subkey for the given KEY. As subkeys are a concept
+ of OpenPGP, calling this is only valid for the OpenPGP
+ protocol.
+
+ ALGORITHM may be used to specify the public key encryption
+ algorithm for the new subkey. By default, a reasonable
+ default is chosen. You may use "future-default" to select an
+ algorithm that will be the default in a future implementation
+ of the engine. ALGORITHM may be a string like "rsa", or
+ "rsa2048" to explicitly request an algorithm and a key size.
+
+ EXPIRES_IN specifies the expiration time of the subkey in
+ number of seconds since the subkeys creation. By default, a
+ reasonable expiration time is chosen. If you want to create a
+ subkey that does not expire, use the keyword argument EXPIRES.
+
+ SIGN, ENCRYPT, and AUTHENTICATE can be used to request the
+ capabilities of the new subkey. If you don't request any, an
+ encryption subkey is generated.
+
+ If PASSPHRASE is None (the default), then the subkey will not
+ be protected with a passphrase. If PASSPHRASE is a string, it
+ will be used to protect the subkey. If PASSPHRASE is True,
+ the passphrase must be supplied using a passphrase callback or
+ out-of-band with a pinentry.
+
+ Keyword arguments:
+ algorithm -- public key algorithm, see above (default: reasonable)
+ expires_in -- expiration time in seconds (default: reasonable)
+ expires -- whether or not the subkey should expire (default: True)
+ sign -- request the signing capability (see above)
+ encrypt -- request the encryption capability (see above)
+ authenticate -- request the authentication capability (see above)
+ passphrase -- protect the subkey with a passphrase (default: no passphrase)
+
+ Returns:
+ -- an object describing the result of the subkey creation
+
+ Raises:
+ GPGMEError -- as signaled by the underlying library
+
+ """
+ if util.is_a_string(passphrase):
+ old_pinentry_mode = self.pinentry_mode
+ old_passphrase_cb = getattr(self, '_passphrase_cb', None)
+ self.pinentry_mode = constants.PINENTRY_MODE_LOOPBACK
+ def passphrase_cb(hint, desc, prev_bad, hook=None):
+ return passphrase
+ self.set_passphrase_cb(passphrase_cb)
+
+ try:
+ self.op_createsubkey(key, algorithm,
+ 0, # reserved
+ expires_in,
+ ((constants.create.SIGN if sign else 0)
+ | (constants.create.ENCR if encrypt else 0)
+ | (constants.create.AUTH if authenticate else 0)
+ | (constants.create.NOPASSWD
+ if passphrase == None else 0)
+ | (0 if expires else constants.create.NOEXPIRE)))
+ finally:
+ if util.is_a_string(passphrase):
+ self.pinentry_mode = old_pinentry_mode
+ if old_passphrase_cb:
+ self.set_passphrase_cb(*old_passphrase_cb[1:])
+
+ return self.op_genkey_result()
+
+ def key_add_uid(self, key, uid):
+ """Add a UID
+
+ Add the uid UID to the given KEY. Calling this function is
+ only valid for the OpenPGP protocol.
+
+ Raises:
+ GPGMEError -- as signaled by the underlying library
+
+ """
+ self.op_adduid(key, uid, 0)
+
+ def key_revoke_uid(self, key, uid):
+ """Revoke a UID
+
+ Revoke the uid UID from the given KEY. Calling this function
+ is only valid for the OpenPGP protocol.
+
+ Raises:
+ GPGMEError -- as signaled by the underlying library
+
+ """
+ self.op_revuid(key, uid, 0)
+
+ def key_sign(self, key, uids=None, expires_in=False, local=False):
+ """Sign a key
+
+ Sign a key with the current set of signing keys. Calling this
+ function is only valid for the OpenPGP protocol.
+
+ If UIDS is None (the default), then all UIDs are signed. If
+ it is a string, then only the matching UID is signed. If it
+ is a list of strings, then all matching UIDs are signed. Note
+ that a case-sensitive exact string comparison is done.
+
+ EXPIRES_IN specifies the expiration time of the signature in
+ seconds. If EXPIRES_IN is False, the signature does not
+ expire.
+
+ Keyword arguments:
+ uids -- user ids to sign, see above (default: sign all)
+ expires_in -- validity period of the signature in seconds
+ (default: do not expire)
+ local -- create a local, non-exportable signature
+ (default: False)
+
+ Raises:
+ GPGMEError -- as signaled by the underlying library
+
+ """
+ flags = 0
+ if uids == None or util.is_a_string(uids):
+ pass#through unchanged
+ else:
+ flags |= constants.keysign.LFSEP
+ uids = "\n".join(uids)
+
+ if not expires_in:
+ flags |= constants.keysign.NOEXPIRE
+
+ if local:
+ flags |= constants.keysign.LOCAL
+
+ self.op_keysign(key, uids, expires_in, flags)
+
+ def key_tofu_policy(self, key, policy):
+ """Set a keys' TOFU policy
+
+ Set the TOFU policy associated with KEY to POLICY. Calling
+ this function is only valid for the OpenPGP protocol.
+
+ Raises:
+ GPGMEError -- as signaled by the underlying library
+
+ """
+ self.op_tofu_policy(key, policy)
def assuan_transact(self, command,
data_cb=None, inquire_cb=None, status_cb=None):
@@ -512,7 +769,7 @@ class Context(GpgmeWrapper):
"""
- if isinstance(command, (str, bytes)):
+ if util.is_a_string(command) or isinstance(command, bytes):
cmd = command
else:
cmd = " ".join(util.percent_escape(f) for f in command)
@@ -602,27 +859,40 @@ class Context(GpgmeWrapper):
errorcheck(gpgme.gpgme_engine_check_version(value))
self.set_protocol(value)
+ @property
+ def home_dir(self):
+ """Engine's home directory"""
+ return self.engine_info.home_dir
+ @home_dir.setter
+ def home_dir(self, value):
+ self.set_engine_info(self.protocol, home_dir=value)
+
_ctype = 'gpgme_ctx_t'
_cprefix = 'gpgme_'
def _errorcheck(self, name):
"""This function should list all functions returning gpgme_error_t"""
+ # The list of functions is created using:
+ #
+ # $ grep '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \
+ # | grep -v _op_ | awk "/\(gpgme_ctx/ { printf (\"'%s',\\n\", \$2) } "
return ((name.startswith('gpgme_op_')
and not name.endswith('_result'))
or name in {
+ 'gpgme_new',
'gpgme_set_ctx_flag',
'gpgme_set_protocol',
'gpgme_set_sub_protocol',
'gpgme_set_keylist_mode',
'gpgme_set_pinentry_mode',
'gpgme_set_locale',
- 'gpgme_set_engine_info',
+ 'gpgme_ctx_set_engine_info',
'gpgme_signers_add',
- 'gpgme_get_sig_key',
'gpgme_sig_notation_add',
+ 'gpgme_set_sender',
'gpgme_cancel',
'gpgme_cancel_async',
- 'gpgme_cancel_get_key',
+ 'gpgme_get_key',
})
_boolean_properties = {'armor', 'textmode', 'offline'}
@@ -829,8 +1099,7 @@ class Context(GpgmeWrapper):
home_dir -- configuration directory (unchanged if None)
"""
- errorcheck(gpgme.gpgme_ctx_set_engine_info(
- self.wrapped, proto, file_name, home_dir))
+ self.ctx_set_engine_info(proto, file_name, home_dir)
def wait(self, hang):
"""Wait for asynchronous call to finish. Wait forever if hang is True.
@@ -884,11 +1153,19 @@ class Data(GpgmeWrapper):
def _errorcheck(self, name):
"""This function should list all functions returning gpgme_error_t"""
+ # This list is compiled using
+ #
+ # $ grep -v '^gpgme_error_t ' obj/lang/python/python3.5-gpg/gpgme.h \
+ # | awk "/\(gpgme_data_t/ { printf (\"'%s',\\n\", \$2) } " | sed "s/'\\*/'/"
return name not in {
+ 'gpgme_data_read',
+ 'gpgme_data_write',
+ 'gpgme_data_seek',
+ 'gpgme_data_release',
'gpgme_data_release_and_get_mem',
'gpgme_data_get_encoding',
- 'gpgme_data_seek',
'gpgme_data_get_file_name',
+ 'gpgme_data_identify',
}
def __init__(self, string=None, file=None, offset=None,
@@ -1097,15 +1374,64 @@ class Data(GpgmeWrapper):
chunks.append(result)
return b''.join(chunks)
+def pubkey_algo_string(subkey):
+ """Return short algorithm string
+
+ Return a public key algorithm string (e.g. "rsa2048") for a given
+ SUBKEY.
+
+ Returns:
+ algo - a string
+
+ """
+ return gpgme.gpgme_pubkey_algo_string(subkey)
+
def pubkey_algo_name(algo):
+ """Return name of public key algorithm
+
+ Return the name of the public key algorithm for a given numeric
+ algorithm id ALGO (cf. RFC4880).
+
+ Returns:
+ algo - a string
+
+ """
return gpgme.gpgme_pubkey_algo_name(algo)
def hash_algo_name(algo):
+ """Return name of hash algorithm
+
+ Return the name of the hash algorithm for a given numeric
+ algorithm id ALGO (cf. RFC4880).
+
+ Returns:
+ algo - a string
+
+ """
return gpgme.gpgme_hash_algo_name(algo)
def get_protocol_name(proto):
+ """Get protocol description
+
+ Get the string describing protocol PROTO.
+
+ Returns:
+ proto - a string
+
+ """
return gpgme.gpgme_get_protocol_name(proto)
+def addrspec_from_uid(uid):
+ """Return the address spec
+
+ Return the addr-spec (cf. RFC2822 section 4.3) from a user id UID.
+
+ Returns:
+ addr_spec - a string
+
+ """
+ return gpgme.gpgme_addrspec_from_uid(uid)
+
def check_version(version=None):
return gpgme.gpgme_check_version(version)
diff --git a/lang/python/gpg/gpgme.py b/lang/python/gpg/gpgme.py
deleted file mode 100644
index 238359d..0000000
--- a/lang/python/gpg/gpgme.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# This file was automatically generated by SWIG (http://www.swig.org).
-# Version 3.0.7
-#
-# Do not make changes to this file unless you know what you are doing--modify
-# the SWIG interface file instead.
-
-
-
-
-
-from sys import version_info
-if version_info >= (2, 6, 0):
- def swig_import_helper():
- from os.path import dirname
- import imp
- fp = None
- try:
- fp, pathname, description = imp.find_module('_gpgme', [dirname(__file__)])
- except ImportError:
- import _gpgme
- return _gpgme
- if fp is not None:
- try:
- _mod = imp.load_module('_gpgme', fp, pathname, description)
- finally:
- fp.close()
- return _mod
- _gpgme = swig_import_helper()
- del swig_import_helper
-else:
- import _gpgme
-del version_info
-from _gpgme import *
-try:
- _swig_property = property
-except NameError:
- pass # Python < 2.2 doesn't have 'property'.
-
-
-def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
- if (name == "thisown"):
- return self.this.own(value)
- if (name == "this"):
- if type(value).__name__ == 'SwigPyObject':
- self.__dict__[name] = value
- return
- method = class_type.__swig_setmethods__.get(name, None)
- if method:
- return method(self, value)
- if (not static):
- if _newclass:
- object.__setattr__(self, name, value)
- else:
- self.__dict__[name] = value
- else:
- raise AttributeError("You cannot add attributes to %s" % self)
-
-
-def _swig_setattr(self, class_type, name, value):
- return _swig_setattr_nondynamic(self, class_type, name, value, 0)
-
-
-def _swig_getattr_nondynamic(self, class_type, name, static=1):
- if (name == "thisown"):
- return self.this.own()
- method = class_type.__swig_getmethods__.get(name, None)
- if method:
- return method(self)
- if (not static):
- return object.__getattr__(self, name)
- else:
- raise AttributeError(name)
-
-def _swig_getattr(self, class_type, name):
- return _swig_getattr_nondynamic(self, class_type, name, 0)
-
-
-def _swig_repr(self):
- try:
- strthis = "proxy of " + self.this.__repr__()
- except:
- strthis = ""
- return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
-
-try:
- _object = object
- _newclass = 1
-except AttributeError:
- class _object:
- pass
- _newclass = 0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# This file is compatible with both classic and new-style classes.
-
-
diff --git a/lang/python/gpg/results.py b/lang/python/gpg/results.py
index 3383896..46ebeec 100644
--- a/lang/python/gpg/results.py
+++ b/lang/python/gpg/results.py
@@ -64,10 +64,10 @@ class Result(object):
setattr(self, key, getattr(fragile, key))
- def __str__(self):
- return '<{} {}>'.format(
+ def __repr__(self):
+ return '{}({})'.format(
self.__class__.__name__,
- ', '.join('{}: {}'.format(k, getattr(self, k))
+ ', '.join('{}={!r}'.format(k, getattr(self, k))
for k in dir(self) if not k.startswith('_')))
class InvalidKey(Result):
diff --git a/lang/python/gpg/version.py b/lang/python/gpg/version.py
index 9ec657d..ff4cd71 100644
--- a/lang/python/gpg/version.py
+++ b/lang/python/gpg/version.py
@@ -22,7 +22,7 @@ del absolute_import, print_function
from . import gpgme
productname = 'gpg'
-versionstr = "1.8.0"
+versionstr = "1.9.0"
gpgme_versionstr = gpgme.GPGME_VERSION
in_tree_build = bool(gpgme.cvar.gpg_in_tree_build)
diff --git a/lang/python/gpgme.i b/lang/python/gpgme.i
index 783531f..610b3d9 100644
--- a/lang/python/gpgme.i
+++ b/lang/python/gpgme.i
@@ -111,8 +111,10 @@
}
/* Release returned buffers as necessary. */
-%typemap(newfree) char * "free($1);";
+%typemap(newfree) char * "gpgme_free($1);";
%newobject gpgme_data_release_and_get_mem;
+%newobject gpgme_pubkey_algo_string;
+%newobject gpgme_addrspec_from_uid;
%typemap(arginit) gpgme_key_t [] {
$1 = NULL;
@@ -135,7 +137,12 @@
/* Following code is from swig's python.swg. */
if ((SWIG_ConvertPtr(pypointer,(void **) &$1[i], $*1_descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) {
- Py_DECREF(pypointer);
+ Py_DECREF(pypointer);
+ PyErr_Format(PyExc_TypeError,
+ "arg %d: list must contain only gpgme_key_ts, got %s "
+ "at position %d",
+ $argnum, pypointer->ob_type->tp_name, i);
+ free($1);
return NULL;
}
Py_DECREF(pypointer);
@@ -287,7 +294,7 @@
gpgme_data_t sig, gpgme_data_t signed_text,
gpgme_data_t plaintext, gpgme_data_t keydata,
gpgme_data_t pubkey, gpgme_data_t seckey,
- gpgme_data_t out};
+ gpgme_data_t out, gpgme_data_t data};
/* SWIG has problems interpreting ssize_t, off_t or gpgme_error_t in
gpgme.h. */
@@ -424,69 +431,24 @@
/* Wrap the fragile result objects into robust Python ones. */
-%typemap(out) gpgme_encrypt_result_t {
- PyObject *fragile;
- fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
- %newpointer_flags);
- $result = _gpg_wrap_result(fragile, "EncryptResult");
- Py_DECREF(fragile);
-}
-
-%typemap(out) gpgme_decrypt_result_t {
- PyObject *fragile;
- fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
- %newpointer_flags);
- $result = _gpg_wrap_result(fragile, "DecryptResult");
- Py_DECREF(fragile);
-}
-
-%typemap(out) gpgme_sign_result_t {
- PyObject *fragile;
- fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
- %newpointer_flags);
- $result = _gpg_wrap_result(fragile, "SignResult");
- Py_DECREF(fragile);
-}
-
-%typemap(out) gpgme_verify_result_t {
- PyObject *fragile;
- fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
- %newpointer_flags);
- $result = _gpg_wrap_result(fragile, "VerifyResult");
- Py_DECREF(fragile);
-}
-
-%typemap(out) gpgme_import_result_t {
- PyObject *fragile;
- fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
- %newpointer_flags);
- $result = _gpg_wrap_result(fragile, "ImportResult");
- Py_DECREF(fragile);
-}
-
-%typemap(out) gpgme_genkey_result_t {
+%define wrapresult(cls, name)
+%typemap(out) cls {
PyObject *fragile;
fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
%newpointer_flags);
- $result = _gpg_wrap_result(fragile, "GenkeyResult");
+ $result = _gpg_wrap_result(fragile, name);
Py_DECREF(fragile);
}
+%enddef
-%typemap(out) gpgme_keylist_result_t {
- PyObject *fragile;
- fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
- %newpointer_flags);
- $result = _gpg_wrap_result(fragile, "KeylistResult");
- Py_DECREF(fragile);
-}
-
-%typemap(out) gpgme_vfs_mount_result_t {
- PyObject *fragile;
- fragile = SWIG_NewPointerObj(SWIG_as_voidptr($1), $1_descriptor,
- %newpointer_flags);
- $result = _gpg_wrap_result(fragile, "VFSMountResult");
- Py_DECREF(fragile);
-}
+wrapresult(gpgme_encrypt_result_t, "EncryptResult")
+wrapresult(gpgme_decrypt_result_t, "DecryptResult")
+wrapresult(gpgme_sign_result_t, "SignResult")
+wrapresult(gpgme_verify_result_t, "VerifyResult")
+wrapresult(gpgme_import_result_t, "ImportResult")
+wrapresult(gpgme_genkey_result_t, "GenkeyResult")
+wrapresult(gpgme_keylist_result_t, "KeylistResult")
+wrapresult(gpgme_vfs_mount_result_t, "VFSMountResult")
%typemap(out) gpgme_engine_info_t {
int i;
@@ -586,6 +548,15 @@
}
}
+
+/* With SWIG, you can define default arguments for parameters.
+ * While it's legal in C++ it is not in C, so we cannot change the
+ * already existing gpgme.h. We need, however, to declare the function
+ * *before* SWIG loads it from gpgme.h. Hence, we define it here. */
+gpgme_error_t gpgme_op_keylist_start (gpgme_ctx_t ctx,
+ const char *pattern="",
+ int secret_only=0);
+
/* Include the unmodified <gpgme.h> for cc, and the cleaned-up local
version for SWIG. We do, however, want to hide certain fields on
some structs, which we provide prior to including the version for
@@ -656,7 +627,17 @@ FILE *fdopen(int fildes, const char *mode);
PyObject *
_gpg_wrap_gpgme_data_t(gpgme_data_t data)
{
- return SWIG_Python_NewPointerObj(NULL, data, SWIGTYPE_p_gpgme_data, 0);
+ /*
+ * If SWIG is invoked without -builtin, the macro SWIG_NewPointerObj
+ * expects a variable named "self".
+ *
+ * XXX: It is not quite clear why passing NULL as self is okay, but
+ * it works with -builtin, and it seems to work just fine without
+ * it too.
+ */
+ PyObject* self = NULL;
+ (void) self;
+ return SWIG_NewPointerObj(data, SWIGTYPE_p_gpgme_data, 0);
}
gpgme_ctx_t
@@ -675,3 +656,38 @@ _gpg_unwrap_gpgme_ctx_t(PyObject *wrapped)
/* ... but only the public definitions here. They will be exposed to
the Python world, so let's be careful. */
%include "helpers.h"
+
+
+%define genericrepr(cls)
+%pythoncode %{
+ def __repr__(self):
+ names = [name for name in dir(self)
+ if not name.startswith("_") and name != "this"]
+ props = ", ".join(("{}={!r}".format(name, getattr(self, name))
+ for name in names)
+ )
+ return "cls({})".format(props)
+%}
+
+%enddef
+
+%extend _gpgme_key {
+ genericrepr(Key)
+};
+
+
+%extend _gpgme_subkey {
+ genericrepr(SubKey)
+};
+
+%extend _gpgme_key_sig {
+ genericrepr(KeySig)
+};
+
+%extend _gpgme_user_id {
+ genericrepr(UID)
+};
+
+%extend _gpgme_tofu_info {
+ genericrepr(TofuInfo)
+};
diff --git a/lang/python/helpers.c b/lang/python/helpers.c
index 8f71a30..947819d 100644
--- a/lang/python/helpers.c
+++ b/lang/python/helpers.c
@@ -293,8 +293,10 @@ _gpg_obj2gpgme_data_t(PyObject *input, int argnum, gpgme_data_t *wrapper,
return _gpg_obj2gpgme_t(data, "gpgme_data_t", argnum);
return PyErr_Format(PyExc_TypeError,
- "arg %d: expected gpg.Data, file, or an object "
- "implementing the buffer protocol, got %s",
+ "arg %d: expected gpg.Data, file, "
+ "bytes (not string!), or an object "
+ "implementing the buffer protocol. Got: %s. "
+ "If you provided a string, try to encode() it.",
argnum, data->ob_type->tp_name);
}
@@ -375,7 +377,21 @@ static gpgme_error_t pyPassphraseCb(void *hook,
goto leave;
}
- PyTuple_SetItem(args, 1, PyBytes_FromString(passphrase_info));
+ if (passphrase_info == NULL)
+ {
+ Py_INCREF(Py_None);
+ PyTuple_SetItem(args, 1, Py_None);
+ }
+ else
+ PyTuple_SetItem(args, 1, PyUnicode_DecodeUTF8(passphrase_info,
+ strlen (passphrase_info),
+ "strict"));
+ if (PyErr_Occurred()) {
+ Py_DECREF(args);
+ err_status = gpg_error(GPG_ERR_GENERAL);
+ goto leave;
+ }
+
PyTuple_SetItem(args, 2, PyBool_FromLong((long)prev_was_bad));
if (dataarg) {
Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */
diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in
index 9669c28..bf4efa3 100755
--- a/lang/python/setup.py.in
+++ b/lang/python/setup.py.in
@@ -34,12 +34,12 @@ in_tree = False
extra_swig_opts = []
extra_macros = dict()
-if os.path.exists("../../src/gpgme-config"):
+if os.path.exists("../../../src/gpgme-config"):
# In-tree build.
in_tree = True
- gpgme_config = ["../../src/gpgme-config"] + gpgme_config_flags
- gpgme_h = "../../src/gpgme.h"
- library_dirs = ["../../src/.libs"] # XXX uses libtool internals
+ gpgme_config = ["../../../src/gpgme-config"] + gpgme_config_flags
+ gpgme_h = "../../../src/gpgme.h"
+ library_dirs = ["../../../src/.libs"] # XXX uses libtool internals
extra_macros.update(
HAVE_CONFIG_H=1,
HAVE_DATA_H=1,
@@ -152,9 +152,10 @@ class BuildExtFirstHack(build):
self.run_command('build_ext')
build.run(self)
+py3 = [] if sys.version_info.major < 3 else ['-py3']
swige = Extension("gpg._gpgme", ["gpgme.i", "helpers.c"],
- swig_opts = ['-py3', '-builtin', '-threads',
- '-outdir', 'gpg'] + extra_swig_opts,
+ swig_opts = ['-threads',
+ '-outdir', 'gpg'] + py3 + extra_swig_opts,
include_dirs = include_dirs,
define_macros = define_macros,
library_dirs = library_dirs,
@@ -171,7 +172,8 @@ setup(name="gpg",
url='https://www.gnupg.org',
ext_modules=[swige],
packages = ['gpg', 'gpg.constants', 'gpg.constants.data',
- 'gpg.constants.keylist', 'gpg.constants.sig'],
+ 'gpg.constants.keylist', 'gpg.constants.sig',
+ 'gpg.constants.tofu'],
license="LGPL2.1+ (the library), GPL2+ (tests and examples)",
classifiers=[
'Development Status :: 4 - Beta',
diff --git a/lang/python/tests/Makefile.am b/lang/python/tests/Makefile.am
index 39f532c..9c19a13 100644
--- a/lang/python/tests/Makefile.am
+++ b/lang/python/tests/Makefile.am
@@ -46,11 +46,16 @@ py_tests = t-wrapper.py \
t-trustlist.py \
t-edit.py \
t-keylist.py \
+ t-keylist-from-data.py \
t-wait.py \
t-encrypt-large.py \
t-file-name.py \
t-idiomatic.py \
- t-protocol-assuan.py
+ t-protocol-assuan.py \
+ t-quick-key-creation.py \
+ t-quick-subkey-creation.py \
+ t-quick-key-manipulation.py \
+ t-quick-key-signing.py
XTESTS = initial.py $(py_tests) final.py
EXTRA_DIST = support.py $(XTESTS) encrypt-only.asc sign-only.asc \
@@ -73,7 +78,7 @@ xcheck: ./pubring-stamp
CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
gpg-agent.conf pubring.kbx~ gpg.conf pubring.gpg~ \
- random_seed .gpg-v21-migrated \
+ random_seed .gpg-v21-migrated tofu.db \
pubring-stamp private-keys-v1.d/gpg-sample.stamp
private_keys = \
@@ -107,8 +112,9 @@ clean-local:
./gpg.conf:
# This is required for t-sig-notations.
echo no-force-v3-sigs > ./gpg.conf
+ echo ignore-invalid-option agent-program >> ./gpg.conf
+ echo "agent-program `which $(GPG_AGENT)`|--debug-quick-random" >> ./gpg.conf
./gpg-agent.conf:
# This is required for gpg2, which does not support command fd.
echo pinentry-program $(abs_top_srcdir)/tests/gpg/pinentry >$@
- echo allow-loopback-pinentry >>$@
diff --git a/lang/python/tests/Makefile.in b/lang/python/tests/Makefile.in
index ce60cd5..4940a8e 100644
--- a/lang/python/tests/Makefile.in
+++ b/lang/python/tests/Makefile.in
@@ -108,8 +108,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
@@ -358,11 +358,16 @@ py_tests = t-wrapper.py \
t-trustlist.py \
t-edit.py \
t-keylist.py \
+ t-keylist-from-data.py \
t-wait.py \
t-encrypt-large.py \
t-file-name.py \
t-idiomatic.py \
- t-protocol-assuan.py
+ t-protocol-assuan.py \
+ t-quick-key-creation.py \
+ t-quick-subkey-creation.py \
+ t-quick-key-manipulation.py \
+ t-quick-key-signing.py
XTESTS = initial.py $(py_tests) final.py
EXTRA_DIST = support.py $(XTESTS) encrypt-only.asc sign-only.asc \
@@ -370,7 +375,7 @@ EXTRA_DIST = support.py $(XTESTS) encrypt-only.asc sign-only.asc \
CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
gpg-agent.conf pubring.kbx~ gpg.conf pubring.gpg~ \
- random_seed .gpg-v21-migrated \
+ random_seed .gpg-v21-migrated tofu.db \
pubring-stamp private-keys-v1.d/gpg-sample.stamp
private_keys = \
@@ -612,11 +617,12 @@ clean-local:
./gpg.conf:
# This is required for t-sig-notations.
echo no-force-v3-sigs > ./gpg.conf
+ echo ignore-invalid-option agent-program >> ./gpg.conf
+ echo "agent-program `which $(GPG_AGENT)`|--debug-quick-random" >> ./gpg.conf
./gpg-agent.conf:
# This is required for gpg2, which does not support command fd.
echo pinentry-program $(abs_top_srcdir)/tests/gpg/pinentry >$@
- echo allow-loopback-pinentry >>$@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/lang/python/tests/initial.py b/lang/python/tests/initial.py
index ebe7f8a..49e4f82 100755
--- a/lang/python/tests/initial.py
+++ b/lang/python/tests/initial.py
@@ -24,7 +24,8 @@ import os
import subprocess
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
+
+print("Using gpg module from {0!r}.".format(os.path.dirname(gpg.__file__)))
subprocess.check_call([os.path.join(os.getenv('top_srcdir'),
"tests", "start-stop-agent"), "--start"])
diff --git a/lang/python/tests/run-tests.py b/lang/python/tests/run-tests.py
index 55d3f11..c4af526 100644
--- a/lang/python/tests/run-tests.py
+++ b/lang/python/tests/run-tests.py
@@ -39,6 +39,8 @@ parser.add_argument('tests', metavar='TEST', type=str, nargs='+',
help='A test to run')
parser.add_argument('-v', '--verbose', action="store_true", default=False,
help='Be verbose.')
+parser.add_argument('-q', '--quiet', action="store_true", default=False,
+ help='Be quiet.')
parser.add_argument('--interpreters', metavar='PYTHON', type=str,
default=[], action=SplitAndAccumulate,
help='Use these interpreters to run the tests, ' +
@@ -49,6 +51,8 @@ parser.add_argument('--srcdir', type=str,
parser.add_argument('--builddir', type=str,
default=os.environ.get("abs_builddir", ""),
help='Location of the tests.')
+parser.add_argument('--parallel', action="store_true", default=False,
+ help='Ignored. For compatibility with run-tests.scm.')
args = parser.parse_args()
if not args.interpreters:
@@ -65,19 +69,29 @@ for interpreter in args.interpreters:
version = subprocess.check_output(
[interpreter, "-c", "import sys; print('{0}.{1}'.format(sys.version_info[0], sys.version_info[1]))"]).strip().decode()
- builddirs = glob.glob(os.path.join(args.builddir, "..", "build",
- "lib*"+version))
- assert len(builddirs) == 1, \
- "Expected one build directory, got {0}".format(builddirs)
+ pattern = os.path.join(args.builddir, "..",
+ "python{0}-gpg".format(version),
+ "build",
+ "lib*"+version)
+ builddirs = glob.glob(pattern)
+ if len(builddirs) == 0:
+ sys.exit("Build directory matching {0!r} not found.".format(pattern))
+ elif len(builddirs) > 1:
+ sys.exit("Multiple build directories matching {0!r} found: {1}".format(
+ pattern, builddirs))
+
env = dict(os.environ)
env["PYTHONPATH"] = builddirs[0]
- print("Running tests using {0} ({1})...".format(interpreter, version))
+ if not args.quiet:
+ print("Running tests using {0} ({1})...".format(interpreter, version))
+
for test in args.tests:
status = subprocess.call(
[interpreter, os.path.join(args.srcdir, test)],
env=env, stdout=out, stderr=err)
- print("{0}: {1}".format(status_to_str(status), test))
+ if not args.quiet:
+ print("{0}: {1}".format(status_to_str(status), test))
results.append(status)
def count(status):
@@ -85,6 +99,8 @@ def count(status):
def failed():
return len(list(filter(lambda x: x not in (0, 77, 99), results)))
-print("{0} tests run, {1} succeeded, {2} failed, {3} skipped.".format(
- len(results), count(0), failed(), count(77)))
-sys.exit(len(results) - count(0))
+if not args.quiet:
+ print("{0} tests run, {1} succeeded, {2} failed, {3} skipped.".format(
+ len(results), count(0), failed(), count(77)))
+ sys.exit(len(results) - count(0))
+sys.exit(results[0])
diff --git a/lang/python/tests/support.py b/lang/python/tests/support.py
index f991c6d..fabd818 100644
--- a/lang/python/tests/support.py
+++ b/lang/python/tests/support.py
@@ -18,10 +18,28 @@
from __future__ import absolute_import, print_function, unicode_literals
del absolute_import, print_function, unicode_literals
+import contextlib
+import shutil
import sys
import os
+import re
+import tempfile
+import time
import gpg
+def assert_gpg_version(version=(2, 1, 0)):
+ with gpg.Context() as c:
+ clean_version = re.match(r'\d+\.\d+\.\d+', c.engine_info.version).group(0)
+ if tuple(map(int, clean_version.split('.'))) < version:
+ print("GnuPG too old: have {0}, need {1}.".format(
+ c.engine_info.version, '.'.join(map(str, version))))
+ sys.exit(77)
+
+# Skip the Python tests for GnuPG < 2.1.12. Prior versions do not
+# understand the command line flags that we assume exist. C.f. issue
+# 3008.
+assert_gpg_version((2, 1, 12))
+
# known keys
alpha = "A0FF4590BB6122EDEF6E3C542D727CC768697734"
bob = "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2"
@@ -35,9 +53,6 @@ def make_filename(name):
def in_srcdir(name):
return os.path.join(os.environ['srcdir'], name)
-def init_gpgme(proto):
- gpg.core.engine_check_version(proto)
-
verbose = int(os.environ.get('verbose', 0)) > 1
def print_data(data):
if verbose:
@@ -48,7 +63,11 @@ def print_data(data):
except:
# Hope for the best.
pass
- sys.stdout.buffer.write(data)
+
+ if hasattr(sys.stdout, "buffer"):
+ sys.stdout.buffer.write(data)
+ else:
+ sys.stdout.write(data)
def mark_key_trusted(ctx, key):
class Editor(object):
@@ -68,3 +87,41 @@ def mark_key_trusted(ctx, key):
return result
with gpg.Data() as sink:
ctx.op_edit(key, Editor().edit, sink, sink)
+
+
+# Python3.2 and up has tempfile.TemporaryDirectory, but we cannot use
+# that, because there shutil.rmtree is used without
+# ignore_errors=True, and that races against gpg-agent deleting its
+# sockets.
+class TemporaryDirectory(object):
+ def __enter__(self):
+ self.path = tempfile.mkdtemp()
+ return self.path
+ def __exit__(self, *args):
+ shutil.rmtree(self.path, ignore_errors=True)
+
+@contextlib.contextmanager
+def EphemeralContext():
+ with TemporaryDirectory() as tmp:
+ home = os.environ['GNUPGHOME']
+ shutil.copy(os.path.join(home, "gpg.conf"), tmp)
+ shutil.copy(os.path.join(home, "gpg-agent.conf"), tmp)
+
+ with gpg.Context(home_dir=tmp) as ctx:
+ yield ctx
+
+ # Ask the agent to quit.
+ agent_socket = os.path.join(tmp, "S.gpg-agent")
+ ctx.protocol = gpg.constants.protocol.ASSUAN
+ ctx.set_engine_info(ctx.protocol, file_name=agent_socket)
+ try:
+ ctx.assuan_transact(["KILLAGENT"])
+ except gpg.errors.GPGMEError as e:
+ if e.getcode() == gpg.errors.ASS_CONNECT_FAILED:
+ pass # the agent was not running
+ else:
+ raise
+
+ # Block until it is really gone.
+ while os.path.exists(agent_socket):
+ time.sleep(.01)
diff --git a/lang/python/tests/t-callbacks.py b/lang/python/tests/t-callbacks.py
index eed50bc..94cf11e 100755
--- a/lang/python/tests/t-callbacks.py
+++ b/lang/python/tests/t-callbacks.py
@@ -24,7 +24,7 @@ import os
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
+support.assert_gpg_version()
c = gpg.Context()
c.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK)
diff --git a/lang/python/tests/t-decrypt-verify.py b/lang/python/tests/t-decrypt-verify.py
index 6243167..03bbc4b 100755
--- a/lang/python/tests/t-decrypt-verify.py
+++ b/lang/python/tests/t-decrypt-verify.py
@@ -34,7 +34,6 @@ def check_verify_result(result, summary, fpr, status):
assert sig.validity == gpg.constants.validity.FULL
assert gpg.errors.GPGMEError(sig.validity_reason).getcode() == gpg.errors.NO_ERROR
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
source = gpg.Data(file=support.make_filename("cipher-2.asc"))
diff --git a/lang/python/tests/t-decrypt.py b/lang/python/tests/t-decrypt.py
index 1af0562..05b6d8b 100755
--- a/lang/python/tests/t-decrypt.py
+++ b/lang/python/tests/t-decrypt.py
@@ -23,7 +23,6 @@ del absolute_import, print_function, unicode_literals
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
source = gpg.Data(file=support.make_filename("cipher-1.asc"))
diff --git a/lang/python/tests/t-edit.py b/lang/python/tests/t-edit.py
index bd70e7e..ffc3296 100755
--- a/lang/python/tests/t-edit.py
+++ b/lang/python/tests/t-edit.py
@@ -26,6 +26,8 @@ import os
import gpg
import support
+support.assert_gpg_version()
+
class KeyEditor(object):
def __init__(self):
self.steps = ["fpr", "expire", "1", "primary", "quit"]
@@ -51,8 +53,6 @@ class KeyEditor(object):
return result
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
-
c = gpg.Context()
c.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK)
c.set_passphrase_cb(lambda *args: "abc")
diff --git a/lang/python/tests/t-encrypt-large.py b/lang/python/tests/t-encrypt-large.py
index cdb4a32..5646085 100755
--- a/lang/python/tests/t-encrypt-large.py
+++ b/lang/python/tests/t-encrypt-large.py
@@ -30,7 +30,6 @@ if len(sys.argv) == 2:
else:
nbytes = 100000
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
ntoread = nbytes
diff --git a/lang/python/tests/t-encrypt-sign.py b/lang/python/tests/t-encrypt-sign.py
index 094a2b0..f04783f 100755
--- a/lang/python/tests/t-encrypt-sign.py
+++ b/lang/python/tests/t-encrypt-sign.py
@@ -24,7 +24,6 @@ import sys
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
c.set_armor(True)
diff --git a/lang/python/tests/t-encrypt-sym.py b/lang/python/tests/t-encrypt-sym.py
index 07e6b62..8ee9cd6 100755
--- a/lang/python/tests/t-encrypt-sym.py
+++ b/lang/python/tests/t-encrypt-sym.py
@@ -24,7 +24,7 @@ import os
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
+support.assert_gpg_version()
for passphrase in ("abc", b"abc"):
c = gpg.Context()
diff --git a/lang/python/tests/t-encrypt.py b/lang/python/tests/t-encrypt.py
index 0c0ca35..921502a 100755
--- a/lang/python/tests/t-encrypt.py
+++ b/lang/python/tests/t-encrypt.py
@@ -23,7 +23,6 @@ del absolute_import, print_function, unicode_literals
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
c.set_armor(True)
@@ -62,3 +61,18 @@ with gpg.Context(armor=True) as c:
assert support.sign_only.endswith(e.recipients[0].fpr)
else:
assert False, "Expected an InvalidRecipients error, got none"
+
+
+
+ try:
+ # People might be tempted to provide strings.
+ # We should raise something useful.
+ ciphertext, _, _ = c.encrypt("Hallo Leute\n",
+ recipients=keys,
+ sign=False,
+ always_trust=True)
+ except TypeError as e:
+ # This test is a bit fragile, because the message
+ # may very well change. So if the behaviour will change
+ # this test can easily be deleted.
+ assert "encode" in str(e)
diff --git a/lang/python/tests/t-export.py b/lang/python/tests/t-export.py
index 4927beb..b9d5204 100755
--- a/lang/python/tests/t-export.py
+++ b/lang/python/tests/t-export.py
@@ -23,7 +23,6 @@ del absolute_import, print_function, unicode_literals
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
c.set_armor(True)
diff --git a/lang/python/tests/t-file-name.py b/lang/python/tests/t-file-name.py
index d12afb8..aab5680 100755
--- a/lang/python/tests/t-file-name.py
+++ b/lang/python/tests/t-file-name.py
@@ -26,7 +26,6 @@ import support
testname = "abcde12345"
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
c.set_armor(True)
diff --git a/lang/python/tests/t-idiomatic.py b/lang/python/tests/t-idiomatic.py
index 485f048..826bc23 100755
--- a/lang/python/tests/t-idiomatic.py
+++ b/lang/python/tests/t-idiomatic.py
@@ -27,8 +27,6 @@ import tempfile
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
-
# Both Context and Data can be used as context manager:
with gpg.Context() as c, gpg.Data() as d:
c.get_engine_info()
diff --git a/lang/python/tests/t-import.py b/lang/python/tests/t-import.py
index 5b0576f..e2edf5a 100755
--- a/lang/python/tests/t-import.py
+++ b/lang/python/tests/t-import.py
@@ -67,7 +67,6 @@ def check_result(result, fpr, secret):
assert len(result.imports) == 1 or fpr == result.imports[1].fpr
assert result.imports[0].result == 0
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
c.op_import(gpg.Data(file=support.make_filename("pubkey-1.asc")))
diff --git a/lang/python/tests/t-keylist-from-data.py b/lang/python/tests/t-keylist-from-data.py
new file mode 100755
index 0000000..6a26267
--- /dev/null
+++ b/lang/python/tests/t-keylist-from-data.py
@@ -0,0 +1,213 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2016 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import, print_function, unicode_literals
+del absolute_import, print_function, unicode_literals
+
+import os
+import sys
+import gpg
+import support
+
+support.assert_gpg_version((2, 1, 14))
+
+# Check expration of keys. This test assumes three subkeys of which
+# 2 are expired; it is used with the "Whisky" test key. It has
+# already been checked that these 3 subkeys are available.
+def check_whisky(name, key):
+ sub1 = key.subkeys[2]
+ sub2 = key.subkeys[3]
+
+ assert sub1.expired and sub2.expired, \
+ "Subkey of `{}' not flagged as expired".format(name)
+ assert sub1.expires == 1129636886 and sub2.expires == 1129636939, \
+ "Subkey of `{}' has wrong expiration date".format(name)
+
+keys = [
+ [ "A0FF4590BB6122EDEF6E3C542D727CC768697734", "6AE6D7EE46A871F8",
+ [ [ "Alfa Test", "demo key", "alfa@example.net" ],
+ [ "Alpha Test", "demo key", "alpha@example.net" ],
+ [ "Alice", "demo key", "" ] ], 1 ],
+ [ "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2", "5381EA4EE29BA37F",
+ [ [ "Bob", "demo key", "" ],
+ [ "Bravo Test", "demo key", "bravo@example.net" ] ], 1 ],
+ [ "61EE841A2A27EB983B3B3C26413F4AF31AFDAB6C", "E71E72ACBC43DA60",
+ [ [ "Charlie Test", "demo key", "charlie@example.net" ] ], 1 ],
+ [ "6560C59C43D031C54D7C588EEBA9F240EB9DC9E6", "06F22880B0C45424",
+ [ [ "Delta Test", "demo key", "delta@example.net" ] ], 1 ],
+ [ "3531152DE293E26A07F504BC318C1FAEFAEF6D1B", "B5C79E1A7272144D",
+ [ [ "Echelon", "demo key", "" ],
+ [ "Echo Test", "demo key", "echo@example.net" ],
+ [ "Eve", "demo key", "" ] ], 1 ],
+ [ "56D33268F7FE693FBB594762D4BF57F37372E243", "0A32EE79EE45198E",
+ [ [ "Foxtrot Test", "demo key", "foxtrot@example.net" ] ], 1 ],
+ [ "C9C07DCC6621B9FB8D071B1D168410A48FC282E6", "247491CC9DCAD354",
+ [ [ "Golf Test", "demo key", "golf@example.net" ] ], 1 ],
+ [ "9E91CBB11E4D4135583EF90513DB965534C6E3F1", "76E26537D622AD0A",
+ [ [ "Hotel Test", "demo key", "hotel@example.net" ] ], 1 ],
+ [ "CD538D6CC9FB3D745ECDA5201FE8FC6F04259677", "C1C8EFDE61F76C73",
+ [ [ "India Test", "demo key", "india@example.net" ] ], 1 ],
+ [ "F8F1EDC73995AB739AD54B380C820C71D2699313", "BD0B108735F8F136",
+ [ [ "Juliet Test", "demo key", "juliet@example.net" ] ], 1 ],
+ [ "3FD11083779196C2ECDD9594AD1B0FAD43C2D0C7", "86CBB34A9AF64D02",
+ [ [ "Kilo Test", "demo key", "kilo@example.net" ] ], 1 ],
+ [ "1DDD28CEF714F5B03B8C246937CAB51FB79103F8", "0363B449FE56350C",
+ [ [ "Lima Test", "demo key", "lima@example.net" ] ], 1 ],
+ [ "2686AA191A278013992C72EBBE794852BE5CF886", "5F600A834F31EAE8",
+ [ [ "Mallory", "demo key", "" ],
+ [ "Mike Test", "demo key", "mike@example.net" ] ], 1 ],
+ [ "5AB9D6D7BAA1C95B3BAA3D9425B00FD430CEC684", "4C1D63308B70E472",
+ [ [ "November Test", "demo key", "november@example.net" ] ], 1 ],
+ [ "43929E89F8F79381678CAE515F6356BA6D9732AC", "FF0785712681619F",
+ [ [ "Oscar Test", "demo key", "oscar@example.net" ] ], 1 ],
+ [ "6FAA9C201E5E26DCBAEC39FD5D15E01D3FF13206", "2764E18263330D9C",
+ [ [ "Papa test", "demo key", "papa@example.net" ] ], 1 ],
+ [ "A7969DA1C3297AA96D49843F1C67EC133C661C84", "6CDCFC44A029ACF4",
+ [ [ "Quebec Test", "demo key", "quebec@example.net" ] ], 1 ],
+ [ "38FBE1E4BF6A5E1242C8F6A13BDBEDB1777FBED3", "9FAB805A11D102EA",
+ [ [ "Romeo Test", "demo key", "romeo@example.net" ] ], 1 ],
+ [ "045B2334ADD69FC221076841A5E67F7FA3AE3EA1", "93B88B0F0F1B50B4",
+ [ [ "Sierra Test", "demo key", "sierra@example.net" ] ], 1 ],
+ [ "ECAC774F4EEEB0620767044A58CB9A4C85A81F38", "97B60E01101C0402",
+ [ [ "Tango Test", "demo key", "tango@example.net" ] ], 1 ],
+ [ "0DBCAD3F08843B9557C6C4D4A94C0F75653244D6", "93079B915522BDB9",
+ [ [ "Uniform Test", "demo key", "uniform@example.net" ] ], 1 ],
+ [ "E8143C489C8D41124DC40D0B47AF4B6961F04784", "04071FB807287134",
+ [ [ "Victor Test", "demo key", "victor@example.org" ] ], 1 ],
+ [ "E8D6C90B683B0982BD557A99DEF0F7B8EC67DBDE", "D7FBB421FD6E27F6",
+ [ [ "Whisky Test", "demo key", "whisky@example.net" ] ], 3,
+ check_whisky ],
+ [ "04C1DF62EFA0EBB00519B06A8979A6C5567FB34A", "5CC6F87F41E408BE",
+ [ [ "XRay Test", "demo key", "xray@example.net" ] ], 1 ],
+ [ "ED9B316F78644A58D042655A9EEF34CD4B11B25F", "5ADFD255F7B080AD",
+ [ [ "Yankee Test", "demo key", "yankee@example.net" ] ], 1 ],
+ [ "23FD347A419429BACCD5E72D6BC4778054ACD246", "EF9DC276A172C881",
+ [ [ "Zulu Test", "demo key", "zulu@example.net" ] ], 1 ],
+]
+
+def check_global(key, uids, n_subkeys):
+ assert not key.revoked, "Key unexpectedly revoked"
+ assert not key.expired, "Key unexpectedly expired"
+ assert not key.disabled, "Key unexpectedly disabled"
+ assert not key.invalid, "Key unexpectedly invalid"
+ assert key.can_sign, "Key unexpectedly unusable for signing"
+ assert key.can_certify, "Key unexpectedly unusable for certifications"
+ assert not key.secret, "Key unexpectedly secret"
+ assert not key.protocol != gpg.constants.protocol.OpenPGP, \
+ "Key has unexpected protocol: {}".format(key.protocol)
+ assert not key.issuer_serial, \
+ "Key unexpectedly carries issuer serial: {}".format(key.issuer_serial)
+ assert not key.issuer_name, \
+ "Key unexpectedly carries issuer name: {}".format(key.issuer_name)
+ assert not key.chain_id, \
+ "Key unexpectedly carries chain ID: {}".format(key.chain_id)
+ assert key.owner_trust == gpg.constants.validity.UNKNOWN, \
+ "Key has unexpected owner trust: {}".format(key.owner_trust)
+ assert len(key.subkeys) - 1 == n_subkeys, \
+ "Key `{}' has unexpected number of subkeys".format(uids[0][0])
+
+
+def check_subkey(fpr, which, subkey):
+ assert not subkey.revoked, which + " key unexpectedly revoked"
+ assert not subkey.expired, which + " key unexpectedly expired"
+ assert not subkey.disabled, which + " key unexpectedly disabled"
+ assert not subkey.invalid, which + " key unexpectedly invalid"
+
+ if which == "Primary":
+ assert not subkey.can_encrypt, \
+ which + " key unexpectedly usable for encryption"
+ assert subkey.can_sign, \
+ which + " key unexpectedly unusable for signing"
+ assert subkey.can_certify, \
+ which + " key unexpectedly unusable for certifications"
+ else:
+ assert subkey.can_encrypt, \
+ which + " key unexpectedly unusable for encryption"
+ assert not subkey.can_sign, \
+ which + " key unexpectedly usable for signing"
+ assert not subkey.can_certify, \
+ which + " key unexpectedly usable for certifications"
+
+ assert not subkey.secret, which + " key unexpectedly secret"
+ assert not subkey.is_cardkey, "Public key marked as card key"
+ assert not subkey.card_number, "Public key with card number set"
+ assert not subkey.pubkey_algo != (gpg.constants.pk.DSA if which == "Primary"
+ else gpg.constants.pk.ELG_E), \
+ which + " key has unexpected public key algo: {}".\
+ format(subkey.pubkey_algo)
+ assert subkey.length == 1024, \
+ which + " key has unexpected length: {}".format(subkey.length)
+ assert fpr.endswith(subkey.keyid), \
+ which + " key has unexpected key ID: {}".format(subkey.keyid)
+ assert which == "Secondary" or subkey.fpr == fpr, \
+ which + " key has unexpected fingerprint: {}".format(subkey.fpr)
+ assert not subkey.expires, \
+ which + " key unexpectedly expires: {}".format(subkey.expires)
+
+def check_uid(which, ref, uid):
+ assert not uid.revoked, which + " user ID unexpectedly revoked"
+ assert not uid.invalid, which + " user ID unexpectedly invalid"
+ assert uid.validity == gpg.constants.validity.UNKNOWN, \
+ which + " user ID has unexpected validity: {}".format(uid.validity)
+ assert not uid.signatures, which + " user ID unexpectedly signed"
+ assert uid.name == ref[0], \
+ "Unexpected name in {} user ID: {!r}".format(which.lower(), uid.name)
+ assert uid.comment == ref[1], \
+ "Unexpected comment in {} user ID: {!r}".format(which.lower(),
+ uid.comment)
+ assert uid.email == ref[2], \
+ "Unexpected email in {} user ID: {!r}".format(which.lower(), uid.email)
+
+# Export all the data from our keyring...
+key_data = gpg.Data()
+with gpg.Context() as c:
+ c.op_export_keys([c.get_key(k[0]) for k in keys], 0, key_data)
+
+# ... rewind the tape...
+key_data.rewind()
+
+# ... and feed it into a keylist in an empty context.
+with support.EphemeralContext() as c:
+ for i, key in enumerate(c.keylist(source=key_data)):
+ try:
+ if len(keys[i]) == 4:
+ fpr, sec_keyid, uids, n_subkeys = keys[i]
+ misc_check = None
+ else:
+ fpr, sec_keyid, uids, n_subkeys, misc_check = keys[i]
+ except IndexError:
+ # There are more keys. We don't check for that.
+ break
+
+ # Global key flags.
+ check_global(key, uids, n_subkeys)
+ check_subkey(fpr, "Primary", key.subkeys[0])
+ check_subkey(sec_keyid, "Secondary", key.subkeys[1])
+
+ assert len(key.uids) == len(uids)
+ check_uid("First", uids[0], key.uids[0])
+ if len(key.uids) > 1:
+ check_uid("Second", uids[1], key.uids[1])
+ if len(key.uids) > 2:
+ check_uid("Third", uids[2], key.uids[2])
+
+ if misc_check:
+ misc_check (uids[0][0], key)
+
+ assert len(list(c.keylist())) == 0, "Keys were imported"
diff --git a/lang/python/tests/t-keylist.py b/lang/python/tests/t-keylist.py
index ea2a724..76c793e 100755
--- a/lang/python/tests/t-keylist.py
+++ b/lang/python/tests/t-keylist.py
@@ -23,7 +23,6 @@ del absolute_import, print_function, unicode_literals
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
# Check expration of keys. This test assumes three subkeys of which
@@ -219,6 +218,18 @@ result = c.op_keylist_result()
assert not result.truncated, "Key listing unexpectedly truncated"
+# We test for a parameter-less keylist
+keyring_length = len(list(c.op_keylist_all()))
+assert keyring_length > 1,\
+ "Expected to find some keys, but got %r" % keyring_length
+
+# Then we do want to call with a pattern, only
+# i.e. without giving secret=0
+alpha_keys = list(c.op_keylist_all(b"Alpha"))
+assert len(alpha_keys) == 1, "Expected only one key for 'Alpha', got %r" % len(alpha_keys)
+
+
+
for i, key in enumerate(c.keylist()):
try:
if len(keys[i]) == 4:
diff --git a/lang/python/tests/t-protocol-assuan.py b/lang/python/tests/t-protocol-assuan.py
index 0084a6b..27b28c7 100755
--- a/lang/python/tests/t-protocol-assuan.py
+++ b/lang/python/tests/t-protocol-assuan.py
@@ -24,9 +24,12 @@ import gpg
with gpg.Context(protocol=gpg.constants.protocol.ASSUAN) as c:
# Do nothing.
- c.assuan_transact('nop')
- c.assuan_transact('NOP')
- c.assuan_transact(['NOP'])
+ err = c.assuan_transact('nop')
+ assert err == None
+ err = c.assuan_transact(b'NOP')
+ assert err == None
+ err = c.assuan_transact(['NOP'])
+ assert err == None
err = c.assuan_transact('idontexist')
assert err.getsource() == gpg.errors.SOURCE_GPGAGENT
diff --git a/lang/python/tests/t-quick-key-creation.py b/lang/python/tests/t-quick-key-creation.py
new file mode 100755
index 0000000..8b7372e
--- /dev/null
+++ b/lang/python/tests/t-quick-key-creation.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2017 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import, print_function, unicode_literals
+del absolute_import, print_function, unicode_literals
+
+import gpg
+import itertools
+import time
+
+import support
+support.assert_gpg_version((2, 1, 2))
+
+alpha = "Alpha <alpha@invalid.example.net>"
+
+with support.EphemeralContext() as ctx:
+ res = ctx.create_key(alpha)
+
+ keys = list(ctx.keylist())
+ assert len(keys) == 1, "Weird number of keys created"
+
+ key = keys[0]
+ assert key.fpr == res.fpr
+ assert len(key.subkeys) == 2, "Expected one primary key and one subkey"
+ assert key.subkeys[0].expires > 0, "Expected primary key to expire"
+
+ # Try to create a key with the same UID
+ try:
+ ctx.create_key(alpha)
+ assert False, "Expected an error but got none"
+ except gpg.errors.GpgError as e:
+ pass
+
+ # Try to create a key with the same UID, now with force!
+ res2 = ctx.create_key(alpha, force=True)
+ assert res.fpr != res2.fpr
+
+
+# From here on, we use one context, and create unique UIDs
+uid_counter = 0
+def make_uid():
+ global uid_counter
+ uid_counter += 1
+ return "user{0}@invalid.example.org".format(uid_counter)
+
+with support.EphemeralContext() as ctx:
+ # Check gpg.constants.create.NOEXPIRE...
+ res = ctx.create_key(make_uid(), expires=False)
+ key = ctx.get_key(res.fpr, secret=True)
+ assert key.fpr == res.fpr
+ assert len(key.subkeys) == 2, "Expected one primary key and one subkey"
+ assert key.subkeys[0].expires == 0, "Expected primary key not to expire"
+
+ t = 2 * 24 * 60 * 60
+ slack = 5 * 60
+ res = ctx.create_key(make_uid(), expires_in=t)
+ key = ctx.get_key(res.fpr, secret=True)
+ assert key.fpr == res.fpr
+ assert len(key.subkeys) == 2, "Expected one primary key and one subkey"
+ assert abs(time.time() + t - key.subkeys[0].expires) < slack, \
+ "Primary keys expiration time is off"
+
+ # Check capabilities
+ for sign, encrypt, certify, authenticate in itertools.product([False, True],
+ [False, True],
+ [False, True],
+ [False, True]):
+ # Filter some out
+ if not (sign or encrypt or certify or authenticate):
+ # This triggers the default capabilities tested before.
+ continue
+ if (sign or encrypt or authenticate) and not certify:
+ # The primary key always certifies.
+ continue
+
+ res = ctx.create_key(make_uid(), algorithm="rsa",
+ sign=sign, encrypt=encrypt, certify=certify,
+ authenticate=authenticate)
+ key = ctx.get_key(res.fpr, secret=True)
+ assert key.fpr == res.fpr
+ assert len(key.subkeys) == 1, \
+ "Expected no subkey for non-default capabilities"
+
+ p = key.subkeys[0]
+ assert sign == p.can_sign
+ assert encrypt == p.can_encrypt
+ assert certify == p.can_certify
+ assert authenticate == p.can_authenticate
+
+ # Check algorithm
+ res = ctx.create_key(make_uid(), algorithm="rsa")
+ key = ctx.get_key(res.fpr, secret=True)
+ assert key.fpr == res.fpr
+ for k in key.subkeys:
+ assert k.pubkey_algo == 1
+
+ # Check algorithm with size
+ res = ctx.create_key(make_uid(), algorithm="rsa1024")
+ key = ctx.get_key(res.fpr, secret=True)
+ assert key.fpr == res.fpr
+ for k in key.subkeys:
+ assert k.pubkey_algo == 1
+ assert k.length == 1024
+
+ # Check algorithm future-default
+ ctx.create_key(make_uid(), algorithm="future-default")
+
+ # Check passphrase protection
+ recipient = make_uid()
+ passphrase = "streng geheim"
+ res = ctx.create_key(recipient, passphrase=passphrase)
+ ciphertext, _, _ = ctx.encrypt(b"hello there", recipients=[ctx.get_key(res.fpr)])
+
+ cb_called = False
+ def cb(*args):
+ global cb_called
+ cb_called = True
+ return passphrase
+ ctx.pinentry_mode = gpg.constants.PINENTRY_MODE_LOOPBACK
+ ctx.set_passphrase_cb(cb)
+
+ plaintext, _, _ = ctx.decrypt(ciphertext)
+ assert plaintext == b"hello there"
+ assert cb_called
diff --git a/lang/python/tests/t-quick-key-manipulation.py b/lang/python/tests/t-quick-key-manipulation.py
new file mode 100755
index 0000000..0f47006
--- /dev/null
+++ b/lang/python/tests/t-quick-key-manipulation.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2017 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import, print_function, unicode_literals
+del absolute_import, print_function, unicode_literals
+
+import os
+import gpg
+
+import support
+support.assert_gpg_version((2, 1, 14))
+
+alpha = "Alpha <alpha@invalid.example.net>"
+bravo = "Bravo <bravo@invalid.example.net>"
+
+with support.EphemeralContext() as ctx:
+ res = ctx.create_key(alpha, certify=True)
+ key = ctx.get_key(res.fpr)
+ assert len(key.subkeys) == 1, "Expected one primary key and no subkeys"
+ assert len(key.uids) == 1, "Expected exactly one UID"
+
+ def get_uid(uid):
+ key = ctx.get_key(res.fpr)
+ for u in key.uids:
+ if u.uid == uid:
+ return u
+ return None
+
+ # sanity check
+ uid = get_uid(alpha)
+ assert uid, "UID alpha not found"
+ assert uid.revoked == 0
+
+ # add bravo
+ ctx.key_add_uid(key, bravo)
+ uid = get_uid(bravo)
+ assert uid, "UID bravo not found"
+ assert uid.revoked == 0
+
+ # revoke alpha
+ ctx.key_revoke_uid(key, alpha)
+ uid = get_uid(alpha)
+ assert uid, "UID alpha not found"
+ assert uid.revoked == 1
+ uid = get_uid(bravo)
+ assert uid, "UID bravo not found"
+ assert uid.revoked == 0
+
+ # try to revoke the last UID
+ try:
+ ctx.key_revoke_uid(key, alpha)
+ # IMHO this should fail. issue2961.
+ # assert False, "Expected an error but got none"
+ except gpg.errors.GpgError:
+ pass
+
+ # Everything should be the same
+ uid = get_uid(alpha)
+ assert uid, "UID alpha not found"
+ assert uid.revoked == 1
+ uid = get_uid(bravo)
+ assert uid, "UID bravo not found"
+ assert uid.revoked == 0
+
+ # try to revoke a non-existent UID
+ try:
+ ctx.key_revoke_uid(key, "i dont exist")
+ # IMHO this should fail. issue2963.
+ # assert False, "Expected an error but got none"
+ except gpg.errors.GpgError:
+ pass
+
+ # try to add an pre-existent UID
+ try:
+ ctx.key_add_uid(key, bravo)
+ assert False, "Expected an error but got none"
+ except gpg.errors.GpgError:
+ pass
+
+ # Check setting the TOFU policy.
+ with open(os.path.join(ctx.home_dir, "gpg.conf"), "a") as handle:
+ handle.write("trust-model tofu+pgp\n")
+
+ for name, policy in [(name, getattr(gpg.constants.tofu.policy, name))
+ for name in filter(lambda x: not x.startswith('__'),
+ dir(gpg.constants.tofu.policy))]:
+ if policy == gpg.constants.tofu.policy.NONE:
+ # We must not set the policy to NONE.
+ continue
+
+ ctx.key_tofu_policy(key, policy)
+
+ keys = list(ctx.keylist(key.uids[0].uid,
+ mode=(gpg.constants.keylist.mode.LOCAL
+ |gpg.constants.keylist.mode.WITH_TOFU)))
+ assert len(keys) == 1
+
+ if policy == gpg.constants.tofu.policy.AUTO:
+ # We cannot check that it is set to AUTO.
+ continue
+
+ for uid in keys[0].uids:
+ if uid.uid == alpha:
+ # TOFU information of revoked UIDs is not updated.
+ # XXX: Is that expected?
+ continue
+ assert uid.tofu[0].policy == policy, \
+ "Expected policy {0} ({1}), got {2}".format(policy, name,
+ uid.tofu[0].policy)
diff --git a/lang/python/tests/t-quick-key-signing.py b/lang/python/tests/t-quick-key-signing.py
new file mode 100755
index 0000000..3d648c5
--- /dev/null
+++ b/lang/python/tests/t-quick-key-signing.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2017 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import, print_function, unicode_literals
+del absolute_import, print_function, unicode_literals
+
+import gpg
+import itertools
+import time
+
+import support
+support.assert_gpg_version((2, 1, 1))
+
+with support.EphemeralContext() as ctx:
+ uid_counter = 0
+ def make_uid():
+ global uid_counter
+ uid_counter += 1
+ return "user{0}@invalid.example.org".format(uid_counter)
+
+ def make_key():
+ uids = [make_uid() for i in range(3)]
+ res = ctx.create_key(uids[0], certify=True)
+ key = ctx.get_key(res.fpr)
+ for u in uids[1:]:
+ ctx.key_add_uid(key, u)
+ return key, uids
+
+ def check_sigs(key, expected_sigs):
+ keys = list(ctx.keylist(key.fpr, mode=(gpg.constants.keylist.mode.LOCAL
+ |gpg.constants.keylist.mode.SIGS)))
+ assert len(keys) == 1
+ key_uids = {uid.uid: [s for s in uid.signatures] for uid in keys[0].uids}
+ expected = list(expected_sigs)
+
+ while key_uids and expected:
+ uid, signing_key, func = expected[0]
+ match = False
+ for i, s in enumerate(key_uids[uid]):
+ if signing_key.fpr.endswith(s.keyid):
+ if func:
+ func(s)
+ match = True
+ break
+ if match:
+ expected.pop(0)
+ key_uids[uid].pop(i)
+ if not key_uids[uid]:
+ del key_uids[uid]
+
+ assert not key_uids, "Superfluous signatures: {0}".format(key_uids)
+ assert not expected, "Missing signatures: {0}".format(expected)
+
+ # Simplest case. Sign without any options.
+ key_a, uids_a = make_key()
+ key_b, uids_b = make_key()
+ ctx.signers = [key_a]
+
+ def exportable_non_expiring(s):
+ assert s.exportable
+ assert s.expires == 0
+
+ check_sigs(key_b, itertools.product(uids_b, [key_b], [exportable_non_expiring]))
+ ctx.key_sign(key_b)
+ check_sigs(key_b, itertools.product(uids_b, [key_b, key_a], [exportable_non_expiring]))
+
+ # Create a non-exportable signature, and explicitly name all uids.
+ key_c, uids_c = make_key()
+ ctx.signers = [key_a, key_b]
+
+ def non_exportable_non_expiring(s):
+ assert s.exportable == 0
+ assert s.expires == 0
+
+ ctx.key_sign(key_c, local=True, uids=uids_c)
+ check_sigs(key_c,
+ list(itertools.product(uids_c, [key_c],
+ [exportable_non_expiring]))
+ + list(itertools.product(uids_c, [key_b, key_a],
+ [non_exportable_non_expiring])))
+
+ # Create a non-exportable, expiring signature for a single uid.
+ key_d, uids_d = make_key()
+ ctx.signers = [key_c]
+ expires_in = 600
+ slack = 10
+
+ def non_exportable_expiring(s):
+ assert s.exportable == 0
+ assert abs(time.time() + expires_in - s.expires) < slack
+
+ ctx.key_sign(key_d, local=True, expires_in=expires_in, uids=uids_d[0])
+ check_sigs(key_d,
+ list(itertools.product(uids_d, [key_d],
+ [exportable_non_expiring]))
+ + list(itertools.product(uids_d[:1], [key_c],
+ [non_exportable_expiring])))
+
+ # Now sign the second in the same fashion, but use a singleton list.
+ ctx.key_sign(key_d, local=True, expires_in=expires_in, uids=uids_d[1:2])
+ check_sigs(key_d,
+ list(itertools.product(uids_d, [key_d],
+ [exportable_non_expiring]))
+ + list(itertools.product(uids_d[:2], [key_c],
+ [non_exportable_expiring])))
diff --git a/lang/python/tests/t-quick-subkey-creation.py b/lang/python/tests/t-quick-subkey-creation.py
new file mode 100755
index 0000000..ad4f35c
--- /dev/null
+++ b/lang/python/tests/t-quick-subkey-creation.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2017 g10 Code GmbH
+#
+# This file is part of GPGME.
+#
+# GPGME is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GPGME is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import absolute_import, print_function, unicode_literals
+del absolute_import, print_function, unicode_literals
+
+import gpg
+import itertools
+import time
+
+import support
+
+alpha = "Alpha <alpha@invalid.example.net>"
+bravo = "Bravo <bravo@invalid.example.net>"
+
+with support.EphemeralContext() as ctx:
+ res = ctx.create_key(alpha, certify=True)
+ keys = list(ctx.keylist())
+ assert len(keys) == 1, "Weird number of keys created"
+ key = keys[0]
+ assert key.fpr == res.fpr
+ assert len(key.subkeys) == 1, "Expected one primary key and no subkeys"
+
+ def get_subkey(fpr):
+ k = ctx.get_key(fpr)
+ for sk in k.subkeys:
+ if sk.fpr == fpr:
+ return sk
+ return None
+
+ # Check gpg.constants.create.NOEXPIRE...
+ res = ctx.create_subkey(key, expires=False)
+ subkey = get_subkey(res.fpr)
+ assert subkey.expires == 0, "Expected subkey not to expire"
+ assert subkey.can_encrypt, \
+ "Default subkey capabilities do not include encryption"
+
+ t = 2 * 24 * 60 * 60
+ slack = 5 * 60
+ res = ctx.create_subkey(key, expires_in=t)
+ subkey = get_subkey(res.fpr)
+ assert abs(time.time() + t - subkey.expires) < slack, \
+ "subkeys expiration time is off"
+
+ # Check capabilities
+ for sign, encrypt, authenticate in itertools.product([False, True],
+ [False, True],
+ [False, True]):
+ # Filter some out
+ if not (sign or encrypt or authenticate):
+ # This triggers the default capabilities tested before.
+ continue
+
+ res = ctx.create_subkey(key, sign=sign, encrypt=encrypt,
+ authenticate=authenticate)
+ subkey = get_subkey(res.fpr)
+ assert sign == subkey.can_sign
+ assert encrypt == subkey.can_encrypt
+ assert authenticate == subkey.can_authenticate
+
+ # Check algorithm
+ res = ctx.create_subkey(key, algorithm="rsa")
+ subkey = get_subkey(res.fpr)
+ assert subkey.pubkey_algo == 1
+
+ # Check algorithm with size
+ res = ctx.create_subkey(key, algorithm="rsa1024")
+ subkey = get_subkey(res.fpr)
+ assert subkey.pubkey_algo == 1
+ assert subkey.length == 1024
+
+ # Check algorithm future-default
+ ctx.create_subkey(key, algorithm="future-default")
+
+ # Check passphrase protection. For this we create a new key
+ # so that we have a key with just one encryption subkey.
+ bravo_res = ctx.create_key(bravo, certify=True)
+ bravo_key = ctx.get_key(bravo_res.fpr)
+ assert len(bravo_key.subkeys) == 1, "Expected one primary key and no subkeys"
+
+ passphrase = "streng geheim"
+ res = ctx.create_subkey(bravo_key, passphrase=passphrase)
+ ciphertext, _, _ = ctx.encrypt(b"hello there",
+ recipients=[ctx.get_key(bravo_res.fpr)])
+
+ cb_called = False
+ def cb(*args):
+ global cb_called
+ cb_called = True
+ return passphrase
+ ctx.pinentry_mode = gpg.constants.PINENTRY_MODE_LOOPBACK
+ ctx.set_passphrase_cb(cb)
+
+ plaintext, _, _ = ctx.decrypt(ciphertext)
+ assert plaintext == b"hello there"
+ assert cb_called
diff --git a/lang/python/tests/t-sig-notation.py b/lang/python/tests/t-sig-notation.py
index f1342b1..2277497 100755
--- a/lang/python/tests/t-sig-notation.py
+++ b/lang/python/tests/t-sig-notation.py
@@ -62,8 +62,6 @@ def check_result(result):
assert len(expected_notations) == 0
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
-
source = gpg.Data("Hallo Leute\n")
signed = gpg.Data()
diff --git a/lang/python/tests/t-sign.py b/lang/python/tests/t-sign.py
index 9418ed8..d375729 100755
--- a/lang/python/tests/t-sign.py
+++ b/lang/python/tests/t-sign.py
@@ -53,8 +53,6 @@ def check_result(r, typ):
if signature.fpr != "A0FF4590BB6122EDEF6E3C542D727CC768697734":
fail("Wrong fingerprint reported: {}".format(signature.fpr))
-
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
c.set_textmode(True)
c.set_armor(True)
diff --git a/lang/python/tests/t-signers.py b/lang/python/tests/t-signers.py
index 80e797c..5864ee5 100755
--- a/lang/python/tests/t-signers.py
+++ b/lang/python/tests/t-signers.py
@@ -53,8 +53,6 @@ def check_result(r, typ):
"23FD347A419429BACCD5E72D6BC4778054ACD246"):
fail("Wrong fingerprint reported: {}".format(signature.fpr))
-
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
c.set_textmode(True)
c.set_armor(True)
diff --git a/lang/python/tests/t-trustlist.py b/lang/python/tests/t-trustlist.py
index 8c5e214..8586596 100755
--- a/lang/python/tests/t-trustlist.py
+++ b/lang/python/tests/t-trustlist.py
@@ -23,7 +23,6 @@ del absolute_import, print_function, unicode_literals
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
def dump_item(item):
diff --git a/lang/python/tests/t-verify.py b/lang/python/tests/t-verify.py
index f18e1dd..0347638 100755
--- a/lang/python/tests/t-verify.py
+++ b/lang/python/tests/t-verify.py
@@ -97,8 +97,6 @@ def check_result(result, summary, validity, fpr, status, notation):
sig.validity, validity)
assert gpg.errors.GPGMEError(sig.validity_reason).getcode() == gpg.errors.NO_ERROR
-
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
c.set_armor(True)
diff --git a/lang/python/tests/t-wait.py b/lang/python/tests/t-wait.py
index b1f2043..0c403fa 100755
--- a/lang/python/tests/t-wait.py
+++ b/lang/python/tests/t-wait.py
@@ -24,7 +24,6 @@ import time
import gpg
import support
-support.init_gpgme(gpg.constants.protocol.OpenPGP)
c = gpg.Context()
c.set_armor(True)
diff --git a/lang/qt/Makefile.in b/lang/qt/Makefile.in
index 5c32620..e054e25 100644
--- a/lang/qt/Makefile.in
+++ b/lang/qt/Makefile.in
@@ -110,8 +110,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
diff --git a/lang/qt/doc/Makefile.in b/lang/qt/doc/Makefile.in
index c4aff43..7e86941 100644
--- a/lang/qt/doc/Makefile.in
+++ b/lang/qt/doc/Makefile.in
@@ -108,8 +108,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am
index 87e2ec2..c81461e 100644
--- a/lang/qt/src/Makefile.am
+++ b/lang/qt/src/Makefile.am
@@ -37,7 +37,7 @@ qgpgme_sources = \
qgpgmekeyformailboxjob.cpp gpgme_backend_debug.cpp \
qgpgmetofupolicyjob.cpp \
defaultkeygenerationjob.cpp qgpgmewkspublishjob.cpp \
- dn.cpp
+ dn.cpp cryptoconfig.cpp
# If you add one here make sure that you also add one in camelcase
qgpgme_headers= \
@@ -220,6 +220,12 @@ libqgpgme_la_LIBADD = ../../cpp/src/libgpgmepp.la ../../../src/libgpgme.la \
libqgpgme_la_LDFLAGS = -no-undefined -version-info \
@LIBQGPGME_LT_CURRENT@:@LIBQGPGME_LT_REVISION@:@LIBQGPGME_LT_AGE@
+if HAVE_MACOS_SYSTEM
+libsuffix=.dylib
+else
+libsuffix=.so
+endif
+
if HAVE_W32_SYSTEM
QGpgmeConfig.cmake: QGpgmeConfig-w32.cmake.in
sed -e 's|[@]resolved_bindir@|$(bindir)|g' < "$<" | \
@@ -228,6 +234,7 @@ QGpgmeConfig.cmake: QGpgmeConfig-w32.cmake.in
else
QGpgmeConfig.cmake: QGpgmeConfig.cmake.in
sed -e 's|[@]resolved_libdir@|$(libdir)|g' < "$<" | \
+ sed -e 's|[@]libsuffix@|$(libsuffix)|g' | \
sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@
endif
diff --git a/lang/qt/src/Makefile.in b/lang/qt/src/Makefile.in
index 5b87f6e..635aaaa 100644
--- a/lang/qt/src/Makefile.in
+++ b/lang/qt/src/Makefile.in
@@ -97,8 +97,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
@@ -154,7 +154,8 @@ am__objects_1 = dataprovider.lo job.lo multideletejob.lo \
qgpgmeverifydetachedjob.lo qgpgmeverifyopaquejob.lo \
threadedjobmixin.lo qgpgmekeyformailboxjob.lo \
gpgme_backend_debug.lo qgpgmetofupolicyjob.lo \
- defaultkeygenerationjob.lo qgpgmewkspublishjob.lo dn.lo
+ defaultkeygenerationjob.lo qgpgmewkspublishjob.lo dn.lo \
+ cryptoconfig.lo
am__objects_2 =
am_libqgpgme_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_2)
@@ -484,7 +485,7 @@ qgpgme_sources = \
qgpgmekeyformailboxjob.cpp gpgme_backend_debug.cpp \
qgpgmetofupolicyjob.cpp \
defaultkeygenerationjob.cpp qgpgmewkspublishjob.cpp \
- dn.cpp
+ dn.cpp cryptoconfig.cpp
# If you add one here make sure that you also add one in camelcase
@@ -667,6 +668,8 @@ libqgpgme_la_LIBADD = ../../cpp/src/libgpgmepp.la ../../../src/libgpgme.la \
libqgpgme_la_LDFLAGS = -no-undefined -version-info \
@LIBQGPGME_LT_CURRENT@:@LIBQGPGME_LT_REVISION@:@LIBQGPGME_LT_AGE@
+@HAVE_MACOS_SYSTEM_FALSE@libsuffix = .so
+@HAVE_MACOS_SYSTEM_TRUE@libsuffix = .dylib
BUILT_SOURCES = $(qgpgme_moc_sources) $(camelcase_headers)
CLEANFILES = $(qgpgme_moc_sources) $(camelcase_headers) QGpgmeConfig.cmake \
qgpgme_version.h QGpgmeConfig.cmake.in \
@@ -761,6 +764,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cryptoconfig.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dataprovider.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defaultkeygenerationjob.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dn.Plo@am__quote@
@@ -1113,6 +1117,7 @@ uninstall-am: uninstall-camelcaseincludeHEADERS \
@HAVE_W32_SYSTEM_TRUE@ sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@
@HAVE_W32_SYSTEM_FALSE@QGpgmeConfig.cmake: QGpgmeConfig.cmake.in
@HAVE_W32_SYSTEM_FALSE@ sed -e 's|[@]resolved_libdir@|$(libdir)|g' < "$<" | \
+@HAVE_W32_SYSTEM_FALSE@ sed -e 's|[@]libsuffix@|$(libsuffix)|g' | \
@HAVE_W32_SYSTEM_FALSE@ sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@
$(camelcase_headers): Makefile.am
diff --git a/lang/qt/src/QGpgmeConfig.cmake.in.in b/lang/qt/src/QGpgmeConfig.cmake.in.in
index 88ed242..a17a19f 100644
--- a/lang/qt/src/QGpgmeConfig.cmake.in.in
+++ b/lang/qt/src/QGpgmeConfig.cmake.in.in
@@ -64,7 +64,7 @@ add_library(QGpgme SHARED IMPORTED)
set_target_properties(QGpgme PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "@resolved_includedir@/qgpgme;@resolved_includedir@"
INTERFACE_LINK_LIBRARIES "Gpgmepp;Qt5::Core"
- IMPORTED_LOCATION "@resolved_libdir@/libqgpgme.so"
+ IMPORTED_LOCATION "@resolved_libdir@/libqgpgme@libsuffix@"
)
if(CMAKE_VERSION VERSION_LESS 2.8.12)
diff --git a/lang/qt/src/cryptoconfig.cpp b/lang/qt/src/cryptoconfig.cpp
new file mode 100644
index 0000000..be265d8
--- /dev/null
+++ b/lang/qt/src/cryptoconfig.cpp
@@ -0,0 +1,44 @@
+/*
+ cryptoconfig.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2017 Intevation GmbH
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+#include "cryptoconfig.h"
+#include "qgpgmenewcryptoconfig.h"
+
+using namespace QGpgME;
+
+QStringList CryptoConfigEntry::stringValueList() const
+{
+ const QGpgMENewCryptoConfigEntry *entry = dynamic_cast <const QGpgMENewCryptoConfigEntry*> (this);
+ if (!entry) {
+ return QStringList();
+ }
+ return entry->stringValueList();
+}
diff --git a/lang/qt/src/cryptoconfig.h b/lang/qt/src/cryptoconfig.h
index c3f0c7e..c4de22d 100644
--- a/lang/qt/src/cryptoconfig.h
+++ b/lang/qt/src/cryptoconfig.h
@@ -248,6 +248,15 @@ public:
* @return true if the value was changed
*/
virtual bool isDirty() const = 0;
+
+ // Design change from here on we are closely bound to one implementation
+ // of cryptoconfig. To avoid ABI breaks with every new function we
+ // add real functions from now on.
+
+ /**
+ * @return a stringValueList.
+ */
+ QStringList stringValueList() const;
};
/**
@@ -379,9 +388,8 @@ public:
/**
* Write back changes
*
- * @param runtime If this option is set, the changes will take effect at run-time, as
- * far as this is possible. Otherwise, they will take effect at the next
- * start of the respective backend programs.
+ * @param runtime this parameter is ignored. Changes will always
+ * be made with --runtime set.
*/
virtual void sync(bool runtime) = 0;
diff --git a/lang/qt/src/defaultkeygenerationjob.cpp b/lang/qt/src/defaultkeygenerationjob.cpp
index 020f4d2..f589384 100644
--- a/lang/qt/src/defaultkeygenerationjob.cpp
+++ b/lang/qt/src/defaultkeygenerationjob.cpp
@@ -91,6 +91,11 @@ void DefaultKeyGenerationJob::slotCancel()
GpgME::Error DefaultKeyGenerationJob::start(const QString &email, const QString &name)
{
+ const QString namePart = name.isEmpty() ? QString() :
+ QStringLiteral("name-real: %1\n").arg(name);
+ const QString mailPart = email.isEmpty() ? QString() :
+ QStringLiteral("name-email: %1\n").arg(email);
+
const QString args = QStringLiteral("<GnupgKeyParms format=\"internal\">\n"
"%ask-passphrase\n"
"key-type: RSA\n"
@@ -99,9 +104,9 @@ GpgME::Error DefaultKeyGenerationJob::start(const QString &email, const QString
"subkey-type: RSA\n"
"subkey-length: 2048\n"
"subkey-usage: encrypt\n"
- "name-email: %1\n"
- "name-real: %2\n"
- "</GnupgKeyParms>").arg(email, name);
+ "%1"
+ "%2"
+ "</GnupgKeyParms>").arg(mailPart, namePart);
d->job = openpgp()->keyGenerationJob();
d->job->installEventFilter(this);
diff --git a/lang/qt/src/dn.cpp b/lang/qt/src/dn.cpp
index 0f81a4c..f9fb2f6 100644
--- a/lang/qt/src/dn.cpp
+++ b/lang/qt/src/dn.cpp
@@ -37,6 +37,8 @@
#include "dn.h"
+#include <gpg-error.h>
+
static const struct {
const char *name;
const char *oid;
@@ -165,7 +167,7 @@ parse_dn_part(DnPair *array, const unsigned char *string)
for (unsigned int i = 0; i < numOidMaps; ++i)
if (!strcasecmp((char *)p, oidmap[i].oid)) {
free(p);
- p = strdup(oidmap[i].name);
+ gpgrt_asprintf(&p, oidmap[i].name);
break;
}
array->key = p;
diff --git a/lang/qt/src/qgpgmenewcryptoconfig.cpp b/lang/qt/src/qgpgmenewcryptoconfig.cpp
index eb3af56..6901eef 100644
--- a/lang/qt/src/qgpgmenewcryptoconfig.cpp
+++ b/lang/qt/src/qgpgmenewcryptoconfig.cpp
@@ -49,6 +49,7 @@
#include <sstream>
#include <string>
#include <cassert>
+#include <functional>
using namespace QGpgME;
using namespace GpgME;
@@ -216,17 +217,12 @@ QGpgMENewCryptoConfigGroup *QGpgMENewCryptoConfigComponent::group(const QString
void QGpgMENewCryptoConfigComponent::sync(bool runtime)
{
- Q_UNUSED(runtime)
- // ### how to pass --runtime to gpgconf? -> marcus: not yet supported (2010-11-20)
+ Q_UNUSED(runtime) // runtime is always set by engine_gpgconf
if (const Error err = m_component.save()) {
-#if 0
- TODO port
- const QString wmsg = i18n("Error from gpgconf while saving configuration: %1", QString::fromLocal8Bit(err.asString()));
- qCWarning(GPGPME_BACKEND_LOG) << ":" << wmsg;
- KMessageBox::error(0, wmsg);
-#endif
+ qCWarning(GPGPME_BACKEND_LOG) << ":"
+ << "Error from gpgconf while saving configuration: %1"
+ << QString::fromLocal8Bit(err.asString());
}
- // ### unset dirty state again
}
////
@@ -551,6 +547,18 @@ std::vector<unsigned int> QGpgMENewCryptoConfigEntry::uintValueList() const
return m_option.currentValue().uintValues();
}
+QStringList QGpgMENewCryptoConfigEntry::stringValueList() const
+{
+ Q_ASSERT(isList());
+ const Argument arg = m_option.currentValue();
+ const std::vector<const char *> values = arg.stringValues();
+ QStringList ret;
+ for(const char *value: values) {
+ ret << QString::fromUtf8(value);
+ }
+ return ret;
+}
+
QList<QUrl> QGpgMENewCryptoConfigEntry::urlValueList() const
{
const Type type = m_option.type();
diff --git a/lang/qt/src/qgpgmenewcryptoconfig.h b/lang/qt/src/qgpgmenewcryptoconfig.h
index 81b4cb4..7100e70 100644
--- a/lang/qt/src/qgpgmenewcryptoconfig.h
+++ b/lang/qt/src/qgpgmenewcryptoconfig.h
@@ -93,6 +93,8 @@ public:
void setURLValueList(const QList<QUrl> &) Q_DECL_OVERRIDE;
bool isDirty() const Q_DECL_OVERRIDE;
+ QStringList stringValueList() const;
+
#if 0
void setDirty(bool b);
QString outputString() const;
diff --git a/lang/qt/src/threadedjobmixin.h b/lang/qt/src/threadedjobmixin.h
index 32b23db..5ad2737 100644
--- a/lang/qt/src/threadedjobmixin.h
+++ b/lang/qt/src/threadedjobmixin.h
@@ -51,6 +51,7 @@
#include "job.h"
#include <cassert>
+#include <functional>
namespace QGpgME
{
diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am
index ad08ad4..93dce07 100644
--- a/lang/qt/tests/Makefile.am
+++ b/lang/qt/tests/Makefile.am
@@ -25,10 +25,11 @@ TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir)
EXTRA_DIST = initial.test
TESTS = initial.test t-keylist t-keylocate t-ownertrust t-tofuinfo \
- t-encrypt t-verify
+ t-encrypt t-verify t-various t-config
moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \
- t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc
+ t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc \
+ t-various.moc t-config.moc
AM_LDFLAGS = -no-install
@@ -57,6 +58,8 @@ t_tofuinfo_SOURCES = t-tofuinfo.cpp $(support_src)
t_encrypt_SOURCES = t-encrypt.cpp $(support_src)
t_wkspublish_SOURCES = t-wkspublish.cpp $(support_src)
t_verify_SOURCES = t-verify.cpp $(support_src)
+t_various_SOURCES = t-various.cpp $(support_src)
+t_config_SOURCES = t-config.cpp $(support_src)
run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp
nodist_t_keylist_SOURCES = $(moc_files)
@@ -64,12 +67,12 @@ nodist_t_keylist_SOURCES = $(moc_files)
BUILT_SOURCES = $(moc_files)
noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt \
- run-keyformailboxjob t-wkspublish t-verify
+ run-keyformailboxjob t-wkspublish t-verify t-various t-config
CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \
random_seed S.gpg-agent .gpg-v21-migrated pubring-stamp $(moc_files) \
- gpg.conf
+ gpg.conf tofu.db
clean-local:
-rm -fR private-keys-v1.d crls.d
diff --git a/lang/qt/tests/Makefile.in b/lang/qt/tests/Makefile.in
index e0ac22e..f370058 100644
--- a/lang/qt/tests/Makefile.in
+++ b/lang/qt/tests/Makefile.in
@@ -98,11 +98,11 @@ build_triplet = @build@
host_triplet = @host@
TESTS = initial.test t-keylist$(EXEEXT) t-keylocate$(EXEEXT) \
t-ownertrust$(EXEEXT) t-tofuinfo$(EXEEXT) t-encrypt$(EXEEXT) \
- t-verify$(EXEEXT)
+ t-verify$(EXEEXT) t-various$(EXEEXT) t-config$(EXEEXT)
noinst_PROGRAMS = t-keylist$(EXEEXT) t-keylocate$(EXEEXT) \
t-ownertrust$(EXEEXT) t-tofuinfo$(EXEEXT) t-encrypt$(EXEEXT) \
run-keyformailboxjob$(EXEEXT) t-wkspublish$(EXEEXT) \
- t-verify$(EXEEXT)
+ t-verify$(EXEEXT) t-various$(EXEEXT) t-config$(EXEEXT)
subdir = lang/qt/tests
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/build-aux/mkinstalldirs \
@@ -117,8 +117,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
@@ -136,6 +136,11 @@ am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
am__objects_1 = t-support.$(OBJEXT)
+am_t_config_OBJECTS = t-config.$(OBJEXT) $(am__objects_1)
+t_config_OBJECTS = $(am_t_config_OBJECTS)
+t_config_LDADD = $(LDADD)
+t_config_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \
+ ../src/libqgpgme.la ../../../src/libgpgme.la
am_t_encrypt_OBJECTS = t-encrypt.$(OBJEXT) $(am__objects_1)
t_encrypt_OBJECTS = $(am_t_encrypt_OBJECTS)
t_encrypt_LDADD = $(LDADD)
@@ -164,6 +169,11 @@ t_tofuinfo_OBJECTS = $(am_t_tofuinfo_OBJECTS)
t_tofuinfo_LDADD = $(LDADD)
t_tofuinfo_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \
../src/libqgpgme.la ../../../src/libgpgme.la
+am_t_various_OBJECTS = t-various.$(OBJEXT) $(am__objects_1)
+t_various_OBJECTS = $(am_t_various_OBJECTS)
+t_various_LDADD = $(LDADD)
+t_various_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \
+ ../src/libqgpgme.la ../../../src/libgpgme.la
am_t_verify_OBJECTS = t-verify.$(OBJEXT) $(am__objects_1)
t_verify_OBJECTS = $(am_t_verify_OBJECTS)
t_verify_LDADD = $(LDADD)
@@ -226,15 +236,17 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
-SOURCES = $(run_keyformailboxjob_SOURCES) $(t_encrypt_SOURCES) \
- $(t_keylist_SOURCES) $(nodist_t_keylist_SOURCES) \
+SOURCES = $(run_keyformailboxjob_SOURCES) $(t_config_SOURCES) \
+ $(t_encrypt_SOURCES) $(t_keylist_SOURCES) \
+ $(nodist_t_keylist_SOURCES) $(t_keylocate_SOURCES) \
+ $(t_ownertrust_SOURCES) $(t_tofuinfo_SOURCES) \
+ $(t_various_SOURCES) $(t_verify_SOURCES) \
+ $(t_wkspublish_SOURCES)
+DIST_SOURCES = $(run_keyformailboxjob_SOURCES) $(t_config_SOURCES) \
+ $(t_encrypt_SOURCES) $(t_keylist_SOURCES) \
$(t_keylocate_SOURCES) $(t_ownertrust_SOURCES) \
- $(t_tofuinfo_SOURCES) $(t_verify_SOURCES) \
+ $(t_tofuinfo_SOURCES) $(t_various_SOURCES) $(t_verify_SOURCES) \
$(t_wkspublish_SOURCES)
-DIST_SOURCES = $(run_keyformailboxjob_SOURCES) $(t_encrypt_SOURCES) \
- $(t_keylist_SOURCES) $(t_keylocate_SOURCES) \
- $(t_ownertrust_SOURCES) $(t_tofuinfo_SOURCES) \
- $(t_verify_SOURCES) $(t_wkspublish_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -481,7 +493,8 @@ GPG = gpg
TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir)
EXTRA_DIST = initial.test
moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \
- t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc
+ t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc \
+ t-various.moc t-config.moc
AM_LDFLAGS = -no-install
LDADD = ../../cpp/src/libgpgmepp.la ../src/libqgpgme.la \
@@ -502,13 +515,15 @@ t_tofuinfo_SOURCES = t-tofuinfo.cpp $(support_src)
t_encrypt_SOURCES = t-encrypt.cpp $(support_src)
t_wkspublish_SOURCES = t-wkspublish.cpp $(support_src)
t_verify_SOURCES = t-verify.cpp $(support_src)
+t_various_SOURCES = t-various.cpp $(support_src)
+t_config_SOURCES = t-config.cpp $(support_src)
run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp
nodist_t_keylist_SOURCES = $(moc_files)
BUILT_SOURCES = $(moc_files)
CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \
random_seed S.gpg-agent .gpg-v21-migrated pubring-stamp $(moc_files) \
- gpg.conf
+ gpg.conf tofu.db
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -559,6 +574,10 @@ run-keyformailboxjob$(EXEEXT): $(run_keyformailboxjob_OBJECTS) $(run_keyformailb
@rm -f run-keyformailboxjob$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(run_keyformailboxjob_OBJECTS) $(run_keyformailboxjob_LDADD) $(LIBS)
+t-config$(EXEEXT): $(t_config_OBJECTS) $(t_config_DEPENDENCIES) $(EXTRA_t_config_DEPENDENCIES)
+ @rm -f t-config$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(t_config_OBJECTS) $(t_config_LDADD) $(LIBS)
+
t-encrypt$(EXEEXT): $(t_encrypt_OBJECTS) $(t_encrypt_DEPENDENCIES) $(EXTRA_t_encrypt_DEPENDENCIES)
@rm -f t-encrypt$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(t_encrypt_OBJECTS) $(t_encrypt_LDADD) $(LIBS)
@@ -579,6 +598,10 @@ t-tofuinfo$(EXEEXT): $(t_tofuinfo_OBJECTS) $(t_tofuinfo_DEPENDENCIES) $(EXTRA_t_
@rm -f t-tofuinfo$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(t_tofuinfo_OBJECTS) $(t_tofuinfo_LDADD) $(LIBS)
+t-various$(EXEEXT): $(t_various_OBJECTS) $(t_various_DEPENDENCIES) $(EXTRA_t_various_DEPENDENCIES)
+ @rm -f t-various$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(t_various_OBJECTS) $(t_various_LDADD) $(LIBS)
+
t-verify$(EXEEXT): $(t_verify_OBJECTS) $(t_verify_DEPENDENCIES) $(EXTRA_t_verify_DEPENDENCIES)
@rm -f t-verify$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(t_verify_OBJECTS) $(t_verify_LDADD) $(LIBS)
@@ -594,12 +617,14 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-keyformailboxjob.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-config.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-encrypt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-keylist.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-keylocate.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-ownertrust.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-support.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-tofuinfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-various.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-verify.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-wkspublish.Po@am__quote@
diff --git a/lang/qt/tests/t-config.cpp b/lang/qt/tests/t-config.cpp
new file mode 100644
index 0000000..0a7df22
--- /dev/null
+++ b/lang/qt/tests/t-config.cpp
@@ -0,0 +1,94 @@
+/* t-config.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2016 Intevation GmbH
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <QDebug>
+#include <QTest>
+#include <QTemporaryDir>
+#include "t-support.h"
+#include "protocol.h"
+#include "cryptoconfig.h"
+#include <unistd.h>
+
+using namespace QGpgME;
+
+class CryptoConfigTest: public QGpgMETest
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void testKeyserver()
+ {
+ // Repeatedly set a config value and clear it
+ // this war broken at some point so it gets a
+ // unit test.
+ for (int i = 0; i < 10; i++) {
+ auto conf = cryptoConfig();
+ QVERIFY(conf);
+ auto entry = conf->entry(QStringLiteral("gpg"),
+ QStringLiteral("Keyserver"),
+ QStringLiteral("keyserver"));
+ QVERIFY(entry);
+ const QString url(QStringLiteral("hkp://foo.bar.baz"));
+ entry->setStringValue(url);
+ conf->sync(false);
+ conf->clear();
+ entry = conf->entry(QStringLiteral("gpg"),
+ QStringLiteral("Keyserver"),
+ QStringLiteral("keyserver"));
+ QCOMPARE (entry->stringValue(), url);
+ entry->setStringValue(QString());
+ conf->sync(false);
+ conf->clear();
+ entry = conf->entry(QStringLiteral("gpg"),
+ QStringLiteral("Keyserver"),
+ QStringLiteral("keyserver"));
+ QCOMPARE (entry->stringValue(), QString());
+ }
+ }
+
+ void initTestCase()
+ {
+ QGpgMETest::initTestCase();
+ const QString gpgHome = qgetenv("GNUPGHOME");
+ qputenv("GNUPGHOME", mDir.path().toUtf8());
+ QVERIFY(mDir.isValid());
+ }
+private:
+ QTemporaryDir mDir;
+
+};
+
+QTEST_MAIN(CryptoConfigTest)
+
+#include "t-config.moc"
diff --git a/lang/qt/tests/t-encrypt.cpp b/lang/qt/tests/t-encrypt.cpp
index 4d65dc7..a2d8dc4 100644
--- a/lang/qt/tests/t-encrypt.cpp
+++ b/lang/qt/tests/t-encrypt.cpp
@@ -39,6 +39,8 @@
#include <QBuffer>
#include "keylistjob.h"
#include "encryptjob.h"
+#include "signencryptjob.h"
+#include "signingresult.h"
#include "qgpgmeencryptjob.h"
#include "encryptionresult.h"
#include "decryptionresult.h"
@@ -46,6 +48,7 @@
#include "qgpgmebackend.h"
#include "keylistresult.h"
#include "engineinfo.h"
+#include "verifyopaquejob.h"
#include "t-support.h"
#define PROGRESS_TEST_SIZE 1 * 1024 * 1024
@@ -85,18 +88,18 @@ private Q_SLOTS:
std::vector<Key> keys;
auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa@example.net"),
false, keys);
- Q_ASSERT(!keylistresult.error());
- Q_ASSERT(keys.size() == 1);
+ QVERIFY(!keylistresult.error());
+ QVERIFY(keys.size() == 1);
delete listjob;
auto job = openpgp()->encryptJob(/*ASCII Armor */true, /* Textmode */ true);
- Q_ASSERT(job);
+ QVERIFY(job);
QByteArray cipherText;
auto result = job->exec(keys, QStringLiteral("Hello World").toUtf8(), Context::AlwaysTrust, cipherText);
delete job;
- Q_ASSERT(!result.error());
+ QVERIFY(!result.error());
const auto cipherString = QString::fromUtf8(cipherText);
- Q_ASSERT(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
+ QVERIFY(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
/* Now decrypt */
if (!decryptSupported()) {
@@ -109,8 +112,8 @@ private Q_SLOTS:
auto decJob = new QGpgMEDecryptJob(ctx);
QByteArray plainText;
auto decResult = decJob->exec(cipherText, plainText);
- Q_ASSERT(!result.error());
- Q_ASSERT(QString::fromUtf8(plainText) == QStringLiteral("Hello World"));
+ QVERIFY(!decResult.error());
+ QVERIFY(QString::fromUtf8(plainText) == QStringLiteral("Hello World"));
delete decJob;
}
@@ -125,12 +128,12 @@ private Q_SLOTS:
std::vector<Key> keys;
auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa@example.net"),
false, keys);
- Q_ASSERT(!keylistresult.error());
- Q_ASSERT(keys.size() == 1);
+ QVERIFY(!keylistresult.error());
+ QVERIFY(keys.size() == 1);
delete listjob;
auto job = openpgp()->encryptJob(/*ASCII Armor */false, /* Textmode */ false);
- Q_ASSERT(job);
+ QVERIFY(job);
QByteArray plainBa;
plainBa.fill('X', PROGRESS_TEST_SIZE);
QByteArray cipherText;
@@ -140,21 +143,21 @@ private Q_SLOTS:
connect(job, &Job::progress, this, [this, &initSeen, &finishSeen] (const QString&, int current, int total) {
// We only check for progress 0 and max progress as the other progress
// lines depend on the system speed and are as such unreliable to test.
- Q_ASSERT(total == PROGRESS_TEST_SIZE);
+ QVERIFY(total == PROGRESS_TEST_SIZE);
if (current == 0) {
initSeen = true;
}
if (current == total) {
finishSeen = true;
}
- Q_ASSERT(current >= 0 && current <= total);
+ QVERIFY(current >= 0 && current <= total);
});
connect(job, &EncryptJob::result, this, [this, &initSeen, &finishSeen] (const GpgME::EncryptionResult &,
const QByteArray &,
const QString,
const GpgME::Error) {
- Q_ASSERT(initSeen);
- Q_ASSERT(finishSeen);
+ QVERIFY(initSeen);
+ QVERIFY(finishSeen);
Q_EMIT asyncDone();
});
@@ -165,7 +168,7 @@ private Q_SLOTS:
job->start(keys, inptr, outptr, Context::AlwaysTrust);
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
}
void testSymmetricEncryptDecrypt()
@@ -183,9 +186,9 @@ private Q_SLOTS:
QByteArray cipherText;
auto result = job->exec(std::vector<Key>(), QStringLiteral("Hello symmetric World").toUtf8(), Context::AlwaysTrust, cipherText);
delete job;
- Q_ASSERT(!result.error());
+ QVERIFY(!result.error());
const auto cipherString = QString::fromUtf8(cipherText);
- Q_ASSERT(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
+ QVERIFY(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
killAgent(mDir.path());
@@ -195,12 +198,76 @@ private Q_SLOTS:
auto decJob = new QGpgMEDecryptJob(ctx2);
QByteArray plainText;
auto decResult = decJob->exec(cipherText, plainText);
- Q_ASSERT(!result.error());
- Q_ASSERT(QString::fromUtf8(plainText) == QStringLiteral("Hello symmetric World"));
+ QVERIFY(!result.error());
+ QVERIFY(QString::fromUtf8(plainText) == QStringLiteral("Hello symmetric World"));
delete decJob;
}
private:
+ /* This apparently does not work under ASAN currently. TODO fix and reeanble */
+ void testEncryptDecryptNowrap()
+ {
+ /* Now decrypt */
+ if (!decryptSupported()) {
+ return;
+ }
+ auto listjob = openpgp()->keyListJob(false, false, false);
+ std::vector<Key> keys;
+ auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa@example.net"),
+ false, keys);
+ QVERIFY(!keylistresult.error());
+ QVERIFY(keys.size() == 1);
+ delete listjob;
+
+ auto job = openpgp()->signEncryptJob(/*ASCII Armor */true, /* Textmode */ true);
+
+ auto encSignCtx = Job::context(job);
+ TestPassphraseProvider provider1;
+ encSignCtx->setPassphraseProvider(&provider1);
+ encSignCtx->setPinentryMode(Context::PinentryLoopback);
+
+ QVERIFY(job);
+ QByteArray cipherText;
+ auto result = job->exec(keys, keys, QStringLiteral("Hello World").toUtf8(), Context::AlwaysTrust, cipherText);
+ delete job;
+ QVERIFY(!result.first.error());
+ QVERIFY(!result.second.error());
+ const auto cipherString = QString::fromUtf8(cipherText);
+ QVERIFY(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
+
+ /* Now decrypt */
+ if (!decryptSupported()) {
+ return;
+ }
+ auto ctx = Context::createForProtocol(OpenPGP);
+ TestPassphraseProvider provider;
+ ctx->setPassphraseProvider(&provider);
+ ctx->setPinentryMode(Context::PinentryLoopback);
+ ctx->setDecryptionFlags(Context::DecryptUnwrap);
+
+ auto decJob = new QGpgMEDecryptJob(ctx);
+ QByteArray plainText;
+ auto decResult = decJob->exec(cipherText, plainText);
+
+ QVERIFY(!decResult.error());
+
+ delete decJob;
+
+ // Now verify the unwrapeped data.
+ auto verifyJob = openpgp()->verifyOpaqueJob(true);
+ QByteArray verified;
+
+ auto verResult = verifyJob->exec(plainText, verified);
+ QVERIFY(!verResult.error());
+ delete verifyJob;
+
+ QVERIFY(verResult.numSignatures() == 1);
+ auto sig = verResult.signatures()[0];
+
+ QVERIFY(verified == QStringLiteral("Hello World"));
+ }
+
+private:
/* Loopback and passphrase provider don't work for mixed encryption.
* So this test is disabled until gnupg(?) is fixed for this. */
void testMixedEncryptDecrypt()
@@ -212,8 +279,8 @@ private:
std::vector<Key> keys;
auto keylistresult = listjob->exec(QStringList() << QStringLiteral("alfa@example.net"),
false, keys);
- Q_ASSERT(!keylistresult.error());
- Q_ASSERT(keys.size() == 1);
+ QVERIFY(!keylistresult.error());
+ QVERIFY(keys.size() == 1);
delete listjob;
auto ctx = Context::createForProtocol(OpenPGP);
@@ -229,10 +296,10 @@ private:
cipherText);
printf("After exec\n");
delete job;
- Q_ASSERT(!result.error());
+ QVERIFY(!result.error());
printf("Cipher:\n%s\n", cipherText.constData());
const auto cipherString = QString::fromUtf8(cipherText);
- Q_ASSERT(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
+ QVERIFY(cipherString.startsWith("-----BEGIN PGP MESSAGE-----"));
killAgent(mDir.path());
@@ -240,7 +307,7 @@ private:
QTemporaryDir tmp;
qputenv("GNUPGHOME", tmp.path().toUtf8());
QFile agentConf(tmp.path() + QStringLiteral("/gpg-agent.conf"));
- Q_ASSERT(agentConf.open(QIODevice::WriteOnly));
+ QVERIFY(agentConf.open(QIODevice::WriteOnly));
agentConf.write("allow-loopback-pinentry");
agentConf.close();
@@ -251,9 +318,9 @@ private:
auto decJob = new QGpgMEDecryptJob(ctx2);
QByteArray plainText;
auto decResult = decJob->exec(cipherText, plainText);
- Q_ASSERT(!decResult.error());
+ QVERIFY(!decResult.error());
qDebug() << "Plain: " << plainText;
- Q_ASSERT(QString::fromUtf8(plainText) == QStringLiteral("Hello symmetric World"));
+ QVERIFY(QString::fromUtf8(plainText) == QStringLiteral("Hello symmetric World"));
delete decJob;
killAgent(tmp.path());
@@ -267,12 +334,12 @@ public Q_SLOT:
QGpgMETest::initTestCase();
const QString gpgHome = qgetenv("GNUPGHOME");
qputenv("GNUPGHOME", mDir.path().toUtf8());
- Q_ASSERT(mDir.isValid());
+ QVERIFY(mDir.isValid());
QFile agentConf(mDir.path() + QStringLiteral("/gpg-agent.conf"));
- Q_ASSERT(agentConf.open(QIODevice::WriteOnly));
+ QVERIFY(agentConf.open(QIODevice::WriteOnly));
agentConf.write("allow-loopback-pinentry");
agentConf.close();
- Q_ASSERT(copyKeyrings(gpgHome, mDir.path()));
+ QVERIFY(copyKeyrings(gpgHome, mDir.path()));
}
private:
diff --git a/lang/qt/tests/t-keylist.cpp b/lang/qt/tests/t-keylist.cpp
index 2578576..a140236 100644
--- a/lang/qt/tests/t-keylist.cpp
+++ b/lang/qt/tests/t-keylist.cpp
@@ -61,14 +61,14 @@ private Q_SLOTS:
GpgME::KeyListResult result = job->exec(QStringList() << QStringLiteral("alfa@example.net"),
false, keys);
delete job;
- Q_ASSERT (!result.error());
- Q_ASSERT (keys.size() == 1);
+ QVERIFY (!result.error());
+ QVERIFY (keys.size() == 1);
const QString kId = QLatin1String(keys.front().keyID());
- Q_ASSERT (kId == QStringLiteral("2D727CC768697734"));
+ QVERIFY (kId == QStringLiteral("2D727CC768697734"));
- Q_ASSERT (keys[0].subkeys().size() == 2);
- Q_ASSERT (keys[0].subkeys()[0].publicKeyAlgorithm() == Subkey::AlgoDSA);
- Q_ASSERT (keys[0].subkeys()[1].publicKeyAlgorithm() == Subkey::AlgoELG_E);
+ QVERIFY (keys[0].subkeys().size() == 2);
+ QVERIFY (keys[0].subkeys()[0].publicKeyAlgorithm() == Subkey::AlgoDSA);
+ QVERIFY (keys[0].subkeys()[1].publicKeyAlgorithm() == Subkey::AlgoELG_E);
}
void testPubkeyAlgoAsString()
@@ -87,7 +87,7 @@ private Q_SLOTS:
{ Subkey::AlgoUnknown, QString() }
};
Q_FOREACH (Subkey::PubkeyAlgo algo, expected.keys()) {
- Q_ASSERT(QString::fromUtf8(Subkey::publicKeyAlgorithmAsString(algo)) ==
+ QVERIFY(QString::fromUtf8(Subkey::publicKeyAlgorithmAsString(algo)) ==
expected.value(algo));
}
}
@@ -97,12 +97,12 @@ private Q_SLOTS:
KeyListJob *job = openpgp()->keyListJob();
connect(job, &KeyListJob::result, job, [this, job](KeyListResult, std::vector<Key> keys, QString, Error)
{
- Q_ASSERT(keys.size() == 1);
+ QVERIFY(keys.size() == 1);
Q_EMIT asyncDone();
});
job->start(QStringList() << "alfa@example.net");
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
}
};
diff --git a/lang/qt/tests/t-keylocate.cpp b/lang/qt/tests/t-keylocate.cpp
index 63cb836..8c99c8b 100644
--- a/lang/qt/tests/t-keylocate.cpp
+++ b/lang/qt/tests/t-keylocate.cpp
@@ -63,7 +63,7 @@ private Q_SLOTS:
qputenv("GNUPGHOME", dir.path().toUtf8());
/* Could do this with gpgconf but this is not a gpgconf test ;-) */
QFile conf(dir.path() + QStringLiteral("/gpg.conf"));
- Q_ASSERT(conf.open(QIODevice::WriteOnly));
+ QVERIFY(conf.open(QIODevice::WriteOnly));
conf.write("auto-key-locate dane");
conf.close();
@@ -71,11 +71,11 @@ private Q_SLOTS:
mTestpattern = QStringLiteral("wk@gnupg.org");
connect(job, &KeyListJob::result, job, [this, job](KeyListResult result, std::vector<Key> keys, QString, Error)
{
- Q_ASSERT(!result.error());
- Q_ASSERT(keys.size() == 1);
+ QVERIFY(!result.error());
+ QVERIFY(keys.size() == 1);
Key k = keys.front();
- Q_ASSERT(k.numUserIDs());
+ QVERIFY(k.numUserIDs());
bool found = false;
Q_FOREACH (const UserID uid, k.userIDs()) {
const QString mailBox = QString::fromUtf8(uid.email());
@@ -83,12 +83,12 @@ private Q_SLOTS:
found = true;
}
}
- Q_ASSERT(found);
+ QVERIFY(found);
Q_EMIT asyncDone();
});
job->start(QStringList() << mTestpattern);
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
qputenv("GNUPGHOME", oldHome.toUtf8());
}
#endif
@@ -103,13 +103,13 @@ private Q_SLOTS:
connect(job, &KeyListJob::result, job, [this, job](KeyListResult result, std::vector<Key> keys, QString, Error)
{
- Q_ASSERT(!result.isNull());
- Q_ASSERT(!result.isTruncated());
- Q_ASSERT(!result.error());
- Q_ASSERT(keys.size() == 1);
+ QVERIFY(!result.isNull());
+ QVERIFY(!result.isTruncated());
+ QVERIFY(!result.error());
+ QVERIFY(keys.size() == 1);
Key k = keys.front();
- Q_ASSERT(k.numUserIDs());
+ QVERIFY(k.numUserIDs());
bool found = false;
Q_FOREACH (const UserID uid, k.userIDs()) {
const QString mailBox = QString::fromUtf8(uid.email());
@@ -117,12 +117,12 @@ private Q_SLOTS:
found = true;
}
}
- Q_ASSERT(found);
+ QVERIFY(found);
Q_EMIT asyncDone();
});
job->start(QStringList() << mTestpattern);
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
}
private:
diff --git a/lang/qt/tests/t-ownertrust.cpp b/lang/qt/tests/t-ownertrust.cpp
index db863b2..e9a4378 100644
--- a/lang/qt/tests/t-ownertrust.cpp
+++ b/lang/qt/tests/t-ownertrust.cpp
@@ -62,10 +62,10 @@ private Q_SLOTS:
GpgME::KeyListResult result = job->exec(QStringList() << QStringLiteral("alfa@example.net"),
false, keys);
delete job;
- Q_ASSERT (!result.error());
- Q_ASSERT (keys.size() == 1);
+ QVERIFY (!result.error());
+ QVERIFY (keys.size() == 1);
Key key = keys.front();
- Q_ASSERT (key.ownerTrust() == Key::Unknown);
+ QVERIFY (key.ownerTrust() == Key::Unknown);
ChangeOwnerTrustJob *job2 = openpgp()->changeOwnerTrustJob();
connect(job2, &ChangeOwnerTrustJob::result, this, [this](Error e)
@@ -73,28 +73,28 @@ private Q_SLOTS:
if (e) {
qDebug() << "Error in result: " << e.asString();
}
- Q_ASSERT(!e);
+ QVERIFY(!e);
Q_EMIT asyncDone();
});
job2->start(key, Key::Ultimate);
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
job = openpgp()->keyListJob(false, true, true);
result = job->exec(QStringList() << QStringLiteral("alfa@example.net"),
false, keys);
delete job;
key = keys.front();
- Q_ASSERT (key.ownerTrust() == Key::Ultimate);
+ QVERIFY (key.ownerTrust() == Key::Ultimate);
ChangeOwnerTrustJob *job3 = openpgp()->changeOwnerTrustJob();
connect(job3, &ChangeOwnerTrustJob::result, this, [this](Error e)
{
- Q_ASSERT(!e);
+ QVERIFY(!e);
Q_EMIT asyncDone();
});
job3->start(key, Key::Unknown);
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
job = openpgp()->keyListJob(false, true, true);
result = job->exec(QStringList() << QStringLiteral("alfa@example.net"),
@@ -102,7 +102,7 @@ private Q_SLOTS:
delete job;
key = keys.front();
- Q_ASSERT (key.ownerTrust() == Key::Unknown);
+ QVERIFY (key.ownerTrust() == Key::Unknown);
}
};
diff --git a/lang/qt/tests/t-support.cpp b/lang/qt/tests/t-support.cpp
index 857d0a3..b3a7a70 100644
--- a/lang/qt/tests/t-support.cpp
+++ b/lang/qt/tests/t-support.cpp
@@ -34,6 +34,7 @@
#endif
#include "t-support.h"
+#include "context.h"
#include <QTest>
@@ -44,6 +45,7 @@
void QGpgMETest::initTestCase()
{
+ GpgME::initializeLibrary();
const QString gpgHome = qgetenv("GNUPGHOME");
QVERIFY2(!gpgHome.isEmpty(), "GNUPGHOME environment variable is not set.");
}
diff --git a/lang/qt/tests/t-support.h b/lang/qt/tests/t-support.h
index 704fab4..b03b05d 100644
--- a/lang/qt/tests/t-support.h
+++ b/lang/qt/tests/t-support.h
@@ -34,6 +34,8 @@
#include "interfaces/passphraseprovider.h"
#include <QObject>
+#include <gpg-error.h>
+
namespace GpgME
{
class TestPassphraseProvider : public PassphraseProvider
@@ -42,7 +44,9 @@ public:
char *getPassphrase(const char * /*useridHint*/, const char * /*description*/,
bool /*previousWasBad*/, bool &/*canceled*/) Q_DECL_OVERRIDE
{
- return strdup("abc");
+ char *ret;
+ gpgrt_asprintf(&ret, "abc");
+ return ret;
}
};
} // namespace GpgME
@@ -60,4 +64,8 @@ public Q_SLOTS:
void cleanupTestCase();
};
+/* Timeout, in milliseconds, for use with QSignalSpy to wait on
+ signals. */
+#define QSIGNALSPY_TIMEOUT 60000
+
#endif // T_SUPPORT_H
diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp
index f89e1c2..e16b1fd 100644
--- a/lang/qt/tests/t-tofuinfo.cpp
+++ b/lang/qt/tests/t-tofuinfo.cpp
@@ -35,12 +35,16 @@
#include <QDebug>
#include <QTest>
#include <QTemporaryDir>
+#include <QSignalSpy>
+
#include "protocol.h"
#include "tofuinfo.h"
#include "tofupolicyjob.h"
#include "verifyopaquejob.h"
#include "verificationresult.h"
#include "signingresult.h"
+#include "importjob.h"
+#include "importresult.h"
#include "keylistjob.h"
#include "keylistresult.h"
#include "qgpgmesignjob.h"
@@ -61,10 +65,57 @@ static const char testMsg1[] =
"=Crq6\n"
"-----END PGP MESSAGE-----\n";
+static const char conflictKey1[] = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n"
+"\n"
+"mDMEWG+w/hYJKwYBBAHaRw8BAQdAiq1oStvDYg8ZfFs5DgisYJo8dJxD+C/AA21O\n"
+"K/aif0O0GXRvZnVfY29uZmxpY3RAZXhhbXBsZS5jb22IlgQTFggAPhYhBHoJBLaV\n"
+"DamYAgoa1L5BwMOl/x88BQJYb7D+AhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMB\n"
+"Ah4BAheAAAoJEL5BwMOl/x88GvwA/0SxkbLyAcshGm2PRrPsFQsSVAfwaSYFVmS2\n"
+"cMVIw1PfAQDclRH1Z4MpufK07ju4qI33o4s0UFpVRBuSxt7A4P2ZD7g4BFhvsP4S\n"
+"CisGAQQBl1UBBQEBB0AmVrgaDNJ7K2BSalsRo2EkRJjHGqnp5bBB0tapnF81CQMB\n"
+"CAeIeAQYFggAIBYhBHoJBLaVDamYAgoa1L5BwMOl/x88BQJYb7D+AhsMAAoJEL5B\n"
+"wMOl/x88OR0BAMq4/vmJUORRTmzjHcv/DDrQB030DSq666rlckGIKTShAPoDXM9N\n"
+"0gZK+YzvrinSKZXHmn0aSwmC1/hyPybJPEljBw==\n"
+"=p2Oj\n"
+"-----END PGP PUBLIC KEY BLOCK-----\n";
+
+static const char conflictKey2[] = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n"
+"\n"
+"mDMEWG+xShYJKwYBBAHaRw8BAQdA567gPEPJRpqKnZjlFJMRNUqruRviYMyygfF6\n"
+"6Ok+ygu0GXRvZnVfY29uZmxpY3RAZXhhbXBsZS5jb22IlgQTFggAPhYhBJ5kRh7E\n"
+"I98w8kgUcmkAfYFvqqHsBQJYb7FKAhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMB\n"
+"Ah4BAheAAAoJEGkAfYFvqqHsYR0BAOz8JjYB4VvGkt6noLS3F5TLfsedGwQkBCw5\n"
+"znw/vGZsAQD9DSX+ekwdrN56mNO8ISt5uVS7B1ZQtouNBF+nzcwbDbg4BFhvsUoS\n"
+"CisGAQQBl1UBBQEBB0BFupW8+Xc1ikab8TJqANjQhvFVh6uLsgcK4g9lZgbGXAMB\n"
+"CAeIeAQYFggAIBYhBJ5kRh7EI98w8kgUcmkAfYFvqqHsBQJYb7FKAhsMAAoJEGkA\n"
+"fYFvqqHs15ABALdN3uiV/07cJ3RkNb3WPcijGsto+lECDS11dKEwTMFeAQDx+V36\n"
+"ocbYC/xEuwi3w45oNqGieazzcD/GBbt8OBk3BA==\n"
+"=45IR\n"
+"-----END PGP PUBLIC KEY BLOCK-----\n";
+
+static const char conflictMsg1[] = "-----BEGIN PGP MESSAGE-----\n"
+"\n"
+"owGbwMvMwCG2z/HA4aX/5W0YT3MlMUTkb2xPSizi6ihlYRDjYJAVU2Sp4mTZNpV3\n"
+"5QwmLqkrMLWsTCCFDFycAjCR1vcMf4U0Qrs6qzqfHJ9puGOFduLN2nVmhsumxjBE\n"
+"mdw4lr1ehIWR4QdLuNBpe86PGx1PtNXfVAzm/hu+vfjCp5BVNjPTM9L0eAA=\n"
+"=MfBD\n"
+"-----END PGP MESSAGE-----\n";
+
+static const char conflictMsg2[] = "-----BEGIN PGP MESSAGE-----\n"
+"\n"
+"owGbwMvMwCGWyVDbmL9q4RvG01xJDBH5GyvS8vO5OkpZGMQ4GGTFFFnmpbjJHVG+\n"
+"b/DJQ6QIppaVCaSQgYtTACaySZHhr/SOPrdFJ89KrcwKY5i1XnflXYf2PK76SafK\n"
+"tkxXuXzvJAvDX4kCybuqFk3HXCexz2+IrnZ+5X5EqOnuo3ens2cte+uzlhMA\n"
+"=BIAi\n"
+"-----END PGP MESSAGE-----\n";
+
class TofuInfoTest: public QGpgMETest
{
Q_OBJECT
+Q_SIGNALS:
+ void asyncDone();
+private:
bool testSupported()
{
return !(GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.16");
@@ -72,12 +123,12 @@ class TofuInfoTest: public QGpgMETest
void testTofuCopy(TofuInfo other, const TofuInfo &orig)
{
- Q_ASSERT(!orig.isNull());
- Q_ASSERT(!other.isNull());
- Q_ASSERT(orig.signLast() == other.signLast());
- Q_ASSERT(orig.signCount() == other.signCount());
- Q_ASSERT(orig.validity() == other.validity());
- Q_ASSERT(orig.policy() == other.policy());
+ QVERIFY(!orig.isNull());
+ QVERIFY(!other.isNull());
+ QVERIFY(orig.signLast() == other.signLast());
+ QVERIFY(orig.signCount() == other.signCount());
+ QVERIFY(orig.validity() == other.validity());
+ QVERIFY(orig.policy() == other.policy());
}
void signAndVerify(const QString &what, const GpgME::Key &key, int expected)
@@ -94,10 +145,10 @@ class TofuInfoTest: public QGpgMETest
auto sigResult = job->exec(keys, what.toUtf8(), NormalSignatureMode, signedData);
delete job;
- Q_ASSERT(!sigResult.error());
+ QVERIFY(!sigResult.error());
foreach (const auto uid, keys[0].userIDs()) {
auto info = uid.tofuInfo();
- Q_ASSERT(info.signCount() == expected - 1);
+ QVERIFY(info.signCount() == expected - 1);
}
auto verifyJob = openpgp()->verifyOpaqueJob();
@@ -106,25 +157,25 @@ class TofuInfoTest: public QGpgMETest
auto result = verifyJob->exec(signedData, verified);
delete verifyJob;
- Q_ASSERT(!result.error());
- Q_ASSERT(verified == what.toUtf8());
+ QVERIFY(!result.error());
+ QVERIFY(verified == what.toUtf8());
- Q_ASSERT(result.numSignatures() == 1);
+ QVERIFY(result.numSignatures() == 1);
auto sig = result.signatures()[0];
auto key2 = sig.key();
- Q_ASSERT(!key.isNull());
- Q_ASSERT(!strcmp (key2.primaryFingerprint(), key.primaryFingerprint()));
- Q_ASSERT(!strcmp (key.primaryFingerprint(), sig.fingerprint()));
+ QVERIFY(!key.isNull());
+ QVERIFY(!strcmp (key2.primaryFingerprint(), key.primaryFingerprint()));
+ QVERIFY(!strcmp (key.primaryFingerprint(), sig.fingerprint()));
auto stats = key2.userID(0).tofuInfo();
- Q_ASSERT(!stats.isNull());
+ QVERIFY(!stats.isNull());
if (stats.signCount() != expected) {
std::cout << "################ Key before verify: "
<< key
<< "################ Key after verify: "
<< key2;
}
- Q_ASSERT(stats.signCount() == expected);
+ QVERIFY(stats.signCount() == expected);
}
private Q_SLOTS:
@@ -134,13 +185,13 @@ private Q_SLOTS:
return;
}
TofuInfo tofu;
- Q_ASSERT(tofu.isNull());
- Q_ASSERT(!tofu.description());
- Q_ASSERT(!tofu.signCount());
- Q_ASSERT(!tofu.signLast());
- Q_ASSERT(!tofu.signFirst());
- Q_ASSERT(tofu.validity() == TofuInfo::ValidityUnknown);
- Q_ASSERT(tofu.policy() == TofuInfo::PolicyUnknown);
+ QVERIFY(tofu.isNull());
+ QVERIFY(!tofu.description());
+ QVERIFY(!tofu.signCount());
+ QVERIFY(!tofu.signLast());
+ QVERIFY(!tofu.signFirst());
+ QVERIFY(tofu.validity() == TofuInfo::ValidityUnknown);
+ QVERIFY(tofu.policy() == TofuInfo::PolicyUnknown);
}
void testTofuInfo()
@@ -153,30 +204,30 @@ private Q_SLOTS:
QByteArray plaintext;
auto ctx = Job::context(job);
- Q_ASSERT(ctx);
+ QVERIFY(ctx);
ctx->setSender("alfa@example.net");
auto result = job->exec(data1, plaintext);
delete job;
- Q_ASSERT(!result.isNull());
- Q_ASSERT(!result.error());
- Q_ASSERT(!strcmp(plaintext.constData(), "Just GNU it!\n"));
+ QVERIFY(!result.isNull());
+ QVERIFY(!result.error());
+ QVERIFY(!strcmp(plaintext.constData(), "Just GNU it!\n"));
- Q_ASSERT(result.numSignatures() == 1);
+ QVERIFY(result.numSignatures() == 1);
Signature sig = result.signatures()[0];
/* TOFU is always marginal */
- Q_ASSERT(sig.validity() == Signature::Marginal);
+ QVERIFY(sig.validity() == Signature::Marginal);
auto stats = sig.key().userID(0).tofuInfo();
- Q_ASSERT(!stats.isNull());
- Q_ASSERT(sig.key().primaryFingerprint());
- Q_ASSERT(sig.fingerprint());
- Q_ASSERT(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
- Q_ASSERT(stats.signFirst() == stats.signLast());
- Q_ASSERT(stats.signCount() == 1);
- Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto);
- Q_ASSERT(stats.validity() == TofuInfo::LittleHistory);
+ QVERIFY(!stats.isNull());
+ QVERIFY(sig.key().primaryFingerprint());
+ QVERIFY(sig.fingerprint());
+ QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
+ QVERIFY(stats.signFirst() == stats.signLast());
+ QVERIFY(stats.signCount() == 1);
+ QVERIFY(stats.policy() == TofuInfo::PolicyAuto);
+ QVERIFY(stats.validity() == TofuInfo::LittleHistory);
testTofuCopy(stats, stats);
@@ -186,42 +237,42 @@ private Q_SLOTS:
result = job->exec(data1, plaintext);
delete job;
- Q_ASSERT(!result.isNull());
- Q_ASSERT(!result.error());
+ QVERIFY(!result.isNull());
+ QVERIFY(!result.error());
- Q_ASSERT(result.numSignatures() == 1);
+ QVERIFY(result.numSignatures() == 1);
sig = result.signatures()[0];
/* TOFU is always marginal */
- Q_ASSERT(sig.validity() == Signature::Marginal);
+ QVERIFY(sig.validity() == Signature::Marginal);
stats = sig.key().userID(0).tofuInfo();
- Q_ASSERT(!stats.isNull());
- Q_ASSERT(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
- Q_ASSERT(stats.signFirst() == stats.signLast());
- Q_ASSERT(stats.signCount() == 1);
- Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto);
- Q_ASSERT(stats.validity() == TofuInfo::LittleHistory);
+ QVERIFY(!stats.isNull());
+ QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
+ QVERIFY(stats.signFirst() == stats.signLast());
+ QVERIFY(stats.signCount() == 1);
+ QVERIFY(stats.policy() == TofuInfo::PolicyAuto);
+ QVERIFY(stats.validity() == TofuInfo::LittleHistory);
/* Verify that another call yields the same result */
job = openpgp()->verifyOpaqueJob(true);
result = job->exec(data1, plaintext);
delete job;
- Q_ASSERT(!result.isNull());
- Q_ASSERT(!result.error());
+ QVERIFY(!result.isNull());
+ QVERIFY(!result.error());
- Q_ASSERT(result.numSignatures() == 1);
+ QVERIFY(result.numSignatures() == 1);
sig = result.signatures()[0];
/* TOFU is always marginal */
- Q_ASSERT(sig.validity() == Signature::Marginal);
+ QVERIFY(sig.validity() == Signature::Marginal);
stats = sig.key().userID(0).tofuInfo();
- Q_ASSERT(!stats.isNull());
- Q_ASSERT(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
- Q_ASSERT(stats.signFirst() == stats.signLast());
- Q_ASSERT(stats.signCount() == 1);
- Q_ASSERT(stats.policy() == TofuInfo::PolicyAuto);
- Q_ASSERT(stats.validity() == TofuInfo::LittleHistory);
+ QVERIFY(!stats.isNull());
+ QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
+ QVERIFY(stats.signFirst() == stats.signLast());
+ QVERIFY(stats.signCount() == 1);
+ QVERIFY(stats.policy() == TofuInfo::PolicyAuto);
+ QVERIFY(stats.validity() == TofuInfo::LittleHistory);
}
void testTofuSignCount()
@@ -235,9 +286,9 @@ private Q_SLOTS:
GpgME::KeyListResult result = job->exec(QStringList() << QStringLiteral("zulu@example.net"),
true, keys);
delete job;
- Q_ASSERT(!keys.empty());
+ QVERIFY(!keys.empty());
Key key = keys[0];
- Q_ASSERT(!key.isNull());
+ QVERIFY(!key.isNull());
/* As we sign & verify quickly here we need different
* messages to avoid having them treated as the same
@@ -266,10 +317,10 @@ private Q_SLOTS:
auto result = job->exec(QStringList() << QStringLiteral("zulu@example.net"),
true, keys);
delete job;
- Q_ASSERT(!keys.empty());
+ QVERIFY(!keys.empty());
auto key = keys[0];
- Q_ASSERT(!key.isNull());
- Q_ASSERT(key.userID(0).tofuInfo().isNull());
+ QVERIFY(!key.isNull());
+ QVERIFY(key.userID(0).tofuInfo().isNull());
auto keyCopy = key;
keyCopy.update();
auto sigCnt = keyCopy.userID(0).tofuInfo().signCount();
@@ -285,13 +336,13 @@ private Q_SLOTS:
result = job->exec(QStringList() << QStringLiteral("zulu@example.net"),
true, keys);
delete job;
- Q_ASSERT(!result.error());
- Q_ASSERT(!keys.empty());
+ QVERIFY(!result.error());
+ QVERIFY(!keys.empty());
auto key2 = keys[0];
- Q_ASSERT(!key2.isNull());
+ QVERIFY(!key2.isNull());
auto info = key2.userID(0).tofuInfo();
- Q_ASSERT(!info.isNull());
- Q_ASSERT(info.signCount());
+ QVERIFY(!info.isNull());
+ QVERIFY(info.signCount());
}
void testTofuPolicy()
@@ -326,44 +377,126 @@ private Q_SLOTS:
<< ">\n fpr: " << key.primaryFingerprint();
}
}
- Q_ASSERT(!result.error());
- Q_ASSERT(!keys.empty());
+ QVERIFY(!result.error());
+ QVERIFY(!keys.empty());
auto key = keys[0];
- Q_ASSERT(!key.isNull());
- Q_ASSERT(key.userID(0).tofuInfo().policy() != TofuInfo::PolicyBad);
+ QVERIFY(!key.isNull());
+ QVERIFY(key.userID(0).tofuInfo().policy() != TofuInfo::PolicyBad);
auto *tofuJob = openpgp()->tofuPolicyJob();
auto err = tofuJob->exec(key, TofuInfo::PolicyBad);
- Q_ASSERT(!err);
+ QVERIFY(!err);
result = job->exec(QStringList() << QStringLiteral("bravo@example.net"),
false, keys);
- Q_ASSERT(!keys.empty());
+ QVERIFY(!keys.empty());
key = keys[0];
- Q_ASSERT(key.userID(0).tofuInfo().policy() == TofuInfo::PolicyBad);
+ QVERIFY(key.userID(0).tofuInfo().policy() == TofuInfo::PolicyBad);
err = tofuJob->exec(key, TofuInfo::PolicyGood);
result = job->exec(QStringList() << QStringLiteral("bravo@example.net"),
false, keys);
key = keys[0];
- Q_ASSERT(key.userID(0).tofuInfo().policy() == TofuInfo::PolicyGood);
+ QVERIFY(key.userID(0).tofuInfo().policy() == TofuInfo::PolicyGood);
delete tofuJob;
delete job;
}
+ void testTofuConflict()
+ {
+ if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.19") {
+ return;
+ }
+
+ // Import key 1
+ auto importjob = openpgp()->importJob();
+ connect(importjob, &ImportJob::result, this,
+ [this](ImportResult result, QString, Error)
+ {
+ QVERIFY(!result.error());
+ QVERIFY(!result.imports().empty());
+ QVERIFY(result.numImported());
+ Q_EMIT asyncDone();
+ });
+ importjob->start(QByteArray(conflictKey1));
+ QSignalSpy spy (this, SIGNAL(asyncDone()));
+ QVERIFY(spy.wait());
+
+ // Verify Message 1
+ const QByteArray signedData(conflictMsg1);
+ auto verifyJob = openpgp()->verifyOpaqueJob(true);
+ QByteArray verified;
+ auto result = verifyJob->exec(signedData, verified);
+ delete verifyJob;
+
+ QVERIFY(!result.isNull());
+ QVERIFY(!result.error());
+
+ QVERIFY(result.numSignatures() == 1);
+ auto sig = result.signatures()[0];
+ QVERIFY(sig.validity() == Signature::Marginal);
+
+ auto stats = sig.key().userID(0).tofuInfo();
+ QVERIFY(!stats.isNull());
+ QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
+ QVERIFY(stats.signFirst() == stats.signLast());
+ QVERIFY(stats.signCount() == 1);
+ QVERIFY(stats.policy() == TofuInfo::PolicyAuto);
+ QVERIFY(stats.validity() == TofuInfo::LittleHistory);
+
+ // Import key 2
+ importjob = openpgp()->importJob();
+ connect(importjob, &ImportJob::result, this,
+ [this](ImportResult result, QString, Error)
+ {
+ QVERIFY(!result.error());
+ QVERIFY(!result.imports().empty());
+ QVERIFY(result.numImported());
+ Q_EMIT asyncDone();
+ });
+ importjob->start(QByteArray(conflictKey2));
+ QSignalSpy spy2 (this, SIGNAL(asyncDone()));
+ QVERIFY(spy2.wait());
+
+ // Verify Message 2
+ const QByteArray signedData2(conflictMsg2);
+ QByteArray verified2;
+ verifyJob = openpgp()->verifyOpaqueJob(true);
+ result = verifyJob->exec(signedData2, verified2);
+ delete verifyJob;
+
+ QVERIFY(!result.isNull());
+ QVERIFY(!result.error());
+
+ QVERIFY(result.numSignatures() == 1);
+ sig = result.signatures()[0];
+ QVERIFY(sig.validity() == Signature::Unknown);
+ // TODO activate when implemented
+ // QVERIFY(sig.summary() == Signature::TofuConflict);
+
+ stats = sig.key().userID(0).tofuInfo();
+ QVERIFY(!stats.isNull());
+ QVERIFY(!strcmp(sig.key().primaryFingerprint(), sig.fingerprint()));
+ QVERIFY(stats.signFirst() == stats.signLast());
+ QVERIFY(stats.signCount() == 1);
+ QVERIFY(stats.policy() == TofuInfo::PolicyAsk);
+ QVERIFY(stats.validity() == TofuInfo::Conflict);
+ }
+
+
void initTestCase()
{
QGpgMETest::initTestCase();
const QString gpgHome = qgetenv("GNUPGHOME");
qputenv("GNUPGHOME", mDir.path().toUtf8());
- Q_ASSERT(mDir.isValid());
+ QVERIFY(mDir.isValid());
QFile conf(mDir.path() + QStringLiteral("/gpg.conf"));
- Q_ASSERT(conf.open(QIODevice::WriteOnly));
+ QVERIFY(conf.open(QIODevice::WriteOnly));
conf.write("trust-model tofu+pgp");
conf.close();
QFile agentConf(mDir.path() + QStringLiteral("/gpg-agent.conf"));
- Q_ASSERT(agentConf.open(QIODevice::WriteOnly));
+ QVERIFY(agentConf.open(QIODevice::WriteOnly));
agentConf.write("allow-loopback-pinentry");
agentConf.close();
- Q_ASSERT(copyKeyrings(gpgHome, mDir.path()));
+ QVERIFY(copyKeyrings(gpgHome, mDir.path()));
}
private:
QTemporaryDir mDir;
diff --git a/lang/qt/tests/t-various.cpp b/lang/qt/tests/t-various.cpp
new file mode 100644
index 0000000..35d8da9
--- /dev/null
+++ b/lang/qt/tests/t-various.cpp
@@ -0,0 +1,167 @@
+/* t-various.cpp
+
+ This file is part of qgpgme, the Qt API binding for gpgme
+ Copyright (c) 2017 Intevation GmbH
+
+ QGpgME is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ QGpgME is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <QDebug>
+#include <QTest>
+#include <QSignalSpy>
+#include <QTemporaryDir>
+#include "keylistjob.h"
+#include "protocol.h"
+#include "keylistresult.h"
+#include "context.h"
+#include "engineinfo.h"
+#include "dn.h"
+#include "data.h"
+#include "dataprovider.h"
+
+#include "t-support.h"
+
+using namespace QGpgME;
+using namespace GpgME;
+
+static const char aKey[] = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n"
+"\n"
+"mDMEWG+w/hYJKwYBBAHaRw8BAQdAiq1oStvDYg8ZfFs5DgisYJo8dJxD+C/AA21O\n"
+"K/aif0O0GXRvZnVfY29uZmxpY3RAZXhhbXBsZS5jb22IlgQTFggAPhYhBHoJBLaV\n"
+"DamYAgoa1L5BwMOl/x88BQJYb7D+AhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMB\n"
+"Ah4BAheAAAoJEL5BwMOl/x88GvwA/0SxkbLyAcshGm2PRrPsFQsSVAfwaSYFVmS2\n"
+"cMVIw1PfAQDclRH1Z4MpufK07ju4qI33o4s0UFpVRBuSxt7A4P2ZD7g4BFhvsP4S\n"
+"CisGAQQBl1UBBQEBB0AmVrgaDNJ7K2BSalsRo2EkRJjHGqnp5bBB0tapnF81CQMB\n"
+"CAeIeAQYFggAIBYhBHoJBLaVDamYAgoa1L5BwMOl/x88BQJYb7D+AhsMAAoJEL5B\n"
+"wMOl/x88OR0BAMq4/vmJUORRTmzjHcv/DDrQB030DSq666rlckGIKTShAPoDXM9N\n"
+"0gZK+YzvrinSKZXHmn0aSwmC1/hyPybJPEljBw==\n"
+"=p2Oj\n"
+"-----END PGP PUBLIC KEY BLOCK-----\n";
+
+class TestVarious: public QGpgMETest
+{
+ Q_OBJECT
+
+Q_SIGNALS:
+ void asyncDone();
+
+private Q_SLOTS:
+ void testDN()
+ {
+ DN dn(QStringLiteral("CN=Before\\0DAfter,OU=Test,DC=North America,DC=Fabrikam,DC=COM"));
+ QVERIFY(dn.dn() == QStringLiteral("CN=Before\rAfter,OU=Test,DC=North America,DC=Fabrikam,DC=COM"));
+ QStringList attrOrder;
+ attrOrder << QStringLiteral("DC") << QStringLiteral("OU") << QStringLiteral("CN");
+ dn.setAttributeOrder(attrOrder);
+ QVERIFY(dn.prettyDN() == QStringLiteral("DC=North America,DC=Fabrikam,DC=COM,OU=Test,CN=Before\rAfter"));
+ }
+
+ void testKeyFromFile()
+ {
+ if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.14") {
+ return;
+ }
+ QGpgME::QByteArrayDataProvider dp(aKey);
+ Data data(&dp);
+ const auto keys = data.toKeys();
+ QVERIFY(keys.size() == 1);
+ const auto key = keys[0];
+ QVERIFY(!key.isNull());
+ QVERIFY(key.primaryFingerprint() == QStringLiteral("7A0904B6950DA998020A1AD4BE41C0C3A5FF1F3C"));
+ }
+
+ void testQuickUid()
+ {
+ if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.13") {
+ return;
+ }
+ KeyListJob *job = openpgp()->keyListJob(false, true, true);
+ std::vector<GpgME::Key> keys;
+ GpgME::KeyListResult result = job->exec(QStringList() << QStringLiteral("alfa@example.net"),
+ false, keys);
+ delete job;
+ QVERIFY (!result.error());
+ QVERIFY (keys.size() == 1);
+ Key key = keys.front();
+
+ QVERIFY (key.numUserIDs() == 3);
+ const char uid[] = "Foo Bar (with comment) <foo@bar.baz>";
+
+ auto ctx = Context::createForProtocol(key.protocol());
+ QVERIFY (ctx);
+ TestPassphraseProvider provider;
+ ctx->setPassphraseProvider(&provider);
+ ctx->setPinentryMode(Context::PinentryLoopback);
+
+ QVERIFY(!ctx->addUid(key, uid));
+ delete ctx;
+ key.update();
+
+ QVERIFY (key.numUserIDs() == 4);
+ bool id_found = false;;
+ for (const auto &u: key.userIDs()) {
+ if (!strcmp (u.id(), uid)) {
+ QVERIFY (!u.isRevoked());
+ id_found = true;
+ break;
+ }
+ }
+ QVERIFY (id_found);
+
+ ctx = Context::createForProtocol(key.protocol());
+ QVERIFY (!ctx->revUid(key, uid));
+ delete ctx;
+ key.update();
+
+ bool id_revoked = false;;
+ for (const auto &u: key.userIDs()) {
+ if (!strcmp (u.id(), uid)) {
+ id_revoked = true;
+ break;
+ }
+ }
+ QVERIFY(id_revoked);
+ }
+
+ void initTestCase()
+ {
+ QGpgMETest::initTestCase();
+ const QString gpgHome = qgetenv("GNUPGHOME");
+ QVERIFY(copyKeyrings(gpgHome, mDir.path()));
+ qputenv("GNUPGHOME", mDir.path().toUtf8());
+ }
+
+private:
+ QTemporaryDir mDir;
+};
+
+QTEST_MAIN(TestVarious)
+
+#include "t-various.moc"
diff --git a/lang/qt/tests/t-verify.cpp b/lang/qt/tests/t-verify.cpp
index aedfc19..7caed28 100644
--- a/lang/qt/tests/t-verify.cpp
+++ b/lang/qt/tests/t-verify.cpp
@@ -70,14 +70,14 @@ private Q_SLOTS:
QByteArray verified;
auto result = verifyJob->exec(signedData, verified);
- Q_ASSERT(!result.error());
+ QVERIFY(!result.error());
delete verifyJob;
- Q_ASSERT(result.numSignatures() == 1);
+ QVERIFY(result.numSignatures() == 1);
auto sig = result.signatures()[0];
const auto key = sig.key(true, false);
- Q_ASSERT(!key.isNull());
+ QVERIFY(!key.isNull());
bool found = false;
for (const auto subkey: key.subkeys()) {
@@ -85,7 +85,7 @@ private Q_SLOTS:
found = true;
}
}
- Q_ASSERT(found);
+ QVERIFY(found);
}
};
diff --git a/lang/qt/tests/t-wkspublish.cpp b/lang/qt/tests/t-wkspublish.cpp
index 326ecaa..c51e8f9 100644
--- a/lang/qt/tests/t-wkspublish.cpp
+++ b/lang/qt/tests/t-wkspublish.cpp
@@ -127,12 +127,12 @@ private Q_SLOTS:
auto job = openpgp()->wksPublishJob();
connect(job, &WKSPublishJob::result, this,
[this] (Error err, QByteArray, QByteArray, QString, Error) {
- Q_ASSERT(err);
+ QVERIFY(err);
Q_EMIT asyncDone();
});
job->startCheck ("testuser1@localhost");
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
}
#ifdef DO_ONLINE_TESTS
private Q_SLOTS:
@@ -147,15 +147,15 @@ private:
[this] (Error err, QByteArray, QByteArray, QString, Error) {
if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.0.16") {
std::cout << err;
- Q_ASSERT(err);
+ QVERIFY(err);
} else {
- Q_ASSERT(!err);
+ QVERIFY(!err);
}
Q_EMIT asyncDone();
});
job->startCheck ("testuser1@test.gnupg.org");
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
}
void testWKSPublishErrors() {
@@ -166,13 +166,13 @@ private:
auto job = openpgp()->wksPublishJob();
connect(job, &WKSPublishJob::result, this,
[this] (Error err, QByteArray, QByteArray, QString, Error) {
- Q_ASSERT(err);
+ QVERIFY(err);
Q_EMIT asyncDone();
});
job->startCreate("AB874F24E98EBB8487EE7B170F8E3D97FE7011B7",
QStringLiteral("Foo@bar.baz"));
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
}
void testWKSPublishCreate() {
@@ -199,31 +199,31 @@ private:
connect(keygenjob, &KeyGenerationJob::result, this,
[this, &fpr](KeyGenerationResult result, QByteArray, QString, Error)
{
- Q_ASSERT(!result.error());
+ QVERIFY(!result.error());
fpr = QByteArray(result.fingerprint());
- Q_ASSERT(!fpr.isEmpty());
+ QVERIFY(!fpr.isEmpty());
Q_EMIT asyncDone();
});
keygenjob->start(args);
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
/* Then try to create a request. */
auto job = openpgp()->wksPublishJob();
connect(job, &WKSPublishJob::result, this,
[this] (Error err, QByteArray out, QByteArray, QString, Error) {
- Q_ASSERT(!err);
+ QVERIFY(!err);
Q_EMIT asyncDone();
const QString outstr = QString(out);
- Q_ASSERT(outstr.contains(
+ QVERIFY(outstr.contains(
QStringLiteral("-----BEGIN PGP PUBLIC KEY BLOCK-----")));
- Q_ASSERT(outstr.contains(
+ QVERIFY(outstr.contains(
QStringLiteral("Content-Type: application/pgp-keys")));
- Q_ASSERT(outstr.contains(
+ QVERIFY(outstr.contains(
QStringLiteral("From: " TEST_ADDRESS)));
});
job->startCreate(fpr.constData(), QLatin1String(TEST_ADDRESS));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
}
void testWKSPublishReceive() {
@@ -235,31 +235,31 @@ private:
connect(importjob, &ImportJob::result, this,
[this](ImportResult result, QString, Error)
{
- Q_ASSERT(!result.error());
- Q_ASSERT(!result.imports().empty());
- Q_ASSERT(result.numSecretKeysImported());
+ QVERIFY(!result.error());
+ QVERIFY(!result.imports().empty());
+ QVERIFY(result.numSecretKeysImported());
Q_EMIT asyncDone();
});
importjob->start(QByteArray(testSecKey));
QSignalSpy spy (this, SIGNAL(asyncDone()));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
/* Get a response. */
auto job = openpgp()->wksPublishJob();
connect(job, &WKSPublishJob::result, this,
[this] (Error err, QByteArray out, QByteArray, QString, Error) {
- Q_ASSERT(!err);
+ QVERIFY(!err);
Q_EMIT asyncDone();
const QString outstr = QString(out);
- Q_ASSERT(outstr.contains(
+ QVERIFY(outstr.contains(
QStringLiteral("-----BEGIN PGP MESSAGE-----")));
- Q_ASSERT(outstr.contains(
+ QVERIFY(outstr.contains(
QStringLiteral("Content-Type: multipart/encrypted;")));
- Q_ASSERT(outstr.contains(
+ QVERIFY(outstr.contains(
QStringLiteral("From: " TEST_ADDRESS)));
});
job->startReceive(QByteArray(testResponse));
- Q_ASSERT(spy.wait());
+ QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));
}
void initTestCase()
@@ -267,9 +267,9 @@ private:
QGpgMETest::initTestCase();
const QString gpgHome = qgetenv("GNUPGHOME");
qputenv("GNUPGHOME", mDir.path().toUtf8());
- Q_ASSERT(mDir.isValid());
+ QVERIFY(mDir.isValid());
QFile agentConf(mDir.path() + QStringLiteral("/gpg-agent.conf"));
- Q_ASSERT(agentConf.open(QIODevice::WriteOnly));
+ QVERIFY(agentConf.open(QIODevice::WriteOnly));
agentConf.write("allow-loopback-pinentry");
agentConf.close();
}
diff --git a/m4/ax_python_devel.m4 b/m4/ax_python_devel.m4
index de992c8..b990d5b 100644
--- a/m4/ax_python_devel.m4
+++ b/m4/ax_python_devel.m4
@@ -195,8 +195,11 @@ EOD`
fi
# Make the versioning information available to the compiler
- AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
- [If available, contains the Python version number currently in use.])
+
+ # JW: We don't need it and it interferes with the hack
+ # to detect multiple Pyhton versions
+ #AC_DEFINE_UNQUOTED([HAVE_PYTHON], ["$ac_python_version"],
+ # [If available, contains the Python version number currently in use.])
# First, the library directory:
ac_python_libdir=`cat<<EOD | $PYTHON -
diff --git a/m4/python.m4 b/m4/python.m4
new file mode 100644
index 0000000..822b2dd
--- /dev/null
+++ b/m4/python.m4
@@ -0,0 +1,241 @@
+## ------------------------ -*- Autoconf -*-
+## Python file handling
+## From Andrew Dalke
+## Updated by James Henstridge
+## ------------------------
+# Copyright (C) 1999-2017 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# ---------------------------------------------------------------------------
+# Adds support for distributing Python modules and packages. To
+# install modules, copy them to $(pythondir), using the python_PYTHON
+# automake variable. To install a package with the same name as the
+# automake package, install to $(pkgpythondir), or use the
+# pkgpython_PYTHON automake variable.
+#
+# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
+# locations to install python extension modules (shared libraries).
+# Another macro is required to find the appropriate flags to compile
+# extension modules.
+#
+# If your package is configured with a different prefix to python,
+# users will have to add the install directory to the PYTHONPATH
+# environment variable, or create a .pth file (see the python
+# documentation for details).
+#
+# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will
+# cause an error if the version of python installed on the system
+# doesn't meet the requirement. MINIMUM-VERSION should consist of
+# numbers and dots only.
+AC_DEFUN([AM_PATH_PYTHON],
+ [
+ dnl Find a Python interpreter. Python versions prior to 2.0 are not
+ dnl supported. (2.0 was released on October 16, 2000).
+ m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
+[python2 python2.7 dnl
+ python dnl
+ python3 python3.0 python3.1 python3.2 python3.3 dnl
+ python3.4 python3.5 python3.6 python3.7 python3.8])
+
+ AC_ARG_VAR([PYTHON], [the Python interpreter])
+
+ m4_if([$1],[],[
+ dnl No version check is needed.
+ # Find any Python interpreter.
+ if test -z "$PYTHON"; then
+ AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :)
+ fi
+ am_display_PYTHON=python
+ ], [
+ dnl A version check is needed.
+ if test -n "$PYTHON"; then
+ # If the user set $PYTHON, use it and don't search something else.
+ AC_MSG_CHECKING([whether $PYTHON version is >= $1])
+ AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ AC_MSG_ERROR([Python interpreter is too old])])
+ am_display_PYTHON=$PYTHON
+ else
+ # Otherwise, try each interpreter until we find one that satisfies
+ # VERSION.
+ AC_CACHE_CHECK([for a Python interpreter with version >= $1],
+ [am_cv_pathless_PYTHON],[
+ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do
+ test "$am_cv_pathless_PYTHON" = none && break
+ AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break])
+ done])
+ # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
+ if test "$am_cv_pathless_PYTHON" = none; then
+ PYTHON=:
+ else
+ AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON])
+ fi
+ am_display_PYTHON=$am_cv_pathless_PYTHON
+ fi
+ ])
+
+ if test "$PYTHON" = :; then
+ dnl Run any user-specified action, or abort.
+ m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
+ else
+
+ dnl Query Python for its version number. Getting [:3] seems to be
+ dnl the best way to do this; it's what "site.py" does in the standard
+ dnl library.
+
+ AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
+ [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
+ AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
+
+ dnl Use the values of $prefix and $exec_prefix for the corresponding
+ dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made
+ dnl distinct variables so they can be overridden if need be. However,
+ dnl general consensus is that you shouldn't need this ability.
+
+ AC_SUBST([PYTHON_PREFIX], ['${prefix}'])
+ AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}'])
+
+ dnl At times (like when building shared libraries) you may want
+ dnl to know which OS platform Python thinks this is.
+
+ AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform],
+ [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
+ AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
+
+ # Just factor out some code duplication.
+ am_python_setup_sysconfig="\
+import sys
+# Prefer sysconfig over distutils.sysconfig, for better compatibility
+# with python 3.x. See automake bug#10227.
+try:
+ import sysconfig
+except ImportError:
+ can_use_sysconfig = 0
+else:
+ can_use_sysconfig = 1
+# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
+# <https://github.com/pypa/virtualenv/issues/118>
+try:
+ from platform import python_implementation
+ if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
+ can_use_sysconfig = 0
+except ImportError:
+ pass"
+
+ dnl Set up 4 directories:
+
+ dnl pythondir -- where to install python scripts. This is the
+ dnl site-packages directory, not the python standard library
+ dnl directory like in previous automake betas. This behavior
+ dnl is more consistent with lispdir.m4 for example.
+ dnl Query distutils for this directory.
+ AC_CACHE_CHECK([for $am_display_PYTHON script directory],
+ [am_cv_python_pythondir],
+ [if test "x$prefix" = xNONE
+ then
+ am_py_prefix=$ac_default_prefix
+ else
+ am_py_prefix=$prefix
+ fi
+ am_cv_python_pythondir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+ sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
+else:
+ from distutils import sysconfig
+ sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
+ case $am_cv_python_pythondir in
+ $am_py_prefix*)
+ am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
+ am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
+ ;;
+ *)
+ case $am_py_prefix in
+ /usr|/System*) ;;
+ *)
+ am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
+ ;;
+ esac
+ ;;
+ esac
+ ])
+ AC_SUBST([pythondir], [$am_cv_python_pythondir])
+
+ dnl pkgpythondir -- $PACKAGE directory under pythondir. Was
+ dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is
+ dnl more consistent with the rest of automake.
+
+ AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE])
+
+ dnl pyexecdir -- directory for installing python extension modules
+ dnl (shared libraries)
+ dnl Query distutils for this directory.
+ AC_CACHE_CHECK([for $am_display_PYTHON extension module directory],
+ [am_cv_python_pyexecdir],
+ [if test "x$exec_prefix" = xNONE
+ then
+ am_py_exec_prefix=$am_py_prefix
+ else
+ am_py_exec_prefix=$exec_prefix
+ fi
+ am_cv_python_pyexecdir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+ sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
+else:
+ from distutils import sysconfig
+ sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
+ case $am_cv_python_pyexecdir in
+ $am_py_exec_prefix*)
+ am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
+ am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
+ ;;
+ *)
+ case $am_py_exec_prefix in
+ /usr|/System*) ;;
+ *)
+ am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
+ ;;
+ esac
+ ;;
+ esac
+ ])
+ AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir])
+
+ dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE)
+
+ AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE])
+
+ dnl Run any user-specified action.
+ $2
+ fi
+
+])
+
+
+# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+# ---------------------------------------------------------------------------
+# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION.
+# Run ACTION-IF-FALSE otherwise.
+# This test uses sys.hexversion instead of the string equivalent (first
+# word of sys.version), in order to cope with versions such as 2.2c1.
+# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000).
+AC_DEFUN([AM_PYTHON_CHECK_VERSION],
+ [prog="import sys
+# split strings by '.' and convert to numeric. Append some zeros
+# because we need at least 4 digits for the hex conversion.
+# map returns an iterator in Python 3.0 and a list in 2.x
+minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]]
+minverhex = 0
+# xrange is not present in Python 3.0 and range returns an iterator
+for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
+sys.exit(sys.hexversion < minverhex)"
+ AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
diff --git a/m4/qt.m4 b/m4/qt.m4
index e7aac41..700f4e0 100644
--- a/m4/qt.m4
+++ b/m4/qt.m4
@@ -32,18 +32,18 @@ AC_DEFUN([FIND_QT],
AC_CHECK_TOOL(MOC, moc)
AC_MSG_CHECKING([moc version])
mocversion=`$MOC -v 2>&1`
- mocversiongrep=`echo $mocversion | grep "Qt 5\|moc 5"`
+ mocversiongrep=`echo $mocversion | grep -E "Qt 5|moc 5"`
if test x"$mocversiongrep" != x"$mocversion"; then
AC_MSG_RESULT([no])
# moc was not the qt5 one, try with moc-qt5
AC_CHECK_TOOL(MOC2, moc-qt5)
mocversion=`$MOC2 -v 2>&1`
- mocversiongrep=`echo $mocversion | grep "Qt 5\|moc-qt5 5\|moc 5"`
+ mocversiongrep=`echo $mocversion | grep -E "Qt 5|moc-qt5 5|moc 5"`
if test x"$mocversiongrep" != x"$mocversion"; then
AC_CHECK_TOOL(QTCHOOSER, qtchooser)
qt5tooldir=`QT_SELECT=qt5 qtchooser -print-env | grep QTTOOLDIR | cut -d '=' -f 2 | cut -d \" -f 2`
mocversion=`$qt5tooldir/moc -v 2>&1`
- mocversiongrep=`echo $mocversion | grep "Qt 5\|moc 5"`
+ mocversiongrep=`echo $mocversion | grep -E "Qt 5|moc 5"`
if test x"$mocversiongrep" != x"$mocversion"; then
# no valid moc found
have_qt5_libs="no";
diff --git a/src/Makefile.in b/src/Makefile.in
index 3f0da74..5f153a8 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -107,8 +107,8 @@ subdir = src
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/build-aux/mkinstalldirs \
$(srcdir)/versioninfo.rc.in $(srcdir)/gpgme.h.in \
- $(srcdir)/gpgme-config.in stpcpy.c funopen.c ttyname_r.c \
- vasprintf.c setenv.c $(top_srcdir)/build-aux/depcomp
+ $(srcdir)/gpgme-config.in stpcpy.c ttyname_r.c setenv.c \
+ $(top_srcdir)/build-aux/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_pkg_swig.m4 \
@@ -119,8 +119,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
@@ -818,11 +818,9 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/funopen.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/setenv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/stpcpy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ttyname_r.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/vasprintf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argparse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assuan-support.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ath.Plo@am__quote@
diff --git a/src/context.h b/src/context.h
index 1a8698c..d0542d9 100644
--- a/src/context.h
+++ b/src/context.h
@@ -114,10 +114,14 @@ struct gpgme_context
/* True if session keys should be exported upon decryption. */
unsigned int export_session_keys : 1;
+ /* True if a Pinentry was launched during the last operation. This
+ * flag is cleared with each operation. */
+ unsigned int redraw_suggested : 1;
+
/* Flags for keylist mode. */
gpgme_keylist_mode_t keylist_mode;
- /* The current pinnetry mode. */
+ /* The current pinentry mode. */
gpgme_pinentry_mode_t pinentry_mode;
/* Number of certs to be included. */
diff --git a/src/conversion.c b/src/conversion.c
index 6dfabe7..92dd214 100644
--- a/src/conversion.c
+++ b/src/conversion.c
@@ -536,6 +536,25 @@ _gpgme_parse_timestamp (const char *timestamp, char **endp)
}
+/* This function is similar to _gpgme_parse_timestamp but returns an
+ * unsigned long and 0 on error. */
+unsigned long
+_gpgme_parse_timestamp_ul (const char *timestamp)
+{
+ time_t tim;
+ char *tail;
+
+ if (!*timestamp)
+ return 0; /* Shortcut empty strings. */
+
+ tim = _gpgme_parse_timestamp (timestamp, &tail);
+ if (tim == -1 || timestamp == tail || (*tail && *tail != ' '))
+ tim = 0; /* No time given or invalid engine. */
+
+ return (unsigned long)tim;
+}
+
+
/* The GPG backend uses OpenPGP algorithm numbers which we need to map
to our algorithm numbers. This function MUST not change ERRNO. */
int
diff --git a/src/data-compat.c b/src/data-compat.c
index 5c7d543..87eaeef 100644
--- a/src/data-compat.c
+++ b/src/data-compat.c
@@ -239,16 +239,3 @@ gpgme_data_new_with_read_cb (gpgme_data_t *r_dh,
(*r_dh)->data.old_user.handle = read_cb_value;
return TRACE_ERR (0);
}
-
-
-gpgme_error_t
-gpgme_data_rewind (gpgme_data_t dh)
-{
- gpgme_error_t err;
- TRACE_BEG (DEBUG_DATA, "gpgme_data_rewind", dh);
-
- err = ((gpgme_data_seek (dh, 0, SEEK_SET) == -1)
- ? gpg_error_from_syserror () : 0);
-
- return TRACE_ERR (err);
-}
diff --git a/src/data.c b/src/data.c
index 6964246..e4e9ee3 100644
--- a/src/data.c
+++ b/src/data.c
@@ -158,6 +158,20 @@ gpgme_data_seek (gpgme_data_t dh, gpgme_off_t offset, int whence)
}
+/* Convenience function to do a gpgme_data_seek (dh, 0, SEEK_SET). */
+gpgme_error_t
+gpgme_data_rewind (gpgme_data_t dh)
+{
+ gpgme_error_t err;
+ TRACE_BEG (DEBUG_DATA, "gpgme_data_rewind", dh);
+
+ err = ((gpgme_data_seek (dh, 0, SEEK_SET) == -1)
+ ? gpg_error_from_syserror () : 0);
+
+ return TRACE_ERR (err);
+}
+
+
/* Release the data object with the handle DH. */
void
gpgme_data_release (gpgme_data_t dh)
diff --git a/src/debug.c b/src/debug.c
index 1dd3723..e9bfc40 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -313,7 +313,7 @@ _gpgme_debug_begin (void **line, int level, const char *format, ...)
}
va_start (arg_ptr, format);
- res = vasprintf ((char **) line, format, arg_ptr);
+ res = gpgrt_vasprintf ((char **) line, format, arg_ptr);
va_end (arg_ptr);
if (res < 0)
*line = NULL;
@@ -333,16 +333,16 @@ _gpgme_debug_add (void **line, const char *format, ...)
return;
va_start (arg_ptr, format);
- res = vasprintf (&toadd, format, arg_ptr);
+ res = gpgrt_vasprintf (&toadd, format, arg_ptr);
va_end (arg_ptr);
if (res < 0)
{
- free (*line);
+ gpgrt_free (*line);
*line = NULL;
}
- res = asprintf (&result, "%s%s", *(char **) line, toadd);
- free (toadd);
- free (*line);
+ res = gpgrt_asprintf (&result, "%s%s", *(char **) line, toadd);
+ gpgrt_free (toadd);
+ gpgrt_free (*line);
if (res < 0)
*line = NULL;
else
@@ -361,7 +361,7 @@ _gpgme_debug_end (void **line)
/* The smallest possible level is 1, so force logging here by
using that. */
_gpgme_debug (1, "%s", *line);
- free (*line);
+ gpgrt_free (*line);
*line = NULL;
}
diff --git a/src/decrypt-verify.c b/src/decrypt-verify.c
index e0aa8ea..66cfe94 100644
--- a/src/decrypt-verify.c
+++ b/src/decrypt-verify.c
@@ -23,6 +23,8 @@
#include <config.h>
#endif
+#include <assert.h>
+
#include "debug.h"
#include "gpgme.h"
#include "ops.h"
@@ -45,10 +47,13 @@ decrypt_verify_status_handler (void *priv, gpgme_status_code_t code,
static gpgme_error_t
decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
+ gpgme_decrypt_flags_t flags,
gpgme_data_t cipher, gpgme_data_t plain)
{
gpgme_error_t err;
+ assert ((flags & GPGME_DECRYPT_VERIFY));
+
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
@@ -77,9 +82,11 @@ decrypt_verify_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine,
decrypt_verify_status_handler, ctx);
- return _gpgme_engine_op_decrypt_verify (ctx->engine, cipher, plain,
- ctx->export_session_keys,
- ctx->override_session_key);
+ return _gpgme_engine_op_decrypt (ctx->engine,
+ flags,
+ cipher, plain,
+ ctx->export_session_keys,
+ ctx->override_session_key);
}
@@ -97,7 +104,7 @@ gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = decrypt_verify_start (ctx, 0, cipher, plain);
+ err = decrypt_verify_start (ctx, 0, GPGME_DECRYPT_VERIFY, cipher, plain);
return TRACE_ERR (err);
}
@@ -116,7 +123,57 @@ gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = decrypt_verify_start (ctx, 1, cipher, plain);
+ err = decrypt_verify_start (ctx, 1, GPGME_DECRYPT_VERIFY, cipher, plain);
+ if (!err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
+
+
+/* Decrypt ciphertext CIPHER within CTX and store the resulting
+ plaintext in PLAIN. */
+gpgme_error_t
+gpgme_op_decrypt_ext_start (gpgme_ctx_t ctx,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher,
+ gpgme_data_t plain)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_ext_start", ctx,
+ "cipher=%p, plain=%p", cipher, plain);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ if ((flags & GPGME_DECRYPT_VERIFY))
+ err = decrypt_verify_start (ctx, 0, flags, cipher, plain);
+ else
+ err = _gpgme_decrypt_start (ctx, 0, flags, cipher, plain);
+ return TRACE_ERR (err);
+}
+
+
+/* Decrypt ciphertext CIPHER within CTX and store the resulting
+ plaintext in PLAIN. */
+gpgme_error_t
+gpgme_op_decrypt_ext (gpgme_ctx_t ctx,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher,
+ gpgme_data_t plain)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_decrypt_ext", ctx,
+ "cipher=%p, plain=%p", cipher, plain);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ if ((flags & GPGME_DECRYPT_VERIFY))
+ err = decrypt_verify_start (ctx, 1, flags, cipher, plain);
+ else
+ err = _gpgme_decrypt_start (ctx, 1, flags, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
diff --git a/src/decrypt.c b/src/decrypt.c
index 43717c0..f30f80f 100644
--- a/src/decrypt.c
+++ b/src/decrypt.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <assert.h>
#include "debug.h"
#include "gpgme.h"
@@ -358,12 +359,15 @@ _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
}
-static gpgme_error_t
-decrypt_start (gpgme_ctx_t ctx, int synchronous,
- gpgme_data_t cipher, gpgme_data_t plain)
+gpgme_error_t
+_gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher, gpgme_data_t plain)
{
gpgme_error_t err;
+ assert (!(flags & GPGME_DECRYPT_VERIFY));
+
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
@@ -390,7 +394,9 @@ decrypt_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine, decrypt_status_handler, ctx);
- return _gpgme_engine_op_decrypt (ctx->engine, cipher, plain,
+ return _gpgme_engine_op_decrypt (ctx->engine,
+ flags,
+ cipher, plain,
ctx->export_session_keys,
ctx->override_session_key);
}
@@ -408,7 +414,7 @@ gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = decrypt_start (ctx, 0, cipher, plain);
+ err = _gpgme_decrypt_start (ctx, 0, 0, cipher, plain);
return TRACE_ERR (err);
}
@@ -426,7 +432,7 @@ gpgme_op_decrypt (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain)
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
- err = decrypt_start (ctx, 1, cipher, plain);
+ err = _gpgme_decrypt_start (ctx, 1, 0, cipher, plain);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
diff --git a/src/dirinfo.c b/src/dirinfo.c
index a0cbc03..7374412 100644
--- a/src/dirinfo.c
+++ b/src/dirinfo.c
@@ -51,6 +51,7 @@ enum
WANT_GPG_NAME,
WANT_GPGSM_NAME,
WANT_G13_NAME,
+ WANT_GPG_WKS_CLIENT_NAME,
WANT_GPG_ONE_MODE
};
@@ -73,6 +74,7 @@ static struct {
char *gpg_name;
char *gpgsm_name;
char *g13_name;
+ char *gpg_wks_client_name;
int gpg_one_mode; /* System is in gpg1 mode. */
} dirinfo;
@@ -333,6 +335,14 @@ get_gpgconf_item (int what)
case WANT_G13_NAME: result = dirinfo.g13_name; break;
case WANT_UISRV_SOCKET: result = dirinfo.uisrv_socket; break;
case WANT_GPG_ONE_MODE: result = dirinfo.gpg_one_mode? "1":NULL; break;
+ case WANT_GPG_WKS_CLIENT_NAME:
+ if (!dirinfo.gpg_wks_client_name && dirinfo.libexecdir)
+ dirinfo.gpg_wks_client_name = _gpgme_strconcat (dirinfo.libexecdir,
+ "/",
+ "gpg-wks-client",
+ NULL);
+ result = dirinfo.gpg_wks_client_name;
+ break;
}
UNLOCK (dirinfo_lock);
return result;
@@ -438,6 +448,8 @@ gpgme_get_dirinfo (const char *what)
return get_gpgconf_item (WANT_GPGSM_NAME);
else if (!strcmp (what, "g13-name"))
return get_gpgconf_item (WANT_G13_NAME);
+ else if (!strcmp (what, "gpg-wks-client-name"))
+ return get_gpgconf_item (WANT_GPG_WKS_CLIENT_NAME);
else if (!strcmp (what, "agent-ssh-socket"))
return get_gpgconf_item (WANT_AGENT_SSH_SOCKET);
else if (!strcmp (what, "dirmngr-socket"))
diff --git a/src/engine-assuan.c b/src/engine-assuan.c
index 3e3b89f..68bdaa6 100644
--- a/src/engine-assuan.c
+++ b/src/engine-assuan.c
@@ -265,7 +265,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_display)
{
- if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
{
err = gpg_error_from_syserror ();
free (dft_display);
@@ -275,7 +275,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -304,14 +304,14 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
- if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{
err = gpg_error_from_syserror ();
goto leave;
}
err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
@@ -320,7 +320,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_ttytype)
{
- if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0)
{
err = gpg_error_from_syserror ();
free (dft_ttytype);
@@ -330,7 +330,7 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -408,13 +408,13 @@ llass_set_locale (void *engine, int category, const char *value)
if (!value)
return 0;
- if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
err = gpg_error_from_syserror ();
else
{
err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
}
return err;
}
@@ -776,7 +776,6 @@ struct engine_ops _gpgme_engine_ops_assuan =
llass_set_locale,
NULL, /* set_protocol */
NULL, /* decrypt */
- NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */
@@ -787,6 +786,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 a8457af..53af662 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -61,12 +61,11 @@ struct engine_ops
void *fnc_value);
gpgme_error_t (*set_locale) (void *engine, int category, const char *value);
gpgme_error_t (*set_protocol) (void *engine, gpgme_protocol_t protocol);
- gpgme_error_t (*decrypt) (void *engine, gpgme_data_t ciph,
+ gpgme_error_t (*decrypt) (void *engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph,
gpgme_data_t plain, int export_session_key,
const char *override_session_key);
- gpgme_error_t (*decrypt_verify) (void *engine, gpgme_data_t ciph,
- gpgme_data_t plain, int export_session_key,
- const char *override_session_key);
gpgme_error_t (*delete) (void *engine, gpgme_key_t key, int allow_secret);
gpgme_error_t (*edit) (void *engine, int type, gpgme_key_t key,
gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */);
@@ -100,6 +99,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 972c3a8..02951e8 100644
--- a/src/engine-g13.c
+++ b/src/engine-g13.c
@@ -270,7 +270,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_display)
{
- if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
{
free (dft_display);
err = gpg_error_from_syserror ();
@@ -280,7 +280,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -304,14 +304,14 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
- if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{
err = gpg_error_from_syserror ();
goto leave;
}
err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
@@ -320,7 +320,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_ttytype)
{
- if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0)
{
free (dft_ttytype);
err = gpg_error_from_syserror ();
@@ -330,7 +330,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -400,13 +400,13 @@ g13_set_locale (void *engine, int category, const char *value)
if (!value)
return 0;
- if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
err = gpg_error_from_syserror ();
else
{
err = assuan_transact (g13->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
}
return err;
@@ -791,7 +791,6 @@ struct engine_ops _gpgme_engine_ops_g13 =
g13_set_locale,
NULL, /* set_protocol */
NULL, /* decrypt */
- NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */
@@ -802,6 +801,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 3ddaa07..0c3a63e 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -74,6 +74,10 @@ struct fd_data_map_s
};
+/* NB.: R_LINE is allocated an gpgrt function and thus gpgrt_free
+ * shall be used to release it. This takes care of custom memory
+ * allocators and avoids problems on Windows with different runtimes
+ * used for libgpg-error/gpgrt and gpgme. */
typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline);
struct engine_gpg
@@ -1346,7 +1350,7 @@ read_colon_line (engine_gpg_t gpg)
}
while (linep && *linep);
- free (line);
+ gpgrt_free (line);
}
else
gpg->colon.fnc (gpg->colon.fnc_value, buffer);
@@ -1555,7 +1559,9 @@ add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
static gpgme_error_t
-gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
+gpg_decrypt (void *engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key)
{
engine_gpg_t gpg = engine;
@@ -1563,6 +1569,14 @@ gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
err = add_arg (gpg, "--decrypt");
+ if (!err && (flags & GPGME_DECRYPT_UNWRAP))
+ {
+ if (!have_gpg_version (gpg, "2.1.12"))
+ err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+ else
+ err = add_arg (gpg, "--unwrap");
+ }
+
if (!err && export_session_key)
err = add_arg (gpg, "--show-session-key");
@@ -1853,9 +1867,23 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!err && use_armor)
err = add_arg (gpg, "--armor");
+ if (!err && (flags & GPGME_ENCRYPT_WRAP))
+ {
+ /* gpg is current not abale to detect already compressed
+ * packets. Thus when using
+ * gpg --unwrap -d | gpg --no-literal -e
+ * the encryption would add an additional compression layer.
+ * We better suppress that. */
+ flags |= GPGME_ENCRYPT_NO_COMPRESS;
+ err = add_arg (gpg, "--no-literal");
+ }
+
if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
err = add_arg (gpg, "--compress-algo=none");
+ if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
+ err = add_arg (gpg, "--throw-keyids");
+
if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
&& have_gpg_version (gpg, "2.1.14"))
err = add_arg (gpg, "--mimemode");
@@ -1925,6 +1953,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
err = add_arg (gpg, "--compress-algo=none");
+ if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
+ err = add_arg (gpg, "--throw-keyids");
+
if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
&& have_gpg_version (gpg, "2.1.14"))
err = add_arg (gpg, "--mimemode");
@@ -2072,7 +2103,8 @@ gpg_add_algo_usage_expire (engine_gpg_t gpg,
/* This condition is only required to allow the use of gpg < 2.1.16 */
if (algo
|| (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR
- | GPGME_CREATE_CERT | GPGME_CREATE_AUTH))
+ | GPGME_CREATE_CERT | GPGME_CREATE_AUTH
+ | GPGME_CREATE_NOEXPIRE))
|| expires)
{
err = add_arg (gpg, algo? algo : "default");
@@ -2086,11 +2118,18 @@ gpg_add_algo_usage_expire (engine_gpg_t gpg,
(flags & GPGME_CREATE_AUTH)? " auth":"");
err = add_arg (gpg, *tmpbuf? tmpbuf : "default");
}
- if (!err && expires)
+ if (!err)
{
- char tmpbuf[8+20];
- snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
- err = add_arg (gpg, tmpbuf);
+ if ((flags & GPGME_CREATE_NOEXPIRE))
+ err = add_arg (gpg, "never");
+ else if (expires == 0)
+ err = add_arg (gpg, "-");
+ else
+ {
+ char tmpbuf[8+20];
+ snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
+ err = add_arg (gpg, tmpbuf);
+ }
}
}
else
@@ -2136,6 +2175,8 @@ gpg_createkey (engine_gpg_t gpg,
err = add_arg (gpg, "--passphrase");
if (!err)
err = add_arg (gpg, "");
+ if (!err)
+ err = add_arg (gpg, "--batch");
}
if (!err && (flags & GPGME_CREATE_FORCE))
err = add_arg (gpg, "--yes");
@@ -2174,6 +2215,8 @@ gpg_addkey (engine_gpg_t gpg,
err = add_arg (gpg, "--passphrase");
if (!err)
err = add_arg (gpg, "");
+ if (!err)
+ err = add_arg (gpg, "--batch");
}
if (!err)
err = add_arg (gpg, "--");
@@ -2200,7 +2243,14 @@ gpg_adduid (engine_gpg_t gpg,
if (!key || !key->fpr || !userid)
return gpg_error (GPG_ERR_INV_ARG);
- if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
+ if ((extraflags & GENKEY_EXTRAFLAG_SETPRIMARY))
+ {
+ if (!have_gpg_version (gpg, "2.1.20"))
+ err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+ else
+ err = add_arg (gpg, "--quick-set-primary-uid");
+ }
+ else if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
err = add_arg (gpg, "--quick-revuid");
else
err = add_arg (gpg, "--quick-adduid");
@@ -2240,7 +2290,7 @@ gpg_genkey (void *engine,
* USERID && !KEY - Create a new keyblock.
* !USERID && KEY - Add a new subkey to KEY (gpg >= 2.1.14)
* USERID && KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
- *
+ * or set a flag on a user id.
*/
if (help_data)
{
@@ -2509,7 +2559,7 @@ gpg_keylist_preprocess (char *line, char **r_line)
n = strlen (field[1]);
if (n > 16)
{
- if (asprintf (r_line,
+ if (gpgrt_asprintf (r_line,
"pub:o%s:%s:%s:%s:%s:%s::::::::\n"
"fpr:::::::::%s:",
field[6], field[3], field[2], field[1] + n - 16,
@@ -2518,7 +2568,7 @@ gpg_keylist_preprocess (char *line, char **r_line)
}
else
{
- if (asprintf (r_line,
+ if (gpgrt_asprintf (r_line,
"pub:o%s:%s:%s:%s:%s:%s::::::::",
field[6], field[3], field[2], field[1],
field[4], field[5]) < 0)
@@ -2576,7 +2626,7 @@ gpg_keylist_preprocess (char *line, char **r_line)
}
*dst = '\0';
- if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
+ if (gpgrt_asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
field[4], field[2], field[3], uid) < 0)
return gpg_error_from_syserror ();
}
@@ -2715,6 +2765,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)
@@ -2986,7 +3068,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
gpg_set_locale,
NULL, /* set_protocol */
gpg_decrypt,
- gpg_decrypt, /* decrypt_verify */
gpg_delete,
gpg_edit,
gpg_encrypt,
@@ -2997,6 +3078,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 2ea8673..6f7c8ac 100644
--- a/src/engine-gpgconf.c
+++ b/src/engine-gpgconf.c
@@ -708,10 +708,13 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf)
#define BUFLEN 1024
char buf[BUFLEN];
int buflen = 0;
- char *argv[6];
+ char *argv[7];
int argc = 0;
- int rp[2];
- struct spawn_fd_item_s cfd[] = { {-1, 0 /* STDIN_FILENO */}, {-1, -1} };
+ int rp[2] = { -1, -1 };
+ int errp[2] = { -1, -1 };
+ struct spawn_fd_item_s cfd[] = { {-1, 0 /* STDIN_FILENO */},
+ {-1, 2 /* STDERR_FILENO */, -1},
+ {-1, -1} };
int status;
int nwrite;
@@ -724,25 +727,38 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf)
argv[argc++] = gpgconf->home_dir;
}
+ argv[argc++] = (char*)"--runtime";
argv[argc++] = (char*)arg1;
argv[argc++] = arg2;
argv[argc] = NULL;
assert (argc < DIM (argv));
if (_gpgme_io_pipe (rp, 0) < 0)
- return gpg_error_from_syserror ();
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+
+ if (_gpgme_io_pipe (errp, 1) < 0)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
cfd[0].fd = rp[0];
+ cfd[1].fd = errp[1];
status = _gpgme_io_spawn (gpgconf->file_name, argv,
IOSPAWN_FLAG_DETACHED, cfd, NULL, NULL, NULL);
if (status < 0)
{
- _gpgme_io_close (rp[0]);
- _gpgme_io_close (rp[1]);
- return gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
+ goto leave;
}
+ rp[0] = -1;
+ errp[1] = -1;
+
for (;;)
{
if (buflen == 0)
@@ -756,14 +772,29 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf)
if (buflen < 0)
{
err = gpg_error_from_syserror ();
- _gpgme_io_close (rp[1]);
- return err;
+ goto leave;
}
else if (buflen == 0)
{
/* All is written. */
_gpgme_io_close (rp[1]);
- return 0;
+ rp[1] = -1;
+
+ for (;;)
+ {
+ do
+ {
+ buflen = _gpgme_io_read (errp[0], buf, BUFLEN);
+ }
+ while (buflen < 0 && errno == EAGAIN);
+
+ if (buflen == 0)
+ {
+ err = 0;
+ goto leave;
+ }
+ /* XXX: Do something useful with BUF. */
+ }
}
}
@@ -781,12 +812,24 @@ gpgconf_write (void *engine, const char *arg1, char *arg2, gpgme_data_t conf)
}
else if (nwrite < 0)
{
- _gpgme_io_close (rp[1]);
- return gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
+ goto leave;
}
}
- return 0;
+ assert (! "reached");
+
+ leave:
+ if (rp[0] != -1)
+ _gpgme_io_close (rp[0]);
+ if (rp[1] != -1)
+ _gpgme_io_close (rp[1]);
+ if (errp[0] != -1)
+ _gpgme_io_close (errp[0]);
+ if (errp[1] != -1)
+ _gpgme_io_close (errp[1]);
+
+ return err;
}
@@ -1190,7 +1233,6 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
NULL, /* set_locale */
NULL, /* set_protocol */
NULL, /* decrypt */
- NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */
@@ -1201,6 +1243,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 d1be049..c3d5427 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -396,7 +396,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_display)
{
- if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
{
free (dft_display);
err = gpg_error_from_syserror ();
@@ -406,7 +406,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -430,14 +430,14 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
- if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{
err = gpg_error_from_syserror ();
goto leave;
}
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
@@ -446,7 +446,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_ttytype)
{
- if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0)
{
free (dft_ttytype);
err = gpg_error_from_syserror ();
@@ -456,7 +456,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -561,13 +561,13 @@ gpgsm_set_locale (void *engine, int category, const char *value)
if (!value)
return 0;
- if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
err = gpg_error_from_syserror ();
else
{
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
}
return err;
@@ -593,7 +593,7 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
{
err = assuan_read_line (ctx, &line, &linelen);
if (err)
- return err;
+ break;
if (*line == '#' || !linelen)
continue;
@@ -601,7 +601,7 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
if (linelen >= 2
&& line[0] == 'O' && line[1] == 'K'
&& (line[2] == '\0' || line[2] == ' '))
- return cb_err;
+ break;
else if (linelen >= 4
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
&& line[3] == ' ')
@@ -610,6 +610,7 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
more related to gpgme and thus probably more important
than the error returned by the engine. */
err = cb_err? cb_err : atoi (&line[4]);
+ cb_err = 0;
}
else if (linelen >= 2
&& line[0] == 'S' && line[1] == ' ')
@@ -646,10 +647,16 @@ gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, const char *cmd,
to stop. As with ERR we prefer a status callback
generated error code, though. */
err = cb_err ? cb_err : gpg_error (GPG_ERR_GENERAL);
+ cb_err = 0;
}
}
while (!err);
+ /* We only want the first error from the status handler, thus we
+ * take the one saved in CB_ERR. */
+ if (!err && cb_err)
+ err = cb_err;
+
return err;
}
@@ -1120,12 +1127,16 @@ gpgsm_reset (void *engine)
static gpgme_error_t
-gpgsm_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
+gpgsm_decrypt (void *engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph, gpgme_data_t plain,
int export_session_key, const char *override_session_key)
{
engine_gpgsm_t gpgsm = engine;
gpgme_error_t err;
+ (void)flags;
+
/* gpgsm is not capable of exporting session keys right now, so we
* will ignore this if requested. */
(void)export_session_key;
@@ -1642,10 +1653,10 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
gpgsm_assuan_simple_command (gpgsm, "GETINFO agent-check", NULL, NULL);
/* Always send list-mode option because RESET does not reset it. */
- if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
+ if (gpgrt_asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
return gpg_error_from_syserror ();
err = gpgsm_assuan_simple_command (gpgsm, line, NULL, NULL);
- free (line);
+ gpgrt_free (line);
if (err)
return err;
@@ -1726,10 +1737,10 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
list_mode |= 2;
/* Always send list-mode option because RESET does not reset it. */
- if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
+ if (gpgrt_asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
return gpg_error_from_syserror ();
err = gpgsm_assuan_simple_command (gpgsm, line, NULL, NULL);
- free (line);
+ gpgrt_free (line);
if (err)
return err;
@@ -1860,10 +1871,11 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
can reset any previously set value in case the default is
requested. */
- if (asprintf (&assuan_cmd, "OPTION include-certs %i", include_certs) < 0)
+ if (gpgrt_asprintf (&assuan_cmd,
+ "OPTION include-certs %i", include_certs) < 0)
return gpg_error_from_syserror ();
err = gpgsm_assuan_simple_command (gpgsm, assuan_cmd, NULL, NULL);
- free (assuan_cmd);
+ gpgrt_free (assuan_cmd);
if (err)
return err;
}
@@ -2048,7 +2060,7 @@ 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);
- if (asprintf (&line, "PASSWD -- %s", key->subkeys->fpr) < 0)
+ if (gpgrt_asprintf (&line, "PASSWD -- %s", key->subkeys->fpr) < 0)
return gpg_error_from_syserror ();
gpgsm_clear_fd (gpgsm, OUTPUT_FD);
@@ -2057,7 +2069,7 @@ gpgsm_passwd (void *engine, gpgme_key_t key, unsigned int flags)
gpgsm->inline_data = NULL;
err = start (gpgsm, line);
- free (line);
+ gpgrt_free (line);
return err;
}
@@ -2087,7 +2099,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
gpgsm_set_locale,
NULL, /* set_protocol */
gpgsm_decrypt,
- gpgsm_decrypt,
gpgsm_delete, /* decrypt_verify */
NULL, /* edit */
gpgsm_encrypt,
@@ -2098,6 +2109,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 1cd4421..9d587cc 100644
--- a/src/engine-spawn.c
+++ b/src/engine-spawn.c
@@ -449,7 +449,6 @@ struct engine_ops _gpgme_engine_ops_spawn =
NULL, /* set_locale */
NULL, /* set_protocol */
NULL, /* decrypt */
- NULL, /* decrypt_verify */
NULL, /* delete */
NULL, /* edit */
NULL, /* encrypt */
@@ -460,6 +459,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 ee7b1d2..20a8abf 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -316,7 +316,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_display)
{
- if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION display=%s", dft_display) < 0)
{
err = gpg_error_from_syserror ();
free (dft_display);
@@ -326,7 +326,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -350,14 +350,14 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
ways, e.g., when /dev/pts is not accessible under chroot. */
if (!rc)
{
- if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0)
{
err = gpg_error_from_syserror ();
goto leave;
}
err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL, NULL,
NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
@@ -366,7 +366,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
goto leave;
if (dft_ttytype)
{
- if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype)< 0)
{
err = gpg_error_from_syserror ();
free (dft_ttytype);
@@ -376,7 +376,7 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir,
err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
if (err)
goto leave;
}
@@ -441,13 +441,13 @@ uiserver_set_locale (void *engine, int category, const char *value)
if (!value)
return 0;
- if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
+ if (gpgrt_asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0)
err = gpg_error_from_syserror ();
else
{
err = assuan_transact (uiserver->assuan_ctx, optstr, NULL, NULL,
NULL, NULL, NULL, NULL);
- free (optstr);
+ gpgrt_free (optstr);
}
return err;
@@ -959,14 +959,16 @@ uiserver_reset (void *engine)
static gpgme_error_t
-_uiserver_decrypt (void *engine, int verify,
- gpgme_data_t ciph, gpgme_data_t plain,
- int export_session_key, const char *override_session_key)
+uiserver_decrypt (void *engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph, gpgme_data_t plain,
+ int export_session_key, const char *override_session_key)
{
engine_uiserver_t uiserver = engine;
gpgme_error_t err;
const char *protocol;
char *cmd;
+ int verify = !!(flags & GPGME_DECRYPT_VERIFY);
(void)override_session_key; /* Fixme: We need to see now to add this
* to the UI server protocol */
@@ -982,7 +984,7 @@ _uiserver_decrypt (void *engine, int verify,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
- if (asprintf (&cmd, "DECRYPT%s%s%s", protocol,
+ if (gpgrt_asprintf (&cmd, "DECRYPT%s%s%s", protocol,
verify ? "" : " --no-verify",
export_session_key ? " --export-session-key" : "") < 0)
return gpg_error_from_syserror ();
@@ -992,44 +994,25 @@ _uiserver_decrypt (void *engine, int verify,
map_data_enc (uiserver->input_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return gpg_error (GPG_ERR_GENERAL); /* FIXME */
}
uiserver->output_cb.data = plain;
err = uiserver_set_fd (uiserver, OUTPUT_FD, 0);
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return gpg_error (GPG_ERR_GENERAL); /* FIXME */
}
uiserver->inline_data = NULL;
err = start (engine, cmd);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
static gpgme_error_t
-uiserver_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
- int export_session_key, const char *override_session_key)
-{
- return _uiserver_decrypt (engine, 0, ciph, plain,
- export_session_key, override_session_key);
-}
-
-
-static gpgme_error_t
-uiserver_decrypt_verify (void *engine, gpgme_data_t ciph, gpgme_data_t plain,
- int export_session_key,
- const char *override_session_key)
-{
- return _uiserver_decrypt (engine, 1, ciph, plain,
- export_session_key, override_session_key);
-}
-
-
-static gpgme_error_t
set_recipients (engine_uiserver_t uiserver, gpgme_key_t recp[])
{
gpgme_error_t err = 0;
@@ -1114,7 +1097,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!recp || plain || ciph)
return gpg_error (GPG_ERR_INV_VALUE);
- if (asprintf (&cmd, "PREP_ENCRYPT%s%s", protocol,
+ if (gpgrt_asprintf (&cmd, "PREP_ENCRYPT%s%s", protocol,
(flags & GPGME_ENCRYPT_EXPECT_SIGN)
? " --expect-sign" : "") < 0)
return gpg_error_from_syserror ();
@@ -1124,7 +1107,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!plain || !ciph)
return gpg_error (GPG_ERR_INV_VALUE);
- if (asprintf (&cmd, "ENCRYPT%s", protocol) < 0)
+ if (gpgrt_asprintf (&cmd, "ENCRYPT%s", protocol) < 0)
return gpg_error_from_syserror ();
}
@@ -1135,7 +1118,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
map_data_enc (uiserver->input_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
}
@@ -1147,7 +1130,7 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
: map_data_enc (uiserver->output_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
}
@@ -1159,13 +1142,13 @@ uiserver_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
err = set_recipients (uiserver, recp);
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
}
err = start (uiserver, cmd);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
@@ -1195,7 +1178,7 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
- if (asprintf (&cmd, "SIGN%s%s", protocol,
+ if (gpgrt_asprintf (&cmd, "SIGN%s%s", protocol,
(mode == GPGME_SIG_MODE_DETACH) ? " --detached" : "") < 0)
return gpg_error_from_syserror ();
@@ -1220,10 +1203,10 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
err = gpg_error (GPG_ERR_INV_VALUE);
gpgme_key_unref (key);
if (err)
- {
- free (cmd);
- return err;
- }
+ {
+ gpgrt_free (cmd);
+ return err;
+ }
}
uiserver->input_cb.data = in;
@@ -1231,7 +1214,7 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
map_data_enc (uiserver->input_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
uiserver->output_cb.data = out;
@@ -1239,13 +1222,13 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
: map_data_enc (uiserver->output_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
uiserver->inline_data = NULL;
err = start (uiserver, cmd);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
@@ -1274,7 +1257,7 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
else
return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
- if (asprintf (&cmd, "VERIFY%s", protocol) < 0)
+ if (gpgrt_asprintf (&cmd, "VERIFY%s", protocol) < 0)
return gpg_error_from_syserror ();
uiserver->input_cb.data = sig;
@@ -1282,7 +1265,7 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
map_data_enc (uiserver->input_cb.data));
if (err)
{
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
if (plaintext)
@@ -1302,7 +1285,7 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
if (!err)
err = start (uiserver, cmd);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
@@ -1383,7 +1366,6 @@ struct engine_ops _gpgme_engine_ops_uiserver =
uiserver_set_locale,
uiserver_set_protocol,
uiserver_decrypt,
- uiserver_decrypt_verify,
NULL, /* delete */
NULL, /* edit */
uiserver_encrypt,
@@ -1394,6 +1376,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 75d9ff7..278916d 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -652,7 +652,9 @@ _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
gpgme_error_t
-_gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
+_gpgme_engine_op_decrypt (engine_t engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph,
gpgme_data_t plain, int export_session_key,
const char *override_session_key)
{
@@ -662,29 +664,12 @@ _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
if (!engine->ops->decrypt)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- return (*engine->ops->decrypt) (engine->engine, ciph, plain,
+ return (*engine->ops->decrypt) (engine->engine, flags, ciph, plain,
export_session_key, override_session_key);
}
gpgme_error_t
-_gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
- gpgme_data_t plain, int export_session_key,
- const char *override_session_key)
-{
- if (!engine)
- return gpg_error (GPG_ERR_INV_VALUE);
-
- if (!engine->ops->decrypt_verify)
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-
- return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain,
- export_session_key,
- override_session_key);
-}
-
-
-gpgme_error_t
_gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret)
{
@@ -876,6 +861,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 29d2f25..dd0ef9c 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -25,8 +25,9 @@
#include "gpgme.h"
/* Flags used by the EXTRAFLAGS arg of _gpgme_engine_op_genkey. */
-#define GENKEY_EXTRAFLAG_ARMOR 1
-#define GENKEY_EXTRAFLAG_REVOKE 2
+#define GENKEY_EXTRAFLAG_ARMOR 1
+#define GENKEY_EXTRAFLAG_REVOKE 2
+#define GENKEY_EXTRAFLAG_SETPRIMARY 4
struct engine;
@@ -82,16 +83,12 @@ gpgme_error_t
_gpgme_engine_set_colon_line_handler (engine_t engine,
engine_colon_line_handler_t fnc,
void *fnc_value);
-gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
+gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t ciph,
gpgme_data_t plain,
int export_session_key,
const char *override_session_key);
-gpgme_error_t _gpgme_engine_op_decrypt_verify (engine_t engine,
- gpgme_data_t ciph,
- gpgme_data_t plain,
- int export_session_key,
- const char *override_session_key
- );
gpgme_error_t _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
int allow_secret);
gpgme_error_t _gpgme_engine_op_edit (engine_t engine, int type,
@@ -148,6 +145,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/funopen.c b/src/funopen.c
deleted file mode 100644
index b722020..0000000
--- a/src/funopen.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* funopen.c - Replacement for funopen.
- Copyright (C) 2004 g10 Code GmbH
-
- This file is part of GPGME
-
- GPGME is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of
- the License, or (at your option) any later version.
-
- GPGME is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-
-
-/* Replacement for the *BSD function:
-
- FILE *funopen (void *cookie,
- int (*readfn)(void *, char *, int),
- int (*writefn)(void *, const char *, int),
- fpos_t (*seekfn)(void *, fpos_t, int),
- int (*closefn)(void *));
-
- The functions to provide my either be NULL if not required or
- similar to the unistd function with the exception of using the
- cookie instead of the file descriptor.
-*/
-
-
-#ifdef HAVE_FOPENCOOKIE
-FILE *
-_gpgme_funopen(void *cookie,
- cookie_read_function_t *readfn,
- cookie_write_function_t *writefn,
- cookie_seek_function_t *seekfn,
- cookie_close_function_t *closefn)
-{
- cookie_io_functions_t io = { NULL };
-
- io.read = readfn;
- io.write = writefn;
- io.seek = seekfn;
- io.close = closefn;
-
- return fopencookie (cookie,
- readfn ? ( writefn ? "rw" : "r" )
- : ( writefn ? "w" : ""), io);
-}
-#else
-#error No known way to implement funopen.
-#endif
diff --git a/src/genkey.c b/src/genkey.c
index ea3f1ea..710b58f 100644
--- a/src/genkey.c
+++ b/src/genkey.c
@@ -489,7 +489,7 @@ gpgme_op_createsubkey (gpgme_ctx_t ctx, gpgme_key_t key, const char *algo,
static gpgme_error_t
-addrevuid_start (gpgme_ctx_t ctx, int synchronous, int revoke,
+addrevuid_start (gpgme_ctx_t ctx, int synchronous, int extraflags,
gpgme_key_t key, const char *userid, unsigned int flags)
{
gpgme_error_t err;
@@ -512,7 +512,7 @@ addrevuid_start (gpgme_ctx_t ctx, int synchronous, int revoke,
if (err)
return err;
- opd->uidmode = revoke? 2 : 1;
+ opd->uidmode = extraflags? 2 : 1;
_gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
@@ -528,7 +528,7 @@ addrevuid_start (gpgme_ctx_t ctx, int synchronous, int revoke,
userid, NULL, 0, 0,
key, flags,
NULL,
- revoke? GENKEY_EXTRAFLAG_REVOKE : 0,
+ extraflags,
NULL, NULL);
}
@@ -584,7 +584,7 @@ gpgme_op_revuid_start (gpgme_ctx_t ctx,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
- err = addrevuid_start (ctx, 0, 1, key, userid, flags);
+ err = addrevuid_start (ctx, 0, GENKEY_EXTRAFLAG_REVOKE, key, userid, flags);
return TRACE_ERR (err);
}
@@ -601,8 +601,60 @@ gpgme_op_revuid (gpgme_ctx_t ctx,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
- err = addrevuid_start (ctx, 1, 1, key, userid, flags);
+ err = addrevuid_start (ctx, 1, GENKEY_EXTRAFLAG_REVOKE, key, userid, flags);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
}
+
+
+/* Set a flag on the USERID of KEY. The only supported flag right now
+ * is "primary" to mark the primary key. */
+static gpg_error_t
+set_uid_flag (gpgme_ctx_t ctx, int synchronous,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG4 (DEBUG_CTX, "gpgme_op_set_uid_flag", ctx,
+ "%d uid='%s' '%s'='%s'", synchronous, userid, name, value);
+
+ if (!ctx || !name || !key || !userid)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
+
+ if (!strcmp (name, "primary"))
+ {
+ if (value)
+ err = gpg_error (GPG_ERR_INV_ARG);
+ else
+ err = addrevuid_start (ctx, synchronous,
+ GENKEY_EXTRAFLAG_SETPRIMARY, key, userid, 0);
+ }
+ else
+ return err = gpg_error (GPG_ERR_UNKNOWN_NAME);
+
+ if (synchronous && !err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
+
+
+/* See set_uid_flag. */
+gpgme_error_t
+gpgme_op_set_uid_flag_start (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value)
+{
+ return set_uid_flag (ctx, 0, key, userid, name, value);
+}
+
+
+/* See set_uid_flag. Thsi is the synchronous variant. */
+gpgme_error_t
+gpgme_op_set_uid_flag (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value)
+{
+ return set_uid_flag (ctx, 1, key, userid, name, value);
+}
diff --git a/src/gpgme.c b/src/gpgme.c
index cf767c7..2b196a2 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -508,6 +508,10 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
if (!ctx || !name || !value)
err = gpg_error (GPG_ERR_INV_VALUE);
+ else if (!strcmp (name, "redraw"))
+ {
+ ctx->redraw_suggested = abool;
+ }
else if (!strcmp (name, "full-status"))
{
ctx->full_status = abool;
@@ -544,6 +548,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
{
if (!ctx || !name)
return NULL;
+ else if (!strcmp (name, "redraw"))
+ {
+ return ctx->redraw_suggested? "1":"";
+ }
else if (!strcmp (name, "full-status"))
{
return ctx->full_status? "1":"";
diff --git a/src/gpgme.def b/src/gpgme.def
index 0d3ce74..51053cd 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,14 @@ EXPORTS
gpgme_op_query_swdb_result @190
gpgme_get_ctx_flag @191
+
+ gpgme_op_keylist_from_data_start @192
+
+ gpgme_op_set_uid_flag_start @193
+ gpgme_op_set_uid_flag @194
+
+ gpgme_op_decrypt_ext @195
+ gpgme_op_decrypt_ext_start @196
+
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 7cfe8f6..24b21e7 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1,6 +1,6 @@
/* gpgme.h - Public interface to GnuPG Made Easy. -*- c -*-
* Copyright (C) 2000 Werner Koch (dd9jn)
- * Copyright (C) 2001-2016 g10 Code GmbH
+ * Copyright (C) 2001-2017 g10 Code GmbH
*
* This file is part of GPGME.
*
@@ -294,24 +294,6 @@ typedef enum
gpgme_hash_algo_t;
-/* The possible signature stati. Deprecated, use error value in sig
- status. */
-typedef enum
- {
- GPGME_SIG_STAT_NONE = 0,
- GPGME_SIG_STAT_GOOD = 1,
- GPGME_SIG_STAT_BAD = 2,
- GPGME_SIG_STAT_NOKEY = 3,
- GPGME_SIG_STAT_NOSIG = 4,
- GPGME_SIG_STAT_ERROR = 5,
- GPGME_SIG_STAT_DIFF = 6,
- GPGME_SIG_STAT_GOOD_EXP = 7,
- GPGME_SIG_STAT_GOOD_EXPKEY = 8
- }
-_gpgme_sig_stat_t;
-typedef _gpgme_sig_stat_t gpgme_sig_stat_t _GPGME_DEPRECATED(0,4);
-
-
/* The available signature modes. */
typedef enum
{
@@ -322,47 +304,6 @@ typedef enum
gpgme_sig_mode_t;
-/* The available key and signature attributes. Deprecated, use the
- individual result structures instead. */
-typedef enum
- {
- GPGME_ATTR_KEYID = 1,
- GPGME_ATTR_FPR = 2,
- GPGME_ATTR_ALGO = 3,
- GPGME_ATTR_LEN = 4,
- GPGME_ATTR_CREATED = 5,
- GPGME_ATTR_EXPIRE = 6,
- GPGME_ATTR_OTRUST = 7,
- GPGME_ATTR_USERID = 8,
- GPGME_ATTR_NAME = 9,
- GPGME_ATTR_EMAIL = 10,
- GPGME_ATTR_COMMENT = 11,
- GPGME_ATTR_VALIDITY = 12,
- GPGME_ATTR_LEVEL = 13,
- GPGME_ATTR_TYPE = 14,
- GPGME_ATTR_IS_SECRET = 15,
- GPGME_ATTR_KEY_REVOKED = 16,
- GPGME_ATTR_KEY_INVALID = 17,
- GPGME_ATTR_UID_REVOKED = 18,
- GPGME_ATTR_UID_INVALID = 19,
- GPGME_ATTR_KEY_CAPS = 20,
- GPGME_ATTR_CAN_ENCRYPT = 21,
- GPGME_ATTR_CAN_SIGN = 22,
- GPGME_ATTR_CAN_CERTIFY = 23,
- GPGME_ATTR_KEY_EXPIRED = 24,
- GPGME_ATTR_KEY_DISABLED = 25,
- GPGME_ATTR_SERIAL = 26,
- GPGME_ATTR_ISSUER = 27,
- GPGME_ATTR_CHAINID = 28,
- GPGME_ATTR_SIG_STATUS = 29,
- GPGME_ATTR_ERRTOK = 30,
- GPGME_ATTR_SIG_SUMMARY = 31,
- GPGME_ATTR_SIG_CLASS = 32
- }
-_gpgme_attr_t;
-typedef _gpgme_attr_t gpgme_attr_t _GPGME_DEPRECATED(0,4);
-
-
/* The available validities for a trust item or key. */
typedef enum
{
@@ -447,128 +388,15 @@ typedef unsigned int gpgme_export_mode_t;
#define GPGME_AUDITLOG_WITH_HELP 128
-/* The possible stati for gpgme_op_edit. The use of that function and
- * these status codes are deprecated in favor of gpgme_op_interact. */
-typedef enum
- {
- GPGME_STATUS_EOF = 0,
- /* mkstatus processing starts here */
- GPGME_STATUS_ENTER = 1,
- GPGME_STATUS_LEAVE = 2,
- GPGME_STATUS_ABORT = 3,
-
- GPGME_STATUS_GOODSIG = 4,
- GPGME_STATUS_BADSIG = 5,
- GPGME_STATUS_ERRSIG = 6,
-
- GPGME_STATUS_BADARMOR = 7,
-
- GPGME_STATUS_RSA_OR_IDEA = 8, /* (legacy) */
- GPGME_STATUS_KEYEXPIRED = 9,
- GPGME_STATUS_KEYREVOKED = 10,
-
- GPGME_STATUS_TRUST_UNDEFINED = 11,
- GPGME_STATUS_TRUST_NEVER = 12,
- GPGME_STATUS_TRUST_MARGINAL = 13,
- GPGME_STATUS_TRUST_FULLY = 14,
- GPGME_STATUS_TRUST_ULTIMATE = 15,
-
- GPGME_STATUS_SHM_INFO = 16, /* (legacy) */
- GPGME_STATUS_SHM_GET = 17, /* (legacy) */
- GPGME_STATUS_SHM_GET_BOOL = 18, /* (legacy) */
- GPGME_STATUS_SHM_GET_HIDDEN = 19, /* (legacy) */
-
- GPGME_STATUS_NEED_PASSPHRASE = 20,
- GPGME_STATUS_VALIDSIG = 21,
- GPGME_STATUS_SIG_ID = 22,
- GPGME_STATUS_ENC_TO = 23,
- GPGME_STATUS_NODATA = 24,
- GPGME_STATUS_BAD_PASSPHRASE = 25,
- GPGME_STATUS_NO_PUBKEY = 26,
- GPGME_STATUS_NO_SECKEY = 27,
- GPGME_STATUS_NEED_PASSPHRASE_SYM = 28,
- GPGME_STATUS_DECRYPTION_FAILED = 29,
- GPGME_STATUS_DECRYPTION_OKAY = 30,
- GPGME_STATUS_MISSING_PASSPHRASE = 31,
- GPGME_STATUS_GOOD_PASSPHRASE = 32,
- GPGME_STATUS_GOODMDC = 33,
- GPGME_STATUS_BADMDC = 34,
- GPGME_STATUS_ERRMDC = 35,
- GPGME_STATUS_IMPORTED = 36,
- GPGME_STATUS_IMPORT_OK = 37,
- GPGME_STATUS_IMPORT_PROBLEM = 38,
- GPGME_STATUS_IMPORT_RES = 39,
- GPGME_STATUS_FILE_START = 40,
- GPGME_STATUS_FILE_DONE = 41,
- GPGME_STATUS_FILE_ERROR = 42,
-
- GPGME_STATUS_BEGIN_DECRYPTION = 43,
- GPGME_STATUS_END_DECRYPTION = 44,
- GPGME_STATUS_BEGIN_ENCRYPTION = 45,
- GPGME_STATUS_END_ENCRYPTION = 46,
-
- GPGME_STATUS_DELETE_PROBLEM = 47,
- GPGME_STATUS_GET_BOOL = 48,
- GPGME_STATUS_GET_LINE = 49,
- GPGME_STATUS_GET_HIDDEN = 50,
- GPGME_STATUS_GOT_IT = 51,
- GPGME_STATUS_PROGRESS = 52,
- GPGME_STATUS_SIG_CREATED = 53,
- GPGME_STATUS_SESSION_KEY = 54,
- GPGME_STATUS_NOTATION_NAME = 55,
- GPGME_STATUS_NOTATION_DATA = 56,
- GPGME_STATUS_POLICY_URL = 57,
- GPGME_STATUS_BEGIN_STREAM = 58, /* (legacy) */
- GPGME_STATUS_END_STREAM = 59, /* (legacy) */
- GPGME_STATUS_KEY_CREATED = 60,
- GPGME_STATUS_USERID_HINT = 61,
- GPGME_STATUS_UNEXPECTED = 62,
- GPGME_STATUS_INV_RECP = 63,
- GPGME_STATUS_NO_RECP = 64,
- GPGME_STATUS_ALREADY_SIGNED = 65,
- GPGME_STATUS_SIGEXPIRED = 66, /* (legacy) */
- GPGME_STATUS_EXPSIG = 67,
- GPGME_STATUS_EXPKEYSIG = 68,
- GPGME_STATUS_TRUNCATED = 69,
- GPGME_STATUS_ERROR = 70,
- GPGME_STATUS_NEWSIG = 71,
- GPGME_STATUS_REVKEYSIG = 72,
- GPGME_STATUS_SIG_SUBPACKET = 73,
- GPGME_STATUS_NEED_PASSPHRASE_PIN = 74,
- GPGME_STATUS_SC_OP_FAILURE = 75,
- GPGME_STATUS_SC_OP_SUCCESS = 76,
- GPGME_STATUS_CARDCTRL = 77,
- GPGME_STATUS_BACKUP_KEY_CREATED = 78,
- GPGME_STATUS_PKA_TRUST_BAD = 79,
- GPGME_STATUS_PKA_TRUST_GOOD = 80,
- GPGME_STATUS_PLAINTEXT = 81,
- GPGME_STATUS_INV_SGNR = 82,
- GPGME_STATUS_NO_SGNR = 83,
- GPGME_STATUS_SUCCESS = 84,
- GPGME_STATUS_DECRYPTION_INFO = 85,
- GPGME_STATUS_PLAINTEXT_LENGTH = 86,
- GPGME_STATUS_MOUNTPOINT = 87,
- GPGME_STATUS_PINENTRY_LAUNCHED = 88,
- GPGME_STATUS_ATTRIBUTE = 89,
- GPGME_STATUS_BEGIN_SIGNING = 90,
- GPGME_STATUS_KEY_NOT_CREATED = 91,
- GPGME_STATUS_INQUIRE_MAXLEN = 92,
- GPGME_STATUS_FAILURE = 93,
- GPGME_STATUS_KEY_CONSIDERED = 94,
- GPGME_STATUS_TOFU_USER = 95,
- GPGME_STATUS_TOFU_STATS = 96,
- GPGME_STATUS_TOFU_STATS_LONG = 97,
- GPGME_STATUS_NOTATION_FLAGS = 98
- }
-gpgme_status_code_t;
-
-
/* The available signature notation flags. */
#define GPGME_SIG_NOTATION_HUMAN_READABLE 1
#define GPGME_SIG_NOTATION_CRITICAL 2
typedef unsigned int gpgme_sig_notation_flags_t;
+/* An object to hold information about notation data. This structure
+ * shall be considered read-only and an application must not allocate
+ * such a structure on its own. */
struct _gpgme_sig_notation
{
struct _gpgme_sig_notation *next;
@@ -606,7 +434,9 @@ typedef struct _gpgme_sig_notation *gpgme_sig_notation_t;
* Public structures.
*/
-/* The engine information structure. */
+/* The engine information structure.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_engine_info
{
struct _gpgme_engine_info *next;
@@ -629,7 +459,9 @@ struct _gpgme_engine_info
typedef struct _gpgme_engine_info *gpgme_engine_info_t;
-/* An object with TOFU information. */
+/* An object with TOFU information.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_tofu_info
{
struct _gpgme_tofu_info *next;
@@ -666,7 +498,9 @@ struct _gpgme_tofu_info
typedef struct _gpgme_tofu_info *gpgme_tofu_info_t;
-/* A subkey from a key. */
+/* A subkey from a key.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_subkey
{
struct _gpgme_subkey *next;
@@ -704,8 +538,11 @@ struct _gpgme_subkey
/* True if the secret key is stored on a smart card. */
unsigned int is_cardkey : 1;
+ /* True if the key is compliant to the de-vs mode. */
+ unsigned int is_de_vs : 1;
+
/* Internal to GPGME, do not use. */
- unsigned int _unused : 21;
+ unsigned int _unused : 20;
/* Public key algorithm supported by this subkey. */
gpgme_pubkey_algo_t pubkey_algo;
@@ -740,7 +577,9 @@ struct _gpgme_subkey
typedef struct _gpgme_subkey *gpgme_subkey_t;
-/* A signature on a user ID. */
+/* A signature on a user ID.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_key_sig
{
struct _gpgme_key_sig *next;
@@ -809,7 +648,9 @@ struct _gpgme_key_sig
typedef struct _gpgme_key_sig *gpgme_key_sig_t;
-/* An user ID from a key. */
+/* An user ID from a key.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_user_id
{
struct _gpgme_user_id *next;
@@ -821,7 +662,10 @@ struct _gpgme_user_id
unsigned int invalid : 1;
/* Internal to GPGME, do not use. */
- unsigned int _unused : 30;
+ unsigned int _unused : 25;
+
+ /* Origin of this user ID. */
+ unsigned int origin : 5;
/* The validity of the user ID. */
gpgme_validity_t validity;
@@ -852,11 +696,16 @@ struct _gpgme_user_id
/* The malloced TOFU information or NULL. */
gpgme_tofu_info_t tofu;
+
+ /* Time of the last refresh of thsi user id. 0 if unknown. */
+ unsigned long last_update;
};
typedef struct _gpgme_user_id *gpgme_user_id_t;
-/* A key from the keyring. */
+/* A key from the keyring.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_key
{
/* Internal to GPGME, do not use. */
@@ -893,7 +742,10 @@ struct _gpgme_key
unsigned int is_qualified : 1;
/* Internal to GPGME, do not use. */
- unsigned int _unused : 22;
+ unsigned int _unused : 17;
+
+ /* Origin of this key. */
+ unsigned int origin : 5;
/* This is the protocol supported by this key. */
gpgme_protocol_t protocol;
@@ -933,11 +785,16 @@ struct _gpgme_key
* this is a copy of the FPR of the first subkey. We need it here
* to allow for an incomplete key object. */
char *fpr;
+
+ /* Time of the last refresh of the entire key. 0 if unknown. */
+ unsigned long last_update;
};
typedef struct _gpgme_key *gpgme_key_t;
-/* An invalid key object. */
+/* An invalid key object.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_invalid_key
{
struct _gpgme_invalid_key *next;
@@ -976,13 +833,6 @@ typedef gpgme_error_t (*gpgme_interact_cb_t) (void *opaque,
const char *keyword,
const char *args, int fd);
-/* The callback type used by the deprecated functions gpgme_op_edit
- * and gpgme_op_card_edit. */
-typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque,
- gpgme_status_code_t status,
- const char *args, int fd);
-
-
/*
@@ -1122,33 +972,6 @@ unsigned int gpgme_signers_count (const gpgme_ctx_t ctx);
/* Return the SEQth signer's key in CTX. */
gpgme_key_t gpgme_signers_enum (const gpgme_ctx_t ctx, int seq);
-/* Retrieve the signature status of signature IDX in CTX after a
- successful verify operation in R_STAT (if non-null). The creation
- time stamp of the signature is returned in R_CREATED (if non-null).
- The function returns a string containing the fingerprint.
- Deprecated, use verify result directly. */
-const char *gpgme_get_sig_status (gpgme_ctx_t ctx, int idx,
- _gpgme_sig_stat_t *r_stat,
- time_t *r_created) _GPGME_DEPRECATED(0,4);
-
-/* Retrieve certain attributes of a signature. IDX is the index
- number of the signature after a successful verify operation. WHAT
- is an attribute where GPGME_ATTR_EXPIRE is probably the most useful
- one. WHATIDX is to be passed as 0 for most attributes . */
-unsigned long gpgme_get_sig_ulong_attr (gpgme_ctx_t c, int idx,
- _gpgme_attr_t what, int whatidx)
- _GPGME_DEPRECATED(0,4);
-const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx,
- _gpgme_attr_t what, int whatidx)
- _GPGME_DEPRECATED(0,4);
-
-
-/* Get the key used to create signature IDX in CTX and return it in
- R_KEY. */
-gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key)
- _GPGME_DEPRECATED(0,4);
-
-
/* Clear all notation data from the context. */
void gpgme_sig_notation_clear (gpgme_ctx_t ctx);
@@ -1360,15 +1183,6 @@ gpg_error_t gpgme_data_set_flag (gpgme_data_t dh,
gpgme_data_type_t gpgme_data_identify (gpgme_data_t dh, int reserved);
-/* Create a new data buffer which retrieves the data from the callback
- function READ_CB. Deprecated, please use gpgme_data_new_from_cbs
- instead. */
-gpgme_error_t gpgme_data_new_with_read_cb (gpgme_data_t *r_dh,
- int (*read_cb) (void*,char *,
- size_t,size_t*),
- void *read_cb_value)
- _GPGME_DEPRECATED(0,4);
-
/* Create a new data buffer filled with the content of file FNAME.
COPY must be non-zero. For delayed read, please use
gpgme_data_new_from_fd or gpgme_data_new_from_stream instead. */
@@ -1383,9 +1197,8 @@ gpgme_error_t gpgme_data_new_from_filepart (gpgme_data_t *r_dh,
const char *fname, FILE *fp,
@API__OFF_T@ offset, size_t length);
-/* Reset the read pointer in DH. Deprecated, please use
- gpgme_data_seek instead. */
-gpgme_error_t gpgme_data_rewind (gpgme_data_t dh) _GPGME_DEPRECATED(0,4);
+/* Convenience function to do a gpgme_data_seek (dh, 0, SEEK_SET). */
+gpgme_error_t gpgme_data_rewind (gpgme_data_t dh);
@@ -1409,46 +1222,15 @@ void gpgme_key_ref (gpgme_key_t key);
void gpgme_key_unref (gpgme_key_t key);
void gpgme_key_release (gpgme_key_t key);
-/* Return the value of the attribute WHAT of KEY, which has to be
- representable by a string. IDX specifies the sub key or user ID
- for attributes related to sub keys or user IDs. Deprecated, use
- key structure directly instead. */
-const char *gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of KEY, which has to be
- representable by an unsigned integer. IDX specifies the sub key or
- user ID for attributes related to sub keys or user IDs.
- Deprecated, use key structure directly instead. */
-unsigned long gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of a signature on user ID
- UID_IDX in KEY, which has to be representable by a string. IDX
- specifies the signature. Deprecated, use key structure directly
- instead. */
-const char *gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
- _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of a signature on user ID
- UID_IDX in KEY, which has to be representable by an unsigned
- integer string. IDX specifies the signature. Deprecated, use key
- structure directly instead. */
-unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx,
- _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
/*
* Encryption.
*/
+/* An object to return results from an encryption operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_encrypt_result
{
/* The list of invalid recipients. */
@@ -1467,7 +1249,9 @@ typedef enum
GPGME_ENCRYPT_PREPARE = 4,
GPGME_ENCRYPT_EXPECT_SIGN = 8,
GPGME_ENCRYPT_NO_COMPRESS = 16,
- GPGME_ENCRYPT_SYMMETRIC = 32
+ GPGME_ENCRYPT_SYMMETRIC = 32,
+ GPGME_ENCRYPT_THROW_KEYIDS = 64,
+ GPGME_ENCRYPT_WRAP = 128
}
gpgme_encrypt_flags_t;
@@ -1497,6 +1281,9 @@ gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
* Decryption.
*/
+/* An object to hold information about a recipient.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_recipient
{
struct _gpgme_recipient *next;
@@ -1515,6 +1302,9 @@ struct _gpgme_recipient
};
typedef struct _gpgme_recipient *gpgme_recipient_t;
+/* An object to return results from a decryption operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_decrypt_result
{
char *unsupported_algorithm;
@@ -1540,6 +1330,14 @@ typedef struct _gpgme_op_decrypt_result *gpgme_decrypt_result_t;
/* Retrieve a pointer to the result of the decrypt operation. */
gpgme_decrypt_result_t gpgme_op_decrypt_result (gpgme_ctx_t ctx);
+/* The valid decryption flags. */
+typedef enum
+ {
+ GPGME_DECRYPT_VERIFY = 1,
+ GPGME_DECRYPT_UNWRAP = 128
+ }
+gpgme_decrypt_flags_t;
+
/* Decrypt ciphertext CIPHER within CTX and store the resulting
plaintext in PLAIN. */
gpgme_error_t gpgme_op_decrypt_start (gpgme_ctx_t ctx, gpgme_data_t cipher,
@@ -1555,11 +1353,27 @@ gpgme_error_t gpgme_op_decrypt_verify_start (gpgme_ctx_t ctx,
gpgme_error_t gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher,
gpgme_data_t plain);
+/* Decrypt ciphertext CIPHER within CTX and store the resulting
+ * plaintext in PLAIN. With the flag GPGME_DECRYPT_VERIFY also do a
+ * signature verification pn the plaintext. */
+gpgme_error_t gpgme_op_decrypt_ext_start (gpgme_ctx_t ctx,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher,
+ gpgme_data_t plain);
+gpgme_error_t gpgme_op_decrypt_ext (gpgme_ctx_t ctx,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher,
+ gpgme_data_t plain);
+
+
/*
* Signing.
*/
+/* An object with signatures data.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_new_signature
{
struct _gpgme_new_signature *next;
@@ -1595,6 +1409,10 @@ struct _gpgme_new_signature
};
typedef struct _gpgme_new_signature *gpgme_new_signature_t;
+
+/* An object to return results from a signing operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_sign_result
{
/* The list of invalid signers. */
@@ -1638,6 +1456,9 @@ typedef enum
gpgme_sigsum_t;
+/* An object to hold the verification status of a signature.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_signature
{
struct _gpgme_signature *next;
@@ -1690,6 +1511,9 @@ struct _gpgme_signature
};
typedef struct _gpgme_signature *gpgme_signature_t;
+/* An object to return the results of a verify operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_verify_result
{
gpgme_signature_t signatures;
@@ -1723,6 +1547,9 @@ gpgme_error_t gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig,
#define GPGME_IMPORT_SECRET 16 /* The key contained a secret key. */
+/* An object to hold results for one imported key.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_import_status
{
struct _gpgme_import_status *next;
@@ -1741,7 +1568,9 @@ struct _gpgme_import_status
};
typedef struct _gpgme_import_status *gpgme_import_status_t;
-/* Import result object. */
+/* Import result object.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_import_result
{
/* Number of considered keys. */
@@ -1797,8 +1626,6 @@ gpgme_import_result_t gpgme_op_import_result (gpgme_ctx_t ctx);
/* Import the key in KEYDATA into the keyring. */
gpgme_error_t gpgme_op_import_start (gpgme_ctx_t ctx, gpgme_data_t keydata);
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(0,4);
/* 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[]);
@@ -1848,7 +1675,11 @@ gpgme_error_t gpgme_op_export_keys (gpgme_ctx_t ctx,
#define GPGME_CREATE_WANTPUB (1 << 10) /* Return the public key. */
#define GPGME_CREATE_WANTSEC (1 << 11) /* Return the secret key. */
#define GPGME_CREATE_FORCE (1 << 12) /* Force creation. */
+#define GPGME_CREATE_NOEXPIRE (1 << 13) /* Create w/o expiration. */
+/* An object to return result from a key generation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_genkey_result
{
/* A primary key was generated. */
@@ -1929,6 +1760,13 @@ gpgme_error_t gpgme_op_revuid (gpgme_ctx_t ctx,
gpgme_key_t key, const char *userid,
unsigned int reserved);
+/* Set a flag on the USERID of KEY. See the manual for supported flags. */
+gpgme_error_t gpgme_op_set_uid_flag_start (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value);
+gpgme_error_t gpgme_op_set_uid_flag (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value);
/* Retrieve a pointer to the result of a genkey, createkey, or
@@ -1989,21 +1827,6 @@ gpgme_error_t gpgme_op_interact (gpgme_ctx_t ctx, gpgme_key_t key,
void *fnc_value,
gpgme_data_t out);
-gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
- gpgme_edit_cb_t fnc, void *fnc_value,
- gpgme_data_t out) _GPGME_DEPRECATED(1,7);
-gpgme_error_t gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
- gpgme_edit_cb_t fnc, void *fnc_value,
- gpgme_data_t out) _GPGME_DEPRECATED(1,7);
-gpgme_error_t gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
- gpgme_edit_cb_t fnc, void *fnc_value,
- gpgme_data_t out)
- _GPGME_DEPRECATED(1,7);
-gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
- gpgme_edit_cb_t fnc, void *fnc_value,
- gpgme_data_t out)
- _GPGME_DEPRECATED(1,7);
-
/* Set the Tofu policy of KEY to POLCIY. */
gpgme_error_t gpgme_op_tofu_policy_start (gpgme_ctx_t ctx,
@@ -2020,6 +1843,9 @@ gpgme_error_t gpgme_op_tofu_policy (gpgme_ctx_t ctx,
* Key listing
*/
+/* An object to return results from a key listing operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_keylist_result
{
unsigned int truncated : 1;
@@ -2033,20 +1859,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,
@@ -2060,6 +1897,9 @@ gpgme_error_t gpgme_op_passwd (gpgme_ctx_t ctx, gpgme_key_t key,
* Trust items and operations.
*/
+/* An object to hold data of a trust item.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_trust_item
{
/* Internal to GPGME, do not use. */
@@ -2113,26 +1953,6 @@ void gpgme_trust_item_ref (gpgme_trust_item_t item);
item is destroyed. */
void gpgme_trust_item_unref (gpgme_trust_item_t item);
-/* Release the trust item ITEM. Deprecated, use
- gpgme_trust_item_unref. */
-void gpgme_trust_item_release (gpgme_trust_item_t item) _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of ITEM, which has to be
- representable by a string. Deprecated, use trust item structure
- directly. */
-const char *gpgme_trust_item_get_string_attr (gpgme_trust_item_t item,
- _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
-/* Return the value of the attribute WHAT of KEY, which has to be
- representable by an integer. IDX specifies a running index if the
- attribute appears more than once in the key. Deprecated, use trust
- item structure directly. */
-int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what,
- const void *reserved, int idx)
- _GPGME_DEPRECATED(0,4);
-
/*
@@ -2209,35 +2029,14 @@ gpgme_error_t gpgme_op_assuan_transact_ext (gpgme_ctx_t ctx,
void *stat_cb_value,
gpgme_error_t *op_err);
-/* Compat. */
-struct _gpgme_op_assuan_result
-{
- /* Deprecated. Use the second value in a DONE event or the
- synchronous variant gpgme_op_assuan_transact_ext. */
- gpgme_error_t err _GPGME_DEPRECATED_OUTSIDE_GPGME(1,2);
-};
-typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t;
-
-
-/* Return the result of the last Assuan command. */
-gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx)
- _GPGME_DEPRECATED(1,2);
-
-gpgme_error_t
-gpgme_op_assuan_transact (gpgme_ctx_t ctx,
- const char *command,
- gpgme_assuan_data_cb_t data_cb,
- void *data_cb_value,
- gpgme_assuan_inquire_cb_t inq_cb,
- void *inq_cb_value,
- gpgme_assuan_status_cb_t status_cb,
- void *status_cb_value) _GPGME_DEPRECATED(1,2);
-
/*
* Crypto container support.
*/
+/* An object to return results from a VFS mount operation.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
struct _gpgme_op_vfs_mount_result
{
char *mount_dir;
@@ -2410,7 +2209,8 @@ void gpgme_conf_arg_release (gpgme_conf_arg_t arg, gpgme_conf_type_t type);
/* Register a change for the value of OPT to ARG. If RESET is 1 (do
not use any values but 0 or 1), ARG is ignored and the option is
not changed (reverting a previous change). Otherwise, if ARG is
- NULL, the option is cleared or reset to its default. */
+ NULL, the option is cleared or reset to its default. The change
+ is done with gpgconf's --runtime option to immediately take effect. */
gpgme_error_t gpgme_conf_opt_change (gpgme_conf_opt_t opt, int reset,
gpgme_conf_arg_t arg);
@@ -2425,7 +2225,9 @@ gpgme_error_t gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p);
gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp);
-/* Information about software versions. */
+/* Information about software versions.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
typedef struct _gpgme_op_query_swdb_result
{
/* RFU */
@@ -2552,8 +2354,323 @@ char *gpgme_addrspec_from_uid (const char *uid);
/*
- * Deprecated types.
+ * Deprecated types, constants and functions.
*/
+
+/* The possible stati for gpgme_op_edit. The use of that function and
+ * these status codes are deprecated in favor of gpgme_op_interact. */
+typedef enum
+ {
+ GPGME_STATUS_EOF = 0,
+ /* mkstatus processing starts here */
+ GPGME_STATUS_ENTER = 1,
+ GPGME_STATUS_LEAVE = 2,
+ GPGME_STATUS_ABORT = 3,
+
+ GPGME_STATUS_GOODSIG = 4,
+ GPGME_STATUS_BADSIG = 5,
+ GPGME_STATUS_ERRSIG = 6,
+
+ GPGME_STATUS_BADARMOR = 7,
+
+ GPGME_STATUS_RSA_OR_IDEA = 8, /* (legacy) */
+ GPGME_STATUS_KEYEXPIRED = 9,
+ GPGME_STATUS_KEYREVOKED = 10,
+
+ GPGME_STATUS_TRUST_UNDEFINED = 11,
+ GPGME_STATUS_TRUST_NEVER = 12,
+ GPGME_STATUS_TRUST_MARGINAL = 13,
+ GPGME_STATUS_TRUST_FULLY = 14,
+ GPGME_STATUS_TRUST_ULTIMATE = 15,
+
+ GPGME_STATUS_SHM_INFO = 16, /* (legacy) */
+ GPGME_STATUS_SHM_GET = 17, /* (legacy) */
+ GPGME_STATUS_SHM_GET_BOOL = 18, /* (legacy) */
+ GPGME_STATUS_SHM_GET_HIDDEN = 19, /* (legacy) */
+
+ GPGME_STATUS_NEED_PASSPHRASE = 20,
+ GPGME_STATUS_VALIDSIG = 21,
+ GPGME_STATUS_SIG_ID = 22,
+ GPGME_STATUS_ENC_TO = 23,
+ GPGME_STATUS_NODATA = 24,
+ GPGME_STATUS_BAD_PASSPHRASE = 25,
+ GPGME_STATUS_NO_PUBKEY = 26,
+ GPGME_STATUS_NO_SECKEY = 27,
+ GPGME_STATUS_NEED_PASSPHRASE_SYM = 28,
+ GPGME_STATUS_DECRYPTION_FAILED = 29,
+ GPGME_STATUS_DECRYPTION_OKAY = 30,
+ GPGME_STATUS_MISSING_PASSPHRASE = 31,
+ GPGME_STATUS_GOOD_PASSPHRASE = 32,
+ GPGME_STATUS_GOODMDC = 33,
+ GPGME_STATUS_BADMDC = 34,
+ GPGME_STATUS_ERRMDC = 35,
+ GPGME_STATUS_IMPORTED = 36,
+ GPGME_STATUS_IMPORT_OK = 37,
+ GPGME_STATUS_IMPORT_PROBLEM = 38,
+ GPGME_STATUS_IMPORT_RES = 39,
+ GPGME_STATUS_FILE_START = 40,
+ GPGME_STATUS_FILE_DONE = 41,
+ GPGME_STATUS_FILE_ERROR = 42,
+
+ GPGME_STATUS_BEGIN_DECRYPTION = 43,
+ GPGME_STATUS_END_DECRYPTION = 44,
+ GPGME_STATUS_BEGIN_ENCRYPTION = 45,
+ GPGME_STATUS_END_ENCRYPTION = 46,
+
+ GPGME_STATUS_DELETE_PROBLEM = 47,
+ GPGME_STATUS_GET_BOOL = 48,
+ GPGME_STATUS_GET_LINE = 49,
+ GPGME_STATUS_GET_HIDDEN = 50,
+ GPGME_STATUS_GOT_IT = 51,
+ GPGME_STATUS_PROGRESS = 52,
+ GPGME_STATUS_SIG_CREATED = 53,
+ GPGME_STATUS_SESSION_KEY = 54,
+ GPGME_STATUS_NOTATION_NAME = 55,
+ GPGME_STATUS_NOTATION_DATA = 56,
+ GPGME_STATUS_POLICY_URL = 57,
+ GPGME_STATUS_BEGIN_STREAM = 58, /* (legacy) */
+ GPGME_STATUS_END_STREAM = 59, /* (legacy) */
+ GPGME_STATUS_KEY_CREATED = 60,
+ GPGME_STATUS_USERID_HINT = 61,
+ GPGME_STATUS_UNEXPECTED = 62,
+ GPGME_STATUS_INV_RECP = 63,
+ GPGME_STATUS_NO_RECP = 64,
+ GPGME_STATUS_ALREADY_SIGNED = 65,
+ GPGME_STATUS_SIGEXPIRED = 66, /* (legacy) */
+ GPGME_STATUS_EXPSIG = 67,
+ GPGME_STATUS_EXPKEYSIG = 68,
+ GPGME_STATUS_TRUNCATED = 69,
+ GPGME_STATUS_ERROR = 70,
+ GPGME_STATUS_NEWSIG = 71,
+ GPGME_STATUS_REVKEYSIG = 72,
+ GPGME_STATUS_SIG_SUBPACKET = 73,
+ GPGME_STATUS_NEED_PASSPHRASE_PIN = 74,
+ GPGME_STATUS_SC_OP_FAILURE = 75,
+ GPGME_STATUS_SC_OP_SUCCESS = 76,
+ GPGME_STATUS_CARDCTRL = 77,
+ GPGME_STATUS_BACKUP_KEY_CREATED = 78,
+ GPGME_STATUS_PKA_TRUST_BAD = 79,
+ GPGME_STATUS_PKA_TRUST_GOOD = 80,
+ GPGME_STATUS_PLAINTEXT = 81,
+ GPGME_STATUS_INV_SGNR = 82,
+ GPGME_STATUS_NO_SGNR = 83,
+ GPGME_STATUS_SUCCESS = 84,
+ GPGME_STATUS_DECRYPTION_INFO = 85,
+ GPGME_STATUS_PLAINTEXT_LENGTH = 86,
+ GPGME_STATUS_MOUNTPOINT = 87,
+ GPGME_STATUS_PINENTRY_LAUNCHED = 88,
+ GPGME_STATUS_ATTRIBUTE = 89,
+ GPGME_STATUS_BEGIN_SIGNING = 90,
+ GPGME_STATUS_KEY_NOT_CREATED = 91,
+ GPGME_STATUS_INQUIRE_MAXLEN = 92,
+ GPGME_STATUS_FAILURE = 93,
+ GPGME_STATUS_KEY_CONSIDERED = 94,
+ GPGME_STATUS_TOFU_USER = 95,
+ GPGME_STATUS_TOFU_STATS = 96,
+ GPGME_STATUS_TOFU_STATS_LONG = 97,
+ GPGME_STATUS_NOTATION_FLAGS = 98
+ }
+gpgme_status_code_t;
+
+/* The callback type used by the deprecated functions gpgme_op_edit
+ * and gpgme_op_card_edit. */
+typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque,
+ gpgme_status_code_t status,
+ const char *args, int fd);
+
+gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
+ gpgme_edit_cb_t fnc, void *fnc_value,
+ gpgme_data_t out) _GPGME_DEPRECATED(1,7);
+gpgme_error_t gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
+ gpgme_edit_cb_t fnc, void *fnc_value,
+ gpgme_data_t out) _GPGME_DEPRECATED(1,7);
+gpgme_error_t gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
+ gpgme_edit_cb_t fnc, void *fnc_value,
+ gpgme_data_t out)
+ _GPGME_DEPRECATED(1,7);
+gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
+ gpgme_edit_cb_t fnc, void *fnc_value,
+ gpgme_data_t out)
+ _GPGME_DEPRECATED(1,7);
+
+/* The possible signature stati. Deprecated, use error value in sig
+ status. */
+typedef enum
+ {
+ GPGME_SIG_STAT_NONE = 0,
+ GPGME_SIG_STAT_GOOD = 1,
+ GPGME_SIG_STAT_BAD = 2,
+ GPGME_SIG_STAT_NOKEY = 3,
+ GPGME_SIG_STAT_NOSIG = 4,
+ GPGME_SIG_STAT_ERROR = 5,
+ GPGME_SIG_STAT_DIFF = 6,
+ GPGME_SIG_STAT_GOOD_EXP = 7,
+ GPGME_SIG_STAT_GOOD_EXPKEY = 8
+ }
+_gpgme_sig_stat_t;
+typedef _gpgme_sig_stat_t gpgme_sig_stat_t _GPGME_DEPRECATED(0,4);
+
+/* The available key and signature attributes. Deprecated, use the
+ individual result structures instead. */
+typedef enum
+ {
+ GPGME_ATTR_KEYID = 1,
+ GPGME_ATTR_FPR = 2,
+ GPGME_ATTR_ALGO = 3,
+ GPGME_ATTR_LEN = 4,
+ GPGME_ATTR_CREATED = 5,
+ GPGME_ATTR_EXPIRE = 6,
+ GPGME_ATTR_OTRUST = 7,
+ GPGME_ATTR_USERID = 8,
+ GPGME_ATTR_NAME = 9,
+ GPGME_ATTR_EMAIL = 10,
+ GPGME_ATTR_COMMENT = 11,
+ GPGME_ATTR_VALIDITY = 12,
+ GPGME_ATTR_LEVEL = 13,
+ GPGME_ATTR_TYPE = 14,
+ GPGME_ATTR_IS_SECRET = 15,
+ GPGME_ATTR_KEY_REVOKED = 16,
+ GPGME_ATTR_KEY_INVALID = 17,
+ GPGME_ATTR_UID_REVOKED = 18,
+ GPGME_ATTR_UID_INVALID = 19,
+ GPGME_ATTR_KEY_CAPS = 20,
+ GPGME_ATTR_CAN_ENCRYPT = 21,
+ GPGME_ATTR_CAN_SIGN = 22,
+ GPGME_ATTR_CAN_CERTIFY = 23,
+ GPGME_ATTR_KEY_EXPIRED = 24,
+ GPGME_ATTR_KEY_DISABLED = 25,
+ GPGME_ATTR_SERIAL = 26,
+ GPGME_ATTR_ISSUER = 27,
+ GPGME_ATTR_CHAINID = 28,
+ GPGME_ATTR_SIG_STATUS = 29,
+ GPGME_ATTR_ERRTOK = 30,
+ GPGME_ATTR_SIG_SUMMARY = 31,
+ GPGME_ATTR_SIG_CLASS = 32
+ }
+_gpgme_attr_t;
+typedef _gpgme_attr_t gpgme_attr_t _GPGME_DEPRECATED(0,4);
+
+/* Retrieve the signature status of signature IDX in CTX after a
+ successful verify operation in R_STAT (if non-null). The creation
+ time stamp of the signature is returned in R_CREATED (if non-null).
+ The function returns a string containing the fingerprint.
+ Deprecated, use verify result directly. */
+const char *gpgme_get_sig_status (gpgme_ctx_t ctx, int idx,
+ _gpgme_sig_stat_t *r_stat,
+ time_t *r_created) _GPGME_DEPRECATED(0,4);
+
+/* Retrieve certain attributes of a signature. IDX is the index
+ number of the signature after a successful verify operation. WHAT
+ is an attribute where GPGME_ATTR_EXPIRE is probably the most useful
+ one. WHATIDX is to be passed as 0 for most attributes . */
+unsigned long gpgme_get_sig_ulong_attr (gpgme_ctx_t c, int idx,
+ _gpgme_attr_t what, int whatidx)
+ _GPGME_DEPRECATED(0,4);
+const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx,
+ _gpgme_attr_t what, int whatidx)
+ _GPGME_DEPRECATED(0,4);
+
+
+/* Get the key used to create signature IDX in CTX and return it in
+ R_KEY. */
+gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key)
+ _GPGME_DEPRECATED(0,4);
+
+/* Create a new data buffer which retrieves the data from the callback
+ function READ_CB. Deprecated, please use gpgme_data_new_from_cbs
+ instead. */
+gpgme_error_t gpgme_data_new_with_read_cb (gpgme_data_t *r_dh,
+ int (*read_cb) (void*,char *,
+ size_t,size_t*),
+ void *read_cb_value)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+ representable by a string. IDX specifies the sub key or user ID
+ for attributes related to sub keys or user IDs. Deprecated, use
+ key structure directly instead. */
+const char *gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+ representable by an unsigned integer. IDX specifies the sub key or
+ user ID for attributes related to sub keys or user IDs.
+ Deprecated, use key structure directly instead. */
+unsigned long gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of a signature on user ID
+ UID_IDX in KEY, which has to be representable by a string. IDX
+ specifies the signature. Deprecated, use key structure directly
+ instead. */
+const char *gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
+ _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of a signature on user ID
+ UID_IDX in KEY, which has to be representable by an unsigned
+ integer string. IDX specifies the signature. Deprecated, use key
+ structure directly instead. */
+unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx,
+ _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+
+gpgme_error_t gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata,
+ int *nr) _GPGME_DEPRECATED(0,4);
+
+/* Release the trust item ITEM. Deprecated, use
+ gpgme_trust_item_unref. */
+void gpgme_trust_item_release (gpgme_trust_item_t item) _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of ITEM, which has to be
+ representable by a string. Deprecated, use trust item structure
+ directly. */
+const char *gpgme_trust_item_get_string_attr (gpgme_trust_item_t item,
+ _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Return the value of the attribute WHAT of KEY, which has to be
+ representable by an integer. IDX specifies a running index if the
+ attribute appears more than once in the key. Deprecated, use trust
+ item structure directly. */
+int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what,
+ const void *reserved, int idx)
+ _GPGME_DEPRECATED(0,4);
+
+/* Compat.
+ * This structure shall be considered read-only and an application
+ * must not allocate such a structure on its own. */
+struct _gpgme_op_assuan_result
+{
+ /* Deprecated. Use the second value in a DONE event or the
+ synchronous variant gpgme_op_assuan_transact_ext. */
+ gpgme_error_t err _GPGME_DEPRECATED_OUTSIDE_GPGME(1,2);
+};
+typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t;
+
+
+/* Return the result of the last Assuan command. */
+gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx)
+ _GPGME_DEPRECATED(1,2);
+
+gpgme_error_t
+gpgme_op_assuan_transact (gpgme_ctx_t ctx,
+ const char *command,
+ gpgme_assuan_data_cb_t data_cb,
+ void *data_cb_value,
+ gpgme_assuan_inquire_cb_t inq_cb,
+ void *inq_cb_value,
+ gpgme_assuan_status_cb_t status_cb,
+ void *status_cb_value) _GPGME_DEPRECATED(1,2);
+
+
+
typedef gpgme_ctx_t GpgmeCtx _GPGME_DEPRECATED(0,4);
typedef gpgme_data_t GpgmeData _GPGME_DEPRECATED(0,4);
typedef gpgme_error_t GpgmeError _GPGME_DEPRECATED(0,4);
diff --git a/src/import.c b/src/import.c
index 6233a15..4173fe9 100644
--- a/src/import.c
+++ b/src/import.c
@@ -193,7 +193,7 @@ parse_import_res (char *args, gpgme_import_result_t result)
#define PARSE_NEXT(x) \
(x) = strtol (args, &tail, 0); \
- if (errno || args == tail || *tail != ' ') \
+ if (errno || args == tail || !(*tail == ' ' || !*tail)) \
/* The crypto backend does not behave. */ \
return trace_gpg_error (GPG_ERR_INV_ENGINE); \
args = tail;
@@ -249,7 +249,7 @@ import_status_handler (void *priv, gpgme_status_code_t code, char *args)
default:
break;
}
- return 0;
+ return err;
}
diff --git a/src/key.c b/src/key.c
index 38acc71..e2e30db 100644
--- a/src/key.c
+++ b/src/key.c
@@ -236,11 +236,13 @@ _gpgme_key_append_name (gpgme_key_t key, const char *src, int convert)
&uid->comment, dst);
uid->address = _gpgme_mailbox_from_userid (uid->uid);
- if (uid->address && uid->email && !strcmp (uid->address, uid->email))
+ if ((!uid->email || !*uid->email) && uid->address && uid->name
+ && !strcmp (uid->name, uid->address))
{
- /* The ADDRESS is the same as EMAIL: Save some space. */
- free (uid->address);
- uid->address = uid->email;
+ /* Name and address are the same. This is a mailbox only key.
+ Use address as email and remove name. */
+ *uid->name = '\0';
+ uid->email = uid->address;
}
if (!key->uids)
@@ -339,14 +341,10 @@ gpgme_key_unref (gpgme_key_t key)
while (subkey)
{
gpgme_subkey_t next = subkey->next;
- if (subkey->fpr)
- free (subkey->fpr);
- if (subkey->curve)
- free (subkey->curve);
- if (subkey->keygrip)
- free (subkey->keygrip);
- if (subkey->card_number)
- free (subkey->card_number);
+ free (subkey->fpr);
+ free (subkey->curve);
+ free (subkey->keygrip);
+ free (subkey->card_number);
free (subkey);
subkey = next;
}
@@ -386,22 +384,15 @@ gpgme_key_unref (gpgme_key_t key)
tofu = tofu_next;
}
- if (uid->address && uid->address != uid->email)
- free (uid->address);
-
+ free (uid->address);
free (uid);
uid = next_uid;
}
- if (key->issuer_serial)
- free (key->issuer_serial);
- if (key->issuer_name)
- free (key->issuer_name);
-
- if (key->chain_id)
- free (key->chain_id);
- if (key->fpr)
- free (key->fpr);
+ free (key->issuer_serial);
+ free (key->issuer_name);
+ free (key->chain_id);
+ free (key->fpr);
free (key);
}
diff --git a/src/keylist.c b/src/keylist.c
index 2ce0846..e16ba4d 100644
--- a/src/keylist.c
+++ b/src/keylist.c
@@ -416,6 +416,23 @@ parse_sec_field15 (gpgme_key_t key, gpgme_subkey_t subkey, char *field)
}
+/* Parse the compliance field. */
+static void
+parse_pub_field18 (gpgme_subkey_t subkey, char *field)
+{
+ char *p, *endp;
+ unsigned long ul;
+
+ for (p = field; p && (ul = strtoul (p, &endp, 10)) && p != endp; p = endp)
+ {
+ switch (ul)
+ {
+ case 23: subkey->is_de_vs = 1; break;
+ }
+ }
+}
+
+
/* Parse a tfs record. */
static gpg_error_t
parse_tfs_record (gpgme_user_id_t uid, char **field, int nfield)
@@ -535,7 +552,7 @@ keylist_colon_handler (void *priv, char *line)
RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
}
rectype = RT_NONE;
-#define NR_FIELDS 17
+#define NR_FIELDS 20
char *field[NR_FIELDS];
int fields = 0;
void *hook;
@@ -712,6 +729,16 @@ keylist_colon_handler (void *priv, char *line)
return gpg_error_from_syserror ();
}
+ /* Field 18 has the compliance flags. */
+ if (fields >= 17 && *field[17])
+ parse_pub_field18 (subkey, field[17]);
+
+ if (fields >= 20)
+ {
+ key->last_update = _gpgme_parse_timestamp_ul (field[18]);
+ key->origin = 0; /* Fixme: Not yet defined in gpg. */
+ }
+
break;
case RT_SUB:
@@ -785,6 +812,10 @@ keylist_colon_handler (void *priv, char *line)
return gpg_error_from_syserror ();
}
+ /* Field 18 has the compliance flags. */
+ if (fields >= 17 && *field[17])
+ parse_pub_field18 (subkey, field[17]);
+
break;
case RT_UID:
@@ -793,12 +824,15 @@ keylist_colon_handler (void *priv, char *line)
{
if (_gpgme_key_append_name (key, field[9], 1))
return gpg_error (GPG_ERR_ENOMEM); /* FIXME */
- else
- {
- if (field[1])
- set_userid_flags (key, field[1]);
- opd->tmp_uid = key->_last_uid;
- }
+
+ if (field[1])
+ set_userid_flags (key, field[1]);
+ opd->tmp_uid = key->_last_uid;
+ if (fields >= 20)
+ {
+ opd->tmp_uid->last_update = _gpgme_parse_timestamp_ul (field[18]);
+ opd->tmp_uid->origin = 0; /* Fixme: Not yet defined in gpg. */
+ }
}
break;
@@ -1117,6 +1151,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 a55cd10..adc8d7d 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -126,6 +126,12 @@ GPGME_1.1 {
gpgme_op_query_swdb;
gpgme_op_query_swdb_result;
+
+ gpgme_op_set_uid_flag_start;
+ gpgme_op_set_uid_flag;
+
+ gpgme_op_decrypt_ext;
+ gpgme_op_decrypt_ext_start;
};
@@ -223,6 +229,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/src/op-support.c b/src/op-support.c
index d9217ec..817c569 100644
--- a/src/op-support.c
+++ b/src/op-support.c
@@ -94,6 +94,7 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
_gpgme_release_result (ctx);
LOCK (ctx->lock);
ctx->canceled = 0;
+ ctx->redraw_suggested = 0;
UNLOCK (ctx->lock);
if (ctx->engine && no_reset)
diff --git a/src/ops.h b/src/ops.h
index 97b1019..cc61dc4 100644
--- a/src/ops.h
+++ b/src/ops.h
@@ -89,6 +89,9 @@ gpgme_error_t _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx);
gpgme_error_t _gpgme_decrypt_status_handler (void *priv,
gpgme_status_code_t code,
char *args);
+gpgme_error_t _gpgme_decrypt_start (gpgme_ctx_t ctx, int synchronous,
+ gpgme_decrypt_flags_t flags,
+ gpgme_data_t cipher, gpgme_data_t plain);
/* From signers.c. */
diff --git a/src/posix-io.c b/src/posix-io.c
index 5296f5f..a351806 100644
--- a/src/posix-io.c
+++ b/src/posix-io.c
@@ -287,37 +287,43 @@ get_max_fds (void)
int rc;
/* Under Linux we can figure out the highest used file descriptor by
- * reading /proc/self/fd. This is in the common cases much fast than
- * for example doing 4096 close calls where almost all of them will
- * fail. */
-#ifdef __linux__
- {
- DIR *dir = NULL;
- struct dirent *dir_entry;
- const char *s;
- int x;
-
- dir = opendir ("/proc/self/fd");
- if (dir)
- {
- while ((dir_entry = readdir (dir)))
- {
- s = dir_entry->d_name;
- if ( *s < '0' || *s > '9')
- continue;
- x = atoi (s);
- if (x > fds)
- fds = x;
- }
- closedir (dir);
- }
- if (fds != -1)
- {
- fds++;
- source = "/proc";
- }
- }
-#endif /* __linux__ */
+ * reading /proc/self/fd. This is in the common cases much faster
+ * than for example doing 4096 close calls where almost all of them
+ * will fail.
+ *
+ * Unfortunately we can't call opendir between fork and exec in a
+ * multi-threaded process because opendir uses malloc and thus a
+ * mutex which may deadlock with a malloc in another thread. Thus
+ * the code is not used until we can have a opendir variant which
+ * does not use malloc. */
+/* #ifdef __linux__ */
+/* { */
+/* DIR *dir = NULL; */
+/* struct dirent *dir_entry; */
+/* const char *s; */
+/* int x; */
+
+/* dir = opendir ("/proc/self/fd"); */
+/* if (dir) */
+/* { */
+/* while ((dir_entry = readdir (dir))) */
+/* { */
+/* s = dir_entry->d_name; */
+/* if ( *s < '0' || *s > '9') */
+/* continue; */
+/* x = atoi (s); */
+/* if (x > fds) */
+/* fds = x; */
+/* } */
+/* closedir (dir); */
+/* } */
+/* if (fds != -1) */
+/* { */
+/* fds++; */
+/* source = "/proc"; */
+/* } */
+/* } */
+/* #endif /\* __linux__ *\/ */
#ifdef RLIMIT_NOFILE
if (fds == -1)
@@ -453,10 +459,9 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
/* Intermediate child to prevent zombie processes. */
if ((pid = fork ()) == 0)
{
- int max_fds = get_max_fds ();
- int fd;
-
/* Child. */
+ int max_fds = -1;
+ int fd;
int seen_stdin = 0;
int seen_stdout = 0;
int seen_stderr = 0;
@@ -464,15 +469,40 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
if (atfork)
atfork (atforkvalue, 0);
- /* First close all fds which will not be inherited. */
- for (fd = 0; fd < max_fds; fd++)
- {
- for (i = 0; fd_list[i].fd != -1; i++)
- if (fd_list[i].fd == fd)
- break;
- if (fd_list[i].fd == -1)
- close (fd);
- }
+ /* First close all fds which will not be inherited. If we
+ * have closefrom(2) we first figure out the highest fd we
+ * do not want to close, then call closefrom, and on success
+ * use the regular code to close all fds up to the start
+ * point of closefrom. Note that Solaris' closefrom does
+ * not return errors. */
+#ifdef HAVE_CLOSEFROM
+ {
+ fd = -1;
+ for (i = 0; fd_list[i].fd != -1; i++)
+ if (fd_list[i].fd > fd)
+ fd = fd_list[i].fd;
+ fd++;
+#ifdef __sun
+ closefrom (fd);
+ max_fds = fd;
+#else /*!__sun */
+ while ((i = closefrom (fd)) && errno == EINTR)
+ ;
+ if (!i || errno == EBADF)
+ max_fds = fd;
+#endif /*!__sun*/
+ }
+#endif /*HAVE_CLOSEFROM*/
+ if (max_fds == -1)
+ max_fds = get_max_fds ();
+ for (fd = 0; fd < max_fds; fd++)
+ {
+ for (i = 0; fd_list[i].fd != -1; i++)
+ if (fd_list[i].fd == fd)
+ break;
+ if (fd_list[i].fd == -1)
+ close (fd);
+ }
/* And now dup and close those to be duplicated. */
for (i = 0; fd_list[i].fd != -1; i++)
diff --git a/src/progress.c b/src/progress.c
index c10ccaa..066a7f5 100644
--- a/src/progress.c
+++ b/src/progress.c
@@ -31,6 +31,8 @@
#include "debug.h"
+/* The status handler for progress status lines which also monitors
+ * the PINENTRY_LAUNCHED status. */
gpgme_error_t
_gpgme_progress_status_handler (void *priv, gpgme_status_code_t code,
char *args)
@@ -42,6 +44,12 @@ _gpgme_progress_status_handler (void *priv, gpgme_status_code_t code,
int current = 0;
int total = 0;
+ if (code == GPGME_STATUS_PINENTRY_LAUNCHED)
+ {
+ ctx->redraw_suggested = 1;
+ return 0;
+ }
+
if (code != GPGME_STATUS_PROGRESS || !*args || !ctx->progress_cb)
return 0;
diff --git a/src/util.h b/src/util.h
index a1be6e7..7b7924c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -95,11 +95,12 @@ _gpgme_stpcpy (char *a, const char *b)
#define stpcpy(a,b) _gpgme_stpcpy ((a), (b))
#endif /*!HAVE_STPCPY*/
-#if !HAVE_VASPRINTF
-#include <stdarg.h>
-int vasprintf (char **result, const char *format, va_list args);
-int asprintf (char **result, const char *format, ...);
-#endif
+
+/* Due to a bug in mingw32's snprintf related to the 'l' modifier and
+ for increased portability we use our snprintf on all systems. */
+#undef snprintf
+#define snprintf gpgrt_snprintf
+
#if REPLACE_TTYNAME_R
int _gpgme_ttyname_r (int fd, char *buf, size_t buflen);
@@ -164,6 +165,9 @@ gpgme_off_t _gpgme_string_to_off (const char *string);
point to the next non-parsed character in TIMESTRING. */
time_t _gpgme_parse_timestamp (const char *timestamp, char **endp);
+/* Variant of _gpgme_parse_timestamp to return an unsigned long or 0
+ * on error or missing timestamp. */
+unsigned long _gpgme_parse_timestamp_ul (const char *timestamp);
gpgme_error_t _gpgme_map_gnupg_error (char *err);
diff --git a/src/vasprintf.c b/src/vasprintf.c
deleted file mode 100644
index 4c40131..0000000
--- a/src/vasprintf.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/* Like vsprintf but provides a pointer to malloc'd storage, which must
- be freed by the caller.
- Copyright (C) 1994, 2002 Free Software Foundation, Inc.
-
-This file is part of the libiberty library.
-Libiberty is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-Libiberty is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with libiberty; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-
-#ifndef va_copy /* According to POSIX, va_copy is a macro. */
-#if defined (__GNUC__) && defined (__PPC__) \
- && (defined (_CALL_SYSV) || defined (_WIN32))
-#define va_copy(d, s) (*(d) = *(s))
-#elif defined (MUST_COPY_VA_BYVAL)
-#define va_copy(d, s) ((d) = (s))
-#else
-#define va_copy(d, s) memcpy ((d), (s), sizeof (va_list))
-#endif
-#endif
-
-
-#ifdef TEST
-int global_total_width;
-#endif
-
-static int int_vasprintf (char **, const char *, va_list *);
-
-static int
-int_vasprintf (result, format, args)
- char **result;
- const char *format;
- va_list *args;
-{
-#ifdef HAVE_W32CE_SYSTEM
- /* No va_copy and the replacement above doesn't work. */
-#define MAX_STRLEN 256
- *result = malloc (MAX_STRLEN);
- if (*result != NULL)
- {
- int res = _vsnprintf (*result, MAX_STRLEN, format, *args);
- (*result)[MAX_STRLEN - 1] = '\0';
- return res;
- }
- else
- return 0;
-#else
- const char *p = format;
- /* Add one to make sure that it is never zero, which might cause malloc
- to return NULL. */
- int total_width = strlen (format) + 1;
- va_list ap;
-
- va_copy (ap, *args);
-
- while (*p != '\0')
- {
- if (*p++ == '%')
- {
- while (strchr ("-+ #0", *p))
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **) &p, 10);
- if (*p == '.')
- {
- ++p;
- if (*p == '*')
- {
- ++p;
- total_width += abs (va_arg (ap, int));
- }
- else
- total_width += strtoul (p, (char **) &p, 10);
- }
- while (strchr ("hlL", *p))
- ++p;
- /* Should be big enough for any format specifier except %s and floats. */
- total_width += 30;
- switch (*p)
- {
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- case 'c':
- (void) va_arg (ap, int);
- break;
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- (void) va_arg (ap, double);
- /* Since an ieee double can have an exponent of 307, we'll
- make the buffer wide enough to cover the gross case. */
- total_width += 307;
- break;
- case 's':
- {
- char *tmp = va_arg (ap, char *);
- if (tmp)
- total_width += strlen (tmp);
- else /* in case the vsprintf does prints a text */
- total_width += 25; /* e.g. "(null pointer reference)" */
- }
- break;
- case 'p':
- case 'n':
- (void) va_arg (ap, char *);
- break;
- }
- p++;
- }
- }
-#ifdef TEST
- global_total_width = total_width;
-#endif
- *result = malloc (total_width);
- if (*result != NULL)
- return vsprintf (*result, format, *args);
- else
- return 0;
-#endif
-}
-
-int
-vasprintf (result, format, args)
- char **result;
- const char *format;
-#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
- _BSD_VA_LIST_ args;
-#else
- va_list args;
-#endif
-{
- return int_vasprintf (result, format, &args);
-}
-
-
-int
-asprintf (char **buf, const char *fmt, ...)
-{
- int status;
- va_list ap;
-
- va_start (ap, fmt);
- status = vasprintf (buf, fmt, ap);
- va_end (ap);
- return status;
-}
-
-
-#ifdef TEST
-void
-checkit (const char* format, ...)
-{
- va_list args;
- char *result;
-
- va_start (args, format);
- vasprintf (&result, format, args);
- if (strlen (result) < global_total_width)
- printf ("PASS: ");
- else
- printf ("FAIL: ");
- printf ("%d %s\n", global_total_width, result);
-}
-
-int
-main (void)
-{
- checkit ("%d", 0x12345678);
- checkit ("%200d", 5);
- checkit ("%.300d", 6);
- checkit ("%100.150d", 7);
- checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
-777777777777777777333333333333366666666666622222222222777777777777733333");
- checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
-}
-#endif /* TEST */
diff --git a/src/verify.c b/src/verify.c
index faa8deb..900f925 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -46,6 +46,7 @@ typedef struct
int did_prepare_new_sig;
int only_newsig_seen;
int plaintext_seen;
+ int conflict_user_seen;
} *op_data_t;
@@ -680,6 +681,14 @@ parse_tofu_user (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol)
goto leave;
}
+ if (sig->key && sig->key->fpr && strcmp (sig->key->fpr, fpr))
+ {
+ /* GnuPG since 2.1.17 emits multiple TOFU_USER lines with
+ different fingerprints in case of conflicts for a signature. */
+ err = gpg_error (GPG_ERR_DUP_VALUE);
+ goto leave;
+ }
+
args = tail;
tail = strchr (args, ' ');
if (tail == args)
@@ -708,12 +717,6 @@ parse_tofu_user (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol)
err = trace_gpg_error (GPG_ERR_INTERNAL);
goto leave;
}
- else if (strcmp (sig->key->fpr, fpr))
- {
- /* The engine did not emit NEWSIG before a new key. */
- err = trace_gpg_error (GPG_ERR_INV_ENGINE);
- goto leave;
- }
err = _gpgme_key_append_name (sig->key, address, 0);
if (err)
@@ -930,6 +933,7 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
calc_sig_summary (sig);
err = prepare_new_sig (opd);
opd->only_newsig_seen = 1;
+ opd->conflict_user_seen = 0;
return err;
case GPGME_STATUS_GOODSIG:
@@ -995,16 +999,35 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
case GPGME_STATUS_TOFU_USER:
opd->only_newsig_seen = 0;
- return sig ? parse_tofu_user (sig, args, ctx->protocol)
- /* */ : trace_gpg_error (GPG_ERR_INV_ENGINE);
+ if (!sig)
+ return trace_gpg_error (GPG_ERR_INV_ENGINE);
+ err = parse_tofu_user (sig, args, ctx->protocol);
+ /* gpg emits TOFU User lines for each conflicting key.
+ * GPGME does not expose this to have a clean API and
+ * a GPGME user can do a keylisting with the address
+ * normalisation.
+ * So when a duplicated TOFU_USER line is encountered
+ * we ignore the conflicting tofu stats emited afterwards.
+ */
+ if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
+ {
+ opd->conflict_user_seen = 1;
+ break;
+ }
+ opd->conflict_user_seen = 0;
+ return trace_gpg_error (err);
case GPGME_STATUS_TOFU_STATS:
opd->only_newsig_seen = 0;
+ if (opd->conflict_user_seen)
+ break;
return sig ? parse_tofu_stats (sig, args)
/* */ : trace_gpg_error (GPG_ERR_INV_ENGINE);
case GPGME_STATUS_TOFU_STATS_LONG:
opd->only_newsig_seen = 0;
+ if (opd->conflict_user_seen)
+ break;
return sig ? parse_tofu_stats_long (sig, args, ctx->raw_description)
/* */ : trace_gpg_error (GPG_ERR_INV_ENGINE);
diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in
index 3ce38f0..2b1cc81 100644
--- a/src/versioninfo.rc.in
+++ b/src/versioninfo.rc.in
@@ -39,7 +39,7 @@ BEGIN
VALUE "FileDescription", "GPGME - GnuPG Made Easy\0"
VALUE "FileVersion", "@LIBGPGME_LT_CURRENT@.@LIBGPGME_LT_AGE@.@LIBGPGME_LT_REVISION@.@BUILD_REVISION@\0"
VALUE "InternalName", "gpgme\0"
- VALUE "LegalCopyright", "Copyright © 2001-2016 g10 Code GmbH\0"
+ VALUE "LegalCopyright", "Copyright © 2001-2017 g10 Code GmbH\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "gpgme.dll\0"
VALUE "PrivateBuild", "\0"
diff --git a/src/vfs-create.c b/src/vfs-create.c
index a01d4da..a3bec19 100644
--- a/src/vfs-create.c
+++ b/src/vfs-create.c
@@ -138,7 +138,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
}
- if (asprintf (&cmd, "RECIPIENT %s", recp[i]->subkeys->fpr) < 0)
+ if (gpgrt_asprintf (&cmd, "RECIPIENT %s", recp[i]->subkeys->fpr) < 0)
{
err = gpg_error_from_syserror ();
free (container_file_esc);
@@ -147,7 +147,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
NULL, NULL, op_err);
- free (cmd);
+ gpgrt_free (cmd);
if (err || *op_err)
{
free (container_file_esc);
@@ -156,7 +156,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
recp++;
}
- if (asprintf (&cmd, "CREATE -- %s", container_file_esc) < 0)
+ if (gpgrt_asprintf (&cmd, "CREATE -- %s", container_file_esc) < 0)
{
err = gpg_error_from_syserror ();
free (container_file_esc);
@@ -166,7 +166,7 @@ _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
NULL, NULL, op_err);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
diff --git a/src/vfs-mount.c b/src/vfs-mount.c
index 5d2f2a9..68a8efe 100644
--- a/src/vfs-mount.c
+++ b/src/vfs-mount.c
@@ -184,7 +184,7 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
if (err)
return err;
- if (asprintf (&cmd, "OPEN -- %s", container_file_esc) < 0)
+ if (gpgrt_asprintf (&cmd, "OPEN -- %s", container_file_esc) < 0)
{
err = gpg_error_from_syserror ();
free (container_file_esc);
@@ -194,7 +194,7 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
NULL, NULL, op_err);
- free (cmd);
+ gpgrt_free (cmd);
if (err || *op_err)
return err;
@@ -206,7 +206,7 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
if (err)
return err;
- if (asprintf (&cmd, "MOUNT -- %s", mount_dir_esc) < 0)
+ if (gpgrt_asprintf (&cmd, "MOUNT -- %s", mount_dir_esc) < 0)
{
err = gpg_error_from_syserror ();
free (mount_dir_esc);
@@ -216,13 +216,13 @@ _gpgme_op_vfs_mount (gpgme_ctx_t ctx, const char *container_file,
}
else
{
- if (asprintf (&cmd, "MOUNT") < 0)
+ if (gpgrt_asprintf (&cmd, "MOUNT") < 0)
return gpg_error_from_syserror ();
}
err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
_gpgme_vfs_mount_status_handler, ctx, op_err);
- free (cmd);
+ gpgrt_free (cmd);
return err;
}
diff --git a/src/w32-io.c b/src/w32-io.c
index 0d1c810..eed8a00 100644
--- a/src/w32-io.c
+++ b/src/w32-io.c
@@ -700,7 +700,7 @@ writer (void *arg)
for (;;)
{
LOCK (ctx->mutex);
- if (ctx->stop_me)
+ if (ctx->stop_me && !ctx->nbytes)
{
UNLOCK (ctx->mutex);
break;
@@ -717,7 +717,7 @@ writer (void *arg)
TRACE_LOG ("got data to send");
LOCK (ctx->mutex);
}
- if (ctx->stop_me)
+ if (ctx->stop_me && !ctx->nbytes)
{
UNLOCK (ctx->mutex);
break;
@@ -776,6 +776,9 @@ writer (void *arg)
TRACE_LOG ("waiting for close");
WaitForSingleObject (ctx->close_ev, INFINITE);
+ if (ctx->nbytes)
+ TRACE_LOG1 ("still %d bytes in buffer at close time", ctx->nbytes);
+
CloseHandle (ctx->close_ev);
CloseHandle (ctx->have_data);
CloseHandle (ctx->is_empty);
@@ -892,6 +895,9 @@ destroy_writer (struct writer_context_s *ctx)
SetEvent (ctx->have_data);
UNLOCK (ctx->mutex);
+ /* Give the writer a chance to flush the buffer. */
+ WaitForSingleObject (ctx->is_empty, INFINITE);
+
#ifdef HAVE_W32CE_SYSTEM
/* Scenario: We never create a full pipe, but already started
writing more than the pipe buffer. Then we need to unblock the
@@ -1637,11 +1643,11 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
"with your installation.\n"
"Please report the problem to your "
"distributor of GpgME.\n\n"
- "Developers Note: The install dir can be "
+ "Developer's Note: The install dir can be "
"manually set with: gpgme_set_global_flag",
_gpgme_get_inst_dir ());
MessageBoxA (NULL, msg, "GpgME not installed correctly", MB_OK);
- free (msg);
+ gpgrt_free (msg);
gpg_err_set_errno (EIO);
return TRACE_SYSRES (-1);
}
diff --git a/src/w32-util.c b/src/w32-util.c
index ad36c9a..5b02c7e 100644
--- a/src/w32-util.c
+++ b/src/w32-util.c
@@ -577,9 +577,10 @@ _gpgme_get_gpgconf_path (void)
"Install Directory");
if (tmp)
{
- if (gpgrt_asprintf (&dir, "%s\\bin", tmp) == -1)
- return NULL;
+ dir = _gpgme_strconcat (tmp, "\\bin", NULL);
free (tmp);
+ if (!dir)
+ return NULL;
}
}
if (dir)
diff --git a/tests/Makefile.in b/tests/Makefile.in
index a908f95..7ccf806 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -118,8 +118,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
diff --git a/tests/gpg/Makefile.am b/tests/gpg/Makefile.am
index c46feb0..8e26a92 100644
--- a/tests/gpg/Makefile.am
+++ b/tests/gpg/Makefile.am
@@ -45,7 +45,8 @@ TESTS = initial.test $(c_tests) final.test
CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \
- random_seed S.gpg-agent .gpg-v21-migrated pubring-stamp
+ random_seed S.gpg-agent .gpg-v21-migrated pubring-stamp \
+ tofu.db *.conf.gpgconf.bak
private_keys = \
13CD0F3BDF24BE53FE192D62F18737256FF6E4FD \
diff --git a/tests/gpg/Makefile.in b/tests/gpg/Makefile.in
index ed75d8a..d8cd64b 100644
--- a/tests/gpg/Makefile.in
+++ b/tests/gpg/Makefile.in
@@ -115,8 +115,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
@@ -551,7 +551,8 @@ c_tests = \
CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \
gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \
- random_seed S.gpg-agent .gpg-v21-migrated pubring-stamp
+ random_seed S.gpg-agent .gpg-v21-migrated pubring-stamp \
+ tofu.db *.conf.gpgconf.bak
private_keys = \
13CD0F3BDF24BE53FE192D62F18737256FF6E4FD \
diff --git a/tests/gpg/t-gpgconf.c b/tests/gpg/t-gpgconf.c
index 55033bf..67bb886 100644
--- a/tests/gpg/t-gpgconf.c
+++ b/tests/gpg/t-gpgconf.c
@@ -34,37 +34,7 @@
#include <gpgme.h>
-
-#define fail_if_err(err) \
- do \
- { \
- if (err) \
- { \
- fprintf (stderr, "%s:%d: %s: %s\n", \
- __FILE__, __LINE__, gpgme_strsource (err), \
- gpgme_strerror (err)); \
- exit (1); \
- } \
- } \
- while (0)
-
-
-void
-init_gpgme (gpgme_protocol_t proto)
-{
- gpgme_error_t err;
-
- gpgme_check_version (NULL);
- setlocale (LC_ALL, "");
- gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
-#ifndef HAVE_W32_SYSTEM
- gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
-#endif
-
- err = gpgme_engine_check_version (proto);
- fail_if_err (err);
-}
-
+#include "t-support.h"
static char *
spaces (char *str, int extra)
@@ -251,6 +221,34 @@ dump_comp (gpgme_conf_comp_t comp)
int
+lookup (gpgme_conf_comp_t conf,
+ const char *component,
+ const char *option,
+ gpgme_conf_comp_t *comp,
+ gpgme_conf_opt_t *opt)
+{
+ *comp = conf;
+ while (*comp && strcmp ((*comp)->name, component))
+ *comp = (*comp)->next;
+
+ if (*comp)
+ {
+ *opt = (*comp)->options;
+ while (*opt && strcmp ((*opt)->name, option))
+ *opt = (*opt)->next;
+
+ /* Allow for the option not to be there. */
+ if (*opt)
+ return 1; /* Found. */
+ }
+
+ return 0; /* Not found. */
+}
+
+#include <assert.h>
+
+
+int
main (void)
{
gpgme_ctx_t ctx;
@@ -258,10 +256,7 @@ main (void)
gpgme_conf_comp_t conf;
gpgme_conf_comp_t comp;
int first;
-
-#ifndef ENABLE_GPGCONF
- return 0;
-#endif
+ int i, N = 10;
init_gpgme (GPGME_PROTOCOL_GPGCONF);
@@ -283,40 +278,92 @@ main (void)
comp = comp->next;
}
-#if 1
/* Now change something. */
- {
- unsigned int count = 1;
+ fprintf (stderr, " dirmngr.verbose ");
+ for (i = 0; i < N; i++) {
+ unsigned int count = i % 4 + 1; /* counts must not be zero */
gpgme_conf_arg_t arg;
gpgme_conf_opt_t opt;
err = gpgme_conf_arg_new (&arg, GPGME_CONF_NONE, &count);
fail_if_err (err);
- comp = conf;
- while (comp && strcmp (comp->name, "dirmngr"))
- comp = comp->next;
+ if (lookup (conf, "dirmngr", "verbose", &comp, &opt))
+ {
+ /* Found. */
+ err = gpgme_conf_opt_change (opt, 0, arg);
+ fail_if_err (err);
- if (comp)
+ err = gpgme_op_conf_save (ctx, comp);
+ fail_if_err (err);
+ }
+ else
{
- opt = comp->options;
- while (opt && strcmp (opt->name, "verbose"))
- opt = opt->next;
-
- /* Allow for the verbose option not to be there. */
- if (opt)
- {
- err = gpgme_conf_opt_change (opt, 0, arg);
- fail_if_err (err);
-
- err = gpgme_op_conf_save (ctx, comp);
- fail_if_err (err);
- }
+ fprintf (stderr, "Skipping test, option dirmngr.verbose not found.\n");
+ break;
}
+
+ /* Reload config and verify that the value was updated. */
+ gpgme_conf_release (conf);
+ err = gpgme_op_conf_load (ctx, &conf);
+ fail_if_err (err);
+ if (lookup (conf, "dirmngr", "verbose", &comp, &opt))
+ {
+ /* Found. */
+ test (opt->alt_type == GPGME_CONF_NONE);
+ test (opt->value);
+ test ((unsigned long) opt->value->value.count == count);
+ }
+
+ fprintf (stderr, ".");
+ fflush (stderr);
}
-#endif
- gpgme_conf_release (conf);
+ /* Now change something else. */
+ fprintf (stderr, " gpg.keyserver ");
+ for (i = 0; i < N; i++) {
+ const char *values[2] = { "hkp://foo.bar", "hkps://bar.foo" };
+ gpgme_conf_arg_t arg;
+ gpgme_conf_opt_t opt;
+
+ err = gpgme_conf_arg_new (&arg, GPGME_CONF_STRING, values[i%2]);
+ fail_if_err (err);
+ if (lookup (conf, "gpg", "keyserver", &comp, &opt))
+ {
+ /* Found. */
+ test (opt->alt_type == GPGME_CONF_STRING);
+ err = gpgme_conf_opt_change (opt, 0, arg);
+ fail_if_err (err);
+
+ err = gpgme_op_conf_save (ctx, comp);
+ fail_if_err (err);
+ }
+ else
+ {
+ fprintf (stderr, "Skipping test, option gpg.keyserver not found.\n");
+ break;
+ }
+
+ /* Reload config and verify that the value was updated. */
+ gpgme_conf_release (conf);
+ err = gpgme_op_conf_load (ctx, &conf);
+ fail_if_err (err);
+ if (lookup (conf, "gpg", "keyserver", &comp, &opt))
+ {
+ /* Found. */
+ test (opt->alt_type == GPGME_CONF_STRING);
+ test (opt->value);
+ test (opt->value->value.string);
+ test (strcmp (opt->value->value.string, values[i%2]) == 0);
+ }
+
+ fprintf (stderr, ".");
+ fflush (stderr);
+ }
+ fprintf (stderr, "\n");
+
+ gpgme_conf_release (conf);
+ gpgme_release (ctx);
return 0;
}
diff --git a/tests/gpg/t-support.h b/tests/gpg/t-support.h
index db69dd0..f6dec68 100644
--- a/tests/gpg/t-support.h
+++ b/tests/gpg/t-support.h
@@ -48,6 +48,34 @@
while (0)
+#ifdef GPGRT_HAVE_MACRO_FUNCTION
+void GPGRT_ATTR_NORETURN
+_test (const char *expr, const char *file, int line,
+ const char *func)
+{
+ fprintf (stderr, "Test \"%s\" in %s failed (%s:%d)\n",
+ expr, func, file, line);
+ exit (1);
+}
+# define test(expr) \
+ ((expr) \
+ ? (void) 0 \
+ : _test (#expr, __FILE__, __LINE__, __FUNCTION__))
+#else /*!GPGRT_HAVE_MACRO_FUNCTION*/
+void
+_test (const char *expr, const char *file, int line)
+{
+ fprintf (stderr, "Test \"%s\" failed (%s:%d)\n",
+ expr, file, line);
+ exit (1);
+}
+# define test(expr) \
+ ((expr) \
+ ? (void) 0 \
+ : _test (#expr, __FILE__, __LINE__))
+#endif /*!GPGRT_HAVE_MACRO_FUNCTION*/
+
+
static const char *
nonnull (const char *s)
{
diff --git a/tests/gpg/t-thread-keylist-verify.c b/tests/gpg/t-thread-keylist-verify.c
index 6f747a6..b327a1f 100644
--- a/tests/gpg/t-thread-keylist-verify.c
+++ b/tests/gpg/t-thread-keylist-verify.c
@@ -32,7 +32,7 @@
#include "t-support.h"
-#define THREAD_COUNT 100
+#define THREAD_COUNT 10
static const char test_text1[] = "Just GNU it!\n";
static const char test_sig1[] =
diff --git a/tests/gpg/t-thread-keylist.c b/tests/gpg/t-thread-keylist.c
index c03f1ca..b9feeda 100644
--- a/tests/gpg/t-thread-keylist.c
+++ b/tests/gpg/t-thread-keylist.c
@@ -32,7 +32,7 @@
#include "t-support.h"
-#define THREAD_COUNT 100
+#define THREAD_COUNT 10
void *
start_keylist (void *arg)
diff --git a/tests/gpgsm/Makefile.in b/tests/gpgsm/Makefile.in
index 8f2109b..1be6794 100644
--- a/tests/gpgsm/Makefile.in
+++ b/tests/gpgsm/Makefile.in
@@ -115,8 +115,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
diff --git a/tests/opassuan/Makefile.in b/tests/opassuan/Makefile.in
index 797c4ae..3287799 100644
--- a/tests/opassuan/Makefile.in
+++ b/tests/opassuan/Makefile.in
@@ -112,8 +112,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
- $(top_srcdir)/m4/qt.m4 $(top_srcdir)/acinclude.m4 \
- $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/python.m4 $(top_srcdir)/m4/qt.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
diff --git a/tests/run-decrypt.c b/tests/run-decrypt.c
index 8bcca0e..0fcacf8 100644
--- a/tests/run-decrypt.c
+++ b/tests/run-decrypt.c
@@ -80,6 +80,7 @@ show_usage (int ex)
" --cms use the CMS protocol\n"
" --export-session-key show the session key\n"
" --override-session-key STRING use STRING as session key\n"
+ " --unwrap remove only the encryption layer\n"
, stderr);
exit (ex);
}
@@ -92,6 +93,7 @@ main (int argc, char **argv)
gpgme_error_t err;
gpgme_ctx_t ctx;
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
+ gpgme_decrypt_flags_t flags = 0;
FILE *fp_in = NULL;
gpgme_data_t in = NULL;
gpgme_data_t out = NULL;
@@ -99,6 +101,7 @@ main (int argc, char **argv)
int print_status = 0;
int export_session_key = 0;
const char *override_session_key = NULL;
+ int raw_output = 0;
if (argc)
{ argc--; argv++; }
@@ -146,6 +149,12 @@ main (int argc, char **argv)
override_session_key = *argv;
argc--; argv++;
}
+ else if (!strcmp (*argv, "--unwrap"))
+ {
+ flags |= GPGME_DECRYPT_UNWRAP;
+ raw_output = 1;
+ argc--; argv++;
+ }
else if (!strncmp (*argv, "--", 2))
show_usage (1);
@@ -211,7 +220,7 @@ main (int argc, char **argv)
exit (1);
}
- err = gpgme_op_decrypt (ctx, in, out);
+ err = gpgme_op_decrypt_ext (ctx, flags, in, out);
result = gpgme_op_decrypt_result (ctx);
if (err)
{
@@ -220,8 +229,13 @@ main (int argc, char **argv)
}
if (result)
{
- print_result (result);
+ if (!raw_output)
+ print_result (result);
+ if (!raw_output)
+ fputs ("Begin Output:\n", stdout);
print_data (out);
+ if (!raw_output)
+ fputs ("End Output.\n", stdout);
}
gpgme_data_release (out);
diff --git a/tests/run-encrypt.c b/tests/run-encrypt.c
index fd86836..e949d76 100644
--- a/tests/run-encrypt.c
+++ b/tests/run-encrypt.c
@@ -88,6 +88,8 @@ show_usage (int ex)
" --uiserver use the UI server\n"
" --loopback use a loopback pinentry\n"
" --key NAME encrypt to key NAME\n"
+ " --throw-keyids use this option\n"
+ " --wrap assume input is valid OpenPGP message\n"
" --symmetric encrypt symmetric (OpenPGP only)\n"
, stderr);
exit (ex);
@@ -170,6 +172,16 @@ main (int argc, char **argv)
keyargs[keycount++] = *argv;
argc--; argv++;
}
+ else if (!strcmp (*argv, "--throw-keyids"))
+ {
+ flags |= GPGME_ENCRYPT_THROW_KEYIDS;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--wrap"))
+ {
+ flags |= GPGME_ENCRYPT_WRAP;
+ argc--; argv++;
+ }
else if (!strcmp (*argv, "--loopback"))
{
use_loopback = 1;
diff --git a/tests/run-genkey.c b/tests/run-genkey.c
index c5abc42..91edb22 100644
--- a/tests/run-genkey.c
+++ b/tests/run-genkey.c
@@ -204,10 +204,12 @@ show_usage (int ex)
" for addkey: FPR [ALGO [USAGE [EXPIRESECONDS]]]\n"
" for adduid: FPR USERID\n"
" for revuid: FPR USERID\n"
+ " for set-primary: FPR USERID\n"
"Options:\n"
" --addkey add a subkey to the key with FPR\n"
" --adduid add a user id to the key with FPR\n"
- " --revuid Revoke a user id from the key with FPR\n"
+ " --revuid revoke a user id from the key with FPR\n"
+ " --set-primary set the primary key flag on USERID\n"
" --verbose run in verbose mode\n"
" --status print status lines from the backend\n"
" --progress print progress info\n"
@@ -234,6 +236,7 @@ main (int argc, char **argv)
int addkey = 0;
int adduid = 0;
int revuid = 0;
+ int setpri = 0;
const char *userid;
const char *algo = NULL;
const char *newuserid = NULL;
@@ -259,6 +262,7 @@ main (int argc, char **argv)
addkey = 1;
adduid = 0;
revuid = 0;
+ setpri = 0;
argc--; argv++;
}
else if (!strcmp (*argv, "--adduid"))
@@ -266,6 +270,7 @@ main (int argc, char **argv)
addkey = 0;
adduid = 1;
revuid = 0;
+ setpri = 0;
argc--; argv++;
}
else if (!strcmp (*argv, "--revuid"))
@@ -273,6 +278,15 @@ main (int argc, char **argv)
addkey = 0;
adduid = 0;
revuid = 1;
+ setpri = 0;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--set-primary"))
+ {
+ addkey = 0;
+ adduid = 0;
+ revuid = 0;
+ setpri = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--verbose"))
@@ -319,7 +333,7 @@ main (int argc, char **argv)
show_usage (1);
}
- if (adduid || revuid)
+ if (adduid || revuid || setpri)
{
if (argc != 2)
show_usage (1);
@@ -358,7 +372,7 @@ main (int argc, char **argv)
gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
}
- if (addkey || adduid || revuid)
+ if (addkey || adduid || revuid || setpri)
{
gpgme_key_t akey;
@@ -400,6 +414,16 @@ main (int argc, char **argv)
exit (1);
}
}
+ else if (setpri)
+ {
+ err = gpgme_op_set_uid_flag (ctx, akey, newuserid, "primary", NULL);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gpgme_op_set_uid_flag failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
gpgme_key_unref (akey);
}
else
@@ -413,26 +437,29 @@ main (int argc, char **argv)
}
}
- result = gpgme_op_genkey_result (ctx);
- if (!result)
+ if (!setpri)
{
- fprintf (stderr, PGM": gpgme_op_genkey_result returned NULL\n");
- exit (1);
- }
+ result = gpgme_op_genkey_result (ctx);
+ if (!result)
+ {
+ fprintf (stderr, PGM": gpgme_op_genkey_result returned NULL\n");
+ exit (1);
+ }
- printf ("Generated key: %s (%s)\n",
- result->fpr ? result->fpr : "none",
- result->primary ? (result->sub ? "primary, sub" : "primary")
- /**/ : (result->sub ? "sub" : "none"));
-
- if (result->fpr && strlen (result->fpr) < 40)
- fprintf (stderr, PGM": generated key has unexpected fingerprint\n");
- if (!result->primary)
- fprintf (stderr, PGM": primary key was not generated\n");
- if (!result->sub)
- fprintf (stderr, PGM": sub key was not generated\n");
- if (!result->uid)
- fprintf (stderr, PGM": uid was not generated\n");
+ printf ("Generated key: %s (%s)\n",
+ result->fpr ? result->fpr : "none",
+ result->primary ? (result->sub ? "primary, sub" : "primary")
+ /**/ : (result->sub ? "sub" : "none"));
+
+ if (result->fpr && strlen (result->fpr) < 40)
+ fprintf (stderr, PGM": generated key has unexpected fingerprint\n");
+ if (!result->primary)
+ fprintf (stderr, PGM": primary key was not generated\n");
+ if (!result->sub)
+ fprintf (stderr, PGM": sub key was not generated\n");
+ if (!result->uid)
+ fprintf (stderr, PGM": uid was not generated\n");
+ }
gpgme_release (ctx);
return 0;
diff --git a/tests/run-keylist.c b/tests/run-keylist.c
index 93fbeb5..dd310e5 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)))
@@ -223,14 +242,16 @@ main (int argc, char **argv)
key->can_sign? "s":"",
key->can_certify? "c":"",
key->can_authenticate? "a":"");
- printf ("flags :%s%s%s%s%s%s%s\n",
+ printf ("flags :%s%s%s%s%s%s%s%s\n",
key->secret? " secret":"",
key->revoked? " revoked":"",
key->expired? " expired":"",
key->disabled? " disabled":"",
key->invalid? " invalid":"",
- key->is_qualified? " qualifid":"",
+ key->is_qualified? " qualified":"",
+ key->subkeys && key->subkeys->is_de_vs? " de-vs":"",
key->subkeys && key->subkeys->is_cardkey? " cardkey":"");
+ printf ("upd : %lu (%u)\n", key->last_update, key->origin);
subkey = key->subkeys;
if (subkey)
@@ -248,14 +269,15 @@ main (int argc, char **argv)
subkey->can_sign? "s":"",
subkey->can_certify? "c":"",
subkey->can_authenticate? "a":"");
- printf ("flags %2d:%s%s%s%s%s%s%s\n",
+ printf ("flags %2d:%s%s%s%s%s%s%s%s\n",
nsub,
subkey->secret? " secret":"",
subkey->revoked? " revoked":"",
subkey->expired? " expired":"",
subkey->disabled? " disabled":"",
subkey->invalid? " invalid":"",
- subkey->is_qualified? " qualifid":"",
+ subkey->is_qualified? " qualified":"",
+ subkey->is_de_vs? " de-vs":"",
subkey->is_cardkey? " cardkey":"");
}
for (nuids=0, uid=key->uids; uid; uid = uid->next, nuids++)
@@ -268,6 +290,7 @@ main (int argc, char **argv)
printf (" name: %s\n", uid->name);
if (uid->comment)
printf (" cmmnt: %s\n", uid->comment);
+ printf (" upd: %lu (%u)\n", uid->last_update, uid->origin);
printf (" valid: %s\n",
uid->validity == GPGME_VALIDITY_UNKNOWN? "unknown":
uid->validity == GPGME_VALIDITY_UNDEFINED? "undefined":
@@ -320,6 +343,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)
diff --git a/tests/run-sign.c b/tests/run-sign.c
index 9f2e175..1daf173 100644
--- a/tests/run-sign.c
+++ b/tests/run-sign.c
@@ -103,6 +103,7 @@ main (int argc, char **argv)
int print_status = 0;
int use_loopback = 0;
const char *sender = NULL;
+ const char *s;
if (argc)
{ argc--; argv++; }
@@ -229,6 +230,9 @@ main (int argc, char **argv)
exit (1);
}
+ if ((s = gpgme_get_ctx_flag (ctx, "redraw")) && *s)
+ fputs ("Screen redraw suggested\n", stdout);
+
fputs ("Begin Output:\n", stdout);
print_data (out);
fputs ("End Output.\n", stdout);
diff --git a/tests/start-stop-agent b/tests/start-stop-agent
index ab47d8d..3ce6f22 100755
--- a/tests/start-stop-agent
+++ b/tests/start-stop-agent
@@ -15,11 +15,12 @@ fi
GPG_AGENT_INFO=
export GPG_AGENT_INFO
+GPG_AGENT=$(which gpg-agent)
token=$(echo "gpgme-$(pwd)" | tr ' ' '_')
if [ "$1" = "--stop" ]; then
- if [ "$(gpg-connect-agent getval\ $token /bye 2>/dev/null | head -1)" \
+ if [ "$(gpg-connect-agent --no-autostart getval\ $token /bye 2>/dev/null | head -1)" \
!= "D set" ]; then
echo "gpg-agent not running" >&2
exit 0
@@ -29,15 +30,25 @@ if [ "$1" = "--stop" ]; then
exit 0
fi
-if [ "$(gpg-connect-agent getval\ $token /bye 2>/dev/null | head -1)" \
+if [ "$(gpg-connect-agent --no-autostart getval\ $token /bye 2>/dev/null | head -1)" \
= "D set" ]; then
echo "gpg-agent already running" >&2
exit 0
fi
-echo "starting gpg-agent " >&2
-gpg-connect-agent putval\ $token\ set /bye >/dev/null 2>&1
-if [ "$(gpg-connect-agent getval\ $token /bye 2>/dev/null | head -1)" \
+echo "starting gpg-agent.." >&2
+
+# GnuPG prior to 2.1.12 needs --allow-loopback-pinentry for the
+# loopback entry to work. Old versions do not understand this though,
+# so we need to be careful.
+if "$GPG_AGENT" --gpgconf-test --allow-loopback-pinentry &&
+ test -f "$GNUPGHOME/gpg-agent.conf" &&
+ ! grep -q allow-loopback-pinentry "$GNUPGHOME/gpg-agent.conf"; then
+ echo allow-loopback-pinentry >> "$GNUPGHOME/gpg-agent.conf"
+fi
+
+gpg-connect-agent --agent-program="${GPG_AGENT}|--debug-quick-random" putval\ $token\ set /bye
+if [ $? -ne 0 -o "$(gpg-connect-agent getval\ $token /bye 2>/dev/null | head -1)" \
!= "D set" ]; then
echo "error starting gpg-agent" >&2
exit 1
diff --git a/tests/t-engine-info.c b/tests/t-engine-info.c
index 8f617f9..43257eb 100644
--- a/tests/t-engine-info.c
+++ b/tests/t-engine-info.c
@@ -125,7 +125,9 @@ main (int argc, char **argv )
"gpgconf-name",
"gpg-name",
"gpgsm-name",
- "g13-name", NULL };
+ "g13-name",
+ "gpg-wks-client-name",
+ NULL };
const char *s;
int i;