diff options
Diffstat (limited to 'lang/qt/tests')
-rw-r--r-- | lang/qt/tests/Makefile.am | 36 | ||||
-rw-r--r-- | lang/qt/tests/Makefile.in | 184 | ||||
-rwxr-xr-x | lang/qt/tests/final.test | 6 | ||||
-rw-r--r-- | lang/qt/tests/run-exportjob.cpp | 119 | ||||
-rw-r--r-- | lang/qt/tests/run-importjob.cpp | 99 | ||||
-rw-r--r-- | lang/qt/tests/run-receivekeysjob.cpp | 65 | ||||
-rw-r--r-- | lang/qt/tests/t-addexistingsubkey.cpp | 260 | ||||
-rw-r--r-- | lang/qt/tests/t-changeexpiryjob.cpp | 396 | ||||
-rw-r--r-- | lang/qt/tests/t-config.cpp | 19 | ||||
-rw-r--r-- | lang/qt/tests/t-encrypt.cpp | 34 | ||||
-rw-r--r-- | lang/qt/tests/t-import.cpp | 169 | ||||
-rw-r--r-- | lang/qt/tests/t-keylist.cpp | 7 | ||||
-rw-r--r-- | lang/qt/tests/t-keylocate.cpp | 3 | ||||
-rw-r--r-- | lang/qt/tests/t-ownertrust.cpp | 3 | ||||
-rw-r--r-- | lang/qt/tests/t-remarks.cpp | 68 | ||||
-rw-r--r-- | lang/qt/tests/t-support.cpp | 52 | ||||
-rw-r--r-- | lang/qt/tests/t-support.h | 60 | ||||
-rw-r--r-- | lang/qt/tests/t-tofuinfo.cpp | 7 | ||||
-rw-r--r-- | lang/qt/tests/t-trustsignatures.cpp | 61 | ||||
-rw-r--r-- | lang/qt/tests/t-various.cpp | 29 | ||||
-rw-r--r-- | lang/qt/tests/t-wkdlookup.cpp | 155 | ||||
-rw-r--r-- | lang/qt/tests/t-wkspublish.cpp | 3 |
22 files changed, 1603 insertions, 232 deletions
diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index 41ea808..6c082b0 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -24,14 +24,22 @@ GPG = gpg GNUPGHOME=$(abs_builddir) TESTS_ENVIRONMENT = GNUPGHOME=$(GNUPGHOME) -EXTRA_DIST = initial.test +EXTRA_DIST = initial.test final.test -TESTS = initial.test t-keylist t-keylocate t-ownertrust t-tofuinfo \ - t-encrypt t-verify t-various t-config t-remarks t-trustsignatures +the_tests = \ + t-addexistingsubkey \ + t-keylist t-keylocate t-ownertrust t-tofuinfo \ + t-encrypt t-verify t-various t-config t-remarks t-trustsignatures \ + t-changeexpiryjob t-wkdlookup t-import -moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \ - t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc \ - t-various.moc t-config.moc t-remarks.moc t-trustsignatures.moc +TESTS = initial.test $(the_tests) final.test + +moc_files = \ + t-addexistingsubkey.moc \ + t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \ + t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc \ + t-various.moc t-config.moc t-remarks.moc t-trustsignatures.moc \ + t-changeexpiryjob.moc t-wkdlookup.moc t-import.moc AM_LDFLAGS = -no-install @@ -47,6 +55,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/lang/cpp/src -I$(top_builddir)/src \ support_src = t-support.h t-support.cpp +t_addexistingsubkey_SOURCES = t-addexistingsubkey.cpp $(support_src) t_keylist_SOURCES = t-keylist.cpp $(support_src) t_keylocate_SOURCES = t-keylocate.cpp $(support_src) t_ownertrust_SOURCES = t-ownertrust.cpp $(support_src) @@ -58,15 +67,24 @@ t_various_SOURCES = t-various.cpp $(support_src) t_config_SOURCES = t-config.cpp $(support_src) t_remarks_SOURCES = t-remarks.cpp $(support_src) t_trustsignatures_SOURCES = t-trustsignatures.cpp $(support_src) +t_changeexpiryjob_SOURCES = t-changeexpiryjob.cpp $(support_src) +t_wkdlookup_SOURCES = t-wkdlookup.cpp $(support_src) +t_import_SOURCES = t-import.cpp $(support_src) +run_exportjob_SOURCES = run-exportjob.cpp +run_importjob_SOURCES = run-importjob.cpp run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp +run_receivekeysjob_SOURCES = run-receivekeysjob.cpp nodist_t_keylist_SOURCES = $(moc_files) BUILT_SOURCES = $(moc_files) pubring-stamp -noinst_PROGRAMS = t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt \ - run-keyformailboxjob t-wkspublish t-verify t-various t-config t-remarks \ - t-trustsignatures +noinst_PROGRAMS = \ + t-addexistingsubkey \ + t-keylist t-keylocate t-ownertrust t-tofuinfo t-encrypt \ + run-keyformailboxjob t-wkspublish t-verify t-various t-config t-remarks \ + t-trustsignatures t-changeexpiryjob t-wkdlookup t-import run-importjob \ + run-exportjob run-receivekeysjob CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \ gpg-agent.conf pubring.kbx~ S.gpg-agent gpg.conf pubring.gpg~ \ diff --git a/lang/qt/tests/Makefile.in b/lang/qt/tests/Makefile.in index 2b0e0ee..89fad15 100644 --- a/lang/qt/tests/Makefile.in +++ b/lang/qt/tests/Makefile.in @@ -107,15 +107,15 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -TESTS = initial.test t-keylist$(EXEEXT) t-keylocate$(EXEEXT) \ - t-ownertrust$(EXEEXT) t-tofuinfo$(EXEEXT) t-encrypt$(EXEEXT) \ - t-verify$(EXEEXT) t-various$(EXEEXT) t-config$(EXEEXT) \ - t-remarks$(EXEEXT) t-trustsignatures$(EXEEXT) -noinst_PROGRAMS = t-keylist$(EXEEXT) t-keylocate$(EXEEXT) \ - t-ownertrust$(EXEEXT) t-tofuinfo$(EXEEXT) t-encrypt$(EXEEXT) \ - run-keyformailboxjob$(EXEEXT) t-wkspublish$(EXEEXT) \ - t-verify$(EXEEXT) t-various$(EXEEXT) t-config$(EXEEXT) \ - t-remarks$(EXEEXT) t-trustsignatures$(EXEEXT) +TESTS = initial.test $(am__EXEEXT_1) final.test +noinst_PROGRAMS = t-addexistingsubkey$(EXEEXT) t-keylist$(EXEEXT) \ + t-keylocate$(EXEEXT) t-ownertrust$(EXEEXT) t-tofuinfo$(EXEEXT) \ + t-encrypt$(EXEEXT) run-keyformailboxjob$(EXEEXT) \ + t-wkspublish$(EXEEXT) t-verify$(EXEEXT) t-various$(EXEEXT) \ + t-config$(EXEEXT) t-remarks$(EXEEXT) \ + t-trustsignatures$(EXEEXT) t-changeexpiryjob$(EXEEXT) \ + t-wkdlookup$(EXEEXT) t-import$(EXEEXT) run-importjob$(EXEEXT) \ + run-exportjob$(EXEEXT) run-receivekeysjob$(EXEEXT) subdir = lang/qt/tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ @@ -137,16 +137,43 @@ CONFIG_HEADER = $(top_builddir)/conf/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am_run_keyformailboxjob_OBJECTS = run-keyformailboxjob.$(OBJEXT) -run_keyformailboxjob_OBJECTS = $(am_run_keyformailboxjob_OBJECTS) -run_keyformailboxjob_LDADD = $(LDADD) -run_keyformailboxjob_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ +am_run_exportjob_OBJECTS = run-exportjob.$(OBJEXT) +run_exportjob_OBJECTS = $(am_run_exportjob_OBJECTS) +run_exportjob_LDADD = $(LDADD) +run_exportjob_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ ../src/libqgpgme.la ../../../src/libgpgme.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = +am_run_importjob_OBJECTS = run-importjob.$(OBJEXT) +run_importjob_OBJECTS = $(am_run_importjob_OBJECTS) +run_importjob_LDADD = $(LDADD) +run_importjob_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ + ../src/libqgpgme.la ../../../src/libgpgme.la +am_run_keyformailboxjob_OBJECTS = run-keyformailboxjob.$(OBJEXT) +run_keyformailboxjob_OBJECTS = $(am_run_keyformailboxjob_OBJECTS) +run_keyformailboxjob_LDADD = $(LDADD) +run_keyformailboxjob_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ + ../src/libqgpgme.la ../../../src/libgpgme.la +am_run_receivekeysjob_OBJECTS = run-receivekeysjob.$(OBJEXT) +run_receivekeysjob_OBJECTS = $(am_run_receivekeysjob_OBJECTS) +run_receivekeysjob_LDADD = $(LDADD) +run_receivekeysjob_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ + ../src/libqgpgme.la ../../../src/libgpgme.la am__objects_1 = t-support.$(OBJEXT) +am_t_addexistingsubkey_OBJECTS = t-addexistingsubkey.$(OBJEXT) \ + $(am__objects_1) +t_addexistingsubkey_OBJECTS = $(am_t_addexistingsubkey_OBJECTS) +t_addexistingsubkey_LDADD = $(LDADD) +t_addexistingsubkey_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ + ../src/libqgpgme.la ../../../src/libgpgme.la +am_t_changeexpiryjob_OBJECTS = t-changeexpiryjob.$(OBJEXT) \ + $(am__objects_1) +t_changeexpiryjob_OBJECTS = $(am_t_changeexpiryjob_OBJECTS) +t_changeexpiryjob_LDADD = $(LDADD) +t_changeexpiryjob_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ + ../src/libqgpgme.la ../../../src/libgpgme.la am_t_config_OBJECTS = t-config.$(OBJEXT) $(am__objects_1) t_config_OBJECTS = $(am_t_config_OBJECTS) t_config_LDADD = $(LDADD) @@ -157,6 +184,11 @@ t_encrypt_OBJECTS = $(am_t_encrypt_OBJECTS) t_encrypt_LDADD = $(LDADD) t_encrypt_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ ../src/libqgpgme.la ../../../src/libgpgme.la +am_t_import_OBJECTS = t-import.$(OBJEXT) $(am__objects_1) +t_import_OBJECTS = $(am_t_import_OBJECTS) +t_import_LDADD = $(LDADD) +t_import_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ + ../src/libqgpgme.la ../../../src/libgpgme.la am_t_keylist_OBJECTS = t-keylist.$(OBJEXT) $(am__objects_1) am__objects_2 = nodist_t_keylist_OBJECTS = $(am__objects_2) @@ -201,6 +233,11 @@ t_verify_OBJECTS = $(am_t_verify_OBJECTS) t_verify_LDADD = $(LDADD) t_verify_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ ../src/libqgpgme.la ../../../src/libgpgme.la +am_t_wkdlookup_OBJECTS = t-wkdlookup.$(OBJEXT) $(am__objects_1) +t_wkdlookup_OBJECTS = $(am_t_wkdlookup_OBJECTS) +t_wkdlookup_LDADD = $(LDADD) +t_wkdlookup_DEPENDENCIES = ../../cpp/src/libgpgmepp.la \ + ../src/libqgpgme.la ../../../src/libgpgme.la am_t_wkspublish_OBJECTS = t-wkspublish.$(OBJEXT) $(am__objects_1) t_wkspublish_OBJECTS = $(am_t_wkspublish_OBJECTS) t_wkspublish_LDADD = $(LDADD) @@ -221,13 +258,19 @@ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/conf depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/run-keyformailboxjob.Po \ - ./$(DEPDIR)/t-config.Po ./$(DEPDIR)/t-encrypt.Po \ +am__depfiles_remade = ./$(DEPDIR)/run-exportjob.Po \ + ./$(DEPDIR)/run-importjob.Po \ + ./$(DEPDIR)/run-keyformailboxjob.Po \ + ./$(DEPDIR)/run-receivekeysjob.Po \ + ./$(DEPDIR)/t-addexistingsubkey.Po \ + ./$(DEPDIR)/t-changeexpiryjob.Po ./$(DEPDIR)/t-config.Po \ + ./$(DEPDIR)/t-encrypt.Po ./$(DEPDIR)/t-import.Po \ ./$(DEPDIR)/t-keylist.Po ./$(DEPDIR)/t-keylocate.Po \ ./$(DEPDIR)/t-ownertrust.Po ./$(DEPDIR)/t-remarks.Po \ ./$(DEPDIR)/t-support.Po ./$(DEPDIR)/t-tofuinfo.Po \ ./$(DEPDIR)/t-trustsignatures.Po ./$(DEPDIR)/t-various.Po \ - ./$(DEPDIR)/t-verify.Po ./$(DEPDIR)/t-wkspublish.Po + ./$(DEPDIR)/t-verify.Po ./$(DEPDIR)/t-wkdlookup.Po \ + ./$(DEPDIR)/t-wkspublish.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) @@ -265,19 +308,25 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(run_keyformailboxjob_SOURCES) $(t_config_SOURCES) \ - $(t_encrypt_SOURCES) $(t_keylist_SOURCES) \ - $(nodist_t_keylist_SOURCES) $(t_keylocate_SOURCES) \ - $(t_ownertrust_SOURCES) $(t_remarks_SOURCES) \ - $(t_tofuinfo_SOURCES) $(t_trustsignatures_SOURCES) \ - $(t_various_SOURCES) $(t_verify_SOURCES) \ - $(t_wkspublish_SOURCES) -DIST_SOURCES = $(run_keyformailboxjob_SOURCES) $(t_config_SOURCES) \ - $(t_encrypt_SOURCES) $(t_keylist_SOURCES) \ +SOURCES = $(run_exportjob_SOURCES) $(run_importjob_SOURCES) \ + $(run_keyformailboxjob_SOURCES) $(run_receivekeysjob_SOURCES) \ + $(t_addexistingsubkey_SOURCES) $(t_changeexpiryjob_SOURCES) \ + $(t_config_SOURCES) $(t_encrypt_SOURCES) $(t_import_SOURCES) \ + $(t_keylist_SOURCES) $(nodist_t_keylist_SOURCES) \ $(t_keylocate_SOURCES) $(t_ownertrust_SOURCES) \ $(t_remarks_SOURCES) $(t_tofuinfo_SOURCES) \ $(t_trustsignatures_SOURCES) $(t_various_SOURCES) \ - $(t_verify_SOURCES) $(t_wkspublish_SOURCES) + $(t_verify_SOURCES) $(t_wkdlookup_SOURCES) \ + $(t_wkspublish_SOURCES) +DIST_SOURCES = $(run_exportjob_SOURCES) $(run_importjob_SOURCES) \ + $(run_keyformailboxjob_SOURCES) $(run_receivekeysjob_SOURCES) \ + $(t_addexistingsubkey_SOURCES) $(t_changeexpiryjob_SOURCES) \ + $(t_config_SOURCES) $(t_encrypt_SOURCES) $(t_import_SOURCES) \ + $(t_keylist_SOURCES) $(t_keylocate_SOURCES) \ + $(t_ownertrust_SOURCES) $(t_remarks_SOURCES) \ + $(t_tofuinfo_SOURCES) $(t_trustsignatures_SOURCES) \ + $(t_various_SOURCES) $(t_verify_SOURCES) \ + $(t_wkdlookup_SOURCES) $(t_wkspublish_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -324,6 +373,12 @@ am__tty_colors = { \ std='[m'; \ fi; \ } +am__EXEEXT_1 = t-addexistingsubkey$(EXEEXT) t-keylist$(EXEEXT) \ + t-keylocate$(EXEEXT) t-ownertrust$(EXEEXT) t-tofuinfo$(EXEEXT) \ + t-encrypt$(EXEEXT) t-verify$(EXEEXT) t-various$(EXEEXT) \ + t-config$(EXEEXT) t-remarks$(EXEEXT) \ + t-trustsignatures$(EXEEXT) t-changeexpiryjob$(EXEEXT) \ + t-wkdlookup$(EXEEXT) t-import$(EXEEXT) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp \ $(top_srcdir)/build-aux/mkinstalldirs @@ -529,10 +584,19 @@ top_srcdir = @top_srcdir@ GPG = gpg GNUPGHOME = $(abs_builddir) TESTS_ENVIRONMENT = GNUPGHOME=$(GNUPGHOME) -EXTRA_DIST = initial.test -moc_files = t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \ - t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc \ - t-various.moc t-config.moc t-remarks.moc t-trustsignatures.moc +EXTRA_DIST = initial.test final.test +the_tests = \ + t-addexistingsubkey \ + t-keylist t-keylocate t-ownertrust t-tofuinfo \ + t-encrypt t-verify t-various t-config t-remarks t-trustsignatures \ + t-changeexpiryjob t-wkdlookup t-import + +moc_files = \ + t-addexistingsubkey.moc \ + t-keylist.moc t-keylocate.moc t-ownertrust.moc t-tofuinfo.moc \ + t-encrypt.moc t-support.hmoc t-wkspublish.moc t-verify.moc \ + t-various.moc t-config.moc t-remarks.moc t-trustsignatures.moc \ + t-changeexpiryjob.moc t-wkdlookup.moc t-import.moc AM_LDFLAGS = -no-install LDADD = ../../cpp/src/libgpgmepp.la ../src/libqgpgme.la \ @@ -546,6 +610,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/lang/cpp/src -I$(top_builddir)/src \ -DTOP_SRCDIR="$(top_srcdir)" support_src = t-support.h t-support.cpp +t_addexistingsubkey_SOURCES = t-addexistingsubkey.cpp $(support_src) t_keylist_SOURCES = t-keylist.cpp $(support_src) t_keylocate_SOURCES = t-keylocate.cpp $(support_src) t_ownertrust_SOURCES = t-ownertrust.cpp $(support_src) @@ -557,7 +622,13 @@ t_various_SOURCES = t-various.cpp $(support_src) t_config_SOURCES = t-config.cpp $(support_src) t_remarks_SOURCES = t-remarks.cpp $(support_src) t_trustsignatures_SOURCES = t-trustsignatures.cpp $(support_src) +t_changeexpiryjob_SOURCES = t-changeexpiryjob.cpp $(support_src) +t_wkdlookup_SOURCES = t-wkdlookup.cpp $(support_src) +t_import_SOURCES = t-import.cpp $(support_src) +run_exportjob_SOURCES = run-exportjob.cpp +run_importjob_SOURCES = run-importjob.cpp run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp +run_receivekeysjob_SOURCES = run-receivekeysjob.cpp nodist_t_keylist_SOURCES = $(moc_files) BUILT_SOURCES = $(moc_files) pubring-stamp CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \ @@ -609,10 +680,30 @@ clean-noinstPROGRAMS: echo " rm -f" $$list; \ rm -f $$list +run-exportjob$(EXEEXT): $(run_exportjob_OBJECTS) $(run_exportjob_DEPENDENCIES) $(EXTRA_run_exportjob_DEPENDENCIES) + @rm -f run-exportjob$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(run_exportjob_OBJECTS) $(run_exportjob_LDADD) $(LIBS) + +run-importjob$(EXEEXT): $(run_importjob_OBJECTS) $(run_importjob_DEPENDENCIES) $(EXTRA_run_importjob_DEPENDENCIES) + @rm -f run-importjob$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(run_importjob_OBJECTS) $(run_importjob_LDADD) $(LIBS) + run-keyformailboxjob$(EXEEXT): $(run_keyformailboxjob_OBJECTS) $(run_keyformailboxjob_DEPENDENCIES) $(EXTRA_run_keyformailboxjob_DEPENDENCIES) @rm -f run-keyformailboxjob$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(run_keyformailboxjob_OBJECTS) $(run_keyformailboxjob_LDADD) $(LIBS) +run-receivekeysjob$(EXEEXT): $(run_receivekeysjob_OBJECTS) $(run_receivekeysjob_DEPENDENCIES) $(EXTRA_run_receivekeysjob_DEPENDENCIES) + @rm -f run-receivekeysjob$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(run_receivekeysjob_OBJECTS) $(run_receivekeysjob_LDADD) $(LIBS) + +t-addexistingsubkey$(EXEEXT): $(t_addexistingsubkey_OBJECTS) $(t_addexistingsubkey_DEPENDENCIES) $(EXTRA_t_addexistingsubkey_DEPENDENCIES) + @rm -f t-addexistingsubkey$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(t_addexistingsubkey_OBJECTS) $(t_addexistingsubkey_LDADD) $(LIBS) + +t-changeexpiryjob$(EXEEXT): $(t_changeexpiryjob_OBJECTS) $(t_changeexpiryjob_DEPENDENCIES) $(EXTRA_t_changeexpiryjob_DEPENDENCIES) + @rm -f t-changeexpiryjob$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(t_changeexpiryjob_OBJECTS) $(t_changeexpiryjob_LDADD) $(LIBS) + t-config$(EXEEXT): $(t_config_OBJECTS) $(t_config_DEPENDENCIES) $(EXTRA_t_config_DEPENDENCIES) @rm -f t-config$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t_config_OBJECTS) $(t_config_LDADD) $(LIBS) @@ -621,6 +712,10 @@ t-encrypt$(EXEEXT): $(t_encrypt_OBJECTS) $(t_encrypt_DEPENDENCIES) $(EXTRA_t_enc @rm -f t-encrypt$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t_encrypt_OBJECTS) $(t_encrypt_LDADD) $(LIBS) +t-import$(EXEEXT): $(t_import_OBJECTS) $(t_import_DEPENDENCIES) $(EXTRA_t_import_DEPENDENCIES) + @rm -f t-import$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(t_import_OBJECTS) $(t_import_LDADD) $(LIBS) + t-keylist$(EXEEXT): $(t_keylist_OBJECTS) $(t_keylist_DEPENDENCIES) $(EXTRA_t_keylist_DEPENDENCIES) @rm -f t-keylist$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t_keylist_OBJECTS) $(t_keylist_LDADD) $(LIBS) @@ -653,6 +748,10 @@ t-verify$(EXEEXT): $(t_verify_OBJECTS) $(t_verify_DEPENDENCIES) $(EXTRA_t_verify @rm -f t-verify$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t_verify_OBJECTS) $(t_verify_LDADD) $(LIBS) +t-wkdlookup$(EXEEXT): $(t_wkdlookup_OBJECTS) $(t_wkdlookup_DEPENDENCIES) $(EXTRA_t_wkdlookup_DEPENDENCIES) + @rm -f t-wkdlookup$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(t_wkdlookup_OBJECTS) $(t_wkdlookup_LDADD) $(LIBS) + t-wkspublish$(EXEEXT): $(t_wkspublish_OBJECTS) $(t_wkspublish_DEPENDENCIES) $(EXTRA_t_wkspublish_DEPENDENCIES) @rm -f t-wkspublish$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(t_wkspublish_OBJECTS) $(t_wkspublish_LDADD) $(LIBS) @@ -663,9 +762,15 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-exportjob.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-importjob.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-keyformailboxjob.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-receivekeysjob.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-addexistingsubkey.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-changeexpiryjob.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-config.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-encrypt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-import.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-keylist.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-keylocate.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-ownertrust.Po@am__quote@ # am--include-marker @@ -675,6 +780,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-trustsignatures.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-various.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-verify.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-wkdlookup.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-wkspublish.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @@ -934,9 +1040,15 @@ clean-am: clean-generic clean-libtool clean-local clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/run-keyformailboxjob.Po + -rm -f ./$(DEPDIR)/run-exportjob.Po + -rm -f ./$(DEPDIR)/run-importjob.Po + -rm -f ./$(DEPDIR)/run-keyformailboxjob.Po + -rm -f ./$(DEPDIR)/run-receivekeysjob.Po + -rm -f ./$(DEPDIR)/t-addexistingsubkey.Po + -rm -f ./$(DEPDIR)/t-changeexpiryjob.Po -rm -f ./$(DEPDIR)/t-config.Po -rm -f ./$(DEPDIR)/t-encrypt.Po + -rm -f ./$(DEPDIR)/t-import.Po -rm -f ./$(DEPDIR)/t-keylist.Po -rm -f ./$(DEPDIR)/t-keylocate.Po -rm -f ./$(DEPDIR)/t-ownertrust.Po @@ -946,6 +1058,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/t-trustsignatures.Po -rm -f ./$(DEPDIR)/t-various.Po -rm -f ./$(DEPDIR)/t-verify.Po + -rm -f ./$(DEPDIR)/t-wkdlookup.Po -rm -f ./$(DEPDIR)/t-wkspublish.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ @@ -992,9 +1105,15 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/run-keyformailboxjob.Po + -rm -f ./$(DEPDIR)/run-exportjob.Po + -rm -f ./$(DEPDIR)/run-importjob.Po + -rm -f ./$(DEPDIR)/run-keyformailboxjob.Po + -rm -f ./$(DEPDIR)/run-receivekeysjob.Po + -rm -f ./$(DEPDIR)/t-addexistingsubkey.Po + -rm -f ./$(DEPDIR)/t-changeexpiryjob.Po -rm -f ./$(DEPDIR)/t-config.Po -rm -f ./$(DEPDIR)/t-encrypt.Po + -rm -f ./$(DEPDIR)/t-import.Po -rm -f ./$(DEPDIR)/t-keylist.Po -rm -f ./$(DEPDIR)/t-keylocate.Po -rm -f ./$(DEPDIR)/t-ownertrust.Po @@ -1004,6 +1123,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/t-trustsignatures.Po -rm -f ./$(DEPDIR)/t-various.Po -rm -f ./$(DEPDIR)/t-verify.Po + -rm -f ./$(DEPDIR)/t-wkdlookup.Po -rm -f ./$(DEPDIR)/t-wkspublish.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/lang/qt/tests/final.test b/lang/qt/tests/final.test new file mode 100755 index 0000000..f28aaa4 --- /dev/null +++ b/lang/qt/tests/final.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# stop the dirmngr that may have been started +gpgconf --kill dirmngr + +exit 0 diff --git a/lang/qt/tests/run-exportjob.cpp b/lang/qt/tests/run-exportjob.cpp new file mode 100644 index 0000000..0f8fd8f --- /dev/null +++ b/lang/qt/tests/run-exportjob.cpp @@ -0,0 +1,119 @@ +/* + run-exportjob.cpp + + This file is part of QGpgME's test suite. + Copyright (c) 2022 by g10 Code GmbH + Software engineering by Ingo Klöcker <dev@ingo-kloecker.de> + + QGpgME is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + 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 <exportjob.h> +#include <protocol.h> + +#include <context.h> + +#include <QCoreApplication> + +#include <iostream> + +using namespace GpgME; +using std::cout; +using std::cerr; + +static void showUsageAndExitWithCode(int exitCode) +{ + cerr << "Usage: run-exportjob [OPTION]... [PATTERN]...\n" + "Options:\n" + " --secret export secret keys instead of public keys\n" + " --secret-subkey export secret subkeys instead of public keys\n"; + + exit(exitCode); +} + +static auto createExportJob(unsigned int mode) +{ + if (mode & Context::ExportSecretSubkey) { + return QGpgME::openpgp()->secretSubkeyExportJob(/*armor=*/true); + } else if (mode & Context::ExportSecret) { + return QGpgME::openpgp()->secretKeyExportJob(/*armor=*/true); + } + return QGpgME::openpgp()->publicKeyExportJob(/*armor=*/true); +} + +int main(int argc, char *argv[]) +{ + GpgME::initializeLibrary(); + + QCoreApplication app{argc, argv}; + + unsigned int exportMode = 0; + + auto arguments = app.arguments(); + if (!arguments.isEmpty()) { + arguments.pop_front(); // remove program name + } + while (!arguments.isEmpty()) { + const auto &arg = arguments.front(); + if (!arg.startsWith(QLatin1String{"--"})) { + break; + } + if (arg == QLatin1String{"--"}) { + arguments.pop_front(); + break; + } + if (arg == QLatin1String{"--help"}) { + showUsageAndExitWithCode(0); + } else if (arg == QLatin1String{"--secret"}) { + exportMode = Context::ExportSecret; + arguments.pop_front(); + } else if (arg == QLatin1String{"--secret-subkey"}) { + exportMode = Context::ExportSecretSubkey; + arguments.pop_front(); + } else { + cerr << "Error: Invalid option " << arg.toStdString() << std::endl; + showUsageAndExitWithCode(1); + } + } + + auto job = createExportJob(exportMode); + QObject::connect(job, &QGpgME::ExportJob::result, + &app, [&app] (const GpgME::Error &err, const QByteArray &keyData, const QString &, const GpgME::Error &) { + if (err) { + cerr << "The ChangeExpiryJob failed with" << err.asString() << "."; + app.exit(1); + return; + } + cout << "Begin Result:\n" << keyData.toStdString() << "End Result:\n"; + app.exit(); + }); + job->start(arguments); + + return app.exec(); +} diff --git a/lang/qt/tests/run-importjob.cpp b/lang/qt/tests/run-importjob.cpp new file mode 100644 index 0000000..b1814fa --- /dev/null +++ b/lang/qt/tests/run-importjob.cpp @@ -0,0 +1,99 @@ +/* + run-importjob.cpp + + This file is part of QGpgME's test suite. + Copyright (c) 2021 by g10 Code GmbH + Software engineering by Ingo Klöcker <dev@ingo-kloecker.de> + + QGpgME is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + 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 <importjob.h> +#include <importresult.h> +#include <protocol.h> + +#include <QFile> +#include <QFileInfo> + +#include <QDebug> + +#include <set> +#include <sstream> + +GpgME::Protocol guessProtocol(const QString &filename) +{ + static const std::set<QString> cmsExtensions = {"cer", "crt", "der", "p12", "p7c", "pem", "pfx"}; + static const std::set<QString> pgpExtensions = {"asc", "gpg", "pgp"}; + + const auto extension = QFileInfo{filename}.suffix(); + if (cmsExtensions.find(extension) != cmsExtensions.end()) { + return GpgME::CMS; + } else if (pgpExtensions.find(extension) != pgpExtensions.end()) { + return GpgME::OpenPGP; + } + qDebug() << "Unknown file name extension" << extension; + return GpgME::UnknownProtocol; +} + +int main(int argc, char **argv) +{ + GpgME::initializeLibrary(); + + if (argc != 2) { + qInfo().noquote() << "Usage:" << argv[0] << "<certificate file>"; + return 1; + } + const auto filename = QString::fromLocal8Bit(argv[1]); + + QFile f{filename}; + if (!f.exists()) { + qWarning() << "Error: File not found" << filename; + return 1; + } + const auto protocol = guessProtocol(filename); + if (protocol == GpgME::UnknownProtocol) { + qWarning() << "Error: Unknown file type"; + return 1; + } + if (!f.open(QIODevice::ReadOnly)) { + qWarning() << "Error: Failed to open file" << filename << "for reading."; + return 1; + } + + const auto keyData = f.readAll(); + auto job = (protocol == GpgME::CMS ? QGpgME::smime() : QGpgME::openpgp())->importJob(); + const auto result = job->exec(keyData); + qDebug() << "Result error:" << result.error().asString(); + std::ostringstream ostr; + ostr << result; + for (const auto &line : QString::fromStdString(ostr.str()).split('\n')) { + qDebug().noquote() << line; + } + return 0; +} diff --git a/lang/qt/tests/run-receivekeysjob.cpp b/lang/qt/tests/run-receivekeysjob.cpp new file mode 100644 index 0000000..0dc1575 --- /dev/null +++ b/lang/qt/tests/run-receivekeysjob.cpp @@ -0,0 +1,65 @@ +/* + run-receivekeysjob.cpp + + This file is part of QGpgME's test suite. + Copyright (c) 2022 by g10 Code GmbH + Software engineering by Ingo Klöcker <dev@ingo-kloecker.de> + + QGpgME is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + 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 <importresult.h> +#include <protocol.h> +#include <receivekeysjob.h> + +#include <QCoreApplication> +#include <QDebug> + +#include <iostream> + +int main(int argc, char **argv) +{ + GpgME::initializeLibrary(); + + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " KEYID..." << std::endl; + return 1; + } + + QCoreApplication app(argc, argv); + const QStringList keyIds = qApp->arguments().mid(1); + + auto job = QGpgME::openpgp()->receiveKeysJob(); + const auto result = job->exec(keyIds); + + std::cout << "Result: " << result.error().asString() << std::endl; + std::cout << "Details:\n" << result << std::endl; + + return 0; +} diff --git a/lang/qt/tests/t-addexistingsubkey.cpp b/lang/qt/tests/t-addexistingsubkey.cpp new file mode 100644 index 0000000..589c90b --- /dev/null +++ b/lang/qt/tests/t-addexistingsubkey.cpp @@ -0,0 +1,260 @@ +/* t-addexistingsubkey.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2022 g10 Code GmbH + Software engineering by Ingo Klöcker <dev@ingo-kloecker.de> + + 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 "t-support.h" + +#include "addexistingsubkeyjob.h" +#include "protocol.h" + +#include <QSignalSpy> +#include <QTest> + +#include "context.h" +#include "data.h" +#include "engineinfo.h" + +#include <algorithm> + +using namespace QGpgME; +using namespace GpgME; + +static const char *requiredVersion = "2.3.5"; + +/* Test keys + sec# ed25519 2022-01-13 [SC] + 1CB8C6A0317AA83F44FE009932392C82B814C8E0 + uid [ unknown] source-key@example.net + ssb cv25519 2022-01-13 [E] + ssb cv25519 2022-01-13 [E] [expires: 2100-01-01] + + sec ed25519 2022-01-13 [SC] + C3C87F0A3920B01F9E4450EA2B79F21D4DD10BFC + uid [ unknown] target-key@example.net + ssb cv25519 2022-01-13 [E] + * generated with +export GNUPGHOME=$(mktemp -d) +gpg -K +gpg --batch --pinentry-mode loopback --passphrase abc --quick-gen-key source-key@example.net default default never +fpr=$(gpg -k --with-colons source-key@example.net | grep ^fpr | head -1 | cut -d ':' -f 10) +gpg --batch --pinentry-mode loopback --passphrase abc --quick-add-key ${fpr} default default 21000101T120000 +gpg --batch --pinentry-mode loopback --passphrase abc --quick-gen-key target-key@example.net default default never +gpg -K +gpg --export-secret-subkeys --armor --batch --pinentry-mode loopback --passphrase abc --comment source-key@example.net source-key@example.net | sed 's/\(.*\)/ "\1\\n"/' +gpg --export-secret-keys --armor --batch --pinentry-mode loopback --passphrase abc --comment target-key@example.net target-key@example.net | sed 's/\(.*\)/ "\1\\n"/' +#rm -rf ${GNUPGHOME} +unset GNUPGHOME +*/ +static const char *testKeyData = + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + "Comment: source-key@example.net\n" + "\n" + "lDsEYd/ujBYJKwYBBAHaRw8BAQdAwiZPINTcrpgmu6ZWSaPZlcRSd4nDuofVMhe7\n" + "c2XrFyT/AGUAR05VAbQWc291cmNlLWtleUBleGFtcGxlLm5ldIiUBBMWCgA8FiEE\n" + "HLjGoDF6qD9E/gCZMjksgrgUyOAFAmHf7owCGwMFCwkIBwIDIgIBBhUKCQgLAgQW\n" + "AgMBAh4HAheAAAoJEDI5LIK4FMjgupIA/Au2YEAT9dYdJd0eJCJerG5YAeoB+uBs\n" + "mBkgr6xXE0bIAP43b6u1Jtvf/Wm3BhRbLd5Tg67Ba4CIZ8ZLGng73FBoBpyLBGHf\n" + "7owSCisGAQQBl1UBBQEBB0Cpg8Qof/WShxROZZtmPnw24vTk0R8nIAF1CZJ0bG/C\n" + "SwMBCAf+BwMCtzxziVxQEor8w/VVzHp4/hVSCUyrpiX7Djf04cIMs2bFPduZLgxb\n" + "c1SXhlgiqU0YBNntbGGNdKjTP6FMbYWq1+NwQm6ZXtC76LPG7syM94h4BBgWCgAg\n" + "FiEEHLjGoDF6qD9E/gCZMjksgrgUyOAFAmHf7owCGwwACgkQMjksgrgUyOCI0wEA\n" + "+f56fkvDDUwMOMw7n4+GKpfJXpWhVL08ttccbBOa/9IA/2HYA/78ZaD8E5EyqAEK\n" + "Aj9Au+2oJu9V5qo92QEoqwYHnIsEYd/vgxIKKwYBBAGXVQEFAQEHQBa9FxJkm/9D\n" + "xABildkaYMrbJbu8BPk6uv9V8aLmv9FnAwEIB/4HAwIPhcbN8s6OzPz8/g78TrCh\n" + "xqQb2kygCEj+OQ4/XXU3lus2b5xS5h44LGt99Wisqx+wVPDXmPDJOaxjhHXDmJxd\n" + "/LplIEhykojSm3uUDxERiH4EGBYKACYWIQQcuMagMXqoP0T+AJkyOSyCuBTI4AUC\n" + "Yd/vgwIbDAUJkqcQPQAKCRAyOSyCuBTI4IUjAP9BTfOD+jy6lLmzNO9pquRSAxi/\n" + "PQuglGtpS0LQEJMEOwD+PFnsMe2EtQ+WVSDBeB7O0m61EXeY+RhpuhNtsNXVuwc=\n" + "=wIPU\n" + "-----END PGP PRIVATE KEY BLOCK-----\n" + "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + "Comment: target-key@example.net\n" + "\n" + "lIYEYd/v/RYJKwYBBAHaRw8BAQdAKoILWXG3yaLb2EniNKQLUjwsrvy5vgAN299J\n" + "W5cFbrz+BwMC/uKbCq3sK5H8QVtEQ/IxGmjWNBpy6c8EDlOG4APi4o4VE+bEYD8w\n" + "J3Kk/lzSm6ZT5vC6DDASks797omjXD+J7zZ0vtTPvheYi/nsVz2UebQWdGFyZ2V0\n" + "LWtleUBleGFtcGxlLm5ldIiUBBMWCgA8FiEEw8h/CjkgsB+eRFDqK3nyHU3RC/wF\n" + "AmHf7/0CGwMFCwkIBwIDIgIBBhUKCQgLAgQWAgMBAh4HAheAAAoJECt58h1N0Qv8\n" + "rXcBAPxnkXqpp4IY3iTKV5XAdo7Uys7U/joUD73rj2XEvgI1AQDhKK4PLxPhf3ki\n" + "FKU0RA7itxzOH+F8bQ5BdYS49jDPCpyLBGHf7/0SCisGAQQBl1UBBQEBB0Dq9rwA\n" + "hAA2UFJShFsLFp7+g4uhWDfuDa3VjeIQRM+9QgMBCAf+BwMCMfCTl0LNqsn836t5\n" + "f2ZHBuMcNs4JWYmdLAIVaewEHq7zhOsX3iB+/yxwu9g2mXc4XUJ1iQzXLOYwgGov\n" + "8jIovrr01hDkSg4rvM9JKMWdd4h4BBgWCgAgFiEEw8h/CjkgsB+eRFDqK3nyHU3R\n" + "C/wFAmHf7/0CGwwACgkQK3nyHU3RC/xyfAEAqnMdSv6FTAwAWrYvJqJtSVoEhjMn\n" + "3c2qMsu34Bk86/MBAKHbLFmdyePvHaxKeO8CkQDoJzK8rYzw3RAmq/5JsQkL\n" + "=rOVf\n" + "-----END PGP PRIVATE KEY BLOCK-----\n"; + +class AddExistingSubkeyJobTest : public QGpgMETest +{ + Q_OBJECT + +private Q_SLOTS: + + void initTestCase() + { + QGpgMETest::initTestCase(); + + // set up the test fixture for this test + qputenv("GNUPGHOME", mGnupgHomeTestFixture.path().toUtf8()); + QVERIFY(importSecretKeys(testKeyData, 2)); + } + + void init() + { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < requiredVersion) { + QSKIP("gpg does not yet support adding an existing subkey to another key via the command API"); + } + + // set up a copy of the test fixture for each test function + mGnupgHomeTestCopy.reset(new QTemporaryDir{}); + QVERIFY(copyKeyrings(mGnupgHomeTestFixture.path(), mGnupgHomeTestCopy->path())); + qputenv("GNUPGHOME", mGnupgHomeTestCopy->path().toUtf8()); + } + + void testAddExistingSubkeyAsync() + { + // Get the key the subkey should be added to + auto key = getTestKey("target-key@example.net"); + QVERIFY(!key.isNull()); + + // Get the key with the subkey to add + auto sourceKey = getTestKey("source-key@example.net", 3); + QVERIFY(!sourceKey.isNull()); + + auto job = std::unique_ptr<AddExistingSubkeyJob>{openpgp()->addExistingSubkeyJob()}; + hookUpPassphraseProvider(job.get()); + + Error result; + connect(job.get(), &AddExistingSubkeyJob::result, + job.get(), [this, &result](const Error &result_) { + result = result_; + Q_EMIT asyncDone(); + }); + QVERIFY(!job->start(key, sourceKey.subkey(1))); + job.release(); // after the job has been started it's on its own + + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT)); + + QVERIFY(result.code() == GPG_ERR_NO_ERROR); + key.update(); + QCOMPARE(key.numSubkeys(), 3u); + } + + void testAddExistingSubkeySync() + { + // Get the key the subkey should be added to + auto key = getTestKey("target-key@example.net"); + QVERIFY(!key.isNull()); + + // Get the key with the subkey to add + auto sourceKey = getTestKey("source-key@example.net", 3); + QVERIFY(!sourceKey.isNull()); + auto sourceSubkey = sourceKey.subkey(1); + QVERIFY(sourceSubkey.expirationTime() == 0); + + auto job = std::unique_ptr<AddExistingSubkeyJob>{openpgp()->addExistingSubkeyJob()}; + hookUpPassphraseProvider(job.get()); + + const auto result = job->exec(key, sourceSubkey); + + QVERIFY(result.code() == GPG_ERR_NO_ERROR); + key.update(); + QCOMPARE(key.numSubkeys(), 3u); + QCOMPARE(key.subkey(2).expirationTime(), 0); + } + + void testAddExistingSubkeyWithExpiration() + { + // Get the key the subkey should be added to + auto key = getTestKey("target-key@example.net"); + QVERIFY(!key.isNull()); + + // Get the key with the subkey to add + auto sourceKey = getTestKey("source-key@example.net", 3); + QVERIFY(!sourceKey.isNull()); + auto sourceSubkey = sourceKey.subkey(2); + QVERIFY(sourceSubkey.expirationTime() != 0); + + auto job = std::unique_ptr<AddExistingSubkeyJob>{openpgp()->addExistingSubkeyJob()}; + hookUpPassphraseProvider(job.get()); + + const auto result = job->exec(key, sourceSubkey); + + QVERIFY(result.code() == GPG_ERR_NO_ERROR); + key.update(); + QCOMPARE(key.numSubkeys(), 3u); + + // allow 1 second different expiration because gpg calculates with + // expiration as difference to current time and takes current time + // several times + const auto allowedDeltaTSeconds = 1; + const auto expectedExpirationRange = std::make_pair( + sourceSubkey.expirationTime() - allowedDeltaTSeconds, + sourceSubkey.expirationTime() + allowedDeltaTSeconds); + const auto actualExpiration = key.subkey(2).expirationTime(); + QVERIFY2(actualExpiration >= expectedExpirationRange.first, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.first)).c_str()); + QVERIFY2(actualExpiration <= expectedExpirationRange.second, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.second)).c_str()); + } + +private: + Key getTestKey(const char *pattern, unsigned int expectedSubkeys = 2) + { + auto ctx = Context::create(OpenPGP); + VERIFY_OR_OBJECT(ctx); + + Error err; + auto key = ctx->key(pattern, err, /*secret=*/true); + VERIFY_OR_OBJECT(!err); + VERIFY_OR_OBJECT(!key.isNull()); + COMPARE_OR_OBJECT(key.numSubkeys(), expectedSubkeys); + for (unsigned int i = 0; i < key.numSubkeys(); ++i) { + VERIFY_OR_OBJECT(!key.subkey(i).isNull()); + } + return key; + } + +private: + QTemporaryDir mGnupgHomeTestFixture; + std::unique_ptr<QTemporaryDir> mGnupgHomeTestCopy; +}; + +QTEST_MAIN(AddExistingSubkeyJobTest) + +#include "t-addexistingsubkey.moc" diff --git a/lang/qt/tests/t-changeexpiryjob.cpp b/lang/qt/tests/t-changeexpiryjob.cpp new file mode 100644 index 0000000..090002f --- /dev/null +++ b/lang/qt/tests/t-changeexpiryjob.cpp @@ -0,0 +1,396 @@ +/* t-changeexpiryjob.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2021 g10 Code GmbH + Software engineering by Ingo Klöcker <dev@ingo-kloecker.de> + + 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 "t-support.h" + +#include "changeexpiryjob.h" +#include "context.h" +#include "engineinfo.h" +#include "protocol.h" + +#include <QSignalSpy> +#include <QTemporaryDir> +#include <QTest> + +using namespace QGpgME; +using namespace GpgME; + +class TestChangeExpiryJob: public QGpgMETest +{ + Q_OBJECT + +private Q_SLOTS: + void test_change_expiration_default_without_subkeys() + { + Error err; + + if (!loopbackSupported()) { + return; + } + + auto ctx = Context::create(OpenPGP); + QVERIFY(ctx); + + // Get the key (alfa@example.net) + auto key = ctx->key("A0FF4590BB6122EDEF6E3C542D727CC768697734", err, true); + QVERIFY(!err); + QVERIFY(!key.isNull()); + QVERIFY(!key.subkey(0).isNull()); + QVERIFY(!key.subkey(1).isNull()); + const auto subkeyExpiration = key.subkey(1).expirationTime(); + + { + // Create the job + auto job = std::unique_ptr<ChangeExpiryJob>{openpgp()->changeExpiryJob()}; + QVERIFY(job); + hookUpPassphraseProvider(job.get()); + + // Use defaults of job + + connect(job.get(), &ChangeExpiryJob::result, + this, [this] (const GpgME::Error &err2, const QString &, const GpgME::Error &) { + Q_EMIT asyncDone(); + if (err2) { + QFAIL(qPrintable(QString("The ChangeExpiryJob failed with '%1'.").arg(err2.asString()))); + } + }); + + const auto newExpirationDate = QDateTime::currentDateTime().addDays(1); + job->start(key, newExpirationDate); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT)); + + // At this point the expiration date should have been changed. + key.update(); + + // allow a few seconds earlier expiration because job calculates "seconds from now" passed to gpg after it was started + const auto expectedExpirationRange = std::make_pair( + newExpirationDate.toSecsSinceEpoch() - 10, + QDateTime::currentDateTime().addDays(1).toSecsSinceEpoch()); + { + const auto actualExpiration = key.subkey(0).expirationTime(); + QVERIFY2(actualExpiration >= expectedExpirationRange.first, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.first)).c_str()); + QVERIFY2(actualExpiration <= expectedExpirationRange.second, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.second)).c_str()); + } + { + const auto actualExpiration = key.subkey(1).expirationTime(); + QCOMPARE(actualExpiration, subkeyExpiration); // unchanged + } + } + } + + void test_change_expiration_default_with_subkeys() + { + Error err; + + if (!loopbackSupported()) { + return; + } + + auto ctx = Context::create(OpenPGP); + QVERIFY(ctx); + + // Get the key (alfa@example.net) + auto key = ctx->key("A0FF4590BB6122EDEF6E3C542D727CC768697734", err, true); + QVERIFY(!err); + QVERIFY(!key.isNull()); + QVERIFY(!key.subkey(0).isNull()); + QVERIFY(!key.subkey(1).isNull()); + const auto primaryKeyExpiration = key.subkey(0).expirationTime(); + + { + // Create the job + auto job = std::unique_ptr<ChangeExpiryJob>{openpgp()->changeExpiryJob()}; + QVERIFY(job); + hookUpPassphraseProvider(job.get()); + + // Use defaults of job + + connect(job.get(), &ChangeExpiryJob::result, + this, [this] (const GpgME::Error &err2, const QString &, const GpgME::Error &) { + Q_EMIT asyncDone(); + if (err2) { + QFAIL(qPrintable(QString("The ChangeExpiryJob failed with '%1'.").arg(err2.asString()))); + } + }); + + const auto newExpirationDate = QDateTime::currentDateTime().addDays(2); + job->start(key, newExpirationDate, {key.subkey(1)}); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT)); + + // At this point the expiration date should have been changed. + key.update(); + + // allow a few seconds earlier expiration because job calculates "seconds from now" passed to gpg after it was started + const auto expectedExpirationRange = std::make_pair( + newExpirationDate.toSecsSinceEpoch() - 10, + QDateTime::currentDateTime().addDays(2).toSecsSinceEpoch()); + { + const auto actualExpiration = key.subkey(0).expirationTime(); + QCOMPARE(actualExpiration, primaryKeyExpiration); // unchanged + } + { + const auto actualExpiration = key.subkey(1).expirationTime(); + QVERIFY2(actualExpiration >= expectedExpirationRange.first, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.first)).c_str()); + QVERIFY2(actualExpiration <= expectedExpirationRange.second, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.second)).c_str()); + } + } + } + + void test_change_expiration_update_primary_key_without_subkeys() + { + Error err; + + if (!loopbackSupported()) { + return; + } + + auto ctx = Context::create(OpenPGP); + QVERIFY(ctx); + + // Get the key (alfa@example.net) + auto key = ctx->key("A0FF4590BB6122EDEF6E3C542D727CC768697734", err, true); + QVERIFY(!err); + QVERIFY(!key.isNull()); + QVERIFY(!key.subkey(0).isNull()); + QVERIFY(!key.subkey(1).isNull()); + const auto subkeyExpiration = key.subkey(1).expirationTime(); + + { + // Create the job + auto job = std::unique_ptr<ChangeExpiryJob>{openpgp()->changeExpiryJob()}; + QVERIFY(job); + hookUpPassphraseProvider(job.get()); + + // Set up the job + job->setOptions(ChangeExpiryJob::UpdatePrimaryKey); + + connect(job.get(), &ChangeExpiryJob::result, + this, [this] (const GpgME::Error &err2, const QString &, const GpgME::Error &) { + Q_EMIT asyncDone(); + if (err2) { + QFAIL(qPrintable(QString("The ChangeExpiryJob failed with '%1'.").arg(err2.asString()))); + } + }); + + const auto newExpirationDate = QDateTime::currentDateTime().addDays(3); + job->start(key, newExpirationDate, {}); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT)); + + // At this point the expiration date should have been changed. + key.update(); + + // allow a few seconds earlier expiration because job calculates "seconds from now" passed to gpg after it was started + const auto expectedExpirationRange = std::make_pair( + newExpirationDate.toSecsSinceEpoch() - 10, + QDateTime::currentDateTime().addDays(3).toSecsSinceEpoch()); + { + const auto actualExpiration = key.subkey(0).expirationTime(); + QVERIFY2(actualExpiration >= expectedExpirationRange.first, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.first)).c_str()); + QVERIFY2(actualExpiration <= expectedExpirationRange.second, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.second)).c_str()); + } + { + const auto actualExpiration = key.subkey(1).expirationTime(); + QCOMPARE(actualExpiration, subkeyExpiration); // unchanged + } + } + } + + void test_change_expiration_update_primary_key_with_subkeys() + { + Error err; + + if (!loopbackSupported()) { + return; + } + + auto ctx = Context::create(OpenPGP); + QVERIFY(ctx); + + // Get the key (alfa@example.net) + auto key = ctx->key("A0FF4590BB6122EDEF6E3C542D727CC768697734", err, true); + QVERIFY(!err); + QVERIFY(!key.isNull()); + QVERIFY(!key.subkey(0).isNull()); + QVERIFY(!key.subkey(1).isNull()); + + { + // Create the job + auto job = std::unique_ptr<ChangeExpiryJob>{openpgp()->changeExpiryJob()}; + QVERIFY(job); + hookUpPassphraseProvider(job.get()); + + // Set up the job + job->setOptions(ChangeExpiryJob::UpdatePrimaryKey); + + connect(job.get(), &ChangeExpiryJob::result, + this, [this] (const GpgME::Error &err2, const QString &, const GpgME::Error &) { + Q_EMIT asyncDone(); + if (err2) { + QFAIL(qPrintable(QString("The ChangeExpiryJob failed with '%1'.").arg(err2.asString()))); + } + }); + + const auto newExpirationDate = QDateTime::currentDateTime().addDays(4); + job->start(key, newExpirationDate, {key.subkey(1)}); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT)); + + // At this point the expiration date should have been changed. + key.update(); + + // allow a few seconds earlier expiration because job calculates "seconds from now" passed to gpg after it was started + const auto expectedExpirationRange = std::make_pair( + newExpirationDate.toSecsSinceEpoch() - 10, + QDateTime::currentDateTime().addDays(4).toSecsSinceEpoch()); + { + const auto actualExpiration = key.subkey(0).expirationTime(); + QVERIFY2(actualExpiration >= expectedExpirationRange.first, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.first)).c_str()); + QVERIFY2(actualExpiration <= expectedExpirationRange.second, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.second)).c_str()); + } + { + const auto actualExpiration = key.subkey(1).expirationTime(); + QVERIFY2(actualExpiration >= expectedExpirationRange.first, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.first)).c_str()); + QVERIFY2(actualExpiration <= expectedExpirationRange.second, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.second)).c_str()); + } + } + } + + void test_change_expiration_update_primary_key_and_all_subkeys() + { + Error err; + + if (!loopbackSupported()) { + return; + } + + auto ctx = Context::create(OpenPGP); + QVERIFY(ctx); + + // Get the key (alfa@example.net) + auto key = ctx->key("A0FF4590BB6122EDEF6E3C542D727CC768697734", err, true); + QVERIFY(!err); + QVERIFY(!key.isNull()); + QVERIFY(!key.subkey(0).isNull()); + QVERIFY(!key.subkey(1).isNull()); + + { + // Create the job + auto job = std::unique_ptr<ChangeExpiryJob>{openpgp()->changeExpiryJob()}; + QVERIFY(job); + hookUpPassphraseProvider(job.get()); + + // Set up the job + job->setOptions(ChangeExpiryJob::UpdatePrimaryKey | ChangeExpiryJob::UpdateAllSubkeys); + + connect(job.get(), &ChangeExpiryJob::result, + this, [this] (const GpgME::Error &err2, const QString &, const GpgME::Error &) { + Q_EMIT asyncDone(); + if (err2) { + QFAIL(qPrintable(QString("The ChangeExpiryJob failed with '%1'.").arg(err2.asString()))); + } + }); + + const auto newExpirationDate = QDateTime::currentDateTime().addDays(5); + job->start(key, newExpirationDate); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT)); + + // At this point the expiration date should have been changed. + key.update(); + + // allow a few seconds earlier expiration because job calculates "seconds from now" passed to gpg after it was started + const auto expectedExpirationRange = std::make_pair( + newExpirationDate.toSecsSinceEpoch() - 10, + QDateTime::currentDateTime().addDays(5).toSecsSinceEpoch()); + { + const auto actualExpiration = key.subkey(0).expirationTime(); + QVERIFY2(actualExpiration >= expectedExpirationRange.first, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.first)).c_str()); + QVERIFY2(actualExpiration <= expectedExpirationRange.second, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.second)).c_str()); + } + { + const auto actualExpiration = key.subkey(1).expirationTime(); + QVERIFY2(actualExpiration >= expectedExpirationRange.first, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.first)).c_str()); + QVERIFY2(actualExpiration <= expectedExpirationRange.second, + ("actual: " + std::to_string(actualExpiration) + + "; expected: " + std::to_string(expectedExpirationRange.second)).c_str()); + } + } + } + + void initTestCase() + { + QGpgMETest::initTestCase(); + const QString gpgHome = qgetenv("GNUPGHOME"); + QVERIFY(copyKeyrings(gpgHome, mDir.path())); + qputenv("GNUPGHOME", mDir.path().toUtf8()); + } + +private: + QTemporaryDir mDir; +}; + +QTEST_MAIN(TestChangeExpiryJob) + +#include "t-changeexpiryjob.moc" diff --git a/lang/qt/tests/t-config.cpp b/lang/qt/tests/t-config.cpp index 9ec9566..b84dbfd 100644 --- a/lang/qt/tests/t-config.cpp +++ b/lang/qt/tests/t-config.cpp @@ -57,27 +57,24 @@ private Q_SLOTS: // be unsupported in older versions. return; } - // First set compliance to de-vs auto conf = cryptoConfig(); QVERIFY(conf); - auto entry = conf->entry(QStringLiteral("gpg"), - QStringLiteral("Configuration"), - QStringLiteral("compliance")); + auto entry = conf->entry(QStringLiteral("gpg"), QStringLiteral("compliance")); QVERIFY(entry); + const auto defaultValue = entry->defaultValue().toString(); + QCOMPARE(defaultValue, QStringLiteral("gnupg")); + entry->setStringValue("de-vs"); conf->sync(true); conf->clear(); - entry = conf->entry(QStringLiteral("gpg"), - QStringLiteral("Configuration"), - QStringLiteral("compliance")); + entry = conf->entry(QStringLiteral("gpg"), QStringLiteral("compliance")); QCOMPARE(entry->stringValue(), QStringLiteral("de-vs")); + entry->resetToDefault(); conf->sync(true); conf->clear(); - entry = conf->entry(QStringLiteral("gpg"), - QStringLiteral("Configuration"), - QStringLiteral("compliance")); - QCOMPARE(entry->stringValue(), QStringLiteral("gnupg")); + entry = conf->entry(QStringLiteral("gpg"), QStringLiteral("compliance")); + QCOMPARE(entry->stringValue(), defaultValue); } void initTestCase() diff --git a/lang/qt/tests/t-encrypt.cpp b/lang/qt/tests/t-encrypt.cpp index 9ad1033..6a4c68e 100644 --- a/lang/qt/tests/t-encrypt.cpp +++ b/lang/qt/tests/t-encrypt.cpp @@ -63,9 +63,6 @@ class EncryptionTest : public QGpgMETest { Q_OBJECT -Q_SIGNALS: - void asyncDone(); - private Q_SLOTS: void testSimpleEncryptDecrypt() @@ -92,10 +89,7 @@ private Q_SLOTS: return; } auto decJob = openpgp()->decryptJob(); - auto ctx = Job::context(decJob); - TestPassphraseProvider provider; - ctx->setPassphraseProvider(&provider); - ctx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(decJob); QByteArray plainText; auto decResult = decJob->exec(cipherText, plainText); QVERIFY(!decResult.error()); @@ -163,10 +157,8 @@ private Q_SLOTS: return; } auto job = openpgp()->encryptJob(); + hookUpPassphraseProvider(job); auto ctx = Job::context(job); - TestPassphraseProvider provider; - ctx->setPassphraseProvider(&provider); - ctx->setPinentryMode(Context::PinentryLoopback); ctx->setArmor(true); ctx->setTextMode(true); QByteArray cipherText; @@ -179,9 +171,7 @@ private Q_SLOTS: killAgent(mDir.path()); auto decJob = openpgp()->decryptJob(); - auto ctx2 = Job::context(decJob); - ctx2->setPassphraseProvider(&provider); - ctx2->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(decJob); QByteArray plainText; auto decResult = decJob->exec(cipherText, plainText); QVERIFY(!result.error()); @@ -204,13 +194,9 @@ private Q_SLOTS: delete listjob; auto job = openpgp()->signEncryptJob(/*ASCII Armor */true, /* Textmode */ true); - - auto encSignCtx = Job::context(job); - TestPassphraseProvider provider1; - encSignCtx->setPassphraseProvider(&provider1); - encSignCtx->setPinentryMode(Context::PinentryLoopback); - QVERIFY(job); + hookUpPassphraseProvider(job); + QByteArray cipherText; auto result = job->exec(keys, keys, QStringLiteral("Hello World").toUtf8(), Context::AlwaysTrust, cipherText); delete job; @@ -225,10 +211,8 @@ private Q_SLOTS: } auto decJob = openpgp()->decryptJob(); + hookUpPassphraseProvider(decJob); auto ctx = Job::context(decJob); - TestPassphraseProvider provider; - ctx->setPassphraseProvider(&provider); - ctx->setPinentryMode(Context::PinentryLoopback); ctx->setDecryptionFlags(Context::DecryptUnwrap); QByteArray plainText; @@ -269,9 +253,8 @@ private: delete listjob; auto job = openpgp()->encryptJob(); + hookUpPassphraseProvider(job); auto ctx = Job::context(job); - ctx->setPassphraseProvider(new TestPassphraseProvider); - ctx->setPinentryMode(Context::PinentryLoopback); ctx->setArmor(true); ctx->setTextMode(true); QByteArray cipherText; @@ -297,9 +280,8 @@ private: agentConf.close(); auto decJob = openpgp()->decryptJob(); + hookUpPassphraseProvider(decJob); auto ctx2 = Job::context(decJob); - ctx2->setPassphraseProvider(new TestPassphraseProvider); - ctx2->setPinentryMode(Context::PinentryLoopback); ctx2->setTextMode(true); QByteArray plainText; auto decResult = decJob->exec(cipherText, plainText); diff --git a/lang/qt/tests/t-import.cpp b/lang/qt/tests/t-import.cpp new file mode 100644 index 0000000..33e242f --- /dev/null +++ b/lang/qt/tests/t-import.cpp @@ -0,0 +1,169 @@ +/* t-import.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2021 g10 Code GmbH + Software engineering by Ingo Klöcker <dev@ingo-kloecker.de> + + 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 "t-support.h" + +#include "context.h" +#include "engineinfo.h" +#include "protocol.h" +#include "importjob.h" + +#include <importresult.h> + +#include <QDebug> +#include <QSignalSpy> +#include <QTemporaryDir> +#include <QTest> + +using namespace QGpgME; +using namespace GpgME; + +class ImportTest : public QGpgMETest +{ + Q_OBJECT + +private: + QTemporaryDir tempGpgHome; + +private Q_SLOTS: + void initTestCase() + { + QGpgMETest::initTestCase(); + QVERIFY2(tempGpgHome.isValid(), "Failed to create temporary GNUPGHOME"); + qputenv("GNUPGHOME", tempGpgHome.path().toLocal8Bit()); + } + + void testImportWithImportFilter() + { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.14") { + QSKIP("gpg does not yet support the --import-filter option"); + } + + // pub ed25519 2021-12-15 [SC] + // E7A0841292ACC9465D3142652FB3A6F51FBF28A2 + // uid [ultimate] importWithImportFilter@example.com + // uid [ultimate] importWithImportFilter@example.net + // sub cv25519 2021-12-15 [E] + static const char keyFpr[] = "E7A0841292ACC9465D3142652FB3A6F51FBF28A2"; + static const char keyData[] = + "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + "\n" + "mDMEYbm2PhYJKwYBBAHaRw8BAQdACzxBWtNNsmJ6rzpZkjh1yBe+Ajsk9NR8umEu\n" + "Da3HLgG0ImltcG9ydFdpdGhJbXBvcnRGaWx0ZXJAZXhhbXBsZS5uZXSIlAQTFgoA\n" + "PBYhBOeghBKSrMlGXTFCZS+zpvUfvyiiBQJhubY+AhsDBQsJCAcCAyICAQYVCgkI\n" + "CwIEFgIDAQIeBwIXgAAKCRAvs6b1H78oosRgAQCc/ke6q076nvzIE2UzT83JK/B6\n" + "lxSV7Fb8bKltOMpvsAD+Phap3EzA8jdMyKoO0FM926bw5lX7QROfeZ/JBYqyPwC0\n" + "ImltcG9ydFdpdGhJbXBvcnRGaWx0ZXJAZXhhbXBsZS5jb22IlAQTFgoAPBYhBOeg\n" + "hBKSrMlGXTFCZS+zpvUfvyiiBQJhubZlAhsDBQsJCAcCAyICAQYVCgkICwIEFgID\n" + "AQIeBwIXgAAKCRAvs6b1H78oohPWAQC/u9UXzkxRkrB2huaTZCsyimWEGZIMmxWd\n" + "tE+vN9/IvQD/Yzia+xRS6yca3Yz6iW8xS844ZqRxvkUEHjtJXSOzagm4OARhubY+\n" + "EgorBgEEAZdVAQUBAQdANQFjmDctY3N0/ELPZtj9tapwFs4vrmTVpx/SCfZmihkD\n" + "AQgHiHgEGBYKACAWIQTnoIQSkqzJRl0xQmUvs6b1H78oogUCYbm2PgIbDAAKCRAv\n" + "s6b1H78oovGyAP41ySzvvDpV7XDJBOAFxvWLmywa5IcO7Lrg7y1efoWj0AD+Kk/B\n" + "s7jGLdoG51h670h50MMoYCANB6MwAdSP+qZUlQg=\n" + "=/3O0\n" + "-----END PGP PUBLIC KEY BLOCK-----\n"; + + auto *job = openpgp()->importJob(); + job->setImportFilter(QLatin1String{"keep-uid=mbox = importWithImportFilter@example.net"}); + connect(job, &ImportJob::result, this, + [this](ImportResult result, QString, Error) + { + QVERIFY(!result.error()); + QVERIFY(!result.imports().empty()); + QVERIFY(result.numImported()); + Q_EMIT asyncDone(); + }); + job->start(QByteArray{keyData}); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait()); + + auto ctx = Context::createForProtocol(GpgME::OpenPGP); + GpgME::Error err; + const auto key = ctx->key(keyFpr, err, false); + QVERIFY(!key.isNull()); + QCOMPARE(key.numUserIDs(), 1); + QCOMPARE(key.userID(0).id(), "importWithImportFilter@example.net"); + } + + void testImportWithKeyOrigin() + { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.22") { + QSKIP("gpg does not yet support the --key-origin option"); + } + + static const char keyFpr[] = "5C5C428FABCC20F6913464BCCA6FB442887289B3"; + static const char keyData[] = + "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + "\n" + "mDMEYbhuixYJKwYBBAHaRw8BAQdAulOM3IksCjdOJluEVlwalD8oZ5oa6wCw3EgW\n" + "NswXXb60H2ltcG9ydFdpdGhLZXlPcmlnaW5AZXhhbXBsZS5uZXSIlAQTFgoAPBYh\n" + "BFxcQo+rzCD2kTRkvMpvtEKIcomzBQJhuG6LAhsDBQsJCAcCAyICAQYVCgkICwIE\n" + "FgIDAQIeBwIXgAAKCRDKb7RCiHKJs+cIAQDaeoOw1OCAGpZQb8xJmLJHul5dLLzU\n" + "RBdHauMx9NROmQEA23QUVedc7walQjNKFzyIJA/YqRdbAKPiLonRBmxk9Ay4OARh\n" + "uG6LEgorBgEEAZdVAQUBAQdAMVdO9mNWIP/q8PtNOnBGlPyhx/vs07sF5sXk50A+\n" + "61QDAQgHiHgEGBYKACAWIQRcXEKPq8wg9pE0ZLzKb7RCiHKJswUCYbhuiwIbDAAK\n" + "CRDKb7RCiHKJs/x6AP0SEbZqW4iLCz2i1JntQghK5qpSZOVqsBTcARd6pcJ/cwEA\n" + "mrwskWazuS9+GVbHT5RATWOXnGaj+AICSDPE6qHtGgA=\n" + "=putz\n" + "-----END PGP PUBLIC KEY BLOCK-----\n"; + + auto *job = openpgp()->importJob(); + job->setKeyOrigin(GpgME::Key::OriginWKD, "https://example.net"); + connect(job, &ImportJob::result, this, + [this](ImportResult result, QString, Error) + { + QVERIFY(!result.error()); + QVERIFY(!result.imports().empty()); + QVERIFY(result.numImported()); + Q_EMIT asyncDone(); + }); + job->start(QByteArray{keyData}); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait()); + + auto ctx = Context::createForProtocol(GpgME::OpenPGP); + GpgME::Error err; + const auto key = ctx->key(keyFpr, err, false); + QVERIFY(!key.isNull()); + QVERIFY(key.origin() == Key::OriginWKD); + // the origin URL is currently not available in GpgME + } +}; + +QTEST_MAIN(ImportTest) + +#include "t-import.moc" diff --git a/lang/qt/tests/t-keylist.cpp b/lang/qt/tests/t-keylist.cpp index 5875dfb..e481dfe 100644 --- a/lang/qt/tests/t-keylist.cpp +++ b/lang/qt/tests/t-keylist.cpp @@ -57,9 +57,6 @@ class KeyListTest : public QGpgMETest { Q_OBJECT -Q_SIGNALS: - void asyncDone(); - private Q_SLOTS: void testSingleKeyListSync() { @@ -151,7 +148,7 @@ private Q_SLOTS: delete job; QVERIFY(!result.error()); - QCOMPARE(secKeys.size(), 2u); + QCOMPARE(secKeys.size(), static_cast<decltype(secKeys.size())>(2)); std::vector<std::string> secKeyFingerprints = std::accumulate(secKeys.begin(), secKeys.end(), std::vector<std::string>(), accumulateFingerprints); QCOMPARE(secKeyFingerprints, std::vector<std::string>({ "23FD347A419429BACCD5E72D6BC4778054ACD246", @@ -162,7 +159,7 @@ private Q_SLOTS: QVERIFY(secKeys[0].subkeys()[0].keyGrip()); } - QCOMPARE(pubKeys.size(), 26u); + QCOMPARE(pubKeys.size(), static_cast<decltype(pubKeys.size())>(26)); std::vector<std::string> pubKeyFingerprints = std::accumulate(pubKeys.begin(), pubKeys.end(), std::vector<std::string>(), accumulateFingerprints); QCOMPARE(pubKeyFingerprints, std::vector<std::string>({ "045B2334ADD69FC221076841A5E67F7FA3AE3EA1", diff --git a/lang/qt/tests/t-keylocate.cpp b/lang/qt/tests/t-keylocate.cpp index 6d00da3..d84249c 100644 --- a/lang/qt/tests/t-keylocate.cpp +++ b/lang/qt/tests/t-keylocate.cpp @@ -51,9 +51,6 @@ class KeyLocateTest : public QGpgMETest { Q_OBJECT -Q_SIGNALS: - void asyncDone(); - private Q_SLOTS: #ifdef DO_ONLINE_TESTS diff --git a/lang/qt/tests/t-ownertrust.cpp b/lang/qt/tests/t-ownertrust.cpp index 093c21e..31d2247 100644 --- a/lang/qt/tests/t-ownertrust.cpp +++ b/lang/qt/tests/t-ownertrust.cpp @@ -51,9 +51,6 @@ class ChangeOwnerTrustTest: public QGpgMETest { Q_OBJECT -Q_SIGNALS: - void asyncDone(); - private Q_SLOTS: void testChangeOwnerTrust() diff --git a/lang/qt/tests/t-remarks.cpp b/lang/qt/tests/t-remarks.cpp index c1880a7..f9a901a 100644 --- a/lang/qt/tests/t-remarks.cpp +++ b/lang/qt/tests/t-remarks.cpp @@ -54,9 +54,6 @@ class TestRemarks: public QGpgMETest { Q_OBJECT -Q_SIGNALS: - void asyncDone(); - public: // This test is disabled (no slot) because the behavior // is not clearly defined. Better to prevent that @@ -77,12 +74,7 @@ public: // Create the job auto job = openpgp()->signKeyJob(); QVERIFY (job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(false); @@ -133,12 +125,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob(); QVERIFY (job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(true); @@ -170,11 +157,7 @@ private Q_SLOTS: // Now replace the remark auto job3 = openpgp()->signKeyJob(); QVERIFY (job3); - - // Hack in the passphrase provider - auto jobCtx3 = Job::context(job3); - jobCtx3->setPassphraseProvider(&provider); - jobCtx3->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job3); // Setup the job job3->setExportable(false); @@ -229,12 +212,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob(); QVERIFY (job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the first job job->setExportable(false); @@ -257,11 +235,7 @@ private Q_SLOTS: // Now another remark from zulu auto job3 = openpgp()->signKeyJob(); QVERIFY (job3); - - // Hack in the passphrase provider - auto jobCtx3 = Job::context(job3); - jobCtx3->setPassphraseProvider(&provider); - jobCtx3->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job3); // Setup the job job3->setExportable(false); @@ -315,12 +289,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob(); QVERIFY (job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(false); @@ -352,11 +321,7 @@ private Q_SLOTS: // Now replace the remark auto job3 = openpgp()->signKeyJob(); QVERIFY (job3); - - // Hack in the passphrase provider - auto jobCtx3 = Job::context(job3); - jobCtx3->setPassphraseProvider(&provider); - jobCtx3->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job3); // Setup the job job3->setExportable(false); @@ -405,12 +370,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob(); QVERIFY (job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(false); @@ -441,11 +401,7 @@ private Q_SLOTS: // Try to replace it without dupeOK auto job2 = openpgp()->signKeyJob(); QVERIFY (job2); - - // Hack in the passphrase provider - auto jobCtx2 = Job::context(job2); - jobCtx2->setPassphraseProvider(&provider); - jobCtx2->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job2); // Setup the job job2->setExportable(false); @@ -466,11 +422,7 @@ private Q_SLOTS: // Now replace the remark auto job3 = openpgp()->signKeyJob(); QVERIFY (job3); - - // Hack in the passphrase provider - auto jobCtx3 = Job::context(job3); - jobCtx3->setPassphraseProvider(&provider); - jobCtx3->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job3); // Setup the job job3->setExportable(false); diff --git a/lang/qt/tests/t-support.cpp b/lang/qt/tests/t-support.cpp index 7b16ccc..6db082f 100644 --- a/lang/qt/tests/t-support.cpp +++ b/lang/qt/tests/t-support.cpp @@ -35,7 +35,10 @@ #endif #include "t-support.h" -#include "context.h" + +#include "importjob.h" +#include "job.h" +#include "protocol.h" #include <QTest> @@ -43,8 +46,14 @@ #include <QCoreApplication> #include <QObject> #include <QDir> +#include <QSignalSpy> +#include "context.h" #include "engineinfo.h" +#include "importresult.h" + +using namespace GpgME; +using namespace QGpgME; void QGpgMETest::initTestCase() { @@ -59,6 +68,12 @@ void QGpgMETest::cleanupTestCase() killAgent(); } +// static +bool QGpgMETest::doOnlineTests() +{ + return !qgetenv("DO_ONLINE_TESTS").isEmpty(); +} + bool QGpgMETest::copyKeyrings(const QString &src, const QString &dest) { bool is21dir = QFileInfo(src + QDir::separator() + QStringLiteral("pubring.kbx")).exists(); @@ -86,6 +101,41 @@ bool QGpgMETest::copyKeyrings(const QString &src, const QString &dest) return true; } +bool QGpgMETest::importSecretKeys(const char *keyData, int expectedKeys) +{ + auto job = std::unique_ptr<ImportJob>{openpgp()->importJob()}; + VERIFY_OR_FALSE(job); + hookUpPassphraseProvider(job.get()); + + ImportResult result; + connect(job.get(), &ImportJob::result, + this, [this, &result](const ImportResult &result_) { + result = result_; + Q_EMIT asyncDone(); + }); + VERIFY_OR_FALSE(!job->start(keyData)); + job.release(); // after the job has been started it's on its own + + QSignalSpy spy (this, SIGNAL(asyncDone())); + VERIFY_OR_FALSE(spy.wait(QSIGNALSPY_TIMEOUT)); + VERIFY_OR_FALSE(!result.error()); + VERIFY_OR_FALSE(!result.imports().empty()); + COMPARE_OR_FALSE(result.numSecretKeysImported(), expectedKeys); + + return true; +} + +void QGpgMETest::hookUpPassphraseProvider(GpgME::Context *context) +{ + context->setPassphraseProvider(&mPassphraseProvider); + context->setPinentryMode(Context::PinentryLoopback); +} + +void QGpgMETest::hookUpPassphraseProvider(QGpgME::Job *job) +{ + hookUpPassphraseProvider(Job::context(job)); +} + void killAgent(const QString& dir) { QProcess proc; diff --git a/lang/qt/tests/t-support.h b/lang/qt/tests/t-support.h index 77bef56..ecafe2f 100644 --- a/lang/qt/tests/t-support.h +++ b/lang/qt/tests/t-support.h @@ -34,11 +34,57 @@ #include "interfaces/passphraseprovider.h" #include <QObject> +#include <QTest> #include <gpg-error.h> namespace GpgME { +class Context; +} + +namespace QGpgME +{ +class Job; +} + +/// generic variant of QVERIFY returning \a returnValue on failure +#define VERIFY_OR_RETURN_VALUE(statement, returnValue) \ +do {\ + if (!QTest::qVerify(static_cast<bool>(statement), #statement, "", __FILE__, __LINE__))\ + return returnValue;\ +} while (false) + +/// generic variant of QCOMPARE returning \a returnValue on failure +#define COMPARE_OR_RETURN_VALUE(actual, expected, returnValue) \ +do {\ + if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\ + return returnValue;\ +} while (false) + +/// variant of QVERIFY returning a default constructed object on failure +#define VERIFY_OR_OBJECT(statement) VERIFY_OR_RETURN_VALUE(statement, {}) + +/// variant of QCOMPARE returning a default constructed object on failure +#define COMPARE_OR_OBJECT(actual, expected) COMPARE_OR_RETURN_VALUE(actual, expected, {}) + +/// variant of QVERIFY returning \c false on failure +#define VERIFY_OR_FALSE(statement) VERIFY_OR_RETURN_VALUE(statement, false) + +/// variant of QCOMPARE returning \c false on failure +#define COMPARE_OR_FALSE(actual, expected) COMPARE_OR_RETURN_VALUE(actual, expected, false) + +namespace QTest +{ +template <> +inline char *toString(const std::string &s) +{ + return QTest::toString(s.c_str()); +} +} + +namespace GpgME +{ class TestPassphraseProvider : public PassphraseProvider { public: @@ -59,12 +105,26 @@ bool loopbackSupported(); class QGpgMETest : public QObject { Q_OBJECT + +Q_SIGNALS: + void asyncDone(); + protected: + static bool doOnlineTests(); + bool copyKeyrings(const QString &from, const QString& to); + bool importSecretKeys(const char *keyData, int expectedKeys = 1); + + void hookUpPassphraseProvider(GpgME::Context *context); + void hookUpPassphraseProvider(QGpgME::Job *job); + public Q_SLOTS: void initTestCase(); void cleanupTestCase(); + +private: + GpgME::TestPassphraseProvider mPassphraseProvider; }; /* Timeout, in milliseconds, for use with QSignalSpy to wait on diff --git a/lang/qt/tests/t-tofuinfo.cpp b/lang/qt/tests/t-tofuinfo.cpp index 2d88106..a1871c4 100644 --- a/lang/qt/tests/t-tofuinfo.cpp +++ b/lang/qt/tests/t-tofuinfo.cpp @@ -116,8 +116,6 @@ static const char conflictMsg2[] = "-----BEGIN PGP MESSAGE-----\n" class TofuInfoTest: public QGpgMETest { Q_OBJECT -Q_SIGNALS: - void asyncDone(); private: bool testSupported() @@ -155,10 +153,7 @@ private: void signAndVerify(const QString &what, const GpgME::Key &key, int expected) { auto job = openpgp()->signJob(); - auto ctx = Job::context(job); - TestPassphraseProvider provider; - ctx->setPassphraseProvider(&provider); - ctx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); std::vector<Key> keys; keys.push_back(key); diff --git a/lang/qt/tests/t-trustsignatures.cpp b/lang/qt/tests/t-trustsignatures.cpp index d392b2f..6f7ad82 100644 --- a/lang/qt/tests/t-trustsignatures.cpp +++ b/lang/qt/tests/t-trustsignatures.cpp @@ -1,4 +1,4 @@ -/* t-remarks.cpp +/* t-trustsignatures.cpp This file is part of qgpgme, the Qt API binding for gpgme Copyright (c) 2021 g10 Code GmbH @@ -52,9 +52,6 @@ class TestTrustSignatures: public QGpgMETest { Q_OBJECT -Q_SIGNALS: - void asyncDone(); - private Q_SLOTS: void test_tsign_single_uid_key_and_then_tsign_it_again() { @@ -83,12 +80,7 @@ private Q_SLOTS: // Create the job auto job = std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job.get()); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job.get()); // Setup the job job->setExportable(true); @@ -131,12 +123,7 @@ private Q_SLOTS: // Create the job auto job = std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job.get()); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job.get()); // Setup the job job->setExportable(true); @@ -204,12 +191,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob();//std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(true); @@ -252,12 +234,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob();//std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(true); @@ -325,12 +302,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob();//std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(true); @@ -374,12 +346,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob();//std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(true); @@ -447,12 +414,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob();//std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(true); @@ -495,12 +457,7 @@ private Q_SLOTS: // Create the job auto job = openpgp()->signKeyJob();//std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job); // Setup the job job->setExportable(true); diff --git a/lang/qt/tests/t-various.cpp b/lang/qt/tests/t-various.cpp index 8563b68..b630350 100644 --- a/lang/qt/tests/t-various.cpp +++ b/lang/qt/tests/t-various.cpp @@ -71,9 +71,6 @@ class TestVarious: public QGpgMETest { Q_OBJECT -Q_SIGNALS: - void asyncDone(); - private Q_SLOTS: void testDN() { @@ -137,9 +134,7 @@ private Q_SLOTS: auto ctx = Context::createForProtocol(key.protocol()); QVERIFY (ctx); - TestPassphraseProvider provider; - ctx->setPassphraseProvider(&provider); - ctx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(ctx); QVERIFY(!ctx->addUid(key, uid)); delete ctx; @@ -190,9 +185,7 @@ private Q_SLOTS: auto ctx = Context::createForProtocol(key.protocol()); QVERIFY (ctx); - TestPassphraseProvider provider; - ctx->setPassphraseProvider(&provider); - ctx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(ctx); // change expiration of the main key QVERIFY(!ctx->setExpire(key, 1000)); @@ -230,7 +223,7 @@ private Q_SLOTS: std::vector<Subkey> primaryKey; primaryKey.push_back(key.subkey(0)); const auto err = ctx->setExpire(key, 3000, primaryKey); - QCOMPARE(err.code(), GPG_ERR_NOT_FOUND); + QCOMPARE(err.code(), static_cast<int>(GPG_ERR_NOT_FOUND)); delete ctx; } @@ -259,12 +252,7 @@ private Q_SLOTS: // Create the job auto job = std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job.get()); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job.get()); // Setup the job job->setExportable(true); @@ -319,12 +307,7 @@ private Q_SLOTS: // Create the job auto job = std::unique_ptr<SignKeyJob>{openpgp()->signKeyJob()}; QVERIFY(job); - - // Hack in the passphrase provider - auto jobCtx = Job::context(job.get()); - TestPassphraseProvider provider; - jobCtx->setPassphraseProvider(&provider); - jobCtx->setPinentryMode(Context::PinentryLoopback); + hookUpPassphraseProvider(job.get()); // Setup the job job->setExportable(true); @@ -355,7 +338,7 @@ private Q_SLOTS: target.update(); const auto keySignature = target.userID(0).signature(target.userID(0).numSignatures() - 1); QVERIFY(!keySignature.neverExpires()); - const auto expirationDate = QDateTime::fromSecsSinceEpoch(keySignature.expirationTime()).date(); + const auto expirationDate = QDateTime::fromSecsSinceEpoch(uint_least32_t(keySignature.expirationTime())).date(); QCOMPARE(expirationDate, QDate(2106, 2, 6)); // expiration date is capped at 2106-02-06 } diff --git a/lang/qt/tests/t-wkdlookup.cpp b/lang/qt/tests/t-wkdlookup.cpp new file mode 100644 index 0000000..5c2816c --- /dev/null +++ b/lang/qt/tests/t-wkdlookup.cpp @@ -0,0 +1,155 @@ +/* t-wkdlookup.cpp + + This file is part of qgpgme, the Qt API binding for gpgme + Copyright (c) 2021 g10 Code GmbH + Software engineering by Ingo Klöcker <dev@ingo-kloecker.de> + + 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 "t-support.h" + +#include "data.h" +#include "engineinfo.h" +#include "protocol.h" +#include "wkdlookupjob.h" +#include "wkdlookupresult.h" + +#include <QDebug> +#include <QSignalSpy> +#include <QTest> + +#include <algorithm> + +using namespace QGpgME; +using namespace GpgME; + +static const char *requiredVersion = "2.1.12"; + +namespace +{ +bool keyHasUserIDWithMatchingEmailAddress(const Key &key, const QString &expectedEmailAddress) +{ + const auto email = expectedEmailAddress.toLower(); + const auto userIds = key.userIDs(); + return std::any_of( + std::begin(userIds), std::end(userIds), + [email](const UserID &uid) { + return email == QString::fromUtf8(uid.email()).toLower(); + }); +} +} + +class WKDLookupTest : public QGpgMETest +{ + Q_OBJECT + +private Q_SLOTS: + + void testWKDLookupAsync() + { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < requiredVersion) { + QSKIP("dirmngr does not yet support WKD lookup"); + } + if (!doOnlineTests()) { + QSKIP("Set DO_ONLINE_TESTS environment variable to run this test."); + } + const QString email = QLatin1String{"wk@gnupg.org"}; + + WKDLookupResult result; + auto *job = openpgp()->wkdLookupJob(); + connect(job, &WKDLookupJob::result, job, [this, &result](const WKDLookupResult &result_, const QString &, const Error &) + { + result = result_; + Q_EMIT asyncDone(); + }); + job->start(email); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT)); + + QVERIFY(result.error().code() == GPG_ERR_NO_ERROR); + QCOMPARE(result.pattern(), "wk@gnupg.org"); + QCOMPARE(result.source(), "https://openpgpkey.gnupg.org"); + const auto keys = result.keyData().toKeys(GpgME::OpenPGP); + QVERIFY(keys.size() == 1); + QVERIFY(keyHasUserIDWithMatchingEmailAddress(keys.front(), email)); + } + + void testWKDLookupSync() + { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < requiredVersion) { + QSKIP("dirmngr does not yet support WKD lookup"); + } + if (!doOnlineTests()) { + QSKIP("Set DO_ONLINE_TESTS environment variable to run this test."); + } + const QString email = QLatin1String{"wk@gnupg.org"}; + + auto *job = openpgp()->wkdLookupJob(); + const auto result = job->exec(email); + + QVERIFY(result.error().code() == GPG_ERR_NO_ERROR); + QCOMPARE(result.pattern(), "wk@gnupg.org"); + QCOMPARE(result.source(), "https://openpgpkey.gnupg.org"); + const auto keys = result.keyData().toKeys(GpgME::OpenPGP); + QVERIFY(keys.size() == 1); + QVERIFY(keyHasUserIDWithMatchingEmailAddress(keys.front(), email)); + } + + void testLookupWithNoResultAsync() + { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < requiredVersion) { + QSKIP("dirmngr does not yet support WKD lookup"); + } + if (!doOnlineTests()) { + QSKIP("Set DO_ONLINE_TESTS environment variable to run this test."); + } + const QString email = QLatin1String{"alfa@example.net"}; + + WKDLookupResult result; + auto *job = openpgp()->wkdLookupJob(); + connect(job, &WKDLookupJob::result, job, [this, &result](const WKDLookupResult &result_, const QString &, const Error &) + { + result = result_; + Q_EMIT asyncDone(); + }); + job->start(email); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT)); + + QVERIFY(result.error().code() == GPG_ERR_NO_ERROR); + QCOMPARE(result.pattern(), "alfa@example.net"); + QCOMPARE(result.source(), ""); + QVERIFY(result.keyData().isNull()); + } +}; + +QTEST_MAIN(WKDLookupTest) + +#include "t-wkdlookup.moc" diff --git a/lang/qt/tests/t-wkspublish.cpp b/lang/qt/tests/t-wkspublish.cpp index b389194..618f0b4 100644 --- a/lang/qt/tests/t-wkspublish.cpp +++ b/lang/qt/tests/t-wkspublish.cpp @@ -118,9 +118,6 @@ class WKSPublishTest : public QGpgMETest { Q_OBJECT -Q_SIGNALS: - void asyncDone(); - private Q_SLOTS: void testUnsupported() { |