diff --git a/lang/python/tests/t-callbacks.py b/lang/python/tests/t-callbacks.py index 9a70cdae..b311e3d4 100755 --- a/lang/python/tests/t-callbacks.py +++ b/lang/python/tests/t-callbacks.py @@ -1,256 +1,256 @@ #!/usr/bin/env python # Copyright (C) 2016 g10 Code GmbH # # This file is part of GPGME. # # GPGME is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # GPGME is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General # Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this program; if not, see . from __future__ import absolute_import, print_function, unicode_literals del absolute_import, print_function, unicode_literals import os import gpg import support _ = support # to appease pyflakes. c = gpg.Context() c.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK) source = gpg.Data("Hallo Leute\n") sink = gpg.Data() # Valid passphrases, both as string and bytes. for passphrase in ('foo', b'foo'): def passphrase_cb(hint, desc, prev_bad, hook=None): assert hook == passphrase return hook c.set_passphrase_cb(passphrase_cb, passphrase) c.op_encrypt([], 0, source, sink) # Returning an invalid type. def passphrase_cb(hint, desc, prev_bad, hook=None): return 0 c.set_passphrase_cb(passphrase_cb, None) try: c.op_encrypt([], 0, source, sink) except Exception as e: assert type(e) == TypeError assert str(e) == "expected str or bytes from passphrase callback, got int" else: assert False, "Expected an error, got none" # Raising an exception inside callback. myException = Exception() def passphrase_cb(hint, desc, prev_bad, hook=None): raise myException c.set_passphrase_cb(passphrase_cb, None) try: c.op_encrypt([], 0, source, sink) except Exception as e: assert e == myException else: assert False, "Expected an error, got none" # Wrong kind of callback function. def bad_passphrase_cb(): pass c.set_passphrase_cb(bad_passphrase_cb, None) try: c.op_encrypt([], 0, source, sink) except Exception as e: assert type(e) == TypeError else: assert False, "Expected an error, got none" # Test the progress callback. parms = """ Key-Type: RSA Key-Length: 1024 Name-Real: Joe Tester Name-Comment: with stupid passphrase Name-Email: joe+gpg@example.org Passphrase: Crypt0R0cks -Expire-Date: 2020-12-31 +Expire-Date: 2099-12-31 """ messages = [] def progress_cb(what, typ, current, total, hook=None): assert hook == messages messages.append( "PROGRESS UPDATE: what = {}, type = {}, current = {}, total = {}" .format(what, typ, current, total)) c = gpg.Context() c.set_progress_cb(progress_cb, messages) c.op_genkey(parms, None, None) assert len(messages) > 0 # Test exception handling. def progress_cb(what, typ, current, total, hook=None): raise myException c = gpg.Context() c.set_progress_cb(progress_cb, None) try: c.op_genkey(parms, None, None) except Exception as e: assert e == myException else: assert False, "Expected an error, got none" # Test the edit callback. c = gpg.Context() c.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK) c.set_passphrase_cb(lambda *args: "abc") sink = gpg.Data() alpha = c.get_key("A0FF4590BB6122EDEF6E3C542D727CC768697734", False) cookie = object() edit_cb_called = False def edit_cb(status, args, hook): global edit_cb_called edit_cb_called = True assert hook == cookie return "quit" if args == "keyedit.prompt" else None c.op_edit(alpha, edit_cb, cookie, sink) assert edit_cb_called # Test exceptions. c = gpg.Context() c.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK) c.set_passphrase_cb(lambda *args: "abc") sink = gpg.Data() def edit_cb(status, args): raise myException try: c.op_edit(alpha, edit_cb, None, sink) except Exception as e: assert e == myException else: assert False, "Expected an error, got none" # Test the status callback. source = gpg.Data("Hallo Leute\n") sink = gpg.Data() status_cb_called = False def status_cb(keyword, args, hook=None): global status_cb_called status_cb_called = True assert hook == cookie c = gpg.Context() c.set_status_cb(status_cb, cookie) c.set_ctx_flag("full-status", "1") c.op_encrypt([alpha], gpg.constants.ENCRYPT_ALWAYS_TRUST, source, sink) assert status_cb_called # Test exceptions. source = gpg.Data("Hallo Leute\n") sink = gpg.Data() def status_cb(keyword, args): raise myException c = gpg.Context() c.set_status_cb(status_cb, None) c.set_ctx_flag("full-status", "1") try: c.op_encrypt([alpha], gpg.constants.ENCRYPT_ALWAYS_TRUST, source, sink) except Exception as e: assert e == myException else: assert False, "Expected an error, got none" # Test the data callbacks. def read_cb(amount, hook=None): assert hook == cookie return 0 def release_cb(hook=None): assert hook == cookie data = gpg.Data(cbs=(read_cb, None, None, release_cb, cookie)) try: data.read() except Exception as e: assert type(e) == TypeError else: assert False, "Expected an error, got none" def read_cb(amount): raise myException data = gpg.Data(cbs=(read_cb, None, None, lambda: None)) try: data.read() except Exception as e: assert e == myException else: assert False, "Expected an error, got none" def write_cb(what, hook=None): assert hook == cookie return "wrong type" data = gpg.Data(cbs=(None, write_cb, None, release_cb, cookie)) try: data.write(b'stuff') except Exception as e: assert type(e) == TypeError else: assert False, "Expected an error, got none" def write_cb(what): raise myException data = gpg.Data(cbs=(None, write_cb, None, lambda: None)) try: data.write(b'stuff') except Exception as e: assert e == myException else: assert False, "Expected an error, got none" def seek_cb(offset, whence, hook=None): assert hook == cookie return "wrong type" data = gpg.Data(cbs=(None, None, seek_cb, release_cb, cookie)) try: data.seek(0, os.SEEK_SET) except Exception as e: assert type(e) == TypeError else: assert False, "Expected an error, got none" def seek_cb(offset, whence): raise myException data = gpg.Data(cbs=(None, None, seek_cb, lambda: None)) try: data.seek(0, os.SEEK_SET) except Exception as e: assert e == myException else: assert False, "Expected an error, got none" diff --git a/lang/qt/Makefile.am b/lang/qt/Makefile.am index ab859609..a1b83e8d 100644 --- a/lang/qt/Makefile.am +++ b/lang/qt/Makefile.am @@ -1,24 +1,30 @@ # 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 -SUBDIRS = src tests doc +if RUN_GPG_TESTS +tests = tests +else +tests = +endif + +SUBDIRS = src ${tests} doc EXTRA_DIST = README diff --git a/lang/qt/src/qgpgmenewcryptoconfig.cpp b/lang/qt/src/qgpgmenewcryptoconfig.cpp index ba028a97..070ab697 100644 --- a/lang/qt/src/qgpgmenewcryptoconfig.cpp +++ b/lang/qt/src/qgpgmenewcryptoconfig.cpp @@ -1,752 +1,752 @@ /* qgpgmenewcryptoconfig.cpp This file is part of qgpgme, the Qt API binding for gpgme Copyright (c) 2010 Klarälvdalens Datakonsult AB Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik Software engineering by Intevation GmbH QGpgME is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. QGpgME is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the Qt library by Trolltech AS, Norway (or with modified versions of Qt that use the same license as Qt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than Qt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "qgpgmenewcryptoconfig.h" #include #include "gpgme_backend_debug.h" #include +#include #include "global.h" #include "error.h" #include #include #include #include #include using namespace QGpgME; using namespace GpgME; using namespace GpgME::Configuration; namespace { struct Select1St { template const U &operator()(const std::pair &p) const { return p.first; } template const U &operator()(const QPair &p) const { return p.first; } }; } // Just for the Q_ASSERT in the dtor. Not thread-safe, but who would // have 2 threads talking to gpgconf anyway? :) static bool s_duringClear = false; QGpgMENewCryptoConfig::QGpgMENewCryptoConfig() : m_parsed(false) { } QGpgMENewCryptoConfig::~QGpgMENewCryptoConfig() { clear(); } void QGpgMENewCryptoConfig::reloadConfiguration(bool) { clear(); Error error; const std::vector components = Component::load(error); #ifndef NDEBUG { std::stringstream ss; ss << "error: " << error << "components:\n"; std::copy(components.begin(), components.end(), std::ostream_iterator(ss, "\n")); qCDebug(GPGPME_BACKEND_LOG) << ss.str().c_str(); } #endif #if 0 TODO port? if (error && showErrors) { const QString wmsg = i18n("Failed to execute gpgconf:

