From fd5caec0dccd1229c2b9dd5220c8e2b1ef966d0e Mon Sep 17 00:00:00 2001 From: JinWang An Date: Wed, 1 Dec 2021 16:54:35 +0900 Subject: [PATCH] Imported Upstream version 1.6.0 --- ChangeLog | 170 +++++++++++ NEWS | 33 ++ VERSION | 2 +- configure | 51 ++-- configure.ac | 24 +- doc/HACKING | 48 ++- doc/gpgme.info | 230 +++++++------- doc/gpgme.info-1 | 825 ++++++-------------------------------------------- doc/gpgme.info-2 | Bin 42141 -> 81028 bytes doc/gpgme.texi | 97 +++++- doc/lesser.texi | 13 +- doc/stamp-vti | 8 +- doc/version.texi | 8 +- gpgme.spec | 2 +- lang/cl/gpgme.asd | 2 +- src/Makefile.in | 4 +- src/context.h | 7 + src/debug.c | 12 +- src/decrypt.c | 19 ++ src/encrypt.c | 9 + src/engine-assuan.c | 10 +- src/engine-backend.h | 6 +- src/engine-g13.c | 10 +- src/engine-gpg.c | 33 +- src/engine-gpgsm.c | 58 ++-- src/engine-uiserver.c | 10 +- src/engine.c | 10 +- src/engine.h | 9 +- src/export.c | 35 ++- src/genkey.c | 26 ++ src/gpgme-tool.c | 35 ++- src/gpgme.c | 65 ++++ src/gpgme.def | 6 + src/gpgme.h.in | 485 +++++++++++++++++------------ src/keylist.c | 13 +- src/libgpgme.vers | 6 + src/op-support.c | 24 ++ src/ops.h | 4 + src/passphrase.c | 43 ++- src/passwd.c | 9 + src/sign.c | 15 +- src/status-table.c | 2 + src/sys-util.h | 4 + src/verify.c | 9 + src/versioninfo.rc.in | 2 +- src/w32-util.c | 132 ++++---- tests/Makefile.am | 1 + tests/Makefile.in | 1 + tests/run-export.c | 41 ++- tests/run-keylist.c | 9 + tests/run-sign.c | 26 ++ 51 files changed, 1475 insertions(+), 1228 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1008491..b1a8397 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,173 @@ +2015-08-26 Werner Koch + + Release 1.6.0. + * configure.ac: Set LT version to C25/A14/R0. + + Make use of GPGRT macros is available. + * 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. + +2015-08-25 Werner Koch + + Avoid -Wundef warnings if gpgme.h is used by g++. + * src/gpgme.h.in (_GPGME_INLINE): Move definition into the + extern-C-scope. + + Add configure option --enable-build-timestamp. + * configure.ac (BUILD_TIMESTAMP): Set to "" by default. + +2015-08-25 Daiki Ueno + + Relax ttyname_r error checks. + * src/engine-assuan.c (llass_new): Don't treat ttyname_r error as + fatal. + * src/engine-g13.c (g13_new): Likewise. + * src/engine-gpg.c (gpg_new): Likewise. + * src/engine-gpgsm.c (gpgsm_new): Likewise. + * src/engine-uiserver.c (uiserver_new): Likewise. + +2015-08-25 Werner Koch + + Cleanup layout of gpgme.h. + * src/gpgme.h.in: Reorder prototypes. Chnage some comments. + + Improve error return by checking the FAILURE status. + * src/gpgme.h.in (GPGME_STATUS_FAILURE): New. + * src/status-table.c (FAILURE): New. + * src/op-support.c (_gpgme_parse_failure): New. + * src/passphrase.c (_gpgme_passphrase_status_handler): Forward FAILURE + status line to the status callback. + + * src/decrypt.c (op_data_t): Add field failure_code. + (_gpgme_decrypt_status_handler): Parse that code and act upon it on EOF. + * src/encrypt.c (op_data_t): Add field failure_code. + (_gpgme_encrypt_status_handler): Parse that code and act upon it on EOF. + * src/genkey.c (op_data_t): Add field failure_code. + (genkey_status_handler): Parse that code and act upon it on EOF. + * src/passwd.c (op_data_t): Add field failure_code. + (passwd_status_handler): Parse that code and act upon it on EOF. + * src/sign.c (op_data_t): Add field failure_code. + (_gpgme_sign_status_handler): Parse that code and act upon it on EOF. + * src/verify.c (op_data_t): Add field failure_code. + (_gpgme_verify_status_handler): Parse that code and act upon it on EOF. + + tests: Allow using run-sign to test loopback pinentry problems. + * tests/run-sign.c: Add options --status and --loopback. + +2015-08-24 Werner Koch + + Call status_cb for an ERROR status seen in the passphrase handler. + * src/passphrase.c (_gpgme_passphrase_status_handler): Call status_cb. + + w32: Look for gpgconf in the new GnuPG 2.1 install dir. + * 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. + * 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. + * src/debug.c (debug_init) [W32]: Show libgpgme installation dir. + + Add an export secret key feature. + * src/gpgme.h.in (GPGME_EXPORT_MODE_SECRET): New. + (GPGME_EXPORT_MODE_RAW): New. + (GPGME_EXPORT_MODE_PKCS12): New. + * src/export.c (export_start, export_ext_start): Allow new flags. + * src/engine-gpg.c (export_common): Support secret key export. + * src/engine-gpgsm.c (gpgsm_export, gpgsm_export_ext): Ditto. + + * src/gpgme-tool.c (cmd_export): Add options --secret, --raw, + and --pkcs12. + * tests/run-export.c (main): Likewise. + +2015-08-16 Ben Kibbey + + Parse INQUIRE_MAXLEN in the passphrase callback. + * 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. + * 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. + * 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. + * src/decrypt.c (_gpgme_decrypt_status_handler): Ditto. + * src/sign.c (_gpgme_sign_status_handler): Ditto. + + This status message informs the client of the maximum length of an + inquired line. It is sent from gpg and forwarded to the client via + gpgme_status_cb_t. + + Add gpgme_set/get_status_cb(). + * src/gpgme.h.in (gpgme_set_status_cb): New. + (gpgme_get_status_cb): New. + (gpgme_status_cb_t): New. + * src/gpgme.c (gpgme_set_status_cb): New. + (gpgme_get_status_cb): New. + * src/context.h (status_cb): New. + (status_cb_value): New. + * src/gpgme.def: Export new symbols. + * src/libgpgme.vers: Ditto. + * doc/gpgme.texi: Document these new functions. + + Make use of user passphrase handler during genkey. + * src/genkey.c (genkey_start): set engine passphrase command handler. + +2015-08-12 Ben Kibbey + + Also check the return code in gpg_sign(). + * src/engine-gpg.c (gpg_sign): Check return value from start(). + +2015-08-11 Ben Kibbey + + Check the return value when starting gpg. + * src/engine-gpg.c (gpg_decrypt, gpg_delete, gpg_passwd): Check return + value of start(). + +2015-07-31 Andre Heinecke + + Add offline mode support for CMS keylisting. + * doc/gpgme.texi: Document offline mode. + * src/context.h (gpgme_context): Add offline. + * src/engine-backend.h (keylist, keylist_ext): Add engine_flags. + * src/engine.c, src/engine.h (_gpgme_engine_op_keylist): Ditto. + (_gpgme_engine_op_keylist_ext): Ditto. + * src/engine.h (GPGME_ENGINE_FLAG_OFFLINE): New. + * src/engine-gpg.c (gpg_keylist, gpg_keylist_ext): Ditto. + * src/engine-gpgsm.c (gpgsm_keylist): Handle engine_flags. + (gpgsm_keylist_ext): Ditto. + * src/gpgme.c (gpgme_set_offline, gpgme_get_offline): New. + * src/gpgme.def (gpgme_set_offline, gpgme_get_offline): New. + * src/gpgme.h.in (gpgme_set_offline, gpgme_get_offline): New. + * src/libgpgme.vers (gpgme_set_offline, gpgme_get_offline): New. + * src/keylist.c (gpgme_op_keylist_start): Set offline flag. + (gpgme_op_keylist_ext_start): Ditto. + * tests/run-keylist.c (show_usage, main): Add offline argument. + +2015-07-23 Peter Wu + + build: ignore scissor line for the commit-msg hook. + * build-aux/git-hooks/commit-msg: Stop processing more lines when the + scissor line is encountered. + +2015-07-23 Werner Koch + + Add option --lib-version to gpgme-tool. + * src/gpgme-tool.c (options, parse_options): Add --lib-version + (CMD_LIBVERSION): New. + (main): Implement. + 2015-06-08 Werner Koch Release 1.5.5. diff --git a/NEWS b/NEWS index 8e9472a..8518dae 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,36 @@ +Noteworthy changes in version 1.6.0 (2015-08-26) [C25/A14/R0] +------------------------------------------------ + + * Added gpgme_set_offline to do a key listinging w/o requiring CRL. + + * Added gpgme_set_status_cb to allow a user to see some status + messages. + + * Added an export mode for secret keys. + + * More precise error codes are returned if GnuPG >= 2.1.8 is used. + + * The passphrase handler for the loopback mode has been improved and may + also be used with genkey. + + * [w32] The standard GnuPG 2.1 install directory is now seached for + gpgconf.exe before a registry specified directory and the Gpg4win + install directory. + + * [w32] gpgme-w32spawn.exe will now only be searched in the gpgme DLL + directory. + + * Interface changes relative to the 1.5.1 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgme_set_offline NEW. + gpgme_get_offline NEW. + gpgme_set_status_cb NEW. + gpgme_get_status_cb NEW. + GPGME_EXPORT_MODE_SECRET NEW + GPGME_EXPORT_MODE_RAW NEW. + GPGME_EXPORT_MODE_PKCS12 NEW. + + Noteworthy changes in version 1.5.5 (2015-06-08) [C24/A13/R4] ------------------------------------------------ diff --git a/VERSION b/VERSION index 9075be4..dc1e644 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.5 +1.6.0 diff --git a/configure b/configure index 4d9c0e5..cf0c337 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.5.5. +# Generated by GNU Autoconf 2.69 for gpgme 1.6.0. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='gpgme' PACKAGE_TARNAME='gpgme' -PACKAGE_VERSION='1.5.5' -PACKAGE_STRING='gpgme 1.5.5' +PACKAGE_VERSION='1.6.0' +PACKAGE_STRING='gpgme 1.6.0' PACKAGE_BUGREPORT='http://bugs.gnupg.org' PACKAGE_URL='' @@ -845,6 +845,7 @@ enable_glibtest enable_w32_glib enable_w32_qt enable_fixed_path +enable_build_timestamp enable_gpgconf_test enable_gpg_test enable_gpgsm_test @@ -1409,7 +1410,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.5.5 to adapt to many kinds of systems. +\`configure' configures gpgme 1.6.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1479,7 +1480,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of gpgme 1.5.5:";; + short | recursive ) echo "Configuration of gpgme 1.6.0:";; esac cat <<\_ACEOF @@ -1506,6 +1507,9 @@ Optional Features: --enable-w32-qt build GPGME Qt for W32 --enable-fixed-path=PATH locate binaries only via this PATH + --enable-build-timestamp + set an explicit build timestamp for reproducibility. + (default is the current time in ISO-8601 format) --disable-gpgconf-test disable GPGCONF regression test --disable-gpg-test disable GPG regression test --disable-gpgsm-test disable GPGSM regression test @@ -1607,7 +1611,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -gpgme configure 1.5.5 +gpgme configure 1.6.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2437,7 +2441,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.5.5, which was +It was created by gpgme $as_me 1.6.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2800,11 +2804,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # (Interfaces added: AGE++) # (Interfaces removed/changed: AGE=0) # -LIBGPGME_LT_CURRENT=24 +LIBGPGME_LT_CURRENT=25 # Subtract 2 from this value if you want to make the LFS transition an # ABI break. [Note to self: Remove this comment with the next regular break.] -LIBGPGME_LT_AGE=13 -LIBGPGME_LT_REVISION=4 +LIBGPGME_LT_AGE=14 +LIBGPGME_LT_REVISION=0 # If the API is changed in an incompatible way: increment the next counter. GPGME_CONFIG_API_VERSION=1 @@ -3337,7 +3341,7 @@ fi # Define the identity of the package. PACKAGE='gpgme' - VERSION='1.5.5' + VERSION='1.6.0' cat >>confdefs.h <<_ACEOF @@ -6241,7 +6245,7 @@ cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF -VERSION_NUMBER=0x010505 +VERSION_NUMBER=0x010600 # Don't default to build static libs. @@ -17585,7 +17589,7 @@ fi # # Provide information about the build. # -BUILD_REVISION="052a9e3" +BUILD_REVISION="107bff7" cat >>confdefs.h <<_ACEOF @@ -17594,10 +17598,20 @@ _ACEOF BUILD_FILEVERSION=`echo "$PACKAGE_VERSION"|sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` -BUILD_FILEVERSION="${BUILD_FILEVERSION}1322" +BUILD_FILEVERSION="${BUILD_FILEVERSION}4219" -BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date` +# Check whether --enable-build-timestamp was given. +if test "${enable_build_timestamp+set}" = set; then : + enableval=$enable_build_timestamp; if test "$enableval" = "yes"; then + BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date` + else + BUILD_TIMESTAMP="$enableval" + fi +else + BUILD_TIMESTAMP="" +fi + cat >>confdefs.h <<_ACEOF @@ -17605,6 +17619,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF + # # Options to disable some regression tests # @@ -19843,7 +19858,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.5.5, which was +This file was extended by gpgme $as_me 1.6.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19909,7 +19924,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.5.5 +gpgme config.status 1.6.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -22201,7 +22216,7 @@ fi echo " GPGME v${VERSION} has been configured as follows: - Revision: 052a9e3 (1322) + Revision: 107bff7 (4219) Platform: $host UI Server: $uiserver diff --git a/configure.ac b/configure.ac index 7f03170..015ed46 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # configure.ac for GPGME # Copyright (C) 2000 Werner Koch (dd9jn) # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -# 2009, 2010, 2011, 2012, 2013 g10 Code GmbH +# 2009, 2010, 2011, 2012, 2013, 2014, 2015 g10 Code GmbH # # This file is part of GPGME. # @@ -28,8 +28,8 @@ 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, [5]) -m4_define(mym4_version_micro, [5]) +m4_define(mym4_version_minor, [6]) +m4_define(mym4_version_micro, [0]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag @@ -55,11 +55,11 @@ AC_INIT([gpgme],[mym4_full_version],[http://bugs.gnupg.org]) # (Interfaces added: AGE++) # (Interfaces removed/changed: AGE=0) # -LIBGPGME_LT_CURRENT=24 +LIBGPGME_LT_CURRENT=25 # Subtract 2 from this value if you want to make the LFS transition an # ABI break. [Note to self: Remove this comment with the next regular break.] -LIBGPGME_LT_AGE=13 -LIBGPGME_LT_REVISION=4 +LIBGPGME_LT_AGE=14 +LIBGPGME_LT_REVISION=0 # If the API is changed in an incompatible way: increment the next counter. GPGME_CONFIG_API_VERSION=1 @@ -260,11 +260,21 @@ changequote([,])dnl BUILD_FILEVERSION="${BUILD_FILEVERSION}mym4_revision_dec" AC_SUBST(BUILD_FILEVERSION) -BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date` +AC_ARG_ENABLE([build-timestamp], + AC_HELP_STRING([--enable-build-timestamp], + [set an explicit build timestamp for reproducibility. + (default is the current time in ISO-8601 format)]), + [if test "$enableval" = "yes"; then + BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date` + else + BUILD_TIMESTAMP="$enableval" + fi], + [BUILD_TIMESTAMP=""]) AC_SUBST(BUILD_TIMESTAMP) AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP", [The time this package was configured for a build]) + # # Options to disable some regression tests # diff --git a/doc/HACKING b/doc/HACKING index aedcf09..83c0f51 100644 --- a/doc/HACKING +++ b/doc/HACKING @@ -23,11 +23,34 @@ the big picture. Omit the leading TABs that you're used to seeing in a "real" ChangeLog file, but keep the maximum line length at 72 or smaller, so that the generated ChangeLog lines, each with its - leading TAB, will not exceed 80 columns. + leading TAB, will not exceed 80 columns. If you want to add text + which shall not be copied to the ChangeLog, separate it by a line + consisting of two dashes at the begin of a line. Note that ./autogen.sh installs a git hook to do some basic syntax checking on the commit log message. + Typo fixes and documentation updates don't need a ChangeLog entry; + thus you would use a commit message like + + #+begin_example + Fix typo in a comment + + -- + #+end_example + + The marker line here is important; without it the first line would + appear in the ChangeLog. + + If you exceptionally need to have longer lines in a commit log you may + do this after this scissor line: + #+begin_example + # ------------------------ >8 ------------------------ + #+end_example + (hash, blank, 24 dashes, blank, scissor, blank, 24 dashes). + Note that such a comment will be removed if the git commit option + =--cleanup-scissor= is used. + ** License policy GPGME is currently licensed under the LGPLv2.1+ with tools and the @@ -73,6 +96,29 @@ need. If you really need to do it, use a separate commit for such a change. + - C99 syntax should not be used; stick to C90. + - Please do not use C++ =//= style comments. + - Try to fit lines into 80 columns. + - Ignore signed/unsigned pointer mismatches + - No arithmetic on void pointers; cast to char* first. + +** Commit log keywords + + - GnuPG-bug-id :: Values are comma or space delimited bug numbers + from bug.gnupg.org pertaining to this commit. + - Debian-bug-id :: Same as above but from the Debian bug tracker. + - CVE-id :: CVE id number pertaining to this commit. + - Regression-due-to :: Commit id of the regression fixed by this commit. + - Fixes-commit :: Commit id this commit fixes. + - Reported-by :: Value is a name or mail address of a bug reporte. + - Suggested-by :: Value is a name or mail address of someone how + suggested this change. + - Co-authored-by :: Name or mail address of a co-author + - Some-comments-by :: Name or mail address of the author of + additional comments (commit log or code). + - Proofread-by :: Sometimes used by translation commits. + - Signed-off-by :: Name or mail address of the developer + * Debug hints - Use gpgme-tool for manual tests. diff --git a/doc/gpgme.info b/doc/gpgme.info index b2ee2d4..793c20b 100644 --- a/doc/gpgme.info +++ b/doc/gpgme.info @@ -20,8 +20,8 @@ END-INFO-DIR-ENTRY This file documents the GPGME library. - This is Edition 1.5.5, last updated 6 November 2014, of ‘The ‘GnuPG -Made Easy’ Reference Manual’, for Version 1.5.5. + This is Edition 1.6.0, last updated 26 August 2015, of ‘The ‘GnuPG +Made Easy’ Reference Manual’, for Version 1.6.0. Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2012, 2013, 2014 g10 Code GmbH. @@ -39,121 +39,123 @@ Public License for more details.  Indirect: -gpgme.info-1: 1739 -gpgme.info-2: 336269 +gpgme.info-1: 1738 +gpgme.info-2: 302237  Tag Table: (Indirect) -Node: Top1739 -Node: Introduction8866 -Node: Getting Started9656 -Node: Features10781 -Node: Overview11937 -Node: Preparation13046 -Node: Header14043 -Node: Building the Source14790 -Node: Largefile Support (LFS)16963 -Node: Using Automake22377 -Node: Using Libtool24823 -Node: Library Version Check25185 -Node: Signal Handling30279 -Node: Multi Threading31549 -Ref: Multi Threading-Footnote-133783 -Node: Protocols and Engines34206 -Node: Engine Version Check36695 -Node: Engine Information38321 -Node: Engine Configuration42181 -Node: OpenPGP43465 -Node: Cryptographic Message Syntax43805 -Node: Algorithms44103 -Ref: Algorithms-Footnote-144582 -Node: Public Key Algorithms44710 -Node: Hash Algorithms46687 -Node: Error Handling47877 -Node: Error Values49751 -Node: Error Sources54954 -Node: Error Codes57394 -Node: Error Strings62185 -Node: Exchanging Data63992 -Node: Creating Data Buffers65858 -Node: Memory Based Data Buffers66374 -Node: File Based Data Buffers69807 -Node: Callback Based Data Buffers72009 -Node: Destroying Data Buffers77696 -Node: Manipulating Data Buffers79087 -Node: Data Buffer I/O Operations79579 -Node: Data Buffer Meta-Data82306 -Node: Data Buffer Convenience85774 -Node: Contexts87751 -Node: Creating Contexts88937 -Node: Destroying Contexts89784 -Node: Result Management90123 -Node: Context Attributes91552 -Node: Protocol Selection92332 -Node: Crypto Engine93364 -Node: ASCII Armor95207 -Node: Text Mode95831 -Node: Included Certificates96774 -Node: Key Listing Mode98192 -Node: Passphrase Callback102066 -Node: Progress Meter Callback105278 -Node: Locale107244 -Node: Key Management108801 -Node: Listing Keys119694 -Node: Information About Keys127120 -Node: Key Signatures135451 -Node: Manipulating Keys139587 -Node: Generating Keys140447 -Node: Exporting Keys145171 -Node: Importing Keys151209 -Ref: Importing Keys-Footnote-1158646 -Node: Deleting Keys158774 -Node: Changing Passphrases160219 -Node: Advanced Key Editing161508 -Node: Trust Item Management164690 -Node: Listing Trust Items165802 -Node: Information About Trust Items168168 -Node: Manipulating Trust Items170097 -Node: Crypto Operations171076 -Node: Decrypt172340 -Node: Verify176210 -Node: Decrypt and Verify194587 -Node: Sign196655 -Node: Selecting Signers197219 -Node: Creating a Signature198391 -Node: Signature Notation Data203161 -Node: Encrypt205389 -Node: Encrypting a Plaintext205745 -Node: Miscellaneous212419 -Node: Running other Programs212707 -Node: Run Control214731 -Node: Waiting For Completion215475 -Node: Using External Event Loops217593 -Node: I/O Callback Interface219565 -Node: Registering I/O Callbacks224803 -Node: I/O Callback Example226841 -Node: I/O Callback Example GTK+233058 -Node: I/O Callback Example GDK234847 -Node: I/O Callback Example Qt236489 -Node: Cancellation238777 -Node: UI Server Protocol241070 -Ref: UI Server Protocol-Footnote-1242505 -Node: UI Server Encrypt242624 -Node: UI Server Sign247769 -Node: UI Server Decrypt250122 -Node: UI Server Verify251588 -Node: UI Server Set Input Files255160 -Node: UI Server Sign/Encrypt Files256230 -Node: UI Server Verify/Decrypt Files258038 -Node: UI Server Import/Export Keys259914 -Node: UI Server Checksum Files260976 -Node: Miscellaneous UI Server Commands263192 -Ref: command SENDER265123 -Node: Debugging266825 -Node: Library Copying268569 -Node: Copying296774 -Node: Function and Data Index336269 -Node: Concept Index362522 +Node: Top1738 +Node: Introduction8990 +Node: Getting Started9780 +Node: Features10905 +Node: Overview12061 +Node: Preparation13170 +Node: Header14167 +Node: Building the Source14914 +Node: Largefile Support (LFS)17087 +Node: Using Automake22501 +Node: Using Libtool24947 +Node: Library Version Check25309 +Node: Signal Handling30403 +Node: Multi Threading31673 +Ref: Multi Threading-Footnote-133907 +Node: Protocols and Engines34330 +Node: Engine Version Check36819 +Node: Engine Information38445 +Node: Engine Configuration42305 +Node: OpenPGP43589 +Node: Cryptographic Message Syntax43929 +Node: Algorithms44227 +Ref: Algorithms-Footnote-144706 +Node: Public Key Algorithms44834 +Node: Hash Algorithms46811 +Node: Error Handling48001 +Node: Error Values49875 +Node: Error Sources55078 +Node: Error Codes57518 +Node: Error Strings62309 +Node: Exchanging Data64116 +Node: Creating Data Buffers65982 +Node: Memory Based Data Buffers66498 +Node: File Based Data Buffers69931 +Node: Callback Based Data Buffers72133 +Node: Destroying Data Buffers77820 +Node: Manipulating Data Buffers79211 +Node: Data Buffer I/O Operations79703 +Node: Data Buffer Meta-Data82430 +Node: Data Buffer Convenience85898 +Node: Contexts87875 +Node: Creating Contexts89061 +Node: Destroying Contexts89908 +Node: Result Management90247 +Node: Context Attributes91676 +Node: Protocol Selection92582 +Node: Crypto Engine93614 +Node: ASCII Armor95457 +Node: Text Mode96081 +Node: Offline Mode97015 +Node: Included Certificates98095 +Node: Key Listing Mode99516 +Node: Passphrase Callback103390 +Node: Progress Meter Callback106602 +Node: Status Message Callback108585 +Node: Locale110305 +Node: Key Management111864 +Node: Listing Keys122757 +Node: Information About Keys130183 +Node: Key Signatures138514 +Node: Manipulating Keys142650 +Node: Generating Keys143510 +Node: Exporting Keys148234 +Node: Importing Keys154934 +Ref: Importing Keys-Footnote-1162371 +Node: Deleting Keys162499 +Node: Changing Passphrases163944 +Node: Advanced Key Editing165233 +Node: Trust Item Management168415 +Node: Listing Trust Items169527 +Node: Information About Trust Items171893 +Node: Manipulating Trust Items173822 +Node: Crypto Operations174801 +Node: Decrypt176065 +Node: Verify179935 +Node: Decrypt and Verify198312 +Node: Sign200380 +Node: Selecting Signers200944 +Node: Creating a Signature202116 +Node: Signature Notation Data206886 +Node: Encrypt209114 +Node: Encrypting a Plaintext209470 +Node: Miscellaneous216144 +Node: Running other Programs216432 +Node: Run Control218456 +Node: Waiting For Completion219200 +Node: Using External Event Loops221318 +Node: I/O Callback Interface223290 +Node: Registering I/O Callbacks228528 +Node: I/O Callback Example230566 +Node: I/O Callback Example GTK+236783 +Node: I/O Callback Example GDK238572 +Node: I/O Callback Example Qt240214 +Node: Cancellation242502 +Node: UI Server Protocol244795 +Ref: UI Server Protocol-Footnote-1246230 +Node: UI Server Encrypt246349 +Node: UI Server Sign251494 +Node: UI Server Decrypt253847 +Node: UI Server Verify255313 +Node: UI Server Set Input Files258885 +Node: UI Server Sign/Encrypt Files259955 +Node: UI Server Verify/Decrypt Files261763 +Node: UI Server Import/Export Keys263639 +Node: UI Server Checksum Files264701 +Node: Miscellaneous UI Server Commands266917 +Ref: command SENDER268848 +Node: Debugging270550 +Node: Library Copying272294 +Node: Copying302237 +Node: Concept Index339983 +Node: Function and Data Index354540  End Tag Table diff --git a/doc/gpgme.info-1 b/doc/gpgme.info-1 index 3ae7217..26184d8 100644 --- a/doc/gpgme.info-1 +++ b/doc/gpgme.info-1 @@ -20,8 +20,8 @@ END-INFO-DIR-ENTRY This file documents the GPGME library. - This is Edition 1.5.5, last updated 6 November 2014, of ‘The ‘GnuPG -Made Easy’ Reference Manual’, for Version 1.5.5. + This is Edition 1.6.0, last updated 26 August 2015, of ‘The ‘GnuPG +Made Easy’ Reference Manual’, for Version 1.6.0. Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2012, 2013, 2014 g10 Code GmbH. @@ -43,8 +43,8 @@ File: gpgme.info, Node: Top, Next: Introduction, Up: (dir) Main Menu ********* -This is Edition 1.5.5, last updated 6 November 2014, of ‘The ‘GnuPG Made -Easy’ Reference Manual’, for Version 1.5.5 of the GPGME library. +This is Edition 1.6.0, last updated 26 August 2015, of ‘The ‘GnuPG Made +Easy’ Reference Manual’, for Version 1.6.0 of the GPGME library. * Menu: @@ -146,10 +146,12 @@ Context Attributes * Crypto Engine:: Configuring the crypto engine. * ASCII Armor:: Requesting ASCII armored output. * Text Mode:: Choosing canonical text mode. +* Offline Mode:: Choosing offline mode. * Included Certificates:: Including a number of certificates. * Key Listing Mode:: Selecting key listing mode. * Passphrase Callback:: Getting the passphrase from the user. * Progress Meter Callback:: Being informed about the progress. +* Status Message Callback:: Status messages received from gpg. * Locale:: Setting the locale of a context. Key Management @@ -2123,10 +2125,12 @@ File: gpgme.info, Node: Context Attributes, Next: Key Management, Prev: Resul * Crypto Engine:: Configuring the crypto engine. * ASCII Armor:: Requesting ASCII armored output. * Text Mode:: Choosing canonical text mode. +* Offline Mode:: Choosing offline mode. * Included Certificates:: Including a number of certificates. * Key Listing Mode:: Selecting key listing mode. * Passphrase Callback:: Getting the passphrase from the user. * Progress Meter Callback:: Being informed about the progress. +* Status Message Callback:: Status messages received from gpg. * Locale:: Setting the locale of a context.  @@ -2216,7 +2220,7 @@ File: gpgme.info, Node: ASCII Armor, Next: Text Mode, Prev: Crypto Engine, U armored, and ‘0’ if it is not, or if CTX is not a valid pointer.  -File: gpgme.info, Node: Text Mode, Next: Included Certificates, Prev: ASCII Armor, Up: Context Attributes +File: gpgme.info, Node: Text Mode, Next: Offline Mode, Prev: ASCII Armor, Up: Context Attributes 7.4.4 Text Mode --------------- @@ -2240,9 +2244,36 @@ File: gpgme.info, Node: Text Mode, Next: Included Certificates, Prev: ASCII A is enabled, and ‘0’ if it is not, or if CTX is not a valid pointer.  -File: gpgme.info, Node: Included Certificates, Next: Key Listing Mode, Prev: Text Mode, Up: Context Attributes +File: gpgme.info, Node: Offline Mode, Next: Included Certificates, Prev: Text Mode, Up: Context Attributes -7.4.5 Included Certificates +7.4.5 Offline Mode +------------------ + + -- Function: void gpgme_set_offline (gpgme_ctx_t CTX, int YES) + The function ‘gpgme_set_offline’ specifies if offline mode should + be used. By default, offline mode is not used. + + The offline mode specifies if dirmngr should be used to do + additional validation that might require connections to external + services. (e.g. CRL / OCSP checks). + + Offline mode only affects the keylist mode + ‘GPGME_KEYLIST_MODE_VALIDATE’ and is only relevant to the CMS + crypto engine. Offline mode is ignored otherwise. + + This option may be extended in the future to completely disable the + use of dirmngr for any engine. + + Offline mode is disabled if YES is zero, and enabled otherwise. + + -- Function: int gpgme_get_offline (gpgme_ctx_t CTX) + The function ‘gpgme_get_offline’ returns 1 if offline mode is + enabled, and ‘0’ if it is not, or if CTX is not a valid pointer. + + +File: gpgme.info, Node: Included Certificates, Next: Key Listing Mode, Prev: Offline Mode, Up: Context Attributes + +7.4.6 Included Certificates --------------------------- -- Function: void gpgme_set_include_certs (gpgme_ctx_t CTX, @@ -2280,7 +2311,7 @@ File: gpgme.info, Node: Included Certificates, Next: Key Listing Mode, Prev:  File: gpgme.info, Node: Key Listing Mode, Next: Passphrase Callback, Prev: Included Certificates, Up: Context Attributes -7.4.6 Key Listing Mode +7.4.7 Key Listing Mode ---------------------- -- Function: gpgme_error_t gpgme_set_keylist_mode (gpgme_ctx_t CTX, @@ -2358,7 +2389,7 @@ File: gpgme.info, Node: Key Listing Mode, Next: Passphrase Callback, Prev: In  File: gpgme.info, Node: Passphrase Callback, Next: Progress Meter Callback, Prev: Key Listing Mode, Up: Context Attributes -7.4.7 Passphrase Callback +7.4.8 Passphrase Callback ------------------------- -- Data type: gpgme_error_t (*gpgme_passphrase_cb_t)(void *HOOK, const @@ -2421,9 +2452,9 @@ File: gpgme.info, Node: Passphrase Callback, Next: Progress Meter Callback, P corresponding value will not be returned.  -File: gpgme.info, Node: Progress Meter Callback, Next: Locale, Prev: Passphrase Callback, Up: Context Attributes +File: gpgme.info, Node: Progress Meter Callback, Next: Status Message Callback, Prev: Passphrase Callback, Up: Context Attributes -7.4.8 Progress Meter Callback +7.4.9 Progress Meter Callback ----------------------------- -- Data type: void (*gpgme_progress_cb_t)(void *HOOK, const char *WHAT, @@ -2463,10 +2494,47 @@ File: gpgme.info, Node: Progress Meter Callback, Next: Locale, Prev: Passphra corresponding value will not be returned.  -File: gpgme.info, Node: Locale, Prev: Progress Meter Callback, Up: Context Attributes +File: gpgme.info, Node: Status Message Callback, Next: Locale, Prev: Progress Meter Callback, Up: Context Attributes -7.4.9 Locale ------------- +7.4.10 Status Message Callback +------------------------------ + + -- Data type: gpgme_error_t (*gpgme_status_cb_t)(void *HOOK, const char + *KEYWORD, const char *ARGS) + The ‘gpgme_status_cb_t’ type is the type of function usable as a + status message callback function. + + The argument KEYWORD is the name of the status message while the + ARGS argument contains any arguments for the status message. + + If an error occurs, return the corresponding ‘gpgme_error_t’ value. + Otherwise, return ‘0’. + + -- Function: void gpgme_set_status_cb (gpgme_ctx_t CTX, + gpgme_status_cb_t STATUSFUNC, void *HOOK_VALUE) + The function ‘gpgme_set_status_cb’ sets the function that is used + when a status message is received from gpg to STATUSFUNC. The + function STATUSFUNC needs to be implemented by the user, and + whenever it is called, it is called with its first argument being + HOOK_VALUE. By default, no status message callback function is + set. + + The user can disable the use of a status message callback function + by calling ‘gpgme_set_status_cb’ with STATUSFUNC being ‘NULL’. + + -- Function: void gpgme_get_status_cb (gpgme_ctx_t CTX, + gpgme_status_cb_t *STATUSFUNC, void **HOOK_VALUE) + The function ‘gpgme_get_status_cb’ returns the function that is + used to process status messages from gpg in *STATUSFUNC, and the + first argument for this function in *HOOK_VALUE. If no status + message callback is set, or CTX is not a valid pointer, ‘NULL’ is + returned in both variables. + + +File: gpgme.info, Node: Locale, Prev: Status Message Callback, Up: Context Attributes + +7.4.11 Locale +------------- A locale setting can be associated with a context. This locale is passed to the crypto engine, and used for applications like the PIN @@ -3412,6 +3480,21 @@ or-ed together. OpenPGP keys it removes all signatures except for the latest self-signatures. For X.509 keys it has no effect. +‘GPGME_EXPORT_MODE_SECRET’ + Instead of exporting the public key, the secret key is exported. + This may not be combined with ‘GPGME_EXPORT_MODE_EXTERN’. For + X.509 the export format is PKCS#8. + +‘GPGME_EXPORT_MODE_RAW’ + If this flag is used with ‘GPGME_EXPORT_MODE_SECRET’ for an X.509 + key the export format will be changed to PKCS#1. This flag may not + be used with OpenPGP. + +‘GPGME_EXPORT_MODE_PKCS12’ + If this flag is used with ‘GPGME_EXPORT_MODE_SECRET’ for an X.509 + key the export format will be changed to PKCS#12 which also + includes the certificate. This flag may not be used with OpenPGP. + -- Function: gpgme_error_t gpgme_op_export (gpgme_ctx_t CTX, const char *PATTERN, gpgme_export_mode_t MODE, gpgme_data_t KEYDATA) @@ -6864,717 +6947,3 @@ if necessary. Here is a sample; alter the names: That’s all there is to it! - -File: gpgme.info, Node: Copying, Next: Function and Data Index, Prev: Library Copying, Up: Top - -GNU General Public License -************************** - - Version 3, 29 June 2007 - - Copyright © 2007 Free Software Foundation, Inc. - - Everyone is permitted to copy and distribute verbatim copies of this - license document, but changing it is not allowed. - -Preamble -======== - -The GNU General Public License is a free, copyleft license for software -and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program–to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers’ and authors’ protection, the GPL clearly explains -that there is no warranty for this free software. For both users’ and -authors’ sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users’ freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - “This License” refers to version 3 of the GNU General Public - License. - - “Copyright” also means copyright-like laws that apply to other - kinds of works, such as semiconductor masks. - - “The Program” refers to any copyrightable work licensed under this - License. Each licensee is addressed as “you”. “Licensees” and - “recipients” may be individuals or organizations. - - To “modify” a work means to copy from or adapt all or part of the - work in a fashion requiring copyright permission, other than the - making of an exact copy. The resulting work is called a “modified - version” of the earlier work or a work “based on” the earlier work. - - A “covered work” means either the unmodified Program or a work - based on the Program. - - To “propagate” a work means to do anything with it that, without - permission, would make you directly or secondarily liable for - infringement under applicable copyright law, except executing it on - a computer or modifying a private copy. Propagation includes - copying, distribution (with or without modification), making - available to the public, and in some countries other activities as - well. - - To “convey” a work means any kind of propagation that enables other - parties to make or receive copies. Mere interaction with a user - through a computer network, with no transfer of a copy, is not - conveying. - - An interactive user interface displays “Appropriate Legal Notices” - to the extent that it includes a convenient and prominently visible - feature that (1) displays an appropriate copyright notice, and (2) - tells the user that there is no warranty for the work (except to - the extent that warranties are provided), that licensees may convey - the work under this License, and how to view a copy of this - License. If the interface presents a list of user commands or - options, such as a menu, a prominent item in the list meets this - criterion. - - 1. Source Code. - - The “source code” for a work means the preferred form of the work - for making modifications to it. “Object code” means any non-source - form of a work. - - A “Standard Interface” means an interface that either is an - official standard defined by a recognized standards body, or, in - the case of interfaces specified for a particular programming - language, one that is widely used among developers working in that - language. - - The “System Libraries” of an executable work include anything, - other than the work as a whole, that (a) is included in the normal - form of packaging a Major Component, but which is not part of that - Major Component, and (b) serves only to enable use of the work with - that Major Component, or to implement a Standard Interface for - which an implementation is available to the public in source code - form. A “Major Component”, in this context, means a major - essential component (kernel, window system, and so on) of the - specific operating system (if any) on which the executable work - runs, or a compiler used to produce the work, or an object code - interpreter used to run it. - - The “Corresponding Source” for a work in object code form means all - the source code needed to generate, install, and (for an executable - work) run the object code and to modify the work, including scripts - to control those activities. However, it does not include the - work’s System Libraries, or general-purpose tools or generally - available free programs which are used unmodified in performing - those activities but which are not part of the work. For example, - Corresponding Source includes interface definition files associated - with source files for the work, and the source code for shared - libraries and dynamically linked subprograms that the work is - specifically designed to require, such as by intimate data - communication or control flow between those subprograms and other - parts of the work. - - The Corresponding Source need not include anything that users can - regenerate automatically from other parts of the Corresponding - Source. - - The Corresponding Source for a work in source code form is that - same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of - copyright on the Program, and are irrevocable provided the stated - conditions are met. This License explicitly affirms your unlimited - permission to run the unmodified Program. The output from running - a covered work is covered by this License only if the output, given - its content, constitutes a covered work. This License acknowledges - your rights of fair use or other equivalent, as provided by - copyright law. - - You may make, run and propagate covered works that you do not - convey, without conditions so long as your license otherwise - remains in force. You may convey covered works to others for the - sole purpose of having them make modifications exclusively for you, - or provide you with facilities for running those works, provided - that you comply with the terms of this License in conveying all - material for which you do not control copyright. Those thus making - or running the covered works for you must do so exclusively on your - behalf, under your direction and control, on terms that prohibit - them from making any copies of your copyrighted material outside - their relationship with you. - - Conveying under any other circumstances is permitted solely under - the conditions stated below. Sublicensing is not allowed; section - 10 makes it unnecessary. - - 3. Protecting Users’ Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological - measure under any applicable law fulfilling obligations under - article 11 of the WIPO copyright treaty adopted on 20 December - 1996, or similar laws prohibiting or restricting circumvention of - such measures. - - When you convey a covered work, you waive any legal power to forbid - circumvention of technological measures to the extent such - circumvention is effected by exercising rights under this License - with respect to the covered work, and you disclaim any intention to - limit operation or modification of the work as a means of - enforcing, against the work’s users, your or third parties’ legal - rights to forbid circumvention of technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program’s source code as you - receive it, in any medium, provided that you conspicuously and - appropriately publish on each copy an appropriate copyright notice; - keep intact all notices stating that this License and any - non-permissive terms added in accord with section 7 apply to the - code; keep intact all notices of the absence of any warranty; and - give all recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, - and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to - produce it from the Program, in the form of source code under the - terms of section 4, provided that you also meet all of these - conditions: - - a. The work must carry prominent notices stating that you - modified it, and giving a relevant date. - - b. The work must carry prominent notices stating that it is - released under this License and any conditions added under - section 7. This requirement modifies the requirement in - section 4 to “keep intact all notices”. - - c. You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable - section 7 additional terms, to the whole of the work, and all - its parts, regardless of how they are packaged. This License - gives no permission to license the work in any other way, but - it does not invalidate such permission if you have separately - received it. - - d. If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has - interactive interfaces that do not display Appropriate Legal - Notices, your work need not make them do so. - - A compilation of a covered work with other separate and independent - works, which are not by their nature extensions of the covered - work, and which are not combined with it such as to form a larger - program, in or on a volume of a storage or distribution medium, is - called an “aggregate” if the compilation and its resulting - copyright are not used to limit the access or legal rights of the - compilation’s users beyond what the individual works permit. - Inclusion of a covered work in an aggregate does not cause this - License to apply to the other parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms - of sections 4 and 5, provided that you also convey the - machine-readable Corresponding Source under the terms of this - License, in one of these ways: - - a. Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b. Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that - product model, to give anyone who possesses the object code - either (1) a copy of the Corresponding Source for all the - software in the product that is covered by this License, on a - durable physical medium customarily used for software - interchange, for a price no more than your reasonable cost of - physically performing this conveying of source, or (2) access - to copy the Corresponding Source from a network server at no - charge. - - c. Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, - and only if you received the object code with such an offer, - in accord with subsection 6b. - - d. Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to - the Corresponding Source in the same way through the same - place at no further charge. You need not require recipients - to copy the Corresponding Source along with the object code. - If the place to copy the object code is a network server, the - Corresponding Source may be on a different server (operated by - you or a third party) that supports equivalent copying - facilities, provided you maintain clear directions next to the - object code saying where to find the Corresponding Source. - Regardless of what server hosts the Corresponding Source, you - remain obligated to ensure that it is available for as long as - needed to satisfy these requirements. - - e. Convey the object code using peer-to-peer transmission, - provided you inform other peers where the object code and - Corresponding Source of the work are being offered to the - general public at no charge under subsection 6d. - - A separable portion of the object code, whose source code is - excluded from the Corresponding Source as a System Library, need - not be included in conveying the object code work. - - A “User Product” is either (1) a “consumer product”, which means - any tangible personal property which is normally used for personal, - family, or household purposes, or (2) anything designed or sold for - incorporation into a dwelling. In determining whether a product is - a consumer product, doubtful cases shall be resolved in favor of - coverage. For a particular product received by a particular user, - “normally used” refers to a typical or common use of that class of - product, regardless of the status of the particular user or of the - way in which the particular user actually uses, or expects or is - expected to use, the product. A product is a consumer product - regardless of whether the product has substantial commercial, - industrial or non-consumer uses, unless such uses represent the - only significant mode of use of the product. - - “Installation Information” for a User Product means any methods, - procedures, authorization keys, or other information required to - install and execute modified versions of a covered work in that - User Product from a modified version of its Corresponding Source. - The information must suffice to ensure that the continued - functioning of the modified object code is in no case prevented or - interfered with solely because modification has been made. - - If you convey an object code work under this section in, or with, - or specifically for use in, a User Product, and the conveying - occurs as part of a transaction in which the right of possession - and use of the User Product is transferred to the recipient in - perpetuity or for a fixed term (regardless of how the transaction - is characterized), the Corresponding Source conveyed under this - section must be accompanied by the Installation Information. But - this requirement does not apply if neither you nor any third party - retains the ability to install modified object code on the User - Product (for example, the work has been installed in ROM). - - The requirement to provide Installation Information does not - include a requirement to continue to provide support service, - warranty, or updates for a work that has been modified or installed - by the recipient, or for the User Product in which it has been - modified or installed. Access to a network may be denied when the - modification itself materially and adversely affects the operation - of the network or violates the rules and protocols for - communication across the network. - - Corresponding Source conveyed, and Installation Information - provided, in accord with this section must be in a format that is - publicly documented (and with an implementation available to the - public in source code form), and must require no special password - or key for unpacking, reading or copying. - - 7. Additional Terms. - - “Additional permissions” are terms that supplement the terms of - this License by making exceptions from one or more of its - conditions. Additional permissions that are applicable to the - entire Program shall be treated as though they were included in - this License, to the extent that they are valid under applicable - law. If additional permissions apply only to part of the Program, - that part may be used separately under those permissions, but the - entire Program remains governed by this License without regard to - the additional permissions. - - When you convey a copy of a covered work, you may at your option - remove any additional permissions from that copy, or from any part - of it. (Additional permissions may be written to require their own - removal in certain cases when you modify the work.) You may place - additional permissions on material, added by you to a covered work, - for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material - you add to a covered work, you may (if authorized by the copyright - holders of that material) supplement the terms of this License with - terms: - - a. Disclaiming warranty or limiting liability differently from - the terms of sections 15 and 16 of this License; or - - b. Requiring preservation of specified reasonable legal notices - or author attributions in that material or in the Appropriate - Legal Notices displayed by works containing it; or - - c. Prohibiting misrepresentation of the origin of that material, - or requiring that modified versions of such material be marked - in reasonable ways as different from the original version; or - - d. Limiting the use for publicity purposes of names of licensors - or authors of the material; or - - e. Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f. Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified - versions of it) with contractual assumptions of liability to - the recipient, for any liability that these contractual - assumptions directly impose on those licensors and authors. - - All other non-permissive additional terms are considered “further - restrictions” within the meaning of section 10. If the Program as - you received it, or any part of it, contains a notice stating that - it is governed by this License along with a term that is a further - restriction, you may remove that term. If a license document - contains a further restriction but permits relicensing or conveying - under this License, you may add to a covered work material governed - by the terms of that license document, provided that the further - restriction does not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you - must place, in the relevant source files, a statement of the - additional terms that apply to those files, or a notice indicating - where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in - the form of a separately written license, or stated as exceptions; - the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly - provided under this License. Any attempt otherwise to propagate or - modify it is void, and will automatically terminate your rights - under this License (including any patent licenses granted under the - third paragraph of section 11). - - However, if you cease all violation of this License, then your - license from a particular copyright holder is reinstated (a) - provisionally, unless and until the copyright holder explicitly and - finally terminates your license, and (b) permanently, if the - copyright holder fails to notify you of the violation by some - reasonable means prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is - reinstated permanently if the copyright holder notifies you of the - violation by some reasonable means, this is the first time you have - received notice of violation of this License (for any work) from - that copyright holder, and you cure the violation prior to 30 days - after your receipt of the notice. - - Termination of your rights under this section does not terminate - the licenses of parties who have received copies or rights from you - under this License. If your rights have been terminated and not - permanently reinstated, you do not qualify to receive new licenses - for the same material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or - run a copy of the Program. Ancillary propagation of a covered work - occurring solely as a consequence of using peer-to-peer - transmission to receive a copy likewise does not require - acceptance. However, nothing other than this License grants you - permission to propagate or modify any covered work. These actions - infringe copyright if you do not accept this License. Therefore, - by modifying or propagating a covered work, you indicate your - acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically - receives a license from the original licensors, to run, modify and - propagate that work, subject to this License. You are not - responsible for enforcing compliance by third parties with this - License. - - An “entity transaction” is a transaction transferring control of an - organization, or substantially all assets of one, or subdividing an - organization, or merging organizations. If propagation of a - covered work results from an entity transaction, each party to that - transaction who receives a copy of the work also receives whatever - licenses to the work the party’s predecessor in interest had or - could give under the previous paragraph, plus a right to possession - of the Corresponding Source of the work from the predecessor in - interest, if the predecessor has it or can get it with reasonable - efforts. - - You may not impose any further restrictions on the exercise of the - rights granted or affirmed under this License. For example, you - may not impose a license fee, royalty, or other charge for exercise - of rights granted under this License, and you may not initiate - litigation (including a cross-claim or counterclaim in a lawsuit) - alleging that any patent claim is infringed by making, using, - selling, offering for sale, or importing the Program or any portion - of it. - - 11. Patents. - - A “contributor” is a copyright holder who authorizes use under this - License of the Program or a work on which the Program is based. - The work thus licensed is called the contributor’s “contributor - version”. - - A contributor’s “essential patent claims” are all patent claims - owned or controlled by the contributor, whether already acquired or - hereafter acquired, that would be infringed by some manner, - permitted by this License, of making, using, or selling its - contributor version, but do not include claims that would be - infringed only as a consequence of further modification of the - contributor version. For purposes of this definition, “control” - includes the right to grant patent sublicenses in a manner - consistent with the requirements of this License. - - Each contributor grants you a non-exclusive, worldwide, - royalty-free patent license under the contributor’s essential - patent claims, to make, use, sell, offer for sale, import and - otherwise run, modify and propagate the contents of its contributor - version. - - In the following three paragraphs, a “patent license” is any - express agreement or commitment, however denominated, not to - enforce a patent (such as an express permission to practice a - patent or covenant not to sue for patent infringement). To “grant” - such a patent license to a party means to make such an agreement or - commitment not to enforce a patent against the party. - - If you convey a covered work, knowingly relying on a patent - license, and the Corresponding Source of the work is not available - for anyone to copy, free of charge and under the terms of this - License, through a publicly available network server or other - readily accessible means, then you must either (1) cause the - Corresponding Source to be so available, or (2) arrange to deprive - yourself of the benefit of the patent license for this particular - work, or (3) arrange, in a manner consistent with the requirements - of this License, to extend the patent license to downstream - recipients. “Knowingly relying” means you have actual knowledge - that, but for the patent license, your conveying the covered work - in a country, or your recipient’s use of the covered work in a - country, would infringe one or more identifiable patents in that - country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or - arrangement, you convey, or propagate by procuring conveyance of, a - covered work, and grant a patent license to some of the parties - receiving the covered work authorizing them to use, propagate, - modify or convey a specific copy of the covered work, then the - patent license you grant is automatically extended to all - recipients of the covered work and works based on it. - - A patent license is “discriminatory” if it does not include within - the scope of its coverage, prohibits the exercise of, or is - conditioned on the non-exercise of one or more of the rights that - are specifically granted under this License. You may not convey a - covered work if you are a party to an arrangement with a third - party that is in the business of distributing software, under which - you make payment to the third party based on the extent of your - activity of conveying the work, and under which the third party - grants, to any of the parties who would receive the covered work - from you, a discriminatory patent license (a) in connection with - copies of the covered work conveyed by you (or copies made from - those copies), or (b) primarily for and in connection with specific - products or compilations that contain the covered work, unless you - entered into that arrangement, or that patent license was granted, - prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting - any implied license or other defenses to infringement that may - otherwise be available to you under applicable patent law. - - 12. No Surrender of Others’ Freedom. - - If conditions are imposed on you (whether by court order, agreement - or otherwise) that contradict the conditions of this License, they - do not excuse you from the conditions of this License. If you - cannot convey a covered work so as to satisfy simultaneously your - obligations under this License and any other pertinent obligations, - then as a consequence you may not convey it at all. For example, - if you agree to terms that obligate you to collect a royalty for - further conveying from those to whom you convey the Program, the - only way you could satisfy both those terms and this License would - be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have - permission to link or combine any covered work with a work licensed - under version 3 of the GNU Affero General Public License into a - single combined work, and to convey the resulting work. The terms - of this License will continue to apply to the part which is the - covered work, but the special requirements of the GNU Affero - General Public License, section 13, concerning interaction through - a network will apply to the combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new - versions of the GNU General Public License from time to time. Such - new versions will be similar in spirit to the present version, but - may differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the - Program specifies that a certain numbered version of the GNU - General Public License “or any later version” applies to it, you - have the option of following the terms and conditions either of - that numbered version or of any later version published by the Free - Software Foundation. If the Program does not specify a version - number of the GNU General Public License, you may choose any - version ever published by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future - versions of the GNU General Public License can be used, that - proxy’s public statement of acceptance of a version permanently - authorizes you to choose that version for the Program. - - Later license versions may give you additional or different - permissions. However, no additional obligations are imposed on any - author or copyright holder as a result of your choosing to follow a - later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY - APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE - COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE - RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. - SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL - NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN - WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES - AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR - DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR - CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE - THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA - BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD - PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER - PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF - THE POSSIBILITY OF SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided - above cannot be given local legal effect according to their terms, - reviewing courts shall apply local law that most closely - approximates an absolute waiver of all civil liability in - connection with the Program, unless a warranty or assumption of - liability accompanies a copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - -How to Apply These Terms to Your New Programs -============================================= - -If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least the -“copyright” line and a pointer to where the full notice is found. - - ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES. - Copyright (C) YEAR NAME OF AUTHOR - - This program 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 3 of the License, or (at - your option) any later version. - - This program 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, see . - -Also add information on how to contact you by electronic and paper mail. - -If the program does terminal interaction, make it output a short notice -like this when it starts in an interactive mode: - - PROGRAM Copyright (C) YEAR NAME OF AUTHOR - This program comes with ABSOLUTELY NO WARRANTY; for details - type ‘show w’. This is free software, and you are - welcome to redistribute it under certain conditions; - type ‘show c’ for details. - - The hypothetical commands ‘show w’ and ‘show c’ should show the -appropriate parts of the General Public License. Of course, your -program’s commands might be different; for a GUI interface, you would -use an “about box”. - - You should also get your employer (if you work as a programmer) or -school, if any, to sign a “copyright disclaimer” for the program, if -necessary. For more information on this, and how to apply and follow -the GNU GPL, see . - - The GNU General Public License does not permit incorporating your -program into proprietary programs. If your program is a subroutine -library, you may consider it more useful to permit linking proprietary -applications with the library. If this is what you want to do, use the -GNU Lesser General Public License instead of this License. But first, -please read . - diff --git a/doc/gpgme.info-2 b/doc/gpgme.info-2 index 543c024039357bad89c1044fc2312484001eaff8..8c01702ab69cd9156a6ac1de4c41040acf545ce4 100644 GIT binary patch literal 81028 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

