diff --git a/cmake/modules/kdepim_add_gpg_crypto_test.cmake b/cmake/modules/kdepim_add_gpg_crypto_test.cmake new file mode 100644 index 00000000..66504240 --- /dev/null +++ b/cmake/modules/kdepim_add_gpg_crypto_test.cmake @@ -0,0 +1,59 @@ +# Copyright (c) 2013 Sandro Knauß +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +set( GNUPGHOME ${CMAKE_BINARY_DIR}/plugins/messageviewer/bodypartformatter/autotests/gnupg_home ) + +macro (ADD_GPG_CRYPTO_TEST _target _testname) + if (UNIX) + if (APPLE) + set(_library_path_variable "DYLD_LIBRARY_PATH") + elseif (CYGWIN) + set(_library_path_variable "PATH") + else (APPLE) + set(_library_path_variable "LD_LIBRARY_PATH") + endif (APPLE) + + if (APPLE) + # DYLD_LIBRARY_PATH does not work like LD_LIBRARY_PATH + # OSX already has the RPATH in libraries and executables, putting runtime directories in + # DYLD_LIBRARY_PATH actually breaks things + set(_ld_library_path "${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/") + else (APPLE) + set(_ld_library_path "${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/:${LIB_INSTALL_DIR}:${QT_LIBRARY_DIR}") + endif (APPLE) + set(_executable "$") + + # use add_custom_target() to have the sh-wrapper generated during build time instead of cmake time + add_custom_command(TARGET ${_target} POST_BUILD + COMMAND ${CMAKE_COMMAND} + -D_filename=${_executable}.shell -D_library_path_variable=${_library_path_variable} + -D_ld_library_path="${_ld_library_path}" -D_executable=$ + -D_gnupghome="${GNUPGHOME}" + -P ${CMAKE_SOURCE_DIR}/cmake/modules/kdepim_generate_crypto_test_wrapper.cmake + ) + + set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${_executable}.shell" ) + add_test(NAME ${_testname} COMMAND ${_executable}.shell) + + else (UNIX) + # under windows, set the property WRAPPER_SCRIPT just to the name of the executable + # maybe later this will change to a generated batch file (for setting the PATH so that the Qt libs are found) + set(_ld_library_path "${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}\;${LIB_INSTALL_DIR}\;${QT_LIBRARY_DIR}") + set(_executable "$") + + # use add_custom_target() to have the batch-file-wrapper generated during build time instead of cmake time + add_custom_command(TARGET ${_target} POST_BUILD + COMMAND ${CMAKE_COMMAND} + -D_filename="${_executable}.bat" + -D_ld_library_path="${_ld_library_path}" -D_executable="${_executable}" + -D_gnupghome="${GNUPGHOME}" + -P ${CMAKE_SOURCE_DIR}/cmake/modules/kdepim_generate_crypto_test_wrapper.cmake + ) + + add_test(NAME ${_testname} COMMAND ${_executable}.bat) + + endif (UNIX) +endmacro (ADD_GPG_CRYPTO_TEST) + diff --git a/cmake/modules/kdepim_generate_crypto_test_wrapper.cmake b/cmake/modules/kdepim_generate_crypto_test_wrapper.cmake new file mode 100644 index 00000000..13ad5e85 --- /dev/null +++ b/cmake/modules/kdepim_generate_crypto_test_wrapper.cmake @@ -0,0 +1,53 @@ +# Copyright (c) 2006, Alexander Neundorf, +# Copyright (c) 2013, Sandro Knauß +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +if (UNIX) + +file(WRITE "${_filename}" +"#!/bin/sh +# created by cmake, don't edit, changes will be lost + +# don't mess with a gpg-agent already running on the system +unset GPG_AGENT_INFO + +# _gnupghome will contain a socket, and the path to that has a length limit of 108 chars +# which that is easily reached. Therefore shorten this by copying this to a temporary dir. +# This has the convenient side-effect that modifications to the content are not propagated +# to other tests. +tmp_dir=`mktemp -d -t messagelib-test-gnupg-home.XXXXXXXX` || exit 1 +cp -rf ${_gnupghome}/* $tmp_dir + +${_library_path_variable}=${_ld_library_path}\${${_library_path_variable}:+:\$${_library_path_variable}} GNUPGHOME=$tmp_dir gpg-agent --daemon \"${_executable}\" \"$@\" +_result=$? +_pid=`echo GETINFO pid | GNUPGHOME=$tmp_dir gpg-connect-agent | grep 'D' | cut -d' ' -f2` +if [ ! -z \"\$_pid\" ]; then + echo \"Waiting for gpg-agent to terminate (PID: $_pid)...\" + while kill -0 \"\$_pid\"; do + sleep 1 + done +fi +rm -rf $tmp_dir +exit \$_result +") + +# make it executable +# since this is only executed on UNIX, it is safe to call chmod +exec_program(chmod ARGS ug+x \"${_filename}\" OUTPUT_VARIABLE _dummy ) + +else (UNIX) + +file(TO_NATIVE_PATH "${_ld_library_path}" win_path) +file(TO_NATIVE_PATH "${_gnupghome}" win_gnupghome) + +file(WRITE "${_filename}" +" +set PATH=${win_path};$ENV{PATH} +set GNUPGHOME=${win_gnupghome};$ENV{GNUPGHOME} +gpg-agent --daemon \"${_executable}\" %* +") + +endif (UNIX) diff --git a/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt b/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt index 837338d5..e909d898 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt +++ b/plugins/messageviewer/bodypartformatter/autotests/CMakeLists.txt @@ -1,54 +1,58 @@ set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) add_definitions( -DMAIL_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data" ) add_definitions( -DDIFF_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/diffdata" ) -macro(add_kdepimaddons_unittest _source) +include(${CMAKE_SOURCE_DIR}/cmake/modules/kdepim_add_gpg_crypto_test.cmake) +add_subdirectory(gnupg_home) + +macro(add_kdepimaddons_crypto_unittest _source) set(_test ${_source}) get_filename_component(_name ${_source} NAME_WE) - ecm_add_test(${_source} - TEST_NAME ${_name} - NAME_PREFIX "messageviewerplugins-" - LINK_LIBRARIES + add_executable( ${_name} ${_source}) + target_link_libraries( ${_name} KF5::MessageViewer Qt5::Test KF5::IconThemes ) + add_gpg_crypto_test(${_name} messageviewerplugins-${_name}) + ecm_mark_as_test(messageviewerplugins-${_name}) endmacro () -add_kdepimaddons_unittest(rendertest.cpp) + +add_kdepimaddons_crypto_unittest(rendertest.cpp) macro(add_messageviewer_bodyformatter_class_unittest _source _additional) set( _test ${_source} ${common_SRCS} ${_additional}) get_filename_component(_name ${_source} NAME_WE) ecm_add_test(${_test} TEST_NAME ${_name} NAME_PREFIX "messageviewerplugins-" LINK_LIBRARIES KF5::MessageViewer Qt5::Test KF5::PimTextEdit KF5::I18n KF5::Completion KF5::LibkdepimAkonadi ) endmacro () add_messageviewer_bodyformatter_class_unittest(reactiontoinvitationdialogtest.cpp "../calendar/reactiontoinvitationdialog.cpp") add_messageviewer_bodyformatter_class_unittest(delegateselectortest.cpp "../calendar/delegateselector.cpp") macro(add_diff_bodyformatter_class_unittest _source _additional) set( _test ${_source} ${common_SRCS} ${_additional}) get_filename_component(_name ${_source} NAME_WE) ecm_add_test(${_test} TEST_NAME ${_name} NAME_PREFIX "messageviewerplugins-" LINK_LIBRARIES KF5::MessageViewer Qt5::Test KF5::PimTextEdit KF5::I18n KF5::SyntaxHighlighting ) endmacro () add_diff_bodyformatter_class_unittest(diffhighlightertest.cpp "../highlighter/highlighter.cpp") add_definitions(-DSOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" ) include_directories(${CMAKE_CURRENT_BINARY_DIR}/../semantic/) ecm_add_test( structureddataextractortest.cpp ${CMAKE_CURRENT_BINARY_DIR}/../semantic/semantic_debug.cpp TEST_NAME structureddataextractortest NAME_PREFIX "messageviewerplugins" LINK_LIBRARIES Qt5::Test ) diff --git a/plugins/messageviewer/bodypartformatter/autotests/data/message-with-openpgp-key.mbox.html.details b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-openpgp-key.mbox.html.details new file mode 100644 index 00000000..67e81590 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-openpgp-key.mbox.html.details @@ -0,0 +1,67 @@ + + + + + + + diff --git a/plugins/messageviewer/bodypartformatter/autotests/data/message-with-openpgp-key.mbox.html.running b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-openpgp-key.mbox.html.running new file mode 100644 index 00000000..f0e81185 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-openpgp-key.mbox.html.running @@ -0,0 +1,67 @@ + + + + + + + diff --git a/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox new file mode 100644 index 00000000..119d8b3d --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox @@ -0,0 +1,717 @@ +From keysender@kde.org Sun Nov 20 13:00:00 2017 +Subject:One vaild key, that exitis in keyring and one invalid +To: =?UTF-8?Q?Sandro_Knau=c3=9f?= +From: keysender@kde.org +Message-ID: +Date: Sun, 20 Nov 2017 13:00:00 +0100 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------2B654679356396FC66556C4C" + + This is a multi-part message in MIME format. +--------------2B654679356396FC66556C4C +Content-Type: text/plain; charset=windows-1252 +Content-Transfer-Encoding: quoted-printable + +The first atachment is a key that exists in local keyring. +The second attachment is a file with invalid keymaterial. + + +--------------2B654679356396FC66556C4C +Content-Type: application/pgp-keys; + name="0xE3ADB00850605636.asc" +Content-Transfer-Encoding: quoted-printable +Content-Disposition: attachment; + filename="0xE3ADB00850605636.asc" + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +8g== +=AjoZ +-----END PGP PUBLIC KEY BLOCK----- + +--------------2B654679356396FC66556C4C +Content-Type: application/pgp-keys; + name="0xFFFFFFFF-invalid.asc" +Content-Transfer-Encoding: quoted-printable +Content-Disposition: attachment; + filename="0xFFFFFFFF-invalid.asc" + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +9WKwJ8frjycUW+KNKKs08PqE50bPHMSbA03/oog9fnGZOWAizMRpo+WsIwdFVBi6 +f/Wl2J7y4KXjGPE79130NPTtRTDo8odD4FXc6ymQG9X4qw9d8c5Dl23LNDt1v4vd +ft2z+2JCMbN8bxiAj1IDURT1yf1DwRzKxoN0MLQbTT2I2z9r+Dwd4mkxHvXN/PZG +Usv6RDCHtV+yKgpckE7JDkLDCEZDiMjaIUPEc/YE6sIwvN/H0omfou92w9hpQbjA +ZCgc1/PGAj8Att/LCGjcZP9b8WMh9d243oFEUVR+9ADEu+YMfN5NFLC963AjOe5G +RhMiUHfGmsPfvyZJLJvpRlUWEIpM8hS1wbsIYIKp2aRuRzLfbYggcmhWpjXQuCJJ +g7i8ttsJXuXI5QcTb6+b +=3DlNiu +-----END PGP PUBLIC KEY BLOCK----- + +--------------2B654679356396FC66556C4C-- + diff --git a/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox.html b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox.html new file mode 100644 index 00000000..4d060c90 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox.html @@ -0,0 +1,64 @@ + + + + + + + diff --git a/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox.html.details b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox.html.details new file mode 100644 index 00000000..a8497142 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox.html.details @@ -0,0 +1,65 @@ + + + + +
+ + +
+ + diff --git a/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox.html.running b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox.html.running new file mode 100644 index 00000000..9845790b --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/data/message-with-two-openpgp-key.mbox.html.running @@ -0,0 +1,64 @@ + + + + +
+ + +
+ + diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/CMakeLists.txt b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/CMakeLists.txt new file mode 100644 index 00000000..9c64a008 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/CMakeLists.txt @@ -0,0 +1,10 @@ +configure_file( gpg-agent.conf.in + "${CMAKE_CURRENT_BINARY_DIR}/gpg-agent.conf" @ONLY ) + +configure_file( gpgsm.conf.in + "${CMAKE_CURRENT_BINARY_DIR}/gpgsm.conf" @ONLY ) + +file( COPY + ${CMAKE_CURRENT_SOURCE_DIR} + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/../" +) diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr-cache.d/DIR.txt b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr-cache.d/DIR.txt new file mode 100644 index 00000000..1a45a6b3 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr-cache.d/DIR.txt @@ -0,0 +1,3 @@ +v:1: +c:4E31CEB57DDD4A7B9991AB05507B1ED4293FF952:CN=Test-ZS 7,O=Intevation GmbH,C=DE:ldap%3A//ca.intevation.org/cn=Test-ZS 7, o=Intevation GmbH, c=DE?certificateRevocationList:20100615T181523:20100707T181523:72FEF3FD88455A1D4C6796A6499D4422:::: +c:7F2A402CBB016A9146D613568C89D3596A4111AA:CN=Wurzel ZS 3,O=Intevation GmbH,C=DE:ldap%3A//ca.intevation.org/cn=Wurzel ZS 3, o=Intevation GmbH, c=DE?certificateRevocationList:20100625T102134:20100814T102134:44E60EEC02EF2FBF7A5C77E9BD565667:::: diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr-cache.d/crl-4E31CEB57DDD4A7B9991AB05507B1ED4293FF952.db b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr-cache.d/crl-4E31CEB57DDD4A7B9991AB05507B1ED4293FF952.db new file mode 100644 index 00000000..0b7e2dd4 Binary files /dev/null and b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr-cache.d/crl-4E31CEB57DDD4A7B9991AB05507B1ED4293FF952.db differ diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr-cache.d/crl-7F2A402CBB016A9146D613568C89D3596A4111AA.db b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr-cache.d/crl-7F2A402CBB016A9146D613568C89D3596A4111AA.db new file mode 100644 index 00000000..47474a26 Binary files /dev/null and b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr-cache.d/crl-7F2A402CBB016A9146D613568C89D3596A4111AA.db differ diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr.conf b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr.conf new file mode 100644 index 00000000..a17a0354 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/dirmngr.conf @@ -0,0 +1,8 @@ + +###+++--- GPGConf ---+++### +debug-level basic +log-file socket:///home/leo/kde/src/kdepim/messagecomposer/tests/gnupg_home/log-socket +###+++--- GPGConf ---+++### Tue 29 Jun 2010 10:23:13 AM EDT +# GPGConf edited this configuration file. +# It will disable options before this marked block, but it will +# never change anything below these lines. diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/gpg-agent.conf.in b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/gpg-agent.conf.in new file mode 100644 index 00000000..ece69255 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/gpg-agent.conf.in @@ -0,0 +1,10 @@ +pinentry-program @CMAKE_CURRENT_BINARY_DIR@/pinentry-fake.sh +###+++--- GPGConf ---+++### +allow-mark-trusted +debug-level basic +faked-system-time 20130110T154812 +log-file @CMAKE_CURRENT_BINARY_DIR@/gpg-agent.log +###+++--- GPGConf ---+++### Tue 29 Jun 2010 10:23:13 AM EDT +# GPGConf edited this configuration file. +# It will disable options before this marked block, but it will +# never change anything below these lines. diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/gpg.conf b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/gpg.conf new file mode 100644 index 00000000..f1760823 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/gpg.conf @@ -0,0 +1,244 @@ +# Options for GnuPG +# Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Unless you specify which option file to use (with the command line +# option "--options filename"), GnuPG uses the file ~/.gnupg/gpg.conf +# by default. +# +# An options file can contain any long options which are available in +# GnuPG. If the first non white space character of a line is a '#', +# this line is ignored. Empty lines are also ignored. +# +# See the man page for a list of options. + +# Uncomment the following option to get rid of the copyright notice + +#no-greeting + +# If you have more than 1 secret key in your keyring, you may want to +# uncomment the following option and set your preferred keyid. + +#default-key 621CC013 + +# If you do not pass a recipient to gpg, it will ask for one. Using +# this option you can encrypt to a default key. Key validation will +# not be done in this case. The second form uses the default key as +# default recipient. + +#default-recipient some-user-id +#default-recipient-self + +# Use --encrypt-to to add the specified key as a recipient to all +# messages. This is useful, for example, when sending mail through a +# mail client that does not automatically encrypt mail to your key. +# In the example, this option allows you to read your local copy of +# encrypted mail that you've sent to others. + +#encrypt-to some-key-id + +# By default GnuPG creates version 3 signatures for data files. This +# is not strictly OpenPGP compliant but PGP 6 and most versions of PGP +# 7 require them. To disable this behavior, you may use this option +# or --openpgp. + +#no-force-v3-sigs + +# Because some mailers change lines starting with "From " to ">From " +# it is good to handle such lines in a special way when creating +# cleartext signatures; all other PGP versions do it this way too. + +#no-escape-from-lines + +# If you do not use the Latin-1 (ISO-8859-1) charset, you should tell +# GnuPG which is the native character set. Please check the man page +# for supported character sets. This character set is only used for +# metadata and not for the actual message which does not undergo any +# translation. Note that future version of GnuPG will change to UTF-8 +# as default character set. In most cases this option is not required +# as GnuPG is able to figure out the correct charset at runtime. + +#charset utf-8 + +# Group names may be defined like this: +# group mynames = paige 0x12345678 joe patti +# +# Any time "mynames" is a recipient (-r or --recipient), it will be +# expanded to the names "paige", "joe", and "patti", and the key ID +# "0x12345678". Note there is only one level of expansion - you +# cannot make an group that points to another group. Note also that +# if there are spaces in the recipient name, this will appear as two +# recipients. In these cases it is better to use the key ID. + +#group mynames = paige 0x12345678 joe patti + +# Lock the file only once for the lifetime of a process. If you do +# not define this, the lock will be obtained and released every time +# it is needed, which is usually preferable. + +#lock-once + +# GnuPG can send and receive keys to and from a keyserver. These +# servers can be HKP, email, or LDAP (if GnuPG is built with LDAP +# support). +# +# Example HKP keyserver: +# hkp://keys.gnupg.net +# hkp://subkeys.pgp.net +# +# Example email keyserver: +# mailto:pgp-public-keys@keys.pgp.net +# +# Example LDAP keyservers: +# ldap://keyserver.pgp.com +# +# Regular URL syntax applies, and you can set an alternate port +# through the usual method: +# hkp://keyserver.example.net:22742 +# +# Most users just set the name and type of their preferred keyserver. +# Note that most servers (with the notable exception of +# ldap://keyserver.pgp.com) synchronize changes with each other. Note +# also that a single server name may actually point to multiple +# servers via DNS round-robin. hkp://keys.gnupg.net is an example of +# such a "server", which spreads the load over a number of physical +# servers. To see the IP address of the server actually used, you may use +# the "--keyserver-options debug". + +keyserver hkp://keys.gnupg.net +#keyserver mailto:pgp-public-keys@keys.nl.pgp.net +#keyserver ldap://keyserver.pgp.com + +# Common options for keyserver functions: +# +# include-disabled : when searching, include keys marked as "disabled" +# on the keyserver (not all keyservers support this). +# +# no-include-revoked : when searching, do not include keys marked as +# "revoked" on the keyserver. +# +# verbose : show more information as the keys are fetched. +# Can be used more than once to increase the amount +# of information shown. +# +# use-temp-files : use temporary files instead of a pipe to talk to the +# keyserver. Some platforms (Win32 for one) always +# have this on. +# +# keep-temp-files : do not delete temporary files after using them +# (really only useful for debugging) +# +# http-proxy="proxy" : set the proxy to use for HTTP and HKP keyservers. +# This overrides the "http_proxy" environment variable, +# if any. +# +# auto-key-retrieve : automatically fetch keys as needed from the keyserver +# when verifying signatures or when importing keys that +# have been revoked by a revocation key that is not +# present on the keyring. +# +# no-include-attributes : do not include attribute IDs (aka "photo IDs") +# when sending keys to the keyserver. + +#keyserver-options auto-key-retrieve + +# Display photo user IDs in key listings + +# list-options show-photos + +# Display photo user IDs when a signature from a key with a photo is +# verified + +# verify-options show-photos + +# Use this program to display photo user IDs +# +# %i is expanded to a temporary file that contains the photo. +# %I is the same as %i, but the file isn't deleted afterwards by GnuPG. +# %k is expanded to the key ID of the key. +# %K is expanded to the long OpenPGP key ID of the key. +# %t is expanded to the extension of the image (e.g. "jpg"). +# %T is expanded to the MIME type of the image (e.g. "image/jpeg"). +# %f is expanded to the fingerprint of the key. +# %% is %, of course. +# +# If %i or %I are not present, then the photo is supplied to the +# viewer on standard input. If your platform supports it, standard +# input is the best way to do this as it avoids the time and effort in +# generating and then cleaning up a secure temp file. +# +# If no photo-viewer is provided, GnuPG will look for xloadimage, eog, +# or display (ImageMagick). On Mac OS X and Windows, the default is +# to use your regular JPEG image viewer. +# +# Some other viewers: +# photo-viewer "qiv %i" +# photo-viewer "ee %i" +# +# This one saves a copy of the photo ID in your home directory: +# photo-viewer "cat > ~/photoid-for-key-%k.%t" +# +# Use your MIME handler to view photos: +# photo-viewer "metamail -q -d -b -c %T -s 'KeyID 0x%k' -f GnuPG" + +# Passphrase agent +# +# We support the old experimental passphrase agent protocol as well as +# the new Assuan based one (currently available in the "newpg" package +# at ftp.gnupg.org/gcrypt/alpha/aegypten/). To make use of the agent, +# you have to run an agent as daemon and use the option +# +# use-agent +# +# which tries to use the agent but will fallback to the regular mode +# if there is a problem connecting to the agent. The normal way to +# locate the agent is by looking at the environment variable +# GPG_AGENT_INFO which should have been set during gpg-agent startup. +# In certain situations the use of this variable is not possible, thus +# the option +# +# --gpg-agent-info=::1 +# +# may be used to override it. + +# Automatic key location +# +# GnuPG can automatically locate and retrieve keys as needed using the +# auto-key-locate option. This happens when encrypting to an email +# address (in the "user@example.com" form), and there are no +# user@example.com keys on the local keyring. This option takes the +# following arguments, in the order they are to be tried: +# +# cert = locate a key using DNS CERT, as specified in RFC-4398. +# GnuPG can handle both the PGP (key) and IPGP (URL + fingerprint) +# CERT methods. +# +# pka = locate a key using DNS PKA. +# +# ldap = locate a key using the PGP Universal method of checking +# "ldap://keys.(thedomain)". For example, encrypting to +# user@example.com will check ldap://keys.example.com. +# +# keyserver = locate a key using whatever keyserver is defined using +# the keyserver option. +# +# You may also list arbitrary keyservers here by URL. +# +# Try CERT, then PKA, then LDAP, then hkp://subkeys.net: +#auto-key-locate cert pka ldap hkp://subkeys.pgp.net + +###+++--- GPGConf ---+++### +utf8-strings +#debug-level basic +#log-file socket:///home/leo/kde/src/kdepim/messagecomposer/tests/gnupg_home/log-socket +###+++--- GPGConf ---+++### Tue 29 Jun 2010 10:23:13 AM EDT +# GPGConf edited this configuration file. +# It will disable options before this marked block, but it will +# never change anything below these lines. diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/gpgsm.conf.in b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/gpgsm.conf.in new file mode 100644 index 00000000..92b6119d --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/gpgsm.conf.in @@ -0,0 +1,10 @@ + +###+++--- GPGConf ---+++### +disable-crl-checks +debug-level basic +faked-system-time 20130110T154812 +log-file @CMAKE_CURRENT_BINARY_DIR@/gpgsm.log +###+++--- GPGConf ---+++### Tue 29 Jun 2010 10:23:13 AM EDT +# GPGConf edited this configuration file. +# It will disable options before this marked block, but it will +# never change anything below these lines. diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/pinentry-fake.sh b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/pinentry-fake.sh new file mode 100755 index 00000000..7135a942 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/pinentry-fake.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +echo "OK Your orders please" +while : +do + read cmd + echo "OK" + [ "$cmd" = "BYE" ] && break +done diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/private-keys-v1.d/1AA8BA52430E51AE249AF0DA97D59F869E4101A8.key b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/private-keys-v1.d/1AA8BA52430E51AE249AF0DA97D59F869E4101A8.key new file mode 100644 index 00000000..39ac307b Binary files /dev/null and b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/private-keys-v1.d/1AA8BA52430E51AE249AF0DA97D59F869E4101A8.key differ diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/pubring.gpg b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/pubring.gpg new file mode 100644 index 00000000..eb34da28 Binary files /dev/null and b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/pubring.gpg differ diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/pubring.kbx b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/pubring.kbx new file mode 100644 index 00000000..0230f313 Binary files /dev/null and b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/pubring.kbx differ diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/scdaemon.conf b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/scdaemon.conf new file mode 100644 index 00000000..a17a0354 --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/scdaemon.conf @@ -0,0 +1,8 @@ + +###+++--- GPGConf ---+++### +debug-level basic +log-file socket:///home/leo/kde/src/kdepim/messagecomposer/tests/gnupg_home/log-socket +###+++--- GPGConf ---+++### Tue 29 Jun 2010 10:23:13 AM EDT +# GPGConf edited this configuration file. +# It will disable options before this marked block, but it will +# never change anything below these lines. diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/secring.gpg b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/secring.gpg new file mode 100644 index 00000000..cfd3387d Binary files /dev/null and b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/secring.gpg differ diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/trustdb.gpg b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/trustdb.gpg new file mode 100644 index 00000000..a1c4fc8a Binary files /dev/null and b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/trustdb.gpg differ diff --git a/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/trustlist.txt b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/trustlist.txt new file mode 100644 index 00000000..bbb0442d --- /dev/null +++ b/plugins/messageviewer/bodypartformatter/autotests/gnupg_home/trustlist.txt @@ -0,0 +1,11 @@ +5E:7C:B2:F4:9F:70:05:43:42:32:5D:75:74:70:00:09:B9:D8:08:61 S + + + +# CN=unittest cert +# O=KDAB +# C=US +# EMail=test@example.com +24:D2:FC:A2:2E:B3:B8:0A:1E:37:71:D1:4C:C6:58:E3:21:2B:49:DC S + + diff --git a/plugins/messageviewer/bodypartformatter/autotests/rendertest.cpp b/plugins/messageviewer/bodypartformatter/autotests/rendertest.cpp index 743e9749..738d1712 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/rendertest.cpp +++ b/plugins/messageviewer/bodypartformatter/autotests/rendertest.cpp @@ -1,166 +1,230 @@ /* Copyright (c) 2010 Volker Krause Copyright (c) 2016 Sandro Knauß This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "rendertest.h" #include "testobjecttreesource.h" #include #include #include #include #include #include #include #include #include #ifndef Q_OS_WIN void initLocale() { setenv("KDEHOME", QFile::encodeName(QDir::homePath() + QString::fromLatin1( "/.qttest")).constData(), 1); setenv("LC_ALL", "en_US.utf-8", 1); setenv("TZ", "UTC", 1); QStandardPaths::setTestModeEnabled(true); QIcon::setThemeName(QStringLiteral("breeze")); QLocale::setDefault(QLocale(QStringLiteral("en_US"))); } Q_CONSTRUCTOR_FUNCTION(initLocale) #endif void RenderTest::testRender_data() { QTest::addColumn("mailFileName"); QTest::addColumn("referenceFileName"); QTest::addColumn("outFileName"); QDir dir(QStringLiteral(MAIL_DATA_DIR)); const QStringList lst = dir.entryList(QStringList(QStringLiteral("*.mbox")), QDir::Files | QDir::Readable | QDir::NoSymLinks); for (const QString &file : lst) { if (!QFile::exists(dir.path() + QLatin1Char('/') + file + QStringLiteral(".html"))) { continue; } QTest::newRow(file.toLatin1()) << QString(dir.path() + QLatin1Char('/') + file) << QString(dir.path() + QLatin1Char('/') + file + QStringLiteral(".html")) << QString(file + QStringLiteral(".out")); } } void RenderTest::testRender() { QFETCH(QString, mailFileName); QFETCH(QString, referenceFileName); QFETCH(QString, outFileName); // load input mail QFile mailFile(mailFileName); QVERIFY(mailFile.open(QIODevice::ReadOnly)); const QByteArray mailData = KMime::CRLFtoLF(mailFile.readAll()); QVERIFY(!mailData.isEmpty()); KMime::Message::Ptr msg(new KMime::Message); msg->setContent(mailData); msg->parse(); // render the mail MimeTreeParser::FileHtmlWriter fileWriter(outFileName); fileWriter.begin(); QImage paintDevice; MessageViewer::CSSHelperBase cssHelper(&paintDevice); MimeTreeParser::NodeHelper nodeHelper; TestObjectTreeSource testSource(&fileWriter, &cssHelper); MimeTreeParser::ObjectTreeParser otp(&testSource, &nodeHelper); fileWriter.write(QStringLiteral("\n" "\n" "\n")); otp.parseObjectTree(msg.data()); fileWriter.write(QStringLiteral("")); fileWriter.end(); compareFile(outFileName, referenceFileName); } +void RenderTest::testRenderKeyDetails_data() +{ + QTest::addColumn("basename"); + QTest::newRow("message-with-openpgp-key.mbox") << QStringLiteral("message-with-openpgp-key.mbox"); + QTest::newRow("message-with-two-openpgp-key.mbox") << QStringLiteral("message-with-two-openpgp-key.mbox"); +} + +void RenderTest::testRenderKeyDetails() +{ + QFETCH(QString, basename); + QString mailFileName = QStringLiteral(MAIL_DATA_DIR) + QLatin1Char('/') + basename; + QString referenceFileName = QStringLiteral(MAIL_DATA_DIR) + QLatin1Char('/') + basename + QStringLiteral(".html"); + QString outFileName = basename + QStringLiteral(".out"); + + // load input mail + QFile mailFile(mailFileName); + QVERIFY(mailFile.open(QIODevice::ReadOnly)); + const QByteArray mailData = KMime::CRLFtoLF(mailFile.readAll()); + QVERIFY(!mailData.isEmpty()); + KMime::Message::Ptr msg(new KMime::Message); + msg->setContent(mailData); + msg->parse(); + + // render the mail + QEventLoop loop; + MimeTreeParser::FileHtmlWriter fileWriter(outFileName); + fileWriter.begin(); + QImage paintDevice; + MessageViewer::CSSHelperBase cssHelper(&paintDevice); + MimeTreeParser::NodeHelper nodeHelper; + TestObjectTreeSource testSource(&fileWriter, &cssHelper); + testSource.setShowSignatureDetails(true); + MimeTreeParser::ObjectTreeParser otp(&testSource, &nodeHelper); + + fileWriter.write(QStringLiteral("\n" + "\n" + "\n")); + + connect(&nodeHelper, &MimeTreeParser::NodeHelper::update, &loop, &QEventLoop::quit); + otp.parseObjectTree(msg.data()); + + fileWriter.write(QStringLiteral("")); + fileWriter.end(); + + compareFile(outFileName, referenceFileName + QStringLiteral(".running")); + loop.exec(); + + { + MimeTreeParser::ObjectTreeParser otp(&testSource, &nodeHelper); + fileWriter.begin(); + fileWriter.write(QStringLiteral("\n" + "\n" + "\n")); + otp.parseObjectTree(msg.data()); + + fileWriter.write(QStringLiteral("")); + fileWriter.end(); + + compareFile(outFileName, referenceFileName + QStringLiteral(".details")); + } +} + + + void RenderTest::compareFile(const QString &outFile, const QString &referenceFile) { QVERIFY(QFile::exists(outFile)); const QString htmlFile = outFile + QStringLiteral(".html"); // remove tailing newlines and spaces and make htmlmore uniform (breaks pre tags) { QFile f(outFile); QVERIFY(f.open(QIODevice::ReadOnly)); QString content = QString::fromUtf8(f.readAll()); f.close(); content.replace(QRegExp(QStringLiteral("[\t ]+")), QStringLiteral(" ")); content.replace(QRegExp(QStringLiteral("[\t ]*\n+[\t ]*")), QStringLiteral("\n")); content.replace(QRegExp(QStringLiteral("([\n\t ])\\1+")), QStringLiteral("\\1")); content.replace(QRegExp(QStringLiteral(">\n+[\t ]*")), QStringLiteral(">")); content.replace(QRegExp(QStringLiteral("[\t ]*\n+[\t ]*<")), QStringLiteral("<")); content.replace(QLatin1String(" "), QLatin1String("NBSP_ENTITY_PLACEHOLDER")); // xmlling chokes on   QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate)); f.write(content.toUtf8()); f.close(); } // validate xml and pretty-print for comparisson // TODO add proper cmake check for xmllint and diff QStringList args = QStringList() << QStringLiteral("--format") << QStringLiteral("--encode") << QStringLiteral("UTF8") << QStringLiteral("--output") << htmlFile << outFile; QCOMPARE(QProcess::execute(QStringLiteral("xmllint"), args), 0); // get rid of system dependent or random paths { QFile f(htmlFile); QVERIFY(f.open(QIODevice::ReadOnly)); QString content = QString::fromUtf8(f.readAll()); f.close(); content.replace(QRegExp(QStringLiteral( "\"file:[^\"]*[/(?:%2F)]([^\"/(?:%2F)]*)\"")), QStringLiteral("\"file:\\1\"")); content.replace(QLatin1String("NBSP_ENTITY_PLACEHOLDER"), QLatin1String(" ")); // undo above transformation for xmllint content.replace(QRegExp(QStringLiteral("/bodypart/\\d+/")), QStringLiteral("/bodypart/0/")); QVERIFY(f.open(QIODevice::WriteOnly | QIODevice::Truncate)); f.write(content.toUtf8()); f.close(); } // compare to reference file args = QStringList() << QStringLiteral("-u") << referenceFile << htmlFile; QProcess proc; proc.setProcessChannelMode(QProcess::ForwardedChannels); proc.start(QStringLiteral("diff"), args); QVERIFY(proc.waitForFinished()); QCOMPARE(proc.exitCode(), 0); } QTEST_MAIN(RenderTest) diff --git a/plugins/messageviewer/bodypartformatter/autotests/rendertest.h b/plugins/messageviewer/bodypartformatter/autotests/rendertest.h index 1f91c500..6d5268e4 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/rendertest.h +++ b/plugins/messageviewer/bodypartformatter/autotests/rendertest.h @@ -1,37 +1,39 @@ /* Copyright (c) 2010 Volker Krause Copyright (c) 2016 Sandro Knauß This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef RENDERTEST_H #define RENDERTEST_H #include class RenderTest : public QObject { Q_OBJECT private Q_SLOTS: void testRender_data(); void testRender(); + void testRenderKeyDetails_data(); + void testRenderKeyDetails(); private: void compareFile(const QString &outFile, const QString &referenceFile); }; #endif diff --git a/plugins/messageviewer/bodypartformatter/autotests/testobjecttreesource.h b/plugins/messageviewer/bodypartformatter/autotests/testobjecttreesource.h index 0e60a8bc..4b8403aa 100644 --- a/plugins/messageviewer/bodypartformatter/autotests/testobjecttreesource.h +++ b/plugins/messageviewer/bodypartformatter/autotests/testobjecttreesource.h @@ -1,121 +1,128 @@ /* Copyright (C) 2010 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com Copyright (c) 2010 Leo Franchi This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MESSAGECORE_TESTS_UTIL_H #define MESSAGECORE_TESTS_UTIL_H #include #include #include class TestObjectTreeSource : public MessageViewer::EmptySource { public: TestObjectTreeSource(MimeTreeParser::HtmlWriter *writer, MessageViewer::CSSHelperBase *cssHelper) : mWriter(writer) , mCSSHelper(cssHelper) , mHtmlLoadExternal(false) + , mShowSignatureDetails(false) { } MimeTreeParser::HtmlWriter *htmlWriter() override { return mWriter; } MessageViewer::CSSHelperBase *cssHelper() override { return mCSSHelper; } bool htmlLoadExternal() const override { return mHtmlLoadExternal; } void setHtmlLoadExternal(bool loadExternal) { mHtmlLoadExternal = loadExternal; } bool decryptMessage() const override { return false; } bool showSignatureDetails() const override { - return false; + return mShowSignatureDetails; + } + + void setShowSignatureDetails(bool showSignatureDetails) + { + mShowSignatureDetails = showSignatureDetails; } void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList &availableModes) override { Q_UNUSED(mode) Q_UNUSED(availableModes) } int levelQuote() const override { return false; } const QTextCodec *overrideCodec() override { return nullptr; } QString createMessageHeader(KMime::Message *message) override { Q_UNUSED(message); return QString(); } const MimeTreeParser::AttachmentStrategy *attachmentStrategy() override { return MimeTreeParser::AttachmentStrategy::smart(); } bool autoImportKeys() const override { return false; } bool showEmoticons() const override { return false; } bool showExpandQuotesMark() const override { return false; } MimeTreeParser::Util::HtmlMode preferredMode() const override { return MimeTreeParser::Util::Html; } private: MimeTreeParser::HtmlWriter *mWriter = nullptr; MessageViewer::CSSHelperBase *mCSSHelper = nullptr; bool mHtmlLoadExternal; + bool mShowSignatureDetails; }; #endif diff --git a/plugins/messageviewer/bodypartformatter/gnupgwks/templates/pgpkeymessagepart.html b/plugins/messageviewer/bodypartformatter/gnupgwks/templates/pgpkeymessagepart.html index 7ccd7768..d290868e 100644 --- a/plugins/messageviewer/bodypartformatter/gnupgwks/templates/pgpkeymessagepart.html +++ b/plugins/messageviewer/bodypartformatter/gnupgwks/templates/pgpkeymessagepart.html @@ -1,58 +1,58 @@
{% i18n "OpenPGP Key" %}

{% i18n "This is an OpenPGP key, which can be used to sign or encrypt emails." %}

{% if block.showKeyDetails %} {% if block.searchRunning %}

{% i18n "Loading key details..." %}

{% endif %} {% if not block.error %} {% if block.created %} - + {% endif %} {% if block.fingerprint %} - + {% endif %}
{% i18n "Owner:" %} {{ block.uid }}
{% i18n "Created:" %} {{ block.created }}{% i18n "Created:" %} {{ block.created }}
{% i18n "Fingerprint:" %} {{ block.fingerprint }}{% i18n "Fingerprint:" %} {{ block.fingerprint }}
{% if not block.searchRunning and not block.keyUrl %}

{% i18n "This key is unknown, it could not be found in your local keyring. You may want to import this key." %}

{% endif %} {% else %}

{% i18n "Error while loading key: %1" block.error %}

{% endif %} {% i18n "Hide key details" %} {% if block.keyUrl %} | {% i18n "Open in Kleopatra" %} {% endif %} {% else %} {% i18n "Show key details ..." %} {% endif %} | {% i18n "Import key" %}