%1

", QString::fromLocal8Bit(error.asString())); qCWarning(GPGPME_BACKEND_LOG) << wmsg; // to see it from test_cryptoconfig.cpp KMessageBox::error(0, wmsg); } #endif Q_FOREACH(const Component & c, components) { const std::shared_ptr comp(new QGpgMENewCryptoConfigComponent); comp->setComponent(c); m_componentsByName[ comp->name() ] = comp; } m_parsed = true; } QStringList QGpgMENewCryptoConfig::componentList() const { if (!m_parsed) { const_cast(this)->reloadConfiguration(true); } QStringList result; std::transform(m_componentsByName.begin(), m_componentsByName.end(), std::back_inserter(result), mem_fn(&QGpgMENewCryptoConfigComponent::name)); return result; } QGpgMENewCryptoConfigComponent *QGpgMENewCryptoConfig::component(const QString &name) const { if (!m_parsed) { const_cast(this)->reloadConfiguration(false); } return m_componentsByName.value(name).get(); } void QGpgMENewCryptoConfig::sync(bool runtime) { Q_FOREACH(const std::shared_ptr &c, m_componentsByName) c->sync(runtime); } void QGpgMENewCryptoConfig::clear() { s_duringClear = true; m_componentsByName.clear(); s_duringClear = false; m_parsed = false; // next call to componentList/component will need to run gpgconf again } //// QGpgMENewCryptoConfigComponent::QGpgMENewCryptoConfigComponent() : CryptoConfigComponent(), m_component() { } void QGpgMENewCryptoConfigComponent::setComponent(const Component &component) { m_component = component; m_groupsByName.clear(); std::shared_ptr group; const std::vector