FM=?FYTb6TdjeqF_0~9vb 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 V%EAq^A;F3Qv-HFM2(x|7oCP5vPS*ec diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 45c359d..c02a30f 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -189,10 +189,12 @@ Context Attributes * Crypto Engine:: Configuring the crypto engine. * ASCII Armor:: Requesting @acronym{ASCII} armored output. * Text Mode:: Choosing canonical text mode. +* Offline Mode:: Choosing offline mode. * Included Certificates:: Including a number of certificates. * Key Listing Mode:: Selecting key listing mode. * Passphrase Callback:: Getting the passphrase from the user. * Progress Meter Callback:: Being informed about the progress. +* Status Message Callback:: Status messages received from gpg. * Locale:: Setting the locale of a context. Key Management @@ -2285,10 +2287,12 @@ started. In fact, these references are accessed through the * Crypto Engine:: Configuring the crypto engine. * ASCII Armor:: Requesting @acronym{ASCII} armored output. * Text Mode:: Choosing canonical text mode. +* Offline Mode:: Choosing offline mode. * Included Certificates:: Including a number of certificates. * Key Listing Mode:: Selecting key listing mode. * Passphrase Callback:: Getting the passphrase from the user. * Progress Meter Callback:: Being informed about the progress. +* Status Message Callback:: Status messages received from gpg. * Locale:: Setting the locale of a context. @end menu @@ -2413,6 +2417,37 @@ valid pointer. @end deftypefun +@node Offline Mode +@subsection Offline Mode +@cindex context, offline mode +@cindex offline mode + +@deftypefun void gpgme_set_offline (@w{gpgme_ctx_t @var{ctx}}, @w{int @var{yes}}) +The function @code{gpgme_set_offline} specifies if offline mode +should be used. By default, offline mode is not used. + +The offline mode specifies if dirmngr should be used to do additional +validation that might require connections to external services. +(e.g. CRL / OCSP checks). + +Offline mode only affects the keylist mode @code{GPGME_KEYLIST_MODE_VALIDATE} +and is only relevant to the CMS crypto engine. Offline mode +is ignored otherwise. + +This option may be extended in the future to completely disable +the use of dirmngr for any engine. + +Offline mode is disabled if @var{yes} is zero, and enabled +otherwise. +@end deftypefun + +@deftypefun int gpgme_get_offline (@w{gpgme_ctx_t @var{ctx}}) +The function @code{gpgme_get_offline} returns 1 if offline +mode is enabled, and @code{0} if it is not, or if @var{ctx} is not a +valid pointer. +@end deftypefun + + @node Included Certificates @subsection Included Certificates @cindex certificates, included @@ -2642,6 +2677,43 @@ the corresponding value will not be returned. @end deftypefun +@node Status Message Callback +@subsection Status Message Callback +@cindex callback, status message +@cindex status message callback + +@deftp {Data type} {gpgme_error_t (*gpgme_status_cb_t)(void *@var{hook}, const char *@var{keyword}, const char *@var{args})} +@tindex gpgme_status_cb_t +The @code{gpgme_status_cb_t} type is the type of function usable as +a status message callback function. + +The argument @var{keyword} is the name of the status message while the +@var{args} argument contains any arguments for the status message. + +If an error occurs, return the corresponding @code{gpgme_error_t} +value. Otherwise, return @code{0}. +@end deftp + +@deftypefun void gpgme_set_status_cb (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_status_cb_t @var{statusfunc}}, @w{void *@var{hook_value}}) +The function @code{gpgme_set_status_cb} sets the function that is used when a +status message is received from gpg to @var{statusfunc}. The function +@var{statusfunc} needs to be implemented by the user, and whenever it is +called, it is called with its first argument being @var{hook_value}. By +default, no status message callback function is set. + +The user can disable the use of a status message callback function by calling +@code{gpgme_set_status_cb} with @var{statusfunc} being @code{NULL}. +@end deftypefun + +@deftypefun void gpgme_get_status_cb (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_status_cb_t *@var{statusfunc}}, @w{void **@var{hook_value}}) +The function @code{gpgme_get_status_cb} returns the function that is used to +process status messages from gpg in @var{*statusfunc}, and the first argument +for this function in @var{*hook_value}. If no status message callback is set, +or @var{ctx} is not a valid pointer, @code{NULL} is returned in both +variables. +@end deftypefun + + @node Locale @subsection Locale @cindex locale, default @@ -3628,6 +3700,21 @@ keys it removes all signatures except for the latest self-signatures. For X.509 keys it has no effect. +@item GPGME_EXPORT_MODE_SECRET +Instead of exporting the public key, the secret key is exported. This +may not be combined with @code{GPGME_EXPORT_MODE_EXTERN}. For X.509 +the export format is PKCS#8. + +@item GPGME_EXPORT_MODE_RAW +If this flag is used with @code{GPGME_EXPORT_MODE_SECRET} for an X.509 +key the export format will be changed to PKCS#1. This flag may not be +used with OpenPGP. + +@item GPGME_EXPORT_MODE_PKCS12 +If this flag is used with @code{GPGME_EXPORT_MODE_SECRET} for an X.509 +key the export format will be changed to PKCS#12 which also includes +the certificate. This flag may not be used with OpenPGP. + @end table @@ -6116,15 +6203,15 @@ you run your tests only with play data. @include gpl.texi -@node Function and Data Index -@unnumbered Function and Data Index - -@printindex fn - @node Concept Index @unnumbered Concept Index @printindex cp +@node Function and Data Index +@unnumbered Function and Data Index + +@printindex fn + @bye diff --git a/doc/lesser.texi b/doc/lesser.texi index f23f0fd..bbd18a0 100644 --- a/doc/lesser.texi +++ b/doc/lesser.texi @@ -1,7 +1,7 @@ @node Library Copying @unnumbered GNU Lesser General Public License -@cindex LGPL, Lesser General Public License +@cindex LGPL, GNU Lesser General Public License @center Version 2.1, February 1999 @display @@ -16,7 +16,7 @@ as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] @end display -@section Preamble +@heading Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -119,7 +119,7 @@ former contains code derived from the library, whereas the latter must be combined with the library in order to run. @iftex -@section TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +@heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @end iftex @ifinfo @center GNU LESSER GENERAL PUBLIC LICENSE @@ -476,12 +476,7 @@ decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. -@iftex -@heading NO WARRANTY -@end iftex -@ifinfo @center NO WARRANTY -@end ifinfo @item BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO @@ -515,7 +510,7 @@ DAMAGES. @end ifinfo @page -@section How to Apply These Terms to Your New Libraries +@heading How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that diff --git a/doc/stamp-vti b/doc/stamp-vti index 8ad6a99..c0e1438 100644 --- a/doc/stamp-vti +++ b/doc/stamp-vti @@ -1,4 +1,4 @@ -@set UPDATED 6 November 2014 -@set UPDATED-MONTH November 2014 -@set EDITION 1.5.5 -@set VERSION 1.5.5 +@set UPDATED 26 August 2015 +@set UPDATED-MONTH August 2015 +@set EDITION 1.6.0 +@set VERSION 1.6.0 diff --git a/doc/version.texi b/doc/version.texi index 8ad6a99..c0e1438 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 6 November 2014 -@set UPDATED-MONTH November 2014 -@set EDITION 1.5.5 -@set VERSION 1.5.5 +@set UPDATED 26 August 2015 +@set UPDATED-MONTH August 2015 +@set EDITION 1.6.0 +@set VERSION 1.6.0 diff --git a/gpgme.spec b/gpgme.spec index 59c1afa..e97e1db 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.5.5 +Version: 1.6.0 Release: 1 URL: http://www.gnupg.org/gpgme.html Source: ftp://ftp.gnupg.org/gcrypt/alpha/gpgme/%{name}-%{version}.tar.gz diff --git a/lang/cl/gpgme.asd b/lang/cl/gpgme.asd index bc8bf0a..9030a65 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.5.5" + :version "1.6.0" :licence "GPL" :depends-on ("cffi" "gpg-error") :components ((:file "gpgme-package") diff --git a/src/Makefile.in b/src/Makefile.in index bdfcaf2..ec839e4 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 setenv.c funopen.c stpcpy.c \ - vasprintf.c ttyname_r.c $(top_srcdir)/build-aux/depcomp + $(srcdir)/gpgme-config.in stpcpy.c funopen.c vasprintf.c \ + setenv.c ttyname_r.c $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/glib-2.0.m4 \ $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/gnupg-ttyname.m4 \ diff --git a/src/context.h b/src/context.h index 745ffa8..757d9b4 100644 --- a/src/context.h +++ b/src/context.h @@ -98,6 +98,9 @@ struct gpgme_context /* True if text mode should be used. */ unsigned int use_textmode : 1; + /* True if offline mode should be used. */ + unsigned int offline : 1; + /* Flags for keylist mode. */ gpgme_keylist_mode_t keylist_mode; @@ -132,6 +135,10 @@ struct gpgme_context gpgme_progress_cb_t progress_cb; void *progress_cb_value; + /* The user provided status callback and its hook value. */ + gpgme_status_cb_t status_cb; + void *status_cb_value; + /* A list of file descriptors in active use by the current operation. */ struct fd_table fdt; diff --git a/src/debug.c b/src/debug.c index 292db55..1dd3723 100644 --- a/src/debug.c +++ b/src/debug.c @@ -46,6 +46,7 @@ #include "util.h" #include "ath.h" #include "sema.h" +#include "sys-util.h" #include "debug.h" @@ -207,7 +208,16 @@ debug_init (void) UNLOCK (debug_lock); if (debug_level > 0) - _gpgme_debug (DEBUG_INIT, "gpgme_debug: level=%d\n", debug_level); + { + _gpgme_debug (DEBUG_INIT, "gpgme_debug: level=%d\n", debug_level); +#ifdef HAVE_W32_SYSTEM + { + const char *name = _gpgme_get_inst_dir (); + _gpgme_debug (DEBUG_INIT, "gpgme_debug: gpgme='%s'\n", + name? name: "?"); + } +#endif + } } diff --git a/src/decrypt.c b/src/decrypt.c index 4742060..4db68a1 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -38,6 +38,9 @@ typedef struct { struct _gpgme_op_decrypt_result result; + /* The error code from a FAILURE status line or 0. */ + gpg_error_t failure_code; + int okay; int failed; @@ -192,6 +195,10 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, switch (code) { + case GPGME_STATUS_FAILURE: + opd->failure_code = _gpgme_parse_failure (args); + break; + case GPGME_STATUS_EOF: /* FIXME: These error values should probably be attributed to the underlying crypto engine (as error source). */ @@ -199,6 +206,8 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, return gpg_error (GPG_ERR_DECRYPT_FAILED); else if (!opd->okay) return gpg_error (GPG_ERR_NO_DATA); + else if (opd->failure_code) + return opd->failure_code; break; case GPGME_STATUS_DECRYPTION_INFO: @@ -291,6 +300,16 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, err = _gpgme_parse_plaintext (args, &opd->result.file_name); if (err) return err; + break; + + case GPGME_STATUS_INQUIRE_MAXLEN: + if (ctx->status_cb) + { + err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args); + if (err) + return err; + } + break; default: break; diff --git a/src/encrypt.c b/src/encrypt.c index 792c25c..9f5134d 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -36,6 +36,9 @@ typedef struct { struct _gpgme_op_encrypt_result result; + /* The error code from a FAILURE status line or 0. */ + gpg_error_t failure_code; + /* A pointer to the next pointer of the last invalid recipient in the list. This makes appending new invalid recipients painless while preserving the order. */ @@ -114,9 +117,15 @@ _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code, switch (code) { + case GPGME_STATUS_FAILURE: + opd->failure_code = _gpgme_parse_failure (args); + break; + case GPGME_STATUS_EOF: if (opd->result.invalid_recipients) return gpg_error (GPG_ERR_UNUSABLE_PUBKEY); + if (opd->failure_code) + return opd->failure_code; break; case GPGME_STATUS_INV_RECP: diff --git a/src/engine-assuan.c b/src/engine-assuan.c index 663b2ea..9902467 100644 --- a/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -282,12 +282,10 @@ llass_new (void **engine, const char *file_name, const char *home_dir) char *dft_ttytype = NULL; rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)); - if (rc) - { - err = gpg_error_from_errno (rc); - goto leave; - } - else + + /* Even though isatty() returns 1, ttyname_r() may fail in many + ways, e.g., when /dev/pts is not accessible under chroot. */ + if (!rc) { if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) { diff --git a/src/engine-backend.h b/src/engine-backend.h index b3cc412..4f4519c 100644 --- a/src/engine-backend.h +++ b/src/engine-backend.h @@ -85,10 +85,12 @@ struct engine_ops gpgme_error_t (*import) (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray); gpgme_error_t (*keylist) (void *engine, const char *pattern, - int secret_only, gpgme_keylist_mode_t mode); + int secret_only, gpgme_keylist_mode_t mode, + int engine_flags); gpgme_error_t (*keylist_ext) (void *engine, const char *pattern[], int secret_only, int reserved, - gpgme_keylist_mode_t mode); + gpgme_keylist_mode_t mode, + int engine_flags); gpgme_error_t (*sign) (void *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-g13.c b/src/engine-g13.c index a9717ee..4a7b75c 100644 --- a/src/engine-g13.c +++ b/src/engine-g13.c @@ -286,12 +286,10 @@ g13_new (void **engine, const char *file_name, const char *home_dir) int rc; rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)); - if (rc) - { - err = gpg_error_from_errno (rc); - goto leave; - } - else + + /* Even though isatty() returns 1, ttyname_r() may fail in many + ways, e.g., when /dev/pts is not accessible under chroot. */ + if (!rc) { if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) { diff --git a/src/engine-gpg.c b/src/engine-gpg.c index e14fd8d..9efced2 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -513,6 +513,8 @@ gpg_new (void **engine, const char *file_name, const char *home_dir) rc = add_arg (gpg, dft_display); free (dft_display); + if (rc) + goto leave; } if (isatty (1)) @@ -520,9 +522,10 @@ gpg_new (void **engine, const char *file_name, const char *home_dir) int err; err = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)); - if (err) - rc = gpg_error_from_errno (err); - else + + /* Even though isatty() returns 1, ttyname_r() may fail in many + ways, e.g., when /dev/pts is not accessible under chroot. */ + if (!err) { if (*dft_ttyname) { @@ -547,9 +550,9 @@ gpg_new (void **engine, const char *file_name, const char *home_dir) free (dft_ttytype); } + if (rc) + goto leave; } - if (rc) - goto leave; } leave: @@ -1456,7 +1459,7 @@ gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain) err = add_data (gpg, ciph, -1, 0); if (!err) - start (gpg); + err = start (gpg); return err; } @@ -1479,7 +1482,7 @@ gpg_delete (void *engine, gpgme_key_t key, int allow_secret) } if (!err) - start (gpg); + err = start (gpg); return err; } @@ -1497,7 +1500,7 @@ gpg_passwd (void *engine, gpgme_key_t key, unsigned int flags) if (!err) err = add_arg (gpg, key->subkeys->fpr); if (!err) - start (gpg); + err = start (gpg); return err; } @@ -1793,7 +1796,8 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode, gpgme_error_t err = 0; if ((mode & ~(GPGME_EXPORT_MODE_EXTERN - |GPGME_EXPORT_MODE_MINIMAL))) + |GPGME_EXPORT_MODE_MINIMAL + |GPGME_EXPORT_MODE_SECRET))) return gpg_error (GPG_ERR_NOT_SUPPORTED); if ((mode & GPGME_EXPORT_MODE_MINIMAL)) @@ -1807,7 +1811,10 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode, } else { - err = add_arg (gpg, "--export"); + if ((mode & GPGME_EXPORT_MODE_SECRET)) + err = add_arg (gpg, "--export-secret-keys"); + else + err = add_arg (gpg, "--export"); if (!err && use_armor) err = add_arg (gpg, "--armor"); if (!err) @@ -2279,7 +2286,7 @@ gpg_keylist_build_options (engine_gpg_t gpg, int secret_only, static gpgme_error_t gpg_keylist (void *engine, const char *pattern, int secret_only, - gpgme_keylist_mode_t mode) + gpgme_keylist_mode_t mode, int engine_flags) { engine_gpg_t gpg = engine; gpgme_error_t err; @@ -2298,7 +2305,7 @@ gpg_keylist (void *engine, const char *pattern, int secret_only, static gpgme_error_t gpg_keylist_ext (void *engine, const char *pattern[], int secret_only, - int reserved, gpgme_keylist_mode_t mode) + int reserved, gpgme_keylist_mode_t mode, int engine_flags) { engine_gpg_t gpg = engine; gpgme_error_t err; @@ -2364,7 +2371,7 @@ gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out, err = add_data (gpg, out, 1, 1); if (!err) - start (gpg); + err = start (gpg); return err; } diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index ac6c5fc..476e9ef 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -408,12 +408,10 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir) int rc; rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)); - if (rc) - { - err = gpg_error_from_errno (rc); - goto leave; - } - else + + /* Even though isatty() returns 1, ttyname_r() may fail in many + ways, e.g., when /dev/pts is not accessible under chroot. */ + if (!rc) { if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) { @@ -1289,17 +1287,23 @@ gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode, if (!gpgsm) return gpg_error (GPG_ERR_INV_VALUE); - if (mode) - return gpg_error (GPG_ERR_NOT_SUPPORTED); - if (!pattern) pattern = ""; - cmd = malloc (7 + strlen (pattern) + 1); + cmd = malloc (7 + 9 + 9 + strlen (pattern) + 1); if (!cmd) return gpg_error_from_syserror (); + strcpy (cmd, "EXPORT "); - strcpy (&cmd[7], pattern); + if ((mode & GPGME_EXPORT_MODE_SECRET)) + { + strcat (cmd, "--secret "); + if ((mode & GPGME_EXPORT_MODE_RAW)) + strcat (cmd, "--raw "); + else if ((mode & GPGME_EXPORT_MODE_PKCS12)) + strcat (cmd, "--pkcs12 "); + } + strcat (cmd, pattern); gpgsm->output_cb.data = keydata; err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" @@ -1323,16 +1327,13 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode, engine_gpgsm_t gpgsm = engine; gpgme_error_t err = 0; char *line; - /* Length is "EXPORT " + p + '\0'. */ - int length = 7 + 1; + /* Length is "EXPORT " + "--secret " + "--pkcs12 " + p + '\0'. */ + int length = 7 + 9 + 9 + 1; char *linep; if (!gpgsm) return gpg_error (GPG_ERR_INV_VALUE); - if (mode) - return gpg_error (GPG_ERR_NOT_SUPPORTED); - if (pattern && *pattern) { const char **pat = pattern; @@ -1357,7 +1358,15 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode, return gpg_error_from_syserror (); strcpy (line, "EXPORT "); - linep = &line[7]; + if ((mode & GPGME_EXPORT_MODE_SECRET)) + { + strcat (line, "--secret "); + if ((mode & GPGME_EXPORT_MODE_RAW)) + strcat (line, "--raw "); + else if ((mode & GPGME_EXPORT_MODE_PKCS12)) + strcat (line, "--pkcs12 "); + } + linep = &line[strlen (line)]; if (pattern && *pattern) { @@ -1542,7 +1551,7 @@ gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray) static gpgme_error_t gpgsm_keylist (void *engine, const char *pattern, int secret_only, - gpgme_keylist_mode_t mode) + gpgme_keylist_mode_t mode, int engine_flags) { engine_gpgsm_t gpgsm = engine; char *line; @@ -1599,6 +1608,11 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only, "OPTION with-secret=1": "OPTION with-secret=0" , NULL, NULL); + gpgsm_assuan_simple_command (gpgsm->assuan_ctx, + (engine_flags & GPGME_ENGINE_FLAG_OFFLINE)? + "OPTION offline=1": + "OPTION offline=0" , + NULL, NULL); /* Length is "LISTSECRETKEYS " + p + '\0'. */ @@ -1629,7 +1643,7 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only, static gpgme_error_t gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only, - int reserved, gpgme_keylist_mode_t mode) + int reserved, gpgme_keylist_mode_t mode, int engine_flags) { engine_gpgsm_t gpgsm = engine; char *line; @@ -1669,7 +1683,11 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only, "OPTION with-secret=1": "OPTION with-secret=0" , NULL, NULL); - + gpgsm_assuan_simple_command (gpgsm->assuan_ctx, + (engine_flags & GPGME_ENGINE_FLAG_OFFLINE)? + "OPTION offline=1": + "OPTION offline=0" , + NULL, NULL); if (pattern && *pattern) { diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c index a7184b7..e4fd47c 100644 --- a/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -326,12 +326,10 @@ uiserver_new (void **engine, const char *file_name, const char *home_dir) int rc; rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)); - if (rc) - { - err = gpg_error_from_errno (rc); - goto leave; - } - else + + /* Even though isatty() returns 1, ttyname_r() may fail in many + ways, e.g., when /dev/pts is not accessible under chroot. */ + if (!rc) { if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) { diff --git a/src/engine.c b/src/engine.c index ff015c0..8e84da9 100644 --- a/src/engine.c +++ b/src/engine.c @@ -726,7 +726,8 @@ _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata, gpgme_error_t _gpgme_engine_op_keylist (engine_t engine, const char *pattern, - int secret_only, gpgme_keylist_mode_t mode) + int secret_only, gpgme_keylist_mode_t mode, + int engine_flags) { if (!engine) return gpg_error (GPG_ERR_INV_VALUE); @@ -734,14 +735,15 @@ _gpgme_engine_op_keylist (engine_t engine, const char *pattern, if (!engine->ops->keylist) return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode); + return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode, + engine_flags); } gpgme_error_t _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[], int secret_only, int reserved, - gpgme_keylist_mode_t mode) + gpgme_keylist_mode_t mode, int engine_flags) { if (!engine) return gpg_error (GPG_ERR_INV_VALUE); @@ -750,7 +752,7 @@ _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[], return gpg_error (GPG_ERR_NOT_IMPLEMENTED); return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only, - reserved, mode); + reserved, mode, engine_flags); } diff --git a/src/engine.h b/src/engine.h index bbf009d..56fcc42 100644 --- a/src/engine.h +++ b/src/engine.h @@ -113,12 +113,14 @@ gpgme_error_t _gpgme_engine_op_import (engine_t engine, gpgme_error_t _gpgme_engine_op_keylist (engine_t engine, const char *pattern, int secret_only, - gpgme_keylist_mode_t mode); + gpgme_keylist_mode_t mode, + int engine_flags); gpgme_error_t _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[], int secret_only, int reserved, - gpgme_keylist_mode_t mode); + gpgme_keylist_mode_t mode, + int engine_flags); 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, @@ -170,5 +172,8 @@ gpgme_error_t _gpgme_engine_op_spawn (engine_t engine, gpgme_data_t dataerr, unsigned int flags); +/* The available engine option flags. */ +#define GPGME_ENGINE_FLAG_OFFLINE 1 + #endif /* ENGINE_H */ diff --git a/src/export.c b/src/export.c index 8930aa6..a29fbde 100644 --- a/src/export.c +++ b/src/export.c @@ -120,9 +120,24 @@ export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern, op_data_t opd; if ((mode & ~(GPGME_EXPORT_MODE_EXTERN - |GPGME_EXPORT_MODE_MINIMAL))) + |GPGME_EXPORT_MODE_MINIMAL + |GPGME_EXPORT_MODE_SECRET + |GPGME_EXPORT_MODE_RAW + |GPGME_EXPORT_MODE_PKCS12))) return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */ + if ((mode & GPGME_EXPORT_MODE_SECRET)) + { + if ((mode & GPGME_EXPORT_MODE_EXTERN)) + return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */ + if ((mode & GPGME_EXPORT_MODE_RAW) + && (mode & GPGME_EXPORT_MODE_PKCS12)) + return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */ + + if (ctx->protocol != GPGME_PROTOCOL_CMS + && (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12))) + return gpg_error (GPG_ERR_INV_FLAG); /* Only supported for X.509. */ + } if ((mode & GPGME_EXPORT_MODE_EXTERN)) { @@ -199,9 +214,25 @@ export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[], op_data_t opd; if ((mode & ~(GPGME_EXPORT_MODE_EXTERN - |GPGME_EXPORT_MODE_MINIMAL))) + |GPGME_EXPORT_MODE_MINIMAL + |GPGME_EXPORT_MODE_SECRET + |GPGME_EXPORT_MODE_RAW + |GPGME_EXPORT_MODE_PKCS12))) return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */ + if ((mode & GPGME_EXPORT_MODE_SECRET)) + { + if ((mode & GPGME_EXPORT_MODE_EXTERN)) + return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */ + if ((mode & GPGME_EXPORT_MODE_RAW) + && (mode & GPGME_EXPORT_MODE_PKCS12)) + return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */ + + if (ctx->protocol != GPGME_PROTOCOL_CMS + && (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12))) + return gpg_error (GPG_ERR_INV_FLAG); /* Only supported for X.509. */ + } + if ((mode & GPGME_EXPORT_MODE_EXTERN)) { if (keydata) diff --git a/src/genkey.c b/src/genkey.c index fd6685e..3afd3b4 100644 --- a/src/genkey.c +++ b/src/genkey.c @@ -37,6 +37,9 @@ typedef struct { struct _gpgme_op_genkey_result result; + /* The error code from a FAILURE status line or 0. */ + gpg_error_t failure_code; + /* The key parameters passed to the crypto engine. */ gpgme_data_t key_parameter; } *op_data_t; @@ -118,10 +121,25 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args) } break; + case GPGME_STATUS_FAILURE: + opd->failure_code = _gpgme_parse_failure (args); + break; + case GPGME_STATUS_EOF: /* FIXME: Should return some more useful error value. */ if (!opd->result.primary && !opd->result.sub) return gpg_error (GPG_ERR_GENERAL); + else if (opd->failure_code) + return opd->failure_code; + break; + + case GPGME_STATUS_INQUIRE_MAXLEN: + if (ctx->status_cb) + { + err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args); + if (err) + return err; + } break; default: @@ -186,6 +204,14 @@ genkey_start (gpgme_ctx_t ctx, int synchronous, const char *parms, _gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx); + if (ctx->passphrase_cb) + { + err = _gpgme_engine_set_command_handler + (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL); + if (err) + return err; + } + return _gpgme_engine_op_genkey (ctx->engine, opd->key_parameter, ctx->use_armor, pubkey, seckey); } diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c index d42179b..e5e5707 100644 --- a/src/gpgme-tool.c +++ b/src/gpgme-tool.c @@ -3054,7 +3054,7 @@ cmd_import (assuan_context_t ctx, char *line) static const char hlp_export[] = - "EXPORT [--extern] [--minimal] []\n" + "EXPORT [--extern] [--minimal] [--secret [--pkcs12] [--raw]] []\n" "\n" "Export the keys described by PATTERN. Write the\n" "the output to the object set by the last OUTPUT command."; @@ -3082,6 +3082,12 @@ cmd_export (assuan_context_t ctx, char *line) mode |= GPGME_EXPORT_MODE_EXTERN; if (has_option (line, "--minimal")) mode |= GPGME_EXPORT_MODE_MINIMAL; + if (has_option (line, "--secret")) + mode |= GPGME_EXPORT_MODE_SECRET; + if (has_option (line, "--raw")) + mode |= GPGME_EXPORT_MODE_RAW; + if (has_option (line, "--pkcs12")) + mode |= GPGME_EXPORT_MODE_PKCS12; line = skip_options (line); @@ -3728,6 +3734,7 @@ static char args_doc[] = "COMMAND [OPTIONS...]"; static struct argp_option options[] = { { "server", 's', 0, 0, "Server mode" }, { "gpg-binary", 501, "FILE", 0, "Use FILE for the GPG backend" }, + { "lib-version", 502, 0, 0, "Show library version" }, { 0 } }; @@ -3736,7 +3743,7 @@ static struct argp argp = { options, parse_options, args_doc, doc }; struct args { - enum { CMD_DEFAULT, CMD_SERVER } cmd; + enum { CMD_DEFAULT, CMD_SERVER, CMD_LIBVERSION } cmd; const char *gpg_binary; }; @@ -3762,6 +3769,11 @@ parse_options (int key, char *arg, struct argp_state *state) case 501: args->gpg_binary = arg; break; + + case 502: + args->cmd = CMD_LIBVERSION; + break; + #if 0 case ARGP_KEY_ARG: if (state->arg_num >= 2) @@ -3787,6 +3799,7 @@ main (int argc, char *argv[]) struct args args; struct gpgme_tool gt; gpg_error_t err; + int needgt = 1; #ifdef HAVE_SETLOCALE setlocale (LC_ALL, ""); @@ -3804,7 +3817,10 @@ main (int argc, char *argv[]) argp_parse (&argp, argc, argv, 0, 0, &args); log_init (); - if (args.gpg_binary) + if (args.cmd == CMD_LIBVERSION) + needgt = 0; + + if (needgt && args.gpg_binary) { if (access (args.gpg_binary, X_OK)) err = gpg_error_from_syserror (); @@ -3816,7 +3832,8 @@ main (int argc, char *argv[]) args.gpg_binary); } - gt_init (>); + if (needgt) + gt_init (>); switch (args.cmd) { @@ -3824,9 +3841,17 @@ main (int argc, char *argv[]) case CMD_SERVER: gpgme_server (>); break; + + case CMD_LIBVERSION: + printf ("Version from header: %s (0x%06x)\n", + GPGME_VERSION, GPGME_VERSION_NUMBER); + printf ("Version from binary: %s\n", gpgme_check_version (NULL)); + printf ("Copyright blurb ...:%s\n", gpgme_check_version ("\x01\x01")); + break; } - gpgme_release (gt.ctx); + if (needgt) + gpgme_release (gt.ctx); #ifdef HAVE_W32CE_SYSTEM /* Give the buggy ssh server time to flush the output buffers. */ diff --git a/src/gpgme.c b/src/gpgme.c index 628cdae..0cf999a 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -472,6 +472,30 @@ gpgme_get_textmode (gpgme_ctx_t ctx) } +/* Enable offline mode for this context. In offline mode dirmngr + will be disabled. */ +void +gpgme_set_offline (gpgme_ctx_t ctx, int offline) +{ + TRACE2 (DEBUG_CTX, "gpgme_set_offline", ctx, "offline=%i (%s)", + offline, offline ? "yes" : "no"); + + if (!ctx) + return; + + ctx->offline = offline; +} + +/* Return the state of the offline flag. */ +int +gpgme_get_offline (gpgme_ctx_t ctx) +{ + TRACE2 (DEBUG_CTX, "gpgme_get_offline", ctx, "ctx->offline=%i (%s)", + ctx->offline, ctx->offline ? "yes" : "no"); + return ctx->offline; +} + + /* Set the number of certifications to include in an S/MIME message. The default is GPGME_INCLUDE_CERTS_DEFAULT. -1 means all certs, and -2 means all certs except the root cert. */ @@ -632,6 +656,47 @@ gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *r_cb, } +/* This function sets a callback function to be used as a status + message forwarder. */ +void +gpgme_set_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t cb, void *cb_value) +{ + TRACE2 (DEBUG_CTX, "gpgme_set_status_cb", ctx, "status_cb=%p/%p", + cb, cb_value); + + if (!ctx) + return; + + ctx->status_cb = cb; + ctx->status_cb_value = cb_value; +} + + +/* This function returns the callback function to be used as a + status message forwarder. */ +void +gpgme_get_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t *r_cb, + void **r_cb_value) +{ + TRACE2 (DEBUG_CTX, "gpgme_get_status_cb", ctx, "ctx->status_cb=%p/%p", + ctx ? ctx->status_cb : NULL, ctx ? ctx->status_cb_value : NULL); + + if (r_cb) + *r_cb = NULL; + + if (r_cb_value) + *r_cb_value = NULL; + + if (!ctx || !ctx->status_cb) + return; + + if (r_cb) + *r_cb = ctx->status_cb; + if (r_cb_value) + *r_cb_value = ctx->status_cb_value; +} + + /* Set the I/O callback functions for CTX to IO_CBS. */ void gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs) diff --git a/src/gpgme.def b/src/gpgme.def index dc18948..a3f5fb4 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -217,5 +217,11 @@ EXPORTS gpgme_op_spawn_start @163 gpgme_op_spawn @164 + + gpgme_set_offline @165 + gpgme_get_offline @166 + + gpgme_set_status_cb @167 + gpgme_get_status_cb @168 ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 15ed803..6cea2c7 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1,36 +1,28 @@ /* gpgme.h - Public interface to GnuPG Made Easy. -*- c -*- - Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009 - 2010, 2011, 2012, 2013, 2014 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 . - - Generated from gpgme.h.in for @GPGME_CONFIG_HOST@. */ + * Copyright (C) 2000 Werner Koch (dd9jn) + * Copyright (C) 2001-2015 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 . + * + * Generated from gpgme.h.in for @GPGME_CONFIG_HOST@. + */ #ifndef GPGME_H #define GPGME_H -#ifdef __GNUC__ -#define _GPGME_INLINE __inline__ -#elif __STDC_VERSION__ >= 199901L -#define _GPGME_INLINE inline -#else -#define _GPGME_INLINE -#endif - /* Include stdio.h for the FILE type definition. */ #include #include @@ -38,29 +30,60 @@ #ifdef __cplusplus extern "C" { -#if 0 /* just to make Emacs auto-indent happy */ +#if 0 /*(Make Emacsen's auto-indent happy.)*/ } #endif #endif /* __cplusplus */ + +/* The version of this header should match the one of the library. Do + not use this symbol in your application, use gpgme_check_version + instead. The purpose of this macro is to let autoconf (using the + AM_PATH_GPGME macro) check that this header matches the installed + library. */ +#define GPGME_VERSION "@PACKAGE_VERSION@" + +/* The version number of this header. It may be used to handle minor + API incompatibilities. */ +#define GPGME_VERSION_NUMBER @VERSION_NUMBER@ + + +/* System specific typedefs. */ @INSERT__TYPEDEFS_FOR_GPGME_H@ + -/* Check for compiler features. */ -#if __GNUC__ -#define _GPGME_GCC_VERSION (__GNUC__ * 10000 \ - + __GNUC_MINOR__ * 100 \ - + __GNUC_PATCHLEVEL__) - -#if _GPGME_GCC_VERSION > 30100 -#define _GPGME_DEPRECATED __attribute__ ((__deprecated__)) -#endif +/* + * Check for compiler features. + */ +#ifdef GPGRT_INLINE +# define _GPGME_INLINE GPGRT_INLINE +#elif defined(__GNUC__) +# define _GPGME_INLINE __inline__ +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +# define _GPGME_INLINE inline +#else +# define _GPGME_INLINE #endif -#ifndef _GPGME_DEPRECATED -#define _GPGME_DEPRECATED + +#ifdef GPGRT_ATTR_DEPRECATED +# define _GPGME_DEPRECATED GPGRT_ATTR_DEPRECATED +#elif defined(__GNUC__) +# define _GPGME_GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +# if _GPGME_GCC_VERSION > 30100 +# define _GPGME_DEPRECATED __attribute__ ((__deprecated__)) +# else +# define _GPGME_DEPRECATED +# endif +#else +# define _GPGME_DEPRECATED #endif + /* The macro _GPGME_DEPRECATED_OUTSIDE_GPGME suppresses warnings for fields we must access in GPGME for ABI compatibility. */ #ifdef _GPGME_IN_GPGME @@ -69,17 +92,6 @@ extern "C" { #define _GPGME_DEPRECATED_OUTSIDE_GPGME _GPGME_DEPRECATED #endif - -/* The version of this header should match the one of the library. Do - not use this symbol in your application, use gpgme_check_version - instead. The purpose of this macro is to let autoconf (using the - AM_PATH_GPGME macro) check that this header matches the installed - library. */ -#define GPGME_VERSION "@PACKAGE_VERSION@" - -/* The version number of this header. It may be used to handle minor - API incompatibilities. */ -#define GPGME_VERSION_NUMBER @VERSION_NUMBER@ /* Check for a matching _FILE_OFFSET_BITS definition. */ #if @NEED__FILE_OFFSET_BITS@ @@ -94,7 +106,9 @@ extern "C" { -/* Some opaque data types used by GPGME. */ +/* + * Some opaque data types used by GPGME. + */ /* The context holds some global state and configuration options, as well as the results of a crypto operation. */ @@ -105,8 +119,11 @@ typedef struct gpgme_context *gpgme_ctx_t; struct gpgme_data; typedef struct gpgme_data *gpgme_data_t; + -/* Wrappers for the libgpg-error library. */ +/* + * Wrappers for the libgpg-error library. + */ typedef gpg_error_t gpgme_error_t; typedef gpg_err_code_t gpgme_err_code_t; @@ -196,7 +213,12 @@ gpgme_error_from_syserror (void) return gpgme_error (gpgme_err_code_from_syserror ()); } + +/* + * Various constants and types + */ + /* The possible encoding mode of gpgme_data_t objects. */ typedef enum { @@ -210,6 +232,7 @@ typedef enum } gpgme_data_encoding_t; + /* Known data types. */ typedef enum { @@ -226,7 +249,7 @@ typedef enum } gpgme_data_type_t; - + /* Public key algorithms. */ typedef enum { @@ -264,7 +287,7 @@ typedef enum } gpgme_hash_algo_t; - + /* The possible signature stati. Deprecated, use error value in sig status. */ typedef enum @@ -292,7 +315,7 @@ typedef enum } gpgme_sig_mode_t; - + /* The available key and signature attributes. Deprecated, use the individual result structures instead. */ typedef enum @@ -333,7 +356,7 @@ typedef enum _gpgme_attr_t; typedef _gpgme_attr_t gpgme_attr_t _GPGME_DEPRECATED; - + /* The available validities for a trust item or key. */ typedef enum { @@ -346,7 +369,7 @@ typedef enum } gpgme_validity_t; - + /* The available protocols. */ typedef enum { @@ -364,7 +387,7 @@ gpgme_protocol_t; /* Convenience macro for the surprisingly mixed spelling. */ #define GPGME_PROTOCOL_OPENPGP GPGME_PROTOCOL_OpenPGP - + /* The available keylist mode flags. */ #define GPGME_KEYLIST_MODE_LOCAL 1 #define GPGME_KEYLIST_MODE_EXTERN 2 @@ -376,7 +399,7 @@ gpgme_protocol_t; typedef unsigned int gpgme_keylist_mode_t; - + /* The pinentry modes. */ typedef enum { @@ -388,59 +411,21 @@ typedef enum } gpgme_pinentry_mode_t; - + /* The available export mode flags. */ #define GPGME_EXPORT_MODE_EXTERN 2 #define GPGME_EXPORT_MODE_MINIMAL 4 +#define GPGME_EXPORT_MODE_SECRET 16 +#define GPGME_EXPORT_MODE_RAW 32 +#define GPGME_EXPORT_MODE_PKCS12 64 typedef unsigned int gpgme_export_mode_t; - + /* Flags for the audit log functions. */ #define GPGME_AUDITLOG_HTML 1 #define GPGME_AUDITLOG_WITH_HELP 128 - -/* Signature notations. */ - -/* 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; - -struct _gpgme_sig_notation -{ - struct _gpgme_sig_notation *next; - - /* If NAME is a null pointer, then VALUE contains a policy URL - rather than a notation. */ - char *name; - - /* The value of the notation data. */ - char *value; - - /* The length of the name of the notation data. */ - int name_len; - - /* The length of the value of the notation data. */ - int value_len; - - /* The accumulated flags. */ - gpgme_sig_notation_flags_t flags; - - /* Notation data is human-readable. */ - unsigned int human_readable : 1; - - /* Notation data is critical. */ - unsigned int critical : 1; - - /* Internal to GPGME, do not use. */ - int _unused : 30; -}; -typedef struct _gpgme_sig_notation *gpgme_sig_notation_t; - - /* The possible stati for the edit operation. */ typedef enum { @@ -544,11 +529,56 @@ typedef enum GPGME_STATUS_PINENTRY_LAUNCHED = 88, GPGME_STATUS_ATTRIBUTE = 89, GPGME_STATUS_BEGIN_SIGNING = 90, - GPGME_STATUS_KEY_NOT_CREATED = 91 + GPGME_STATUS_KEY_NOT_CREATED = 91, + GPGME_STATUS_INQUIRE_MAXLEN = 92, + GPGME_STATUS_FAILURE = 93 } 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; + +struct _gpgme_sig_notation +{ + struct _gpgme_sig_notation *next; + + /* If NAME is a null pointer, then VALUE contains a policy URL + rather than a notation. */ + char *name; + + /* The value of the notation data. */ + char *value; + + /* The length of the name of the notation data. */ + int name_len; + + /* The length of the value of the notation data. */ + int value_len; + + /* The accumulated flags. */ + gpgme_sig_notation_flags_t flags; + + /* Notation data is human-readable. */ + unsigned int human_readable : 1; + + /* Notation data is critical. */ + unsigned int critical : 1; + + /* Internal to GPGME, do not use. */ + int _unused : 30; +}; +typedef struct _gpgme_sig_notation *gpgme_sig_notation_t; + + +/* + * Public structures. + */ + /* The engine information structure. */ struct _gpgme_engine_info { @@ -571,7 +601,7 @@ struct _gpgme_engine_info }; typedef struct _gpgme_engine_info *gpgme_engine_info_t; - + /* A subkey from a key. */ struct _gpgme_subkey { @@ -826,8 +856,20 @@ struct _gpgme_key typedef struct _gpgme_key *gpgme_key_t; +/* An invalid key object. */ +struct _gpgme_invalid_key +{ + struct _gpgme_invalid_key *next; + char *fpr; + gpgme_error_t reason; +}; +typedef struct _gpgme_invalid_key *gpgme_invalid_key_t; + + -/* Types for callback functions. */ +/* + * Types for callback functions. + */ /* Request a passphrase from the user. */ typedef gpgme_error_t (*gpgme_passphrase_cb_t) (void *hook, @@ -839,6 +881,11 @@ typedef gpgme_error_t (*gpgme_passphrase_cb_t) (void *hook, typedef void (*gpgme_progress_cb_t) (void *opaque, const char *what, int type, int current, int total); +/* Status messages from gpg. */ +typedef gpgme_error_t (*gpgme_status_cb_t) (void *opaque, const char *keyword, + const char *args); + + /* Interact with the user about an edit operation. */ typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque, gpgme_status_code_t status, @@ -847,7 +894,9 @@ typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque, -/* Context management functions. */ +/* + * Context management functions. + */ /* Create a new context and return it in CTX. */ gpgme_error_t gpgme_new (gpgme_ctx_t *ctx); @@ -887,6 +936,12 @@ void gpgme_set_textmode (gpgme_ctx_t ctx, int yes); /* Return non-zero if text mode is set in CTX. */ int gpgme_get_textmode (gpgme_ctx_t ctx); +/* If YES is non-zero, enable offline mode in CTX, disable it otherwise. */ +void gpgme_set_offline (gpgme_ctx_t ctx, int yes); + +/* Return non-zero if offline mode is set in CTX. */ +int gpgme_get_offline (gpgme_ctx_t ctx); + /* Use whatever the default of the backend crypto engine is. */ #define GPGME_INCLUDE_CERTS_DEFAULT -256 @@ -930,6 +985,16 @@ void gpgme_set_progress_cb (gpgme_ctx_t c, gpgme_progress_cb_t cb, void gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *cb, void **hook_value); +/* Set the status callback function in CTX to CB. HOOK_VALUE is + passed as first argument to thes status callback function. */ +void gpgme_set_status_cb (gpgme_ctx_t c, gpgme_status_cb_t cb, + void *hook_value); + +/* Get the current status callback function in *CB and the current + hook value in *HOOK_VALUE. */ +void gpgme_get_status_cb (gpgme_ctx_t ctx, gpgme_status_cb_t *cb, + void **hook_value); + /* This function sets the locale for the context CTX, or the default locale if CTX is a null pointer. */ gpgme_error_t gpgme_set_locale (gpgme_ctx_t ctx, int category, @@ -947,16 +1012,6 @@ gpgme_error_t gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, const char *file_name, const char *home_dir); - -/* Return a statically allocated string with the name of the public - key algorithm ALGO, or NULL if that name is not known. */ -const char *gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo); - -/* Return a statically allocated string with the name of the hash - algorithm ALGO, or NULL if that name is not known. */ -const char *gpgme_hash_algo_name (gpgme_hash_algo_t algo); - - /* Delete all signers from CTX. */ void gpgme_signers_clear (gpgme_ctx_t ctx); @@ -995,7 +1050,7 @@ const char *gpgme_get_sig_string_attr (gpgme_ctx_t c, int idx, gpgme_error_t gpgme_get_sig_key (gpgme_ctx_t ctx, int idx, gpgme_key_t *r_key) _GPGME_DEPRECATED; - + /* Clear all notation data from the context. */ void gpgme_sig_notation_clear (gpgme_ctx_t ctx); @@ -1011,8 +1066,11 @@ gpgme_error_t gpgme_sig_notation_add (gpgme_ctx_t ctx, const char *name, /* Get the sig notations for this context. */ gpgme_sig_notation_t gpgme_sig_notation_get (gpgme_ctx_t ctx); + -/* Run control. */ +/* + * Run control. + */ /* The type of an I/O callback function. */ typedef gpgme_error_t (*gpgme_io_cb_t) (void *data, int fd); @@ -1085,8 +1143,17 @@ gpgme_ctx_t gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang); gpgme_ctx_t gpgme_wait_ext (gpgme_ctx_t ctx, gpgme_error_t *status, gpgme_error_t *op_err, int hang); +/* Cancel a pending asynchronous operation. */ +gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx); + +/* Cancel a pending operation asynchronously. */ +gpgme_error_t gpgme_cancel_async (gpgme_ctx_t ctx); + + -/* Functions to handle data objects. */ +/* + * Functions to handle data objects. + */ /* Read up to SIZE bytes into buffer BUFFER from the data object with the handle HANDLE. Return the number of characters read, 0 on EOF @@ -1209,14 +1276,20 @@ gpgme_error_t gpgme_data_new_from_filepart (gpgme_data_t *r_dh, gpgme_data_seek instead. */ gpgme_error_t gpgme_data_rewind (gpgme_data_t dh) _GPGME_DEPRECATED; + -/* Key and trust functions. */ +/* + * Key and trust functions. + */ /* Get the key with the fingerprint FPR from the crypto backend. If SECRET is true, get the secret key. */ gpgme_error_t gpgme_get_key (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key, int secret); +/* Create a dummy key to specify an email address. */ +gpgme_error_t gpgme_key_from_uid (gpgme_key_t *key, const char *name); + /* Acquire a reference to KEY. */ void gpgme_key_ref (gpgme_key_t key); @@ -1259,26 +1332,12 @@ unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx, const void *reserved, int idx) _GPGME_DEPRECATED; - -/* Crypto Operations. */ - -/* Cancel a pending asynchronous operation. */ -gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx); - -/* Cancel a pending operation asynchronously. */ -gpgme_error_t gpgme_cancel_async (gpgme_ctx_t ctx); -struct _gpgme_invalid_key -{ - struct _gpgme_invalid_key *next; - char *fpr; - gpgme_error_t reason; -}; -typedef struct _gpgme_invalid_key *gpgme_invalid_key_t; +/* + * Encryption. + */ - -/* Encryption. */ struct _gpgme_op_encrypt_result { /* The list of invalid recipients. */ @@ -1322,7 +1381,9 @@ gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[], gpgme_data_t plain, gpgme_data_t cipher); -/* Decryption. */ +/* + * Decryption. + */ struct _gpgme_recipient { @@ -1379,7 +1440,10 @@ gpgme_error_t gpgme_op_decrypt_verify (gpgme_ctx_t ctx, gpgme_data_t cipher, gpgme_data_t plain); -/* Signing. */ +/* + * Signing. + */ + struct _gpgme_new_signature { struct _gpgme_new_signature *next; @@ -1435,7 +1499,9 @@ gpgme_error_t gpgme_op_sign (gpgme_ctx_t ctx, gpgme_sig_mode_t mode); -/* Verify. */ +/* + * Verify. + */ /* Flags used for the SUMMARY field in a gpgme_signature_t. */ typedef enum @@ -1524,22 +1590,15 @@ gpgme_error_t gpgme_op_verify (gpgme_ctx_t ctx, gpgme_data_t sig, gpgme_data_t plaintext); -/* Import. */ - -/* The key was new. */ -#define GPGME_IMPORT_NEW 1 - -/* The key contained new user IDs. */ -#define GPGME_IMPORT_UID 2 - -/* The key contained new signatures. */ -#define GPGME_IMPORT_SIG 4 - -/* The key contained new sub keys. */ -#define GPGME_IMPORT_SUBKEY 8 +/* + * Import/Export + */ -/* The key contained a secret key. */ -#define GPGME_IMPORT_SECRET 16 +#define GPGME_IMPORT_NEW 1 /* The key was new. */ +#define GPGME_IMPORT_UID 2 /* The key contained new user IDs. */ +#define GPGME_IMPORT_SIG 4 /* The key contained new signatures. */ +#define GPGME_IMPORT_SUBKEY 8 /* The key contained new sub keys. */ +#define GPGME_IMPORT_SECRET 16 /* The key contained a secret key. */ struct _gpgme_import_status @@ -1560,7 +1619,7 @@ struct _gpgme_import_status }; typedef struct _gpgme_import_status *gpgme_import_status_t; -/* Import. */ +/* Import result object. */ struct _gpgme_op_import_result { /* Number of considered keys. */ @@ -1624,7 +1683,6 @@ gpgme_error_t gpgme_op_import_keys_start (gpgme_ctx_t ctx, gpgme_key_t keys[]); gpgme_error_t gpgme_op_import_keys (gpgme_ctx_t ctx, gpgme_key_t keys[]); - /* Export the keys found by PATTERN into KEYDATA. */ gpgme_error_t gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern, gpgme_export_mode_t mode, @@ -1653,7 +1711,10 @@ gpgme_error_t gpgme_op_export_keys (gpgme_ctx_t ctx, -/* Key generation. */ +/* + * Key generation. + */ + struct _gpgme_op_genkey_result { /* A primary key was generated. */ @@ -1681,7 +1742,7 @@ gpgme_error_t gpgme_op_genkey (gpgme_ctx_t ctx, const char *parms, /* Retrieve a pointer to the result of the genkey operation. */ gpgme_genkey_result_t gpgme_op_genkey_result (gpgme_ctx_t ctx); - + /* Delete KEY from the keyring. If ALLOW_SECRET is non-zero, secret keys are also deleted. */ gpgme_error_t gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key, @@ -1689,7 +1750,12 @@ gpgme_error_t gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key, gpgme_error_t gpgme_op_delete (gpgme_ctx_t ctx, const gpgme_key_t key, int allow_secret); + +/* + * Key Edit interface + */ + /* Edit the key KEY. Send status and command requests to FNC and output of edit commands to OUT. */ gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key, @@ -1709,27 +1775,11 @@ gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key, gpgme_data_t out); -/* Flags for the spawn operations. */ -#define GPGME_SPAWN_DETACHED 1 -#define GPGME_SPAWN_ALLOW_SET_FG 2 - - -/* Run the command FILE with the arguments in ARGV. Connect stdin to - DATAIN, stdout to DATAOUT, and STDERR to DATAERR. If one the data - streams is NULL, connect to /dev/null instead. */ -gpgme_error_t gpgme_op_spawn_start (gpgme_ctx_t ctx, - const char *file, const char *argv[], - gpgme_data_t datain, - gpgme_data_t dataout, gpgme_data_t dataerr, - unsigned int flags); -gpgme_error_t gpgme_op_spawn (gpgme_ctx_t ctx, - const char *file, const char *argv[], - gpgme_data_t datain, - gpgme_data_t dataout, gpgme_data_t dataerr, - unsigned int flags); - -/* Key management functions. */ +/* + * Key listing + */ + struct _gpgme_op_keylist_result { unsigned int truncated : 1; @@ -1766,7 +1816,9 @@ gpgme_error_t gpgme_op_passwd (gpgme_ctx_t ctx, gpgme_key_t key, -/* Trust items and operations. */ +/* + * Trust items and operations. + */ struct _gpgme_trust_item { @@ -1841,7 +1893,12 @@ int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what, const void *reserved, int idx) _GPGME_DEPRECATED; + +/* + * Audit log + */ + /* Return the auditlog for the current session. This may be called after a successful or failed operation. If no audit log is available GPG_ERR_NO_DATA is returned. */ @@ -1852,7 +1909,33 @@ gpgme_error_t gpgme_op_getauditlog (gpgme_ctx_t ctx, gpgme_data_t output, -/* Low-level Assuan protocol access. */ +/* + * Spawn interface + */ + +/* Flags for the spawn operations. */ +#define GPGME_SPAWN_DETACHED 1 +#define GPGME_SPAWN_ALLOW_SET_FG 2 + + +/* Run the command FILE with the arguments in ARGV. Connect stdin to + DATAIN, stdout to DATAOUT, and STDERR to DATAERR. If one the data + streams is NULL, connect to /dev/null instead. */ +gpgme_error_t gpgme_op_spawn_start (gpgme_ctx_t ctx, + const char *file, const char *argv[], + gpgme_data_t datain, + gpgme_data_t dataout, gpgme_data_t dataerr, + unsigned int flags); +gpgme_error_t gpgme_op_spawn (gpgme_ctx_t ctx, + const char *file, const char *argv[], + gpgme_data_t datain, + gpgme_data_t dataout, gpgme_data_t dataerr, + unsigned int flags); + + +/* + * Low-level Assuan protocol access. + */ typedef gpgme_error_t (*gpgme_assuan_data_cb_t) (void *opaque, const void *data, size_t datalen); @@ -1911,7 +1994,10 @@ gpgme_op_assuan_transact (gpgme_ctx_t ctx, void *status_cb_value) _GPGME_DEPRECATED; -/* Crypto container support. */ +/* + * Crypto container support. + */ + struct _gpgme_op_vfs_mount_result { char *mount_dir; @@ -1932,7 +2018,9 @@ gpgme_error_t gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[], unsigned int flags, gpgme_error_t *op_err); -/* Interface to gpgconf(1). */ +/* + * Interface to gpgconf(1). + */ /* The expert level at which a configuration option or group of options should be displayed. See the gpgconf(1) documentation for @@ -2096,15 +2184,11 @@ gpgme_error_t gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p); follow chained components! */ gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp); - -/* UIServer support. */ - -/* Create a dummy key to specify an email address. */ -gpgme_error_t gpgme_key_from_uid (gpgme_key_t *key, const char *name); - -/* Various functions. */ +/* + * Various functions. + */ /* Set special global flags; consult the manual before use. */ int gpgme_set_global_flag (const char *name, const char *value); @@ -2139,19 +2223,28 @@ gpgme_error_t gpgme_set_engine_info (gpgme_protocol_t proto, const char *file_name, const char *home_dir); - -/* Engine support functions. */ - /* Verify that the engine implementing PROTO is installed and available. */ gpgme_error_t gpgme_engine_check_version (gpgme_protocol_t proto); - + +/* Reference counting for result objects. */ void gpgme_result_ref (void *result); void gpgme_result_unref (void *result); +/* Return a statically allocated string with the name of the public + key algorithm ALGO, or NULL if that name is not known. */ +const char *gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo); + +/* Return a statically allocated string with the name of the hash + algorithm ALGO, or NULL if that name is not known. */ +const char *gpgme_hash_algo_name (gpgme_hash_algo_t algo); + + -/* Deprecated types. */ +/* + * Deprecated types. + */ typedef gpgme_ctx_t GpgmeCtx _GPGME_DEPRECATED; typedef gpgme_data_t GpgmeData _GPGME_DEPRECATED; typedef gpgme_error_t GpgmeError _GPGME_DEPRECATED; diff --git a/src/keylist.c b/src/keylist.c index 36ee3ea..fcf574f 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -889,6 +889,7 @@ gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only) gpgme_error_t err; void *hook; op_data_t opd; + int flags = 0; TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_start", ctx, "pattern=%s, secret_only=%i", pattern, secret_only); @@ -913,8 +914,11 @@ gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only) if (err) return TRACE_ERR (err); + if (ctx->offline) + flags |= GPGME_ENGINE_FLAG_OFFLINE; + err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only, - ctx->keylist_mode); + ctx->keylist_mode, flags); return TRACE_ERR (err); } @@ -929,6 +933,7 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[], gpgme_error_t err; void *hook; op_data_t opd; + int flags = 0; TRACE_BEG2 (DEBUG_CTX, "gpgme_op_keylist_ext_start", ctx, "secret_only=%i, reserved=0x%x", secret_only, reserved); @@ -952,8 +957,12 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[], if (err) return TRACE_ERR (err); + if (ctx->offline) + flags |= GPGME_ENGINE_FLAG_OFFLINE; + err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only, - reserved, ctx->keylist_mode); + reserved, ctx->keylist_mode, + flags); return TRACE_ERR (err); } diff --git a/src/libgpgme.vers b/src/libgpgme.vers index 39663c1..6687571 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -92,6 +92,12 @@ GPGME_1.1 { gpgme_op_spawn_start; gpgme_op_spawn; + + gpgme_set_offline; + gpgme_get_offline; + + gpgme_set_status_cb; + gpgme_get_status_cb; }; diff --git a/src/op-support.c b/src/op-support.c index 2bcb3a3..02940ef 100644 --- a/src/op-support.c +++ b/src/op-support.c @@ -337,3 +337,27 @@ _gpgme_parse_plaintext (char *args, char **filenamep) } return 0; } + + +/* Parse a FAILURE status line and return the error code. ARGS is + modified to contain the location part. */ +gpgme_error_t +_gpgme_parse_failure (char *args) +{ + char *where, *which; + + where = strchr (args, ' '); + if (!where) + return trace_gpg_error (GPG_ERR_INV_ENGINE); + + *where = '\0'; + which = where + 1; + + where = strchr (which, ' '); + if (where) + *where = '\0'; + + where = args; + + return atoi (which); +} diff --git a/src/ops.h b/src/ops.h index 782265e..3662d57 100644 --- a/src/ops.h +++ b/src/ops.h @@ -65,6 +65,10 @@ gpgme_error_t _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key); FILENAMEP. */ gpgme_error_t _gpgme_parse_plaintext (char *args, char **filenamep); +/* Parse a FAILURE status line and return the error code. ARGS is + modified to contain the location part. */ +gpgme_error_t _gpgme_parse_failure (char *args); + /* From verify.c. */ diff --git a/src/passphrase.c b/src/passphrase.c index 00e9d99..c88e57d 100644 --- a/src/passphrase.c +++ b/src/passphrase.c @@ -41,6 +41,7 @@ typedef struct char *uid_hint; char *passphrase_info; int bad_passphrase; + char *maxlen; } *op_data_t; @@ -53,6 +54,7 @@ release_op_data (void *hook) free (opd->passphrase_info); if (opd->uid_hint) free (opd->uid_hint); + free (opd->maxlen); } @@ -73,6 +75,11 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code, switch (code) { + case GPGME_STATUS_INQUIRE_MAXLEN: + free (opd->maxlen); + if (!(opd->maxlen = strdup (args))) + return gpg_error_from_syserror (); + break; case GPGME_STATUS_USERID_HINT: if (opd->uid_hint) free (opd->uid_hint); @@ -109,6 +116,31 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code, return gpg_error (GPG_ERR_BAD_PASSPHRASE); break; + case GPGME_STATUS_ERROR: + /* We abuse this status handler to forward ERROR status codes to + the caller. This should better be done in a generic handler, + but for now this is sufficient. */ + if (ctx->status_cb) + { + err = ctx->status_cb (ctx->status_cb_value, "ERROR", args); + if (err) + return err; + } + break; + + case GPGME_STATUS_FAILURE: + /* We abuse this status handler to forward FAILURE status codes + to the caller. This should better be done in a generic + handler, but for now this is sufficient. */ + if (ctx->status_cb) + { + err = ctx->status_cb (ctx->status_cb_value, "FAILURE", args); + if (err) + return err; + } + break; + + default: /* Ignore all other codes. */ break; @@ -141,9 +173,14 @@ _gpgme_passphrase_command_handler (void *priv, gpgme_status_code_t code, if (processed) *processed = 1; - err = ctx->passphrase_cb (ctx->passphrase_cb_value, - opd->uid_hint, opd->passphrase_info, - opd->bad_passphrase, fd); + if (ctx->status_cb && opd->maxlen) + err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", + opd->maxlen); + + if (!err) + err = ctx->passphrase_cb (ctx->passphrase_cb_value, + opd->uid_hint, opd->passphrase_info, + opd->bad_passphrase, fd); /* Reset bad passphrase flag, in case it is correct now. */ opd->bad_passphrase = 0; diff --git a/src/passwd.c b/src/passwd.c index e832026..ff30df0 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -30,6 +30,9 @@ typedef struct { + /* The error code from a FAILURE status line or 0. */ + gpg_error_t failure_code; + int success_seen; int error_seen; } *op_data_t; @@ -92,6 +95,10 @@ passwd_status_handler (void *priv, gpgme_status_code_t code, char *args) opd->success_seen = 1; break; + case GPGME_STATUS_FAILURE: + opd->failure_code = _gpgme_parse_failure (args); + break; + case GPGME_STATUS_EOF: /* In case the OpenPGP engine does not properly implement the passwd command we won't get a success status back and thus we @@ -102,6 +109,8 @@ passwd_status_handler (void *priv, gpgme_status_code_t code, char *args) if (ctx->protocol == GPGME_PROTOCOL_OpenPGP && !opd->error_seen && !opd->success_seen) err = gpg_error (GPG_ERR_NOT_SUPPORTED); + else if (opd->failure_code) + err = opd->failure_code; break; default: diff --git a/src/sign.c b/src/sign.c index ffbde56..6c9fc03 100644 --- a/src/sign.c +++ b/src/sign.c @@ -39,6 +39,9 @@ typedef struct { struct _gpgme_op_sign_result result; + /* The error code from a FAILURE status line or 0. */ + gpg_error_t failure_code; + /* A pointer to the next pointer of the last invalid signer in the list. This makes appending new invalid signers painless while preserving the order. */ @@ -327,6 +330,10 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args) opd->last_signer_p = &(*opd->last_signer_p)->next; break; + case GPGME_STATUS_FAILURE: + opd->failure_code = _gpgme_parse_failure (args); + break; + case GPGME_STATUS_EOF: /* The UI server does not send information about the created signature. This is irrelevant for this protocol and thus we @@ -335,7 +342,12 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args) err = gpg_error (GPG_ERR_UNUSABLE_SECKEY); else if (!opd->sig_created_seen && ctx->protocol != GPGME_PROTOCOL_UISERVER) - err = gpg_error (GPG_ERR_GENERAL); + err = opd->failure_code? opd->failure_code:gpg_error (GPG_ERR_GENERAL); + break; + + case GPGME_STATUS_INQUIRE_MAXLEN: + if (ctx->status_cb) + err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args); break; default: @@ -369,6 +381,7 @@ sign_init_result (gpgme_ctx_t ctx, int ignore_inv_recp) opd = hook; if (err) return err; + opd->failure_code = 0; opd->last_signer_p = &opd->result.invalid_signers; opd->last_sig_p = &opd->result.signatures; opd->ignore_inv_recp = !!ignore_inv_recp; diff --git a/src/status-table.c b/src/status-table.c index b936997..6d428d7 100644 --- a/src/status-table.c +++ b/src/status-table.c @@ -66,6 +66,7 @@ static struct status_table_s status_table[] = { "ERRSIG", GPGME_STATUS_ERRSIG }, { "EXPKEYSIG", GPGME_STATUS_EXPKEYSIG }, { "EXPSIG", GPGME_STATUS_EXPSIG }, + { "FAILURE", GPGME_STATUS_FAILURE }, { "FILE_DONE", GPGME_STATUS_FILE_DONE }, { "FILE_ERROR", GPGME_STATUS_FILE_ERROR }, { "FILE_START", GPGME_STATUS_FILE_START }, @@ -80,6 +81,7 @@ static struct status_table_s status_table[] = { "IMPORT_PROBLEM", GPGME_STATUS_IMPORT_PROBLEM }, { "IMPORT_RES", GPGME_STATUS_IMPORT_RES }, { "IMPORTED", GPGME_STATUS_IMPORTED }, + { "INQUIRE_MAXLEN", GPGME_STATUS_INQUIRE_MAXLEN }, { "INV_RECP", GPGME_STATUS_INV_RECP }, { "INV_SGNR", GPGME_STATUS_INV_SGNR }, { "KEY_CREATED", GPGME_STATUS_KEY_CREATED }, diff --git a/src/sys-util.h b/src/sys-util.h index 7180fca..589634b 100644 --- a/src/sys-util.h +++ b/src/sys-util.h @@ -27,4 +27,8 @@ int _gpgme_set_default_gpgconf_name (const char *name); char *_gpgme_get_gpg_path (void); char *_gpgme_get_gpgconf_path (void); +#ifdef HAVE_W32_SYSTEM +const char *_gpgme_get_inst_dir (void); +#endif + #endif /* SYS_UTIL_H */ diff --git a/src/verify.c b/src/verify.c index 84487ee..75914e2 100644 --- a/src/verify.c +++ b/src/verify.c @@ -38,6 +38,9 @@ typedef struct { struct _gpgme_op_verify_result result; + /* The error code from a FAILURE status line or 0. */ + gpg_error_t failure_code; + gpgme_signature_t current_sig; int did_prepare_new_sig; int only_newsig_seen; @@ -769,6 +772,10 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) error code if we are not ready to process this status. */ return parse_error (sig, args, !!sig ); + case GPGME_STATUS_FAILURE: + opd->failure_code = _gpgme_parse_failure (args); + break; + case GPGME_STATUS_EOF: if (sig && !opd->did_prepare_new_sig) calc_sig_summary (sig); @@ -795,6 +802,8 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args) opd->current_sig = NULL; } opd->only_newsig_seen = 0; + if (opd->failure_code) + return opd->failure_code; break; case GPGME_STATUS_PLAINTEXT: diff --git a/src/versioninfo.rc.in b/src/versioninfo.rc.in index a4ab0af..7f19b30 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-2013 g10 Code GmbH\0" + VALUE "LegalCopyright", "Copyright © 2001-2015 g10 Code GmbH\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "gpgme.dll\0" VALUE "PrivateBuild", "\0" diff --git a/src/w32-util.c b/src/w32-util.c index daf3bd2..9aba26f 100644 --- a/src/w32-util.c +++ b/src/w32-util.c @@ -398,40 +398,6 @@ find_program_in_dir (const char *dir, const char *name) static char * -find_program_in_inst_dir (const char *inst_dir, const char *name) -{ - char *result; - char *dir; - - /* If an installation directory has been passed, this overrides a - location given by the registry. The idea here is that we prefer - a program installed alongside with gpgme. We don't want the - registry to override this to have a better isolation of an gpgme - aware applications for other effects. Note that the "Install - Directory" registry item has been used for ages in Gpg4win and - earlier GnuPG windows installers. It is technically not anymore - required. */ - if (inst_dir) - { - result = find_program_in_dir (inst_dir, name); - if (result) - return result; - } - - dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE", - "Software\\GNU\\GnuPG", - "Install Directory"); - if (dir) - { - result = find_program_in_dir (dir, name); - free (dir); - return result; - } - return NULL; -} - - -static char * find_program_at_standard_place (const char *name) { char path[MAX_PATH]; @@ -491,29 +457,50 @@ _gpgme_set_default_gpgconf_name (const char *name) /* Return the full file name of the GPG binary. This function is used - if gpgconf was not found and thus it can be assumed that gpg2 is + iff gpgconf was not found and thus it can be assumed that gpg2 is not installed. This function is only called by get_gpgconf_item and may not be called concurrently. */ char * _gpgme_get_gpg_path (void) { - char *gpg; - const char *inst_dir, *name; + char *gpg = NULL; + const char *name, *inst_dir; + + name = default_gpg_name? get_basename (default_gpg_name) : "gpg.exe"; + /* 1. Try to find gpg.exe in the installation directory of gpgme. */ inst_dir = _gpgme_get_inst_dir (); - gpg = find_program_in_inst_dir - (inst_dir, - default_gpg_name? get_basename (default_gpg_name) : "gpg.exe"); + if (inst_dir) + { + gpg = find_program_in_dir (inst_dir, name); + } + + /* 2. Try to find gpg.exe using that ancient registry key. */ if (!gpg) { - name = (default_gpg_name? default_gpg_name - /* */ : "GNU\\GnuPG\\gpg.exe"); + char *dir; + + dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE", + "Software\\GNU\\GnuPG", + "Install Directory"); + if (dir) + { + gpg = find_program_in_dir (dir, name); + free (dir); + } + } + + /* 3. Try to find gpg.exe below CSIDL_PROGRAM_FILES. */ + if (!gpg) + { + name = default_gpg_name? default_gpg_name : "GNU\\GnuPG\\gpg.exe"; gpg = find_program_at_standard_place (name); - if (!gpg) - _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpg_path: '%s' not found", - name); } + /* 4. Print a debug message if not found. */ + if (!gpg) + _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpg_path: '%s' not found", name); + return gpg; } @@ -523,22 +510,52 @@ _gpgme_get_gpg_path (void) char * _gpgme_get_gpgconf_path (void) { - char *gpgconf; + char *gpgconf = NULL; const char *inst_dir, *name; + name = default_gpgconf_name? get_basename(default_gpgconf_name):"gpgconf.exe"; + + /* 1. Try to find gpgconf.exe in the installation directory of gpgme. */ inst_dir = _gpgme_get_inst_dir (); - gpgconf = find_program_in_inst_dir - (inst_dir, - default_gpgconf_name? get_basename (default_gpgconf_name) : "gpgconf.exe"); + if (inst_dir) + { + gpgconf = find_program_in_dir (inst_dir, name); + } + + /* 2. Try to find gpgconf.exe from GnuPG >= 2.1 below CSIDL_PROGRAM_FILES. */ + if (!gpgconf) + { + const char *name2 = (default_gpgconf_name ? default_gpgconf_name + /**/ : "GnuPG\\bin\\gpgconf.exe"); + gpgconf = find_program_at_standard_place (name2); + } + + /* 3. Try to find gpgconf.exe using that ancient registry key. This + should eventually be removed. */ + if (!gpgconf) + { + char *dir; + + dir = read_w32_registry_string ("HKEY_LOCAL_MACHINE", + "Software\\GNU\\GnuPG", + "Install Directory"); + if (dir) + { + gpgconf = find_program_in_dir (dir, name); + free (dir); + } + } + + /* 4. Try to find gpgconf.exe from Gpg4win below CSIDL_PROGRAM_FILES. */ if (!gpgconf) { - name = (default_gpgconf_name? default_gpgconf_name - /* */ : "GNU\\GnuPG\\gpgconf.exe"); - gpgconf = find_program_at_standard_place (name); - if (!gpgconf) - _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpgconf_path: '%s' not found", - name); + gpgconf = find_program_at_standard_place ("GNU\\GnuPG\\gpgconf.exe"); } + + /* 5. Print a debug message if not found. */ + if (!gpgconf) + _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpgconf_path: '%s' not found",name); + return gpgconf; } @@ -552,10 +569,7 @@ _gpgme_get_w32spawn_path (void) inst_dir = _gpgme_get_inst_dir (); LOCK (get_path_lock); if (!w32spawn_program) - w32spawn_program = find_program_in_inst_dir (inst_dir,"gpgme-w32spawn.exe"); - if (!w32spawn_program) - w32spawn_program - = find_program_at_standard_place ("GNU\\GnuPG\\gpgme-w32spawn.exe"); + w32spawn_program = find_program_in_dir (inst_dir, "gpgme-w32spawn.exe"); UNLOCK (get_path_lock); return w32spawn_program; } diff --git a/tests/Makefile.am b/tests/Makefile.am index 94eddac..89e52e8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,6 +26,7 @@ TESTS = t-version t-data t-engine-info EXTRA_DIST = start-stop-agent t-data-1.txt t-data-2.txt ChangeLog-2011 AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@ +AM_LDFLAGS = -no-install LDADD = ../src/libgpgme.la @GPG_ERROR_LIBS@ noinst_HEADERS = run-support.h diff --git a/tests/Makefile.in b/tests/Makefile.in index 183598e..ab2418a 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -446,6 +446,7 @@ top_srcdir = @top_srcdir@ TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) EXTRA_DIST = start-stop-agent t-data-1.txt t-data-2.txt ChangeLog-2011 AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@ +AM_LDFLAGS = -no-install LDADD = ../src/libgpgme.la @GPG_ERROR_LIBS@ noinst_HEADERS = run-support.h @RUN_GPG_TESTS_FALSE@gpgtests = diff --git a/tests/run-export.c b/tests/run-export.c index 4333208..b133f13 100644 --- a/tests/run-export.c +++ b/tests/run-export.c @@ -43,7 +43,12 @@ show_usage (int ex) fputs ("usage: " PGM " [options] USERIDS\n\n" "Options:\n" " --verbose run in verbose mode\n" + " --openpgp use OpenPGP protocol (default)\n" + " --cms use X.509 protocol\n" " --extern send keys to the keyserver (TAKE CARE!)\n" + " --secret export secret keys instead of public keys\n" + " --raw use PKCS#1 as secret key format\n" + " --pkcs12 use PKCS#12 as secret key format\n" , stderr); exit (ex); } @@ -59,6 +64,7 @@ main (int argc, char **argv) gpgme_key_t keyarray[100]; int keyidx = 0; gpgme_data_t out; + gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; gpgme_export_mode_t mode = 0; if (argc) @@ -79,9 +85,34 @@ main (int argc, char **argv) verbose = 1; argc--; argv++; } + else if (!strcmp (*argv, "--openpgp")) + { + protocol = GPGME_PROTOCOL_OpenPGP; + argc--; argv++; + } + else if (!strcmp (*argv, "--cms")) + { + protocol = GPGME_PROTOCOL_CMS; + argc--; argv++; + } else if (!strcmp (*argv, "--extern")) { - mode |= GPGME_KEYLIST_MODE_EXTERN; + mode |= GPGME_EXPORT_MODE_EXTERN; + argc--; argv++; + } + else if (!strcmp (*argv, "--secret")) + { + mode |= GPGME_EXPORT_MODE_SECRET; + argc--; argv++; + } + else if (!strcmp (*argv, "--raw")) + { + mode |= GPGME_EXPORT_MODE_RAW; + argc--; argv++; + } + else if (!strcmp (*argv, "--pkcs12")) + { + mode |= GPGME_EXPORT_MODE_PKCS12; argc--; argv++; } else if (!strncmp (*argv, "--", 2)) @@ -92,11 +123,11 @@ main (int argc, char **argv) if (!argc) show_usage (1); - init_gpgme (GPGME_PROTOCOL_OpenPGP); + init_gpgme (protocol); err = gpgme_new (&ctx); fail_if_err (err); - gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP); + gpgme_set_protocol (ctx, protocol); /* Lookup the keys. */ err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0); @@ -131,8 +162,10 @@ main (int argc, char **argv) } /* Now for the actual export. */ - if ((mode & GPGME_KEYLIST_MODE_EXTERN)) + if ((mode & GPGME_EXPORT_MODE_EXTERN)) printf ("sending keys to keyserver\n"); + if ((mode & GPGME_EXPORT_MODE_SECRET)) + printf ("exporting secret keys!\n"); err = gpgme_data_new (&out); fail_if_err (err); diff --git a/tests/run-keylist.c b/tests/run-keylist.c index 07c6fa1..8abdf43 100644 --- a/tests/run-keylist.c +++ b/tests/run-keylist.c @@ -53,6 +53,7 @@ show_usage (int ex) " --ephemeral use GPGME_KEYLIST_MODE_EPHEMERAL\n" " --validate use GPGME_KEYLIST_MODE_VALIDATE\n" " --import import all keys\n" + " --offline use offline mode\n" , stderr); exit (ex); } @@ -72,6 +73,7 @@ main (int argc, char **argv) int keyidx = 0; gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; int only_secret = 0; + int offline = 0; if (argc) { argc--; argv++; } @@ -141,6 +143,11 @@ main (int argc, char **argv) import = 1; argc--; argv++; } + else if (!strcmp (*argv, "--offline")) + { + offline = 1; + argc--; argv++; + } else if (!strncmp (*argv, "--", 2)) show_usage (1); @@ -157,6 +164,8 @@ main (int argc, char **argv) gpgme_set_keylist_mode (ctx, mode); + gpgme_set_offline (ctx, offline); + err = gpgme_op_keylist_start (ctx, argc? argv[0]:NULL, only_secret); fail_if_err (err); diff --git a/tests/run-sign.c b/tests/run-sign.c index e1498ea..c59c356 100644 --- a/tests/run-sign.c +++ b/tests/run-sign.c @@ -36,6 +36,14 @@ static int verbose; +static gpg_error_t +status_cb (void *opaque, const char *keyword, const char *value) +{ + (void)opaque; + printf ("status_cb: %s %s\n", keyword, value); + return 0; +} + static void print_result (gpgme_sign_result_t result, gpgme_sig_mode_t type) @@ -67,9 +75,11 @@ show_usage (int ex) fputs ("usage: " PGM " [options] FILE\n\n" "Options:\n" " --verbose run in verbose mode\n" + " --status print status lines from the backend\n" " --openpgp use the OpenPGP protocol (default)\n" " --cms use the CMS protocol\n" " --uiserver use the UI server\n" + " --loopback use a loopback pinentry\n" " --key NAME use key NAME for signing\n" , stderr); exit (ex); @@ -87,6 +97,8 @@ main (int argc, char **argv) gpgme_sig_mode_t sigmode = GPGME_SIG_MODE_NORMAL; gpgme_data_t in, out; gpgme_sign_result_t result; + int print_status = 0; + int use_loopback = 0; if (argc) { argc--; argv++; } @@ -106,6 +118,11 @@ main (int argc, char **argv) verbose = 1; argc--; argv++; } + else if (!strcmp (*argv, "--status")) + { + print_status = 1; + argc--; argv++; + } else if (!strcmp (*argv, "--openpgp")) { protocol = GPGME_PROTOCOL_OpenPGP; @@ -129,6 +146,11 @@ main (int argc, char **argv) key_string = *argv; argc--; argv++; } + else if (!strcmp (*argv, "--loopback")) + { + use_loopback = 1; + argc--; argv++; + } else if (!strncmp (*argv, "--", 2)) show_usage (1); @@ -149,6 +171,10 @@ main (int argc, char **argv) fail_if_err (err); gpgme_set_protocol (ctx, protocol); gpgme_set_armor (ctx, 1); + if (print_status) + gpgme_set_status_cb (ctx, status_cb, NULL); + if (use_loopback) + gpgme_set_pinentry_mode (ctx, GPGME_PINENTRY_MODE_LOOPBACK); if (key_string) { -- 2.7.4