Compare commits

..

No commits in common. "master" and "javascript-binding" have entirely different histories.

730 changed files with 16054 additions and 60190 deletions

5
.gitignore vendored
View File

@ -1,13 +1,12 @@
# GnuPG exclusions # GnuPG exclusions
/aclocal.m4 /aclocal.m4
/autom4te.cache /autom4te.cache
/config.h.in
/configure /configure
/config.h
/config.log /config.log
/config.status /config.status
/conf/config.h.in
/conf/config.h
/libtool /libtool
/VERSION
Makefile.in Makefile.in
Makefile Makefile
stamp-h1 stamp-h1

34
AUTHORS
View File

@ -5,32 +5,27 @@ Repository: git://git.gnupg.org/gpgme.git
Maintainer: Werner Koch <wk@gnupg.org> Maintainer: Werner Koch <wk@gnupg.org>
Bug reports: https://bugs.gnupg.org Bug reports: https://bugs.gnupg.org
Security related bug reports: security@gnupg.org Security related bug reports: security@gnupg.org
License (software): LGPL-2.1-or-later License (software): LGPLv2.1+
License (manual+tools): GPL-3.0-or-later License (manual+tools): GPLv3+
GPGME is free software. See the files COPYING.LESSER and COPYING for GPGME is free software. See the files COPYING for copying conditions.
copying conditions, , and LICENSES for notices about contributions License copyright years may be listed using range notation, e.g.,
that require these additional notices to be distributed. License 2000-2013, indicating that every year in the range, inclusive, is a
copyright years may be listed using range notation, e.g., 2000-2013, copyrightable year that would otherwise be listed individually.
indicating that every year in the range, inclusive, is a copyrightable
year that would otherwise be listed individually.
List of Copyright holders List of Copyright holders
========================= =========================
Copyright (C) 1991-2013 Free Software Foundation, Inc. Copyright (C) 1991-2013 Free Software Foundation, Inc.
Copyright (C) 2000-2001 Werner Koch Copyright (C) 2000-2001 Werner Koch
Copyright (C) 2001-2023 g10 Code GmbH Copyright (C) 2001-2018 g10 Code GmbH
Copyright (C) 2002 Klarälvdalens Datakonsult AB Copyright (C) 2002 Klarälvdalens Datakonsult AB
Copyright (C) 2004-2008 Igor Belyi Copyright (C) 2004-2008 Igor Belyi
Copyright (C) 2002 John Goerzen Copyright (C) 2002 John Goerzen
Copyright (c) 2009 Dave Gamble
Copyright (C) 2014, 2015 Martin Albrecht Copyright (C) 2014, 2015 Martin Albrecht
Copyright (C) 2015, 2018 Ben McGinnes Copyright (C) 2015 Ben McGinnes
Copyright (C) 2015, 2016, 2018 Copyright (C) 2015-2016 Bundesamt für Sicherheit in der Informationstechnik
Bundesamt für Sicherheit in der Informationstechnik
Copyright (C) 2016 Intevation GmbH Copyright (C) 2016 Intevation GmbH
@ -43,7 +38,7 @@ FSF <gnu@gnu.org>
src/stpcpy.c, src/w32-ce.c. src/stpcpy.c, src/w32-ce.c.
g10 Code GmbH <code@g10code.com> g10 Code GmbH <code@g10code.com>
- All stuff since mid March 2001. - All stuff since mid march 2001.
Werner Koch <wk@gnupg.org> Werner Koch <wk@gnupg.org>
- Design and most stuff. - Design and most stuff.
@ -64,15 +59,6 @@ Colin Watson <cjwatson@debian.org>
Tobias Mueller <muelli@cryptobitch.de> Tobias Mueller <muelli@cryptobitch.de>
2016-11-23:1479937342.11180.3.camel@cryptobitch.de: 2016-11-23:1479937342.11180.3.camel@cryptobitch.de:
Ben McGinnes <ben@adversary.org>
2017-12-16:20171216002102.l6aejk5xdp6xhtfi@adversary.org:
Jacob Adams <tookmund@gmail.com>
2018-06-03:ad5141df-b6cc-6c2a-59df-b2f18f7160fd@gmail.com:
Guillaume LE VAILLANT <glv@posteo.net>
2018-10-11:20181011113825.76f9752a@yamatai:
Copyright 2001, 2002, 2012, 2013 g10 Code GmbH Copyright 2001, 2002, 2012, 2013 g10 Code GmbH

View File

@ -1,38 +0,0 @@
Additional license notices for GPGME. -*- org -*-
This file contains the copying permission notices for various files in
the GPGME distribution which are not covered by the GNU Lesser
General Public License (LGPL) or the GNU General Public License (GPL).
These notices all require that a copy of the notice be included
in the accompanying documentation and be distributed with binary
distributions of the code, so be sure to include this file along
with any binary distributions derived from the GNU C Library.
* MIT License
For files:
- cJSON.c, cJSON.h
#+begin_quote
Copyright (c) 2009 Dave Gamble
Permission is hereby granted, free of charge, to any person obtaining
a opy of this software and associated documentation files (the
"Software"), to eal in the Software without restriction, including
without limitation the ights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING ROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#+end_quote

View File

@ -15,32 +15,27 @@
# Public License for more details. # Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, see <https://gnu.org/licenses/>. # License along with this program; if not, see <https://www.gnu.org/licenses/>.
# SPDX-License-Identifier: LGPL-2.1-or-later
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
# Location of the released tarball archives. This is prefixed by # Location of the released tarball archives. Note that this is an
# the variable RELEASE_ARCHIVE in ~/.gnupg-autogen.rc. For example: # internal archive and before uploading this to the public server,
# RELEASE_ARCHIVE=user@host:archive/tarballs # manual tests should be run and the git release tat set and pushed.
RELEASE_ARCHIVE_SUFFIX = gpgme # Adjust as needed.
# The variable RELEASE_SIGNKEY in ~/.gnupg-autogen.rc is used RELEASE_ARCHIVE_DIR = wk@vigenere:tarballs/gpgme/
# to specify the key for signing. For example:
# RELEASE_SIGNKEY=D8692123C4065DEA5E0F3AB5249B39D24F25E3B6
# The key used to sign the released sources. Adjust as needed.
RELEASE_SIGNING_KEY = D8692123C4065DEA5E0F3AB5249B39D24F25E3B6
# Autoconf flags # Autoconf flags
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
DISTCHECK_CONFIGURE_FLAGS = DISTCHECK_CONFIGURE_FLAGS =
EXTRA_DIST = autogen.sh autogen.rc gpgme.spec.in \ EXTRA_DIST = autogen.sh autogen.rc gpgme.spec.in \
ChangeLog-2011 m4/ChangeLog-2011 \ ChangeLog-2011 m4/ChangeLog-2011 contrib/ChangeLog-2011
build-aux/libtool-patch.sed \
conf/whatisthis VERSION LICENSES
# This artificial line is to put a dependency to conf/config.h for 'all'
BUILT_SOURCES = conf/config.h
if RUN_GPG_TESTS if RUN_GPG_TESTS
tests = tests tests = tests
@ -50,11 +45,13 @@ endif
SUBDIRS = src ${tests} doc lang SUBDIRS = src ${tests} doc lang
# Fix the version of the spec file. # Fix the version of the spec file and create a file named VERSION
# to be used for patch's Prereq: feature.
dist-hook: gen-ChangeLog dist-hook: gen-ChangeLog
@set -e; \ @set -e; \
sed -e 's/@pkg_version@/$(PACKAGE_VERSION)/g' \ sed -e 's/@pkg_version@/$(PACKAGE_VERSION)/g' \
$(top_srcdir)/gpgme.spec.in > $(distdir)/gpgme.spec $(top_srcdir)/gpgme.spec.in > $(distdir)/gpgme.spec
echo "$(PACKAGE_VERSION)" > $(distdir)/VERSION
distcheck-hook: distcheck-hook:
set -e; ( \ set -e; ( \
@ -100,42 +97,30 @@ release:
cd $(abs_top_builddir); \ cd $(abs_top_builddir); \
rm -rf dist; mkdir dist ; cd dist ; \ rm -rf dist; mkdir dist ; cd dist ; \
$(abs_top_srcdir)/configure --enable-maintainer-mode; \ $(abs_top_srcdir)/configure --enable-maintainer-mode; \
$(MAKE) distcheck; \ $(MAKE) distcheck TESTFLAGS=--parallel; \
echo "/* Build finished at $$(date -uIseconds) */" ;\ echo "/* Build finished at $$(date -uIseconds) */" ;\
echo "/*" ;\ echo "/*" ;\
echo " * Please run the final step interactively:" ;\ echo " * Please run the final step interactivly:" ;\
echo " * make sign-release" ;\ echo " * make sign-release" ;\
echo " */" ;\ echo " */" ;\
) 2>&1 | tee "$(RELEASE_NAME).buildlog" ) 2>&1 | tee "$(RELEASE_NAME).buildlog"
sign-release: sign-release:
+(set -e; \ +(set -e; \
test $$(pwd | sed 's,.*/,,') = dist || cd dist; \ cd dist; \
x=$$(grep '^RELEASE_ARCHIVE=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\
if [ -z "$$x" ]; then \
echo "error: RELEASE_ARCHIVE missing in ~/.gnupg-autogen.rc">&2; \
exit 2;\
fi;\
myarchive="$$x/$(RELEASE_ARCHIVE_SUFFIX)";\
x=$$(grep '^RELEASE_SIGNKEY=' $$HOME/.gnupg-autogen.rc|cut -d= -f2);\
if [ -z "$$x" ]; then \
echo "error: RELEASE_SIGNKEY missing in ~/.gnupg-autogen.rc">&2; \
exit 2;\
fi;\
mysignkey="$$x";\
files1="$(RELEASE_NAME).tar.bz2" ;\ files1="$(RELEASE_NAME).tar.bz2" ;\
files2="$(RELEASE_NAME).tar.bz2.sig \ files2="$(RELEASE_NAME).tar.bz2.sig \
$(RELEASE_NAME).swdb \ $(RELEASE_NAME).swdb \
$(RELEASE_NAME).buildlog" ;\ $(RELEASE_NAME).buildlog" ;\
echo "/* Signing the source tarball ..." ;\ echo "/* Signing the source tarball ..." ;\
gpg -sbu $$mysignkey $(RELEASE_NAME).tar.bz2 ;\ gpg -sbu $(RELEASE_SIGNING_KEY) $(RELEASE_NAME).tar.bz2 ;\
cat $(RELEASE_NAME).swdb >swdb.snippet;\ cat $(RELEASE_NAME).swdb >swdb.snippet;\
echo >>swdb.snippet ;\ echo >>swdb.snippet ;\
sha1sum $${files1} >>swdb.snippet ;\ sha1sum $${files1} >>swdb.snippet ;\
cat "../$(RELEASE_NAME).buildlog" swdb.snippet \ cat "../$(RELEASE_NAME).buildlog" swdb.snippet \
| gzip >$(RELEASE_NAME).buildlog ;\ | gzip >$(RELEASE_NAME).buildlog ;\
echo "Copying to local archive ..." ;\ echo "Copying to local archive ..." ;\
scp -p $${files1} $${files2} $$myarchive/ || true;\ scp -p $${files1} $${files2} $(RELEASE_ARCHIVE_DIR)/ || true;\
echo "Uploading documentation ..." ;\ echo "Uploading documentation ..." ;\
$(MAKE) -C doc online; \ $(MAKE) -C doc online; \
echo '/*' ;\ echo '/*' ;\

819
NEWS
View File

@ -1,812 +1,13 @@
Noteworthy changes in version 1.24.0 (unrelease) Noteworthy changes in version 1.11.2 (unreleased)
------------------------------------------------- -------------------------------------------------
* Extended gpgme_op_decrypt* and gpgme_op_verify* to allow writing the
output directly to a file. [T6550]
* Extended gpgme_op_encrypt*, gpgme_op_encrypt_sign*, and gpgme_op_sign*
to allow reading the input data directly from a file. [T6550]
* Add information about designated revocation keys. [T7118]
* New context flag "import-options". [T7152]
* cpp: Provide information about designated revocation keys for a Key.
[T7118]
* cpp: Add safer member function returning text describing an error.
[T5960]
* qt: Build QGpgME for Qt 5 and Qt 6 simultaneously. [T7205]
* qt: Install headers for Qt 5 and Qt 6 in separate folders. [T7161]
* qt: Allow reading the data to decrypt/encrypt/sign/verify directly from
files. [T6550]
* qt: Allow writing the decrypted/encrypted/signed/verified data directly
to files. [T6550]
* qt: Allow specifying import options when importing keys. [T7152]
* qt: Allow appending a detached signature to an existing file. [T6867]
* Interface changes relative to the 1.23.2 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GPGME_ENCRYPT_FILE NEW.
GPGME_SIG_MODE_FILE NEW.
gpgme_key_t EXTENDED: New field 'revkeys'.
gpgme_revocation_key_t NEW.
gpgme_set_ctx_flag EXTENDED: New flag 'import-options'.
cpp: Context::EncryptFile NEW.
cpp: SignatureMode::SignFile NEW.
cpp: RevocationKey NEW.
cpp: Key::revocationKey NEW.
cpp: Key::numRevocationKeys NEW.
cpp: Key::revocationKeys NEW.
cpp: Error::asStdString NEW.
cpp: Error::asString DEPRECATED.
qt: DecryptVerifyJob::setInputFile NEW.
qt: DecryptVerifyJob::inputFile NEW.
qt: DecryptVerifyJob::setOutputFile NEW.
qt: DecryptVerifyJob::outputFile NEW.
qt: EncryptJob::setRecipients NEW.
qt: EncryptJob::recipients NEW.
qt: EncryptJob::setInputFile NEW.
qt: EncryptJob::inputFile NEW.
qt: EncryptJob::setOutputFile NEW.
qt: EncryptJob::outputFile NEW.
qt: EncryptJob::setEncryptionFlags NEW.
qt: EncryptJob::encryptionFlags NEW.
qt: SignEncryptJob::setSigners NEW.
qt: SignEncryptJob::signers NEW.
qt: SignEncryptJob::setRecipients NEW.
qt: SignEncryptJob::recipients NEW.
qt: SignEncryptJob::setInputFile NEW.
qt: SignEncryptJob::inputFile NEW.
qt: SignEncryptJob::setOutputFile NEW.
qt: SignEncryptJob::outputFile NEW.
qt: SignEncryptJob::setEncryptionFlags NEW.
qt: SignEncryptJob::encryptionFlags NEW.
qt: SignJob::setSigners NEW.
qt: SignJob::signers NEW.
qt: SignJob::setInputFile NEW.
qt: SignJob::inputFile NEW.
qt: SignJob::setOutputFile NEW.
qt: SignJob::outputFile NEW.
qt: SignJob::setSigningFlags NEW.
qt: SignJob::signingFlags NEW.
qt: SignJob::setAppendSignature NEW.
qt: SignJob::appendSignatureEnabled NEW.
qt: VerifyDetachedJob::setSignatureFile NEW.
qt: VerifyDetachedJob::signatureFile NEW.
qt: VerifyDetachedJob::setSignedFile NEW.
qt: VerifyDetachedJob::signedFile NEW.
qt: VerifyOpaqueJob::setInputFile NEW.
qt: VerifyOpaqueJob::inputFile NEW.
qt: VerifyOpaqueJob::setOutputFile NEW.
qt: VerifyOpaqueJob::outputFile NEW.
qt: ImportJob::setImportOptions NEW.
qt: ImportJob::importOptions NEW.
Noteworthy changes in version 1.23.2 (2023-11-28)
-------------------------------------------------
* Preserve more specific existing failure code. [T6575]
* qt: Start dirmngr with gpgconf to avoid multiple instances. [T6833]
* qt: On Windows, use UTF-8 when logging the error text. [T5960]
* qt: Remove left-over partial files more persistently. [T6584]
* qt: Use a temporary file name when creating signed or encrypted
archives. [T6721]
* qt: Build Qt 6 bindings with -fPIC if requested or Qt 6 was built with
this flag. [T6781]
Notes:
~~~~~~
qt: DefaultKeyGenerationJob DEPRECATED.
[c=C43/A32/R1 cpp=C26/A20/R1 qt=C20/A5/R1]
Release-info: https://dev.gnupg.org/T6782
Noteworthy changes in version 1.23.1 (2023-10-27)
-------------------------------------------------
* w32: Change gpgme-w32-spawn to use Unicode arguments. [T6728]
[c=C43/A32/R0 cpp=C26/A20/R0 qt=C20/A5/R0]
Release-info: https://dev.gnupg.org/T6774
Noteworthy changes in version 1.23.0 (2023-10-25)
-------------------------------------------------
* Support GPGME_ENCRYPT_ALWAYS_TRUST also for S/MIME. [T6559]
* New keylist mode GPGME_KEYLIST_MODE_WITH_V5FPR. [T6705]
* New key capability flags has_*. [T6748]
* gpgme-tool: Support use of Windows HANDLE. [T6634]
* qt: Support refreshing keys via WKD. [T6672]
* qt: Handle cancel in changeexpiryjob. [T6754]
* Interface changes relative to the 1.22.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GPGME_KEYLIST_MODE_WITH_V5FPR NEW.
gpgme_key_t EXTENDED: New field has_encrypt.
gpgme_key_t EXTENDED: New field has_sign.
gpgme_key_t EXTENDED: New field has_certify.
gpgme_key_t EXTENDED: New field has_authenticate.
cpp: Key::canCertify NEW.
cpp: Key::canSign NEW.
cpp: Key::canEncrypt NEW.
cpp: Key::canAuthenticate NEW.
qt: Protocol::wkdRefreshJob NEW.
qt: WKDRefreshJob NEW.
[c=C43/A32/R0 cpp=C26/A20/R0 qt=C20/A5/R0]
Release-info: https://dev.gnupg.org/T6774
Noteworthy changes in version 1.22.0 (2023-08-21)
-------------------------------------------------
* Prevent wrong plaintext when verifying clearsigned signature. [T6622]
* Return bad data error instead of general error on unexpected data.
[T6617]
* Take care of offline mode for all operations of gpgsm engine.
[T6648]
* Prepare the use of the forthcoming libassuan version 3.
* New configure option --with-libtool-modification. [T6619]
* cpp: Expose gpgme_decrypt_result_t.is_mime. [T6199]
* qt: Clean up after failure or cancel of sign/encrypt archive
operation. [T6584]
* qt: Add setInputEncoding to QGpgMe::EncryptJob. [T6166]
* qt: Make toLogString helper public. [T6584]
* Interface changes relative to the 1.21.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
qt: EncryptJob::setInputEncoding NEW.
qt: DecryptionResult::isMime NEW.
qt: toLogString NEW.
[c=C42/A31/R0 cpp=C25/A19/R0 qt=C19/A4/R0]
Release-info: https://dev.gnupg.org/T6668
Noteworthy changes in version 1.21.0 (2023-07-07)
-------------------------------------------------
* Extended gpgme_op_encrypt, gpgme_op_encrypt_sign, and gpgme_op_sign
to allow writing the output directly to a file. [T6530]
* Extended gpgme_op_decrypt and gpgme_op_verify to allow reading the
input data directly from files. [T6530]
* For key signing and uid revoking allow an empty user id.
[rMfbc3963d62]
* Pass an input-size-hint also to the gpgsm engine. [T6534]
* qt: Allow writing the created archives directly to a
file. [T6530]
* qt: Allow reading the signed/encrypted archive to decrypt
or verify directly from a file. [T6530]
* qt: Qt Jobs working with QIODeviceDataProvider now properly
handle input-size hints and progress for files larger.
2^32 bytes in 32 bit builds. [T6534]
* cpp: Error::isCanceled now also returns true for error code
GPG_ERR_FULLY_CANCELED. [T6510]
* python: Fix wrong use of write. [T6501]
* Interface changes relative to the 1.20.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cpp: Data::setFlag NEW.
cpp: Data::setSizeHint NEW.
qt: Job::startIt NEW.
qt: DecryptVerifyArchiveJob::setInputFile NEW.
qt: DecryptVerifyArchiveJob::inputFile NEW.
qt: EncryptArchiveJob::setRecipients NEW.
qt: EncryptArchiveJob::recipients NEW.
qt: EncryptArchiveJob::setInputPaths NEW.
qt: EncryptArchiveJob::inputPaths NEW.
qt: EncryptArchiveJob::setOutputFile NEW.
qt: EncryptArchiveJob::outputFile NEW.
qt: EncryptArchiveJob::setEncryptionFlags NEW.
qt: EncryptArchiveJob::encryptionFlags NEW.
qt: SignArchiveJob::setSigners NEW.
qt: SignArchiveJob::signers NEW.
qt: SignArchiveJob::setInputPaths NEW.
qt: SignArchiveJob::inputPaths NEW.
qt: SignArchiveJob::setOutputFile NEW.
qt: SignArchiveJob::outputFile NEW.
qt: SignEncryptArchiveJob::setSigners NEW.
qt: SignEncryptArchiveJob::signers NEW.
qt: SignEncryptArchiveJob::setRecipients NEW.
qt: SignEncryptArchiveJob::recipients NEW.
qt: SignEncryptArchiveJob::setInputPaths NEW.
qt: SignEncryptArchiveJob::inputPaths NEW.
qt: SignEncryptArchiveJob::setOutputFile NEW.
qt: SignEncryptArchiveJob::outputFile NEW.
qt: SignEncryptArchiveJob::setEncryptionFlags NEW.
qt: SignEncryptArchiveJob::encryptionFlags NEW.
[c=C41/A30/R0 cpp=C24/A18/R0 qt=C18/A3/R0]
Release-info: https://dev.gnupg.org/T6585
Noteworthy changes in version 1.20.0 (2023-04-20)
-------------------------------------------------
* On Windows, the gettext functions provided by gpgrt are switched
into utf8 mode, so that all localized texts returned by GpgME or
gpgrt, e.g. the texts for error codes are now UTF-8 encoded.
[T5960]
* Key::canSign now returns false for OpenPGP keys without signing
(sub)key. [T6456]
* The new macOS Homebrew location is now by default supported.
[T6440]
* Fix regression in 1.19.0. [rMb608c084b9]
* Fix invocation of gpgtar on Windows. [rM0c29119e06]
* Interface changes relative to the 1.19.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_subkey_t EXTENDED: New field 'can_renc'.
gpgme_subkey_t EXTENDED: New field 'can_timestamp'.
gpgme_subkey_t EXTENDED: New field 'is_group_owned'.
cpp: Subkey::canRenc NEW.
cpp: Subkey::canTimestamp NEW.
cpp: Subkey::isGroupOwned NEW.
cpp: Key::canReallySign DEPRECATED.
[c=C40/A29/R0 cpp=C23/A17/R0 qt=C17/A2/R1]
Release-info: https://dev.gnupg.org/T6463
Noteworthy changes in version 1.19.0 (2023-03-17)
-------------------------------------------------
* New convenience option --identify for gpgme-json.
* New context flag "no-auto-check-trustdb". [T6261]
* Optionally, build QGpgME for Qt 6
* Support component "gpgtar-name" in gpgme_get_dirinfo. [T6342]
* Extended gpgme_op_encrypt*, gpgme_op_encrypt_sign*, and
gpgme_op_sign* to allow creating an encrypted and/or signed
archive. [T6342]
* Extended gpgme_op_decrypt*, gpgme_op_decrypt_verify*, and gpgme_op_verify*
to allow extracting an encrypted and/or signed archive. [T6342]
* cpp: Handle error when trying to sign expired keys. [T6155]
* cpp: Support encryption flags ThrowKeyIds, EncryptWrap, and WantAddress.
[T6359]
* cpp, qt: Fix building with C++11. [T6141]
* qt: Fix problem with expiration dates after 2038-01-19 on 32-bit systems
when adding an existing subkey to another key. [T6137]
* cpp: Allow setting the curve to use when generating ECC keys
for smart cards. [T4429]
* qt: Extend ListAllKeysJob to allow disabling the automatic trust database
check when listing all keys. [T6261]
* qt: Allow deferred start of import jobs. [T6323]
* qt: Support creating and extracting signed and encrypted archives. [T6342]
* Interface changes relative to the 1.18.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_get_ctx_flag EXTENDED: New flag 'no-auto-check-trustdb'.
gpgme_set_ctx_flag EXTENDED: New flag 'no-auto-check-trustdb'.
GPGME_DECRYPT_ARCHIVE NEW.
GPGME_ENCRYPT_ARCHIVE NEW.
GPGME_SIG_MODE_ARCHIVE NEW.
GPGME_VERIFY_ARCHIVE NEW.
gpgme_verify_flags_t NEW.
gpgme_op_verify_ext_start NEW.
gpgme_op_verify_ext NEW.
cpp: GpgGenCardKeyInteractor::Curve NEW.
cpp: GpgGenCardKeyInteractor::setCurve NEW.
cpp: Context::WantAddress NEW.
cpp: Context::DecryptArchive NEW.
cpp: Context::EncryptArchive NEW.
cpp: SignArchive NEW.
cpp: Data::setFileName EXTENDED: New overload
qt: ListAllKeysJob::Option NEW.
qt: ListAllKeysJob::Options NEW.
qt: ListAllKeysJob::setOptions NEW.
qt: ListAllKeysJob::options NEW.
qt: Job::startNow NEW.
qt: ImportJob::startLater NEW.
qt: FileListDataProvider NEW.
qt: DecryptVerifyArchiveJob NEW.
qt: EncryptArchiveJob NEW.
qt: SignArchiveJob NEW.
qt: SignEncryptArchiveJob NEW.
qt: Protocol::decryptVerifyArchiveJob NEW.
qt: Protocol::encryptArchiveJob NEW.
qt: Protocol::signArchiveJob NEW.
qt: Protocol::signEncryptArchiveJob NEW.
qt: Job::jobProgress NEW.
qt: Job::rawProgress NEW.
qt: Job::progress DEPRECATED.
[c=C39/A28/R0 cpp=C22/A16/R0 qt=C17/A2/R0]
Release-info: https://dev.gnupg.org/T6341
Noteworthy changes in version 1.18.0 (2022-08-10)
-------------------------------------------------
* New keylist mode to force refresh via external methods. [T5951]
* The keylist operations now create an import result to report the
result of the locate keylist modes. [T5951]
* core: Return BAD_PASSPHRASE error code on symmetric decryption
failure. [T5939]
* cpp, qt: Do not export internal symbols anymore. [T5906]
* cpp, qt: Support revocation of own OpenPGP keys. [T5904]
* qt: The file name of (signed and) encrypted data can now be set. [T6056]
* cpp, qt: Support setting the primary user ID. [T5938]
* python: Fix segv(NULL) when inspecting contect after exeception. [T6060]
* Interface changes relative to the 1.17.1 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GPGME_KEYLIST_MODE_FORCE_EXTERN NEW.
GPGME_KEYLIST_MODE_LOCATE_EXTERNAL NEW.
cpp: RevocationReason NEW.
cpp: GpgRevokeKeyEditInteractor NEW.
cpp: Result::setError NEW.
cpp: KeyListMode::ForceExtern NEW.
cpp: KeyListMode::LocateExternal NEW.
cpp: KeyListMode::KeyListModeMask NEW.
cpp: ImportResult::mergeWith NEW.
cpp: KeyListModeSaver NEW.
cpp: Context::setPrimaryUid NEW.
cpp: Context::startSetPrimaryUid NEW.
qt: RevokeKeyJob NEW.
qt: Protocol::revokeKeyJob NEW.
qt: EncryptJob::setFileName NEW.
qt: EncryptJob::fileName NEW.
qt: SignEncryptJob::setFileName NEW.
qt: SignEncryptJob::fileName NEW.
qt: SetPrimaryUserIDJob NEW.
qt: Protocol::setPrimaryUserIDJob NEW.
[c=C38/A27/R0 cpp=C21/A15/R0 qt=C16/A1/R0]
Release-info: https://dev.gnupg.org/T6128
Noteworthy changes in version 1.17.1 (2022-03-06)
-------------------------------------------------
* qt: Fix a bug in the ABI compatibility of 1.17.0. [T5834]
[c=C37/A26/R0 cpp=C20/A14/R0 qt=C15/A0/R0]
Release-info: https://dev.gnupg.org/T5872
Noteworthy changes in version 1.17.0 (2022-02-07)
-------------------------------------------------
* New context flag "key-origin". [#5733]
* New context flag "import-filter". [#5739]
* New export mode to export secret subkeys. [#5757]
* Detect errors during the export of secret keys. [#5766]
* New function gpgme_op_receive_keys to import keys from a keyserver
without first running a key listing. [#5808]
* Detect bad passphrase error in certificate import. [T5713]
* Allow setting --key-origin when importing keys. [T5733]
* Support components "keyboxd", "gpg-agent", "scdaemon", "dirmngr",
"pinentry", and "socketdir" in gpgme_get_dirinfo. [T5727,T5613]
* Under Unix use poll(2) instead of select(2), when available.
[T2385]
* Do not use --flat_namespace when linking for macOS. [T5610]
* Fix results returned by gpgme_data_* functions. [T5481]
* Support closefrom also for glibc. [rM4b64774b6d]
* cpp,qt: Add support for export of secret keys and secret subkeys.
[#5757]
* cpp,qt: Support for adding existing subkeys to other keys. [#5770]
* qt: Extend ChangeExpiryJob to change expiration of primary key
and of subkeys at the same time. [#4717]
* qt: Support WKD lookup without implicit import. [#5728]
* qt: Allow specifying an import filter when importing keys. [#5739]
* qt: Expect UTF-8 on stderr on Windows. [rM8fe1546282]
* qt: Allow retrieving the default value of a config entry. [T5515]
* Interface changes relative to the 1.16.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_op_receive_keys NEW.
gpgme_op_receive_keys_start NEW.
qt: Protocol::secretSubkeyExportJob NEW.
cpp: Context::exportSecretSubkeys NEW.
cpp: Context::startSecretSubkeyExport NEW.
qt: Protocol::secretKeyExportJob CHANGED: Param 'charset' is ignored.
cpp: Context::exportKeys NEW.
cpp: Context::startKeyExport NEW.
cpp: Context::exportSecretKeys NEW.
cpp: Context::startSecretKeyExport NEW.
cpp: GpgAddExistingSubkeyEditInteractor NEW.
GPGME_EXPORT_MODE_SECRET_SUBKEY NEW.
gpgme_set_ctx_flag EXTENDED: New flag 'key-origin'.
gpgme_set_ctx_flag EXTENDED: New flag 'import-filter'.
qt: ChangeExpiryJob::Option NEW.
qt: ChangeExpiryJob::Options NEW.
qt: ChangeExpiryJob::setOptions NEW.
qt: ChangeExpiryJob::options NEW.
qt: CryptoConfigEntry::defaultValue NEW.
qt: WKDLookupJob NEW.
qt: WKDLookupResult NEW.
qt: Protocol::wkdLookupJob NEW.
qt: ImportJob::setKeyOrigin NEW.
qt: ImportJob::keyOrigin NEW.
qt: ImportJob::keyOriginUrl NEW.
qt: setImportFilter NEW.
qt: importFilter NEW.
qt: AddExistingSubkeyJob NEW.
qt: Protocol::addExistingSubkeyJob NEW.
[c=C37/A26/R0 cpp=C20/A14/R0 qt=C14/A7/R0]
Release-info: https://dev.gnupg.org/T5819
Noteworthy changes in version 1.16.0 (2021-06-24)
-------------------------------------------------
* New context flag "cert-expire". [#5505]
* New data flags "io-buffer-size" and "sensitive". [#5478]
* Increase I/O buffer size from 512 to 4k under Windows.
* cpp,qt: Add support for trust signatures. [#5421]
* qt: Add support for flags in LDAP server options. [#5217]
* qt: Fix too high memory consumption due to QProcess. [#5475]
* qt: Do not set empty base DN as query of keyserver URL. [#5465]
* qt: Extend SignKeyJob to create signatures with expiration date.
[5506]
* python: New optional parameter filter_signatures for decrypt.
[#5292]
* Interface changes relative to the 1.15.1 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_set_ctx_flag EXTENDED: New flag 'cert-expire'.
cpp: SignKeyJob::setTrustSignature NEW.
cpp: TrustSignatureTrust NEW.
cpp: GpgSignKeyEditInteractor::setTrustSignatureTrust NEW.
cpp: GpgSignKeyEditInteractor::setTrustSignatureDepth NEW.
cpp: GpgSignKeyEditInteractor::setTrustSignatureScope NEW.
cpp: UserID::Signature::isTrustSignature NEW.
cpp: UserID::Signature::trustValue NEW.
cpp: UserID::Signature::trustDepth NEW.
cpp: UserID::Signature::trustScope NEW.
gpgme_key_sig_t EXTENDED: New field 'trust_depth'.
gpgme_key_sig_t EXTENDED: New field 'trust_value'.
gpgme_key_sig_t EXTENDED: New field 'trust_scope'.
GPGME_KEYSIGN_FORCE NEW.
qt: CryptoConfig::entry CHANGED: Added overload; deprecated old
[c=C36/A25/R0 cpp=C19/A13/R0 qt=C13/A6/R0]
Release-info: https://dev.gnupg.org/T5499
Noteworthy changes in version 1.15.1 (2021-01-08)
-------------------------------------------------
* Fix another bug in the secret key export. [#5046]
* Make listing of signatures work if only secret keys are listed. [#3580]
* Fix build problem on FreeBSD. [a6220adf30]
* qt: Avoid empty "rem@gnupg.org" signature notations. [#5142]
* python: Fix key_export functions. [#5149]
[c=C35/A24/R1 cpp=C18/A12/R1 qt=C12/A5/R1]
Release-info: https://dev.gnupg.org/T5225
Noteworthy changes in version 1.15.0 (2020-11-12)
-------------------------------------------------
* New function gpgme_op_setexpire to make changing the expiration
easier (requires GnuPG 2.1.22). [#4999]
* New function gpgme_op_revsig to revoke key signatures (requires
GnuPG 2.2.24). [#5094]
* Support exporting secret keys. [#5046]
* cpp: Support for set expire operations in the C++ bindings. [#5003]
* cpp: Support for revoking key signatures in the C++ bindings. [#5094]
* qt: Extended ChangeExpiryJob to support changing the expiry of
subkeys. [#4717]
* qt: Extended QuickJob to support revoking of key signatures. [#5094]
* qt: Added QDebug stream operator for GpgME::Error.
* Require a somewhat newer version of libgpg-error (1.36).
* Interface changes relative to the 1.14.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_op_setexpire_start NEW.
gpgme_op_setexpire NEW.
gpgme_op_revsig_start NEW.
gpgme_op_revsig NEW.
GPGME_REVSIG_LFSEP NEW.
cpp: Context::setExpire NEW.
cpp: Context::startSetExpire NEW.
cpp: EngineInfo::Version::operator<= NEW.
cpp: EngineInfo::Version::operator>= NEW.
cpp: EngineInfo::Version::operator!= NEW.
cpp: StatusConsumer NEW.
cpp: StatusConsumerAssuanTransaction NEW.
cpp: Context::cancelPendingOperationImmediately NEW.
cpp: Context::revokeSignature NEW.
cpp: Context::startRevokeSignature NEW.
cpp: UserID::Signature::operator< NEW.
qt: operator<<(QDebug debug, const GpgME::Error &err) NEW.
qt: QuickJob::startRevokeSignature NEW.
qt: QuickJob::result CHANGED: Made params 'auditLogAsHtml'
and 'auditLogError' optional.
[c=C35/A24/R0 cpp=C18/A12/R0 qt=C12/A5/R0]
Release-info: https://dev.gnupg.org/T5131
Noteworthy changes in version 1.14.0 (2020-07-16)
-------------------------------------------------
* New keylist mode to force the engine to return the keygrip. [#4820]
* New export mode to export as OpenSSH public key. [#4310]
* New context flag "extended-edit" to enable expert key edit. [#4734]
* Deprecate the anyway non working trustlist functions. [#4834]
* cpp: Add convenience API to obtain remarks. [#4734]
* cpp: The sign key edit-interactor now supports multiple signatures
from the same key. [#4734]
* qt: Extended signkeyjob to handle remarks and multiple signatures.
[#4734]
* qt: Added job API for gpg-card.
* qt: The logging category has been changed to gpg.qgpgme to be more
consistent with other qt logging categories.
* Interface changes relative to the 1.13.1 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GPGME_KEYLIST_MODE_WITH_KEYGRIP NEW.
GPGME_EXPORT_MODE_SSH NEW.
gpgme_user_id_t EXTENDED: New field 'uidhash'.
cpp: UserID::remark NEW.
cpp: UserID::remarks NEW.
cpp: GpgSignKeyEditInteractor::setDupeOk NEW.
cpp: Context::exportPublicKeys EXTENDED: New param 'flags'.
cpp: Context::startPublicKeyExport EXTENDED: New param 'flags'.
cpp: Context::ExportMode NEW.
qt: SignKeyJob::setDupeOk NEW.
qt: SignKeyJob::setRemark NEW.
qt: GpgCardJob NEW.
qt: ExportJob::setExportFlags NEW.
[c=C34/A23/R0 cpp=C17/A11/R0 qt=C11/A4/R0]
Release-info: https://dev.gnupg.org/T4996
Noteworthy changes in version 1.13.1 (2019-06-13)
-------------------------------------------------
* cpp: gpgme_set_global_flag is now wrapped. [#4471]
* w32: Improved handling of unicode install paths. [#4453]
* w32: The gpgme_io_spawn error message is now only shown once. [#4453]
* Fixed a crash introduced in 1.13.0 when working with S/MIME. [#4556]
* w32: Fixed format string errors introduced in 1.13.0 that could
cause crashes. [#4440]
* w32: Fixed an error in the new diagnostic gpgsm support introduced
in 1.13.0 that caused crashes in low fd scenarios. [#4439]
* python: Fixed a DecryptionError Exception. [#4478]
* python: No longer raises BadSignatures from decrypt(verify=True).
[#4276]
* Interface changes relative to the 1.13.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cpp: setGlobalFlag NEW.
[c=C33/A22/R1 cpp=C16/A10/R0 qt=C10/A3/R4]
Release-info: https://dev.gnupg.org/T4551
Noteworthy changes in version 1.13.0 (2019-03-26)
-------------------------------------------------
* Support GPGME_AUDITLOG_DIAG for gpgsm. [#4426]
* New context flag "trust-model".
* Removed support for WindowsCE and Windows ME.
* Aligned the gpgrt-config code with our other libaries.
* Auto-check for all installed Python versions. [#3354]
* Fixed generating card key in the C++ bindings. [#4428]
* Fixed a segv due to bad parameters in genkey. [#4192]
* Fixed crash if the plaintext is ignored in a CMS verify.
* Fixed memleak on Windows. [T4238]
* Tweaked the Windows I/O code.
* Fixed random crashes on Windows due to closing an arbitrary
handle. [#4237]
* Fixed a segv on Windows. [#4369]
* Fixed test suite problems related to dtags. [#4298]
* Fixed bunch of python bugs. [#4242,commit 9de1c96ac3cf]
* Several fixes to the Common Lisp bindings.
* Fixed minor bugs in gpgme-json. [#4331,#4341,#4342,#4343]
* Require trace level 8 to dump all I/O data.
* The compiler must now support variadic macros.
* Interface changes relative to the 1.12.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_set_ctx_flag EXTENDED: New flag 'trust-model'.
cpp: Context::create NEW.
cpp: Key::isBad NEW.
cpp: Subkey::isBad NEW.
cpp: UserID::isBad NEW.
cpp: UserID::Signature::isBad NEW.
cpp: GenCardKeyInteractor::setAlgo NEW.
[c=C33/A22/R0 cpp=C15/A9/R0 qt=C10/A3/R3]
Release-info: https://dev.gnupg.org/T4376
Noteworthy changes in version 1.12.0 (2018-10-08)
-------------------------------------------------
* Enhanced the JSON based interface tool gpgme-json to support Native
Messaging as well as new Javascript code to support the browser
site. See lang/js/README for details.
* Major overhaul of the Python language bindings documentation.
* Even for old versions of gpg a missing MDC will now lead to a * Even for old versions of gpg a missing MDC will now lead to a
decryption failure. decryption failure.
* Added context flag "auto-key-locate" to control the
behavior of GPGME_KEYLIST_MODE_LOCATE.
* New data function to create a data object from an estream.
* Add more interfaces to the C++ bindings.
* Improved error codes on decryption failure.
* Lots of minor fixes.
* Interface changes relative to the 1.11.1 release: * Interface changes relative to the 1.11.1 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_data_new_from_estream NEW. cpp: DecryptionResult::sessionKey NEW.
gpgme_decrypt_result_t EXTENDED: New field legacy_cipher_nomdc. cpp: DecryptionResult::symkeyAlgo NEW.
gpgme_set_ctx_flag EXTENDED: New flag 'ignore-mdc-error'.
GPGME_AUDITLOG_DEFAULT NEW.
GPGME_AUDITLOG_DIAG NEW.
gpgme_set_ctx_flag EXTENDED: New flag 'auto-key-locate'.
cpp: DecryptionResult::sessionKey NEW.
cpp: DecryptionResult::symkeyAlgo NEW.
cpp: DecryptionResult::isLegacyCipherNoMDC New.
cpp: Data::rewind NEW.
cpp: Context::setFlag NEW.
cpp: Context::getFlag NEW.
cpp: Context::createKeyEx NEW.
[c=C32/A21/R0 cpp=C14/A8/R0 qt=C10/A3/R2]
Release-info: https://dev.gnupg.org/T4109
Noteworthy changes in version 1.11.1 (2018-04-20) Noteworthy changes in version 1.11.1 (2018-04-20)
------------------------------------------------- -------------------------------------------------
@ -1213,7 +414,7 @@ Noteworthy changes in version 1.6.0 (2015-08-26) [C25/A14/R0]
* The passphrase handler for the loopback mode has been improved and may * The passphrase handler for the loopback mode has been improved and may
also be used with genkey. also be used with genkey.
* [w32] The standard GnuPG 2.1 install directory is now searched for * [w32] The standard GnuPG 2.1 install directory is now seached for
gpgconf.exe before a registry specified directory and the Gpg4win gpgconf.exe before a registry specified directory and the Gpg4win
install directory. install directory.
@ -1516,7 +717,7 @@ Noteworthy changes in version 1.1.8 (2008-12-08)
------------------------------------------------ ------------------------------------------------
* SIGPIPE is now again ignored as described in the manual. Fixes * SIGPIPE is now again ignored as described in the manual. Fixes
regression introduced with 1.1.6. regresion introduced with 1.1.6.
Noteworthy changes in version 1.1.7 (2008-10-17) Noteworthy changes in version 1.1.7 (2008-10-17)
@ -1712,8 +913,8 @@ Noteworthy changes in version 1.0.3 (2005-06-20)
* Previousy, GPGME would use a default "include certs" of 1. This * Previousy, GPGME would use a default "include certs" of 1. This
has been changed. Now GPGME will use the crypto backend engines has been changed. Now GPGME will use the crypto backend engines
default unless you set the value with gpgme_set_include_certs() default unless you set the value with gpgme_set_include_certs()
explicitly. A new macro GPGME_INCLUDE_CERTS_DEFAULT can be used explicitely. A new macro GPGME_INCLUDE_CERTS_DEFAULT can be used
as a value to explicitly request the new default behaviour. as a value to explicitely request the new default behaviour.
Because the default changes, this is a slight change of the API Because the default changes, this is a slight change of the API
semantics. We consider it to be a bug fix. semantics. We consider it to be a bug fix.
@ -1800,7 +1001,7 @@ Noteworthy changes in version 0.4.7 (2004-04-29)
disabled in the gpgme_key_t structures. disabled in the gpgme_key_t structures.
* A bug fix: The flag wrong_key_usage of gpgme_signature_t was * A bug fix: The flag wrong_key_usage of gpgme_signature_t was
accidentally of type int instead unsigned int. accidently of type int instead unsigned int.
* Interface changes relative to the 0.4.5 release: * Interface changes relative to the 0.4.5 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -2013,7 +1214,7 @@ Noteworthy changes in version 0.4.1 (2003-06-06)
The error values have been completely replaced by a more The error values have been completely replaced by a more
sophisticated model that allows GPGME to transparently and accurately sophisticated model that allows GPGME to transparently and accurately
report all errors from the other GnuPG components, regardless of report all errors from the other GnuPG components, irregardless of
process boundaries. This is achieved by using the library process boundaries. This is achieved by using the library
libgpg-errors, which is shared by all GnuPG components. This library libgpg-errors, which is shared by all GnuPG components. This library
is now required for GPGME. is now required for GPGME.
@ -2631,7 +1832,7 @@ Noteworthy changes in version 0.3.1 (2002-02-09)
selects between local keyring, remote keyserver, or both. selects between local keyring, remote keyserver, or both.
For this, two new macros are defined, GPGME_KEYLIST_MODE_LOCAL For this, two new macros are defined, GPGME_KEYLIST_MODE_LOCAL
and GPGME_KEYLIST_MODE_EXTERN. To make it possible to modify the and GPGME_KEYLIST_MODE_EXTERN. To make it possible to modify the
current setting, a function gpgme_get_keylist_mode was added to current setting, a fucntion gpgme_get_keylist_mode was added to
retrieve the current mode. retrieve the current mode.
* gpgme_wait accepts a new argument STATUS to return the error status * gpgme_wait accepts a new argument STATUS to return the error status

8
README
View File

@ -1,7 +1,7 @@
GPGME - GnuPG Made Easy GPGME - GnuPG Made Easy
--------------------------- ---------------------------
Copyright 2001-2023 g10 Code GmbH Copyright 2001-2018 g10 Code GmbH
This file is free software; as a special exception the author gives This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without unlimited permission to copy and/or distribute it, with or without
@ -41,11 +41,11 @@ See the file INSTALL for generic installation instructions.
Check that you have unmodified sources. See below on how to do this. Check that you have unmodified sources. See below on how to do this.
Don't skip it - this is an important step! Don't skip it - this is an important step!
To build GPGME, you need to install libgpg-error (>= 1.36) and To build GPGME, you need to install libgpg-error (>= 1.24) and
Libassuan (>= 2.4.2). Libassuan (>= 2.4.2).
For support of the OpenPGP and the CMS protocols, you should use at For support of the OpenPGP and the CMS protocols, you should use the
least GnuPG version 2.2.41 or 2.4.3, available at: latest version of GnuPG (>= 2.1.18) , available at:
https://gnupg.org/ftp/gcrypt/gnupg/. https://gnupg.org/ftp/gcrypt/gnupg/.
For building the Git version of GPGME please see the file README.GIT For building the Git version of GPGME please see the file README.GIT

6
TODO
View File

@ -32,7 +32,7 @@ Hey Emacs, this is -*- org -*- mode!
Clean up the current TODO list. Include properties as relevant (so Clean up the current TODO list. Include properties as relevant (so
if someone does make a PDF or HTML version the TOC will work). if someone does make a PDF or HTML version the TOC will work).
Also check to see if some of these ancient things can be removed Also check ans see if some of these ancient things can be removed
(e.g. do we really need to fix things that were broken in GPG (e.g. do we really need to fix things that were broken in GPG
1.3.x? I'm thinking not so much). 1.3.x? I'm thinking not so much).
@ -78,7 +78,7 @@ Hey Emacs, this is -*- org -*- mode!
:PROPERTIES: :PROPERTIES:
:CUSTOM_ID: set-fd-blocking :CUSTOM_ID: set-fd-blocking
:END: :END:
issuing simple commands, because we are mixing synchronous issueing simple commands, because we are mixing synchronous
commands into potentially asynchronous operations. commands into potentially asynchronous operations.
** Might want to implement nonblock for w32 native backend! ** Might want to implement nonblock for w32 native backend!
:PROPERTIES: :PROPERTIES:
@ -272,7 +272,7 @@ Hey Emacs, this is -*- org -*- mode!
with a string and some optional arguments. This is for example with a string and some optional arguments. This is for example
required to notify an application of a changed smartcard, The required to notify an application of a changed smartcard, The
application can then do whatever is required. There are other application can then do whatever is required. There are other
usages too. This notification system should be independent of any usages too. This notfication system should be independent of any
contextes of course. contextes of course.
Not sure whether this is still required. GPGME_PROTOCOL_ASSUAN is Not sure whether this is still required. GPGME_PROTOCOL_ASSUAN is

View File

@ -2,13 +2,19 @@
case "$myhost" in case "$myhost" in
w32) w32)
configure_opts="" configure_opts="
--with-gpg-error-prefix=@SYSROOT@
--with-libassuan-prefix=@SYSROOT@
"
;; ;;
amd64) amd64)
configure_opts="" configure_opts="
--with-gpg-error-prefix=@SYSROOT@
--with-libassuan-prefix=@SYSROOT@
"
;; ;;
esac esac
final_info="mkdir build && cd build && ../configure --enable-maintainer-mode && make" final_info="./configure --enable-maintainer-mode && make"

View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# autogen.sh # autogen.sh
# Copyright (C) 2003, 2014, 2017, 2018, 2022 g10 Code GmbH # Copyright (C) 2003, 2014, 2017 g10 Code GmbH
# #
# This file is free software; as a special exception the author gives # This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without # unlimited permission to copy and/or distribute it, with or without
@ -15,7 +15,7 @@
# configure it for the respective package. It is maintained as part of # configure it for the respective package. It is maintained as part of
# GnuPG and source copied by other packages. # GnuPG and source copied by other packages.
# #
# Version: 2023-03-15 # Version: 2017-01-17
configure_ac="configure.ac" configure_ac="configure.ac"
@ -74,6 +74,7 @@ PRINT_HOST=no
PRINT_BUILD=no PRINT_BUILD=no
tmp=$(dirname "$0") tmp=$(dirname "$0")
tsdir=$(cd "${tmp}"; pwd) tsdir=$(cd "${tmp}"; pwd)
version_parts=3
if [ -n "${AUTOGEN_SH_SILENT}" ]; then if [ -n "${AUTOGEN_SH_SILENT}" ]; then
SILENT=" --silent" SILENT=" --silent"
@ -84,10 +85,9 @@ if test x"$1" = x"--help"; then
echo " --silent Silent operation" echo " --silent Silent operation"
echo " --force Pass --force to autoconf" echo " --force Pass --force to autoconf"
echo " --find-version Helper for configure.ac" echo " --find-version Helper for configure.ac"
echo " --git-build Run all commands to build from a Git" echo " --build-TYPE Configure to cross build for TYPE"
echo " --print-host Print only the host triplet" echo " --print-host Print only the host triplet"
echo " --print-build Print only the build platform triplet" echo " --print-build Print only the build platform triplet"
echo " --build-TYPE Configure to cross build for TYPE"
echo "" echo ""
echo " ARGS are passed to configure in --build-TYPE mode." echo " ARGS are passed to configure in --build-TYPE mode."
echo " Configuration for this script is expected in autogen.rc" echo " Configuration for this script is expected in autogen.rc"
@ -137,6 +137,8 @@ extraoptions=
# List of optional variables sourced from autogen.rc and ~/.gnupg-autogen.rc # List of optional variables sourced from autogen.rc and ~/.gnupg-autogen.rc
w32_toolprefixes= w32_toolprefixes=
w32_extraoptions= w32_extraoptions=
w32ce_toolprefixes=
w32ce_extraoptions=
w64_toolprefixes= w64_toolprefixes=
w64_extraoptions= w64_extraoptions=
amd64_toolprefixes= amd64_toolprefixes=
@ -144,6 +146,7 @@ amd64_toolprefixes=
# What follows are variables which are sourced but default to # What follows are variables which are sourced but default to
# environment variables or lacking them hardcoded values. # environment variables or lacking them hardcoded values.
#w32root= #w32root=
#w32ce_root=
#w64root= #w64root=
#amd64root= #amd64root=
@ -156,14 +159,15 @@ case "$1" in
SILENT=" --silent" SILENT=" --silent"
shift shift
;; ;;
--git-build)
myhost="git-build"
shift
;;
--build-w32) --build-w32)
myhost="w32" myhost="w32"
shift shift
;; ;;
--build-w32ce)
myhost="w32"
myhostsub="ce"
shift
;;
--build-w64) --build-w64)
myhost="w32" myhost="w32"
myhostsub="64" myhostsub="64"
@ -183,25 +187,6 @@ esac
die_p die_p
# **** GIT BUILD ****
# This is a helper to build from git.
if [ "$myhost" = "git-build" ]; then
tmp="$(pwd)"
cd "$tsdir" || fatal "error cd-ing to $tsdir"
./autogen.sh || fatal "error running ./autogen.sh"
cd "$tmp" || fatal "error cd-ing back to $tmp"
die_p
"$tsdir"/configure || fatal "error running $tsdir/configure"
die_p
make || fatal "error running make"
die_p
make check || fatal "error running make check"
die_p
exit 0
fi
# **** end GIT BUILD ****
# Source our configuration # Source our configuration
if [ -f "${tsdir}/autogen.rc" ]; then if [ -f "${tsdir}/autogen.rc" ]; then
. "${tsdir}/autogen.rc" . "${tsdir}/autogen.rc"
@ -230,38 +215,30 @@ if [ "$myhost" = "find-version" ]; then
exit 1 exit 1
fi fi
if [ -z "$micro" ]; then case "$version_parts" in
matchstr1="$package-$major.[0-9]*" 2)
matchstr2="$package-$major-base" matchstr1="$package-$major.[0-9]*"
matchstr3="" matchstr2="$package-$major-base"
vers="$major.$minor" vers="$major.$minor"
else ;;
matchstr1="$package-$major.$minor.[0-9]*" *)
matchstr2="$package-$major.[0-9]*-base" matchstr1="$package-$major.$minor.[0-9]*"
matchstr3="$package-$major-base" matchstr2="$package-$major.$minor-base"
vers="$major.$minor.$micro" vers="$major.$minor.$micro"
fi ;;
esac
beta=no beta=no
if [ -e .git ]; then if [ -e .git ]; then
ingit=yes ingit=yes
tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null) tmp=$(git describe --match "${matchstr1}" --long 2>/dev/null)
tmp=$(echo "$tmp" | sed s/^"$package"//)
if [ -n "$tmp" ]; then if [ -n "$tmp" ]; then
tmp=$(echo "$tmp" | sed s/^"$package"// \ tmp=$(echo "$tmp" | sed s/^"$package"// \
| awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}') | awk -F- '$3!=0 && $3 !~ /^beta/ {print"-beta"$3}')
else else
# (due tof "-base" in the tag we need to take the 4th field) tmp=$(git describe --match "${matchstr2}" --long 2>/dev/null \
tmp=$(git describe --match "${matchstr2}" --long 2>/dev/null) | awk -F- '$4!=0{print"-beta"$4}')
if [ -n "$tmp" ]; then
tmp=$(echo "$tmp" | sed s/^"$package"// \
| awk -F- '$4!=0 && $4 !~ /^beta/ {print"-beta"$4}')
elif [ -n "${matchstr3}" ]; then
tmp=$(git describe --match "${matchstr3}" --long 2>/dev/null)
if [ -n "$tmp" ]; then
tmp=$(echo "$tmp" | sed s/^"$package"// \
| awk -F- '$4!=0 && $4 !~ /^beta/ {print"-beta"$4}')
fi
fi
fi fi
[ -n "$tmp" ] && beta=yes [ -n "$tmp" ] && beta=yes
rev=$(git rev-parse --short HEAD | tr -d '\n\r') rev=$(git rev-parse --short HEAD | tr -d '\n\r')
@ -297,6 +274,12 @@ fi
# ****************** # ******************
if [ "$myhost" = "w32" ]; then if [ "$myhost" = "w32" ]; then
case $myhostsub in case $myhostsub in
ce)
w32root="$w32ce_root"
[ -z "$w32root" ] && w32root="$HOME/w32ce_root"
toolprefixes="$w32ce_toolprefixes arm-mingw32ce"
extraoptions="$extraoptions $w32ce_extraoptions"
;;
64) 64)
w32root="$w64root" w32root="$w64root"
[ -z "$w32root" ] && w32root="$HOME/w64root" [ -z "$w32root" ] && w32root="$HOME/w64root"
@ -484,10 +467,6 @@ EOF
EOF EOF
$CP build-aux/git-hooks/commit-msg .git/hooks/commit-msg $CP build-aux/git-hooks/commit-msg .git/hooks/commit-msg
chmod +x .git/hooks/commit-msg chmod +x .git/hooks/commit-msg
if [ x"${display_name}" != x ]; then
git config format.subjectPrefix "PATCH ${display_name}"
git config sendemail.to "${patches_to}"
fi
fi fi
fi fi

View File

@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a

1614
build-aux/config.guess vendored

File diff suppressed because it is too large Load Diff

2911
build-aux/config.sub vendored

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ scriptversion=2013-05-30.07; # UTC
# GNU General Public License for more details. # GNU General Public License for more details.
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a

View File

@ -1,68 +0,0 @@
#
# This is a sed script to patch the generated libtool,
# which works well against both of libtool 2.4.2 and 2.4.7.
#
# You may use this work under the terms of a Creative Commons CC0 1.0
# License/Waiver.
#
# CC0 Public Domain Dedication
# https://creativecommons.org/publicdomain/zero/1.0/
#
# This sed script applys two hunks of the patch:
#
# Part1: after the comment "# bleh windows"
# Part2: after the comment "#extension on DOS 8.3..."
#
# Only when those two parts are patched correctly, it exits with 0 or
# else, it exits with 1
#
# Find the part 1, by the comment
/^[ \t]*# bleh windows$/b part1_start
# Not found the part1, raise an error
$ q1
b
:part1_start
n
# The first line in the part 1 must be the begining of the case statement.
/^[ \t]*case \$host in$/! q1
n
# Insert the entry for x86_64-*mingw32*, for modified versuffix.
i\
x86_64-*mingw32*)
i\
func_arith $current - $age
i\
major=$func_arith_result
i\
versuffix="6-$major"
i\
;;
:part1_0
# Find the end of the case statement
/^[ \t]*esac$/b find_part2
# Not found the end of the case statement, raise an error
$ q1
n
b part1_0
:find_part2
/^[ \t]*# extension on DOS 8.3 file.*systems.$/b part2_process
# Not found the part2, raise an error
$ q1
n
b find_part2
:part2_process
$ q1
s/^[ \t]*\(versuffix=\)\(.*\)\(-$major\)\(.*\)$/\t case \$host in\n\t x86_64-*mingw32*)\n\t \1\26\3\4\n\t ;;\n\t *)\n\t \1\2\3\4\n\t ;;\n\t esac/
t part2_done
n
b part2_process
:part2_done
$ q0
n
b part2_done

View File

@ -24,7 +24,7 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with GNU Libtool; see the file COPYING. If not, a copy # along with GNU Libtool; see the file COPYING. If not, a copy
# can be downloaded from https://www.gnu.org/licenses/gpl.html, # can be downloaded from http://www.gnu.org/licenses/gpl.html,
# or obtained by writing to the Free Software Foundation, Inc., # or obtained by writing to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@ -75,8 +75,8 @@
# autoconf: $autoconf_version # autoconf: $autoconf_version
# #
# Report bugs to <bug-libtool@gnu.org>. # Report bugs to <bug-libtool@gnu.org>.
# GNU libtool home page: <https://www.gnu.org/software/libtool/>. # GNU libtool home page: <http://www.gnu.org/software/libtool/>.
# General help using GNU software: <https://www.gnu.org/gethelp/>. # General help using GNU software: <http://www.gnu.org/gethelp/>.
PROGRAM=libtool PROGRAM=libtool
PACKAGE=libtool PACKAGE=libtool

View File

@ -18,7 +18,7 @@ scriptversion=2010-08-21.06; # UTC
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a

View File

@ -17,7 +17,7 @@ scriptversion=2013-10-28.13; # UTC
# GNU General Public License for more details. # GNU General Public License for more details.
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you # As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a # distribute this file as part of a program that contains a
@ -103,7 +103,7 @@ fi
perl_URL=http://www.perl.org/ perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/ flex_URL=http://flex.sourceforge.net/
gnu_software_URL=https://www.gnu.org/software gnu_software_URL=http://www.gnu.org/software
program_details () program_details ()
{ {

View File

@ -20,7 +20,7 @@
% General Public License for more details. % General Public License for more details.
% %
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with this program. If not, see <https://www.gnu.org/licenses/>. % along with this program. If not, see <http://www.gnu.org/licenses/>.
% %
% As a special exception, when this file is read by TeX when processing % As a special exception, when this file is read by TeX when processing
% a Texinfo source document, you may use the result without % a Texinfo source document, you may use the result without
@ -31,7 +31,7 @@
% reports; you can get the latest version from: % reports; you can get the latest version from:
% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or % http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or
% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or % http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or
% https://www.gnu.org/software/texinfo/ (the Texinfo home page) % http://www.gnu.org/software/texinfo/ (the Texinfo home page)
% The texinfo.tex in any given distribution could well be out % The texinfo.tex in any given distribution could well be out
% of date, so if that's what you're using, please check. % of date, so if that's what you're using, please check.
% %
@ -55,7 +55,7 @@
% extent. You can get the existing language-specific files from the % extent. You can get the existing language-specific files from the
% full Texinfo distribution. % full Texinfo distribution.
% %
% The GNU Texinfo home page is https://www.gnu.org/software/texinfo. % The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
\message{Loading texinfo [version \texinfoversion]:} \message{Loading texinfo [version \texinfoversion]:}
@ -482,7 +482,7 @@
% \def\foo{\parsearg\Xfoo} % \def\foo{\parsearg\Xfoo}
% \def\Xfoo#1{...} % \def\Xfoo#1{...}
% %
% Actually, I use \csname\string\foo\endcsname, i.e. \\foo, as it is my % Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
% favourite TeX trick. --kasal, 16nov03 % favourite TeX trick. --kasal, 16nov03
\def\parseargdef#1{% \def\parseargdef#1{%

View File

@ -1,2 +0,0 @@
Configuration files may go here. Note that config.h.in is
auto-generated so that this file is not in git.

View File

@ -1,6 +1,6 @@
# configure.ac for GPGME # configure.ac for GPGME
# Copyright (C) 2000 Werner Koch (dd9jn) # Copyright (C) 2000 Werner Koch (dd9jn)
# Copyright (C) 2001-2021 g10 Code GmbH # Copyright (C) 2001-2018 g10 Code GmbH
# #
# This file is part of GPGME. # This file is part of GPGME.
# #
@ -14,90 +14,81 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
# Public License for more details. # Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU General Public License
# License along with this program; if not, see <https://gnu.org/licenses/>. # along with this program; if not, see <https://www.gnu.org/licenses/>.
# SPDX-License-Identifier: LGPL-2.1-or-later
# (Process this file with autoconf to produce a configure script.) # (Process this file with autoconf to produce a configure script.)
AC_PREREQ([2.69]) AC_PREREQ(2.59)
min_automake_version="1.14" min_automake_version="1.14"
# To build a release you need to create a tag with the version number # To build a release you need to create a tag with the version number
# "gpgme-n.m.k" and run "./autogen.sh --force". Please bump the # (git tag -s gpgme-n.m.k) and run "./autogen.sh --force". Please
# version number immediately after the release and do another commit # bump the version number immediately after the release and do another
# and push so that the git magic is able to work. If you start a new # commit and push so that the git magic is able to work. See below
# series by bumping the minor (m) remember to also create a tag named
# "gpgme-n.m-base" as the start point for beta numbering. See below
# for the LT versions. # for the LT versions.
m4_define([mym4_package],[gpgme]) m4_define(mym4_version_major, [1])
m4_define([mym4_major], [1]) m4_define(mym4_version_minor, [11])
m4_define([mym4_minor], [24]) m4_define(mym4_version_micro, [2])
m4_define([mym4_micro], [0])
# Below is m4 magic to extract and compute the git revision number, # Below is m4 magic to extract and compute the revision number, the
# the decimalized short revision number, a beta version string and a # decimalized short revision number, a beta version string, and a flag
# flag indicating a development version (mym4_isbeta). Note that the # indicating a development version (mym4_isgit). Note that the m4
# m4 processing is done by autoconf and not during the configure run. # processing is done by autoconf and not during the configure run.
m4_define([mym4_verslist], m4_split(m4_esyscmd([./autogen.sh --find-version] \ m4_define(mym4_version,
mym4_package mym4_major mym4_minor mym4_micro),[:])) [mym4_version_major.mym4_version_minor.mym4_version_micro])
m4_define([mym4_isbeta], m4_argn(2, mym4_verslist)) m4_define([mym4_revision],
m4_define([mym4_version], m4_argn(4, mym4_verslist)) m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r']))
m4_define([mym4_revision], m4_argn(7, mym4_verslist)) m4_define([mym4_revision_dec],
m4_define([mym4_revision_dec], m4_argn(8, mym4_verslist)) m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))]))
m4_esyscmd([echo ]mym4_version[>VERSION]) m4_define([mym4_betastring],
AC_INIT([mym4_package],[mym4_version],[https://bugs.gnupg.org]) m4_esyscmd_s([git describe --match 'gpgme-[0-9].*[0-9]' --long|\
awk -F- '$3!=0{print"-beta"$3}']))
m4_define([mym4_isgit],m4_if(mym4_betastring,[],[no],[yes]))
m4_define([mym4_full_version],[mym4_version[]mym4_betastring])
AC_INIT([gpgme],[mym4_full_version],[http://bugs.gnupg.org])
# LT Version numbers, remember to change them just *before* a release. # LT Version numbers, remember to change them just *before* a release.
# (Code changed: REVISION++) # (Code changed: REVISION++)
# (Interfaces added/removed/changed: CURRENT++, REVISION=0) # (Interfaces added/removed/changed: CURRENT++, REVISION=0)
# (Interfaces added: AGE++) # (Interfaces added: AGE++)
# (Interfaces removed: AGE=0) # (Interfaces removed/changed: AGE=0)
# #
LIBGPGME_LT_CURRENT=43 LIBGPGME_LT_CURRENT=31
LIBGPGME_LT_AGE=32 LIBGPGME_LT_AGE=20
LIBGPGME_LT_REVISION=1 LIBGPGME_LT_REVISION=1
# If there is an ABI break in gpgmepp or qgpgme also bump the # If there is an ABI break in gpgmepp or qgpgme also bump the
# version in IMPORTED_LOCATION in the GpgmeppConfig-w32.cmake.in.in # version in IMPORTED_LOCATION in the GpgmeppConfig-w32.cmake.in.in
LIBGPGMEPP_LT_CURRENT=26 LIBGPGMEPP_LT_CURRENT=13
LIBGPGMEPP_LT_AGE=20 LIBGPGMEPP_LT_AGE=7
LIBGPGMEPP_LT_REVISION=1 LIBGPGMEPP_LT_REVISION=0
LIBQGPGME_LT_CURRENT=20 LIBQGPGME_LT_CURRENT=10
LIBQGPGME_LT_AGE=5 LIBQGPGME_LT_AGE=3
LIBQGPGME_LT_REVISION=1 LIBQGPGME_LT_REVISION=2
################################################
AC_SUBST(LIBGPGME_LT_CURRENT)
AC_SUBST(LIBGPGME_LT_AGE)
AC_SUBST(LIBGPGME_LT_REVISION)
AC_SUBST(LIBGPGMEPP_LT_CURRENT)
AC_SUBST(LIBGPGMEPP_LT_AGE)
AC_SUBST(LIBGPGMEPP_LT_REVISION)
AC_SUBST(LIBQGPGME_LT_CURRENT)
AC_SUBST(LIBQGPGME_LT_AGE)
AC_SUBST(LIBQGPGME_LT_REVISION)
# If the API is changed in an incompatible way: increment the next counter. # If the API is changed in an incompatible way: increment the next counter.
GPGME_CONFIG_API_VERSION=1 GPGME_CONFIG_API_VERSION=1
############################################## ##############################################
NEED_GPG_ERROR_VERSION=1.47 NEED_GPG_ERROR_VERSION=1.24
NEED_LIBASSUAN_API=2 NEED_LIBASSUAN_API=2
NEED_LIBASSUAN_VERSION=2.4.2 NEED_LIBASSUAN_VERSION=2.4.2
VERSION_MAJOR=mym4_major PACKAGE=$PACKAGE_NAME
VERSION_MINOR=mym4_minor VERSION=$PACKAGE_VERSION
VERSION_MICRO=mym4_micro
VERSION_MAJOR=mym4_version_major
VERSION_MINOR=mym4_version_minor
VERSION_MICRO=mym4_version_micro
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/gpgme.h.in]) AC_CONFIG_SRCDIR(src/gpgme.h.in)
AC_CONFIG_HEADERS([conf/config.h]) AC_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip]) AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip])
AM_MAINTAINER_MODE AM_MAINTAINER_MODE
AC_CANONICAL_HOST AC_CANONICAL_HOST
@ -105,42 +96,7 @@ AM_SILENT_RULES
AC_ARG_VAR(SYSROOT,[locate config scripts also below that directory]) AC_ARG_VAR(SYSROOT,[locate config scripts also below that directory])
# Enable GNU extensions on systems that have them. # Enable GNU extensions on systems that have them.
AC_USE_SYSTEM_EXTENSIONS AC_GNU_SOURCE
# Taken from mpfr-4.0.1, then modified for LDADD_FOR_TESTS_KLUDGE
dnl Under Linux, make sure that the old dtags are used if LD_LIBRARY_PATH
dnl is defined. The issue is that with the new dtags, LD_LIBRARY_PATH has
dnl the precedence over the run path, so that if a compatible MPFR library
dnl is installed in some directory from $LD_LIBRARY_PATH, then the tested
dnl MPFR library will be this library instead of the MPFR library from the
dnl build tree. Other OS with the same issue might be added later.
dnl
dnl References:
dnl https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=859732
dnl http://lists.gnu.org/archive/html/libtool/2017-05/msg00000.html
dnl
dnl We need to check whether --disable-new-dtags is supported as alternate
dnl linkers may be used (e.g., with tcc: CC=tcc LD=tcc).
dnl
case $host in
*-*-linux*)
if test -n "$LD_LIBRARY_PATH"; then
saved_LDFLAGS="$LDFLAGS"
LDADD_FOR_TESTS_KLUDGE="-Wl,--disable-new-dtags"
LDFLAGS="$LDFLAGS $LDADD_FOR_TESTS_KLUDGE"
AC_MSG_CHECKING(whether --disable-new-dtags is supported by the linker)
AC_LINK_IFELSE([AC_LANG_SOURCE([[
int main (void) { return 0; }
]])],
[AC_MSG_RESULT(yes (use it since LD_LIBRARY_PATH is set))],
[AC_MSG_RESULT(no)
LDADD_FOR_TESTS_KLUDGE=""
])
LDFLAGS="$saved_LDFLAGS"
fi
;;
esac
AC_SUBST([LDADD_FOR_TESTS_KLUDGE])
AH_VERBATIM([_REENTRANT], AH_VERBATIM([_REENTRANT],
[/* To allow the use of GPGME in multithreaded programs we have to use [/* To allow the use of GPGME in multithreaded programs we have to use
@ -158,12 +114,25 @@ AC_PROG_CXX
# Note: A suitable gitlog-to-changelog script can be found in GnuPG master. # Note: A suitable gitlog-to-changelog script can be found in GnuPG master.
AC_CHECK_PROGS(GITLOG_TO_CHANGELOG, gitlog-to-changelog, [gitlog-to-changelog]) AC_CHECK_PROGS(GITLOG_TO_CHANGELOG, gitlog-to-changelog, [gitlog-to-changelog])
AC_SUBST(LIBGPGME_LT_CURRENT)
AC_SUBST(LIBGPGME_LT_AGE)
AC_SUBST(LIBGPGME_LT_REVISION)
AC_SUBST(LIBGPGMEPP_LT_CURRENT)
AC_SUBST(LIBGPGMEPP_LT_AGE)
AC_SUBST(LIBGPGMEPP_LT_REVISION)
AC_SUBST(LIBQGPGME_LT_CURRENT)
AC_SUBST(LIBQGPGME_LT_AGE)
AC_SUBST(LIBQGPGME_LT_REVISION)
AC_SUBST(PACKAGE)
AC_SUBST(VERSION)
AC_SUBST(VERSION_MAJOR) AC_SUBST(VERSION_MAJOR)
AC_SUBST(VERSION_MINOR) AC_SUBST(VERSION_MINOR)
AC_SUBST(VERSION_MICRO) AC_SUBST(VERSION_MICRO)
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package])
VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x%02x" mym4_major \ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package])
mym4_minor mym4_micro) VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x%02x" mym4_version_major \
mym4_version_minor mym4_version_micro)
AC_SUBST(VERSION_NUMBER) AC_SUBST(VERSION_NUMBER)
# We need to compile and run a program on the build machine. A # We need to compile and run a program on the build machine. A
@ -198,7 +167,7 @@ case "${host}" in
have_ld_version_script=yes have_ld_version_script=yes
;; ;;
*-apple-darwin*) *-apple-darwin*)
AC_DEFINE(_DARWIN_C_SOURCE, 1, AC_DEFINE(_DARWIN_C_SOURCE, 900000L,
Expose all libc features (__DARWIN_C_FULL).) Expose all libc features (__DARWIN_C_FULL).)
AC_DEFINE(_XOPEN_SOURCE, 500, Activate POSIX interface on MacOS X) AC_DEFINE(_XOPEN_SOURCE, 500, Activate POSIX interface on MacOS X)
;; ;;
@ -206,44 +175,6 @@ esac
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
#
# Specify how we support our local modification of libtool for Windows
# 64-bit. Options are:
#
# (1) apply: when appying patch fails, it results failure of entire build
# (2) never: never apply the patch (no try)
# (3) try: use patched if it goes well, use original if fails
#
AC_ARG_WITH([libtool-modification],
AS_HELP_STRING([--with-libtool-modification=apply|never|try],
[how to handle libtool modification (default=never)]),
build_libtool_modification=$withval,
build_libtool_modification=never)
#
# Apply a patch (locally maintained one of ours) to libtool
#
case $host in
x86_64-*mingw32*)
AC_CONFIG_COMMANDS([libtool-patch],[[
if test "$build_selection" = never; then
echo "patch not applied"
elif (mv -f libtool libtool.orig; \
sed -f $srcdir/build-aux/libtool-patch.sed libtool.orig >libtool); then
echo "applied successfully"
elif test "$build_selection" = try; then
mv -f libtool.orig libtool
echo "patch failed, thus, using original"
else
echo "patch failed"
as_fn_exit 1
fi
]],[build_selection=$build_libtool_modification])
;;
*)
;;
esac
GPG_DEFAULT=no GPG_DEFAULT=no
GPGSM_DEFAULT=no GPGSM_DEFAULT=no
GPGCONF_DEFAULT=no GPGCONF_DEFAULT=no
@ -256,12 +187,15 @@ have_w64_system=no
have_macos_system=no have_macos_system=no
build_w32_glib=no build_w32_glib=no
build_w32_qt=no build_w32_qt=no
available_languages="cl cpp python qt qt5 qt6" available_languages="cl cpp python python2 python3 qt"
default_languages="cl cpp python qt5 qt6" default_languages="cl cpp python qt"
case "${host}" in case "${host}" in
x86_64-*mingw32*) x86_64-*mingw32*)
have_w64_system=yes have_w64_system=yes
;; ;;
*-mingw32ce*)
have_w32ce_system=yes
;;
*-linux-androideabi) *-linux-androideabi)
have_android_system=yes have_android_system=yes
;; ;;
@ -270,7 +204,7 @@ case "${host}" in
;; ;;
esac esac
case "${host}" in case "${host}" in
*-mingw32*) *-mingw32ce*|*-mingw32*)
have_dosish_system=yes have_dosish_system=yes
have_w32_system=yes have_w32_system=yes
GPG_DEFAULT='c:\\gnupg\\gpg.exe' GPG_DEFAULT='c:\\gnupg\\gpg.exe'
@ -281,7 +215,7 @@ case "${host}" in
AM_PATH_GLIB_2_0 AM_PATH_GLIB_2_0
AC_ARG_ENABLE(w32-glib, AC_ARG_ENABLE(w32-glib,
AS_HELP_STRING([--enable-w32-glib],[build GPGME Glib for W32]), AC_HELP_STRING([--enable-w32-glib], [build GPGME Glib for W32]),
build_w32_glib=$enableval) build_w32_glib=$enableval)
;; ;;
*) *)
@ -314,6 +248,12 @@ if test "$have_w64_system" = yes; then
fi fi
AM_CONDITIONAL(HAVE_W64_SYSTEM, test "$have_w64_system" = yes) AM_CONDITIONAL(HAVE_W64_SYSTEM, test "$have_w64_system" = yes)
if test "$have_w32ce_system" = yes; then
AC_DEFINE(HAVE_W32CE_SYSTEM,1,
[Defined if we run on a W32 CE API based system])
fi
AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes)
if test "$have_android_system" = yes; then if test "$have_android_system" = yes; then
AC_DEFINE(HAVE_ANDROID_SYSTEM,1, [Defined if we build for an Android system]) AC_DEFINE(HAVE_ANDROID_SYSTEM,1, [Defined if we build for an Android system])
fi fi
@ -329,7 +269,7 @@ AM_CONDITIONAL(BUILD_W32_GLIB, test "$build_w32_glib" = yes)
AC_ARG_ENABLE([fixed-path], AC_ARG_ENABLE([fixed-path],
AS_HELP_STRING([--enable-fixed-path=PATH], AC_HELP_STRING([--enable-fixed-path=PATH],
[locate binaries only via this PATH]), [locate binaries only via this PATH]),
[fixed_search_path="$enableval"], [fixed_search_path="$enableval"],
[fixed_search_path=""]) [fixed_search_path=""])
@ -338,44 +278,12 @@ if test x$fixed_search_path != x ; then
[Locate binaries only via this PATH]) [Locate binaries only via this PATH])
fi fi
# Option --enable-reduce-relocations
#
# Allow building the Qt 6 bindings explicitly with -fPIC if the automatic
# detection fails. Note: We assume that this flag is always available (unless
# we built for Windows).
AC_ARG_ENABLE([reduce-relocations],
AS_HELP_STRING([--enable-reduce-relocations],
[build Qt 6 bindings with -fPIC (default is
auto)]),
[use_reduce_relocations="$enableval"],
[use_reduce_relocations=""])
# Option --enable-no-direct-extern-access
#
# Some distributions build Qt 6 with -mno-direct-extern-access. Libraries and
# applications using Qt then must also be build with this flag. As workaround
# for a bug in Qt's pkgconfig files which don't have this flag we allow
# building with this flag explicitly.
AC_LANG_PUSH(C++)
AX_CHECK_COMPILE_FLAG([-mno-direct-extern-access],
[have_no_direct_extern_access="yes"],
[have_no_direct_extern_access="no"],
[-Werror])
AC_LANG_POP()
AC_ARG_ENABLE([no-direct-extern-access],
AS_HELP_STRING([--enable-no-direct-extern-access],
[build Qt 6 bindings with
-mno-direct-extern-access (default is auto)]),
[use_no_direct_extern_access="$enableval"],
[use_no_direct_extern_access=""])
# Note: You need to declare all possible languages also in # Note: You need to declare all possible languages also in
# lang/Makefile.am's DIST_SUBDIRS. # lang/Makefile.am's DIST_SUBDIRS.
AC_ARG_ENABLE([languages], AC_ARG_ENABLE([languages],
AS_HELP_STRING([--enable-languages=languages], AC_HELP_STRING([--enable-languages=languages],
[enable only specific language bindings: [enable only specific language bindings]),
cl cpp python qt5 qt6]),
[enabled_languages=`echo $enableval | \ [enabled_languages=`echo $enableval | \
tr ',:' ' ' | tr '[A-Z]' '[a-z]' | \ tr ',:' ' ' | tr '[A-Z]' '[a-z]' | \
sed 's/c++/cpp/'`], sed 's/c++/cpp/'`],
@ -401,182 +309,69 @@ for language in $enabled_languages; do
fi fi
done done
# Check whether qt5 and/or qt6 are enabled
want_qt5="no"
LIST_MEMBER("qt5", $enabled_languages)
if test "$found" = "1"; then
if test "$explicit_languages" = "1"; then
want_qt5="yes"
else
want_qt5="maybe"
fi
# Remove qt5; further down qt will be added
enabled_languages=$(echo $enabled_languages | sed 's/qt5//')
fi
want_qt6="no"
LIST_MEMBER("qt6", $enabled_languages)
if test "$found" = "1"; then
if test "$explicit_languages" = "1"; then
want_qt6="yes"
else
want_qt6="maybe"
fi
# Remove qt6; further down qt will be added
enabled_languages=$(echo $enabled_languages | sed 's/qt6//')
fi
# Check whether qt is enabled; if yes then it has been enabled explicitly
want_qt="no"
LIST_MEMBER("qt", $enabled_languages)
if test "$found" = "1"; then
# Ignore qt if specified together with qt5 or qt6
if test "$want_qt5" = "no" -a "$want_qt6" = "no"; then
want_qt="yes"
fi
# Remove qt
enabled_languages=$(echo $enabled_languages | sed 's/qt//')
AC_MSG_WARN([[
***
*** Language binding "qt" is deprecated and will be removed in a future version.
*** Use "qt5" and/or "qt6" instead.
***]])
fi
# Ensure that pkg-config is available for all calls of FIND_QT5/FIND_QT6 # Enable C++ 11 if cpp language is requested
PKG_PROG_PKG_CONFIG
# Check for Qt 5 (if qt5 or qt is enabled)
if test "$want_qt" = "yes"; then
want_qt5="maybe"
fi
if test "$want_qt5" != "no"; then
FIND_QT5
if test "$have_qt5_libs" = "yes"; then
want_qt5="yes"
elif test "$want_qt5" = "yes"; then
AC_MSG_ERROR([[
***
*** Qt5 (Qt5Core) is required for the Qt 5 binding.
***]])
else
want_qt5="no"
fi
fi
# Check for Qt 6 (if qt6 is enabled or if qt is enabled and Qt 5 wasn't found)
if test "$want_qt" = "yes" -a "$have_qt5_libs" != "yes"; then
want_qt6="maybe"
fi
if test "$want_qt6" != "no"; then
FIND_QT6
if test "$have_qt6_libs" = "yes"; then
want_qt6="yes";
elif test "$want_qt6" = "yes"; then
AC_MSG_ERROR([[
***
*** Qt6 (Qt6Core) is required for the Qt 6 binding.
***]])
else
want_qt6="no"
fi
fi
# Check if any Qt was found (if qt is enabled)
if test "$want_qt" = "yes" -a "$have_qt5_libs" != "yes" -a "$have_qt6_libs" != "yes"; then
AC_MSG_ERROR([[
***
*** Qt5 (Qt5Core) or Qt6 (Qt6Core) is required for the Qt bindings.
***]])
fi
# Check that cpp is enabled if qt5 or qt6 is enabled and was found
if test "$want_qt5" = "yes" -o "$want_qt6" = "yes"; then
LIST_MEMBER("cpp", $enabled_languages)
if test "$found" = "0"; then
AC_MSG_ERROR([[
***
*** The Qt bindings depend on the C++ binding.
***]])
fi
fi
# Enable C++ 17 if qt6 is requested
if test "$want_qt6" = "yes"; then
AX_CXX_COMPILE_STDCXX(17, noext, optional)
if test "$HAVE_CXX17" != "1"; then
if test "$explicit_languages" = "1"; then
AC_MSG_ERROR([[
***
*** A compiler with c++17 support is required for the Qt 6 binding.
***]])
else
want_qt6="no"
AC_MSG_WARN([[
***
*** No c++17 support detected. Qt 6 binding will be disabled.
***]])
fi
fi
fi
# Enable C++ 11 if cpp is requested (unless C++ 17 was already enabled)
LIST_MEMBER("cpp", $enabled_languages) LIST_MEMBER("cpp", $enabled_languages)
if test "$found" = "1" -a "$HAVE_CXX17" != "1"; then if test "$found" = "1"; then
AX_CXX_COMPILE_STDCXX(11, noext, optional) AX_CXX_COMPILE_STDCXX(11, noext, optional)
if test "$HAVE_CXX11" != "1"; then if test "$HAVE_CXX11" != "1"; then
if test "$explicit_languages" = "1"; then if test "$explicit_languages" = "1"; then
AC_MSG_ERROR([[ AC_MSG_ERROR([[
*** ***
*** A compiler with c++11 support is required for the C++ binding. *** A compiler with c++11 support is required for the c++ binding.
***]]) ***]])
else else
enabled_languages=$(echo $enabled_languages | sed 's/cpp//') enabled_languages=$(echo $enabled_languages | sed 's/cpp//')
want_qt5="no" enabled_languages=$(echo $enabled_languages | sed 's/qt//')
AC_MSG_WARN([[ AC_MSG_WARN([[
*** ***
*** No c++11 support detected. C++ and Qt 5 bindings will be disabled. *** No c++11 support detected. C++ and Qt bindings will be disabled.
***]]) ***]])
fi fi
fi fi
fi fi
# Now append qt to the list of language bindings (to enable the subdir in lang) # Check that if qt is enabled cpp also is enabled
if test "$want_qt5" = "yes" -o "$want_qt6" = "yes"; then LIST_MEMBER("qt", $enabled_languages)
enabled_languages=$(echo $enabled_languages qt)
fi
# Check whether compiler supports visibility attribute (if cpp language is enabled)
LIST_MEMBER("cpp", $enabled_languages)
if test "$found" = "1"; then if test "$found" = "1"; then
AX_GCC_FUNC_ATTRIBUTE(visibility) # We need to ensure that in the language order qt comes after cpp
if test "$ax_cv_have_func_attribute_visibility" = "yes"; then # so we remove qt first and explicitly add it as last list member.
GPGME_CPP_CFLAGS="$GPGME_CPP_CFLAGS -fvisibility=hidden" enabled_languages=$(echo $enabled_languages | sed 's/qt//')
if test "$want_qt5" = "yes"; then LIST_MEMBER("cpp", $enabled_languages)
GPGME_QT5_CFLAGS="$GPGME_QT5_CFLAGS -fvisibility=hidden" if test "$found" = "0"; then
AC_MSG_ERROR([[
***
*** Qt language binding depends on cpp binding.
***]])
fi
FIND_QT
if test "$have_qt5_libs" != "yes"; then
if test "$explicit_languages" = "1"; then
AC_MSG_ERROR([[
***
*** Qt5 (Qt5Core) is required for Qt binding.
***]])
else
AC_MSG_WARN([[
***
*** Qt5 (Qt5Core) not found Qt Binding will be disabled.
***]])
fi fi
if test "$want_qt6" = "yes"; then else
GPGME_QT6_CFLAGS="$GPGME_QT6_CFLAGS -fvisibility=hidden" enabled_languages=`echo $enabled_languages qt`
AC_CHECK_PROGS([DOXYGEN], [doxygen])
if test -z "$DOXYGEN";
# This is not highlighted becase it's not really important.
then AC_MSG_WARN([Doxygen not found - Qt binding doc will not be built.])
fi
AC_CHECK_PROGS([GRAPHVIZ], [dot])
if test -z "$GRAPHVIZ";
then AC_MSG_WARN([Graphviz not found - Qt binding doc will not have diagrams.])
fi fi
fi fi
fi fi
AC_SUBST(GPGME_CPP_CFLAGS)
AM_CONDITIONAL(WANT_QT5, test "$want_qt5" = yes)
AM_CONDITIONAL(WANT_QT6, test "$want_qt6" = yes)
# Check for tools for building the Qt binding docs
if test "$want_qt5" = "yes" -o "$want_qt6" = "yes"; then
AC_CHECK_PROGS([DOXYGEN], [doxygen])
if test -z "$DOXYGEN"; then
# This is not highlighted because it's not really important.
AC_MSG_WARN([Doxygen not found - Qt binding doc will not be built.])
fi
AC_CHECK_PROGS([GRAPHVIZ], [dot])
if test -z "$GRAPHVIZ"; then
AC_MSG_WARN([Graphviz not found - Qt binding doc will not have diagrams.])
fi
fi
AM_CONDITIONAL([HAVE_DOXYGEN], AM_CONDITIONAL([HAVE_DOXYGEN],
[test -n "$DOXYGEN"]) [test -n "$DOXYGEN"])
if test -n "$GRAPHVIZ"; then if test -n "$GRAPHVIZ"; then
@ -587,9 +382,13 @@ fi
AC_SUBST(HAVE_DOT) AC_SUBST(HAVE_DOT)
# Python bindings. # Python bindings.
LIST_MEMBER("python2", $enabled_languages)
found_py2=$found
LIST_MEMBER("python3", $enabled_languages)
found_py3=$found
LIST_MEMBER("python", $enabled_languages) LIST_MEMBER("python", $enabled_languages)
found_py=$found found_py=$found
if test "$found_py" = "1"; then if test "$found_py" = "1" -o "$found_py2" = "1" -o "$found_py3" = "1"; then
AX_PKG_SWIG AX_PKG_SWIG
if test -z "$SWIG"; then if test -z "$SWIG"; then
if test "$explicit_languages" = "1"; then if test "$explicit_languages" = "1"; then
@ -601,19 +400,39 @@ if test "$found_py" = "1"; then
enabled_languages=$(echo $enabled_languages | sed 's/python//') enabled_languages=$(echo $enabled_languages | sed 's/python//')
fi fi
else else
# Reset the version collecting vars. # Reset all the stuff, just to be sure.
PYTHONS= PYTHONS=
PYTHON_VERSIONS= PYTHON_VERSIONS=
unset PYTHON
unset PYTHON_VERSION
unset PYTHON_CPPFLAGS
unset PYTHON_LDFLAGS
unset PYTHON_SITE_PKG
unset PYTHON_EXTRA_LIBS
unset PYTHON_EXTRA_LDFLAGS
unset ac_cv_path_PYTHON
unset am_cv_pathless_PYTHON
unset am_cv_python_version
unset am_cv_python_platform
unset am_cv_python_pythondir
unset am_cv_python_pyexecdir
if test "$found_py" = "1" -o "$found_py2" = "1"; then
AM_PATH_PYTHON([2.7], [
AX_PYTHON_DEVEL
if test "$PYTHON_VERSION"; then
PYTHONS="$(echo $PYTHONS $PYTHON)"
PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
fi
], :)
fi
if test "$found_py" = "1" -o "$found_py3" = "1"; then if test "$found_py" = "1" -o "$found_py3" = "1"; then
# Reset everything, so that we can look for another Python. # Reset everything, so that we can look for another Python.
m4_foreach([mym4pythonver], unset PYTHON
[[2.7],[3.6],[3.8],[3.9],[3.10],[3.11],[3.12],[all]],
[unset PYTHON
unset PYTHON_VERSION unset PYTHON_VERSION
unset PYTHON_CPPFLAGS unset PYTHON_CPPFLAGS
unset PYTHON_LDFLAGS unset PYTHON_LDFLAGS
unset PYTHON_LIBS
unset PYTHON_SITE_PKG unset PYTHON_SITE_PKG
unset PYTHON_EXTRA_LIBS unset PYTHON_EXTRA_LIBS
unset PYTHON_EXTRA_LDFLAGS unset PYTHON_EXTRA_LDFLAGS
@ -623,14 +442,13 @@ if test "$found_py" = "1"; then
unset am_cv_python_platform unset am_cv_python_platform
unset am_cv_python_pythondir unset am_cv_python_pythondir
unset am_cv_python_pyexecdir unset am_cv_python_pyexecdir
AM_PATH_PYTHON(mym4pythonver, [ AM_PATH_PYTHON([3.4], [
AX_PYTHON_DEVEL([], [true]) AX_PYTHON_DEVEL
if test "$PYTHON_VERSION"; then if test "$PYTHON_VERSION"; then
PYTHONS="$(echo $PYTHONS $PYTHON)" PYTHONS="$(echo $PYTHONS $PYTHON)"
PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)" PYTHON_VERSIONS="$(echo $PYTHON_VERSIONS $PYTHON_VERSION)"
fi fi
], :, m4_if([mym4pythonver],[all],[],[python]mym4pythonver)) ], :)
])
fi fi
# Recover some values lost in the second attempt to find Python. # Recover some values lost in the second attempt to find Python.
@ -670,15 +488,13 @@ AC_DEFINE_UNQUOTED(BUILD_REVISION, "$BUILD_REVISION",
[GIT commit id revision used to build this package]) [GIT commit id revision used to build this package])
changequote(,)dnl changequote(,)dnl
BUILD_VERSION=`echo "$PACKAGE_VERSION" | sed 's/\([0-9.]*\).*/\1./'` BUILD_FILEVERSION=`echo "$PACKAGE_VERSION"|sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
changequote([,])dnl changequote([,])dnl
BUILD_VERSION="${BUILD_VERSION}mym4_revision_dec" BUILD_FILEVERSION="${BUILD_FILEVERSION}mym4_revision_dec"
BUILD_FILEVERSION=`echo "${BUILD_VERSION}" | tr . ,`
AC_SUBST(BUILD_VERSION)
AC_SUBST(BUILD_FILEVERSION) AC_SUBST(BUILD_FILEVERSION)
AC_ARG_ENABLE([build-timestamp], AC_ARG_ENABLE([build-timestamp],
AS_HELP_STRING([--enable-build-timestamp], AC_HELP_STRING([--enable-build-timestamp],
[set an explicit build timestamp for reproducibility. [set an explicit build timestamp for reproducibility.
(default is the current time in ISO-8601 format)]), (default is the current time in ISO-8601 format)]),
[if test "$enableval" = "yes"; then [if test "$enableval" = "yes"; then
@ -697,51 +513,41 @@ AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP",
# #
run_gpgconf_test="yes" run_gpgconf_test="yes"
AC_ARG_ENABLE(gpgconf-test, AC_ARG_ENABLE(gpgconf-test,
AS_HELP_STRING([--disable-gpgconf-test],[disable GPGCONF regression test]), AC_HELP_STRING([--disable-gpgconf-test], [disable GPGCONF regression test]),
run_gpgconf_test=$enableval) run_gpgconf_test=$enableval)
AM_CONDITIONAL(RUN_GPGCONF_TESTS, test "$run_gpgconf_test" = "yes") AM_CONDITIONAL(RUN_GPGCONF_TESTS, test "$run_gpgconf_test" = "yes")
run_gpg_test="yes" run_gpg_test="yes"
AC_ARG_ENABLE(gpg-test, AC_ARG_ENABLE(gpg-test,
AS_HELP_STRING([--disable-gpg-test],[disable GPG regression test]), AC_HELP_STRING([--disable-gpg-test], [disable GPG regression test]),
run_gpg_test=$enableval) run_gpg_test=$enableval)
AM_CONDITIONAL(RUN_GPG_TESTS, test "$run_gpg_test" = "yes") AM_CONDITIONAL(RUN_GPG_TESTS, test "$run_gpg_test" = "yes")
run_gpgsm_test="yes" run_gpgsm_test="yes"
AC_ARG_ENABLE(gpgsm-test, AC_ARG_ENABLE(gpgsm-test,
AS_HELP_STRING([--disable-gpgsm-test],[disable GPGSM regression test]), AC_HELP_STRING([--disable-gpgsm-test], [disable GPGSM regression test]),
run_gpgsm_test=$enableval) run_gpgsm_test=$enableval)
AM_CONDITIONAL(RUN_GPGSM_TESTS, test "$run_gpgsm_test" = "yes") AM_CONDITIONAL(RUN_GPGSM_TESTS, test "$run_gpgsm_test" = "yes")
run_g13_test="yes" run_g13_test="yes"
AC_ARG_ENABLE(g13-test, AC_ARG_ENABLE(g13-test,
AS_HELP_STRING([--disable-g13-test],[disable G13 regression test]), AC_HELP_STRING([--disable-g13-test], [disable G13 regression test]),
run_g13_test=$enableval) run_g13_test=$enableval)
AM_CONDITIONAL(RUN_G13_TESTS, test "$run_g13_test" = "yes") AM_CONDITIONAL(RUN_G13_TESTS, test "$run_g13_test" = "yes")
# Checks for header files. # Checks for header files.
AC_CHECK_HEADERS_ONCE([locale.h sys/select.h sys/uio.h argp.h stdint.h AC_CHECK_HEADERS_ONCE([locale.h sys/select.h sys/uio.h argp.h
unistd.h poll.h sys/time.h sys/types.h sys/stat.h]) unistd.h sys/time.h sys/types.h sys/stat.h])
# Type checks. # Type checks.
AC_C_INLINE AC_C_INLINE
AC_C_FLEXIBLE_ARRAY_MEMBER
AC_CHECK_SIZEOF(unsigned int) AC_CHECK_SIZEOF(unsigned int)
AC_SYS_LARGEFILE AC_SYS_LARGEFILE
AC_TYPE_OFF_T AC_TYPE_OFF_T
AC_TYPE_UINTPTR_T AC_TYPE_UINTPTR_T
# We require uint64_t
if test "$ac_cv_header_stdint_h" != yes; then
AC_MSG_ERROR([[
***
*** No stdint.h and thus no uint64_t type. Can't build this library.
***]])
fi
# A simple compile time check in gpgme.h for GNU/Linux systems that # A simple compile time check in gpgme.h for GNU/Linux systems that
# prevents a file offset bits mismatch between gpgme and the application. # prevents a file offset bits mismatch between gpgme and the application.
NEED__FILE_OFFSET_BITS=0 NEED__FILE_OFFSET_BITS=0
@ -786,30 +592,24 @@ AM_SUBST_NOTMAKE(API__SSIZE_T)
# Checks for compiler features. # Checks for compiler features.
if test "$GCC" = yes; then if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
CFLAGS="$CFLAGS -Wno-format-y2k"
# If -Wno-missing-field-initializers is supported we can expect a
# a larger set of warning options.
AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers])
_gcc_cflags_save=$CFLAGS
CFLAGS="-Wno-missing-field-initializers"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no)
AC_MSG_RESULT($_gcc_wopt)
CFLAGS=$_gcc_cflags_save;
if test x"$_gcc_wopt" = xyes ; then
CFLAGS="$CFLAGS -Wno-missing-field-initializers"
CFLAGS="$CFLAGS -Wno-sign-compare"
CFLAGS="$CFLAGS -Wno-format-zero-length"
CFLAGS="$CFLAGS -Wno-format-truncation"
CFLAGS="$CFLAGS -Wno-sizeof-pointer-div"
fi
if test "$USE_MAINTAINER_MODE" = "yes"; then if test "$USE_MAINTAINER_MODE" = "yes"; then
CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security"
# If -Wno-missing-field-initializers is supported we can enable a
# a bunch of really useful warnings.
AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers])
_gcc_cflags_save=$CFLAGS
CFLAGS="-Wno-missing-field-initializers"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no)
AC_MSG_RESULT($_gcc_wopt)
CFLAGS=$_gcc_cflags_save;
if test x"$_gcc_wopt" = xyes ; then if test x"$_gcc_wopt" = xyes ; then
CFLAGS="$CFLAGS -W -Wextra -Wbad-function-cast" CFLAGS="$CFLAGS -W -Wextra -Wbad-function-cast"
CFLAGS="$CFLAGS -Wwrite-strings" CFLAGS="$CFLAGS -Wwrite-strings"
CFLAGS="$CFLAGS -Wdeclaration-after-statement" CFLAGS="$CFLAGS -Wdeclaration-after-statement"
CFLAGS="$CFLAGS -Wno-missing-field-initializers"
CFLAGS="$CFLAGS -Wno-sign-compare"
fi fi
CFLAGS="$CFLAGS -Wformat -Wformat-security"
CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wno-shadow" CXXFLAGS="$CXXFLAGS -Wall -Wextra -Wno-shadow"
AC_MSG_CHECKING([if gcc supports -Wpointer-arith]) AC_MSG_CHECKING([if gcc supports -Wpointer-arith])
@ -890,9 +690,6 @@ AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION",
AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME, AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME,
[The default error source for GPGME.]) [The default error source for GPGME.])
AM_CONDITIONAL(USE_GPGRT_CONFIG, [test -n "$GPGRT_CONFIG" \
-a "$ac_cv_path_GPG_ERROR_CONFIG" = no])
# And for libassuan. # And for libassuan.
have_libassuan=no have_libassuan=no
AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION", AM_PATH_LIBASSUAN("$NEED_LIBASSUAN_API:$NEED_LIBASSUAN_VERSION",
@ -908,7 +705,7 @@ fi
# #
# Check for getgid etc # Check for getgid etc
AC_CHECK_FUNCS(getgid getegid closefrom nanosleep) AC_CHECK_FUNCS(getgid getegid closefrom)
# Replacement functions. # Replacement functions.
@ -938,7 +735,7 @@ AC_CHECK_MEMBER(struct cmsghdr.cmsg_len,
use_descriptor_passing=yes use_descriptor_passing=yes
AC_ARG_ENABLE(fd-passing, AC_ARG_ENABLE(fd-passing,
AS_HELP_STRING([--disable-fd-passing],[do not use FD passing]), AC_HELP_STRING([--disable-fd-passing], [do not use FD passing]),
use_descriptor_passing=$enableval) use_descriptor_passing=$enableval)
if test "$supports_descriptor_passing" != "yes"; then if test "$supports_descriptor_passing" != "yes"; then
@ -970,7 +767,7 @@ AM_CONDITIONAL(HAVE_UISERVER, test "$uiserver" != "no")
# before an exec. This option allows to switch this optimization off. # before an exec. This option allows to switch this optimization off.
use_linux_getdents=yes use_linux_getdents=yes
AC_ARG_ENABLE(linux-getdents, AC_ARG_ENABLE(linux-getdents,
AS_HELP_STRING([--disable-linux-getdents], AC_HELP_STRING([--disable-linux-getdents],
[do not use SYS_getdents on Linux]), [do not use SYS_getdents on Linux]),
use_linux_getdents=$enableval) use_linux_getdents=$enableval)
if test "$use_linux_getdents" = "yes"; then if test "$use_linux_getdents" = "yes"; then
@ -1008,56 +805,19 @@ AH_BOTTOM([
# define GPGME_GCC_A_PURE # define GPGME_GCC_A_PURE
#endif #endif
/* Under Windows we use the gettext code from gpgrt. */
#define GPG_ERR_ENABLE_GETTEXT_MACROS 1
/* Under WindowsCE we need gpg-error's strerror macro. */ /* Under WindowsCE we need gpg-error's strerror macro. */
#define GPG_ERR_ENABLE_ERRNO_MACROS 1 #define GPG_ERR_ENABLE_ERRNO_MACROS 1
#define CRIGHTBLURB "Copyright (C) 2000 Werner Koch\n" \ #define CRIGHTBLURB "Copyright (C) 2000 Werner Koch\n" \
"Copyright (C) 2001--2021 g10 Code GmbH\n" "Copyright (C) 2001--2018 g10 Code GmbH\n"
]) ])
# Substitution used for gpgme-config and gpgme.pc # Substitution used for gpgme-config
GPGME_CONFIG_LIBS="-lgpgme" GPGME_CONFIG_LIBS="-lgpgme"
GPGME_CONFIG_CFLAGS="" GPGME_CONFIG_CFLAGS=""
GPGME_CONFIG_HOST="$host" GPGME_CONFIG_HOST="$host"
GPGME_CONFIG_AVAIL_LANG="$enabled_languages" GPGME_CONFIG_AVAIL_LANG="$enabled_languages"
case "$includedir" in
/usr/include|/include) ;;
'${prefix}/include')
if test "$prefix" != / -a "$prefix" != /usr; then
if test -z "$GPGME_CONFIG_CFLAGS"; then
GPGME_CONFIG_CFLAGS="-I\${includedir}"
else
GPGME_CONFIG_CFLAGS="-I\${includedir} $GPGME_CONFIG_CFLAGS"
fi
fi
;;
*)
if test -z "$GPGME_CONFIG_CFLAGS"; then
GPGME_CONFIG_CFLAGS="-I\${includedir}"
else
GPGME_CONFIG_CFLAGS="-I\${includedir} $GPGME_CONFIG_CFLAGS"
fi
;;
esac
case "$libdir" in
/usr/lib|/usr/lib64|/lib|/lib64) ;;
'${exec_prefix}/lib'|'${exec_prefix}/lib64')
if test "$exec_prefix" = "NONE"; then
if test "$prefix" != / -a "$prefix" != /usr; then
GPGME_CONFIG_LIBS="-L\${libdir} $GPGME_CONFIG_LIBS"
fi
elif test "$exec_prefix" != / -a "$exec_prefix" != /usr; then
GPGME_CONFIG_LIBS="-L\${libdir} $GPGME_CONFIG_LIBS"
fi
;;
*) GPGME_CONFIG_LIBS="-L\${libdir} $GPGME_CONFIG_LIBS" ;;
esac
AC_SUBST(GPGME_CONFIG_API_VERSION) AC_SUBST(GPGME_CONFIG_API_VERSION)
AC_SUBST(GPGME_CONFIG_LIBS) AC_SUBST(GPGME_CONFIG_LIBS)
AC_SUBST(GPGME_CONFIG_CFLAGS) AC_SUBST(GPGME_CONFIG_CFLAGS)
@ -1090,7 +850,7 @@ if test "$have_gpg_error" = "no"; then
*** ***
*** You need libgpg-error to build this program. *** You need libgpg-error to build this program.
** This library is for example available at ** This library is for example available at
*** https://www.gnupg.org/ftp/gcrypt/libgpg-error/ *** ftp://ftp.gnupg.org/gcrypt/libgpg-error
*** (at least version $NEED_GPG_ERROR_VERSION is required.) *** (at least version $NEED_GPG_ERROR_VERSION is required.)
***]]) ***]])
fi fi
@ -1100,7 +860,7 @@ if test "$have_libassuan" = "no"; then
*** ***
*** You need libassuan to build this program. *** You need libassuan to build this program.
*** This library is for example available at *** This library is for example available at
*** https://www.gnupg.org/ftp/gcrypt/libassuan/ *** ftp://ftp.gnupg.org/gcrypt/libassuan/
*** (at least version $NEED_LIBASSUAN_VERSION (API $NEED_LIBASSUAN_API) is required). *** (at least version $NEED_LIBASSUAN_VERSION (API $NEED_LIBASSUAN_API) is required).
***]]) ***]])
fi fi
@ -1122,30 +882,19 @@ AC_CONFIG_FILES(Makefile src/Makefile
tests/gpg/Makefile tests/gpg/Makefile
tests/gpgsm/Makefile tests/gpgsm/Makefile
tests/opassuan/Makefile tests/opassuan/Makefile
tests/json/Makefile
doc/Makefile doc/Makefile
src/versioninfo.rc src/versioninfo.rc
src/gpgme.pc
src/gpgme-glib.pc
src/gpgme.h) src/gpgme.h)
AC_CONFIG_FILES(src/gpgme-config, chmod +x src/gpgme-config) AC_CONFIG_FILES(src/gpgme-config, chmod +x src/gpgme-config)
AC_CONFIG_FILES(lang/cpp/Makefile lang/cpp/src/Makefile) AC_CONFIG_FILES(lang/cpp/Makefile lang/cpp/src/Makefile)
AC_CONFIG_FILES(lang/cpp/tests/Makefile)
AC_CONFIG_FILES(lang/cpp/src/GpgmeppConfig-w32.cmake.in) AC_CONFIG_FILES(lang/cpp/src/GpgmeppConfig-w32.cmake.in)
AC_CONFIG_FILES(lang/cpp/src/GpgmeppConfig.cmake.in) AC_CONFIG_FILES(lang/cpp/src/GpgmeppConfig.cmake.in)
AC_CONFIG_FILES(lang/cpp/src/GpgmeppConfigVersion.cmake) AC_CONFIG_FILES(lang/cpp/src/GpgmeppConfigVersion.cmake)
AC_CONFIG_FILES(lang/cpp/src/gpgmepp_version.h) AC_CONFIG_FILES(lang/cpp/src/gpgmepp_version.h)
AC_CONFIG_FILES(lang/qt/Makefile lang/qt/src/Makefile) AC_CONFIG_FILES(lang/qt/Makefile lang/qt/src/Makefile)
if test "$want_qt5" = "yes"; then AC_CONFIG_FILES(lang/qt/src/QGpgmeConfig-w32.cmake.in)
AC_CONFIG_FILES(lang/qt/src/QGpgmeConfig-w32.cmake.in) AC_CONFIG_FILES(lang/qt/src/QGpgmeConfig.cmake.in)
AC_CONFIG_FILES(lang/qt/src/QGpgmeConfig.cmake.in) AC_CONFIG_FILES(lang/qt/src/QGpgmeConfigVersion.cmake)
AC_CONFIG_FILES(lang/qt/src/QGpgmeConfigVersion.cmake)
fi
if test "$want_qt6" = "yes"; then
AC_CONFIG_FILES(lang/qt/src/QGpgmeQt6Config-w32.cmake.in)
AC_CONFIG_FILES(lang/qt/src/QGpgmeQt6Config.cmake.in)
AC_CONFIG_FILES(lang/qt/src/QGpgmeQt6ConfigVersion.cmake)
fi
AC_CONFIG_FILES(lang/qt/tests/Makefile) AC_CONFIG_FILES(lang/qt/tests/Makefile)
AC_CONFIG_FILES(lang/qt/src/qgpgme_version.h) AC_CONFIG_FILES(lang/qt/src/qgpgme_version.h)
AC_CONFIG_FILES([lang/Makefile lang/cl/Makefile lang/cl/gpgme.asd]) AC_CONFIG_FILES([lang/Makefile lang/cl/Makefile lang/cl/gpgme.asd])
@ -1156,21 +905,10 @@ AC_CONFIG_FILES([lang/js/Makefile lang/js/src/Makefile
AC_CONFIG_FILES(lang/qt/doc/Makefile) AC_CONFIG_FILES(lang/qt/doc/Makefile)
AC_CONFIG_FILES([lang/python/Makefile AC_CONFIG_FILES([lang/python/Makefile
lang/python/version.py lang/python/version.py
lang/python/tests/Makefile lang/python/tests/Makefile])
lang/python/src/Makefile
lang/python/examples/Makefile
lang/python/doc/Makefile])
AC_CONFIG_FILES([lang/python/setup.py], [chmod a+x lang/python/setup.py]) AC_CONFIG_FILES([lang/python/setup.py], [chmod a+x lang/python/setup.py])
AC_OUTPUT AC_OUTPUT
if test "$want_qt5" = "yes" -a "$want_qt6" = "yes"; then
enabled_languages_v=$(echo ${enabled_languages_v:-$enabled_languages} | sed "s/qt/qt (Qt 5, Qt 6)/")
elif test "$want_qt5" = "yes"; then
enabled_languages_v=$(echo ${enabled_languages_v:-$enabled_languages} | sed "s/qt/qt (Qt 5)/")
elif test "$want_qt6" = "yes"; then
enabled_languages_v=$(echo ${enabled_languages_v:-$enabled_languages} | sed "s/qt/qt (Qt 6)/")
fi
echo " echo "
GPGME v${VERSION} has been configured as follows: GPGME v${VERSION} has been configured as follows:

49
contrib/ChangeLog-2011 Normal file
View File

@ -0,0 +1,49 @@
2011-12-02 Werner Koch <wk@g10code.com>
NB: ChangeLog files are no longer manually maintained. Starting
on December 1st, 2011 we put change information only in the GIT
commit log, and generate a top-level ChangeLog file from logs at
"make dist". See doc/HACKING for details.
2010-11-15 Marcus Brinkmann <mb@g10code.com>
* conf-w32ce-msc/fcntl.h: New file.
* conf-w32ce-msc/build.mk (conf_sources): Add fnctl.h.
(sources): Remove memrchr.c.
* conf-w32ce-msc/io.h: New file.
* conf-w32ce-msc/build.mk (conf_sources): Add io.h.
* conf-w32ce-msc/stdint.h: New file.
* conf-w32ce-msc/build.mk (conf_sources): Add stdint.h.
* conf-w32ce-msc/build.mk (copy-static-source): Revert last change.
2010-11-15 Werner Koch <wk@g10code.com>
* conf-w32ce-msc/build.mk (copy-static-source): Create stdint.h.
(all): Add ws2.lib
(clean): New.
2010-11-04 Werner Koch <wk@g10code.com>
* conf-w32ce-msc/build.mk (copy-built-source): Revert last
change. Does not work with W32CE where MSC defines it in except.h.
2010-11-03 Werner Koch <wk@g10code.com>
* conf-w32ce-msc/build.mk (copy-built-source): Create dummy sehmap.h.
2010-11-01 Werner Koch <wk@g10code.com>
* conf-w32ce-msc/config.h: New.
* conf-w32ce-msc/build.mk: New.
Copyright (C) 2010 g10 Code GmbH
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
modifications, as long as this notice is preserved.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

256
contrib/conf-w32ce-msc/build.mk Executable file
View File

@ -0,0 +1,256 @@
# build.mk - Makefile to build libgpg-error using Visual-C
# Copyright 2010 g10 Code GmbH
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# This is a helper make script to build libgpg-error for WindowsCE
# using the Microsoft Visual C compiler.
targetdir = /home/smb/xppro-gnu/src/gpgme/src
# The target build directory where we run the Visual C compiler/ This
# needs to be an absolute directory name. Further we expect this
# structure of the tree:
#
# TARGET/src - Source directories: One directory for each project
# /bin - Installed DLLs
# /lib - Installed import libs.
# /include - Instaled header files.
targetdir = /home/smb/xppro-gnu
targetsrc = $(targetdir)/src
# Install directories (relative)
bindir = ../../../bin
libdir = ../../../lib
incdir = ../../../include
help:
@echo "Run "
@echo " make -f ../contrib/conf-w32ce-msc/build.mk copy-source"
@echo "on the POSIX system and then"
@echo " nmake -f build.mk all"
@echo " nmake -f build.mk install"
@echo "on the Windows system"
ce_defines = -DWINCE -D_WIN32_WCE=0x502 -DUNDER_CE \
-DWIN32_PLATFORM_PSPC -D_UNICODE -DUNICODE \
-D_CONSOLE -DARM -D_ARM_
#-D_DEBUG -DDEBUG
CFLAGS = -nologo -W3 -fp:fast -Os $(ce_defines) \
-DHAVE_CONFIG_H -DDLL_EXPORT -D_CRT_SECURE_NO_WARNINGS \
-I. -I$(incdir) -I$(incdir)/gpg-extra
LDFLAGS =
# Standard source files
sources = \
assuan-support.c \
ath-pth.c \
ath-pthread.c \
ath.c \
ath.h \
context.h \
conversion.c \
data-compat.c \
data-fd.c \
data-mem.c \
data-stream.c \
data-user.c \
data.c \
data.h \
debug.c \
debug.h \
decrypt-verify.c \
decrypt.c \
delete.c \
dirinfo.c \
edit.c \
encrypt-sign.c \
encrypt.c \
engine-assuan.c \
engine-backend.h \
engine-g13.c \
engine-gpg.c \
engine-gpgconf.c \
engine-gpgsm.c \
engine-uiserver.c \
engine.c \
engine.h \
error.c \
export.c \
funopen.c \
genkey.c \
get-env.c \
getauditlog.c \
gpgconf.c \
gpgme-tool.c \
gpgme-w32spawn.c \
gpgme.c \
import.c \
isascii.c \
kdpipeiodevice.h \
key.c \
keylist.c \
op-support.c \
opassuan.c \
ops.h \
passphrase.c \
passwd.c \
priv-io.h \
progress.c \
putc_unlocked.c \
sema.h \
setenv.c \
sig-notation.c \
sign.c \
signers.c \
stpcpy.c \
trust-item.c \
trustlist.c \
ttyname_r.c \
util.h \
vasprintf.c \
verify.c \
version.c \
vfs-create.c \
vfs-mount.c \
w32-ce.c \
w32-ce.h \
w32-glib-io.c \
w32-io.c \
w32-sema.c \
w32-util.c \
wait-global.c \
wait-private.c \
wait-user.c \
wait.c \
wait.h \
gpgme.def
# The object files we need to create from sources.
objs = \
conversion.obj \
get-env.obj \
data.obj \
data-fd.obj \
data-stream.obj \
data-mem.obj \
data-user.obj \
data-compat.obj \
signers.obj \
sig-notation.obj \
wait.obj \
wait-global.obj \
wait-private.obj \
wait-user.obj \
op-support.obj \
encrypt.obj \
encrypt-sign.obj \
decrypt.obj \
decrypt-verify.obj \
verify.obj \
sign.obj \
passphrase.obj \
progress.obj \
key.obj \
keylist.obj \
trust-item.obj \
trustlist.obj \
import.obj \
export.obj \
genkey.obj \
delete.obj \
edit.obj \
getauditlog.obj \
opassuan.obj \
passwd.obj \
engine.obj \
engine-gpg.obj \
engine-gpgsm.obj \
assuan-support.obj \
engine-assuan.obj \
engine-gpgconf.obj \
engine-g13.obj \
vfs-mount.obj \
vfs-create.obj \
gpgconf.obj \
w32-ce.obj \
w32-util.obj \
w32-sema.obj \
w32-io.obj \
dirinfo.obj \
debug.obj \
gpgme.obj \
version.obj \
error.obj \
ath.obj \
vasprintf.obj \
ttyname_r.obj \
stpcpy.obj \
setenv.obj
# Sources files in this directory inclduing this Makefile
conf_sources = \
build.mk \
config.h \
stdint.h io.h fcntl.h
# Source files built by running the standard build system.
built_sources = \
gpgme.h \
status-table.h
copy-static-source:
@if [ ! -f ./gpgme.c ]; then \
echo "Please cd to the src/ directory first"; \
exit 1; \
fi
cp -t $(targetsrc)/gpgme/src $(sources);
cd ../contrib/conf-w32ce-msc ; \
cp -t $(targetsrc)/gpgme/src $(conf_sources)
copy-built-source:
@if [ ! -f ./gpgme.h ]; then \
echo "Please build using ./autogen.sh --build-w32ce first"; \
exit 1; \
fi
cp -t $(targetsrc)/gpgme/src $(built_sources)
copy-source: copy-static-source copy-built-source
.c.obj:
$(CC) $(CFLAGS) -c $<
all: $(sources) $(conf_sources) $(built_sources) $(objs)
link /DLL /IMPLIB:libgpgme-11-msc.lib \
/OUT:libgpgme-11-msc.dll \
/DEF:gpgme.def /NOLOGO /MANIFEST:NO \
/NODEFAULTLIB:"oldnames.lib" /DYNAMICBASE:NO \
$(objs) \
$(libdir)/libgpg-error-0-msc.lib \
$(libdir)/libassuan-0-msc.lib \
coredll.lib corelibc.lib ole32.lib oleaut32.lib uuid.lib \
commctrl.lib ws2.lib /subsystem:windowsce,5.02
# Note that we don't need to create the install directories because
# libgpg-error must have been build and installed prior to this
# package.
install: all
copy /y gpgme.h $(incdir:/=\)
copy /y libgpgme-11-msc.dll $(bindir:/=\)
copy /y libgpgme-11-msc.lib $(libdir:/=\)
clean:
del *.obj libgpgme-11-msc.lib libgpgme-11-msc.dll libgpgme-11-msc.exp

View File

@ -0,0 +1,314 @@
/* config.h for building with Visual-C for WindowsCE.
* Copyright 2010 g10 Code GmbH
*
* This file is free software; as a special exception the author gives
* unlimited permission to copy and/or distribute it, with or without
* modifications, as long as this notice is preserved.
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* This file was originally created by running
* ./autogen.sh --build-w32ce
* on svn revision 1495 (gpgme 1.3.1-svn1495) and then adjusted to work
* with Visual-C.
*/
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.3.1-svn1495-msc1"
/* Name of this package */
#define PACKAGE "gpgme"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "bug-gpgme@gnupg.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "gpgme"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "gpgme " PACKAGE_VERSION
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "gpgme"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Whether Assuan support is enabled */
#define ENABLE_ASSUAN 1
/* Whether G13 support is enabled */
#define ENABLE_G13 1
/* Whether GPGCONF support is enabled */
#define ENABLE_GPGCONF 1
/* Whether GPGSM support is enabled */
#define ENABLE_GPGSM 1
/* Defined if we are building with uiserver support. */
/* #undef ENABLE_UISERVER */
/* Path to the G13 binary. */
#define G13_PATH "c:\\gnupg\\g13.exe"
/* Path to the GPGCONF binary. */
#define GPGCONF_PATH "c:\\gnupg\\gpgconf.exe"
/* version of the libassuan library */
#define GPGME_LIBASSUAN_VERSION "2.0.2-svn381"
/* Path to the GPGSM binary. */
#define GPGSM_PATH "c:\\gnupg\\gpgsm.exe"
/* The default error source for GPGME. */
#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GPGME
/* Path to the GnuPG binary. */
#define GPG_PATH "c:\\gnupg\\gpg.exe"
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2)
with special properties like no file modes */
#define HAVE_DOSISH_SYSTEM 1
/* Define to 1 if the system has the type `error_t'. */
/* #undef HAVE_ERROR_T */
/* Define to 1 if you have the `fopencookie' function. */
/* #undef HAVE_FOPENCOOKIE */
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
/* #undef HAVE_FSEEKO */
/* Define to 1 if you have the `funopen' function. */
/* #undef HAVE_FUNOPEN */
/* Define to 1 if you have the `getegid' function. */
/* #undef HAVE_GETEGID */
/* Define to 1 if you have the `getenv_r' function. */
/* #undef HAVE_GETENV_R */
/* Define to 1 if you have the `getgid' function. */
/* #undef HAVE_GETGID */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <locale.h> header file. */
/* #undef HAVE_LOCALE_H */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if we have Pth. */
/* #undef HAVE_PTH */
/* Define if we have pthread. */
/* #undef HAVE_PTHREAD */
/* Define to 1 if you have the `setenv' function. */
/* #undef HAVE_SETENV */
/* Define to 1 if you have the `setlocale' function. */
/* #undef HAVE_SETLOCALE */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `stpcpy' function. */
/* #undef HAVE_STPCPY */
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
/* #undef HAVE_SYS_SELECT_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
/* #undef HAVE_SYS_STAT_H */
/* Define to 1 if you have the <sys/types.h> header file. */
/* #undef HAVE_SYS_TYPES_H */
/* Define to 1 if you have the <sys/uio.h> header file. */
/* #undef HAVE_SYS_UIO_H */
/* Define if getenv() is thread-safe */
/* #undef HAVE_THREAD_SAFE_GETENV */
/* Define to 1 if you have the `timegm' function. */
/* #undef HAVE_TIMEGM */
/* Define if __thread is supported */
/* #define HAVE_TLS 1 */
/* Define to 1 if you have the `ttyname_r' function. */
/* #undef HAVE_TTYNAME_R */
/* Define to 1 if the system has the type `uintptr_t'. */
#define HAVE_UINTPTR_T 1
/* Define to 1 if you have the <unistd.h> header file. */
/* #define HAVE_UNISTD_H 1 */
/* Define to 1 if you have the `vasprintf' function. */
/* #undef HAVE_VASPRINTF */
/* Defined if we run on a W32 CE API based system */
#define HAVE_W32CE_SYSTEM 1
/* Defined if we run on a W32 API based system */
#define HAVE_W32_SYSTEM 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* used to implement the va_copy macro */
/* #undef MUST_COPY_VA_BYVAL */
/* Min. needed G13 version. */
#define NEED_G13_VERSION "2.1.0"
/* Min. needed GPGCONF version. */
#define NEED_GPGCONF_VERSION "2.0.4"
/* Min. needed GPGSM version. */
#define NEED_GPGSM_VERSION "1.9.6"
/* Min. needed GnuPG version. */
#define NEED_GPG_VERSION "1.4.0"
/* Separators as used in $PATH. */
#ifdef HAVE_DOSISH_SYSTEM
#define PATHSEP_C ';'
#else
#define PATHSEP_C ':'
#endif
/* The size of `unsigned int', as computed by sizeof. */
#define SIZEOF_UNSIGNED_INT 4
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Defined if descriptor passing is enabled and supported */
/* #undef USE_DESCRIPTOR_PASSING */
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Version of this package */
#define VERSION PACKAGE_VERSION
/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
/* #undef _LARGEFILE_SOURCE */
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
/* To allow the use of GPGME in multithreaded programs we have to use
special features from the library.
IMPORTANT: gpgme is not yet fully reentrant and you should use it
only from one thread. */
#ifndef _REENTRANT
# define _REENTRANT 1
#endif
/* Activate POSIX interface on MacOS X */
/* #undef _XOPEN_SOURCE */
/* Define to a type to use for `error_t' if it is not otherwise available. */
#define error_t int
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#define inline __inline
#endif
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to the type of an unsigned integer type wide enough to hold a
pointer, if such a type exists, and if the system does not define it. */
/* #undef uintptr_t */
/* Definition of GCC specific attributes. */
#if __GNUC__ > 2
# define GPGME_GCC_A_PURE __attribute__ ((__pure__))
#else
# define GPGME_GCC_A_PURE
#endif
/* Under WindowsCE we need gpg-error's strerror macro. */
#define GPG_ERR_ENABLE_ERRNO_MACROS 1
/* snprintf is not part of oldnames.lib thus we redefine it here. */
#define snprintf _snprintf
/* We don't want warnings like this:
warning C4996: e.g. "The POSIX name for this item is
deprecated. Instead, use the ISO C++ conformant name: _fileno"
warning C4018: '<' : signed/unsigned mismatch
warning C4244: '=' : conversion from 'time_t' to
'unsigned long', possible loss of data
*/
#pragma warning(disable:4996 4018 4244)

1
contrib/conf-w32ce-msc/fcntl.h Executable file
View File

@ -0,0 +1 @@
/* Dummy fcntl.h header. */

2
contrib/conf-w32ce-msc/io.h Executable file
View File

@ -0,0 +1,2 @@
/* Dummy io.h header. */

View File

@ -0,0 +1,9 @@
typedef unsigned long long uint64_t;
typedef long long int64_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned int uintptr_t;
typedef int intptr_t;

View File

@ -700,7 +700,7 @@
2002-05-26 Marcus Brinkmann <marcus@g10code.de> 2002-05-26 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi: Some typographical corrections throughout. * gpgme.texi: Some typographical correctons throughout.
2002-05-09 Marcus Brinkmann <marcus@g10code.de> 2002-05-09 Marcus Brinkmann <marcus@g10code.de>
@ -720,7 +720,7 @@
* gpgme.texi (Manipulating Data Buffers): Changed some data types * gpgme.texi (Manipulating Data Buffers): Changed some data types
to void*. to void*.
(Protocol Selection): Added gpgme_get_protocol. (Protocol Selection): Added gpgme_get_protocol.
(Verify): Updated to include the new attribute functions and (Verify): Updated to include the new attribute fucntions and
status codes. status codes.
2002-04-27 Werner Koch <wk@gnupg.org> 2002-04-27 Werner Koch <wk@gnupg.org>
@ -839,7 +839,7 @@
2002-01-29 Marcus Brinkmann <marcus@g10code.de> 2002-01-29 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Run Control): New section. * gpgme.texi (Run Control): New section.
(Verify): Document gpgme_get_notation. (Verify): Docuent gpgme_get_notation.
(More Information): New section describing gpgme_get_op_info. (More Information): New section describing gpgme_get_op_info.
2002-01-22 Marcus Brinkmann <marcus@g10code.de> 2002-01-22 Marcus Brinkmann <marcus@g10code.de>
@ -865,7 +865,7 @@
* gpgme.texi (Top): Complete detailmenu. * gpgme.texi (Top): Complete detailmenu.
* gpgme.texi: Convert embarrassing cruft to the real thing. * gpgme.texi: Convert embarassing cruft to the real thing.
2002-01-16 Marcus Brinkmann <marcus@g10code.de> 2002-01-16 Marcus Brinkmann <marcus@g10code.de>

View File

@ -14,8 +14,8 @@
# Public License for more details. # Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, see <https://gnu.org/licenses/>. # License along with this program; if not, write to the Free Software
# SPDX-License-Identifier: LGPL-2.1-or-later # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
@ -34,9 +34,9 @@ gpgme_TEXINFOS = uiserver.texi lesser.texi gpl.texi
gpgme.texi : defs.inc gpgme.texi : defs.inc
mkdefsinc: mkdefsinc.c Makefile $(top_builddir)/conf/config.h mkdefsinc: mkdefsinc.c Makefile ../config.h
$(CC_FOR_BUILD) -I. -I$(top_builddir)/conf -I$(srcdir) \ $(CC_FOR_BUILD) -I. -I.. -I$(srcdir) $(AM_CPPFLAGS) \
$(AM_CPPFLAGS) -o $@ $(srcdir)/mkdefsinc.c -o $@ $(srcdir)/mkdefsinc.c
dist-hook: defsincdate dist-hook: defsincdate
@ -60,3 +60,4 @@ online: gpgme.html gpgme.pdf
(cd gpgme.html && rsync -vr --exclude='.svn' . \ (cd gpgme.html && rsync -vr --exclude='.svn' . \
$${user}@ftp.gnupg.org:webspace/manuals/gpgme/ ); \ $${user}@ftp.gnupg.org:webspace/manuals/gpgme/ ); \
rsync -v gpgme.pdf $${user}@ftp.gnupg.org:webspace/manuals/ rsync -v gpgme.pdf $${user}@ftp.gnupg.org:webspace/manuals/

View File

@ -1,4 +1,4 @@
/* show-group-options.c - Example code to retrieve the group option. /* show-group-options.c - Example code to retriev the group option.
Copyright (C) 2008 g10 Code GmbH Copyright (C) 2008 g10 Code GmbH
This file is part of GPGME. This file is part of GPGME.
@ -14,7 +14,7 @@
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this program; if not, see <https://www.gnu.org/licenses/>. License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdlib.h> #include <stdlib.h>

File diff suppressed because it is too large Load Diff

View File

@ -498,7 +498,7 @@
% \def\foo{\parsearg\Xfoo} % \def\foo{\parsearg\Xfoo}
% \def\Xfoo#1{...} % \def\Xfoo#1{...}
% %
% Actually, I use \csname\string\foo\endcsname, i.e. \\foo, as it is my % Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
% favourite TeX trick. --kasal, 16nov03 % favourite TeX trick. --kasal, 16nov03
\def\parseargdef#1{% \def\parseargdef#1{%

View File

@ -564,7 +564,7 @@ do this it uses the Assuan command:
@deffn Command START_KEYMANAGER @deffn Command START_KEYMANAGER
The server shall pop up the main window of the key manager (aka The server shall pop up the main window of the key manager (aka
certificate manager). The client expects that the key manager is brought certificate manager). The client expects that the key manager is brought
into the foregound and that this command immediately returns (does not into the foregound and that this command immediatley returns (does not
wait until the key manager has been fully brought up). wait until the key manager has been fully brought up).
@end deffn @end deffn
@ -575,7 +575,7 @@ do this it uses the Assuan command:
@deffn Command START_CONFDIALOG @deffn Command START_CONFDIALOG
The server shall pop up its configuration dialog. The client expects The server shall pop up its configuration dialog. The client expects
that this dialog is brought into the foregound and that this command that this dialog is brought into the foregound and that this command
immediately returns (i.e. it does not wait until the dialog has been immediatley returns (i.e. it does not wait until the dialog has been
fully brought up). fully brought up).
@end deffn @end deffn

View File

@ -4,7 +4,7 @@ Name: gpgme
Version: @pkg_version@ Version: @pkg_version@
Release: 1 Release: 1
URL: https://gnupg.org/gpgme.html URL: https://gnupg.org/gpgme.html
Source: https://www.gnupg.org/ftp/gcrypt/gpgme/%{name}-%{version}.tar.gz Source: ftp://ftp.gnupg.org/gcrypt/alpha/gpgme/%{name}-%{version}.tar.gz
Group: Development/Libraries Group: Development/Libraries
Copyright: GPL Copyright: GPL
BuildRoot: %{_tmppath}/%{name}-%{version} BuildRoot: %{_tmppath}/%{name}-%{version}
@ -38,12 +38,10 @@ make distclean
%post %post
/sbin/ldconfig /sbin/ldconfig
/sbin/install-info %{_infodir}/gpgme.info.gz %{_infodir}/dir /sbin/install-info %{_infodir}/gpgme.info.gz %{_infodir}/dir
/sbin/install-info %{_infodir}/gpgme-python-howto.info.gz %{_infodir}/dir
%preun %preun
if [ "$1" = 0 ]; then if [ "$1" = 0 ]; then
/sbin/install-info --delete %{_infodir}/gpgme.info.gz %{_infodir}/dir /sbin/install-info --delete %{_infodir}/gpgme.info.gz %{_infodir}/dir
/sbin/install-info --delete %{_infodir}/gpgme-python-howto.info.gz %{_infodir}/dir
fi fi
%postun %postun
@ -59,7 +57,6 @@ fi
%{_includedir}/gpgme.h %{_includedir}/gpgme.h
%{_datadir}/aclocal/gpgme.m4 %{_datadir}/aclocal/gpgme.m4
%{_infodir}/gpgme.info* %{_infodir}/gpgme.info*
%{_infodir}/gpgme-python-howto.info*
%changelog %changelog
* Sat Aug 30 2003 Robert Schiele <rschiele@uni-mannheim.de> * Sat Aug 30 2003 Robert Schiele <rschiele@uni-mannheim.de>

View File

@ -35,9 +35,9 @@ support OpenPGP and the Cryptographic Message Syntax.
%%GNU: no %%GNU: no
%%web-page: https://www.gnupg.org/gpgme.html %%web-page: http://www.gnupg.org/gpgme.html
%%support: paid extension/consulting from https://www.g10code.com %%support: paid extension/consulting from http://www.g10code.com
%%doc: English programmer reference in Texinfo, Postscript, HTML included %%doc: English programmer reference in Texinfo, Postscript, HTML included
@ -47,13 +47,13 @@ support OpenPGP and the Cryptographic Message Syntax.
%%sponsors: %%sponsors:
%%source: https://www.gnupg.org/ftp/gcrypt/gpgme/ %%source: ftp://ftp.gnupg.org/gcrypt/gpgme/
%%debian: %%debian:
%%redhat: %%redhat:
%%repository: See https://dev.gnupg.org/source/gpgme/ %%repository: See http://www.gnupg.org/cvs-access.html
%%related: %%related:

View File

@ -14,8 +14,8 @@
# Public License for more details. # Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, see <https://gnu.org/licenses/>. # License along with this program; if not, write to the Free Software
# SPDX-License-Identifier: LGPL-2.1-or-later # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
SUBDIRS = $(ENABLED_LANGUAGES) SUBDIRS = $(ENABLED_LANGUAGES)
DIST_SUBDIRS = cl cpp qt python js DIST_SUBDIRS = cl cpp qt python js

View File

@ -13,11 +13,12 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details. # GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU General Public License
# License along with this program; if not, see <https://gnu.org/licenses/>. # along with this program; if not, write to the Free Software
# SPDX-License-Identifier: LGPL-2.1-or-later # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
clfiles = gpgme.asd gpgme-package.lisp gpgme-grovel.lisp gpgme.lisp clfiles = gpgme.asd gpgme-package.lisp gpgme.lisp
# FIXME: Should be configurable. # FIXME: Should be configurable.
clfilesdir = $(datadir)/common-lisp/source/gpgme clfilesdir = $(datadir)/common-lisp/source/gpgme

View File

@ -3,50 +3,33 @@ Common Lisp Support for GPGME
Requirements: Requirements:
ASDF Packaging Support ASDF Packaging Support
CFFI Foreign Function Interface CFFI Foreign Function Interface
trivial-garbage Finalizers gpg-error GPG Error Codes
gpg-error GPG Error Codes
Use with: Use with:
> (asdf:load-system "gpgme") > (asdf:operate 'asdf:load-op ':gpgme)
Examples Examples
-------- --------
(with-open-file (out "/tmp/myout" (with-open-file (stream "/tmp/myout" :direction :output
:direction :output :if-exists :supersede :element-type '(unsigned-byte 8))
:if-exists :supersede
:element-type '(unsigned-byte 8))
(with-context (ctx) (with-context (ctx)
(setf (armorp ctx) t) (setf (armor-p ctx) t)
(op-export ctx "DEADBEEF" out))) (op-export ctx "DEADBEEF" out)))
(with-context (ctx) (with-context (ctx)
(with-output-to-string (out) (with-output-to-string (out)
(setf (armorp ctx) t) (setf (armor-p ctx) t)
(op-export ctx "McTester" out))) (op-export ctx "McTester" out)))
(gpgme:with-context (ctx :armor t) (gpgme:with-context (ctx :armor t)
(with-output-to-string (out) (with-output-to-string (out)
(gpgme:op-export ctx "McTester" out))) (gpgme:op-export ctx "McTester" out)))
(gpgme:with-context (ctx :armor t)
(let ((recipient1 (gpgme:get-key ctx "DEADBEEF"))
(recipient2 (gpgme:get-key ctx "Alice"))
(message "Hello, world!"))
(with-output-to-string (out)
(with-input-from-string (in message)
(gpgme:op-encrypt ctx (vector recipient1 recipient2) in out)))))
(gpgme:with-context (ctx :armor t)
(let ((message "Hello, world!"))
(with-output-to-string (out)
(with-input-from-string (in message)
(gpgme:op-sign ctx in out)))))
TODO TODO
---- ----

View File

@ -1,31 +0,0 @@
;;;; gpgme-grovel.lisp
;;; This file is part of GPGME-CL.
;;;
;;; GPGME-CL is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2 of the License, or
;;; (at your option) any later version.
;;;
;;; GPGME-CL 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 General Public License
;;; along with GPGME; if not, write to the Free Software Foundation,
;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
(in-package :gpgme)
(include "errno.h" "sys/types.h")
(constant (+ebadf+ "EBADF"))
(ctype off-t "off_t")
(ctype size-t "size_t")
(ctype ssize-t "ssize_t")
(cvar ("errno" *errno*) :int)

View File

@ -26,8 +26,7 @@
(defpackage #:gpgme (defpackage #:gpgme
(:use #:common-lisp #:cffi #:gpg-error) (:use #:common-lisp #:cffi #:gpg-error)
(:import-from #:trivial-garbage
#:finalize)
(:export #:check-version (:export #:check-version
#:*version* #:*version*
#:context #:context

View File

@ -25,14 +25,11 @@
(in-package #:gpgme-system) (in-package #:gpgme-system)
(defsystem gpgme (defsystem gpgme
:description "GnuPG Made Easy." :description "GnuPG Made Easy."
:author "g10 Code GmbH" :author "g10 Code GmbH"
:version "@VERSION@" :version "@VERSION@"
:licence "GPL" :licence "GPL"
:defsystem-depends-on ("cffi-grovel") :depends-on ("cffi" "gpg-error")
:depends-on ("cffi" "gpg-error" "trivial-garbage") :components ((:file "gpgme-package")
:components ((:file "gpgme-package") (:file "gpgme"
(:cffi-grovel-file "gpgme-grovel" :depends-on ("gpgme-package"))))
:depends-on ("gpgme-package"))
(:file "gpgme"
:depends-on ("gpgme-package" "gpgme-grovel"))))

View File

@ -24,12 +24,6 @@
(in-package :gpgme) (in-package :gpgme)
(deftype byte-array ()
'(simple-array (unsigned-byte 8) (*)))
(deftype character-array ()
'(simple-array character (*)))
;;; Debugging. ;;; Debugging.
(defvar *debug* nil "If debugging output should be given or not.") (defvar *debug* nil "If debugging output should be given or not.")
@ -44,15 +38,23 @@
;;; System dependencies. ;;; System dependencies.
; Access to ERRNO. ; FIXME: Use cffi-grovel? cffi-unix?
(defctype size-t :unsigned-int "The system size_t type.")
(defctype ssize-t :int "The system ssize_t type.")
; FIXME: Ouch. Grovel? Helper function?
(defconstant +seek-set+ 0)
(defconstant +seek-cur+ 1)
(defconstant +seek-end+ 2)
(defctype off-t :long-long "The system off_t type.")
(defcfun ("strerror" c-strerror) :string (defcfun ("strerror" c-strerror) :string
(err :int)) (err :int))
(defun get-errno () ; Access to ERRNO.
*errno*) ; FIXME: Ouch. Should be grovel + helper function.
(defun set-errno (errno)
(setf *errno* errno))
(define-condition system-error (error) (define-condition system-error (error)
((errno :initarg :errno :reader system-error-errno)) ((errno :initarg :errno :reader system-error-errno))
@ -62,6 +64,14 @@
(c-strerror (system-error-errno c))))) (c-strerror (system-error-errno c)))))
(:documentation "Signalled when an errno is encountered.")) (:documentation "Signalled when an errno is encountered."))
(defconstant +ebadf+ 1)
; Ouch.
(defun get-errno ()
+ebadf+)
;;; More about errno below.
; Needed to write passphrases. ; Needed to write passphrases.
(defcfun ("write" c-write) ssize-t (defcfun ("write" c-write) ssize-t
(fd :int) (fd :int)
@ -73,6 +83,14 @@
(when (< res 0) (error 'system-error :errno (get-errno))) (when (< res 0) (error 'system-error :errno (get-errno)))
res)) res))
;;; More about errno here.
(defun set-errno (errno)
(cond
; Works on GNU/Linux.
((eql errno +ebadf+) (system-write -1 (null-pointer) 0))
(t (error 'invalid-errno :errno errno))))
;;; ;;;
;;; C Interface Definitions ;;; C Interface Definitions
;;; ;;;
@ -82,39 +100,22 @@
;;; Some new data types used for easier translation. ;;; Some new data types used for easier translation.
;;; The number of include certs. Translates to NIL for default. ;;; The number of include certs. Translates to NIL for default.
(defctype cert-int-t (defctype cert-int-t :int)
(:wrapper :int
:from-c translate-cert-int-t-from-foreign
:to-c translate-cert-int-t-to-foreign))
;;; A string that may be NIL to indicate a null pointer. ;;; A string that may be NIL to indicate a null pointer.
(defctype string-or-nil-t (defctype string-or-nil-t :string)
(:wrapper :string
:to-c translate-string-or-nil-t-to-foreign))
;;; Some opaque data types used by GPGME. ;;; Some opaque data types used by GPGME.
(defctype gpgme-ctx-t (defctype gpgme-ctx-t :pointer "The GPGME context type.")
(:wrapper :pointer
:to-c translate-gpgme-ctx-t-to-foreign)
"The GPGME context type.")
(defctype gpgme-data-t (defctype gpgme-data-t :pointer "The GPGME data object type.")
(:wrapper :pointer
:to-c translate-gpgme-data-t-to-foreign)
"The GPGME data object type.")
;;; Wrappers for the libgpg-error library. ;;; Wrappers for the libgpg-error library.
(defctype gpgme-error-t (defctype gpgme-error-t gpg-error::gpg-error-t "The GPGME error type.")
(:wrapper gpg-error::gpg-error-t
:from-c translate-gpgme-error-t-from-foreign
:to-c translate-gpgme-error-t-to-foreign)
"The GPGME error type.")
(defctype gpgme-error-no-signal-t (defctype gpgme-error-no-signal-t gpg-error::gpg-error-t
(:wrapper gpg-error::gpg-error-t
:from-c translate-gpgme-error-no-signal-t-from-foreign)
"The GPGME error type (this version does not signal conditions in translation.") "The GPGME error type (this version does not signal conditions in translation.")
(defctype gpgme-err-code-t gpg-error::gpg-err-code-t (defctype gpgme-err-code-t gpg-error::gpg-err-code-t
@ -140,11 +141,11 @@
(gpg-err-source err)) (gpg-err-source err))
(defun gpgme-strerror (err) (defun gpgme-strerror (err)
"Return a string containing a description of the error code." "Return a string containig a description of the error code."
(gpg-strerror err)) (gpg-strerror err))
(defun gpgme-strsource (err) (defun gpgme-strsource (err)
"Return a string containing a description of the error source." "Return a string containig a description of the error source."
(gpg-strsource err)) (gpg-strsource err))
(defun gpgme-err-code-from-errno (err) (defun gpgme-err-code-from-errno (err)
@ -170,11 +171,7 @@
(:none 0) (:none 0)
(:binary 1) (:binary 1)
(:base64 2) (:base64 2)
(:armor 3) (:armor 3))
(:url 4)
(:urlesc 5)
(:url0 6)
(:mime 7))
;;; ;;;
@ -185,11 +182,7 @@
(:rsa-s 3) (:rsa-s 3)
(:elg-e 16) (:elg-e 16)
(:dsa 17) (:dsa 17)
(:ecc 18) (:elg 20))
(:elg 20)
(:ecdsa 301)
(:ecdh 302)
(:eddsa 303))
(defcenum gpgme-hash-algo-t (defcenum gpgme-hash-algo-t
"Hash algorithms from libgcrypt." "Hash algorithms from libgcrypt."
@ -203,7 +196,6 @@
(:sha256 8) (:sha256 8)
(:sha384 9) (:sha384 9)
(:sha512 10) (:sha512 10)
(:sha224 11)
(:md4 301) (:md4 301)
(:crc32 302) (:crc32 302)
(:crc32-rfc1510 303) (:crc32-rfc1510 303)
@ -233,14 +225,7 @@
(defcenum gpgme-protocol-t (defcenum gpgme-protocol-t
"The available protocols." "The available protocols."
(:openpgp 0) (:openpgp 0)
(:cms 1) (:cms 1))
(:gpgconf 2)
(:assuan 3)
(:g13 4)
(:uiserver 5)
(:spawn 6)
(:default 254)
(:unknown 255))
;;; ;;;
@ -249,10 +234,6 @@
(:local 1) (:local 1)
(:extern 2) (:extern 2)
(:sigs 4) (:sigs 4)
(:sig-notations)
(:with-secret 16)
(:with-tofu 32)
(:ephemeral 128)
(:validate 256)) (:validate 256))
;;; ;;;
@ -262,12 +243,10 @@
(:human-readable 1) (:human-readable 1)
(:critical 2)) (:critical 2))
(defctype gpgme-sig-notation-t (defctype gpgme-sig-notation-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-sig-notation-t-from-foreign)
"Signature notation pointer type.") "Signature notation pointer type.")
;; FIXME: Doesn't this depend on endianness? ;; FIXME: Doesn't this depend on endianess?
(defbitfield (gpgme-sig-notation-bitfield :unsigned-int) (defbitfield (gpgme-sig-notation-bitfield :unsigned-int)
(:human-readable 1) (:human-readable 1)
(:critical 2)) (:critical 2))
@ -284,115 +263,15 @@
;;; ;;;
;; FIXME: Add status codes.
(defcenum gpgme-status-code-t (defcenum gpgme-status-code-t
"The possible status codes for the edit operation." "The possible status codes for the edit operation."
(:eof 0) (:eof 0)
(:enter 1) (:enter 1))
(:leave 2)
(:abort 3)
(:goodsig 4)
(:badsig 5)
(:errsig 6)
(:badarmor 7)
(:rsa-or-idea 8)
(:keyexpired 9)
(:keyrevoked 10)
(:trust-undefined 11)
(:trust-never 12)
(:trust-marginal 13)
(:trust-fully 14)
(:trust-ultimate 15)
(:shm-info 16)
(:shm-get 17)
(:shm-get-bool 18)
(:shm-get-hidden 19)
(:need-passphrase 20)
(:validsig 21)
(:sig-id 22)
(:enc-to 23)
(:nodata 24)
(:bad-passphrase 25)
(:no-pubkey 26)
(:no-seckey 27)
(:need-passphrase-sym 28)
(:decryption-failed 29)
(:decryption-okay 30)
(:missing-passphrase 31)
(:good-passphrase 32)
(:goodmdc 33)
(:badmdc 34)
(:errmdc 35)
(:imported 36)
(:import-ok 37)
(:import-problem 38)
(:import-res 39)
(:file-start 40)
(:file-done 41)
(:file-error 42)
(:begin-decryption 43)
(:end-decryption 44)
(:begin-encryption 45)
(:end-encryption 46)
(:delete-problem 47)
(:get-bool 48)
(:get-line 49)
(:get-hidden 50)
(:got-it 51)
(:progress 52)
(:sig-created 53)
(:session-key 54)
(:notation-name 55)
(:notation-data 56)
(:policy-url 57)
(:begin-stream 58)
(:end-stream 59)
(:key-created 60)
(:userid-hint 61)
(:unexpected 62)
(:inv-recp 63)
(:no-recp 64)
(:already-signed 65)
(:sigexpired 66)
(:expsig 67)
(:expkeysig 68)
(:truncated 69)
(:error 70)
(:newsig 71)
(:revkeysig 72)
(:sig-subpacket 73)
(:need-passphrase-pin 74)
(:sc-op-failure 75)
(:sc-op-success 76)
(:cardctrl 77)
(:backup-key-created 78)
(:pka-trust-bad 79)
(:pka-trust-good 80)
(:plaintext 81)
(:inv-sgnr 82)
(:no-sgnr 83)
(:success 84)
(:decryption-info 85)
(:plaintext-length 86)
(:mountpoint 87)
(:pinentry-launched 88)
(:attribute 89)
(:begin-signing 90)
(:key-not-created 91)
(:inquire-maxlen 92)
(:failure 93)
(:key-considered 94)
(:tofu-user 95)
(:tofu-stats 96)
(:tofu-stats-long 97)
(:notation-flags 98)
(:decryption-compliance-mode 99)
(:verification-compliance-mode 100))
;;; ;;;
(defctype gpgme-engine-info-t (defctype gpgme-engine-info-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-engine-info-t-to-foreign)
"The engine information structure pointer type.") "The engine information structure pointer type.")
(defcstruct gpgme-engine-info (defcstruct gpgme-engine-info
@ -406,12 +285,9 @@
;;; ;;;
(defctype gpgme-subkey-t (defctype gpgme-subkey-t :pointer "A subkey from a key.")
(:wrapper :pointer
:from-c translate-gpgme-subkey-t-from-foreign)
"A subkey from a key.")
;; FIXME: Doesn't this depend on endianness? ;; FIXME: Doesn't this depend on endianess?
(defbitfield (gpgme-subkey-bitfield :unsigned-int) (defbitfield (gpgme-subkey-bitfield :unsigned-int)
"The subkey bitfield." "The subkey bitfield."
(:revoked 1) (:revoked 1)
@ -423,9 +299,7 @@
(:can-certify 64) (:can-certify 64)
(:secret 128) (:secret 128)
(:can-authenticate 256) (:can-authenticate 256)
(:is-qualified 512) (:is-qualified 512))
(:is-cardkey 1024)
(:is-de-vs 2048))
(defcstruct gpgme-subkey (defcstruct gpgme-subkey
"Subkey from a key." "Subkey from a key."
@ -440,12 +314,10 @@
(expires :long)) (expires :long))
(defctype gpgme-key-sig-t (defctype gpgme-key-sig-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-key-sig-t-from-foreign)
"A signature on a user ID.") "A signature on a user ID.")
;; FIXME: Doesn't this depend on endianness? ;; FIXME: Doesn't this depend on endianess?
(defbitfield (gpgme-key-sig-bitfield :unsigned-int) (defbitfield (gpgme-key-sig-bitfield :unsigned-int)
"The key signature bitfield." "The key signature bitfield."
(:revoked 1) (:revoked 1)
@ -471,12 +343,10 @@
(sig-class :unsigned-int)) (sig-class :unsigned-int))
(defctype gpgme-user-id-t (defctype gpgme-user-id-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-user-id-t-from-foreign)
"A user ID from a key.") "A user ID from a key.")
;; FIXME: Doesn't this depend on endianness? ;; FIXME: Doesn't this depend on endianess?
(defbitfield (gpgme-user-id-bitfield :unsigned-int) (defbitfield (gpgme-user-id-bitfield :unsigned-int)
"The user ID bitfield." "The user ID bitfield."
(:revoked 1) (:revoked 1)
@ -495,13 +365,10 @@
(-last-keysig gpgme-key-sig-t)) (-last-keysig gpgme-key-sig-t))
(defctype gpgme-key-t (defctype gpgme-key-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-key-t-from-foreign
:to-c translate-gpgme-key-t-to-foreign)
"A key from the keyring.") "A key from the keyring.")
;; FIXME: Doesn't this depend on endianness? ;; FIXME: Doesn't this depend on endianess?
(defbitfield (gpgme-key-bitfield :unsigned-int) (defbitfield (gpgme-key-bitfield :unsigned-int)
"The key bitfield." "The key bitfield."
(:revoked 1) (:revoked 1)
@ -826,9 +693,7 @@
;;; ;;;
(defctype gpgme-invalid-key-t (defctype gpgme-invalid-key-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-invalid-key-t-from-foreign)
"An invalid key structure.") "An invalid key structure.")
(defcstruct gpgme-invalid-key (defcstruct gpgme-invalid-key
@ -843,9 +708,7 @@
"Encryption result structure." "Encryption result structure."
(invalid-recipients gpgme-invalid-key-t)) (invalid-recipients gpgme-invalid-key-t))
(defctype gpgme-op-encrypt-result-t (defctype gpgme-op-encrypt-result-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-op-encrypt-result-t-from-foreign)
"An encryption result structure.") "An encryption result structure.")
(defcfun ("gpgme_op_encrypt_result" c-gpgme-op-encrypt-result) (defcfun ("gpgme_op_encrypt_result" c-gpgme-op-encrypt-result)
@ -853,15 +716,7 @@
(ctx gpgme-ctx-t)) (ctx gpgme-ctx-t))
(defbitfield gpgme-encrypt-flags-t (defbitfield gpgme-encrypt-flags-t
(:always-trust 1) (:always-trust 1))
(:no-encrypt-to 2)
(:prepare 4)
(:expect-sign 8)
(:no-compress 16)
(:symmetric 32)
(:throw-keyids 64)
(:wrap 128)
(:want-address 256))
(defcfun ("gpgme_op_encrypt_start" c-gpgme-op-encrypt-start) gpgme-error-t (defcfun ("gpgme_op_encrypt_start" c-gpgme-op-encrypt-start) gpgme-error-t
(ctx gpgme-ctx-t) (ctx gpgme-ctx-t)
@ -894,9 +749,7 @@
;;; Decryption. ;;; Decryption.
(defctype gpgme-recipient-t (defctype gpgme-recipient-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-recipient-t-from-foreign)
"A recipient structure.") "A recipient structure.")
(defcstruct gpgme-recipient (defcstruct gpgme-recipient
@ -909,9 +762,7 @@
(defbitfield gpgme-op-decrypt-result-bitfield (defbitfield gpgme-op-decrypt-result-bitfield
"Decryption result structure bitfield." "Decryption result structure bitfield."
(:wrong-key-usage 1) (:wrong-key-usage 1))
(:is-de-vs 2)
(:is-mine 4))
(defcstruct gpgme-op-decrypt-result (defcstruct gpgme-op-decrypt-result
"Decryption result structure." "Decryption result structure."
@ -920,9 +771,7 @@
(recipients gpgme-recipient-t) (recipients gpgme-recipient-t)
(file-name :string)) (file-name :string))
(defctype gpgme-op-decrypt-result-t (defctype gpgme-op-decrypt-result-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-op-decrypt-result-t-from-foreign)
"A decryption result structure.") "A decryption result structure.")
(defcfun ("gpgme_op_decrypt_result" c-gpgme-op-decrypt-result) (defcfun ("gpgme_op_decrypt_result" c-gpgme-op-decrypt-result)
@ -952,9 +801,7 @@
;;; Signing. ;;; Signing.
(defctype gpgme-new-signature-t (defctype gpgme-new-signature-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-new-signature-t-from-foreign)
"A new signature structure.") "A new signature structure.")
(defcstruct gpgme-new-signature (defcstruct gpgme-new-signature
@ -974,9 +821,7 @@
(invalid-signers gpgme-invalid-key-t) (invalid-signers gpgme-invalid-key-t)
(signatures gpgme-new-signature-t)) (signatures gpgme-new-signature-t))
(defctype gpgme-op-sign-result-t (defctype gpgme-op-sign-result-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-op-sign-result-t-from-foreign)
"A signing result structure.") "A signing result structure.")
(defcfun ("gpgme_op_sign_result" c-gpgme-op-sign-result) (defcfun ("gpgme_op_sign_result" c-gpgme-op-sign-result)
@ -1009,21 +854,15 @@
(:crl-missing #x0100) (:crl-missing #x0100)
(:crl-too-old #x0200) (:crl-too-old #x0200)
(:bad-policy #x0400) (:bad-policy #x0400)
(:sys-error #x0800) (:sys-error #x0800))
(:tofu-conflict #x1000))
(defctype gpgme-signature-t (defctype gpgme-signature-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-signature-t-from-foreign)
"A signature structure.") "A signature structure.")
;; FIXME: Doesn't this depend on endianness? ;; FIXME: Doesn't this depend on endianess?
(defbitfield (gpgme-signature-bitfield :unsigned-int) (defbitfield (gpgme-signature-bitfield :unsigned-int)
"The signature bitfield." "The signature bitfield."
(:wrong-key-usage 1) (:wrong-key-usage 1))
(:pka-trust 2)
(:chain-model 4)
(:is-de-vs 8))
(defcstruct gpgme-signature (defcstruct gpgme-signature
"Signature structure." "Signature structure."
@ -1045,9 +884,7 @@
(signatures gpgme-signature-t) (signatures gpgme-signature-t)
(file-name :string)) (file-name :string))
(defctype gpgme-op-verify-result-t (defctype gpgme-op-verify-result-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-op-verify-result-t-from-foreign)
"A verify result structure.") "A verify result structure.")
(defcfun ("gpgme_op_verify_result" c-gpgme-op-verify-result) (defcfun ("gpgme_op_verify_result" c-gpgme-op-verify-result)
@ -1076,9 +913,7 @@
(:subkey #x0008) (:subkey #x0008)
(:secret #x0010)) (:secret #x0010))
(defctype gpgme-import-status-t (defctype gpgme-import-status-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-import-status-t-from-foreign)
"An import status structure.") "An import status structure.")
(defcstruct gpgme-import-status (defcstruct gpgme-import-status
@ -1106,9 +941,7 @@
(not-imported :int) (not-imported :int)
(imports gpgme-import-status-t)) (imports gpgme-import-status-t))
(defctype gpgme-op-import-result-t (defctype gpgme-op-import-result-t :pointer
(:wrapper :pointer
:from-c translate-gpgme-op-import-result-t-from-foreign)
"An import status result structure.") "An import status result structure.")
(defcfun ("gpgme_op_import_result" c-gpgme-op-import-result) (defcfun ("gpgme_op_import_result" c-gpgme-op-import-result)
@ -1144,8 +977,7 @@
(defbitfield (gpgme-genkey-flags-t :unsigned-int) (defbitfield (gpgme-genkey-flags-t :unsigned-int)
"Flags used for the key generation result bitfield." "Flags used for the key generation result bitfield."
(:primary #x0001) (:primary #x0001)
(:sub #x0002) (:sub #x0002))
(:uid #x0004))
(defcstruct gpgme-op-genkey-result (defcstruct gpgme-op-genkey-result
"Key generation result structure." "Key generation result structure."
@ -1246,20 +1078,21 @@
;;; cert-int-t is a helper type that takes care of representing the ;;; cert-int-t is a helper type that takes care of representing the
;;; default number of certs as NIL. ;;; default number of certs as NIL.
(defun translate-cert-int-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'cert-int-t)))
(cond (cond
((eql value +include-certs-default+) nil) ((eql value +include-certs-default+) nil)
(t value))) (t value)))
(defun translate-cert-int-t-to-foreign (value) (defmethod translate-to-foreign (value (type (eql 'cert-int-t)))
(cond (cond
(value value) (value value)
(t +include-certs-default+))) (t +include-certs-default+)))
;;; string-or-nil-t translates a null pointer to NIL and vice versa. ;;; string-or-nil-t translates a null pointer to NIL and vice versa.
;;; Translation from foreign null pointer already works as expected. ;;; Translation from foreign null pointer already works as expected.
;;; FIXME: May the "to foreign" conversion problem be a bug in CFFI?
(defun translate-string-or-nil-t-to-foreign (value) (defmethod translate-to-foreign (value (type (eql 'string-or-nil-t)))
(cond (cond
(value value) (value value)
(t (null-pointer)))) (t (null-pointer))))
@ -1276,12 +1109,12 @@
;;; FIXME: Should we use a hash table (or struct, or clos) instead of ;;; FIXME: Should we use a hash table (or struct, or clos) instead of
;;; property list, as recommended by the Lisp FAQ? ;;; property list, as recommended by the Lisp FAQ?
(defun translate-gpgme-engine-info-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-engine-info-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next protocol file-name version req-version home-dir) ((next protocol file-name version req-version home-dir)
value (:struct gpgme-engine-info)) value gpgme-engine-info)
(append (list protocol (list (append (list protocol (list
:file-name file-name :file-name file-name
:version version :version version
@ -1289,53 +1122,55 @@
:home-dir home-dir)) :home-dir home-dir))
next))))) next)))))
(defun translate-gpgme-invalid-key-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-invalid-key-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next fpr reason) ((next fpr reason)
value (:struct gpgme-invalid-key)) value gpgme-invalid-key)
(append (list (list :fpr fpr (append (list (list :fpr fpr
:reason reason)) :reason reason))
next))))) next)))))
(defun translate-gpgme-op-encrypt-result-t-from-foreign (value) (defmethod translate-from-foreign (value
(type (eql 'gpgme-op-encrypt-result-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((invalid-recipients) ((invalid-recipients)
value (:struct gpgme-op-encrypt-result)) value gpgme-op-encrypt-result)
(list :encrypt (list :encrypt
(list :invalid-recipients invalid-recipients)))))) (list :invalid-recipients invalid-recipients))))))
(defun translate-gpgme-recipient-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-recipient-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next keyid pubkey-algo status) ((next keyid pubkey-algo status)
value (:struct gpgme-recipient)) value gpgme-recipient)
(append (list (list :keyid keyid (append (list (list :keyid keyid
:pubkey-algo pubkey-algo :pubkey-algo pubkey-algo
:status status)) :status status))
next))))) next)))))
(defun translate-gpgme-op-decrypt-result-t-from-foreign (value) (defmethod translate-from-foreign (value
(type (eql 'gpgme-op-decrypt-result-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((unsupported-algorithm bitfield recipients file-name) ((unsupported-algorithm bitfield recipients file-name)
value (:struct gpgme-op-decrypt-result)) value gpgme-op-decrypt-result)
(list :decrypt (list :unsupported-algorithm unsupported-algorithm (list :decrypt (list :unsupported-algorithm unsupported-algorithm
:bitfield bitfield :bitfield bitfield
:recipients recipients :recipients recipients
:file-name file-name)))))) :file-name file-name))))))
(defun translate-gpgme-new-signature-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-new-signature-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next type pubkey-algo hash-algo timestamp fpr sig-class) ((next type pubkey-algo hash-algo timestamp fpr sig-class)
value (:struct gpgme-new-signature)) value gpgme-new-signature)
(append (list (list :type type (append (list (list :type type
:pubkey-algo pubkey-algo :pubkey-algo pubkey-algo
:hash-algo hash-algo :hash-algo hash-algo
@ -1344,23 +1179,24 @@
:sig-class sig-class)) :sig-class sig-class))
next))))) next)))))
(defun translate-gpgme-op-sign-result-t-from-foreign (value) (defmethod translate-from-foreign (value
(type (eql 'gpgme-op-sign-result-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((invalid-signers signatures) ((invalid-signers signatures)
value (:struct gpgme-op-sign-result)) value gpgme-op-sign-result)
(list :sign (list :invalid-signers invalid-signers (list :sign (list :invalid-signers invalid-signers
:signatures signatures)))))) :signatures signatures))))))
(defun translate-gpgme-signature-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-signature-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next summary fpr status notations timestamp ((next summary fpr status notations timestamp
exp-timestamp bitfield validity validity-reason exp-timestamp bitfield validity validity-reason
pubkey-algo hash-algo) pubkey-algo hash-algo)
value (:struct gpgme-signature)) value gpgme-signature)
(append (list (list :summary summary (append (list (list :summary summary
:fpr fpr :fpr fpr
:status status :status status
@ -1373,27 +1209,29 @@
:pubkey-algo pubkey-algo)) :pubkey-algo pubkey-algo))
next))))) next)))))
(defun translate-gpgme-op-verify-result-t-from-foreign (value) (defmethod translate-from-foreign (value
(type (eql 'gpgme-op-verify-result-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((signatures file-name) ((signatures file-name)
value (:struct gpgme-op-verify-result)) value gpgme-op-verify-result)
(list :verify (list :signatures signatures (list :verify (list :signatures signatures
:file-name file-name)))))) :file-name file-name))))))
(defun translate-gpgme-import-status-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-import-status-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next fpr result status) ((next fpr result status)
value (:struct gpgme-import-status)) value gpgme-import-status)
(append (list (list :fpr fpr (append (list (list :fpr fpr
:result result :result result
:status status)) :status status))
next))))) next)))))
(defun translate-gpgme-op-import-result-t-from-foreign (value) (defmethod translate-from-foreign (value
(type (eql 'gpgme-op-import-result-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
@ -1402,7 +1240,7 @@
new-revocations secret-read secret-imported new-revocations secret-read secret-imported
secret-unchanged skipped-new-keys not-imported secret-unchanged skipped-new-keys not-imported
imports) imports)
value (:struct gpgme-op-import-result)) value gpgme-op-import-result)
(list :verify (list :considered considered (list :verify (list :considered considered
:no-user-id no-user-id :no-user-id no-user-id
:imported imported :imported imported
@ -1434,19 +1272,19 @@
(gpgme-strsource (gpgme-error-value c))))) (gpgme-strsource (gpgme-error-value c)))))
(:documentation "Signalled when a GPGME function returns an error.")) (:documentation "Signalled when a GPGME function returns an error."))
(defun translate-gpgme-error-t-from-foreign (value) (defmethod translate-from-foreign (value (name (eql 'gpgme-error-t)))
"Raise a GPGME-ERROR if VALUE is non-zero." "Raise a GPGME-ERROR if VALUE is non-zero."
(when (not (eql (gpgme-err-code value) :gpg-err-no-error)) (when (not (eql (gpgme-err-code value) :gpg-err-no-error))
(error 'gpgme-error :gpgme-error value)) (error 'gpgme-error :gpgme-error value))
(gpg-err-canonicalize value)) (gpg-err-canonicalize value))
(defun translate-gpgme-error-t-to-foreign (value) (defmethod translate-to-foreign (value (name (eql 'gpgme-error-t)))
"Canonicalize the error value." "Canonicalize the error value."
(if (eql (gpgme-err-code value) :gpg-err-no-error) (if (eql (gpgme-err-code value) :gpg-err-no-error)
0 0
(gpg-err-as-value value))) (gpg-err-as-value value)))
(defun translate-gpgme-error-no-signal-t-from-foreign (value) (defmethod translate-from-foreign (value (name (eql 'gpgme-error-no-signal-t)))
"Canonicalize the error value." "Canonicalize the error value."
(gpg-err-canonicalize value)) (gpg-err-canonicalize value))
@ -1683,75 +1521,68 @@
;;; The release callback removes the stream from the *data-handles* ;;; The release callback removes the stream from the *data-handles*
;;; hash and releases the CBS structure that is used as the key in ;;; hash and releases the CBS structure that is used as the key in
;;; that hash. It is implicitly invoked (through GPGME) by ;;; that hash. It is implicitely invoked (through GPGME) by
;;; gpgme-data-release. ;;; gpgme-data-release.
(defcallback data-release-cb :void ((handle :pointer)) (defcallback data-release-cb :void ((handle :pointer))
(unwind-protect (remhash (pointer-address handle) *data-handles*) (unwind-protect (remhash (pointer-address handle) *data-handles*)
(when (not (null-pointer-p handle)) (foreign-free handle)))) (when (not (null-pointer-p handle)) (foreign-free handle))))
(defcallback data-read-cb ssize-t ((handle :pointer) (buffer :pointer) (defcallback data-read-cb ssize-t ((handle :pointer) (buffer :pointer)
(size size-t)) (size size-t))
(when *debug* (format t "DEBUG: gpgme-data-read-cb: want ~A~%" size)) (when *debug* (format t "DEBUG: gpgme-data-read-cb: want ~A~%" size))
(let ((stream (gethash (pointer-address handle) *data-handles*))) (let ((stream (gethash (pointer-address handle) *data-handles*)))
(cond (cond
(stream (stream
(let* ((stream-type (stream-element-type stream)) (let* ((stream-type (stream-element-type stream))
(seq (make-array size :element-type stream-type)) (seq (make-array size :element-type stream-type))
(read (read-sequence seq stream))) (read (read-sequence seq stream)))
(cond (loop for i from 0 to (- read 1)
((equal stream-type '(unsigned-byte 8)) do (setf (mem-aref buffer :unsigned-char i)
(dotimes (i read) ;;; FIXME: This is a half-assed attempt at
(setf (mem-aref buffer :unsigned-char i) ;;; supporting character streams.
(aref (the byte-array seq) i)))) (cond
((eql stream-type 'character) ((eql stream-type 'character)
(dotimes (i read) (char-code (elt seq i)))
(setf (mem-aref buffer :unsigned-char i) (t (coerce (elt seq i) stream-type)))))
(char-code (aref (the character-array seq) i))))) (when *debug* (format t "DEBUG: gpgme-data-read-cb: read ~A~%" read))
(t read))
(dotimes (i read) (t (set-errno +ebadf+)
(setf (mem-aref buffer :unsigned-char i) -1))))
(coerce (aref seq i) '(unsigned-byte 8))))))
(when *debug* (format t "DEBUG: gpgme-data-read-cb: read ~A~%" read))
read))
(t
(set-errno +ebadf+)
-1))))
(defcallback data-write-cb ssize-t ((handle :pointer) (buffer :pointer) (defcallback data-write-cb ssize-t ((handle :pointer) (buffer :pointer)
(size size-t)) (size size-t))
(when *debug* (format t "DEBUG: gpgme-data-write-cb: want ~A~%" size)) (when *debug* (format t "DEBUG: gpgme-data-write-cb: want ~A~%" size))
(let ((stream (gethash (pointer-address handle) *data-handles*))) (let ((stream (gethash (pointer-address handle) *data-handles*)))
(cond (cond
(stream (stream
(let* ((stream-type (stream-element-type stream)) (let* ((stream-type (stream-element-type stream))
(seq (make-array size :element-type stream-type))) (seq (make-array size :element-type stream-type)))
(cond (loop for i from 0 to (- size 1)
((equal stream-type '(unsigned-byte 8)) do (setf (elt seq i)
(dotimes (i size) ;;; FIXME: This is a half-assed attempt at
(setf (aref (the byte-array seq) i) ;;; supporting character streams.
(mem-aref buffer :unsigned-char i)))) (cond
((eql stream-type 'character) ((eql stream-type 'character)
(dotimes (i size) (code-char (mem-aref buffer :unsigned-char i)))
(setf (aref (the character-array seq) i) (t (coerce (mem-aref buffer :unsigned-char i)
(code-char (mem-aref buffer :unsigned-char i))))) stream-type)))))
(t (write-sequence seq stream)
(dotimes (i size) ;;; FIXME: What about write errors?
(setf (aref seq i) size))
(coerce (mem-aref buffer :unsigned-char i) stream-type))))) (t (set-errno +ebadf+)
(write-sequence seq stream) -1))))
size))
(t
(set-errno +ebadf+)
-1))))
;;; This little helper macro allows us to swallow the cbs structure by ;;; This little helper macro allows us to swallow the cbs structure by
;;; simply setting it to a null pointer, but still protect against ;;; simply setting it to a null pointer, but still protect against
;;; conditions. ;;; conditions.
(defmacro with-cbs-swallowed ((cbs) &body body) (defmacro with-cbs-swallowed ((cbs) &body body)
`(let ((,cbs (foreign-alloc '(:struct gpgme-data-cbs)))) `(let ((,cbs (foreign-alloc 'gpgme-data-cbs)))
(unwind-protect (progn ,@body) (unwind-protect (progn ,@body)
(when (not (null-pointer-p ,cbs)) (foreign-free ,cbs))))) (when (not (null-pointer-p ,cbs)) (foreign-free ,cbs)))))
;;; FIXME: Wrap the object and attach to it a finalizer. Requires new
;;; CFFI. Should we use an OO interface, ie make-instance? For now,
;;; we do not provide direct access to data objects.
(defun gpgme-data-new (stream &key encoding file-name) (defun gpgme-data-new (stream &key encoding file-name)
"Allocate a new GPGME data object for STREAM." "Allocate a new GPGME data object for STREAM."
(with-foreign-object (dh-p 'gpgme-data-t) (with-foreign-object (dh-p 'gpgme-data-t)
@ -1761,14 +1592,12 @@
;;; unique C pointer as handle anyway to look up the stream in the ;;; unique C pointer as handle anyway to look up the stream in the
;;; callback. This is a convenient one to use. ;;; callback. This is a convenient one to use.
(with-cbs-swallowed (cbs) (with-cbs-swallowed (cbs)
(setf (foreign-slot-value cbs '(:struct gpgme-data-cbs) 'read) (setf
(callback data-read-cb)) (foreign-slot-value cbs 'gpgme-data-cbs 'read) (callback data-read-cb)
(setf (foreign-slot-value cbs '(:struct gpgme-data-cbs) 'write) (foreign-slot-value cbs 'gpgme-data-cbs 'write) (callback data-write-cb)
(callback data-write-cb)) (foreign-slot-value cbs 'gpgme-data-cbs 'seek) (null-pointer)
(setf (foreign-slot-value cbs '(:struct gpgme-data-cbs) 'seek) (foreign-slot-value cbs 'gpgme-data-cbs 'release) (callback
(null-pointer)) data-release-cb))
(setf (foreign-slot-value cbs '(:struct gpgme-data-cbs) 'release)
(callback data-release-cb))
(c-gpgme-data-new-from-cbs dh-p cbs cbs) (c-gpgme-data-new-from-cbs dh-p cbs cbs)
(let ((dh (mem-ref dh-p 'gpgme-data-t))) (let ((dh (mem-ref dh-p 'gpgme-data-t)))
(when encoding (gpgme-data-set-encoding dh encoding)) (when encoding (gpgme-data-set-encoding dh encoding))
@ -1783,40 +1612,19 @@
(when *debug* (format t "DEBUG: gpgme-data-new: ~A~%" dh)) (when *debug* (format t "DEBUG: gpgme-data-new: ~A~%" dh))
dh)))) dh))))
;;; This function releases a GPGME data object. It implicitly ;;; This function releases a GPGME data object. It implicitely
;;; invokes the data-release-cb function to clean up associated junk. ;;; invokes the data-release-cb function to clean up associated junk.
(defun gpgme-data-release (dh) (defun gpgme-data-release (dh)
"Release a GPGME data object." "Release a GPGME data object."
(when *debug* (format t "DEBUG: gpgme-data-release: ~A~%" dh)) (when *debug* (format t "DEBUG: gpgme-data-release: ~A~%" dh))
(c-gpgme-data-release dh)) (c-gpgme-data-release dh))
(defclass data ()
(c-data) ; The C data object pointer
(:documentation "The GPGME data type."))
(defmethod initialize-instance :after ((data data) &key streamspec
&allow-other-keys)
(let ((c-data (if (listp streamspec)
(apply #'gpgme-data-new streamspec)
(gpgme-data-new streamspec)))
(cleanup t))
(unwind-protect
(progn
(setf (slot-value data 'c-data) c-data)
(finalize data (lambda () (gpgme-data-release c-data)))
(setf cleanup nil))
(if cleanup (gpgme-data-release c-data)))))
(defun translate-gpgme-data-t-to-foreign (value)
;; Allow a pointer to be passed directly for the finalizer to work.
(cond
((null value) (null-pointer))
((pointerp value) value)
(t (slot-value value 'c-data))))
(defmacro with-gpgme-data ((dh streamspec) &body body) (defmacro with-gpgme-data ((dh streamspec) &body body)
`(let ((,dh (make-instance 'data :streamspec ,streamspec))) `(let ((,dh (if (listp ,streamspec)
,@body)) (apply 'gpgme-data-new ,streamspec)
(gpgme-data-new ,streamspec))))
(unwind-protect (progn ,@body)
(when (not (null-pointer-p ,dh)) (gpgme-data-release ,dh)))))
(defun gpgme-data-get-encoding (dh) (defun gpgme-data-get-encoding (dh)
"Get the encoding associated with the data object DH." "Get the encoding associated with the data object DH."
@ -1885,7 +1693,7 @@
(setf cleanup nil)) (setf cleanup nil))
(if cleanup (gpgme-release c-ctx))))) (if cleanup (gpgme-release c-ctx)))))
(defun translate-gpgme-ctx-t-to-foreign (value) (defmethod translate-to-foreign (value (type (eql 'gpgme-ctx-t)))
;; Allow a pointer to be passed directly for the finalizer to work. ;; Allow a pointer to be passed directly for the finalizer to work.
(if (pointerp value) value (slot-value value 'c-ctx))) (if (pointerp value) value (slot-value value 'c-ctx)))
@ -1907,7 +1715,7 @@
(:documentation "Set the protocol of CONTEXT to PROTOCOL.")) (:documentation "Set the protocol of CONTEXT to PROTOCOL."))
;;; FIXME: Adjust translator to reject invalid protocols. Currently, ;;; FIXME: Adjust translator to reject invalid protocols. Currently,
;;; specifying an invalid protocol throws a "NIL is not 32 signed int" ;;; specifing an invalid protocol throws a "NIL is not 32 signed int"
;;; error. This is suboptimal. ;;; error. This is suboptimal.
(defmethod (setf protocol) (protocol (ctx context)) (defmethod (setf protocol) (protocol (ctx context))
(gpgme-set-protocol ctx protocol)) (gpgme-set-protocol ctx protocol))
@ -2040,11 +1848,11 @@
(setf (slot-value key 'c-key) c-key) (setf (slot-value key 'c-key) c-key)
(finalize key (lambda () (gpgme-key-unref c-key)))) (finalize key (lambda () (gpgme-key-unref c-key))))
(defun translate-gpgme-key-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-key-t)))
(when *debug* (format t "DEBUG: import key: ~A~%" value)) (when *debug* (format t "DEBUG: import key: ~A~%" value))
(make-instance 'key :c-key value)) (make-instance 'key :c-key value))
(defun translate-gpgme-key-t-to-foreign (value) (defmethod translate-to-foreign (value (type (eql 'gpgme-key-t)))
;; Allow a pointer to be passed directly for the finalizer to work. ;; Allow a pointer to be passed directly for the finalizer to work.
(if (pointerp value) value (slot-value value 'c-key))) (if (pointerp value) value (slot-value value 'c-key)))
@ -2059,12 +1867,12 @@
;;; and zero length value (omit?) and human-readable (convert to string). ;;; and zero length value (omit?) and human-readable (convert to string).
;;; FIXME: Turn binary data into sequence or vector or what it should be. ;;; FIXME: Turn binary data into sequence or vector or what it should be.
;;; FIXME: Turn the whole thing into a hash? ;;; FIXME: Turn the whole thing into a hash?
(defun translate-gpgme-sig-notation-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-sig-notation-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next name value name-len value-len flags bitfield) ((next name value name-len value-len flags bitfield)
value (:struct gpgme-sig-notation)) value gpgme-sig-notation)
(append (list (list (append (list (list
:name name :name name
:value value :value value
@ -2075,12 +1883,12 @@
next))))) next)))))
;;; FIXME: Deal nicer with timestamps. bitfield field name? ;;; FIXME: Deal nicer with timestamps. bitfield field name?
(defun translate-gpgme-subkey-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-subkey-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next bitfield pubkey-algo length keyid fpr timestamp expires) ((next bitfield pubkey-algo length keyid fpr timestamp expires)
value (:struct gpgme-subkey)) value gpgme-subkey)
(append (list (list (append (list (list
:bitfield bitfield :bitfield bitfield
:pubkey-algo pubkey-algo :pubkey-algo pubkey-algo
@ -2091,13 +1899,13 @@
:expires expires)) :expires expires))
next))))) next)))))
(defun translate-gpgme-key-sig-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-key-sig-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next bitfield pubkey-algo keyid timestamp expires status ((next bitfield pubkey-algo keyid timestamp expires status
uid name email comment sig-class) uid name email comment sig-class)
value (:struct gpgme-key-sig)) value gpgme-key-sig)
(append (list (list (append (list (list
:bitfield bitfield :bitfield bitfield
:pubkey-algo pubkey-algo :pubkey-algo pubkey-algo
@ -2112,12 +1920,12 @@
:sig-class sig-class)) :sig-class sig-class))
next))))) next)))))
(defun translate-gpgme-user-id-t-from-foreign (value) (defmethod translate-from-foreign (value (type (eql 'gpgme-user-id-t)))
(cond (cond
((null-pointer-p value) nil) ((null-pointer-p value) nil)
(t (with-foreign-slots (t (with-foreign-slots
((next bitfield validity uid name email comment signatures) ((next bitfield validity uid name email comment signatures)
value (:struct gpgme-user-id)) value gpgme-user-id)
(append (list (list (append (list (list
:bitfield bitfield :bitfield bitfield
:validity validity :validity validity
@ -2133,7 +1941,7 @@
(with-foreign-slots (with-foreign-slots
((bitfield protocol issuer-serial issuer-name chain-id ((bitfield protocol issuer-serial issuer-name chain-id
owner-trust subkeys uids keylist-mode) owner-trust subkeys uids keylist-mode)
c-key (:struct gpgme-key)) c-key gpgme-key)
(list (list
:bitfield bitfield :bitfield bitfield
:protocol protocol :protocol protocol

View File

@ -14,16 +14,11 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details. # GNU Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU General Public License
# License along with this program; if not, see <https://gnu.org/licenses/>. # along with this program; if not, write to the Free Software
# SPDX-License-Identifier: LGPL-2.1-or-later # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
if RUN_GPG_TESTS SUBDIRS = src
tests = tests
else
tests =
endif
SUBDIRS = src ${tests}
EXTRA_DIST = README EXTRA_DIST = README

View File

@ -43,7 +43,7 @@ pattern so the documentation for GPGME itself provides a good
way to start. way to start.
The context structure in GPGME is mapped to a Context object in The context structure in GPGME is mapped to a Context object in
GpgMEpp. Additional convenience code provides Data objects and GpgMEpp. Additional convienience code provides Data objects and
a Dataprovider interface that can be used to implement GPGME's a Dataprovider interface that can be used to implement GPGME's
data with any subclass by implementing the right callbacks. data with any subclass by implementing the right callbacks.

View File

@ -97,3 +97,7 @@ unset(_IMPORT_CHECK_TARGETS)
# Commands beyond this point should not need to know the version. # Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION) set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP) cmake_policy(POP)
get_filename_component(QGpgme_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
# Pull in QGpgme for compatibility with KF5 variant.
find_package(QGpgme CONFIG)

View File

@ -93,3 +93,7 @@ unset(_IMPORT_CHECK_TARGETS)
# Commands beyond this point should not need to know the version. # Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION) set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP) cmake_policy(POP)
get_filename_component(QGpgme_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
# Pull in QGpgme for compatibility with KF5 variant.
find_package(QGpgme CONFIG)

View File

@ -33,13 +33,9 @@ main_sources = \
engineinfo.cpp gpgsetexpirytimeeditinteractor.cpp \ engineinfo.cpp gpgsetexpirytimeeditinteractor.cpp \
gpgsetownertrusteditinteractor.cpp gpgsignkeyeditinteractor.cpp \ gpgsetownertrusteditinteractor.cpp gpgsignkeyeditinteractor.cpp \
gpgadduserideditinteractor.cpp gpggencardkeyinteractor.cpp \ gpgadduserideditinteractor.cpp gpggencardkeyinteractor.cpp \
gpgaddexistingsubkeyeditinteractor.cpp \
gpgrevokekeyeditinteractor.cpp \
defaultassuantransaction.cpp \ defaultassuantransaction.cpp \
scdgetinfoassuantransaction.cpp gpgagentgetinfoassuantransaction.cpp \ scdgetinfoassuantransaction.cpp gpgagentgetinfoassuantransaction.cpp \
statusconsumerassuantransaction.cpp \ vfsmountresult.cpp configuration.cpp tofuinfo.cpp swdbresult.cpp
vfsmountresult.cpp configuration.cpp tofuinfo.cpp swdbresult.cpp \
util.cpp
gpgmepp_headers = \ gpgmepp_headers = \
configuration.h context.h data.h decryptionresult.h \ configuration.h context.h data.h decryptionresult.h \
@ -49,11 +45,8 @@ gpgmepp_headers = \
gpgmefw.h gpgsetexpirytimeeditinteractor.h \ gpgmefw.h gpgsetexpirytimeeditinteractor.h \
gpgsetownertrusteditinteractor.h gpgsignkeyeditinteractor.h \ gpgsetownertrusteditinteractor.h gpgsignkeyeditinteractor.h \
gpggencardkeyinteractor.h \ gpggencardkeyinteractor.h \
gpgaddexistingsubkeyeditinteractor.h \
gpgrevokekeyeditinteractor.h \
importresult.h keygenerationresult.h key.h keylistresult.h \ importresult.h keygenerationresult.h key.h keylistresult.h \
notation.h result.h scdgetinfoassuantransaction.h signingresult.h \ notation.h result.h scdgetinfoassuantransaction.h signingresult.h \
statusconsumerassuantransaction.h \
trustitem.h verificationresult.h vfsmountresult.h gpgmepp_export.h \ trustitem.h verificationresult.h vfsmountresult.h gpgmepp_export.h \
tofuinfo.h swdbresult.h tofuinfo.h swdbresult.h
@ -62,8 +55,7 @@ private_gpgmepp_headers = \
interface_headers= \ interface_headers= \
interfaces/assuantransaction.h interfaces/dataprovider.h \ interfaces/assuantransaction.h interfaces/dataprovider.h \
interfaces/passphraseprovider.h interfaces/progressprovider.h \ interfaces/passphraseprovider.h interfaces/progressprovider.h
interfaces/statusconsumer.h
gpgmeppincludedir = $(includedir)/gpgme++ gpgmeppincludedir = $(includedir)/gpgme++
gpgmeppinclude_HEADERS = $(gpgmepp_headers) gpgmeppinclude_HEADERS = $(gpgmepp_headers)
@ -73,10 +65,8 @@ nodist_gpgmeppinclude_HEADERS = gpgmepp_version.h
libgpgmepp_la_SOURCES = $(main_sources) $(gpgmepp_headers) context_vanilla.cpp \ libgpgmepp_la_SOURCES = $(main_sources) $(gpgmepp_headers) context_vanilla.cpp \
$(interface_headers) $(private_gpgmepp_headers) $(interface_headers) $(private_gpgmepp_headers)
AM_CPPFLAGS = -I$(top_builddir)/src \ AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \
@GPGME_CPP_CFLAGS@ @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \ -DBUILDING_GPGMEPP
-DBUILDING_GPGMEPP -Wsuggest-override \
-Wzero-as-null-pointer-constant
libgpgmepp_la_LIBADD = ../../../src/libgpgme.la @LIBASSUAN_LIBS@ libgpgmepp_la_LIBADD = ../../../src/libgpgme.la @LIBASSUAN_LIBS@
libgpgmepp_la_LDFLAGS = -no-undefined -version-info \ libgpgmepp_la_LDFLAGS = -no-undefined -version-info \
@ -88,14 +78,6 @@ else
libsuffix=.so libsuffix=.so
endif endif
copied_headers = $(gpgmepp_headers:%=gpgme++/%) $(interface_headers:%=gpgme++/%)
$(copied_headers): Makefile.am
mkdir -p $(builddir)/gpgme++/interfaces
echo -n "#include \"$(abs_srcdir)" > "$@"
echo -n "$@" | sed "s/gpgme++//" >> "$@"
echo "\"" >> "$@"
if HAVE_W32_SYSTEM if HAVE_W32_SYSTEM
GpgmeppConfig.cmake: GpgmeppConfig-w32.cmake.in GpgmeppConfig.cmake: GpgmeppConfig-w32.cmake.in
sed -e 's|[@]resolved_bindir@|$(bindir)|g' < "$<" | \ sed -e 's|[@]resolved_bindir@|$(bindir)|g' < "$<" | \
@ -123,8 +105,5 @@ install-data-local: install-cmake-files
uninstall-local: uninstall-cmake-files uninstall-local: uninstall-cmake-files
BUILT_SOURCES = $(copied_headers)
CLEANFILES = GpgmeppConfig.cmake GpgmeppConfigVersion.cmake \ CLEANFILES = GpgmeppConfig.cmake GpgmeppConfigVersion.cmake \
gpgmepp_version.h GpgmeppConfig.cmake.in \ gpgmepp_version.h GpgmeppConfig.cmake.in
$(copied_headers)

View File

@ -76,7 +76,7 @@ gpgme_error_t passphrase_callback(void *opaque, const char *uid_hint, const char
PassphraseProvider *provider = static_cast<PassphraseProvider *>(opaque); PassphraseProvider *provider = static_cast<PassphraseProvider *>(opaque);
bool canceled = false; bool canceled = false;
gpgme_error_t err = GPG_ERR_NO_ERROR; gpgme_error_t err = GPG_ERR_NO_ERROR;
char *passphrase = provider ? provider->getPassphrase(uid_hint, desc, prev_was_bad, canceled) : nullptr ; char *passphrase = provider ? provider->getPassphrase(uid_hint, desc, prev_was_bad, canceled) : 0 ;
if (canceled) { if (canceled) {
err = make_error(GPG_ERR_CANCELED); err = make_error(GPG_ERR_CANCELED);
} else { } else {

View File

@ -64,7 +64,7 @@ std::vector<Component> Component::load(Error &returnedError)
// //
// 1. get a context: // 1. get a context:
// //
gpgme_ctx_t ctx_native = nullptr; gpgme_ctx_t ctx_native = 0;
if (const gpgme_error_t err = gpgme_new(&ctx_native)) { if (const gpgme_error_t err = gpgme_new(&ctx_native)) {
returnedError = Error(err); returnedError = Error(err);
return std::vector<Component>(); return std::vector<Component>();
@ -74,7 +74,7 @@ std::vector<Component> Component::load(Error &returnedError)
// //
// 2. load the config: // 2. load the config:
// //
gpgme_conf_comp_t conf_list_native = nullptr; gpgme_conf_comp_t conf_list_native = 0;
if (const gpgme_error_t err = gpgme_op_conf_load(ctx_native, &conf_list_native)) { if (const gpgme_error_t err = gpgme_op_conf_load(ctx_native, &conf_list_native)) {
returnedError = Error(err); returnedError = Error(err);
return std::vector<Component>(); return std::vector<Component>();
@ -94,7 +94,7 @@ std::vector<Component> Component::load(Error &returnedError)
} }
// now prevent double-free of next.get() and following: // now prevent double-free of next.get() and following:
head->next = nullptr; head->next = 0;
// now add a new Component to 'result' (may throw): // now add a new Component to 'result' (may throw):
result.resize(result.size() + 1); result.resize(result.size() + 1);
@ -115,7 +115,7 @@ Error Component::save() const
// //
// 1. get a context: // 1. get a context:
// //
gpgme_ctx_t ctx_native = nullptr; gpgme_ctx_t ctx_native = 0;
if (const gpgme_error_t err = gpgme_new(&ctx_native)) { if (const gpgme_error_t err = gpgme_new(&ctx_native)) {
return Error(err); return Error(err);
} }
@ -129,22 +129,22 @@ Error Component::save() const
const char *Component::name() const const char *Component::name() const
{ {
return comp ? comp->name : nullptr; return comp ? comp->name : 0 ;
} }
const char *Component::description() const const char *Component::description() const
{ {
return comp ? comp->description : nullptr ; return comp ? comp->description : 0 ;
} }
const char *Component::programName() const const char *Component::programName() const
{ {
return comp ? comp->program_name : nullptr ; return comp ? comp->program_name : 0 ;
} }
Option Component::option(unsigned int idx) const Option Component::option(unsigned int idx) const
{ {
gpgme_conf_opt_t opt = nullptr; gpgme_conf_opt_t opt = 0;
if (comp) { if (comp) {
opt = comp->options; opt = comp->options;
} }
@ -160,7 +160,7 @@ Option Component::option(unsigned int idx) const
Option Component::option(const char *name) const Option Component::option(const char *name) const
{ {
gpgme_conf_opt_t opt = nullptr; gpgme_conf_opt_t opt = 0;
if (comp) { if (comp) {
opt = comp->options; opt = comp->options;
} }
@ -177,7 +177,7 @@ Option Component::option(const char *name) const
unsigned int Component::numOptions() const unsigned int Component::numOptions() const
{ {
unsigned int result = 0; unsigned int result = 0;
for (gpgme_conf_opt_t opt = comp ? comp->options : nullptr ; opt ; opt = opt->next) { for (gpgme_conf_opt_t opt = comp ? comp->options : 0 ; opt ; opt = opt->next) {
++result; ++result;
} }
return result; return result;
@ -186,7 +186,7 @@ unsigned int Component::numOptions() const
std::vector<Option> Component::options() const std::vector<Option> Component::options() const
{ {
std::vector<Option> result; std::vector<Option> result;
for (gpgme_conf_opt_t opt = comp ? comp->options : nullptr ; opt ; opt = opt->next) { for (gpgme_conf_opt_t opt = comp ? comp->options : 0 ; opt ; opt = opt->next) {
result.push_back(Option(comp, opt)); result.push_back(Option(comp, opt));
} }
return result; return result;
@ -194,17 +194,17 @@ std::vector<Option> Component::options() const
static gpgme_conf_arg_t mygpgme_conf_arg_copy(gpgme_conf_arg_t other, gpgme_conf_type_t type) static gpgme_conf_arg_t mygpgme_conf_arg_copy(gpgme_conf_arg_t other, gpgme_conf_type_t type)
{ {
gpgme_conf_arg_t result = nullptr, last = nullptr; gpgme_conf_arg_t result = 0, last = 0;
for (gpgme_conf_arg_t a = other ; a ; a = a->next) { for (gpgme_conf_arg_t a = other ; a ; a = a->next) {
gpgme_conf_arg_t arg = nullptr; gpgme_conf_arg_t arg = 0;
const gpgme_error_t err const gpgme_error_t err
= gpgme_conf_arg_new(&arg, type, = gpgme_conf_arg_new(&arg, type,
a->no_arg ? nullptr : a->no_arg ? 0 :
type == GPGME_CONF_STRING ? a->value.string : type == GPGME_CONF_STRING ? a->value.string :
/* else */ static_cast<void *>(&a->value)); /* else */ static_cast<void *>(&a->value));
if (err) { if (err) {
gpgme_conf_arg_release(result, type); gpgme_conf_arg_release(result, type);
return nullptr; return 0;
} }
assert(arg); assert(arg);
if (result) { if (result) {
@ -234,17 +234,17 @@ Level Option::level() const
const char *Option::name() const const char *Option::name() const
{ {
return isNull() ? nullptr : opt->name ; return isNull() ? 0 : opt->name ;
} }
const char *Option::description() const const char *Option::description() const
{ {
return isNull() ? nullptr : opt->description ; return isNull() ? 0 : opt->description ;
} }
const char *Option::argumentName() const const char *Option::argumentName() const
{ {
return isNull() ? nullptr : opt->argname ; return isNull() ? 0 : opt->argname ;
} }
Type Option::type() const Type Option::type() const
@ -257,6 +257,158 @@ Type Option::alternateType() const
return isNull() ? NoType : static_cast<Type>(opt->alt_type) ; return isNull() ? NoType : static_cast<Type>(opt->alt_type) ;
} }
#if 0
static Option::Variant argument_to_variant(gpgme_conf_type_t type, bool list, gpgme_conf_arg_t arg)
{
assert(arg);
switch (type) {
case GPGME_CONF_NONE:
if (list) {
// return the count (number of times set):
return arg->value.count;
} else {
return none;
}
case GPGME_CONF_INT32:
if (list) {
std::vector<int> result;
for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
result.push_back(a->value.int32);
}
return result;
} else {
return arg->value.int32;
}
case GPGME_CONF_UINT32:
if (list) {
std::vector<unsigned int> result;
for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
result.push_back(a->value.uint32);
}
return result;
} else {
return arg->value.uint32;
}
case GPGME_CONF_FILENAME:
case GPGME_CONF_LDAP_SERVER:
case GPGME_CONF_KEY_FPR:
case GPGME_CONF_PUB_KEY:
case GPGME_CONF_SEC_KEY:
case GPGME_CONF_ALIAS_LIST:
// these should not happen in alt_type, but fall through
case GPGME_CONF_STRING:
if (list) {
std::vector<const char *> result;
for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
result.push_back(a->value.string);
}
return result;
} else {
return arg->value.string;
}
}
assert(!"Option: unknown alt_type!");
return Option::Variant();
}
namespace
{
inline const void *to_void_star(const char *s)
{
return s;
}
inline const void *to_void_star(const std::string &s)
{
return s.c_str();
}
inline const void *to_void_star(const int &i)
{
return &i; // const-&: sic!
}
inline const void *to_void_star(const unsigned int &i)
{
return &i; // const-&: sic!
}
struct VariantToArgumentVisitor : boost::static_visitor<gpgme_conf_arg_t> {
static gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const void *value)
{
gpgme_conf_arg_t arg = 0;
#ifdef HAVE_GPGME_CONF_ARG_NEW_WITH_CONST_VALUE
if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, value)) {
return 0;
}
#else
if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, const_cast<void *>(value))) {
return 0;
}
#endif
else {
return arg;
}
}
gpgme_conf_arg_t operator()(bool v) const
{
return v ? make_argument(0) : 0 ;
}
gpgme_conf_arg_t operator()(const char *s) const
{
return make_argument(s ? s : "");
}
gpgme_conf_arg_t operator()(const std::string &s) const
{
return operator()(s.c_str());
}
gpgme_conf_arg_t operator()(int i) const
{
return make_argument(&i);
}
gpgme_conf_arg_t operator()(unsigned int i) const
{
return make_argument(&i);
}
template <typename T>
gpgme_conf_arg_t operator()(const std::vector<T> &value) const
{
gpgme_conf_arg_t result = 0;
gpgme_conf_arg_t last = 0;
for (typename std::vector<T>::const_iterator it = value.begin(), end = value.end() ; it != end ; ++it) {
if (gpgme_conf_arg_t arg = make_argument(to_void_star(*it))) {
if (last) {
last = last->next = arg;
} else {
result = last = arg;
}
}
}
return result;
}
};
}
static gpgme_conf_arg_t variant_to_argument(const Option::Variant &value)
{
VariantToArgumentVisitor v;
return apply_visitor(v, value);
}
optional<Option::Variant> Option::defaultValue() const
{
if (isNull()) {
return optional<Variant>();
} else {
return argument_to_variant(opt->alt_type, opt->flags & GPGME_CONF_LIST, opt->default_value);
}
}
#endif
Argument Option::defaultValue() const Argument Option::defaultValue() const
{ {
if (isNull()) { if (isNull()) {
@ -268,7 +420,7 @@ Argument Option::defaultValue() const
const char *Option::defaultDescription() const const char *Option::defaultDescription() const
{ {
return isNull() ? nullptr : opt->default_description ; return isNull() ? 0 : opt->default_description ;
} }
Argument Option::noArgumentValue() const Argument Option::noArgumentValue() const
@ -282,7 +434,7 @@ Argument Option::noArgumentValue() const
const char *Option::noArgumentDescription() const const char *Option::noArgumentDescription() const
{ {
return isNull() ? nullptr : opt->no_arg_description ; return isNull() ? 0 : opt->no_arg_description ;
} }
Argument Option::activeValue() const Argument Option::activeValue() const
@ -349,7 +501,7 @@ Error Option::resetToActiveValue()
if (isNull()) { if (isNull()) {
return Error(make_error(GPG_ERR_INV_ARG)); return Error(make_error(GPG_ERR_INV_ARG));
} else { } else {
return Error(gpgme_conf_opt_change(opt, 1, nullptr)); return Error(gpgme_conf_opt_change(opt, 1, 0));
} }
} }
@ -358,15 +510,15 @@ Error Option::resetToDefaultValue()
if (isNull()) { if (isNull()) {
return Error(make_error(GPG_ERR_INV_ARG)); return Error(make_error(GPG_ERR_INV_ARG));
} else { } else {
return Error(gpgme_conf_opt_change(opt, 0, nullptr)); return Error(gpgme_conf_opt_change(opt, 0, 0));
} }
} }
static gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const void *value) static gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const void *value)
{ {
gpgme_conf_arg_t arg = nullptr; gpgme_conf_arg_t arg = 0;
if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, value)) { if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, value)) {
return nullptr; return 0;
} else { } else {
return arg; return arg;
} }
@ -442,8 +594,8 @@ const void *to_void_star(const unsigned int &i)
template <typename T> template <typename T>
gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const std::vector<T> &value) gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const std::vector<T> &value)
{ {
gpgme_conf_arg_t result = nullptr; gpgme_conf_arg_t result = 0;
gpgme_conf_arg_t last = nullptr; gpgme_conf_arg_t last = 0;
for (typename std::vector<T>::const_iterator it = value.begin(), end = value.end() ; it != end ; ++it) { for (typename std::vector<T>::const_iterator it = value.begin(), end = value.end() ; it != end ; ++it) {
if (gpgme_conf_arg_t arg = make_argument(type, to_void_star(*it))) { if (gpgme_conf_arg_t arg = make_argument(type, to_void_star(*it))) {
if (last) { if (last) {
@ -541,14 +693,14 @@ unsigned int Argument::numElements() const
const char *Argument::stringValue(unsigned int idx) const const char *Argument::stringValue(unsigned int idx) const
{ {
if (isNull() || opt->alt_type != GPGME_CONF_STRING) { if (isNull() || opt->alt_type != GPGME_CONF_STRING) {
return nullptr; return 0;
} }
gpgme_conf_arg_t a = arg; gpgme_conf_arg_t a = arg;
while (a && idx) { while (a && idx) {
a = a->next; a = a->next;
--idx; --idx;
} }
return a ? a->value.string : nullptr ; return a ? a->value.string : 0 ;
} }
int Argument::intValue(unsigned int idx) const int Argument::intValue(unsigned int idx) const

View File

@ -98,7 +98,8 @@ public:
explicit Component(const shared_gpgme_conf_comp_t &gpgme_comp) explicit Component(const shared_gpgme_conf_comp_t &gpgme_comp)
: comp(gpgme_comp) {} : comp(gpgme_comp) {}
Component(const Component &other) = default; // copy ctor is ok
const Component &operator=(const Component &other) const Component &operator=(const Component &other)
{ {
if (this != &other) { if (this != &other) {
@ -144,11 +145,10 @@ private:
class GPGMEPP_EXPORT Option class GPGMEPP_EXPORT Option
{ {
public: public:
Option() : comp(), opt(nullptr) {} Option() : comp(), opt(0) {}
Option(const shared_gpgme_conf_comp_t &gpgme_comp, gpgme_conf_opt_t gpgme_opt) Option(const shared_gpgme_conf_comp_t &gpgme_comp, gpgme_conf_opt_t gpgme_opt)
: comp(gpgme_comp), opt(gpgme_opt) {} : comp(gpgme_comp), opt(gpgme_opt) {}
Option(const Option &other) = default;
const Option &operator=(const Option &other) const Option &operator=(const Option &other)
{ {
if (this != &other) { if (this != &other) {
@ -190,7 +190,7 @@ public:
/*! The value that is in the config file (or null, if it's not set). */ /*! The value that is in the config file (or null, if it's not set). */
Argument activeValue() const; Argument activeValue() const;
/*! The value that is in this object, i.e. either activeValue(), newValue(), or defaultValue() */ /*! The value that is in this object, ie. either activeValue(), newValue(), or defaultValue() */
Argument currentValue() const; Argument currentValue() const;
Argument newValue() const; Argument newValue() const;
@ -228,7 +228,7 @@ class GPGMEPP_EXPORT Argument
friend class ::GpgME::Configuration::Option; friend class ::GpgME::Configuration::Option;
Argument(const shared_gpgme_conf_comp_t &comp, gpgme_conf_opt_t opt, gpgme_conf_arg_t arg, bool owns); Argument(const shared_gpgme_conf_comp_t &comp, gpgme_conf_opt_t opt, gpgme_conf_arg_t arg, bool owns);
public: public:
Argument() : comp(), opt(nullptr), arg(nullptr) {} Argument() : comp(), opt(0), arg(0) {}
//Argument( const shared_gpgme_conf_comp_t & comp, gpgme_conf_opt_t opt, gpgme_conf_arg_t arg ); //Argument( const shared_gpgme_conf_comp_t & comp, gpgme_conf_opt_t opt, gpgme_conf_arg_t arg );
Argument(const Argument &other); Argument(const Argument &other);
~Argument(); ~Argument();

File diff suppressed because it is too large Load Diff

View File

@ -27,11 +27,9 @@
#include "global.h" #include "global.h"
#include "error.h" #include "error.h"
#include "key.h"
#include "verificationresult.h" // for Signature::Notation #include "verificationresult.h" // for Signature::Notation
#include <memory> #include <memory>
#include <string>
#include <vector> #include <vector>
#include <utility> #include <utility>
#include <iosfwd> #include <iosfwd>
@ -39,6 +37,7 @@
namespace GpgME namespace GpgME
{ {
class Key;
class Data; class Data;
class TrustItem; class TrustItem;
class ProgressProvider; class ProgressProvider;
@ -64,25 +63,12 @@ class GPGMEPP_EXPORT Context
public: public:
//using GpgME::Protocol; //using GpgME::Protocol;
/// RAII-style class for saving/restoring the key list mode.
class GPGMEPP_EXPORT KeyListModeSaver
{
public:
explicit KeyListModeSaver(Context *ctx);
~KeyListModeSaver();
private:
Context *mCtx;
unsigned int mKeyListMode;
};
// //
// Creation and destruction: // Creation and destruction:
// //
static Context *createForProtocol(Protocol proto); static Context *createForProtocol(Protocol proto);
/** Same as above but returning a unique ptr. */ static std::unique_ptr<Context> createForEngine(Engine engine, Error *err = 0);
static std::unique_ptr<Context> create(Protocol proto);
static std::unique_ptr<Context> createForEngine(Engine engine, Error *err = nullptr);
virtual ~Context(); virtual ~Context();
// //
@ -100,9 +86,6 @@ public:
void setOffline(bool useOfflineMode); void setOffline(bool useOfflineMode);
bool offline() const; bool offline() const;
const char *getFlag(const char *name) const;
Error setFlag(const char *name, const char *value);
enum CertificateInclusion { enum CertificateInclusion {
DefaultCertificates = -256, DefaultCertificates = -256,
AllCertificatesExceptRoot = -2, AllCertificatesExceptRoot = -2,
@ -173,7 +156,7 @@ public:
// Key Listing // Key Listing
// //
GpgME::Error startKeyListing(const char *pattern = nullptr, bool secretOnly = false); GpgME::Error startKeyListing(const char *pattern = 0, bool secretOnly = false);
GpgME::Error startKeyListing(const char *patterns[], bool secretOnly = false); GpgME::Error startKeyListing(const char *patterns[], bool secretOnly = false);
Key nextKey(GpgME::Error &e); Key nextKey(GpgME::Error &e);
@ -194,42 +177,11 @@ public:
// //
// Key Export // Key Export
// //
enum ExportMode {
ExportDefault = 0,
ExportExtern = 2,
ExportMinimal = 4,
ExportSecret = 16,
ExportRaw = 32,
ExportPKCS12 = 64,
ExportNoUID = 128, // obsolete; has no effect
ExportSSH = 256,
ExportSecretSubkey = 512,
};
GpgME::Error exportPublicKeys(const char *pattern, Data &keyData); GpgME::Error exportPublicKeys(const char *pattern, Data &keyData);
GpgME::Error exportPublicKeys(const char *pattern, Data &keyData, unsigned int mode);
GpgME::Error exportPublicKeys(const char *pattern[], Data &keyData); GpgME::Error exportPublicKeys(const char *pattern[], Data &keyData);
GpgME::Error exportPublicKeys(const char *pattern[], Data &keyData, unsigned int mode);
GpgME::Error startPublicKeyExport(const char *pattern, Data &keyData); GpgME::Error startPublicKeyExport(const char *pattern, Data &keyData);
GpgME::Error startPublicKeyExport(const char *pattern, Data &keyData, unsigned int mode);
GpgME::Error startPublicKeyExport(const char *pattern[], Data &keyData); GpgME::Error startPublicKeyExport(const char *pattern[], Data &keyData);
GpgME::Error startPublicKeyExport(const char *pattern[], Data &keyData, unsigned int mode);
GpgME::Error exportSecretKeys(const char *pattern, Data &keyData, unsigned int mode = ExportSecret);
GpgME::Error exportSecretKeys(const char *pattern[], Data &keyData, unsigned int mode = ExportSecret);
GpgME::Error startSecretKeyExport(const char *pattern, Data &keyData, unsigned int mode = ExportSecret);
GpgME::Error startSecretKeyExport(const char *pattern[], Data &keyData, unsigned int mode = ExportSecret);
GpgME::Error exportSecretSubkeys(const char *pattern, Data &keyData, unsigned int mode = ExportSecretSubkey);
GpgME::Error exportSecretSubkeys(const char *pattern[], Data &keyData, unsigned int mode = ExportSecretSubkey);
GpgME::Error startSecretSubkeyExport(const char *pattern, Data &keyData, unsigned int mode = ExportSecretSubkey);
GpgME::Error startSecretSubkeyExport(const char *pattern[], Data &keyData, unsigned int mode = ExportSecretSubkey);
// generic export functions; prefer using the specific public/secret key export functions
GpgME::Error exportKeys(const char *pattern, Data &keyData, unsigned int mode = ExportDefault);
GpgME::Error exportKeys(const char *pattern[], Data &keyData, unsigned int mode = ExportDefault);
GpgME::Error startKeyExport(const char *pattern, Data &keyData, unsigned int mode = ExportDefault);
GpgME::Error startKeyExport(const char *pattern[], Data &keyData, unsigned int mode = ExportDefault);
// //
// Key Import // Key Import
@ -237,10 +189,8 @@ public:
ImportResult importKeys(const Data &data); ImportResult importKeys(const Data &data);
ImportResult importKeys(const std::vector<Key> &keys); ImportResult importKeys(const std::vector<Key> &keys);
ImportResult importKeys(const std::vector<std::string> &keyIds);
GpgME::Error startKeyImport(const Data &data); GpgME::Error startKeyImport(const Data &data);
GpgME::Error startKeyImport(const std::vector<Key> &keys); GpgME::Error startKeyImport(const std::vector<Key> &keys);
GpgME::Error startKeyImport(const std::vector<std::string> &keyIds);
ImportResult importResult() const; ImportResult importResult() const;
// //
@ -281,23 +231,12 @@ public:
const Key &certkey, const Key &certkey,
unsigned int flags); unsigned int flags);
// Same as create key but returning a result
GpgME::KeyGenerationResult createKeyEx (const char *userid,
const char *algo,
unsigned long reserved,
unsigned long expires,
const Key &certkey,
unsigned int flags);
Error addUid(const Key &key, const char *userid); Error addUid(const Key &key, const char *userid);
Error startAddUid(const Key &key, const char *userid); Error startAddUid(const Key &key, const char *userid);
Error revUid(const Key &key, const char *userid); Error revUid(const Key &key, const char *userid);
Error startRevUid(const Key &key, const char *userid); Error startRevUid(const Key &key, const char *userid);
Error setPrimaryUid(const Key &key, const char *userid);
Error startSetPrimaryUid(const Key &key, const char *userid);
Error createSubkey(const Key &key, const char *algo, Error createSubkey(const Key &key, const char *algo,
unsigned long reserved = 0, unsigned long reserved = 0,
unsigned long expires = 0, unsigned long expires = 0,
@ -307,26 +246,6 @@ public:
unsigned long expires = 0, unsigned long expires = 0,
unsigned int flags = 0); unsigned int flags = 0);
enum SetExpireFlags {
SetExpireDefault = 0,
SetExpireAllSubkeys = 1
};
Error setExpire(const Key &k, unsigned long expires,
const std::vector<Subkey> &subkeys = std::vector<Subkey>(),
const SetExpireFlags flags = SetExpireDefault);
Error startSetExpire(const Key &k, unsigned long expires,
const std::vector<Subkey> &subkeys = std::vector<Subkey>(),
const SetExpireFlags flags = SetExpireDefault);
Error revokeSignature(const Key &key, const Key &signingKey,
const std::vector<UserID> &userIds = std::vector<UserID>());
Error startRevokeSignature(const Key &key, const Key &signingKey,
const std::vector<UserID> &userIds = std::vector<UserID>());
Error addAdsk(const Key &k, const char *adsk);
Error startAddAdsk(const Key &k, const char *adsk);
// using TofuInfo::Policy // using TofuInfo::Policy
Error setTofuPolicy(const Key &k, unsigned int policy); Error setTofuPolicy(const Key &k, unsigned int policy);
Error setTofuPolicyStart(const Key &k, unsigned int policy); Error setTofuPolicyStart(const Key &k, unsigned int policy);
@ -373,7 +292,6 @@ public:
// Keep in line with core's flags // Keep in line with core's flags
DecryptNone = 0, DecryptNone = 0,
DecryptVerify = 1, DecryptVerify = 1,
DecryptArchive = 2,
DecryptUnwrap = 128, DecryptUnwrap = 128,
DecryptMaxValue = 0x80000000 DecryptMaxValue = 0x80000000
}; };
@ -451,10 +369,7 @@ public:
NoCompress = 16, NoCompress = 16,
Symmetric = 32, Symmetric = 32,
ThrowKeyIds = 64, ThrowKeyIds = 64,
EncryptWrap = 128, EncryptWrap = 128
WantAddress = 256,
EncryptArchive = 512,
EncryptFile = 1024
}; };
EncryptionResult encrypt(const std::vector<Key> &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags); EncryptionResult encrypt(const std::vector<Key> &recipients, const Data &plainText, Data &cipherText, EncryptionFlags flags);
GpgME::Error encryptSymmetrically(const Data &plainText, Data &cipherText); GpgME::Error encryptSymmetrically(const Data &plainText, Data &cipherText);
@ -475,9 +390,7 @@ public:
// //
// //
enum AuditLogFlags { enum AuditLogFlags {
DefaultAuditLog = 0,
HtmlAuditLog = 1, HtmlAuditLog = 1,
DiagnosticAuditLog = 2,
AuditLogWithHelp = 128 AuditLogWithHelp = 128
}; };
GpgME::Error startGetAuditLog(Data &output, unsigned int flags = 0); GpgME::Error startGetAuditLog(Data &output, unsigned int flags = 0);
@ -530,7 +443,6 @@ public:
GpgME::Error wait(); GpgME::Error wait();
GpgME::Error lastError() const; GpgME::Error lastError() const;
GpgME::Error cancelPendingOperation(); GpgME::Error cancelPendingOperation();
GpgME::Error cancelPendingOperationImmediately();
class Private; class Private;
const Private *impl() const const Private *impl() const
@ -541,7 +453,6 @@ public:
{ {
return d; return d;
} }
private: private:
// Helper functions that need to be context because they rely // Helper functions that need to be context because they rely
// on the "Friendlyness" of context to access the gpgme types. // on the "Friendlyness" of context to access the gpgme types.

View File

@ -1,7 +1,8 @@
/* /*
statusconsumer.h - Interface for status callbacks context_glib.cpp - wraps a gpgme key context, gpgme-glib-specific functions
Copyright (c) 2020 g10 Code GmbH Copyright (C) 2007 Klarälvdalens Datakonsult AB
Software engineering by Ingo Klöcker <dev@ingo-kloecker.de> 2016 Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH
This file is part of GPGME++. This file is part of GPGME++.
@ -21,22 +22,20 @@
Boston, MA 02110-1301, USA. Boston, MA 02110-1301, USA.
*/ */
#ifndef __GPGMEPP_INTERFACES_STATUSCONSUMER_H__ #ifdef HAVE_CONFIG_H
#define __GPGMEPP_INTERFACES_STATUSCONSUMER_H__ #include "config.h"
#endif
#include "../gpgmepp_export.h" #include <global.h>
namespace GpgME extern "C" GIOChannel *gpgme_get_fdptr(int);
GIOChannel *GpgME::getGIOChannel(int fd)
{ {
return gpgme_get_fdptr(fd);
}
class GPGMEPP_EXPORT StatusConsumer QIODevice *GpgME::getQIODevice(int fd)
{ {
public: return 0;
virtual ~StatusConsumer() {} }
virtual void status(const char *status, const char *details) = 0;
};
} // namespace GpgME
#endif // __GPGMEPP_INTERFACES_STATUSCONSUMER_H__

View File

@ -53,7 +53,6 @@ public:
KeyGen = 0x080, KeyGen = 0x080,
KeyList = 0x100, KeyList = 0x100,
KeyListWithImport = KeyList | Import, // gpgme_keylist_result_t and gpgme_import_result_t
TrustList = 0x200, // no gpgme_trustlist_result_t, but nevertheless... TrustList = 0x200, // no gpgme_trustlist_result_t, but nevertheless...
Edit = 0x400, // no gpgme_edit_result_t, but nevertheless... Edit = 0x400, // no gpgme_edit_result_t, but nevertheless...
@ -70,7 +69,7 @@ public:
EndMarker EndMarker
}; };
Private(gpgme_ctx_t c = nullptr); Private(gpgme_ctx_t c = 0);
~Private(); ~Private();
gpgme_ctx_t ctx; gpgme_ctx_t ctx;

View File

@ -1,7 +1,8 @@
/* /*
util.cpp - some internal helpers context_qt.cpp - wraps a gpgme key context, gpgme-qt-specific functions
Copyright (c) 2022 g10 Code GmbH Copyright (C) 2007 Klarälvdalens Datakonsult AB
Software engineering by Ingo Klöcker <dev@ingo-kloecker.de> 2016 Bundesamt für Sicherheit in der Informationstechnik
Software engineering by Intevation GmbH
This file is part of GPGME++. This file is part of GPGME++.
@ -25,23 +26,16 @@
#include "config.h" #include "config.h"
#endif #endif
#include "util.h" #include <global.h>
#include <functional> extern "C" QIODevice *gpgme_get_fdptr(int);
StringsToCStrings::StringsToCStrings(const std::vector<std::string>& v) GIOChannel *GpgME::getGIOChannel(int)
: m_strings{v}
{ {
return 0;
} }
const char **StringsToCStrings::c_strs() const QIODevice *GpgME::getQIODevice(int fd)
{ {
if (m_cstrings.empty()) { return gpgme_get_fdptr(fd);
m_cstrings.reserve(m_strings.size() + 1);
std::transform(std::begin(m_strings), std::end(m_strings),
std::back_inserter(m_cstrings),
std::mem_fn(&std::string::c_str));
m_cstrings.push_back(nullptr);
}
return m_cstrings.data();
} }

View File

@ -30,10 +30,10 @@
GIOChannel *GpgME::getGIOChannel(int) GIOChannel *GpgME::getGIOChannel(int)
{ {
return nullptr; return 0;
} }
QIODevice *GpgME::getQIODevice(int) QIODevice *GpgME::getQIODevice(int)
{ {
return nullptr; return 0;
} }

View File

@ -48,11 +48,11 @@ GpgME::Data::Data()
{ {
gpgme_data_t data; gpgme_data_t data;
const gpgme_error_t e = gpgme_data_new(&data); const gpgme_error_t e = gpgme_data_new(&data);
d.reset(new Private(e ? nullptr : data)); d.reset(new Private(e ? 0 : data));
} }
GpgME::Data::Data(const Null &) GpgME::Data::Data(const Null &)
: d(new Private(nullptr)) : d(new Private(0))
{ {
} }
@ -70,14 +70,14 @@ GpgME::Data::Data(const char *buffer, size_t size, bool copy)
std::string sizestr = std::to_string(size); std::string sizestr = std::to_string(size);
// Ignore errors as this is optional // Ignore errors as this is optional
gpgme_data_set_flag(data, "size-hint", sizestr.c_str()); gpgme_data_set_flag(data, "size-hint", sizestr.c_str());
d.reset(new Private(e ? nullptr : data)); d.reset(new Private(e ? 0 : data));
} }
GpgME::Data::Data(const char *filename) GpgME::Data::Data(const char *filename)
{ {
gpgme_data_t data; gpgme_data_t data;
const gpgme_error_t e = gpgme_data_new(&data); const gpgme_error_t e = gpgme_data_new(&data);
d.reset(new Private(e ? nullptr : data)); d.reset(new Private(e ? 0 : data));
if (!e) { if (!e) {
setFileName(filename); setFileName(filename);
} }
@ -86,29 +86,29 @@ GpgME::Data::Data(const char *filename)
GpgME::Data::Data(const char *filename, off_t offset, size_t length) GpgME::Data::Data(const char *filename, off_t offset, size_t length)
{ {
gpgme_data_t data; gpgme_data_t data;
const gpgme_error_t e = gpgme_data_new_from_filepart(&data, filename, nullptr, offset, length); const gpgme_error_t e = gpgme_data_new_from_filepart(&data, filename, 0, offset, length);
d.reset(new Private(e ? nullptr : data)); d.reset(new Private(e ? 0 : data));
} }
GpgME::Data::Data(FILE *fp) GpgME::Data::Data(FILE *fp)
{ {
gpgme_data_t data; gpgme_data_t data;
const gpgme_error_t e = gpgme_data_new_from_stream(&data, fp); const gpgme_error_t e = gpgme_data_new_from_stream(&data, fp);
d.reset(new Private(e ? nullptr : data)); d.reset(new Private(e ? 0 : data));
} }
GpgME::Data::Data(FILE *fp, off_t offset, size_t length) GpgME::Data::Data(FILE *fp, off_t offset, size_t length)
{ {
gpgme_data_t data; gpgme_data_t data;
const gpgme_error_t e = gpgme_data_new_from_filepart(&data, nullptr, fp, offset, length); const gpgme_error_t e = gpgme_data_new_from_filepart(&data, 0, fp, offset, length);
d.reset(new Private(e ? nullptr : data)); d.reset(new Private(e ? 0 : data));
} }
GpgME::Data::Data(int fd) GpgME::Data::Data(int fd)
{ {
gpgme_data_t data; gpgme_data_t data;
const gpgme_error_t e = gpgme_data_new_from_fd(&data, fd); const gpgme_error_t e = gpgme_data_new_from_fd(&data, fd);
d.reset(new Private(e ? nullptr : data)); d.reset(new Private(e ? 0 : data));
} }
GpgME::Data::Data(DataProvider *dp) GpgME::Data::Data(DataProvider *dp)
@ -118,20 +118,20 @@ GpgME::Data::Data(DataProvider *dp)
return; return;
} }
if (!dp->isSupported(DataProvider::Read)) { if (!dp->isSupported(DataProvider::Read)) {
d->cbs.read = nullptr; d->cbs.read = 0;
} }
if (!dp->isSupported(DataProvider::Write)) { if (!dp->isSupported(DataProvider::Write)) {
d->cbs.write = nullptr; d->cbs.write = 0;
} }
if (!dp->isSupported(DataProvider::Seek)) { if (!dp->isSupported(DataProvider::Seek)) {
d->cbs.seek = nullptr; d->cbs.seek = 0;
} }
if (!dp->isSupported(DataProvider::Release)) { if (!dp->isSupported(DataProvider::Release)) {
d->cbs.release = nullptr; d->cbs.release = 0;
} }
const gpgme_error_t e = gpgme_data_new_from_cbs(&d->data, &d->cbs, dp); const gpgme_error_t e = gpgme_data_new_from_cbs(&d->data, &d->cbs, dp);
if (e) { if (e) {
d->data = nullptr; d->data = 0;
} }
if (dp->isSupported(DataProvider::Seek)) { if (dp->isSupported(DataProvider::Seek)) {
off_t size = seek(0, SEEK_END); off_t size = seek(0, SEEK_END);
@ -217,11 +217,6 @@ GpgME::Error GpgME::Data::setFileName(const char *name)
return Error(gpgme_data_set_file_name(d->data, name)); return Error(gpgme_data_set_file_name(d->data, name));
} }
GpgME::Error GpgME::Data::setFileName(const std::string &name)
{
return Error(gpgme_data_set_file_name(d->data, name.c_str()));
}
ssize_t GpgME::Data::read(void *buffer, size_t length) ssize_t GpgME::Data::read(void *buffer, size_t length)
{ {
return gpgme_data_read(d->data, buffer, length); return gpgme_data_read(d->data, buffer, length);
@ -237,11 +232,6 @@ off_t GpgME::Data::seek(off_t offset, int whence)
return gpgme_data_seek(d->data, offset, whence); return gpgme_data_seek(d->data, offset, whence);
} }
GpgME::Error GpgME::Data::rewind()
{
return Error(gpgme_data_rewind(d->data));
}
std::vector<GpgME::Key> GpgME::Data::toKeys(Protocol proto) const std::vector<GpgME::Key> GpgME::Data::toKeys(Protocol proto) const
{ {
std::vector<GpgME::Key> ret; std::vector<GpgME::Key> ret;
@ -261,8 +251,6 @@ std::vector<GpgME::Key> GpgME::Data::toKeys(Protocol proto) const
while (!gpgme_op_keylist_next (ctx->impl()->ctx, &key)) { while (!gpgme_op_keylist_next (ctx->impl()->ctx, &key)) {
ret.push_back(GpgME::Key(key, false)); ret.push_back(GpgME::Key(key, false));
} }
gpgme_data_seek (d->data, 0, SEEK_SET);
delete ctx; delete ctx;
return ret; return ret;
} }
@ -280,14 +268,3 @@ std::string GpgME::Data::toString()
seek (0, SEEK_SET); seek (0, SEEK_SET);
return ret; return ret;
} }
GpgME::Error GpgME::Data::setFlag(const char *name, const char *value)
{
return Error(gpgme_data_set_flag(d->data, name, value));
}
GpgME::Error GpgME::Data::setSizeHint(uint64_t size)
{
const std::string val = std::to_string(size);
return Error(gpgme_data_set_flag(d->data, "size-hint", val.c_str()));
}

View File

@ -27,7 +27,6 @@
#include "key.h" #include "key.h"
#include <sys/types.h> // for size_t, off_t #include <sys/types.h> // for size_t, off_t
#include <cstdint> // unit64_t
#include <cstdio> // FILE #include <cstdio> // FILE
#include <algorithm> #include <algorithm>
#include <memory> #include <memory>
@ -61,7 +60,6 @@ public:
static const Null null; static const Null null;
Data(const Data &other) = default;
const Data &operator=(Data other) const Data &operator=(Data other)
{ {
swap(other); swap(other);
@ -107,15 +105,11 @@ public:
char *fileName() const; char *fileName() const;
Error setFileName(const char *name); Error setFileName(const char *name);
Error setFileName(const std::string &name);
ssize_t read(void *buffer, size_t length); ssize_t read(void *buffer, size_t length);
ssize_t write(const void *buffer, size_t length); ssize_t write(const void *buffer, size_t length);
off_t seek(off_t offset, int whence); off_t seek(off_t offset, int whence);
/* Convenience function to do a seek (0, SEEK_SET). */
Error rewind();
/** Try to parse the data to a key object using the /** Try to parse the data to a key object using the
* Protocol proto. Returns an empty list on error.*/ * Protocol proto. Returns an empty list on error.*/
std::vector<Key> toKeys(const Protocol proto = Protocol::OpenPGP) const; std::vector<Key> toKeys(const Protocol proto = Protocol::OpenPGP) const;
@ -123,12 +117,6 @@ public:
/** Return a copy of the data as std::string. Sets seek pos to 0 */ /** Return a copy of the data as std::string. Sets seek pos to 0 */
std::string toString(); std::string toString();
/** See gpgme_data_set_flag */
Error setFlag(const char *name, const char *value);
/** Set a size hint for this data e.g. for progress calculations. */
Error setSizeHint(uint64_t size);
class Private; class Private;
Private *impl() Private *impl()
{ {

View File

@ -31,7 +31,7 @@
class GpgME::Data::Private class GpgME::Data::Private
{ {
public: public:
explicit Private(gpgme_data_t d = nullptr) explicit Private(gpgme_data_t d = 0)
: data(d), cbs(data_provider_callbacks) {} : data(d), cbs(data_provider_callbacks) {}
~Private(); ~Private();

View File

@ -51,30 +51,23 @@ public:
if (res.file_name) { if (res.file_name) {
res.file_name = strdup(res.file_name); res.file_name = strdup(res.file_name);
} }
if (res.symkey_algo) {
res.symkey_algo = strdup(res.symkey_algo);
}
//FIXME: copying gpgme_recipient_t objects invalidates the keyid member, //FIXME: copying gpgme_recipient_t objects invalidates the keyid member,
//thus we use _keyid for now (internal API) //thus we use _keyid for now (internal API)
for (gpgme_recipient_t r = res.recipients ; r ; r = r->next) { for (gpgme_recipient_t r = res.recipients ; r ; r = r->next) {
recipients.push_back(*r); recipients.push_back(*r);
} }
res.recipients = nullptr; res.recipients = 0;
} }
~Private() ~Private()
{ {
if (res.unsupported_algorithm) { if (res.unsupported_algorithm) {
std::free(res.unsupported_algorithm); std::free(res.unsupported_algorithm);
} }
res.unsupported_algorithm = nullptr; res.unsupported_algorithm = 0;
if (res.file_name) { if (res.file_name) {
std::free(res.file_name); std::free(res.file_name);
} }
res.file_name = nullptr; res.file_name = 0;
if (res.symkey_algo) {
std::free(res.symkey_algo);
}
res.symkey_algo = nullptr;
} }
_gpgme_op_decrypt_result res; _gpgme_op_decrypt_result res;
@ -109,7 +102,7 @@ make_standard_stuff(DecryptionResult)
const char *GpgME::DecryptionResult::unsupportedAlgorithm() const const char *GpgME::DecryptionResult::unsupportedAlgorithm() const
{ {
return d ? d->res.unsupported_algorithm : nullptr ; return d ? d->res.unsupported_algorithm : 0 ;
} }
bool GpgME::DecryptionResult::isWrongKeyUsage() const bool GpgME::DecryptionResult::isWrongKeyUsage() const
@ -122,14 +115,9 @@ bool GpgME::DecryptionResult::isDeVs() const
return d && d->res.is_de_vs; return d && d->res.is_de_vs;
} }
bool GpgME::DecryptionResult::isMime() const
{
return d && d->res.is_mime;
}
const char *GpgME::DecryptionResult::fileName() const const char *GpgME::DecryptionResult::fileName() const
{ {
return d ? d->res.file_name : nullptr ; return d ? d->res.file_name : 0 ;
} }
unsigned int GpgME::DecryptionResult::numRecipients() const unsigned int GpgME::DecryptionResult::numRecipients() const
@ -177,11 +165,6 @@ const char *GpgME::DecryptionResult::symkeyAlgo() const
return d ? d->res.symkey_algo : nullptr; return d ? d->res.symkey_algo : nullptr;
} }
bool GpgME::DecryptionResult::isLegacyCipherNoMDC() const
{
return d && d->res.legacy_cipher_nomdc;
}
class GpgME::DecryptionResult::Recipient::Private : public _gpgme_recipient class GpgME::DecryptionResult::Recipient::Private : public _gpgme_recipient
{ {
public: public:
@ -213,7 +196,7 @@ const char *GpgME::DecryptionResult::Recipient::keyID() const
if (d) { if (d) {
return d->_keyid; return d->_keyid;
} }
return nullptr; return 0;
} }
const char *GpgME::DecryptionResult::Recipient::shortKeyID() const const char *GpgME::DecryptionResult::Recipient::shortKeyID() const
@ -222,7 +205,7 @@ const char *GpgME::DecryptionResult::Recipient::shortKeyID() const
if (d) { if (d) {
return d->_keyid + 8; return d->_keyid + 8;
} }
return nullptr; return 0;
} }
unsigned int GpgME::DecryptionResult::Recipient::publicKeyAlgorithm() const unsigned int GpgME::DecryptionResult::Recipient::publicKeyAlgorithm() const
@ -238,7 +221,7 @@ const char *GpgME::DecryptionResult::Recipient::publicKeyAlgorithmAsString() con
if (d) { if (d) {
return gpgme_pubkey_algo_name(d->pubkey_algo); return gpgme_pubkey_algo_name(d->pubkey_algo);
} }
return nullptr; return 0;
} }
GpgME::Error GpgME::DecryptionResult::Recipient::status() const GpgME::Error GpgME::DecryptionResult::Recipient::status() const
@ -258,7 +241,6 @@ std::ostream &GpgME::operator<<(std::ostream &os, const DecryptionResult &result
<< "\n unsupportedAlgorithm: " << protect(result.unsupportedAlgorithm()) << "\n unsupportedAlgorithm: " << protect(result.unsupportedAlgorithm())
<< "\n isWrongKeyUsage: " << result.isWrongKeyUsage() << "\n isWrongKeyUsage: " << result.isWrongKeyUsage()
<< "\n isDeVs " << result.isDeVs() << "\n isDeVs " << result.isDeVs()
<< "\n legacyCipherNoMDC " << result.isLegacyCipherNoMDC()
<< "\n symkeyAlgo: " << protect(result.symkeyAlgo()) << "\n symkeyAlgo: " << protect(result.symkeyAlgo())
<< "\n recipients:\n"; << "\n recipients:\n";
const std::vector<DecryptionResult::Recipient> recipients = result.recipients(); const std::vector<DecryptionResult::Recipient> recipients = result.recipients();

View File

@ -47,7 +47,6 @@ public:
DecryptionResult(gpgme_ctx_t ctx, const Error &err); DecryptionResult(gpgme_ctx_t ctx, const Error &err);
explicit DecryptionResult(const Error &err); explicit DecryptionResult(const Error &err);
DecryptionResult(const DecryptionResult &other) = default;
const DecryptionResult &operator=(DecryptionResult other) const DecryptionResult &operator=(DecryptionResult other)
{ {
swap(other); swap(other);
@ -75,7 +74,6 @@ public:
} }
bool isWrongKeyUsage() const; bool isWrongKeyUsage() const;
bool isDeVs() const; bool isDeVs() const;
bool isMime() const;
const char *fileName() const; const char *fileName() const;
@ -89,8 +87,6 @@ public:
Recipient recipient(unsigned int idx) const; Recipient recipient(unsigned int idx) const;
std::vector<Recipient> recipients() const; std::vector<Recipient> recipients() const;
bool isLegacyCipherNoMDC() const;
private: private:
class Private; class Private;
void init(gpgme_ctx_t ctx); void init(gpgme_ctx_t ctx);
@ -105,7 +101,6 @@ public:
Recipient(); Recipient();
explicit Recipient(gpgme_recipient_t reci); explicit Recipient(gpgme_recipient_t reci);
Recipient(const Recipient &other) = default;
const Recipient &operator=(Recipient other) const Recipient &operator=(Recipient other)
{ {
swap(other); swap(other);

View File

@ -30,6 +30,8 @@
#include "error.h" #include "error.h"
#include "data.h" #include "data.h"
#include <sstream>
using namespace GpgME; using namespace GpgME;
DefaultAssuanTransaction::DefaultAssuanTransaction() DefaultAssuanTransaction::DefaultAssuanTransaction()

View File

@ -25,7 +25,7 @@
#ifndef __GPGMEPP_DEFAULTASSUANTRANSACTION_H__ #ifndef __GPGMEPP_DEFAULTASSUANTRANSACTION_H__
#define __GPGMEPP_DEFAULTASSUANTRANSACTION_H__ #define __GPGMEPP_DEFAULTASSUANTRANSACTION_H__
#include "interfaces/assuantransaction.h" #include <interfaces/assuantransaction.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -53,9 +53,9 @@ public:
} }
private: private:
Error data(const char *data, size_t datalen) override; /* reimp */ Error data(const char *data, size_t datalen);
Data inquire(const char *name, const char *args, Error &err) override; /* reimp */ Data inquire(const char *name, const char *args, Error &err);
Error status(const char *status, const char *args) override; /* reimp */ Error status(const char *status, const char *args);
private: private:
std::vector< std::pair<std::string, std::string> > m_status; std::vector< std::pair<std::string, std::string> > m_status;

View File

@ -29,7 +29,6 @@
#include "editinteractor.h" #include "editinteractor.h"
#include "callbacks.h" #include "callbacks.h"
#include "error.h" #include "error.h"
#include "util.h"
#include <gpgme.h> #include <gpgme.h>
@ -42,7 +41,6 @@
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
#include <cstdlib>
#ifndef GPG_ERR_ALREADY_SIGNED #ifndef GPG_ERR_ALREADY_SIGNED
# define GPG_ERR_ALREADY_SIGNED GPG_ERR_USER_1 # define GPG_ERR_ALREADY_SIGNED GPG_ERR_USER_1
@ -52,7 +50,6 @@ using namespace GpgME;
static const char *status_to_string(unsigned int status); static const char *status_to_string(unsigned int status);
static Error status_to_error(unsigned int status); static Error status_to_error(unsigned int status);
static Error parse_sc_op_failure(const char *args);
class EditInteractor::Private class EditInteractor::Private
{ {
@ -64,10 +61,9 @@ public:
~Private(); ~Private();
private: private:
unsigned int state = StartState; unsigned int state;
Error error; Error error;
std::FILE *debug = nullptr; std::FILE *debug;
bool debugNeedsClosing = false;
}; };
class GpgME::CallbackHelper class GpgME::CallbackHelper
@ -97,24 +93,12 @@ public:
// advance to next state based on input: // advance to next state based on input:
const unsigned int oldState = ei->state; const unsigned int oldState = ei->state;
ei->state = ei->q->nextState(status, args, err);
if (ei->q->needsNoResponse(status)) {
// keep state
} else if (status == GPGME_STATUS_ERROR) {
err = ei->q->parseStatusError(args);
ei->state = EditInteractor::ErrorState;
} else if (status == GPGME_STATUS_SC_OP_FAILURE) {
err = parse_sc_op_failure(args);
ei->state = EditInteractor::ErrorState;
} else {
ei->state = ei->q->nextState(status, args, err);
}
if (ei->debug) { if (ei->debug) {
std::fprintf(ei->debug, "EditInteractor: %u -> nextState( %s, %s ) -> %u\n", std::fprintf(ei->debug, "EditInteractor: %u -> nextState( %s, %s ) -> %u\n",
oldState, status_to_string(status), args ? args : "<null>", ei->state); oldState, status_to_string(status), args ? args : "<null>", ei->state);
} }
if (err || err.isCanceled()) { if (err) {
ei->state = oldState; ei->state = oldState;
goto error; goto error;
} }
@ -138,7 +122,7 @@ public:
if (writeAll(fd, result, len) != len) { if (writeAll(fd, result, len) != len) {
err = Error::fromSystemError(); err = Error::fromSystemError();
if (ei->debug) { if (ei->debug) {
std::fprintf(ei->debug, "EditInteractor: Could not write to fd %d (%s)\n", fd, err.asStdString().c_str()); std::fprintf(ei->debug, "EditInteractor: Could not write to fd %d (%s)\n", fd, err.asString());
} }
goto error; goto error;
} }
@ -147,7 +131,7 @@ public:
if (writeAll(fd, "\n", 1) != 1) { if (writeAll(fd, "\n", 1) != 1) {
err = Error::fromSystemError(); err = Error::fromSystemError();
if (ei->debug) { if (ei->debug) {
std::fprintf(ei->debug, "EditInteractor: Could not write to fd %d (%s)\n", fd, err.asStdString().c_str()); std::fprintf(ei->debug, "EditInteractor: Could not write to fd %d (%s)\n", fd, err.asString());
} }
goto error; goto error;
} }
@ -167,7 +151,7 @@ public:
} }
error: error:
if (err || err.isCanceled()) { if (err) {
ei->error = err; ei->error = err;
ei->state = EditInteractor::ErrorState; ei->state = EditInteractor::ErrorState;
} }
@ -189,28 +173,15 @@ static gpgme_error_t edit_interactor_callback(void *opaque, gpgme_status_code_t
const gpgme_edit_cb_t GpgME::edit_interactor_callback = ::edit_interactor_callback; const gpgme_edit_cb_t GpgME::edit_interactor_callback = ::edit_interactor_callback;
EditInteractor::Private::Private(EditInteractor *qq) EditInteractor::Private::Private(EditInteractor *qq)
: q(qq) : q(qq),
state(StartState),
error(),
debug(0)
{ {
const char *debug_env = std::getenv("GPGMEPP_INTERACTOR_DEBUG");
if (!debug_env) {
return;
}
if (!strcmp(debug_env, "stdout")) {
debug = stdout;
} else if (!strcmp(debug_env, "stderr")) {
debug = stderr;
} else if (debug_env) {
debug = std::fopen(debug_env, "a+");
debugNeedsClosing = true;
}
} }
EditInteractor::Private::~Private() EditInteractor::Private::~Private() {}
{
if (debug && debugNeedsClosing) {
std::fclose(debug);
}
}
EditInteractor::EditInteractor() EditInteractor::EditInteractor()
: d(new Private(this)) : d(new Private(this))
@ -270,52 +241,6 @@ void EditInteractor::setDebugChannel(std::FILE *debug)
d->debug = debug; d->debug = debug;
} }
GpgME::Error EditInteractor::parseStatusError(const char *args)
{
Error err;
const auto fields = split(args, ' ');
if (fields.size() >= 2) {
err = Error{static_cast<unsigned int>(std::stoul(fields[1]))};
} else {
err = Error::fromCode(GPG_ERR_GENERAL);
}
return err;
}
static Error sc_op_failure_to_error(unsigned int status)
{
switch (status) {
case 1:
// GPG_ERR_CANCELED or GPG_ERR_FULLY_CANCELED
return Error::fromCode(GPG_ERR_CANCELED);
case 2:
// GPG_ERR_BAD_PIN or GPG_ERR_BAD_RESET_CODE [sic]
return Error::fromCode(GPG_ERR_BAD_PIN);
case 3:
return Error::fromCode(GPG_ERR_PIN_BLOCKED);
case 4:
return Error::fromCode(GPG_ERR_NO_RESET_CODE);
}
return Error::fromCode(GPG_ERR_CARD);
}
// static
Error parse_sc_op_failure(const char *args)
{
Error err;
const auto fields = split(args, ' ');
if (fields.size() >= 1) {
err = sc_op_failure_to_error(static_cast<unsigned int>(std::stoul(fields[0])));
} else {
err = Error::fromCode(GPG_ERR_CARD);
}
return err;
}
static const char *const status_strings[] = { static const char *const status_strings[] = {
"EOF", "EOF",
/* mkstatus processing starts here */ /* mkstatus processing starts here */

View File

@ -60,9 +60,6 @@ public:
void setDebugChannel(std::FILE *file); void setDebugChannel(std::FILE *file);
protected:
Error parseStatusError(const char *args);
private: private:
class Private; class Private;
Private *const d; Private *const d;

View File

@ -53,7 +53,7 @@ public:
if (ik->fpr) { if (ik->fpr) {
copy->fpr = strdup(ik->fpr); copy->fpr = strdup(ik->fpr);
} }
copy->next = nullptr; copy->next = 0;
invalid.push_back(copy); invalid.push_back(copy);
} }
} }
@ -61,7 +61,7 @@ public:
{ {
for (std::vector<gpgme_invalid_key_t>::iterator it = invalid.begin() ; it != invalid.end() ; ++it) { for (std::vector<gpgme_invalid_key_t>::iterator it = invalid.begin() ; it != invalid.end() ; ++it) {
std::free((*it)->fpr); std::free((*it)->fpr);
delete *it; *it = nullptr; delete *it; *it = 0;
} }
} }
@ -132,7 +132,7 @@ bool GpgME::InvalidRecipient::isNull() const
const char *GpgME::InvalidRecipient::fingerprint() const const char *GpgME::InvalidRecipient::fingerprint() const
{ {
return isNull() ? nullptr : d->invalid[idx]->fpr ; return isNull() ? 0 : d->invalid[idx]->fpr ;
} }
GpgME::Error GpgME::InvalidRecipient::reason() const GpgME::Error GpgME::InvalidRecipient::reason() const

View File

@ -48,7 +48,6 @@ public:
EncryptionResult(gpgme_ctx_t ctx, const Error &error); EncryptionResult(gpgme_ctx_t ctx, const Error &error);
EncryptionResult(const Error &err); EncryptionResult(const Error &err);
EncryptionResult(const EncryptionResult &other) = default;
const EncryptionResult &operator=(EncryptionResult other) const EncryptionResult &operator=(EncryptionResult other)
{ {
swap(other); swap(other);
@ -84,7 +83,6 @@ class GPGMEPP_EXPORT InvalidRecipient
public: public:
InvalidRecipient(); InvalidRecipient();
InvalidRecipient(const InvalidRecipient &other) = default;
const InvalidRecipient &operator=(InvalidRecipient other) const InvalidRecipient &operator=(InvalidRecipient other)
{ {
swap(other); swap(other);

View File

@ -33,10 +33,10 @@
class GpgME::EngineInfo::Private class GpgME::EngineInfo::Private
{ {
public: public:
Private(gpgme_engine_info_t engine = nullptr) : info(engine) {} Private(gpgme_engine_info_t engine = 0) : info(engine) {}
~Private() ~Private()
{ {
info = nullptr; info = 0;
} }
gpgme_engine_info_t info; gpgme_engine_info_t info;
@ -70,12 +70,12 @@ GpgME::Protocol GpgME::EngineInfo::protocol() const
const char *GpgME::EngineInfo::fileName() const const char *GpgME::EngineInfo::fileName() const
{ {
return isNull() ? nullptr : d->info->file_name; return isNull() ? 0 : d->info->file_name;
} }
const char *GpgME::EngineInfo::version() const const char *GpgME::EngineInfo::version() const
{ {
return isNull() ? nullptr : d->info->version; return isNull() ? 0 : d->info->version;
} }
GpgME::EngineInfo::Version GpgME::EngineInfo::engineVersion() const GpgME::EngineInfo::Version GpgME::EngineInfo::engineVersion() const
@ -85,10 +85,10 @@ GpgME::EngineInfo::Version GpgME::EngineInfo::engineVersion() const
const char *GpgME::EngineInfo::requiredVersion() const const char *GpgME::EngineInfo::requiredVersion() const
{ {
return isNull() ? nullptr : d->info->req_version; return isNull() ? 0 : d->info->req_version;
} }
const char *GpgME::EngineInfo::homeDirectory() const const char *GpgME::EngineInfo::homeDirectory() const
{ {
return isNull() ? nullptr : d->info->home_dir; return isNull() ? 0 : d->info->home_dir;
} }

View File

@ -69,76 +69,6 @@ public:
} }
} }
bool operator < (const Version& other) const
{
if (major > other.major ||
(major == other.major && minor > other.minor) ||
(major == other.major && minor == other.minor && patch > other.patch) ||
(major >= other.major && minor >= other.minor && patch >= other.patch)) {
return false;
}
return true;
}
bool operator < (const char* other) const
{
return operator<(Version(other));
}
bool operator <= (const Version &other) const
{
return !operator>(other);
}
bool operator <= (const char *other) const
{
return operator<=(Version(other));
}
bool operator > (const char* other) const
{
return operator>(Version(other));
}
bool operator > (const Version & other) const
{
return !operator<(other) && !operator==(other);
}
bool operator >= (const Version &other) const
{
return !operator<(other);
}
bool operator >= (const char *other) const
{
return operator>=(Version(other));
}
bool operator == (const Version& other) const
{
return major == other.major
&& minor == other.minor
&& patch == other.patch;
}
bool operator == (const char* other) const
{
return operator==(Version(other));
}
bool operator != (const Version &other) const
{
return !operator==(other);
}
bool operator != (const char *other) const
{
return operator!=(Version(other));
}
// the non-const overloads of the comparison operators are kept for
// binary compatibility
bool operator < (const Version& other) bool operator < (const Version& other)
{ {
if (major > other.major || if (major > other.major ||
@ -155,36 +85,15 @@ public:
return operator<(Version(other)); return operator<(Version(other));
} }
bool operator <= (const Version &other)
{
return !operator>(other);
}
bool operator <= (const char *other)
{
return operator<=(Version(other));
}
bool operator > (const char* other) bool operator > (const char* other)
{ {
return operator>(Version(other)); return !operator<(Version(other));
} }
bool operator > (const Version & other) bool operator > (const Version & other)
{
return !operator<(other) && !operator==(other);
}
bool operator >= (const Version &other)
{ {
return !operator<(other); return !operator<(other);
} }
bool operator >= (const char *other)
{
return operator>=(Version(other));
}
bool operator == (const Version& other) bool operator == (const Version& other)
{ {
return major == other.major return major == other.major
@ -197,16 +106,6 @@ public:
return operator==(Version(other)); return operator==(Version(other));
} }
bool operator != (const Version &other)
{
return !operator==(other);
}
bool operator != (const char *other)
{
return operator!=(Version(other));
}
friend std::ostream& operator << (std::ostream& stream, const Version& ver) friend std::ostream& operator << (std::ostream& stream, const Version& ver)
{ {
stream << ver.major; stream << ver.major;
@ -221,7 +120,6 @@ public:
EngineInfo(); EngineInfo();
explicit EngineInfo(gpgme_engine_info_t engine); explicit EngineInfo(gpgme_engine_info_t engine);
EngineInfo(const EngineInfo &other) = default;
const EngineInfo &operator=(EngineInfo other) const EngineInfo &operator=(EngineInfo other)
{ {
swap(other); swap(other);

View File

@ -47,11 +47,7 @@ public:
explicit Error(unsigned int e) : mErr(e), mMessage() {} explicit Error(unsigned int e) : mErr(e), mMessage() {}
const char *source() const; const char *source() const;
/* This function is deprecated. Use asStdString() instead. asString() may const char *asString() const;
* return wrongly encoded (i.e. not UTF-8) results on Windows for the main
* thread if the function was first called from a secondary thread. */
GPGMEPP_DEPRECATED const char *asString() const;
std::string asStdString() const;
int code() const; int code() const;
int sourceID() const; int sourceID() const;

View File

@ -77,10 +77,10 @@ public:
const gpgme_io_cbs EventLoopInteractor::Private::iocbs = { const gpgme_io_cbs EventLoopInteractor::Private::iocbs = {
&EventLoopInteractor::Private::registerIOCb, &EventLoopInteractor::Private::registerIOCb,
nullptr, 0,
&EventLoopInteractor::Private::removeIOCb, &EventLoopInteractor::Private::removeIOCb,
&EventLoopInteractor::Private::eventIOCb, &EventLoopInteractor::Private::eventIOCb,
nullptr 0
}; };
// //
@ -114,7 +114,7 @@ void EventLoopInteractor::Private::removeIOCb(void *tag)
it != instance()->d->mCallbacks.end() ; ++it) { it != instance()->d->mCallbacks.end() ; ++it) {
if (*it == tag) { if (*it == tag) {
instance()->unregisterWatcher((*it)->externalTag); instance()->unregisterWatcher((*it)->externalTag);
delete *it; *it = nullptr; delete *it; *it = 0;
instance()->d->mCallbacks.erase(it); instance()->d->mCallbacks.erase(it);
return; return;
} }
@ -159,7 +159,7 @@ void EventLoopInteractor::Private::eventIOCb(void *data, gpgme_event_io_t type,
// EventLoopInteractor Implementation // EventLoopInteractor Implementation
// //
EventLoopInteractor *EventLoopInteractor::mSelf = nullptr; EventLoopInteractor *EventLoopInteractor::mSelf = 0;
EventLoopInteractor::EventLoopInteractor() : d(new Private) EventLoopInteractor::EventLoopInteractor() : d(new Private)
{ {
@ -170,7 +170,7 @@ EventLoopInteractor::EventLoopInteractor() : d(new Private)
EventLoopInteractor::~EventLoopInteractor() EventLoopInteractor::~EventLoopInteractor()
{ {
// warn if there are still callbacks registered // warn if there are still callbacks registered
mSelf = nullptr; mSelf = 0;
delete d; delete d;
} }

View File

@ -60,34 +60,14 @@ enum Engine { GpgEngine, GpgSMEngine, GpgConfEngine, UnknownEngine, AssuanEngine
enum KeyListMode { enum KeyListMode {
Local = 0x1, Local = 0x1,
Extern = 0x2, Extern = 0x2,
Locate = Local|Extern,
Signatures = 0x4, Signatures = 0x4,
SignatureNotations = 0x8, SignatureNotations = 0x8,
Validate = 0x10, Validate = 0x10,
Ephemeral = 0x20, Ephemeral = 0x20,
WithTofu = 0x40, WithTofu = 0x40
WithKeygrip = 0x80,
WithSecret = 0x100,
ForceExtern = 0x200,
LocateExternal = Locate|ForceExtern,
KeyListModeMask = 0x3ff
}; };
enum SignatureMode { enum SignatureMode { NormalSignatureMode, Detached, Clearsigned };
NormalSignatureMode = 0,
Detached = 1,
Clearsigned = 2,
SignArchive = 4,
SignFile = 8,
};
enum class RevocationReason {
Unspecified = 0,
Compromised = 1,
Superseded = 2,
NoLongerUsed = 3
};
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, Protocol proto); GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, Protocol proto);
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, Engine eng); GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, Engine eng);
@ -108,8 +88,7 @@ GPGMEPP_EXPORT EngineInfo engineInfo(Engine engine);
homedir, sysconfdir, bindir, libexecdir, libdir, homedir, sysconfdir, bindir, libexecdir, libdir,
datadir, localedir, agent-socket, agent-ssh-socket, datadir, localedir, agent-socket, agent-ssh-socket,
dirmngr-socket, uiserver-socket, gpgconf-name, gpg-name, dirmngr-socket, uiserver-socket, gpgconf-name, gpg-name,
gpgsm-name, g13-name, keyboxd-name, agent-name, scdaemon-name, gpgsm-name, g13-name
dirmngr-name, pinentry-name, socketdir, gpg-wks-client-name, gpgtar-name.
This may be extended in the future. This may be extended in the future.
*/ */
@ -118,9 +97,6 @@ GPGMEPP_EXPORT const char *dirInfo(const char *what);
GPGMEPP_EXPORT Error checkEngine(Protocol proto); GPGMEPP_EXPORT Error checkEngine(Protocol proto);
GPGMEPP_EXPORT Error checkEngine(Engine engine); GPGMEPP_EXPORT Error checkEngine(Engine engine);
/* Wrapper for gpgme_set_global_flag */
GPGMEPP_EXPORT int setGlobalFlag(const char *name, const char *value);
GPGMEPP_EXPORT GIOChannel *getGIOChannel(int fd); GPGMEPP_EXPORT GIOChannel *getGIOChannel(int fd);
GPGMEPP_EXPORT QIODevice *getQIODevice(int fd); GPGMEPP_EXPORT QIODevice *getQIODevice(int fd);
@ -188,7 +164,7 @@ GPGMEPP_EXPORT bool hasFeature(unsigned long feature, unsigned long feature2);
struct __safe_bool_dummy__ { void nonnull() {} }; \ struct __safe_bool_dummy__ { void nonnull() {} }; \
typedef void ( __safe_bool_dummy__::*unspecified_bool_type )(); \ typedef void ( __safe_bool_dummy__::*unspecified_bool_type )(); \
public: \ public: \
operator unspecified_bool_type() const { return ( Cond ) ? &__safe_bool_dummy__::nonnull : nullptr; } operator unspecified_bool_type() const { return ( Cond ) ? &__safe_bool_dummy__::nonnull : 0 ; }
# endif # endif
inline int _gpgmepp_strcmp(const char *s1, const char *s2) inline int _gpgmepp_strcmp(const char *s1, const char *s2)

View File

@ -1,205 +0,0 @@
/*
gpgaddexistingsubkeyeditinteractor.cpp - Edit Interactor to add an existing subkey to an OpenPGP key
Copyright (c) 2022 g10 Code GmbH
Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
This file is part of GPGME++.
GPGME++ is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
GPGME++ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with GPGME++; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gpgaddexistingsubkeyeditinteractor.h"
#include "error.h"
#include <gpgme.h>
// avoid conflict (msvc)
#ifdef ERROR
# undef ERROR
#endif
using namespace GpgME;
class GpgAddExistingSubkeyEditInteractor::Private
{
enum {
START = EditInteractor::StartState,
COMMAND,
ADD_EXISTING_KEY,
KEYGRIP,
FLAGS,
VALID,
KEY_CREATED,
QUIT,
SAVE,
ERROR = EditInteractor::ErrorState
};
GpgAddExistingSubkeyEditInteractor *const q = nullptr;
public:
Private(GpgAddExistingSubkeyEditInteractor *q, const std::string &keygrip)
: q{q}
, keygrip{keygrip}
{
}
const char *action(Error &err) const;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const;
std::string keygrip;
std::string expiry;
};
const char *GpgAddExistingSubkeyEditInteractor::Private::action(Error &err) const
{
switch (q->state()) {
case COMMAND:
return "addkey";
case ADD_EXISTING_KEY:
return "keygrip";
case KEYGRIP:
return keygrip.c_str();
case FLAGS:
return "Q"; // do not toggle any usage flags
case VALID:
return expiry.empty() ? "0" : expiry.c_str();
case QUIT:
return "quit";
case SAVE:
return "Y";
case START:
case KEY_CREATED:
case ERROR:
return nullptr;
default:
err = Error::fromCode(GPG_ERR_GENERAL);
return nullptr;
}
}
unsigned int GpgAddExistingSubkeyEditInteractor::Private::nextState(unsigned int status, const char *args, Error &err) const
{
using std::strcmp;
static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL);
static const Error NO_KEY_ERROR = Error::fromCode(GPG_ERR_NO_KEY);
static const Error INV_TIME_ERROR = Error::fromCode(GPG_ERR_INV_TIME);
switch (q->state()) {
case START:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keyedit.prompt") == 0) {
return COMMAND;
}
err = GENERAL_ERROR;
return ERROR;
case COMMAND:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.algo") == 0) {
return ADD_EXISTING_KEY;
}
err = GENERAL_ERROR;
return ERROR;
case ADD_EXISTING_KEY:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.keygrip") == 0) {
return KEYGRIP;
}
err = GENERAL_ERROR;
return ERROR;
case KEYGRIP:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.flags") == 0) {
return FLAGS;
} else if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.keygrip") == 0) {
err = NO_KEY_ERROR;
return ERROR;
}
err = GENERAL_ERROR;
return ERROR;
case FLAGS:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.valid") == 0) {
return VALID;
}
err = GENERAL_ERROR;
return ERROR;
case VALID:
if (status == GPGME_STATUS_KEY_CREATED) {
return KEY_CREATED;
}
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keyedit.prompt") == 0) {
return QUIT;
} else if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.valid") == 0) {
err = INV_TIME_ERROR;
return ERROR;
}
err = GENERAL_ERROR;
return ERROR;
case KEY_CREATED:
return QUIT;
case QUIT:
if (status == GPGME_STATUS_GET_BOOL &&
strcmp(args, "keyedit.save.okay") == 0) {
return SAVE;
}
err = GENERAL_ERROR;
return ERROR;
case ERROR:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keyedit.prompt") == 0) {
return QUIT;
}
err = q->lastError();
return ERROR;
default:
err = GENERAL_ERROR;
return ERROR;
}
}
GpgAddExistingSubkeyEditInteractor::GpgAddExistingSubkeyEditInteractor(const std::string &keygrip)
: EditInteractor{}
, d{new Private{this, keygrip}}
{
}
GpgAddExistingSubkeyEditInteractor::~GpgAddExistingSubkeyEditInteractor() = default;
void GpgAddExistingSubkeyEditInteractor::setExpiry(const std::string &timeString)
{
d->expiry = timeString;
}
const char *GpgAddExistingSubkeyEditInteractor::action(Error &err) const
{
return d->action(err);
}
unsigned int GpgAddExistingSubkeyEditInteractor::nextState(unsigned int status, const char *args, Error &err) const
{
return d->nextState(status, args, err);
}

View File

@ -1,59 +0,0 @@
/*
gpgaddexistingsubkeyeditinteractor.h - Edit Interactor to add an existing subkey to an OpenPGP key
Copyright (c) 2022 g10 Code GmbH
Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
This file is part of GPGME++.
GPGME++ is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
GPGME++ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with GPGME++; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef __GPGMEPP_GPGADDEXISTINGSUBKEYEDITINTERACTOR_H__
#define __GPGMEPP_GPGADDEXISTINGSUBKEYEDITINTERACTOR_H__
#include "editinteractor.h"
#include <memory>
namespace GpgME
{
class GPGMEPP_EXPORT GpgAddExistingSubkeyEditInteractor : public EditInteractor
{
public:
/** Edit interactor to add the existing subkey with keygrip \a keygrip
* to the key a key edit operation is working on.
**/
explicit GpgAddExistingSubkeyEditInteractor(const std::string &keygrip);
~GpgAddExistingSubkeyEditInteractor() override;
/** Sets the validity period of the added subkey. Use "0" for no expiration
* or a simplified ISO date string ("yyyymmddThhmmss") for setting an
* expiration date. */
void setExpiry(const std::string &timeString);
private:
const char *action(Error &err) const override;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override;
private:
class Private;
const std::unique_ptr<Private> d;
};
} // namespace GpgME
#endif // __GPGMEPP_GPGADDEXISTINGSUBKEYEDITINTERACTOR_H__

View File

@ -105,10 +105,10 @@ const char *GpgAddUserIDEditInteractor::action(Error &err) const
return "Y"; return "Y";
case START: case START:
case ERROR: case ERROR:
return nullptr; return 0;
default: default:
err = Error::fromCode(GPG_ERR_GENERAL); err = Error::fromCode(GPG_ERR_GENERAL);
return nullptr; return 0;
} }
} }
@ -120,6 +120,10 @@ unsigned int GpgAddUserIDEditInteractor::nextState(unsigned int status, const ch
static const Error INV_EMAIL_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID); static const Error INV_EMAIL_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID);
static const Error INV_COMMENT_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID); static const Error INV_COMMENT_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID);
if (needsNoResponse(status)) {
return state();
}
using namespace GpgAddUserIDEditInteractor_Private; using namespace GpgAddUserIDEditInteractor_Private;
switch (state()) { switch (state()) {

View File

@ -25,7 +25,7 @@
#ifndef __GPGMEPP_GPGADDUSERIDEDITINTERACTOR_H__ #ifndef __GPGMEPP_GPGADDUSERIDEDITINTERACTOR_H__
#define __GPGMEPP_GPGADDUSERIDEDITINTERACTOR_H__ #define __GPGMEPP_GPGADDUSERIDEDITINTERACTOR_H__
#include "editinteractor.h" #include <editinteractor.h>
#include <string> #include <string>
@ -57,8 +57,8 @@ public:
} }
private: private:
const char *action(Error &err) const override; /* reimp */ const char *action(Error &err) const;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override; /* reimp */ unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const;
private: private:
std::string m_name, m_email, m_comment; std::string m_name, m_email, m_comment;

View File

@ -33,6 +33,8 @@
#include <assert.h> #include <assert.h>
#include <sstream>
using namespace GpgME; using namespace GpgME;
GpgAgentGetInfoAssuanTransaction::GpgAgentGetInfoAssuanTransaction(InfoItem item) GpgAgentGetInfoAssuanTransaction::GpgAgentGetInfoAssuanTransaction(InfoItem item)

View File

@ -25,7 +25,7 @@
#ifndef __GPGMEPP_GPGAGENTGETINFOASSUANTRANSACTION_H__ #ifndef __GPGMEPP_GPGAGENTGETINFOASSUANTRANSACTION_H__
#define __GPGMEPP_GPGAGENTGETINFOASSUANTRANSACTION_H__ #define __GPGMEPP_GPGAGENTGETINFOASSUANTRANSACTION_H__
#include "interfaces/assuantransaction.h" #include <interfaces/assuantransaction.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -56,10 +56,10 @@ public:
std::string sshSocketName() const; std::string sshSocketName() const;
private: private:
const char *command() const; /* reimp */ const char *command() const;
Error data(const char *data, size_t datalen) override; /* reimp */ Error data(const char *data, size_t datalen);
Data inquire(const char *name, const char *args, Error &err) override; /* reimp */ Data inquire(const char *name, const char *args, Error &err);
Error status(const char *status, const char *args) override; /* reimp */ Error status(const char *status, const char *args);
private: private:
void makeCommand() const; void makeCommand() const;

View File

@ -36,17 +36,16 @@ using namespace GpgME;
class GpgGenCardKeyInteractor::Private class GpgGenCardKeyInteractor::Private
{ {
public: public:
Private() : keysize("2048") Private() : keysize(2048), backup(false)
{ {
}
std::string name, email, backupFileName, expiry, serial, keysize; }
bool backup = false; std::string name, email, backupFileName, expiry, serial;
Algo algo = RSA; int keysize;
std::string curve; bool backup;
}; };
GpgGenCardKeyInteractor::~GpgGenCardKeyInteractor() = default; GpgGenCardKeyInteractor::~GpgGenCardKeyInteractor() {}
GpgGenCardKeyInteractor::GpgGenCardKeyInteractor(const std::string &serial): GpgGenCardKeyInteractor::GpgGenCardKeyInteractor(const std::string &serial):
d(new Private) d(new Private)
@ -71,7 +70,7 @@ void GpgGenCardKeyInteractor::setDoBackup(bool value)
void GpgGenCardKeyInteractor::setKeySize(int value) void GpgGenCardKeyInteractor::setKeySize(int value)
{ {
d->keysize = std::to_string(value); d->keysize = value;
} }
void GpgGenCardKeyInteractor::setExpiry(const std::string &timeStr) void GpgGenCardKeyInteractor::setExpiry(const std::string &timeStr)
@ -84,20 +83,6 @@ std::string GpgGenCardKeyInteractor::backupFileName() const
return d->backupFileName; return d->backupFileName;
} }
void GpgGenCardKeyInteractor::setAlgo(Algo algo)
{
d->algo = algo;
}
void GpgGenCardKeyInteractor::setCurve(Curve curve)
{
if (curve == DefaultCurve) {
d->curve.clear();
} else if (curve >= 1 && curve <= LastCurve) {
d->curve = std::to_string(static_cast<int>(curve));
}
}
namespace GpgGenCardKeyInteractor_Private namespace GpgGenCardKeyInteractor_Private
{ {
enum { enum {
@ -120,14 +105,6 @@ enum {
QUIT, QUIT,
SAVE, SAVE,
KEY_ATTR,
KEY_ALGO1,
KEY_ALGO2,
KEY_ALGO3,
KEY_CURVE1,
KEY_CURVE2,
KEY_CURVE3,
ERROR = EditInteractor::ErrorState ERROR = EditInteractor::ErrorState
}; };
} }
@ -142,16 +119,6 @@ const char *GpgGenCardKeyInteractor::action(Error &err) const
return "admin"; return "admin";
case COMMAND: case COMMAND:
return "generate"; return "generate";
case KEY_ATTR:
return "key-attr";
case KEY_ALGO1:
case KEY_ALGO2:
case KEY_ALGO3:
return d->algo == RSA ? "1" : "2";
case KEY_CURVE1:
case KEY_CURVE2:
case KEY_CURVE3:
return d->curve.empty() ? "1" : d->curve.c_str(); // default is Curve25519
case NAME: case NAME:
return d->name.c_str(); return d->name.c_str();
case EMAIL: case EMAIL:
@ -165,7 +132,7 @@ const char *GpgGenCardKeyInteractor::action(Error &err) const
case SIZE: case SIZE:
case SIZE2: case SIZE2:
case SIZE3: case SIZE3:
return d->keysize.c_str(); return std::to_string(d->keysize).c_str();
case COMMENT: case COMMENT:
return ""; return "";
case SAVE: case SAVE:
@ -177,10 +144,10 @@ const char *GpgGenCardKeyInteractor::action(Error &err) const
case GOT_SERIAL: case GOT_SERIAL:
case BACKUP_KEY_CREATED: case BACKUP_KEY_CREATED:
case ERROR: case ERROR:
return nullptr; return 0;
default: default:
err = Error::fromCode(GPG_ERR_GENERAL); err = Error::fromCode(GPG_ERR_GENERAL);
return nullptr; return 0;
} }
} }
@ -192,6 +159,10 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char
static const Error INV_EMAIL_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID); static const Error INV_EMAIL_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID);
static const Error INV_COMMENT_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID); static const Error INV_COMMENT_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID);
if (needsNoResponse(status)) {
return state();
}
using namespace GpgGenCardKeyInteractor_Private; using namespace GpgGenCardKeyInteractor_Private;
switch (state()) { switch (state()) {
@ -221,92 +192,12 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char
err = GENERAL_ERROR; err = GENERAL_ERROR;
return ERROR; return ERROR;
case DO_ADMIN: case DO_ADMIN:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.prompt") == 0) {
return KEY_ATTR;
}
err = GENERAL_ERROR;
return ERROR;
// Handling for key-attr subcommand
case KEY_ATTR:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.prompt") == 0) {
// Happens if key attr is not yet supported.
return COMMAND;
}
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.algo") == 0) {
return KEY_ALGO1;
}
err = GENERAL_ERROR;
return ERROR;
case KEY_ALGO1:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.size") == 0) {
return SIZE;
}
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.curve") == 0) {
return KEY_CURVE1;
}
err = GENERAL_ERROR;
return ERROR;
case KEY_ALGO2:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.size") == 0) {
return SIZE2;
}
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.curve") == 0) {
return KEY_CURVE2;
}
err = GENERAL_ERROR;
return ERROR;
case KEY_ALGO3:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.size") == 0) {
return SIZE3;
}
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.curve") == 0) {
return KEY_CURVE3;
}
err = GENERAL_ERROR;
return ERROR;
case KEY_CURVE1:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.algo") == 0) {
return KEY_ALGO2;
}
if (status == GPGME_STATUS_GET_LINE && if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.prompt") == 0) { strcmp(args, "cardedit.prompt") == 0) {
return COMMAND; return COMMAND;
} }
err = GENERAL_ERROR; err = GENERAL_ERROR;
return ERROR; return ERROR;
case KEY_CURVE2:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.algo") == 0) {
return KEY_ALGO3;
}
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.prompt") == 0) {
return COMMAND;
}
err = GENERAL_ERROR;
return ERROR;
case KEY_CURVE3:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.algo") == 0) {
return KEY_ALGO3;
}
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.prompt") == 0) {
return COMMAND;
}
err = GENERAL_ERROR;
return ERROR;
// End key-attr handling
case COMMAND: case COMMAND:
if (status == GPGME_STATUS_GET_LINE && if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.backup_enc") == 0) { strcmp(args, "cardedit.genkeys.backup_enc") == 0) {
@ -323,21 +214,14 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char
strcmp(args, "cardedit.genkeys.size") == 0) { strcmp(args, "cardedit.genkeys.size") == 0) {
return SIZE; return SIZE;
} }
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.valid") == 0) {
return EXPIRE;
}
err = GENERAL_ERROR; err = GENERAL_ERROR;
return ERROR; return ERROR;
case REPLACE: case REPLACE:
if (status == GPGME_STATUS_GET_LINE && if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.size") == 0) { strcmp(args, "cardedit.genkeys.size") == 0) {
printf("Moving to SIZE\n");
return SIZE; return SIZE;
} }
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keygen.valid") == 0) {
return EXPIRE;
}
err = GENERAL_ERROR; err = GENERAL_ERROR;
return ERROR; return ERROR;
case SIZE: case SIZE:
@ -349,14 +233,6 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char
strcmp(args, "keygen.valid") == 0) { strcmp(args, "keygen.valid") == 0) {
return EXPIRE; return EXPIRE;
} }
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.algo") == 0) {
return KEY_ALGO2;
}
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.prompt") == 0) {
return COMMAND;
}
err = GENERAL_ERROR; err = GENERAL_ERROR;
return ERROR; return ERROR;
case SIZE2: case SIZE2:
@ -368,14 +244,6 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char
strcmp(args, "keygen.valid") == 0) { strcmp(args, "keygen.valid") == 0) {
return EXPIRE; return EXPIRE;
} }
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.genkeys.algo") == 0) {
return KEY_ALGO3;
}
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.prompt") == 0) {
return COMMAND;
}
err = GENERAL_ERROR; err = GENERAL_ERROR;
return ERROR; return ERROR;
case SIZE3: case SIZE3:
@ -383,10 +251,6 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char
strcmp(args, "keygen.valid") == 0) { strcmp(args, "keygen.valid") == 0) {
return EXPIRE; return EXPIRE;
} }
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "cardedit.prompt") == 0) {
return COMMAND;
}
err = GENERAL_ERROR; err = GENERAL_ERROR;
return ERROR; return ERROR;
case EXPIRE: case EXPIRE:

View File

@ -24,7 +24,7 @@
#ifndef __GPGMEPP_GPGGENCARDKEYEDITINTERACTOR_H__ #ifndef __GPGMEPP_GPGGENCARDKEYEDITINTERACTOR_H__
#define __GPGMEPP_GPGGENCARDKEYEDITINTERACTOR_H__ #define __GPGMEPP_GPGGENCARDKEYEDITINTERACTOR_H__
#include "editinteractor.h" #include <editinteractor.h>
#include <string> #include <string>
#include <memory> #include <memory>
@ -56,34 +56,11 @@ public:
void setDoBackup(bool value); void setDoBackup(bool value);
void setExpiry(const std::string &timeString); void setExpiry(const std::string &timeString);
enum Algo {
RSA = 1,
ECC = 2,
};
void setAlgo(Algo algo);
// the enum values minus 1 have to match the indexes of the curves used by
// ask_curve() in gnupg's g10/keygen.c
enum Curve {
DefaultCurve = 0, // currently Curve25519
Curve25519 = 1,
Curve448,
NISTP256,
NISTP384,
NISTP521,
BrainpoolP256,
BrainpoolP384,
BrainpoolP512,
Secp256k1,
LastCurve = Secp256k1,
};
void setCurve(Curve curve);
std::string backupFileName() const; std::string backupFileName() const;
private: private:
const char *action(Error &err) const override; /* reimp */ const char *action(Error &err) const;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override; /* reimp */ unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const;
private: private:
class Private; class Private;

View File

@ -75,7 +75,4 @@ typedef struct _gpgme_tofu_info *gpgme_tofu_info_t;
struct _gpgme_op_query_swdb_result; struct _gpgme_op_query_swdb_result;
typedef struct _gpgme_op_query_swdb_result *gpgme_query_swdb_result_t; typedef struct _gpgme_op_query_swdb_result *gpgme_query_swdb_result_t;
struct _gpgme_revocation_key;
typedef struct _gpgme_revocation_key *gpgme_revocation_key_t;
#endif // __GPGMEPP_GPGMEFW_H__ #endif // __GPGMEPP_GPGMEFW_H__

View File

@ -1,207 +0,0 @@
/*
gpgrevokekeyeditinteractor.cpp - Edit Interactor to revoke own OpenPGP keys
Copyright (c) 2022 g10 Code GmbH
Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
This file is part of GPGME++.
GPGME++ is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
GPGME++ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with GPGME++; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gpgrevokekeyeditinteractor.h"
#include "error.h"
#include <gpgme.h>
#include <vector>
// avoid conflict (msvc)
#ifdef ERROR
# undef ERROR
#endif
using namespace GpgME;
class GpgRevokeKeyEditInteractor::Private
{
enum {
START = EditInteractor::StartState,
COMMAND,
CONFIRM_REVOKING_ENTIRE_KEY,
REASON_CODE,
REASON_TEXT,
// all these free slots belong to REASON_TEXT, too; we increase state()
// by one for each line of text, so that action() is called
REASON_TEXT_DONE = REASON_TEXT + 1000,
CONFIRM_REASON,
QUIT,
CONFIRM_SAVE,
ERROR = EditInteractor::ErrorState
};
GpgRevokeKeyEditInteractor *const q = nullptr;
public:
Private(GpgRevokeKeyEditInteractor *q)
: q{q}
, reasonCode{"0"}
{
}
const char *action(Error &err) const;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err);
std::string reasonCode;
std::vector<std::string> reasonLines;
int nextLine = -1;
};
const char *GpgRevokeKeyEditInteractor::Private::action(Error &err) const
{
switch (const auto state = q->state()) {
case COMMAND:
return "revkey";
case CONFIRM_REVOKING_ENTIRE_KEY:
return "Y";
case REASON_CODE:
return reasonCode.c_str();
case REASON_TEXT_DONE:
return "";
case CONFIRM_REASON:
return "Y";
case QUIT:
return "quit";
case CONFIRM_SAVE:
return "Y";
case START:
return nullptr;
default:
if (state >= REASON_TEXT && state < REASON_TEXT_DONE) {
return reasonLines[nextLine].c_str();
}
// fall through
case ERROR:
err = Error::fromCode(GPG_ERR_GENERAL);
return nullptr;
}
}
unsigned int GpgRevokeKeyEditInteractor::Private::nextState(unsigned int status, const char *args, Error &err)
{
using std::strcmp;
static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL);
switch (const auto state = q->state()) {
case START:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keyedit.prompt") == 0) {
return COMMAND;
}
err = GENERAL_ERROR;
return ERROR;
case COMMAND:
if (status == GPGME_STATUS_GET_BOOL &&
strcmp(args, "keyedit.revoke.subkey.okay") == 0) {
return CONFIRM_REVOKING_ENTIRE_KEY;
}
err = GENERAL_ERROR;
return ERROR;
case CONFIRM_REVOKING_ENTIRE_KEY:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "ask_revocation_reason.code") == 0) {
return REASON_CODE;
}
err = GENERAL_ERROR;
return ERROR;
case REASON_CODE:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "ask_revocation_reason.text") == 0) {
nextLine++;
return static_cast<std::size_t>(nextLine) < reasonLines.size() ? REASON_TEXT : REASON_TEXT_DONE;
}
err = GENERAL_ERROR;
return ERROR;
default:
if (state >= REASON_TEXT && state < REASON_TEXT_DONE) {
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "ask_revocation_reason.text") == 0) {
nextLine++;
return static_cast<std::size_t>(nextLine) < reasonLines.size() ? state + 1 : REASON_TEXT_DONE;
}
}
err = GENERAL_ERROR;
return ERROR;
case REASON_TEXT_DONE:
if (status == GPGME_STATUS_GET_BOOL &&
strcmp(args, "ask_revocation_reason.okay") == 0) {
return CONFIRM_REASON;
}
err = GENERAL_ERROR;
return ERROR;
case CONFIRM_REASON:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keyedit.prompt") == 0) {
return QUIT;
}
err = GENERAL_ERROR;
return ERROR;
case QUIT:
if (status == GPGME_STATUS_GET_BOOL &&
strcmp(args, "keyedit.save.okay") == 0) {
return CONFIRM_SAVE;
}
err = GENERAL_ERROR;
return ERROR;
case ERROR:
if (status == GPGME_STATUS_GET_LINE &&
strcmp(args, "keyedit.prompt") == 0) {
return QUIT;
}
err = q->lastError();
return ERROR;
}
}
GpgRevokeKeyEditInteractor::GpgRevokeKeyEditInteractor()
: EditInteractor{}
, d{new Private{this}}
{
}
GpgRevokeKeyEditInteractor::~GpgRevokeKeyEditInteractor() = default;
void GpgRevokeKeyEditInteractor::setReason(RevocationReason reason, const std::vector<std::string> &description)
{
d->reasonCode = std::to_string(static_cast<int>(reason));
d->reasonLines = description;
}
const char *GpgRevokeKeyEditInteractor::action(Error &err) const
{
return d->action(err);
}
unsigned int GpgRevokeKeyEditInteractor::nextState(unsigned int status, const char *args, Error &err) const
{
return d->nextState(status, args, err);
}

View File

@ -1,62 +0,0 @@
/*
gpgrevokekeyeditinteractor.h - Edit Interactor to revoke own OpenPGP keys
Copyright (c) 2022 g10 Code GmbH
Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
This file is part of GPGME++.
GPGME++ is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
GPGME++ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with GPGME++; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef __GPGMEPP_GPGREVOKEKEYEDITINTERACTOR_H__
#define __GPGMEPP_GPGREVOKEKEYEDITINTERACTOR_H__
#include "editinteractor.h"
#include "global.h"
#include <memory>
#include <vector>
namespace GpgME
{
/** Edit interactor to revoke the key a key edit operation is working on.
* Supports revocation of own keys only. */
class GPGMEPP_EXPORT GpgRevokeKeyEditInteractor : public EditInteractor
{
public:
GpgRevokeKeyEditInteractor();
~GpgRevokeKeyEditInteractor() override;
/** Sets the reason for the revocation. The reason defaults to \c Unspecified.
* \a description can be used for adding a comment for the revocation. The
* individual elements of \a description must be non-empty strings and they
* must not contain any endline characters.
*/
void setReason(RevocationReason reason, const std::vector<std::string> &description = {});
private:
const char *action(Error &err) const override;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override;
private:
class GPGMEPP_NO_EXPORT Private;
const std::unique_ptr<Private> d;
};
} // namespace GpgME
#endif // __GPGMEPP_GPGREVOKEKEYEDITINTERACTOR_H__

View File

@ -81,10 +81,10 @@ const char *GpgSetExpiryTimeEditInteractor::action(Error &err) const
return "Y"; return "Y";
case START: case START:
case ERROR: case ERROR:
return nullptr; return 0;
default: default:
err = Error::fromCode(GPG_ERR_GENERAL); err = Error::fromCode(GPG_ERR_GENERAL);
return nullptr; return 0;
} }
} }
@ -94,6 +94,10 @@ unsigned int GpgSetExpiryTimeEditInteractor::nextState(unsigned int status, cons
static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL); static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL);
static const Error INV_TIME_ERROR = Error::fromCode(GPG_ERR_INV_TIME); static const Error INV_TIME_ERROR = Error::fromCode(GPG_ERR_INV_TIME);
if (needsNoResponse(status)) {
return state();
}
using namespace GpgSetExpiryTimeEditInteractor_Private; using namespace GpgSetExpiryTimeEditInteractor_Private;
switch (state()) { switch (state()) {

View File

@ -25,7 +25,7 @@
#ifndef __GPGMEPP_GPGSETEXPIRYTIMEEDITINTERACTOR_H__ #ifndef __GPGMEPP_GPGSETEXPIRYTIMEEDITINTERACTOR_H__
#define __GPGMEPP_GPGSETEXPIRYTIMEEDITINTERACTOR_H__ #define __GPGMEPP_GPGSETEXPIRYTIMEEDITINTERACTOR_H__
#include "editinteractor.h" #include <editinteractor.h>
#include <string> #include <string>
@ -39,8 +39,8 @@ public:
~GpgSetExpiryTimeEditInteractor(); ~GpgSetExpiryTimeEditInteractor();
private: private:
const char *action(Error &err) const override; /* reimp */ const char *action(Error &err) const;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override; /* reimp */ unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const;
private: private:
const std::string m_strtime; const std::string m_strtime;

View File

@ -85,10 +85,10 @@ const char *GpgSetOwnerTrustEditInteractor::action(Error &err) const
return "Y"; return "Y";
case START: case START:
case ERROR: case ERROR:
return nullptr; return 0;
default: default:
err = Error::fromCode(GPG_ERR_GENERAL); err = Error::fromCode(GPG_ERR_GENERAL);
return nullptr; return 0;
} }
} }
@ -98,6 +98,10 @@ unsigned int GpgSetOwnerTrustEditInteractor::nextState(unsigned int status, cons
static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL); static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL);
//static const Error INV_TIME_ERROR = Error::fromCode( GPG_ERR_INV_TIME ); //static const Error INV_TIME_ERROR = Error::fromCode( GPG_ERR_INV_TIME );
if (needsNoResponse(status)) {
return state();
}
using namespace GpgSetOwnerTrustEditInteractor_Private; using namespace GpgSetOwnerTrustEditInteractor_Private;
switch (state()) { switch (state()) {

View File

@ -25,8 +25,8 @@
#ifndef __GPGMEPP_GPGSETOWNERTRUSTEDITINTERACTOR_H__ #ifndef __GPGMEPP_GPGSETOWNERTRUSTEDITINTERACTOR_H__
#define __GPGMEPP_GPGSETOWNERTRUSTEDITINTERACTOR_H__ #define __GPGMEPP_GPGSETOWNERTRUSTEDITINTERACTOR_H__
#include "editinteractor.h" #include <editinteractor.h>
#include "key.h" #include <key.h>
#include <string> #include <string>
@ -40,8 +40,8 @@ public:
~GpgSetOwnerTrustEditInteractor(); ~GpgSetOwnerTrustEditInteractor();
private: private:
const char *action(Error &err) const override; /* reimp */ const char *action(Error &err) const;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override; /* reimp */ unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const;
private: private:
const Key::OwnerTrust m_ownertrust; const Key::OwnerTrust m_ownertrust;

View File

@ -64,13 +64,6 @@ public:
std::vector<unsigned int> userIDs; std::vector<unsigned int> userIDs;
std::vector<unsigned int>::const_iterator currentId, nextId; std::vector<unsigned int>::const_iterator currentId, nextId;
unsigned int checkLevel; unsigned int checkLevel;
bool dupeOk;
Key key;
struct {
TrustSignatureTrust trust;
std::string depth;
std::string scope;
} trustSignature;
const char *command() const const char *command() const
{ {
@ -133,9 +126,7 @@ GpgSignKeyEditInteractor::Private::Private()
userIDs(), userIDs(),
currentId(), currentId(),
nextId(), nextId(),
checkLevel(0), checkLevel(0)
dupeOk(false),
trustSignature{TrustSignatureTrust::None, "0", {}}
{ {
} }
@ -168,9 +159,6 @@ enum SignKeyState {
SET_TRUST_REGEXP, SET_TRUST_REGEXP,
CONFIRM, CONFIRM,
CONFIRM2, CONFIRM2,
DUPE_OK,
DUPE_OK2,
REJECT_SIGN_EXPIRED,
QUIT, QUIT,
SAVE, SAVE,
ERROR = EditInteractor::ErrorState ERROR = EditInteractor::ErrorState
@ -194,43 +182,30 @@ static GpgSignKeyEditInteractor_Private::TransitionMap makeTable()
#define addEntry( s1, status, str, s2 ) tab[std::make_tuple( s1, status, str)] = s2 #define addEntry( s1, status, str, s2 ) tab[std::make_tuple( s1, status, str)] = s2
addEntry(START, GET_LINE, "keyedit.prompt", COMMAND); addEntry(START, GET_LINE, "keyedit.prompt", COMMAND);
addEntry(COMMAND, GET_BOOL, "keyedit.sign_all.okay", UIDS_ANSWER_SIGN_ALL); addEntry(COMMAND, GET_BOOL, "keyedit.sign_all.okay", UIDS_ANSWER_SIGN_ALL);
addEntry(COMMAND, GET_BOOL, "sign_uid.expired_okay", REJECT_SIGN_EXPIRED);
addEntry(COMMAND, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(COMMAND, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(COMMAND, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM2); addEntry(COMMAND, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM2);
addEntry(COMMAND, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK);
addEntry(COMMAND, GET_LINE, "trustsig_prompt.trust_value", SET_TRUST_VALUE);
addEntry(UIDS_ANSWER_SIGN_ALL, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(UIDS_ANSWER_SIGN_ALL, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(UIDS_ANSWER_SIGN_ALL, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK);
addEntry(UIDS_ANSWER_SIGN_ALL, GET_LINE, "sign_uid.expire", SET_EXPIRE); addEntry(UIDS_ANSWER_SIGN_ALL, GET_LINE, "sign_uid.expire", SET_EXPIRE);
addEntry(UIDS_ANSWER_SIGN_ALL, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL); addEntry(UIDS_ANSWER_SIGN_ALL, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL);
addEntry(UIDS_ANSWER_SIGN_ALL, GET_LINE, "trustsig_prompt.trust_value", SET_TRUST_VALUE); addEntry(SET_TRUST_VALUE, GET_LINE, "trustsign_prompt.trust_depth", SET_TRUST_DEPTH);
addEntry(SET_TRUST_VALUE, GET_LINE, "trustsig_prompt.trust_depth", SET_TRUST_DEPTH); addEntry(SET_TRUST_DEPTH, GET_LINE, "trustsign_prompt.trust_regexp", SET_TRUST_REGEXP);
addEntry(SET_TRUST_DEPTH, GET_LINE, "trustsig_prompt.trust_regexp", SET_TRUST_REGEXP); addEntry(SET_TRUST_REGEXP, GET_LINE, "sign_uid.okay", CONFIRM);
addEntry(SET_TRUST_REGEXP, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(SET_CHECK_LEVEL, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(SET_CHECK_LEVEL, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(SET_EXPIRE, GET_BOOL, "sign_uid.class", SET_CHECK_LEVEL); addEntry(SET_EXPIRE, GET_BOOL, "sign_uid.class", SET_CHECK_LEVEL);
addEntry(CONFIRM, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM); addEntry(CONFIRM, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM);
addEntry(DUPE_OK, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(DUPE_OK2, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(DUPE_OK, GET_LINE, "trustsig_prompt.trust_value", SET_TRUST_VALUE);
addEntry(DUPE_OK2, GET_LINE, "trustsig_prompt.trust_value", SET_TRUST_VALUE);
addEntry(CONFIRM, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(CONFIRM, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(CONFIRM2, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(CONFIRM2, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(CONFIRM, GET_LINE, "keyedit.prompt", COMMAND); addEntry(CONFIRM, GET_LINE, "keyedit.prompt", COMMAND);
addEntry(CONFIRM, GET_LINE, "trustsig_prompt.trust_value", SET_TRUST_VALUE); addEntry(CONFIRM, GET_LINE, "trustsign_prompt.trust_value", SET_TRUST_VALUE);
addEntry(CONFIRM, GET_LINE, "sign_uid.expire", SET_EXPIRE); addEntry(CONFIRM, GET_LINE, "sign_uid.expire", SET_EXPIRE);
addEntry(CONFIRM, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL); addEntry(CONFIRM, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.local_promote_okay", CONFIRM);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "keyedit.prompt", COMMAND); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "keyedit.prompt", COMMAND);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "trustsig_prompt.trust_value", SET_TRUST_VALUE); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "trustsign_prompt.trust_value", SET_TRUST_VALUE);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.expire", SET_EXPIRE); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.expire", SET_EXPIRE);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_LINE, "sign_uid.class", SET_CHECK_LEVEL);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.okay", CONFIRM); addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.okay", CONFIRM);
addEntry(UIDS_LIST_SEPARATELY_DONE, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK);
addEntry(DUPE_OK, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK2);
addEntry(DUPE_OK2, GET_BOOL, "sign_uid.dupe_okay", DUPE_OK);
addEntry(CONFIRM, GET_LINE, "keyedit.prompt", QUIT); addEntry(CONFIRM, GET_LINE, "keyedit.prompt", QUIT);
addEntry(REJECT_SIGN_EXPIRED, GET_LINE, "keyedit.prompt", QUIT);
addEntry(ERROR, GET_LINE, "keyedit.prompt", QUIT); addEntry(ERROR, GET_LINE, "keyedit.prompt", QUIT);
addEntry(QUIT, GET_BOOL, "keyedit.save.okay", SAVE); addEntry(QUIT, GET_BOOL, "keyedit.save.okay", SAVE);
#undef addEntry #undef addEntry
@ -253,22 +228,17 @@ const char *GpgSignKeyEditInteractor::action(Error &err) const
case SET_EXPIRE: case SET_EXPIRE:
return answer(true); return answer(true);
case SET_TRUST_VALUE: case SET_TRUST_VALUE:
return d->trustSignature.trust == TrustSignatureTrust::Partial ? "1" : "2"; // TODO
case SET_TRUST_DEPTH: case SET_TRUST_DEPTH:
return d->trustSignature.depth.c_str(); //TODO
case SET_TRUST_REGEXP: case SET_TRUST_REGEXP:
return d->trustSignature.scope.c_str(); //TODO
return 0;
case SET_CHECK_LEVEL: case SET_CHECK_LEVEL:
return check_level_strings[d->checkLevel]; return check_level_strings[d->checkLevel];
case DUPE_OK:
case DUPE_OK2:
return answer(d->dupeOk);
case CONFIRM2: case CONFIRM2:
case CONFIRM: case CONFIRM:
return answer(true); return answer(true);
case REJECT_SIGN_EXPIRED:
err = Error::fromCode(GPG_ERR_KEY_EXPIRED);
return answer(false);
case QUIT: case QUIT:
return "quit"; return "quit";
case SAVE: case SAVE:
@ -276,24 +246,14 @@ const char *GpgSignKeyEditInteractor::action(Error &err) const
default: default:
if (st >= UIDS_LIST_SEPARATELY && st < UIDS_LIST_SEPARATELY_DONE) { if (st >= UIDS_LIST_SEPARATELY && st < UIDS_LIST_SEPARATELY_DONE) {
std::stringstream ss; std::stringstream ss;
auto nextID = d->nextUserID(); ss << d->nextUserID();
const char *hash;
assert (nextID);
if (!d->key.isNull() && (hash = d->key.userID(nextID - 1).uidhash())) {
/* Prefer uidhash if it is available as it might happen
* that uidattrs break the ordering of the uids in the
* edit-key interface */
ss << "uid " << hash;
} else {
ss << nextID;
}
d->scratch = ss.str(); d->scratch = ss.str();
return d->scratch.c_str(); return d->scratch.c_str();
} }
// fall through // fall through
case ERROR: case ERROR:
err = Error::fromCode(GPG_ERR_GENERAL); err = Error::fromCode(GPG_ERR_GENERAL);
return nullptr; return 0;
} }
} }
@ -304,6 +264,9 @@ unsigned int GpgSignKeyEditInteractor::nextState(unsigned int status, const char
static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL); static const Error GENERAL_ERROR = Error::fromCode(GPG_ERR_GENERAL);
//static const Error INV_TIME_ERROR = Error::fromCode( GPG_ERR_INV_TIME ); //static const Error INV_TIME_ERROR = Error::fromCode( GPG_ERR_INV_TIME );
static const TransitionMap table(makeTable()); static const TransitionMap table(makeTable());
if (needsNoResponse(status)) {
return state();
}
using namespace GpgSignKeyEditInteractor_Private; using namespace GpgSignKeyEditInteractor_Private;
@ -342,10 +305,6 @@ unsigned int GpgSignKeyEditInteractor::nextState(unsigned int status, const char
err = GENERAL_ERROR; err = GENERAL_ERROR;
return ERROR; return ERROR;
} }
void GpgSignKeyEditInteractor::setKey(const Key &key)
{
d->key = key;
}
void GpgSignKeyEditInteractor::setCheckLevel(unsigned int checkLevel) void GpgSignKeyEditInteractor::setCheckLevel(unsigned int checkLevel)
{ {
@ -367,29 +326,3 @@ void GpgSignKeyEditInteractor::setSigningOptions(int options)
assert(!d->started); assert(!d->started);
d->options = options; d->options = options;
} }
void GpgSignKeyEditInteractor::setDupeOk(bool value)
{
assert(!d->started);
d->dupeOk = value;
}
void GpgSignKeyEditInteractor::setTrustSignatureTrust(GpgME::TrustSignatureTrust trust)
{
assert(!d->started);
assert(trust != TrustSignatureTrust::None);
d->trustSignature.trust = trust;
}
void GpgSignKeyEditInteractor::setTrustSignatureDepth(unsigned short depth)
{
assert(!d->started);
assert(depth <= 255);
d->trustSignature.depth = std::to_string(depth);
}
void GpgSignKeyEditInteractor::setTrustSignatureScope(const std::string &scope)
{
assert(!d->started);
d->trustSignature.scope = scope;
}

View File

@ -25,7 +25,7 @@
#ifndef __GPGMEPP_GPGSIGNKEYEDITINTERACTOR_H__ #ifndef __GPGMEPP_GPGSIGNKEYEDITINTERACTOR_H__
#define __GPGMEPP_GPGSIGNKEYEDITINTERACTOR_H__ #define __GPGMEPP_GPGSIGNKEYEDITINTERACTOR_H__
#include "editinteractor.h" #include <editinteractor.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -35,7 +35,6 @@ namespace GpgME
class Key; class Key;
class UserID; class UserID;
enum class TrustSignatureTrust : char;
class GPGMEPP_EXPORT GpgSignKeyEditInteractor : public EditInteractor class GPGMEPP_EXPORT GpgSignKeyEditInteractor : public EditInteractor
{ {
@ -51,21 +50,11 @@ public:
void setCheckLevel(unsigned int checkLevel); void setCheckLevel(unsigned int checkLevel);
void setUserIDsToSign(const std::vector<unsigned int> &userIDsToSign); void setUserIDsToSign(const std::vector<unsigned int> &userIDsToSign);
void setKey(const Key &key);
void setSigningOptions(int options); void setSigningOptions(int options);
/* Set this if it is ok to overwrite an existing signature. In that
* case the context has to have the flag "extended-edit" set to 1 through
* Context::setFlag before calling edit.*/
void setDupeOk(bool value);
void setTrustSignatureTrust(TrustSignatureTrust trust);
void setTrustSignatureDepth(unsigned short depth);
void setTrustSignatureScope(const std::string &scope);
private: private:
const char *action(Error &err) const override; /* reimp */ const char *action(Error &err) const;
unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const override; /* reimp */ unsigned int nextState(unsigned int statusCode, const char *args, Error &err) const;
private: private:
class Private; class Private;

View File

@ -35,9 +35,6 @@
#include <cstring> #include <cstring>
#include <string.h> #include <string.h>
#include <strings.h>
#include <istream>
#include <iterator>
class GpgME::ImportResult::Private class GpgME::ImportResult::Private
{ {
@ -48,19 +45,17 @@ public:
// We just need to handle the pointers in the structs: // We just need to handle the pointers in the structs:
for (gpgme_import_status_t is = r.imports ; is ; is = is->next) { for (gpgme_import_status_t is = r.imports ; is ; is = is->next) {
gpgme_import_status_t copy = new _gpgme_import_status(*is); gpgme_import_status_t copy = new _gpgme_import_status(*is);
if (is->fpr) { copy->fpr = strdup(is->fpr);
copy->fpr = strdup(is->fpr); copy->next = 0;
}
copy->next = nullptr;
imports.push_back(copy); imports.push_back(copy);
} }
res.imports = nullptr; res.imports = 0;
} }
~Private() ~Private()
{ {
for (std::vector<gpgme_import_status_t>::iterator it = imports.begin() ; it != imports.end() ; ++it) { for (std::vector<gpgme_import_status_t>::iterator it = imports.begin() ; it != imports.end() ; ++it) {
std::free((*it)->fpr); std::free((*it)->fpr);
delete *it; *it = nullptr; delete *it; *it = 0;
} }
} }
@ -94,131 +89,6 @@ void GpgME::ImportResult::init(gpgme_ctx_t ctx)
make_standard_stuff(ImportResult) make_standard_stuff(ImportResult)
void GpgME::ImportResult::mergeWith(const ImportResult &other)
{
if (other.isNull()) {
return;
}
if (isNull()) { // just assign
operator=(other);
return;
}
// Add the numbers of considered keys; the number will be corrected when
// merging the imports to account for duplicates
d->res.considered += other.d->res.considered;
// Add the numbers of keys without user ID; may count duplicates
d->res.no_user_id += other.d->res.no_user_id;
// Add the numbers of imported keys
d->res.imported += other.d->res.imported;
// Add the numbers of imported RSA keys
d->res.imported_rsa += other.d->res.imported_rsa;
// Add the numbers of unchanged keys; the number will be corrected when
// merging the imports to account for keys changed by this import
d->res.unchanged += other.d->res.unchanged;
// Add the numbers of new user IDs
d->res.new_user_ids += other.d->res.new_user_ids;
// Add the numbers of new subkeys
d->res.new_sub_keys += other.d->res.new_sub_keys;
// Add the numbers of new signatures
d->res.new_signatures += other.d->res.new_signatures;
// Add the numbers of new revocations
d->res.new_revocations += other.d->res.new_revocations;
// Add the numbers of considered secret keys; the number will be corrected when
// merging the imports to account for duplicates
d->res.secret_read += other.d->res.secret_read;
// Add the numbers of imported secret keys
d->res.secret_imported += other.d->res.secret_imported;
// Add the numbers of unchanged secret keys; the number will be corrected when
// merging the imports to account for keys changed by this import
d->res.secret_unchanged += other.d->res.secret_unchanged;
// Add the numbers of new keys that were skipped; may count duplicates
d->res.skipped_new_keys += other.d->res.skipped_new_keys;
// Add the numbers of keys that were not imported; may count duplicates
d->res.not_imported += other.d->res.not_imported;
// Add the numbers of v3 keys that were skipped; may count duplicates
d->res.skipped_v3_keys += other.d->res.skipped_v3_keys;
// Look at the list of keys for which an import was attempted during the
// other import to correct some of the consolidated numbers
for (auto it = std::begin(other.d->imports), end = std::end(other.d->imports); it != end; ++it) {
const char *fpr = (*it)->fpr;
if (!fpr || !*fpr) {
// we cannot derive any useful information about an import if the
// fingerprint is null or empty
continue;
}
// was this key also considered during the first import
const auto consideredInFirstImports =
std::any_of(std::begin(d->imports), std::end(d->imports), [fpr](const gpgme_import_status_t i) {
return i->fpr && !strcmp(i->fpr, fpr);
});
// did we see this key already in the list of keys of the other import
const auto consideredInPreviousOtherImports =
std::any_of(std::begin(other.d->imports), it, [fpr](const gpgme_import_status_t i) {
return i->fpr && !strcmp(i->fpr, fpr);
});
// was anything added to this key during the other import
const auto changedInOtherImports =
std::any_of(std::begin(other.d->imports), std::end(other.d->imports), [fpr](const gpgme_import_status_t i) {
return i->fpr && !strcmp(i->fpr, fpr) && (i->status != 0);
});
if (consideredInFirstImports && !consideredInPreviousOtherImports) {
// key was also considered during first import, but not before in the list of other imports
d->res.considered -= 1;
if (!changedInOtherImports) {
// key was (most likely) counted as unchanged in the second import;
// this needs to be corrected (regardless of whether it was changed in the first import)
d->res.unchanged -= 1;
}
}
// now do the same for the secret key counts
const auto secretKeyConsideredInFirstImports =
std::any_of(std::begin(d->imports), std::end(d->imports), [fpr](const gpgme_import_status_t i) {
return i->fpr && !strcmp(i->fpr, fpr) && (i->status & GPGME_IMPORT_SECRET);
});
const auto secretKeyConsideredInPreviousOtherImports =
std::any_of(std::begin(other.d->imports), it, [fpr](const gpgme_import_status_t i) {
return i->fpr && !strcmp(i->fpr, fpr) && (i->status & GPGME_IMPORT_SECRET);
});
const auto secretKeyChangedInOtherImports =
std::any_of(std::begin(other.d->imports), std::end(other.d->imports), [fpr](const gpgme_import_status_t i) {
return i->fpr && !strcmp(i->fpr, fpr) && (i->status & GPGME_IMPORT_SECRET) && (i->status != GPGME_IMPORT_SECRET);
});
if (secretKeyConsideredInFirstImports && !secretKeyConsideredInPreviousOtherImports) {
// key was also considered during first import, but not before in the list of other imports
d->res.secret_read -= 1;
if (!secretKeyChangedInOtherImports) {
// key was (most likely) counted as unchanged in the second import;
// this needs to be corrected (regardless of whether it was changed in the first import)
d->res.secret_unchanged -= 1;
}
}
}
// Now append the list of keys for which an import was attempted during the
// other import
d->imports.reserve(d->imports.size() + other.d->imports.size());
std::transform(std::begin(other.d->imports), std::end(other.d->imports),
std::back_inserter(d->imports),
[](const gpgme_import_status_t import) {
gpgme_import_status_t copy = new _gpgme_import_status{*import};
if (import->fpr) {
copy->fpr = strdup(import->fpr);
}
copy->next = nullptr; // should already be null, but better safe than sorry
return copy;
});
// Finally, merge the error if there was none yet
if (!bool(error())) {
Result::operator=(other);
}
}
int GpgME::ImportResult::numConsidered() const int GpgME::ImportResult::numConsidered() const
{ {
return d ? d->res.considered : 0 ; return d ? d->res.considered : 0 ;
@ -322,7 +192,7 @@ bool GpgME::Import::isNull() const
const char *GpgME::Import::fingerprint() const const char *GpgME::Import::fingerprint() const
{ {
return isNull() ? nullptr : d->imports[idx]->fpr ; return isNull() ? 0 : d->imports[idx]->fpr ;
} }
GpgME::Error GpgME::Import::error() const GpgME::Error GpgME::Import::error() const
@ -354,42 +224,3 @@ GpgME::Import::Status GpgME::Import::status() const
} }
return static_cast<Status>(result); return static_cast<Status>(result);
} }
std::ostream &GpgME::operator<<(std::ostream &os,
const GpgME::ImportResult &result)
{
os << "GpgME::ImportResult(";
if (!result.isNull()) {
os << "\n considered: " << result.numConsidered()
<< "\n without UID: " << result.numKeysWithoutUserID()
<< "\n imported: " << result.numImported()
<< "\n RSA Imported: " << result.numRSAImported()
<< "\n unchanged: " << result.numUnchanged()
<< "\n newUserIDs: " << result.newUserIDs()
<< "\n newSubkeys: " << result.newSubkeys()
<< "\n newSignatures: " << result.newSignatures()
<< "\n newRevocations: " << result.newRevocations()
<< "\n numSecretKeysConsidered: " << result.numSecretKeysConsidered()
<< "\n numSecretKeysImported: " << result.numSecretKeysImported()
<< "\n numSecretKeysUnchanged: " << result.numSecretKeysUnchanged()
<< "\n"
<< "\n notImported: " << result.notImported()
<< "\n numV3KeysSkipped: " << result.numV3KeysSkipped()
<< "\n imports:\n";
const std::vector<Import> imp = result.imports();
std::copy(imp.begin(), imp.end(),
std::ostream_iterator<Import>(os, "\n"));
}
return os << ')';
}
std::ostream &GpgME::operator<<(std::ostream &os, const GpgME::Import &imp)
{
os << "GpgME::Import(";
if (!imp.isNull()) {
os << "\n fpr: " << (imp.fingerprint() ? imp.fingerprint() : "null")
<< "\n status: " << imp.status()
<< "\n err: " << imp.error();
}
return os << ')';
}

View File

@ -47,7 +47,6 @@ public:
ImportResult(gpgme_ctx_t ctx, const Error &error); ImportResult(gpgme_ctx_t ctx, const Error &error);
explicit ImportResult(const Error &error); explicit ImportResult(const Error &error);
ImportResult(const ImportResult &other) = default;
const ImportResult &operator=(ImportResult other) const ImportResult &operator=(ImportResult other)
{ {
swap(other); swap(other);
@ -61,16 +60,6 @@ public:
swap(this->d, other.d); swap(this->d, other.d);
} }
/**
* Merges the result @p other into this result (and all of its copies).
*
* @note The merge algorithm assumes that @p other is the result of an
* import that was performed after the import of this result.
* @note Some numbers cannot be consolidated reliably, e.g. the number of
* keys without user ID.
*/
void mergeWith(const ImportResult &other);
bool isNull() const; bool isNull() const;
int numConsidered() const; int numConsidered() const;
@ -107,7 +96,6 @@ class GPGMEPP_EXPORT Import
public: public:
Import(); Import();
Import(const Import &other) = default;
const Import &operator=(Import other) const Import &operator=(Import other)
{ {
swap(other); swap(other);
@ -141,10 +129,7 @@ private:
unsigned int idx; unsigned int idx;
}; };
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const ImportResult &irs); }
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const Import &imp);
} // namespace GpgME
GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(ImportResult) GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(ImportResult)
GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(Import) GPGMEPP_MAKE_STD_SWAP_SPECIALIZATION(Import)

View File

@ -26,7 +26,7 @@
#ifndef __GPGMEPP_INTERFACES_ASSUANTRANSACTION_H__ #ifndef __GPGMEPP_INTERFACES_ASSUANTRANSACTION_H__
#define __GPGMEPP_INTERFACES_ASSUANTRANSACTION_H__ #define __GPGMEPP_INTERFACES_ASSUANTRANSACTION_H__
#include "../gpgmepp_export.h" #include "gpgmepp_export.h"
#include <stddef.h> #include <stddef.h>

View File

@ -27,7 +27,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "../gpgmepp_export.h" #include "gpgmepp_export.h"
#include <gpg-error.h> #include <gpg-error.h>

View File

@ -29,13 +29,11 @@
#include "util.h" #include "util.h"
#include "tofuinfo.h" #include "tofuinfo.h"
#include "context.h" #include "context.h"
#include "engineinfo.h"
#include <gpgme.h> #include <gpgme.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <cassert>
#include <istream> #include <istream>
#include <iterator> #include <iterator>
@ -122,37 +120,6 @@ std::vector<Subkey> Key::subkeys() const
return v; return v;
} }
RevocationKey Key::revocationKey(unsigned int index) const
{
return RevocationKey(key, index);
}
unsigned int Key::numRevocationKeys() const
{
if (!key) {
return 0;
}
unsigned int count = 0;
for (auto revkey = key->revocation_keys; revkey; revkey = revkey->next) {
++count;
}
return count;
}
std::vector<RevocationKey> Key::revocationKeys() const
{
if (!key) {
return std::vector<RevocationKey>();
}
std::vector<RevocationKey> v;
v.reserve(numRevocationKeys());
for (auto revkey = key->revocation_keys; revkey; revkey = revkey->next) {
v.push_back(RevocationKey(key, revkey));
}
return v;
}
Key::OwnerTrust Key::ownerTrust() const Key::OwnerTrust Key::ownerTrust() const
{ {
if (!key) { if (!key) {
@ -198,7 +165,7 @@ Protocol Key::protocol() const
const char *Key::protocolAsString() const const char *Key::protocolAsString() const
{ {
return key ? gpgme_get_protocol_name(key->protocol) : nullptr ; return key ? gpgme_get_protocol_name(key->protocol) : 0 ;
} }
bool Key::isRevoked() const bool Key::isRevoked() const
@ -239,12 +206,17 @@ bool Key::canEncrypt() const
bool Key::canSign() const bool Key::canSign() const
{ {
return key && key->can_sign; #ifndef GPGME_CAN_SIGN_ON_SECRET_OPENPGP_KEYLISTING_NOT_BROKEN
if (key && key->protocol == GPGME_PROTOCOL_OpenPGP) {
return true;
}
#endif
return canReallySign();
} }
bool Key::canReallySign() const bool Key::canReallySign() const
{ {
return canSign(); return key && key->can_sign;
} }
bool Key::canCertify() const bool Key::canCertify() const
@ -278,48 +250,28 @@ bool Key::isDeVs() const
return true; return true;
} }
bool Key::hasCertify() const
{
return key && key->has_certify;
}
bool Key::hasSign() const
{
return key && key->has_sign;
}
bool Key::hasEncrypt() const
{
return key && key->has_encrypt;
}
bool Key::hasAuthenticate() const
{
return key && key->has_authenticate;
}
const char *Key::issuerSerial() const const char *Key::issuerSerial() const
{ {
return key ? key->issuer_serial : nullptr ; return key ? key->issuer_serial : 0 ;
} }
const char *Key::issuerName() const const char *Key::issuerName() const
{ {
return key ? key->issuer_name : nullptr ; return key ? key->issuer_name : 0 ;
} }
const char *Key::chainID() const const char *Key::chainID() const
{ {
return key ? key->chain_id : nullptr ; return key ? key->chain_id : 0 ;
} }
const char *Key::keyID() const const char *Key::keyID() const
{ {
return key && key->subkeys ? key->subkeys->keyid : nullptr ; return key && key->subkeys ? key->subkeys->keyid : 0 ;
} }
const char *Key::shortKeyID() const const char *Key::shortKeyID() const
{ {
if (!key || !key->subkeys || !key->subkeys->keyid) { if (!key || !key->subkeys || !key->subkeys->keyid) {
return nullptr; return 0;
} }
const int len = strlen(key->subkeys->keyid); const int len = strlen(key->subkeys->keyid);
if (len > 8) { if (len > 8) {
@ -347,7 +299,7 @@ const char *Key::primaryFingerprint() const
unsigned int Key::keyListMode() const unsigned int Key::keyListMode() const
{ {
return key ? convert_from_gpgme_keylist_mode_t(key->keylist_mode) : 0; return key ? convert_from_gpgme_keylist_mode_t(key->keylist_mode) : 0 ;
} }
const Key &Key::mergeWith(const Key &other) const Key &Key::mergeWith(const Key &other)
@ -385,10 +337,6 @@ const Key &Key::mergeWith(const Key &other)
for (gpgme_sub_key_t hissk = him->subkeys ; hissk ; hissk = hissk->next) { for (gpgme_sub_key_t hissk = him->subkeys ; hissk ; hissk = hissk->next) {
if (strcmp(mysk->fpr, hissk->fpr) == 0) { if (strcmp(mysk->fpr, hissk->fpr) == 0) {
mysk->is_cardkey |= hissk->is_cardkey; mysk->is_cardkey |= hissk->is_cardkey;
mysk->secret |= hissk->secret;
if (hissk->keygrip && !mysk->keygrip) {
mysk->keygrip = strdup(hissk->keygrip);
}
break; break;
} }
} }
@ -399,9 +347,6 @@ const Key &Key::mergeWith(const Key &other)
void Key::update() void Key::update()
{ {
if (isNull() || !primaryFingerprint()) {
return;
}
auto ctx = Context::createForProtocol(protocol()); auto ctx = Context::createForProtocol(protocol());
if (!ctx) { if (!ctx) {
return; return;
@ -410,25 +355,20 @@ void Key::update()
KeyListMode::Signatures | KeyListMode::Signatures |
KeyListMode::SignatureNotations | KeyListMode::SignatureNotations |
KeyListMode::Validate | KeyListMode::Validate |
KeyListMode::WithTofu | KeyListMode::WithTofu);
KeyListMode::WithKeygrip |
KeyListMode::WithSecret);
Error err; Error err;
Key newKey; auto newKey = ctx->key(primaryFingerprint(), err, true);
if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.0") { // Not secret so we get the information from the pubring.
newKey = ctx->key(primaryFingerprint(), err, true); if (newKey.isNull())
// Not secret so we get the information from the pubring. {
if (newKey.isNull()) {
newKey = ctx->key(primaryFingerprint(), err, false);
}
} else {
newKey = ctx->key(primaryFingerprint(), err, false); newKey = ctx->key(primaryFingerprint(), err, false);
} }
delete ctx; delete ctx;
if (err) { if (err) {
return; return;
} }
swap(newKey); swap(newKey);
return;
} }
// static // static
@ -458,7 +398,7 @@ Key Key::locate(const char *mbox)
// //
// //
static gpgme_sub_key_t find_subkey(const shared_gpgme_key_t &key, unsigned int idx) gpgme_sub_key_t find_subkey(const shared_gpgme_key_t &key, unsigned int idx)
{ {
if (key) { if (key) {
for (gpgme_sub_key_t s = key->subkeys ; s ; s = s->next, --idx) { for (gpgme_sub_key_t s = key->subkeys ; s ; s = s->next, --idx) {
@ -467,10 +407,10 @@ static gpgme_sub_key_t find_subkey(const shared_gpgme_key_t &key, unsigned int i
} }
} }
} }
return nullptr; return 0;
} }
static gpgme_sub_key_t verify_subkey(const shared_gpgme_key_t &key, gpgme_sub_key_t subkey) gpgme_sub_key_t verify_subkey(const shared_gpgme_key_t &key, gpgme_sub_key_t subkey)
{ {
if (key) { if (key) {
for (gpgme_sub_key_t s = key->subkeys ; s ; s = s->next) { for (gpgme_sub_key_t s = key->subkeys ; s ; s = s->next) {
@ -479,10 +419,10 @@ static gpgme_sub_key_t verify_subkey(const shared_gpgme_key_t &key, gpgme_sub_ke
} }
} }
} }
return nullptr; return 0;
} }
Subkey::Subkey() : key(), subkey(nullptr) {} Subkey::Subkey() : key(), subkey(0) {}
Subkey::Subkey(const shared_gpgme_key_t &k, unsigned int idx) Subkey::Subkey(const shared_gpgme_key_t &k, unsigned int idx)
: key(k), subkey(find_subkey(k, idx)) : key(k), subkey(find_subkey(k, idx))
@ -503,12 +443,12 @@ Key Subkey::parent() const
const char *Subkey::keyID() const const char *Subkey::keyID() const
{ {
return subkey ? subkey->keyid : nullptr ; return subkey ? subkey->keyid : 0 ;
} }
const char *Subkey::fingerprint() const const char *Subkey::fingerprint() const
{ {
return subkey ? subkey->fpr : nullptr ; return subkey ? subkey->fpr : 0 ;
} }
Subkey::PubkeyAlgo Subkey::publicKeyAlgorithm() const Subkey::PubkeyAlgo Subkey::publicKeyAlgorithm() const
@ -561,21 +501,6 @@ bool Subkey::canAuthenticate() const
return subkey && subkey->can_authenticate; return subkey && subkey->can_authenticate;
} }
bool Subkey::canRenc() const
{
return subkey && subkey->can_renc;
}
bool Subkey::canTimestamp() const
{
return subkey && subkey->can_timestamp;
}
bool Subkey::isGroupOwned() const
{
return subkey && subkey->is_group_owned;
}
bool Subkey::isQualified() const bool Subkey::isQualified() const
{ {
return subkey && subkey->is_qualified; return subkey && subkey->is_qualified;
@ -652,7 +577,7 @@ bool Subkey::isDisabled() const
// //
// //
static gpgme_user_id_t find_uid(const shared_gpgme_key_t &key, unsigned int idx) gpgme_user_id_t find_uid(const shared_gpgme_key_t &key, unsigned int idx)
{ {
if (key) { if (key) {
for (gpgme_user_id_t u = key->uids ; u ; u = u->next, --idx) { for (gpgme_user_id_t u = key->uids ; u ; u = u->next, --idx) {
@ -661,10 +586,10 @@ static gpgme_user_id_t find_uid(const shared_gpgme_key_t &key, unsigned int idx)
} }
} }
} }
return nullptr; return 0;
} }
static gpgme_user_id_t verify_uid(const shared_gpgme_key_t &key, gpgme_user_id_t uid) gpgme_user_id_t verify_uid(const shared_gpgme_key_t &key, gpgme_user_id_t uid)
{ {
if (key) { if (key) {
for (gpgme_user_id_t u = key->uids ; u ; u = u->next) { for (gpgme_user_id_t u = key->uids ; u ; u = u->next) {
@ -673,10 +598,10 @@ static gpgme_user_id_t verify_uid(const shared_gpgme_key_t &key, gpgme_user_id_t
} }
} }
} }
return nullptr; return 0;
} }
UserID::UserID() : key(), uid(nullptr) {} UserID::UserID() : key(), uid(0) {}
UserID::UserID(const shared_gpgme_key_t &k, gpgme_user_id_t u) UserID::UserID(const shared_gpgme_key_t &k, gpgme_user_id_t u)
: key(k), uid(verify_uid(k, u)) : key(k), uid(verify_uid(k, u))
@ -728,27 +653,22 @@ std::vector<UserID::Signature> UserID::signatures() const
const char *UserID::id() const const char *UserID::id() const
{ {
return uid ? uid->uid : nullptr ; return uid ? uid->uid : 0 ;
} }
const char *UserID::name() const const char *UserID::name() const
{ {
return uid ? uid->name : nullptr ; return uid ? uid->name : 0 ;
} }
const char *UserID::email() const const char *UserID::email() const
{ {
return uid ? uid->email : nullptr ; return uid ? uid->email : 0 ;
} }
const char *UserID::comment() const const char *UserID::comment() const
{ {
return uid ? uid->comment : nullptr ; return uid ? uid->comment : 0 ;
}
const char *UserID::uidhash() const
{
return uid ? uid->uidhash : nullptr ;
} }
UserID::Validity UserID::validity() const UserID::Validity UserID::validity() const
@ -801,83 +721,13 @@ TofuInfo UserID::tofuInfo() const
return TofuInfo(uid->tofu); return TofuInfo(uid->tofu);
} }
static gpgme_key_sig_t find_last_valid_sig_for_keyid (gpgme_user_id_t uid,
const char *keyid)
{
if (!keyid) {
return nullptr;
}
gpgme_key_sig_t ret = NULL;
for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next) {
if (s->keyid && !strcmp(keyid, s->keyid)) {
if (!s->expired && !s->revoked && !s->invalid && !s->status) {
if (!ret) {
ret = s;
} else if (ret && ret->timestamp <= s->timestamp) {
/* Equals because when the timestamps are the same we prefer
the last in the list */
ret = s;
}
}
}
}
return ret;
}
const char *UserID::remark(const Key &remarker, Error &err) const
{
if (!uid || remarker.isNull()) {
err = Error::fromCode(GPG_ERR_GENERAL);
return nullptr;
}
if (key->protocol != GPGME_PROTOCOL_OpenPGP) {
return nullptr;
}
if (!(key->keylist_mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS) ||
!(key->keylist_mode & GPGME_KEYLIST_MODE_SIGS)) {
err = Error::fromCode(GPG_ERR_NO_DATA);
return nullptr;
}
gpgme_key_sig_t s = find_last_valid_sig_for_keyid(uid, remarker.keyID());
if (!s) {
return nullptr;
}
for (gpgme_sig_notation_t n = s->notations; n ; n = n->next) {
if (n->name && !strcmp(n->name, "rem@gnupg.org")) {
return n->value;
}
}
return nullptr;
}
std::vector<std::string> UserID::remarks(std::vector<Key> keys, Error &err) const
{
std::vector<std::string> ret;
for (const auto &key: keys) {
const char *rem = remark(key, err);
if (err) {
return ret;
}
if (rem) {
ret.push_back(rem);
}
}
return ret;
}
// //
// //
// class Signature // class Signature
// //
// //
static gpgme_key_sig_t find_signature(gpgme_user_id_t uid, unsigned int idx) gpgme_key_sig_t find_signature(gpgme_user_id_t uid, unsigned int idx)
{ {
if (uid) { if (uid) {
for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next, --idx) { for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next, --idx) {
@ -886,10 +736,10 @@ static gpgme_key_sig_t find_signature(gpgme_user_id_t uid, unsigned int idx)
} }
} }
} }
return nullptr; return 0;
} }
static gpgme_key_sig_t verify_signature(gpgme_user_id_t uid, gpgme_key_sig_t sig) gpgme_key_sig_t verify_signature(gpgme_user_id_t uid, gpgme_key_sig_t sig)
{ {
if (uid) { if (uid) {
for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next) { for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next) {
@ -898,85 +748,21 @@ static gpgme_key_sig_t verify_signature(gpgme_user_id_t uid, gpgme_key_sig_t sig
} }
} }
} }
return nullptr; return 0;
} }
static int signature_index(gpgme_user_id_t uid, gpgme_key_sig_t sig) UserID::Signature::Signature() : key(), uid(0), sig(0) {}
{
if (uid) {
int i = 0;
for (gpgme_key_sig_t s = uid->signatures ; s ; s = s->next, ++i) {
if (s == sig) {
return i;
}
}
}
return -1;
}
UserID::Signature::Signature() : key(), uid(nullptr), sig(nullptr) {}
UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, unsigned int idx) UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, unsigned int idx)
: key(k), uid(verify_uid(k, u)), sig(find_signature(uid, idx)) : key(k), uid(verify_uid(k, u)), sig(find_signature(uid, idx))
{ {
} }
UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, gpgme_key_sig_t s) UserID::Signature::Signature(const shared_gpgme_key_t &k, gpgme_user_id_t u, gpgme_key_sig_t s)
: key(k), uid(verify_uid(k, u)), sig(verify_signature(uid, s)) : key(k), uid(verify_uid(k, u)), sig(verify_signature(uid, s))
{ {
}
bool UserID::Signature::operator<(const Signature &other)
{
// kept for binary compatibility
return static_cast<const UserID::Signature *>(this)->operator<(other);
}
bool UserID::Signature::operator<(const Signature &other) const
{
// based on cmp_signodes() in g10/keylist.c
// both signatures must belong to the same user ID
assert(uid == other.uid);
// self-signatures are ordered first
const char *primaryKeyId = parent().parent().keyID();
const bool thisIsSelfSignature = strcmp(signerKeyID(), primaryKeyId) == 0;
const bool otherIsSelfSignature = strcmp(other.signerKeyID(), primaryKeyId) == 0;
if (thisIsSelfSignature && !otherIsSelfSignature) {
return true;
}
if (otherIsSelfSignature && !thisIsSelfSignature) {
return false;
}
// then sort by signer key ID (which are or course the same for self-sigs)
const int keyIdComparison = strcmp(signerKeyID(), other.signerKeyID());
if (keyIdComparison < 0) {
return true;
}
if (keyIdComparison > 0) {
return false;
}
// followed by creation time
if (creationTime() < other.creationTime()) {
return true;
}
if (creationTime() > other.creationTime()) {
return false;
}
// followed by the class in a way that a rev comes first
if (certClass() < other.certClass()) {
return true;
}
if (certClass() > other.certClass()) {
return false;
}
// to make the sort stable we compare the indexes of the signatures as last resort
return signature_index(uid, sig) < signature_index(uid, other.sig);
} }
UserID UserID::Signature::parent() const UserID UserID::Signature::parent() const
@ -986,7 +772,7 @@ UserID UserID::Signature::parent() const
const char *UserID::Signature::signerKeyID() const const char *UserID::Signature::signerKeyID() const
{ {
return sig ? sig->keyid : nullptr ; return sig ? sig->keyid : 0 ;
} }
const char *UserID::Signature::algorithmAsString() const const char *UserID::Signature::algorithmAsString() const
@ -1036,22 +822,22 @@ bool UserID::Signature::isExportable() const
const char *UserID::Signature::signerUserID() const const char *UserID::Signature::signerUserID() const
{ {
return sig ? sig->uid : nullptr ; return sig ? sig->uid : 0 ;
} }
const char *UserID::Signature::signerName() const const char *UserID::Signature::signerName() const
{ {
return sig ? sig->name : nullptr ; return sig ? sig->name : 0 ;
} }
const char *UserID::Signature::signerEmail() const const char *UserID::Signature::signerEmail() const
{ {
return sig ? sig->email : nullptr ; return sig ? sig->email : 0 ;
} }
const char *UserID::Signature::signerComment() const const char *UserID::Signature::signerComment() const
{ {
return sig ? sig->comment : nullptr ; return sig ? sig->comment : 0 ;
} }
unsigned int UserID::Signature::certClass() const unsigned int UserID::Signature::certClass() const
@ -1134,37 +920,14 @@ std::vector<Notation> UserID::Signature::notations() const
const char *UserID::Signature::policyURL() const const char *UserID::Signature::policyURL() const
{ {
if (!sig) { if (!sig) {
return nullptr; return 0;
} }
for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) { for (gpgme_sig_notation_t nota = sig->notations ; nota ; nota = nota->next) {
if (!nota->name) { if (!nota->name) {
return nota->value; return nota->value;
} }
} }
return nullptr; return 0;
}
bool UserID::Signature::isTrustSignature() const
{
return sig && sig->trust_depth > 0;
}
TrustSignatureTrust UserID::Signature::trustValue() const
{
if (!sig || !isTrustSignature()) {
return TrustSignatureTrust::None;
}
return sig->trust_value >= 120 ? TrustSignatureTrust::Complete : TrustSignatureTrust::Partial;
}
unsigned int UserID::Signature::trustDepth() const
{
return sig ? sig->trust_depth : 0;
}
const char *UserID::Signature::trustScope() const
{
return sig ? sig->trust_scope : nullptr;
} }
std::string UserID::addrSpecFromString(const char *userid) std::string UserID::addrSpecFromString(const char *userid)
@ -1267,88 +1030,6 @@ time_t Key::lastUpdate() const
return static_cast<time_t>(key ? key->last_update : 0); return static_cast<time_t>(key ? key->last_update : 0);
} }
bool Key::isBad() const
{
return isNull() || isRevoked() || isExpired() || isDisabled() || isInvalid();
}
bool Subkey::isBad() const
{
return isNull() || isRevoked() || isExpired() || isDisabled() || isInvalid();
}
bool UserID::isBad() const
{
return isNull() || isRevoked() || isInvalid();
}
bool UserID::Signature::isBad() const
{
return isNull() || isExpired() || isInvalid();
}
//
//
// class RevocationKey
//
//
static gpgme_revocation_key_t find_revkey(const shared_gpgme_key_t &key, unsigned int idx)
{
if (key) {
for (gpgme_revocation_key_t s = key->revocation_keys; s; s = s->next, --idx) {
if (idx == 0) {
return s;
}
}
}
return nullptr;
}
static gpgme_revocation_key_t verify_revkey(const shared_gpgme_key_t &key, gpgme_revocation_key_t revkey)
{
if (key) {
for (gpgme_revocation_key_t s = key->revocation_keys; s; s = s->next) {
if (s == revkey) {
return revkey;
}
}
}
return nullptr;
}
RevocationKey::RevocationKey() : key(), revkey(nullptr) {}
RevocationKey::RevocationKey(const shared_gpgme_key_t &k, unsigned int idx)
: key(k), revkey(find_revkey(k, idx))
{
}
RevocationKey::RevocationKey(const shared_gpgme_key_t &k, gpgme_revocation_key_t sk)
: key(k), revkey(verify_revkey(k, sk))
{
}
Key RevocationKey::parent() const
{
return Key(key);
}
const char *RevocationKey::fingerprint() const
{
return revkey ? revkey->fpr : nullptr;
}
bool RevocationKey::isSensitive() const
{
return revkey ? revkey->sensitive : false;
}
int RevocationKey::algorithm() const
{
return revkey ? revkey->pubkey_algo : 0;
}
std::ostream &operator<<(std::ostream &os, const UserID &uid) std::ostream &operator<<(std::ostream &os, const UserID &uid)
{ {
os << "GpgME::UserID("; os << "GpgME::UserID(";
@ -1361,41 +1042,11 @@ std::ostream &operator<<(std::ostream &os, const UserID &uid)
<< "\n revoked: " << uid.isRevoked() << "\n revoked: " << uid.isRevoked()
<< "\n invalid: " << uid.isInvalid() << "\n invalid: " << uid.isInvalid()
<< "\n numsigs: " << uid.numSignatures() << "\n numsigs: " << uid.numSignatures()
<< "\n origin: " << uid.origin()
<< "\n updated: " << uid.lastUpdate()
<< "\n tofuinfo:\n" << uid.tofuInfo(); << "\n tofuinfo:\n" << uid.tofuInfo();
} }
return os << ')'; return os << ')';
} }
std::ostream &operator<<(std::ostream &os, const Subkey &subkey)
{
os << "GpgME::Subkey(";
if (!subkey.isNull()) {
os << "\n fingerprint: " << protect(subkey.fingerprint())
<< "\n keyGrip: " << protect(subkey.keyGrip())
<< "\n creationTime: " << subkey.creationTime()
<< "\n expirationTime:" << subkey.expirationTime()
<< "\n isRevoked: " << subkey.isRevoked()
<< "\n isExpired: " << subkey.isExpired()
<< "\n isInvalid: " << subkey.isInvalid()
<< "\n isDisabled: " << subkey.isDisabled()
<< "\n canSign: " << subkey.canSign()
<< "\n canEncrypt: " << subkey.canEncrypt()
<< "\n canCertify: " << subkey.canCertify()
<< "\n canAuth: " << subkey.canAuthenticate()
<< "\n canRenc: " << subkey.canRenc()
<< "\n canTimestanp: " << subkey.canTimestamp()
<< "\n isSecret: " << subkey.isSecret()
<< "\n isGroupOwned: " << subkey.isGroupOwned()
<< "\n isQualified: " << subkey.isQualified()
<< "\n isDeVs: " << subkey.isDeVs()
<< "\n isCardKey: " << subkey.isCardKey()
<< "\n cardSerialNumber:" << protect(subkey.cardSerialNumber());
}
return os << ')';
}
std::ostream &operator<<(std::ostream &os, const Key &key) std::ostream &operator<<(std::ostream &os, const Key &key)
{ {
os << "GpgME::Key("; os << "GpgME::Key(";
@ -1405,33 +1056,14 @@ std::ostream &operator<<(std::ostream &os, const Key &key)
<< "\n issuer: " << protect(key.issuerName()) << "\n issuer: " << protect(key.issuerName())
<< "\n fingerprint:" << protect(key.primaryFingerprint()) << "\n fingerprint:" << protect(key.primaryFingerprint())
<< "\n listmode: " << key.keyListMode() << "\n listmode: " << key.keyListMode()
<< "\n canSign: " << key.canSign() << "\n canSign: " << key.canReallySign()
<< "\n canEncrypt: " << key.canEncrypt() << "\n canEncrypt: " << key.canEncrypt()
<< "\n canCertify: " << key.canCertify() << "\n canCertify: " << key.canCertify()
<< "\n canAuth: " << key.canAuthenticate() << "\n canAuth: " << key.canAuthenticate()
<< "\n origin: " << key.origin()
<< "\n updated: " << key.lastUpdate()
<< "\n uids:\n"; << "\n uids:\n";
const std::vector<UserID> uids = key.userIDs(); const std::vector<UserID> uids = key.userIDs();
std::copy(uids.begin(), uids.end(), std::copy(uids.begin(), uids.end(),
std::ostream_iterator<UserID>(os, "\n")); std::ostream_iterator<UserID>(os, "\n"));
const std::vector<Subkey> subkeys = key.subkeys();
std::copy(subkeys.begin(), subkeys.end(),
std::ostream_iterator<Subkey>(os, "\n"));
os << " revocationKeys:\n";
const std::vector<RevocationKey> revkeys = key.revocationKeys();
std::copy(revkeys.begin(), revkeys.end(),
std::ostream_iterator<RevocationKey>(os, "\n"));
}
return os << ')';
}
std::ostream &operator<<(std::ostream &os, const RevocationKey &revkey)
{
os << "GpgME::RevocationKey(";
if (!revkey.isNull()) {
os << "\n fingerprint: " << protect(revkey.fingerprint())
<< "\n isSensitive: " << revkey.isSensitive();
} }
return os << ')'; return os << ')';
} }

View File

@ -44,16 +44,9 @@ class Context;
class Subkey; class Subkey;
class UserID; class UserID;
class TofuInfo; class TofuInfo;
class RevocationKey;
typedef std::shared_ptr< std::remove_pointer<gpgme_key_t>::type > shared_gpgme_key_t; typedef std::shared_ptr< std::remove_pointer<gpgme_key_t>::type > shared_gpgme_key_t;
enum class TrustSignatureTrust : char {
None = 0,
Partial,
Complete,
};
// //
// class Key // class Key
// //
@ -72,7 +65,6 @@ public:
static const Null null; static const Null null;
Key(const Key &other) = default;
const Key &operator=(Key other) const Key &operator=(Key other)
{ {
swap(other); swap(other);
@ -101,44 +93,27 @@ public:
std::vector<UserID> userIDs() const; std::vector<UserID> userIDs() const;
std::vector<Subkey> subkeys() const; std::vector<Subkey> subkeys() const;
RevocationKey revocationKey(unsigned int index) const;
unsigned int numRevocationKeys() const;
std::vector<RevocationKey> revocationKeys() const;
bool isRevoked() const; bool isRevoked() const;
bool isExpired() const; bool isExpired() const;
bool isDisabled() const; bool isDisabled() const;
bool isInvalid() const; bool isInvalid() const;
/*! Shorthand for isNull || isRevoked || isExpired ||
* isDisabled || isInvalid */
bool isBad() const;
/** Returns true, if the key can be used for encryption (i.e. it's not bad
* and has an encryption subkey) or if the primary subkey can encrypt. */
bool canEncrypt() const; bool canEncrypt() const;
/** Returns true, if the key can be used for signing (i.e. it's not bad /*!
* and has a signing subkey) or if the primary subkey can sign. */ This function contains a workaround for old gpgme's: all secret
OpenPGP keys canSign() == true, which canReallySign() doesn't
have. I don't have time to find what breaks when I remove this
workaround, but since Kleopatra merges secret into public keys,
the workaround is not necessary there (and actively harms), I've
added a new function instead.
*/
bool canSign() const; bool canSign() const;
GPGMEPP_DEPRECATED bool canReallySign() const; bool canReallySign() const;
/** Returns true, if the key can be used for certification (i.e. it's not bad
* and has a certification subkey) or if the primary subkey can certify. */
bool canCertify() const; bool canCertify() const;
/** Returns true, if the key can be used for authentication (i.e. it's not bad
* and has a authentication subkey) or if the primary subkey can authenticate. */
bool canAuthenticate() const; bool canAuthenticate() const;
bool isQualified() const; bool isQualified() const;
bool isDeVs() const; bool isDeVs() const;
/** Returns true, if the key has a certification subkey. */
bool hasCertify() const;
/** Returns true, if the key has a signing subkey. */
bool hasSign() const;
/** Returns true, if the key has an encryption subkey. */
bool hasEncrypt() const;
/** Returns true, if the key has an authentication subkey. */
bool hasAuthenticate() const;
bool hasSecret() const; bool hasSecret() const;
GPGMEPP_DEPRECATED bool isSecret() const GPGMEPP_DEPRECATED bool isSecret() const
{ {
@ -184,7 +159,7 @@ public:
* Needs gnupg 2.1.13 and the key needs to be updated * Needs gnupg 2.1.13 and the key needs to be updated
* afterwards to see the new uid. * afterwards to see the new uid.
* *
* @param uid should be fully formatted and UTF-8 encoded. * @param uid should be fully formated and UTF-8 encoded.
* *
* @returns a possible error. * @returns a possible error.
**/ **/
@ -243,7 +218,6 @@ public:
Subkey(const shared_gpgme_key_t &key, gpgme_sub_key_t subkey); Subkey(const shared_gpgme_key_t &key, gpgme_sub_key_t subkey);
Subkey(const shared_gpgme_key_t &key, unsigned int idx); Subkey(const shared_gpgme_key_t &key, unsigned int idx);
Subkey(const Subkey &other) = default;
const Subkey &operator=(Subkey other) const Subkey &operator=(Subkey other)
{ {
swap(other); swap(other);
@ -276,17 +250,10 @@ public:
bool isInvalid() const; bool isInvalid() const;
bool isDisabled() const; bool isDisabled() const;
/*! Shorthand for isNull || isRevoked || isExpired ||
* isDisabled || isInvalid */
bool isBad() const;
bool canEncrypt() const; bool canEncrypt() const;
bool canSign() const; bool canSign() const;
bool canCertify() const; bool canCertify() const;
bool canAuthenticate() const; bool canAuthenticate() const;
bool canRenc() const;
bool canTimestamp() const;
bool isGroupOwned() const;
bool isQualified() const; bool isQualified() const;
bool isDeVs() const; bool isDeVs() const;
bool isCardKey() const; bool isCardKey() const;
@ -360,7 +327,6 @@ public:
UserID(const shared_gpgme_key_t &key, gpgme_user_id_t uid); UserID(const shared_gpgme_key_t &key, gpgme_user_id_t uid);
UserID(const shared_gpgme_key_t &key, unsigned int idx); UserID(const shared_gpgme_key_t &key, unsigned int idx);
UserID(const UserID &other) = default;
const UserID &operator=(UserID other) const UserID &operator=(UserID other)
{ {
swap(other); swap(other);
@ -389,7 +355,6 @@ public:
const char *name() const; const char *name() const;
const char *email() const; const char *email() const;
const char *comment() const; const char *comment() const;
const char *uidhash() const;
enum Validity { Unknown = 0, Undefined = 1, Never = 2, enum Validity { Unknown = 0, Undefined = 1, Never = 2,
Marginal = 3, Full = 4, Ultimate = 5 Marginal = 3, Full = 4, Ultimate = 5
@ -401,9 +366,6 @@ public:
bool isRevoked() const; bool isRevoked() const;
bool isInvalid() const; bool isInvalid() const;
/*! Shorthand for isNull || isRevoked || isInvalid */
bool isBad() const;
/** TOFU info for this userid. /** TOFU info for this userid.
* @returns The TOFU stats or a null TofuInfo. * @returns The TOFU stats or a null TofuInfo.
*/ */
@ -440,27 +402,6 @@ public:
* *
* @returns the last update time. */ * @returns the last update time. */
time_t lastUpdate() const; time_t lastUpdate() const;
/*! Get a remark made by the key provided.
* A remark is a signature notation on
* this user id made by the key with the
* name "rem@gnupg.org". Returns an error if the
* parent key of this user id was not listed with the
* keylist mode flags for signatures and signature notations.
*
* @param key The key for which comments should be searched.
* @param error Set to GPG_ERR_NO_DATA if the keylist did
* not include signature notations.
*
* @returns The value of the comment or NULL if none exists.
**/
const char *remark(const Key &key,
Error &error) const;
/*! Get multiple remarks made by potentially multiple keys. */
std::vector <std::string> remarks(std::vector<GpgME::Key> remarkers,
Error &error) const;
private: private:
shared_gpgme_key_t key; shared_gpgme_key_t key;
gpgme_user_id_t uid; gpgme_user_id_t uid;
@ -479,7 +420,6 @@ public:
Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, gpgme_key_sig_t sig); Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, gpgme_key_sig_t sig);
Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, unsigned int idx); Signature(const shared_gpgme_key_t &key, gpgme_user_id_t uid, unsigned int idx);
Signature(const Signature &other) = default;
const Signature &operator=(Signature other) const Signature &operator=(Signature other)
{ {
swap(other); swap(other);
@ -494,11 +434,6 @@ public:
swap(this->sig, other.sig); swap(this->sig, other.sig);
} }
/*! Defines a canonical sort order for signatures of the same user ID. */
bool operator<(const Signature &other) const;
GPGMEPP_DEPRECATED bool operator<(const Signature &other);
bool isNull() const bool isNull() const
{ {
return !sig || !uid || !key ; return !sig || !uid || !key ;
@ -519,9 +454,6 @@ public:
bool isExpired() const; bool isExpired() const;
bool isExportable() const; bool isExportable() const;
/*! Shorthand for isNull || isExpired || isInvalid */
bool isBad() const;
const char *signerUserID() const; const char *signerUserID() const;
const char *signerName() const; const char *signerName() const;
const char *signerEmail() const; const char *signerEmail() const;
@ -541,64 +473,14 @@ public:
GpgME::Notation notation(unsigned int idx) const; GpgME::Notation notation(unsigned int idx) const;
std::vector<GpgME::Notation> notations() const; std::vector<GpgME::Notation> notations() const;
bool isTrustSignature() const;
TrustSignatureTrust trustValue() const;
unsigned int trustDepth() const;
const char *trustScope() const;
private: private:
shared_gpgme_key_t key; shared_gpgme_key_t key;
gpgme_user_id_t uid; gpgme_user_id_t uid;
gpgme_key_sig_t sig; gpgme_key_sig_t sig;
}; };
//
// class RevocationKey
//
class GPGMEPP_EXPORT RevocationKey
{
public:
RevocationKey();
RevocationKey(const shared_gpgme_key_t &key, gpgme_revocation_key_t revkey);
RevocationKey(const shared_gpgme_key_t &key, unsigned int idx);
// Rule of Zero
void swap(RevocationKey &other)
{
using std::swap;
swap(this->key, other.key);
swap(this->revkey, other.revkey);
}
bool isNull() const
{
return !key || !revkey;
}
Key parent() const;
const char *fingerprint() const;
bool isSensitive() const;
int algorithm() const;
private:
shared_gpgme_key_t key;
gpgme_revocation_key_t revkey;
};
inline void swap(RevocationKey& v1, RevocationKey& v2)
{
v1.swap(v2);
}
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const UserID &uid); GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const UserID &uid);
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const Subkey &subkey);
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const Key &key); GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const Key &key);
GPGMEPP_EXPORT std::ostream &operator<<(std::ostream &os, const RevocationKey &revkey);
} // namespace GpgME } // namespace GpgME

View File

@ -50,7 +50,7 @@ public:
if (res.fpr) { if (res.fpr) {
std::free(res.fpr); std::free(res.fpr);
} }
res.fpr = nullptr; res.fpr = 0;
} }
_gpgme_op_genkey_result res; _gpgme_op_genkey_result res;
@ -94,5 +94,5 @@ bool GpgME::KeyGenerationResult::isSubkeyGenerated() const
const char *GpgME::KeyGenerationResult::fingerprint() const const char *GpgME::KeyGenerationResult::fingerprint() const
{ {
return d ? d->res.fpr : nullptr ; return d ? d->res.fpr : 0 ;
} }

View File

@ -44,7 +44,6 @@ public:
KeyGenerationResult(gpgme_ctx_t ctx, const Error &error); KeyGenerationResult(gpgme_ctx_t ctx, const Error &error);
explicit KeyGenerationResult(const Error &err); explicit KeyGenerationResult(const Error &err);
KeyGenerationResult(const KeyGenerationResult &other) = default;
const KeyGenerationResult &operator=(KeyGenerationResult other) const KeyGenerationResult &operator=(KeyGenerationResult other)
{ {
swap(other); swap(other);

View File

@ -45,7 +45,6 @@ public:
explicit KeyListResult(const Error &err); explicit KeyListResult(const Error &err);
KeyListResult(const Error &err, const _gpgme_op_keylist_result &res); KeyListResult(const Error &err, const _gpgme_op_keylist_result &res);
KeyListResult(const KeyListResult &other) = default;
const KeyListResult &operator=(KeyListResult other) const KeyListResult &operator=(KeyListResult other)
{ {
swap(other); swap(other);

View File

@ -44,7 +44,6 @@ public:
Notation(); Notation();
explicit Notation(gpgme_sig_notation_t nota); explicit Notation(gpgme_sig_notation_t nota);
Notation(const Notation &other) = default;
const Notation &operator=(Notation other) const Notation &operator=(Notation other)
{ {
swap(other); swap(other);

View File

@ -50,14 +50,6 @@ public:
{ {
return mError; return mError;
} }
/**
* Replaces the error set during construction with \p error.
* Use with care, e.g. to set a more suitable error.
*/
void setError(const Error &error)
{
mError = error;
}
protected: protected:
Error mError; Error mError;

View File

@ -31,6 +31,7 @@
#include "data.h" #include "data.h"
#include "util.h" #include "util.h"
#include <sstream>
#include <assert.h> #include <assert.h>
using namespace GpgME; using namespace GpgME;

Some files were not shown because too many files have changed in this diff Show More