diff --git a/lang/cpp/src/Makefile.am b/lang/cpp/src/Makefile.am index 7af66325..ba8a7fb1 100644 --- a/lang/cpp/src/Makefile.am +++ b/lang/cpp/src/Makefile.am @@ -1,115 +1,116 @@ # Makefile.am for GPGMEPP. # Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik # Software engineering by Intevation GmbH # # This file is part of GPGMEPP. # # 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 this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA EXTRA_DIST = GpgmeppConfig.cmake.in.in GpgmeppConfigVersion.cmake.in \ gpgmepp_version.h.in GpgmeppConfig-w32.cmake.in.in lib_LTLIBRARIES = libgpgmepp.la main_sources = \ exception.cpp context.cpp key.cpp trustitem.cpp data.cpp callbacks.cpp \ eventloopinteractor.cpp editinteractor.cpp \ keylistresult.cpp keygenerationresult.cpp importresult.cpp \ decryptionresult.cpp verificationresult.cpp \ signingresult.cpp encryptionresult.cpp \ engineinfo.cpp gpgsetexpirytimeeditinteractor.cpp \ gpgsetownertrusteditinteractor.cpp gpgsignkeyeditinteractor.cpp \ gpgadduserideditinteractor.cpp gpggencardkeyinteractor.cpp \ gpgaddexistingsubkeyeditinteractor.cpp \ defaultassuantransaction.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 = \ configuration.h context.h data.h decryptionresult.h \ defaultassuantransaction.h editinteractor.h encryptionresult.h \ engineinfo.h error.h eventloopinteractor.h exception.h global.h \ gpgadduserideditinteractor.h gpgagentgetinfoassuantransaction.h \ gpgmefw.h gpgsetexpirytimeeditinteractor.h \ gpgsetownertrusteditinteractor.h gpgsignkeyeditinteractor.h \ gpggencardkeyinteractor.h \ gpgaddexistingsubkeyeditinteractor.h \ importresult.h keygenerationresult.h key.h keylistresult.h \ notation.h result.h scdgetinfoassuantransaction.h signingresult.h \ statusconsumerassuantransaction.h \ trustitem.h verificationresult.h vfsmountresult.h gpgmepp_export.h \ tofuinfo.h swdbresult.h private_gpgmepp_headers = \ result_p.h context_p.h util.h callbacks.h data_p.h interface_headers= \ interfaces/assuantransaction.h interfaces/dataprovider.h \ interfaces/passphraseprovider.h interfaces/progressprovider.h \ interfaces/statusconsumer.h gpgmeppincludedir = $(includedir)/gpgme++ gpgmeppinclude_HEADERS = $(gpgmepp_headers) nobase_gpgmeppinclude_HEADERS = $(interface_headers) nodist_gpgmeppinclude_HEADERS = gpgmepp_version.h libgpgmepp_la_SOURCES = $(main_sources) $(gpgmepp_headers) context_vanilla.cpp \ $(interface_headers) $(private_gpgmepp_headers) AM_CPPFLAGS = -I$(top_builddir)/src @GPG_ERROR_CFLAGS@ @LIBASSUAN_CFLAGS@ \ -DBUILDING_GPGMEPP -Wsuggest-override \ -Wzero-as-null-pointer-constant libgpgmepp_la_LIBADD = ../../../src/libgpgme.la @LIBASSUAN_LIBS@ libgpgmepp_la_LDFLAGS = -no-undefined -version-info \ @LIBGPGMEPP_LT_CURRENT@:@LIBGPGMEPP_LT_REVISION@:@LIBGPGMEPP_LT_AGE@ if HAVE_MACOS_SYSTEM libsuffix=.dylib else libsuffix=.so endif if HAVE_W32_SYSTEM GpgmeppConfig.cmake: GpgmeppConfig-w32.cmake.in sed -e 's|[@]resolved_bindir@|$(bindir)|g' < "$<" | \ sed -e 's|[@]resolved_libdir@|$(libdir)|g' | \ sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@ else GpgmeppConfig.cmake: GpgmeppConfig.cmake.in sed -e 's|[@]resolved_libdir@|$(libdir)|g' < "$<" | \ sed -e 's|[@]libsuffix@|$(libsuffix)|g' | \ sed -e 's|[@]resolved_includedir@|$(includedir)|g' > $@ endif install-cmake-files: GpgmeppConfig.cmake GpgmeppConfigVersion.cmake -$(INSTALL) -d $(DESTDIR)$(libdir)/cmake/Gpgmepp $(INSTALL) -m 644 GpgmeppConfig.cmake \ $(DESTDIR)$(libdir)/cmake/Gpgmepp/GpgmeppConfig.cmake $(INSTALL) -m 644 GpgmeppConfigVersion.cmake \ $(DESTDIR)$(libdir)/cmake/Gpgmepp/GpgmeppConfigVersion.cmake uninstall-cmake-files: -rm $(DESTDIR)$(libdir)/cmake/Gpgmepp/GpgmeppConfigVersion.cmake -rm $(DESTDIR)$(libdir)/cmake/Gpgmepp/GpgmeppConfig.cmake -rmdir $(DESTDIR)$(libdir)/cmake/Gpgmepp/ install-data-local: install-cmake-files uninstall-local: uninstall-cmake-files CLEANFILES = GpgmeppConfig.cmake GpgmeppConfigVersion.cmake \ gpgmepp_version.h GpgmeppConfig.cmake.in diff --git a/lang/cpp/src/util.cpp b/lang/cpp/src/util.cpp new file mode 100644 index 00000000..9104435f --- /dev/null +++ b/lang/cpp/src/util.cpp @@ -0,0 +1,47 @@ +/* + util.cpp - some internal helpers + Copyright (c) 2022 g10 Code GmbH + Software engineering by Ingo Klöcker + + 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 "util.h" + +#include + +StringsToCStrings::StringsToCStrings(const std::vector& v) + : m_strings{v} +{ +} + +const char **StringsToCStrings::c_strs() const +{ + if (m_cstrings.empty()) { + 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(); +} diff --git a/lang/cpp/src/util.h b/lang/cpp/src/util.h index e04115bf..b6f9ca50 100644 --- a/lang/cpp/src/util.h +++ b/lang/cpp/src/util.h @@ -1,178 +1,201 @@ /* - util.h - some inline helper functions + util.h - some internal helpers Copyright (C) 2004 Klarälvdalens Datakonsult AB 2016 Bundesamt für Sicherheit in der Informationstechnik Software engineering by Intevation GmbH + Copyright (c) 2022 g10 Code GmbH + Software engineering by Ingo Klöcker 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. */ // -*- c++ -*- #ifndef __GPGMEPP_UTIL_H__ #define __GPGMEPP_UTIL_H__ #include "global.h" #include "notation.h" #include #ifndef NDEBUG #include #endif #include #include static inline const char *protect(const char *s) { return s ? s : "" ; } static inline gpgme_error_t make_error(gpgme_err_code_t code) { return gpgme_err_make((gpgme_err_source_t)22, code); } static inline unsigned long to_pid(const std::string &s) { std::stringstream ss(s); unsigned int result; if (ss >> result) { return result; } else { return 0U; } } static inline gpgme_keylist_mode_t add_to_gpgme_keylist_mode_t(unsigned int oldmode, unsigned int newmodes) { if (newmodes & GpgME::Local) { oldmode |= GPGME_KEYLIST_MODE_LOCAL; } if (newmodes & GpgME::Extern) { oldmode |= GPGME_KEYLIST_MODE_EXTERN; } if (newmodes & GpgME::Signatures) { oldmode |= GPGME_KEYLIST_MODE_SIGS; } if (newmodes & GpgME::SignatureNotations) { oldmode |= GPGME_KEYLIST_MODE_SIG_NOTATIONS; } if (newmodes & GpgME::Validate) { oldmode |= GPGME_KEYLIST_MODE_VALIDATE; } if (newmodes & GpgME::Ephemeral) { oldmode |= GPGME_KEYLIST_MODE_EPHEMERAL; } if (newmodes & GpgME::WithTofu) { oldmode |= GPGME_KEYLIST_MODE_WITH_TOFU; } if (newmodes & GpgME::WithKeygrip) { oldmode |= GPGME_KEYLIST_MODE_WITH_KEYGRIP; } if (newmodes & GpgME::WithSecret) { oldmode |= GPGME_KEYLIST_MODE_WITH_SECRET; } #ifndef NDEBUG if (newmodes & ~(GpgME::Local | GpgME::Extern | GpgME::Signatures | GpgME::SignatureNotations | GpgME::Validate | GpgME::Ephemeral | GpgME::WithTofu | GpgME::WithKeygrip | GpgME::WithSecret)) { //std::cerr << "GpgME::Context: keylist mode must be one of Local, " //"Extern, Signatures, SignatureNotations, Validate, Ephemeral, WithTofu, " //"WithKeygrip, WithSecret, or a combination thereof!" << std::endl; } #endif return static_cast(oldmode); } static inline unsigned int convert_from_gpgme_keylist_mode_t(unsigned int mode) { unsigned int result = 0; if (mode & GPGME_KEYLIST_MODE_LOCAL) { result |= GpgME::Local; } if (mode & GPGME_KEYLIST_MODE_EXTERN) { result |= GpgME::Extern; } if (mode & GPGME_KEYLIST_MODE_SIGS) { result |= GpgME::Signatures; } if (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS) { result |= GpgME::SignatureNotations; } if (mode & GPGME_KEYLIST_MODE_WITH_SECRET) { result |= GpgME::WithSecret; } if (mode & GPGME_KEYLIST_MODE_WITH_TOFU) { result |= GpgME::WithTofu; } if (mode & GPGME_KEYLIST_MODE_WITH_KEYGRIP) { result |= GpgME::WithKeygrip; } if (mode & GPGME_KEYLIST_MODE_EPHEMERAL) { result |= GpgME::Ephemeral; } if (mode & GPGME_KEYLIST_MODE_VALIDATE) { result |= GpgME::Validate; } #ifndef NDEBUG if (mode & ~(GPGME_KEYLIST_MODE_LOCAL | GPGME_KEYLIST_MODE_EXTERN | GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS | GPGME_KEYLIST_MODE_WITH_SECRET | GPGME_KEYLIST_MODE_WITH_TOFU | GPGME_KEYLIST_MODE_WITH_KEYGRIP | GPGME_KEYLIST_MODE_EPHEMERAL | GPGME_KEYLIST_MODE_VALIDATE)) { //std::cerr << "GpgME: WARNING: gpgme_get_keylist_mode() returned an unknown flag!" << std::endl; } #endif // NDEBUG return result; } static inline GpgME::Notation::Flags convert_from_gpgme_sig_notation_flags_t(unsigned int flags) { unsigned int result = 0; if (flags & GPGME_SIG_NOTATION_HUMAN_READABLE) { result |= GpgME::Notation::HumanReadable ; } if (flags & GPGME_SIG_NOTATION_CRITICAL) { result |= GpgME::Notation::Critical ; } return static_cast(result); } static inline gpgme_sig_notation_flags_t add_to_gpgme_sig_notation_flags_t(unsigned int oldflags, unsigned int newflags) { unsigned int result = oldflags; if (newflags & GpgME::Notation::HumanReadable) { result |= GPGME_SIG_NOTATION_HUMAN_READABLE; } if (newflags & GpgME::Notation::Critical) { result |= GPGME_SIG_NOTATION_CRITICAL; } return static_cast(result); } +/** + * Adapter for passing a vector of strings as NULL-terminated array of + * const char* to the C-interface of gpgme. + */ +class StringsToCStrings +{ +public: + explicit StringsToCStrings(const std::vector &v); + ~StringsToCStrings() = default; + + StringsToCStrings(const StringsToCStrings &) = delete; + StringsToCStrings &operator=(const StringsToCStrings &) = delete; + StringsToCStrings(StringsToCStrings &&) = delete; + StringsToCStrings &operator=(StringsToCStrings &&) = delete; + + const char **c_strs() const; +private: + const std::vector m_strings; + mutable std::vector m_cstrings; +}; + #endif // __GPGMEPP_UTIL_H__