diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index d2479e381..1e46108f0 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -1,182 +1,78 @@
 # assuan configure checks
 include(CheckFunctionExists)
 
 if ( ASSUAN2_FOUND )
-  set ( ASSUAN_SUFFIX "2" )
 else ( ASSUAN2_FOUND )
   # TODO Clean this up with assuan 2 as hard dependency.
   message(FATAL_ERROR "At least version 2 of libassuan is required for Kleopatra.")
 endif ( ASSUAN2_FOUND )
 
 set( USABLE_ASSUAN_FOUND false )
 
-if ( ASSUAN${ASSUAN_SUFFIX}_FOUND )
 
-  set( CMAKE_REQUIRED_INCLUDES ${ASSUAN${ASSUAN_SUFFIX}_INCLUDES} )
+  set( CMAKE_REQUIRED_INCLUDES ${ASSUAN2_INCLUDES} )
 
-  if ( ASSUAN2_FOUND )
     set( CMAKE_REQUIRED_LIBRARIES ${ASSUAN2_LIBRARIES} )
     set( USABLE_ASSUAN_FOUND true )
-  elseif ( WIN32 AND ASSUAN_VANILLA_FOUND )
-    set( CMAKE_REQUIRED_LIBRARIES ${ASSUAN_VANILLA_LIBRARIES} )
-    set( USABLE_ASSUAN_FOUND true )
-  elseif( NOT WIN32 AND ASSUAN_PTHREAD_FOUND )
-    set( CMAKE_REQUIRED_LIBRARIES ${ASSUAN_PTHREAD_LIBRARIES} )
-    set( USABLE_ASSUAN_FOUND true )
-  endif( ASSUAN2_FOUND )
 
   # TODO: this workaround will be removed as soon as we find better solution
   if(MINGW)
     set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${KDEWIN32_INCLUDE_DIR}/mingw)
   elseif(MSVC)
     set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${KDEWIN32_INCLUDE_DIR}/msvc)
   endif(MINGW)
 
-endif( ASSUAN${ASSUAN_SUFFIX}_FOUND )
-
 if ( USABLE_ASSUAN_FOUND )
   # check if assuan.h can be compiled standalone (it couldn't, on
   # Windows, until recently, because of a HAVE_W32_SYSTEM #ifdef in
   # there)
   check_cxx_source_compiles( "
        #include <assuan.h>
        int main() {
            return 1;
        }
        "
        USABLE_ASSUAN_FOUND )
 endif( USABLE_ASSUAN_FOUND )
 
 if ( USABLE_ASSUAN_FOUND )
 
   # check whether assuan and gpgme may be linked to simultaneously
   check_function_exists( "assuan_get_pointer" USABLE_ASSUAN_FOUND )
 
 endif( USABLE_ASSUAN_FOUND )
 
-if ( USABLE_ASSUAN_FOUND AND NOT ASSUAN2_FOUND )
-
-  # check if assuan has assuan_fd_t
-  check_cxx_source_compiles("
-        #include <assuan.h>
-        int main() {
-            assuan_fd_t fd = ASSUAN_INVALID_FD;
-            return fd ? 1 : 0 ;
-        }
-        "
-    HAVE_ASSUAN_FD_T )
-
-  if ( WIN32 AND NOT HAVE_ASSUAN_FD_T )
-    set( USABLE_ASSUAN_FOUND false )
-  endif ( WIN32 AND NOT HAVE_ASSUAN_FD_T )
-
-  # check if assuan has assuan_inquire_ext, old style
-  check_function_exists( "assuan_inquire_ext" HAVE_ASSUAN_INQUIRE_EXT )
-
-  if ( NOT HAVE_ASSUAN_INQUIRE_EXT )
-    set( USABLE_ASSUAN_FOUND false )
-  endif( NOT HAVE_ASSUAN_INQUIRE_EXT )
-
-  # check if assuan has new-style assuan_inquire_ext:
-  check_cxx_source_compiles("
-        #include <assuan.h>
-        static int handler( void *, int, unsigned char*, size_t ) { return 0; }
-        int main() {
-            assuan_context_t ctx = 0;
-            const size_t maxSize = 0U;
-            assuan_error_t err = assuan_inquire_ext( ctx, \"FOO\", maxSize, handler, (void*)0 );
-            return err ? 1 : 0 ;
-        }
-        "
-    HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT )
-
-endif( USABLE_ASSUAN_FOUND AND NOT ASSUAN2_FOUND )
-
 if ( USABLE_ASSUAN_FOUND )
 
   # check if gpg-error already has GPG_ERR_SOURCE_KLEO
   check_cxx_source_compiles("
         #include <gpg-error.h>
         static gpg_err_source_t src = GPG_ERR_SOURCE_KLEO;
         int main() { return 0; }
         "
     HAVE_GPG_ERR_SOURCE_KLEO )
 
 endif ( USABLE_ASSUAN_FOUND )
 
-if ( USABLE_ASSUAN_FOUND AND NOT ASSUAN2_FOUND )
-
-  # check if assuan has assuan_sock_get_nonce (via assuan_sock_nonce_t)
-  # function_exists runs into linking errors - libassuan is static,
-  # and assuan_sock_get_nonce drags in stuff that needs linking
-  # against winsock2.
-  check_cxx_source_compiles("
-        #include <assuan.h>
-        static assuan_sock_nonce_t nonce;
-        int main() { return 0; }
-        "
-    HAVE_ASSUAN_SOCK_GET_NONCE )
-
-  if ( WIN32 AND NOT HAVE_ASSUAN_SOCK_GET_NONCE )
-    set( USABLE_ASSUAN_FOUND false )
-  endif ( WIN32 AND NOT HAVE_ASSUAN_SOCK_GET_NONCE )  
-
-endif ( USABLE_ASSUAN_FOUND AND NOT ASSUAN2_FOUND )
-
 if ( USABLE_ASSUAN_FOUND )
   message( STATUS "Usable assuan found for Kleopatra" )
 else ( USABLE_ASSUAN_FOUND )
   message( STATUS "NO usable assuan found for Kleopatra" )
 endif ( USABLE_ASSUAN_FOUND )
 
-if ( NOT ASSUAN2_FOUND )
-
-#
-# Check that libassuan (which is built statically) can be linked into a DSO
-# (e.g. on amd64, this requires it to be compiled with -fPIC).
-#
-
-set ( ASSUAN_LINKABLE_TO_DSO false )
-
-endif ( NOT ASSUAN2_FOUND )
-
 OPTION( BUILD_libkleopatraclient "Build directory kleopatra/libkleopatraclient" ${USABLE_ASSUAN_FOUND} )
 
 if ( NOT USABLE_ASSUAN_FOUND )
   set( BUILD_libkleopatraclient false )
 endif ( NOT USABLE_ASSUAN_FOUND )
 
-if ( BUILD_libkleopatraclient AND NOT ASSUAN2_FOUND )
-
-  message( STATUS "Checking whether libassuan can be linked against from DSO's" )
-
-  set ( YUP TRUE )
-  if ( YUP )
-    set ( ASSUAN_LINKABLE_TO_DSO true )
-    message( STATUS "--> Assuming that it can. If compilation of libkleopatraclient fails on AMD64, check that libassuan is compiled with -fPIC and try again. Otherwise, pass -DBUILD_libkleopatraclient=OFF." )
-  else ( YUP )
-  # TODO: make this one executed at configure time, so the check below works:
-  add_library( dso_with_assuan_check SHARED ${CMAKE_SOURCE_DIR}/kleopatra/dso_with_assuan_check.c )
-
-  set( CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} dso_with_assuan_check )
-  check_cxx_source_compiles( "int main() { return 0; }" ASSUAN_LINKABLE_TO_DSO )
-
-  if ( ASSUAN_LINKABLE_TO_DSO )
-    message( STATUS "Usable assuan found for libkleopatraclient" )
-  else ( ASSUAN_LINKABLE_TO_DSO )
-    message( STATUS "NO usable assuan found for libkleopatraclient - if this is AMD64, check that libassuan is compiled with -fPIC" )
-  endif ( ASSUAN_LINKABLE_TO_DSO )
-  endif ( YUP )
-
-endif ( BUILD_libkleopatraclient AND NOT ASSUAN2_FOUND )
-
 if (USABLE_ASSUAN_FOUND)
   set (HAVE_USABLE_ASSUAN 1)
   set (HAVE_KLEOPATRACLIENT_LIBRARY 1)
 else()
   set (HAVE_USABLE_ASSUAN 0)
   set (HAVE_KLEOPATRACLIENT_LIBRARY 0)
 endif()
 
 set(CMAKE_REQUIRED_INCLUDES)
 set(CMAKE_REQUIRED_LIBRARIES)
diff --git a/cmake/modules/FindAssuan2.cmake b/cmake/modules/FindAssuan2.cmake
index 176dc142d..2a46fbe19 100644
--- a/cmake/modules/FindAssuan2.cmake
+++ b/cmake/modules/FindAssuan2.cmake
@@ -1,251 +1,239 @@
 # - Try :to find the assuan v2 library
 
 # Variables set:
 #  ASSUAN2_{INCLUDES,FOUND,LIBRARIES} will be set for each of the above
 
 #if this is built-in, please replace, if it isn't, export into a MacroToBool.cmake of it's own
 macro( macro_bool_to_bool FOUND_VAR )
   foreach( _current_VAR ${ARGN} )
     if ( ${FOUND_VAR} )
       set( ${_current_VAR} TRUE )
     else()
       set( ${_current_VAR} FALSE )
     endif()
   endforeach()
 endmacro()
 
 if ( WIN32 )
 
   # On Windows, we don't have a libassuan-config script, so we need to
   # look for the stuff ourselves:
 
   # in cmake, AND and OR have the same precedence, there's no
   # subexpressions, and expressions are evaluated short-circuit'ed
   # IOW: CMake if() suxx.
   set( _seem_to_have_cached_assuan2 false )
   if ( ASSUAN2_INCLUDES )
     if ( ASSUAN2_VANILLA_LIBRARIES )#OR ASSUAN2_QT_LIBRARIES OR ASSUAN2_GLIB_LIBRARIES )
       set( _seem_to_have_cached_assuan2 true )
     endif()
   endif()
 
   if ( _seem_to_have_cached_assuan2 )
 
     macro_bool_to_bool( ASSUAN2_VANILLA_LIBRARIES  ASSUAN2_VANILLA_FOUND )
     # this would have been preferred:
     #set( ASSUAN2_*_FOUND macro_bool_to_bool(ASSUAN2_*_LIBRARIES) )
 
     if ( ASSUAN2_VANILLA_FOUND ) #OR ASSUAN2_GLIB_FOUND OR ASSUAN2_QT_FOUND )
       set( ASSUAN2_FOUND true )
     else()
       set( ASSUAN2_FOUND false )
     endif()
 
   else()
 
     set( ASSUAN2_FOUND         false )
     set( ASSUAN2_VANILLA_FOUND false )
     #set( ASSUAN2_GLIB_FOUND    false )
     #set( ASSUAN2_QT_FOUND      false )
 
     find_path( ASSUAN2_INCLUDES assuan.h
       ${CMAKE_INCLUDE_PATH}
       ${CMAKE_INSTALL_PREFIX}/include
     )
 
     find_library( _assuan2_library NAMES assuan2 libassuan2 assuan libassuan assuan-0 libassuan-0 #sic!
       PATHS
         ${CMAKE_LIBRARY_PATH}
         ${CMAKE_INSTALL_PREFIX}/lib
     )
 
     find_library( _gpg_error_library     NAMES gpg-error libgpg-error gpg-error-0 libgpg-error-0
       PATHS
         ${CMAKE_LIBRARY_PATH}
         ${CMAKE_INSTALL_PREFIX}/lib
     )
 
     set( ASSUAN2_INCLUDES ${ASSUAN2_INCLUDES} )
 
     if ( _assuan2_library AND _gpg_error_library )
       set( ASSUAN2_LIBRARIES ${_assuan2_library} ${_gpg_error_library} ws2_32 )
       set( ASSUAN2_FOUND             true )
     endif()
 
   endif()
 
-  if (ASSUAN2_FOUND)
-    set (HAVE_ASSUAN2 1)
-  else()
-    set (HAVE_ASSUAN2 0)
-  endif()
-
 else() # not WIN32
 
   # On *nix, we have the libassuan-config script which can tell us all we
   # need to know:
 
   # see WIN32 case for an explanation of what this does:
   set( _seem_to_have_cached_assuan2 false )
   if ( ASSUAN2_INCLUDES AND ASSUAN2_LIBRARIES )
     set( _seem_to_have_cached_assuan2 true )
   endif()
 
   if ( _seem_to_have_cached_assuan2 )
 
     set( ASSUAN2_FOUND true )
 
   else()
 
     set( ASSUAN2_FOUND         false )
 
     find_program( _ASSUAN2CONFIG_EXECUTABLE NAMES libassuan-config )
 
     # if libassuan-config has been found
     if ( _ASSUAN2CONFIG_EXECUTABLE )
 
       message( STATUS "Found libassuan-config at ${_ASSUAN2CONFIG_EXECUTABLE}" )
 
       exec_program( ${_ASSUAN2CONFIG_EXECUTABLE} ARGS --version OUTPUT_VARIABLE ASSUAN2_VERSION )
 
       set( _ASSUAN2_MIN_VERSION "2.0.0" )
       if( ASSUAN2_VERSION VERSION_GREATER ${_ASSUAN2_MIN_VERSION} )
         set( _ASSUAN2_INSTALLED_VERSION_OK TRUE )
       endif()
 
       if ( NOT _ASSUAN2_INSTALLED_VERSION_OK )
 
         message( STATUS "The installed version of assuan is too old: ${ASSUAN2_VERSION} (required: >= ${_ASSUAN2_MIN_VERSION})" )
 
       else()
 
         message( STATUS "Found assuan v${ASSUAN2_VERSION}" )
 
         exec_program( ${_ASSUAN2CONFIG_EXECUTABLE} ARGS --libs OUTPUT_VARIABLE _assuan2_config_libs RETURN_VALUE _ret )
 	if ( _ret )
 	  set( _assuan2_config_libs )
 	endif()
 
         # append -lgpg-error to the list of libraries, if necessary
         if ( _assuan2_config_libs AND NOT _assuan2_config_libs MATCHES "lgpg-error" )
           set( _assuan2_config_libs "${_assuan2_config_libs} -lgpg-error" )
         endif()
 
         if ( _assuan2_config_libs )
 
           exec_program( ${_ASSUAN2CONFIG_EXECUTABLE} ARGS --cflags OUTPUT_VARIABLE _ASSUAN2_CFLAGS )
 
           if ( _ASSUAN2_CFLAGS )
             string( REGEX REPLACE "(\r?\n)+$" " " _ASSUAN2_CFLAGS  "${_ASSUAN2_CFLAGS}" )
             string( REGEX REPLACE " *-I"      ";" ASSUAN2_INCLUDES "${_ASSUAN2_CFLAGS}" )
           endif()
 
           if ( _assuan2_config_libs )
 
             set( _assuan2_library_dirs )
             set( _assuan2_library_names )
 
             string( REGEX REPLACE " +" ";" _assuan2_config_libs "${_assuan2_config_libs}" )
 
             foreach( _flag ${_assuan2_config_libs} )
               if ( "${_flag}" MATCHES "^-L" )
                 string( REGEX REPLACE "^-L" "" _dir "${_flag}" )
                 file( TO_CMAKE_PATH "${_dir}" _dir )
                 set( _assuan2_library_dirs ${_assuan2_library_dirs} "${_dir}" )
               elseif( "${_flag}" MATCHES "^-l" )
                 string( REGEX REPLACE "^-l" "" _name "${_flag}" )
                 set( _assuan2_library_names ${_assuan2_library_names} "${_name}" )
               endif()
             endforeach()
 
             set( ASSUAN2_FOUND true )
 
             foreach( _name ${_assuan2_library_names} )
               set( _assuan2_${_name}_lib )
 
               # if -L options were given, look only there
               if ( _assuan2_library_dirs )
                 find_library( _assuan2_${_name}_lib NAMES ${_name} PATHS ${_assuan2_library_dirs} NO_DEFAULT_PATH )
               endif()
 
               # if not found there, look in system directories
               if ( NOT _assuan2_${_name}_lib )
                 find_library( _assuan2_${_name}_lib NAMES ${_name} )
               endif()
 
               # if still not found, then the whole flavour isn't found
               if ( NOT _assuan2_${_name}_lib )
                 if ( ASSUAN2_FOUND )
                   set( ASSUAN2_FOUND false )
                   set( _not_found_reason "dependent library ${_name} wasn't found" )
                 endif()
               endif()
 
               set( ASSUAN2_LIBRARIES ${ASSUAN2_LIBRARIES} "${_assuan2_${_name}_lib}" )
             endforeach()
 
             #check_c_library_exists_explicit( assuan         assuan_check_version "${_ASSUAN2_CFLAGS}" "${ASSUAN2_LIBRARIES}"         ASSUAN2_FOUND         )
             if ( ASSUAN2_FOUND )
               message( STATUS " Checking whether assuan is usable...yes" )
             else()
               message( STATUS " Checking whether assuan is usable...no" )
               message( STATUS "  (${_not_found_reason})" )
             endif()
           endif()
 
           # ensure that they are cached
           set( ASSUAN2_INCLUDES  ${ASSUAN2_INCLUDES}  )
           set( ASSUAN2_LIBRARIES ${ASSUAN2_LIBRARIES} )
 
         endif()
 
       endif()
 
     endif()
 
   endif()
 
-  if (ASSUAN2_FOUND)
-    set (HAVE_ASSUAN2 1)
-  else()
-    set (HAVE_ASSUAN2 0)
-  endif()
-
 endif() # WIN32 | Unix
 
 
 if ( NOT Assuan2_FIND_QUIETLY )
 
   if ( ASSUAN2_FOUND )
     message( STATUS "Usable assuan found." )
     message( STATUS " Includes:  ${ASSUAN2_INCLUDES}" )
     message( STATUS " Libraries: ${ASSUAN2_LIBRARIES}" )
   else()
     message( STATUS "No usable assuan found." )
   endif()
 
   if( Assuan2_FIND_REQUIRED )
     set( _ASSUAN2_TYPE "REQUIRED" )
   else()
     set( _ASSUAN2_TYPE "OPTIONAL" )
   endif()
 
   if ( WIN32 )
     set( _assuan2_homepage "https://www.gpg4win.org" )
   else()
     set( _assuan2_homepage "https://www.gnupg.org/related_software/libassuan" )
   endif()
 
   set_package_properties(ASSUAN2 PROPERTIES DESCRIPTION "Assuan v2 IPC library"
                          URL ${_assuan2_homepage}
                          TYPE ${_ASSUAN2_TYPE}
                          PURPOSE "Needed for Kleopatra to act as the GnuPG UI Server"
   )
 
 else()
 
   if ( Assuan2_FIND_REQUIRED AND NOT ASSUAN2_FOUND )
     message( FATAL_ERROR "Assuan2 is required but was not found." )
   endif()
 
 endif()
diff --git a/config-kleopatra.h.cmake b/config-kleopatra.h.cmake
index be13e2cbc..e2439bc32 100644
--- a/config-kleopatra.h.cmake
+++ b/config-kleopatra.h.cmake
@@ -1,64 +1,47 @@
 /* Define to 1 if you have a recent enough libassuan */
 #cmakedefine HAVE_USABLE_ASSUAN 1
 
-/* Define to 1 if you have libassuan v2 */
-#cmakedefine HAVE_ASSUAN2 1
-
-#ifndef HAVE_ASSUAN2
-/* Define to 1 if your libassuan has the assuan_fd_t type  */
-#cmakedefine HAVE_ASSUAN_FD_T 1
-
-/* Define to 1 if your libassuan has the assuan_inquire_ext function */
-#cmakedefine HAVE_ASSUAN_INQUIRE_EXT 1
-
-/* Define to 1 if your assuan_inquire_ext puts the buffer arguments into the callback signature */
-#cmakedefine HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT 1
-
-/* Define to 1 if your libassuan has the assuan_sock_get_nonce function */
-#cmakedefine HAVE_ASSUAN_SOCK_GET_NONCE 1
-
-#endif
 /* Define to 1 if you build libkleopatraclient */
 #cmakedefine HAVE_KLEOPATRACLIENT_LIBRARY 1
 
 /* DBus available */
 #cmakedefine01 HAVE_QDBUS
 
 /* Defined if QGpgME supports changing the expiration date of the primary key and the subkeys simultaneously */
 #cmakedefine QGPGME_SUPPORTS_CHANGING_EXPIRATION_OF_COMPLETE_KEY 1
 
 /* Defined if QGpgME supports retrieving the default value of a config entry */
 #cmakedefine QGPGME_CRYPTOCONFIGENTRY_HAS_DEFAULT_VALUE 1
 
 /* Defined if QGpgME supports WKD lookup */
 #cmakedefine QGPGME_SUPPORTS_WKDLOOKUP 1
 
 /* Defined if QGpgME supports specifying an import filter when importing keys */
 #cmakedefine QGPGME_SUPPORTS_IMPORT_WITH_FILTER 1
 
 /* Defined if QGpgME supports setting key origin when importing keys */
 #cmakedefine QGPGME_SUPPORTS_IMPORT_WITH_KEY_ORIGIN 1
 
 /* Defined if QGpgME supports the export of secret keys */
 #cmakedefine QGPGME_SUPPORTS_SECRET_KEY_EXPORT 1
 
 /* Defined if QGpgME supports the export of secret subkeys */
 #cmakedefine QGPGME_SUPPORTS_SECRET_SUBKEY_EXPORT 1
 
 /* Defined if QGpgME supports receiving keys by their key ids */
 #cmakedefine QGPGME_SUPPORTS_RECEIVING_KEYS_BY_KEY_ID 1
 
 /* Defined if QGpgME supports revoking own OpenPGP keys */
 #cmakedefine QGPGME_SUPPORTS_KEY_REVOCATION 1
 
 /* Defined if QGpgME supports refreshing keys */
 #cmakedefine QGPGME_SUPPORTS_KEY_REFRESH 1
 
 /* Defined if QGpgME supports setting the file name of encrypted data */
 #cmakedefine QGPGME_SUPPORTS_SET_FILENAME 1
 
 /* Defined if QGpgME supports setting the primary user id of a key */
 #cmakedefine QGPGME_SUPPORTS_SET_PRIMARY_UID 1
 
 /* Defined if GpgME++ supports setting the curve when generating ECC card keys */
 #cmakedefine GPGMEPP_SUPPORTS_SET_CURVE 1
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d67e090d7..2cb83ad3d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,621 +1,612 @@
 # SPDX-FileCopyrightText: none
 # SPDX-License-Identifier: BSD-3-Clause
 add_subdirectory(icons)
 add_subdirectory(mimetypes)
 
 include_directories(${CMAKE_CURRENT_BINARY_DIR})
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
 if (NOT DISABLE_KWATCHGNUPG)
     add_subdirectory(kwatchgnupg)
 endif()
 add_subdirectory(libkleopatraclient)
 add_subdirectory(conf)
 add_subdirectory(kconf_update)
 
 if(WIN32)
   set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_win.cpp)
   set(_kleopatra_extra_SRCS
       selftest/registrycheck.cpp
       utils/gnupg-registry.c
       utils/userinfo_win.cpp
       utils/windowsprocessdevice.cpp
   )
 else()
   set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_unix.cpp)
   set(_kleopatra_extra_SRCS)
 endif()
 
 set(_kleopatra_uiserver_SRCS
     ${_kleopatra_extra_uiserver_SRCS}
 
     selftest/uiservercheck.cpp
     uiserver/assuanserverconnection.cpp
     uiserver/createchecksumscommand.cpp
     uiserver/decryptverifycommandemailbase.cpp
     uiserver/decryptverifycommandfilesbase.cpp
     uiserver/echocommand.cpp
     uiserver/encryptcommand.cpp
     uiserver/importfilescommand.cpp
     uiserver/prepencryptcommand.cpp
     uiserver/prepsigncommand.cpp
     uiserver/selectcertificatecommand.cpp
     uiserver/sessiondata.cpp
     uiserver/signcommand.cpp
     uiserver/signencryptfilescommand.cpp
     uiserver/uiserver.cpp
     uiserver/verifychecksumscommand.cpp
   )
 
-if(ASSUAN2_FOUND)
   include_directories(${ASSUAN2_INCLUDES})
   set(_kleopatra_uiserver_extra_libs ${ASSUAN2_LIBRARIES})
-else()
-  include_directories(${ASSUAN_INCLUDES})
-  if(WIN32)
-    set(_kleopatra_uiserver_extra_libs ${ASSUAN_VANILLA_LIBRARIES})
-  else()
-    set(_kleopatra_uiserver_extra_libs ${ASSUAN_PTHREAD_LIBRARIES})
-  endif()
-endif()
 
 if(HAVE_GPG_ERR_SOURCE_KLEO)
   add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO)
   add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO)
 else()
   add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1)
   add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1)
 endif()
 
 if(KF5IdentityManagement_FOUND AND KF5MailTransport_FOUND AND KF5MailTransportAkonadi_FOUND)
   set(_kleopatra_mail_libs
       KF5::IdentityManagement # Export OpenPGP keys using WKS
       KF5::MailTransport
       KF5::MailTransportAkonadi
   )
   add_definitions(-DMAILAKONADI_ENABLED)
 endif()
 
 ki18n_wrap_ui(_kleopatra_uiserver_SRCS crypto/gui/signingcertificateselectionwidget.ui)
 
 set(_kleopatra_SRCS
   ${_kleopatra_extra_SRCS}
 
   accessibility/accessiblelink.cpp
   accessibility/accessiblelink_p.h
   accessibility/accessiblerichtextlabel.cpp
   accessibility/accessiblerichtextlabel_p.h
   accessibility/accessiblevaluelabel.cpp
   accessibility/accessiblevaluelabel_p.h
   accessibility/accessiblewidgetfactory.cpp
   accessibility/accessiblewidgetfactory.h
   commands/adduseridcommand.cpp
   commands/adduseridcommand.h
   commands/authenticatepivcardapplicationcommand.cpp
   commands/authenticatepivcardapplicationcommand.h
   commands/cardcommand.cpp
   commands/cardcommand.h
   commands/certificatetopivcardcommand.cpp
   commands/certificatetopivcardcommand.h
   commands/certifycertificatecommand.cpp
   commands/certifycertificatecommand.h
   commands/changeexpirycommand.cpp
   commands/changeexpirycommand.h
   commands/changeownertrustcommand.cpp
   commands/changeownertrustcommand.h
   commands/changepassphrasecommand.cpp
   commands/changepassphrasecommand.h
   commands/changepincommand.cpp
   commands/changepincommand.h
   commands/changeroottrustcommand.cpp
   commands/changeroottrustcommand.h
   commands/checksumcreatefilescommand.cpp
   commands/checksumcreatefilescommand.h
   commands/checksumverifyfilescommand.cpp
   commands/checksumverifyfilescommand.h
   commands/clearcrlcachecommand.cpp
   commands/clearcrlcachecommand.h
   commands/command.cpp
   commands/command.h
   commands/createcsrforcardkeycommand.cpp
   commands/createcsrforcardkeycommand.h
   commands/createopenpgpkeyfromcardkeyscommand.cpp
   commands/createopenpgpkeyfromcardkeyscommand.h
   commands/decryptverifyclipboardcommand.cpp
   commands/decryptverifyclipboardcommand.h
   commands/decryptverifyfilescommand.cpp
   commands/decryptverifyfilescommand.h
   commands/deletecertificatescommand.cpp
   commands/deletecertificatescommand.h
   commands/detailscommand.cpp
   commands/detailscommand.h
   commands/dumpcertificatecommand.cpp
   commands/dumpcertificatecommand.h
   commands/dumpcrlcachecommand.cpp
   commands/dumpcrlcachecommand.h
   commands/encryptclipboardcommand.cpp
   commands/encryptclipboardcommand.h
   commands/exportcertificatecommand.cpp
   commands/exportcertificatecommand.h
   commands/exportgroupscommand.cpp
   commands/exportgroupscommand.h
   commands/exportopenpgpcertstoservercommand.cpp
   commands/exportopenpgpcertstoservercommand.h
   commands/exportopenpgpcerttoprovidercommand.cpp
   commands/exportopenpgpcerttoprovidercommand.h
   commands/exportpaperkeycommand.cpp
   commands/exportpaperkeycommand.h
   commands/exportsecretkeycommand.cpp
   commands/exportsecretkeycommand.h
   commands/exportsecretkeycommand_old.cpp
   commands/exportsecretkeycommand_old.h
   commands/exportsecretsubkeycommand.cpp
   commands/exportsecretsubkeycommand.h
   commands/genrevokecommand.cpp
   commands/genrevokecommand.h
   commands/gnupgprocesscommand.cpp
   commands/gnupgprocesscommand.h
   commands/importcertificatefromclipboardcommand.cpp
   commands/importcertificatefromclipboardcommand.h
   commands/importcertificatefromdatacommand.cpp
   commands/importcertificatefromdatacommand.h
   commands/importcertificatefromfilecommand.cpp
   commands/importcertificatefromfilecommand.h
   commands/importcertificatefromkeyservercommand.cpp
   commands/importcertificatefromkeyservercommand.h
   commands/importcertificatefrompivcardcommand.cpp
   commands/importcertificatefrompivcardcommand.h
   commands/importcertificatescommand.cpp
   commands/importcertificatescommand.h
   commands/importcrlcommand.cpp
   commands/importcrlcommand.h
   commands/importpaperkeycommand.cpp
   commands/importpaperkeycommand.h
   commands/keytocardcommand.cpp
   commands/keytocardcommand.h
   commands/learncardkeyscommand.cpp
   commands/learncardkeyscommand.h
   commands/lookupcertificatescommand.cpp
   commands/lookupcertificatescommand.h
   commands/newcertificatesigningrequestcommand.cpp
   commands/newcertificatesigningrequestcommand.h
   commands/newopenpgpcertificatecommand.cpp
   commands/newopenpgpcertificatecommand.h
   commands/openpgpgeneratecardkeycommand.cpp
   commands/openpgpgeneratecardkeycommand.h
   commands/pivgeneratecardkeycommand.cpp
   commands/pivgeneratecardkeycommand.h
   commands/refreshcertificatecommand.cpp
   commands/refreshcertificatecommand.h
   commands/refreshopenpgpcertscommand.cpp
   commands/refreshopenpgpcertscommand.h
   commands/refreshx509certscommand.cpp
   commands/refreshx509certscommand.h
   commands/reloadkeyscommand.cpp
   commands/reloadkeyscommand.h
   commands/revokecertificationcommand.cpp
   commands/revokecertificationcommand.h
   commands/revokekeycommand.cpp
   commands/revokekeycommand.h
   commands/revokeuseridcommand.cpp
   commands/revokeuseridcommand.h
   commands/selftestcommand.cpp
   commands/selftestcommand.h
   commands/setinitialpincommand.cpp
   commands/setinitialpincommand.h
   commands/setpivcardapplicationadministrationkeycommand.cpp
   commands/setpivcardapplicationadministrationkeycommand.h
   commands/setprimaryuseridcommand.cpp
   commands/setprimaryuseridcommand.h
   commands/signclipboardcommand.cpp
   commands/signclipboardcommand.h
   commands/signencryptfilescommand.cpp
   commands/signencryptfilescommand.h
   commands/signencryptfoldercommand.cpp
   commands/signencryptfoldercommand.h
   conf/configuredialog.cpp
   conf/configuredialog.h
   conf/groupsconfigdialog.cpp
   conf/groupsconfigdialog.h
   conf/groupsconfigpage.cpp
   conf/groupsconfigpage.h
   conf/groupsconfigwidget.cpp
   conf/groupsconfigwidget.h
   crypto/autodecryptverifyfilescontroller.cpp
   crypto/autodecryptverifyfilescontroller.h
   crypto/certificateresolver.cpp
   crypto/certificateresolver.h
   crypto/checksumsutils_p.cpp
   crypto/checksumsutils_p.h
   crypto/controller.cpp
   crypto/controller.h
   crypto/createchecksumscontroller.cpp
   crypto/createchecksumscontroller.h
   crypto/decryptverifyemailcontroller.cpp
   crypto/decryptverifyemailcontroller.h
   crypto/decryptverifyfilescontroller.cpp
   crypto/decryptverifyfilescontroller.h
   crypto/decryptverifytask.cpp
   crypto/decryptverifytask.h
   crypto/encryptemailcontroller.cpp
   crypto/encryptemailcontroller.h
   crypto/encryptemailtask.cpp
   crypto/encryptemailtask.h
   crypto/gui/certificatelineedit.cpp
   crypto/gui/certificatelineedit.h
   crypto/gui/certificateselectionline.cpp
   crypto/gui/certificateselectionline.h
   crypto/gui/decryptverifyfilesdialog.cpp
   crypto/gui/decryptverifyfilesdialog.h
   crypto/gui/decryptverifyfileswizard.cpp
   crypto/gui/decryptverifyfileswizard.h
   crypto/gui/decryptverifyoperationwidget.cpp
   crypto/gui/decryptverifyoperationwidget.h
   crypto/gui/encryptemailwizard.cpp
   crypto/gui/encryptemailwizard.h
   crypto/gui/newresultpage.cpp
   crypto/gui/newresultpage.h
   crypto/gui/objectspage.cpp
   crypto/gui/objectspage.h
   crypto/gui/resolverecipientspage.cpp
   crypto/gui/resolverecipientspage.h
   crypto/gui/resultitemwidget.cpp
   crypto/gui/resultitemwidget.h
   crypto/gui/resultlistwidget.cpp
   crypto/gui/resultlistwidget.h
   crypto/gui/resultpage.cpp
   crypto/gui/resultpage.h
   crypto/gui/signemailwizard.cpp
   crypto/gui/signemailwizard.h
   crypto/gui/signencryptemailconflictdialog.cpp
   crypto/gui/signencryptemailconflictdialog.h
   crypto/gui/signencryptfileswizard.cpp
   crypto/gui/signencryptfileswizard.h
   crypto/gui/signencryptwidget.cpp
   crypto/gui/signencryptwidget.h
   crypto/gui/signencryptwizard.cpp
   crypto/gui/signencryptwizard.h
   crypto/gui/signerresolvepage.cpp
   crypto/gui/signerresolvepage.h
   crypto/gui/signingcertificateselectiondialog.cpp
   crypto/gui/signingcertificateselectiondialog.h
   crypto/gui/signingcertificateselectionwidget.cpp
   crypto/gui/signingcertificateselectionwidget.h
   crypto/gui/unknownrecipientwidget.cpp
   crypto/gui/unknownrecipientwidget.h
   crypto/gui/verifychecksumsdialog.cpp
   crypto/gui/verifychecksumsdialog.h
   crypto/gui/wizard.cpp
   crypto/gui/wizard.h
   crypto/gui/wizardpage.cpp
   crypto/gui/wizardpage.h
   crypto/newsignencryptemailcontroller.cpp
   crypto/newsignencryptemailcontroller.h
   crypto/recipient.cpp
   crypto/recipient.h
   crypto/sender.cpp
   crypto/sender.h
   crypto/signemailcontroller.cpp
   crypto/signemailcontroller.h
   crypto/signemailtask.cpp
   crypto/signemailtask.h
   crypto/signencryptfilescontroller.cpp
   crypto/signencryptfilescontroller.h
   crypto/signencrypttask.cpp
   crypto/signencrypttask.h
   crypto/task.cpp
   crypto/task.h
   crypto/taskcollection.cpp
   crypto/taskcollection.h
   crypto/verifychecksumscontroller.cpp
   crypto/verifychecksumscontroller.h
   dialogs/adduseriddialog.cpp
   dialogs/adduseriddialog.h
   dialogs/certificatedetailsdialog.cpp
   dialogs/certificatedetailsdialog.h
   dialogs/certificatedetailsinputwidget.cpp
   dialogs/certificatedetailsinputwidget.h
   dialogs/certificatedetailswidget.cpp
   dialogs/certificatedetailswidget.h
   dialogs/certificateselectiondialog.cpp
   dialogs/certificateselectiondialog.h
   dialogs/certifycertificatedialog.cpp
   dialogs/certifycertificatedialog.h
   dialogs/certifywidget.cpp
   dialogs/certifywidget.h
   dialogs/createcsrforcardkeydialog.cpp
   dialogs/createcsrforcardkeydialog.h
   dialogs/deletecertificatesdialog.cpp
   dialogs/deletecertificatesdialog.h
   dialogs/editgroupdialog.cpp
   dialogs/editgroupdialog.h
   dialogs/expirydialog.cpp
   dialogs/expirydialog.h
   dialogs/exportdialog.cpp
   dialogs/exportdialog.h
   dialogs/gencardkeydialog.cpp
   dialogs/gencardkeydialog.h
   dialogs/groupdetailsdialog.cpp
   dialogs/groupdetailsdialog.h
   dialogs/lookupcertificatesdialog.cpp
   dialogs/lookupcertificatesdialog.h
   dialogs/nameandemailwidget.cpp
   dialogs/nameandemailwidget.h
   dialogs/newopenpgpcertificatedetailsdialog.cpp
   dialogs/newopenpgpcertificatedetailsdialog.h
   dialogs/pivcardapplicationadministrationkeyinputdialog.cpp
   dialogs/pivcardapplicationadministrationkeyinputdialog.h
   dialogs/revokekeydialog.cpp
   dialogs/revokekeydialog.h
   dialogs/selftestdialog.cpp
   dialogs/selftestdialog.h
   dialogs/setinitialpindialog.cpp
   dialogs/setinitialpindialog.h
   dialogs/subkeyswidget.cpp
   dialogs/subkeyswidget.h
   dialogs/trustchainwidget.cpp
   dialogs/trustchainwidget.h
   dialogs/updatenotification.cpp
   dialogs/updatenotification.h
   dialogs/weboftrustdialog.cpp
   dialogs/weboftrustdialog.h
   dialogs/weboftrustwidget.cpp
   dialogs/weboftrustwidget.h
   interfaces/anchorprovider.h
   interfaces/focusfirstchild.h
   newcertificatewizard/advancedsettingsdialog.cpp
   newcertificatewizard/advancedsettingsdialog_p.h
   newcertificatewizard/enterdetailspage.cpp
   newcertificatewizard/enterdetailspage_p.h
   newcertificatewizard/keyalgo.cpp
   newcertificatewizard/keyalgo_p.h
   newcertificatewizard/keycreationpage.cpp
   newcertificatewizard/keycreationpage_p.h
   newcertificatewizard/listwidget.cpp
   newcertificatewizard/listwidget.h
   newcertificatewizard/newcertificatewizard.cpp
   newcertificatewizard/newcertificatewizard.h
   newcertificatewizard/resultpage.cpp
   newcertificatewizard/resultpage_p.h
   newcertificatewizard/wizardpage.cpp
   newcertificatewizard/wizardpage_p.h
   selftest/compliancecheck.cpp
   selftest/compliancecheck.h
   selftest/enginecheck.cpp
   selftest/enginecheck.h
   selftest/gpgagentcheck.cpp
   selftest/gpgagentcheck.h
   selftest/gpgconfcheck.cpp
   selftest/gpgconfcheck.h
   selftest/libkleopatrarccheck.cpp
   selftest/libkleopatrarccheck.h
   selftest/selftest.cpp
   selftest/selftest.h
   smartcard/algorithminfo.h
   smartcard/card.cpp
   smartcard/card.h
   smartcard/deviceinfowatcher.cpp
   smartcard/deviceinfowatcher.h
   smartcard/keypairinfo.cpp
   smartcard/keypairinfo.h
   smartcard/netkeycard.cpp
   smartcard/netkeycard.h
   smartcard/openpgpcard.cpp
   smartcard/openpgpcard.h
   smartcard/p15card.cpp
   smartcard/p15card.h
   smartcard/pivcard.cpp
   smartcard/pivcard.h
   smartcard/readerstatus.cpp
   smartcard/readerstatus.h
   smartcard/utils.cpp
   smartcard/utils.h
   utils/accessibility.cpp
   utils/accessibility.h
   utils/action_data.cpp
   utils/action_data.h
   utils/applicationstate.cpp
   utils/applicationstate.h
   utils/archivedefinition.cpp
   utils/archivedefinition.h
   utils/clipboardmenu.cpp
   utils/clipboardmenu.h
   utils/debug-helpers.cpp
   utils/debug-helpers.h
   utils/dragqueen.cpp
   utils/dragqueen.h
   utils/email.cpp
   utils/email.h
   utils/emptypassphraseprovider.cpp
   utils/emptypassphraseprovider.h
   utils/filedialog.cpp
   utils/filedialog.h
   utils/gui-helper.cpp
   utils/gui-helper.h
   utils/headerview.cpp
   utils/headerview.h
   utils/input.cpp
   utils/input.h
   utils/iodevicelogger.cpp
   utils/iodevicelogger.h
   utils/kdpipeiodevice.cpp
   utils/kdpipeiodevice.h
   utils/keyparameters.cpp
   utils/keyparameters.h
   utils/keys.cpp
   utils/keys.h
   utils/kuniqueservice.cpp
   utils/kuniqueservice.h
   utils/log.cpp
   utils/log.h
   utils/memory-helpers.h
   utils/multivalidator.cpp
   utils/multivalidator.h
   utils/output.cpp
   utils/output.h
   utils/path-helper.cpp
   utils/path-helper.h
   utils/scrollarea.cpp
   utils/scrollarea.h
   utils/systemtrayicon.cpp
   utils/systemtrayicon.h
   utils/tags.cpp
   utils/tags.h
   utils/types.cpp
   utils/types.h
   utils/userinfo.cpp
   utils/userinfo.h
   utils/validation.cpp
   utils/validation.h
   utils/writecertassuantransaction.cpp
   utils/writecertassuantransaction.h
   utils/wsastarter.cpp
   utils/wsastarter.h
   view/anchorcache.cpp
   view/anchorcache_p.h
   view/errorlabel.cpp
   view/errorlabel.h
   view/formtextinput.cpp
   view/formtextinput.h
   view/htmllabel.cpp
   view/htmllabel.h
   view/infofield.cpp
   view/infofield.h
   view/keycacheoverlay.cpp
   view/keycacheoverlay.h
   view/keylistcontroller.cpp
   view/keylistcontroller.h
   view/keytreeview.cpp
   view/keytreeview.h
   view/netkeywidget.cpp
   view/netkeywidget.h
   view/nullpinwidget.cpp
   view/nullpinwidget.h
   view/openpgpkeycardwidget.cpp
   view/openpgpkeycardwidget.h
   view/p15cardwidget.cpp
   view/p15cardwidget.h
   view/padwidget.cpp
   view/padwidget.h
   view/pgpcardwidget.cpp
   view/pgpcardwidget.h
   view/pivcardwidget.cpp
   view/pivcardwidget.h
   view/searchbar.cpp
   view/searchbar.h
   view/smartcardwidget.cpp
   view/smartcardwidget.h
   view/tabwidget.cpp
   view/tabwidget.h
   view/urllabel.cpp
   view/urllabel.h
   view/waitwidget.cpp
   view/waitwidget.h
   view/welcomewidget.cpp
   view/welcomewidget.h
 
   aboutdata.cpp
   aboutdata.h
   kleopatra.qrc
   kleopatraapplication.cpp
   kleopatraapplication.h
   main.cpp
   mainwindow.cpp
   mainwindow.h
   systrayicon.cpp
   systrayicon.h
 )
 
 if(WIN32)
   configure_file (versioninfo.rc.in versioninfo.rc)
   set(_kleopatra_SRCS ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc ${_kleopatra_SRCS})
 endif()
 
 set (_kleopatra_SRCS conf/kleopageconfigdialog.cpp ${_kleopatra_SRCS})
 
 ecm_qt_declare_logging_category(_kleopatra_SRCS HEADER kleopatra_debug.h IDENTIFIER KLEOPATRA_LOG CATEGORY_NAME org.kde.pim.kleopatra
         DESCRIPTION "kleopatra (kleopatra)"
         OLD_CATEGORY_NAMES log_kleopatra
         EXPORT KLEOPATRA
     )
 
 
 if(KLEO_MODEL_TEST)
   add_definitions(-DKLEO_MODEL_TEST)
   set(_kleopatra_SRCS ${_kleopatra_SRCS} models/modeltest.cpp)
 endif()
 
 ki18n_wrap_ui(_kleopatra_SRCS
   dialogs/selectchecklevelwidget.ui
   dialogs/setinitialpindialog.ui
   dialogs/trustchainwidget.ui
   newcertificatewizard/listwidget.ui
 )
 
 kconfig_add_kcfg_files(_kleopatra_SRCS
   kcfg/emailoperationspreferences.kcfgc
   kcfg/fileoperationspreferences.kcfgc
   kcfg/settings.kcfgc
   kcfg/smimevalidationpreferences.kcfgc
   kcfg/tagspreferences.kcfgc
   kcfg/tooltippreferences.kcfgc
 )
 
 file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*-apps-kleopatra.png")
 ecm_add_app_icon(_kleopatra_SRCS ICONS ${ICONS_SRCS})
 
 add_executable(kleopatra_bin ${_kleopatra_SRCS} ${_kleopatra_uiserver_SRCS})
 
 # For the ConfigureDialog & KCMs
 target_link_libraries(kleopatra_bin kcm_kleopatra_static)
 
 #if (COMPILE_WITH_UNITY_CMAKE_SUPPORT)
 #    set_target_properties(kleopatra_bin PROPERTIES UNITY_BUILD ON)
 #endif()
 set_target_properties(kleopatra_bin PROPERTIES OUTPUT_NAME kleopatra)
 
 if (WIN32)
   set(_kleopatra_platform_libs "secur32")
 endif ()
 
 target_link_libraries(kleopatra_bin
   Gpgmepp
   ${_kleopatra_extra_libs}
   KF5::Libkleo
   KF5::Mime
   KF5::I18n
   KF5::XmlGui
   KF5::IconThemes
   KF5::WindowSystem
   KF5::CoreAddons
   KF5::ItemModels
   KF5::Crash
   ${_kleopatra_mail_libs}
   Qt::Network
   Qt::PrintSupport # Printing secret keys
   ${_kleopatra_uiserver_extra_libs}
   ${_kleopatra_dbusaddons_libs}
   kleopatraclientcore
   ${_kleopatra_platform_libs}
 )
 
 if (QT_MAJOR_VERSION STREQUAL "6")
     target_link_libraries(kleopatra_bin QGpgmeQt6)
 else()
     target_link_libraries(kleopatra_bin QGpgme)
 endif()
 
 install(TARGETS kleopatra_bin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
 
 install(
   PROGRAMS data/org.kde.kleopatra.desktop data/kleopatra_import.desktop
   DESTINATION ${KDE_INSTALL_APPDIR}
 )
 install(FILES data/org.kde.kleopatra.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
 install(
   PROGRAMS data/kleopatra_signencryptfiles.desktop
         data/kleopatra_signencryptfolders.desktop
         data/kleopatra_decryptverifyfiles.desktop
         data/kleopatra_decryptverifyfolders.desktop
   DESTINATION ${KDE_INSTALL_DATADIR}/kio/servicemenus
 )
diff --git a/src/libkleopatraclient/core/CMakeLists.txt b/src/libkleopatraclient/core/CMakeLists.txt
index 68b738525..eb03c6c1e 100644
--- a/src/libkleopatraclient/core/CMakeLists.txt
+++ b/src/libkleopatraclient/core/CMakeLists.txt
@@ -1,74 +1,59 @@
 # SPDX-FileCopyrightText: none
 # SPDX-License-Identifier: BSD-3-Clause
 
 if(WIN32)
   set(_kleopatraclientcore_extra_SRCS ../../utils/gnupg-registry.c)
 else()
   set(_kleopatraclientcore_extra_SRCS)
 endif()
 
 ecm_qt_declare_logging_category(_kleopatraclientcore_common_SRCS HEADER libkleopatraclientcore_debug.h IDENTIFIER LIBKLEOPATRACLIENTCORE_LOG CATEGORY_NAME org.kde.pim.libkleopatraclientcore
         DESCRIPTION "kleopatra (kleopatra)"
         OLD_CATEGORY_NAMES log_libkleopatraclientcore
         EXPORT KLEOPATRA
     )
 
 
 add_library(kleopatraclientcore
   ${_kleopatraclientcore_extra_SRCS}
   initialization.cpp
   command.cpp
   selectcertificatecommand.cpp
   signencryptfilescommand.cpp
   decryptverifyfilescommand.cpp
   libkleopatraclientcore_debug.cpp
   initialization.h
   command.h
   selectcertificatecommand.h
   signencryptfilescommand.h
   decryptverifyfilescommand.h
   libkleopatraclientcore_debug.h
   ${_kleopatraclientcore_common_SRCS}
 )
 generate_export_header(kleopatraclientcore BASE_NAME kleopatraclientcore)
 
 set_target_properties(kleopatraclientcore PROPERTIES
   VERSION ${libkleopatraclient_version}
   SOVERSION ${libkleopatraclient_soversion}
 )
 if (COMPILE_WITH_UNITY_CMAKE_SUPPORT)
     set_target_properties(kleopatraclientcore PROPERTIES UNITY_BUILD ON)
 endif()
 
 
 if(WIN32)
-  if(ASSUAN2_FOUND)
     target_link_libraries(kleopatraclientcore
       
       ${ASSUAN2_LIBRARIES}
       ws2_32
     )
-  else()
-    target_link_libraries(kleopatraclientcore
-      
-      ${ASSUAN_VANILLA_LIBRARIES}
-      ws2_32
-    )
-  endif()
 else()
-  if(ASSUAN2_FOUND)
     target_link_libraries(kleopatraclientcore
       
       ${ASSUAN2_LIBRARIES}
     )
-  else()
-    target_link_libraries(kleopatraclientcore
-      
-      ${ASSUAN_PTHREAD_LIBRARIES}
-    )
-  endif()
 endif()
 
 target_link_libraries(kleopatraclientcore Qt::Widgets KF5::I18n Gpgmepp)
 
 install(TARGETS kleopatraclientcore ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
diff --git a/src/libkleopatraclient/core/command.cpp b/src/libkleopatraclient/core/command.cpp
index cef2a1f1f..8476a4907 100644
--- a/src/libkleopatraclient/core/command.cpp
+++ b/src/libkleopatraclient/core/command.cpp
@@ -1,702 +1,678 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     command.cpp
 
     This file is part of KleopatraClient, the Kleopatra interface library
     SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: LGPL-2.0-or-later
 */
 
 #include <config-kleopatra.h>
 
 #include "command.h"
 #include "command_p.h"
 
 #include <QtGlobal> // Q_OS_WIN
 
 #ifdef Q_OS_WIN // HACK: AllowSetForegroundWindow needs _WIN32_WINDOWS >= 0x0490 set
 # ifndef _WIN32_WINDOWS
 #  define _WIN32_WINDOWS 0x0500
 # endif
 # ifndef _WIN32_WINNT
 #  define _WIN32_WINNT 0x0500 // good enough for Vista too
 # endif
 # include <utils/gnupg-registry.h>
 # include <windows.h>
 #endif
 
 #include <QMutexLocker>
 #include <QFile>
 #include "libkleopatraclientcore_debug.h"
 #include <QDir>
 #include <QProcess>
 #include <KLocalizedString>
 
 #include <assuan.h>
 #include <gpg-error.h>
 #include <gpgme++/global.h>
 
 #include <algorithm>
 #include <string>
 #include <sstream>
 #include <memory>
 #include <type_traits>
 
 using namespace KleopatraClientCopy;
 
 // copied from kleopatra/utils/hex.cpp
 static std::string hexencode(const std::string &in)
 {
     std::string result;
     result.reserve(3 * in.size());
 
     static const char hex[] = "0123456789ABCDEF";
 
     for (std::string::const_iterator it = in.begin(), end = in.end(); it != end; ++it)
         switch (const unsigned char ch = *it) {
         default:
             if ((ch >= '!' && ch <= '~') || ch > 0xA0) {
                 result += ch;
                 break;
             }
             Q_FALLTHROUGH();
         // else fall through
         case ' ':
             result += '+';
             break;
         case '"':
         case '#':
         case '$':
         case '%':
         case '\'':
         case '+':
         case '=':
             result += '%';
             result += hex[(ch & 0xF0) >> 4 ];
             result += hex[(ch & 0x0F)      ];
             break;
         }
 
     return result;
 }
 
 #ifdef UNUSED
 static std::string hexencode(const char *in)
 {
     if (!in) {
         return std::string();
     }
     return hexencode(std::string(in));
 }
 #endif
 
 // changed from returning QByteArray to returning std::string
 static std::string hexencode(const QByteArray &in)
 {
     if (in.isNull()) {
         return std::string();
     }
     return hexencode(std::string(in.data(), in.size()));
 }
 // end copied from kleopatra/utils/hex.cpp
 
 Command::Command(QObject *p)
     : QObject(p), d(new Private(this))
 {
     d->init();
 }
 
 Command::Command(Private *pp, QObject *p)
     : QObject(p), d(pp)
 {
     d->init();
 }
 
 Command::~Command()
 {
     delete d; d = nullptr;
 }
 
 void Command::Private::init()
 {
     connect(this, &QThread::started,  q, &Command::started);
     connect(this, &QThread::finished, q, &Command::finished);
 }
 
 void Command::setParentWId(WId wid)
 {
     const QMutexLocker locker(&d->mutex);
     d->inputs.parentWId = wid;
 }
 
 WId Command::parentWId() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->inputs.parentWId;
 }
 
 void Command::setServerLocation(const QString &location)
 {
     const QMutexLocker locker(&d->mutex);
     d->outputs.serverLocation = location;
 }
 
 QString Command::serverLocation() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->outputs.serverLocation;
 }
 
 bool Command::waitForFinished()
 {
     return d->wait();
 }
 
 bool Command::waitForFinished(unsigned long ms)
 {
     return d->wait(ms);
 }
 
 bool Command::error() const
 {
     const QMutexLocker locker(&d->mutex);
     return !d->outputs.errorString.isEmpty();
 }
 
 bool Command::wasCanceled() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->outputs.canceled;
 }
 
 QString Command::errorString() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->outputs.errorString;
 }
 
 qint64 Command::serverPid() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->outputs.serverPid;
 }
 
 void Command::start()
 {
     d->start();
 }
 
 void Command::cancel()
 {
     qCDebug(LIBKLEOPATRACLIENTCORE_LOG) << "Sorry, not implemented: KleopatraClient::Command::Cancel";
 }
 
 void Command::setOptionValue(const char *name, const QVariant &value, bool critical)
 {
     if (!name || !*name) {
         return;
     }
     const Private::Option opt = {
         value,
         true,
         critical
     };
     const QMutexLocker locker(&d->mutex);
     d->inputs.options[name] = opt;
 }
 
 QVariant Command::optionValue(const char *name) const
 {
     if (!name || !*name) {
         return QVariant();
     }
     const QMutexLocker locker(&d->mutex);
 
     const auto it = d->inputs.options.find(name);
     if (it == d->inputs.options.end()) {
         return QVariant();
     } else {
         return it->second.value;
     }
 }
 
 void Command::setOption(const char *name, bool critical)
 {
     if (!name || !*name) {
         return;
     }
     const QMutexLocker locker(&d->mutex);
 
     if (isOptionSet(name)) {
         unsetOption(name);
     }
 
     const Private::Option opt = {
         QVariant(),
         false,
         critical
     };
 
     d->inputs.options[name] = opt;
 }
 
 void Command::unsetOption(const char *name)
 {
     if (!name || !*name) {
         return;
     }
     const QMutexLocker locker(&d->mutex);
     d->inputs.options.erase(name);
 }
 
 bool Command::isOptionSet(const char *name) const
 {
     if (!name || !*name) {
         return false;
     }
     const QMutexLocker locker(&d->mutex);
     return d->inputs.options.count(name);
 }
 
 bool Command::isOptionCritical(const char *name) const
 {
     if (!name || !*name) {
         return false;
     }
     const QMutexLocker locker(&d->mutex);
     const auto it = d->inputs.options.find(name);
     return it != d->inputs.options.end() && it->second.isCritical;
 }
 
 void Command::setFilePaths(const QStringList &filePaths)
 {
     const QMutexLocker locker(&d->mutex);
     d->inputs.filePaths = filePaths;
 }
 
 QStringList Command::filePaths() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->inputs.filePaths;
 }
 
 void Command::setRecipients(const QStringList &recipients, bool informative)
 {
     const QMutexLocker locker(&d->mutex);
     d->inputs.recipients = recipients;
     d->inputs.areRecipientsInformative = informative;
 }
 
 QStringList Command::recipients() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->inputs.recipients;
 }
 
 bool Command::areRecipientsInformative() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->inputs.areRecipientsInformative;
 }
 
 void Command::setSenders(const QStringList &senders, bool informative)
 {
     const QMutexLocker locker(&d->mutex);
     d->inputs.senders = senders;
     d->inputs.areSendersInformative = informative;
 }
 
 QStringList Command::senders() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->inputs.senders;
 }
 
 bool Command::areSendersInformative() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->inputs.areSendersInformative;
 }
 
 void Command::setInquireData(const char *what, const QByteArray &data)
 {
     const QMutexLocker locker(&d->mutex);
     d->inputs.inquireData[what] = data;
 }
 
 void Command::unsetInquireData(const char *what)
 {
     const QMutexLocker locker(&d->mutex);
     d->inputs.inquireData.erase(what);
 }
 
 QByteArray Command::inquireData(const char *what) const
 {
     const QMutexLocker locker(&d->mutex);
     const auto it = d->inputs.inquireData.find(what);
     if (it == d->inputs.inquireData.end()) {
         return QByteArray();
     } else {
         return it->second;
     }
 }
 
 bool Command::isInquireDataSet(const char *what) const
 {
     const QMutexLocker locker(&d->mutex);
     const auto it = d->inputs.inquireData.find(what);
     return it != d->inputs.inquireData.end();
 }
 
 QByteArray Command::receivedData() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->outputs.data;
 }
 
 void Command::setCommand(const char *command)
 {
     const QMutexLocker locker(&d->mutex);
     d->inputs.command = command;
 }
 
 QByteArray Command::command() const
 {
     const QMutexLocker locker(&d->mutex);
     return d->inputs.command;
 }
 
 //
 // here comes the ugly part
 //
 
-#ifdef HAVE_ASSUAN2
 static void my_assuan_release(assuan_context_t ctx)
 {
     if (ctx) {
         assuan_release(ctx);
     }
 }
-#endif
 
 using AssuanContextBase = std::shared_ptr<std::remove_pointer<assuan_context_t>::type>;
 namespace
 {
 struct AssuanClientContext : AssuanContextBase {
     AssuanClientContext() : AssuanContextBase() {}
-#ifndef HAVE_ASSUAN2
-    explicit AssuanClientContext(assuan_context_t ctx) : AssuanContextBase(ctx, &assuan_disconnect) {}
-    void reset(assuan_context_t ctx = nullptr)
-    {
-        AssuanContextBase::reset(ctx, &assuan_disconnect);
-    }
-#else
     explicit AssuanClientContext(assuan_context_t ctx) : AssuanContextBase(ctx, &my_assuan_release) {}
     void reset(assuan_context_t ctx = nullptr)
     {
         AssuanContextBase::reset(ctx, &my_assuan_release);
     }
-#endif
 };
 }
 
-#ifdef HAVE_ASSUAN2
 // compatibility typedef - remove when we require assuan v2...
 using assuan_error_t = gpg_error_t;
-#endif
 
 static assuan_error_t
 my_assuan_transact(const AssuanClientContext &ctx,
                    const char *command,
                    assuan_error_t (*data_cb)(void *, const void *, size_t) = nullptr,
                    void *data_cb_arg = nullptr,
                    assuan_error_t (*inquire_cb)(void *, const char *) = nullptr,
                    void *inquire_cb_arg = nullptr,
                    assuan_error_t (*status_cb)(void *, const char *) = nullptr,
                    void *status_cb_arg = nullptr)
 {
     return assuan_transact(ctx.get(), command, data_cb, data_cb_arg, inquire_cb, inquire_cb_arg, status_cb, status_cb_arg);
 }
 
 static QString to_error_string(int err)
 {
     char buffer[1024];
     gpg_strerror_r(static_cast<gpg_error_t>(err),
                    buffer, sizeof buffer);
     buffer[sizeof buffer - 1] = '\0';
     return QString::fromLocal8Bit(buffer);
 }
 
 static QString gnupg_home_directory()
 {
     static const char *hDir = GpgME::dirInfo("homedir");
     return QFile::decodeName(hDir);
 }
 
 static QString get_default_socket_name()
 {
     const QString socketPath{QString::fromUtf8(GpgME::dirInfo("uiserver-socket"))};
     if (!socketPath.isEmpty()) {
         // Note: The socket directory exists after GpgME::dirInfo() has been called.
         return socketPath;
     }
     const QString homeDir = gnupg_home_directory();
     if (homeDir.isEmpty()) {
         return QString();
     }
     return QDir(homeDir).absoluteFilePath(QStringLiteral("S.uiserver"));
 }
 
 static QString default_socket_name()
 {
     static QString name = get_default_socket_name();
     return name;
 }
 
 static QString uiserver_executable()
 {
     return QStringLiteral("kleopatra");
 }
 
 static QString start_uiserver()
 {
     // Warning: Don't assume that the program needs to be in PATH. On Windows, it will also be found next to the calling process.
     if (!QProcess::startDetached(uiserver_executable(), QStringList() << QStringLiteral("--daemon"))) {
         return i18n("Failed to start uiserver %1", uiserver_executable());
     } else {
         return QString();
     }
 }
 
 static assuan_error_t getinfo_pid_cb(void *opaque, const void *buffer, size_t length)
 {
     qint64 &pid = *static_cast<qint64 *>(opaque);
     pid = QByteArray(static_cast<const char *>(buffer), length).toLongLong();
     return 0;
 }
 
 static assuan_error_t command_data_cb(void *opaque, const void *buffer, size_t length)
 {
     QByteArray &ba = *static_cast<QByteArray *>(opaque);
     ba.append(QByteArray(static_cast<const char *>(buffer), length));
     return 0;
 }
 
 namespace
 {
 struct inquire_data {
     const std::map<std::string, QByteArray> *map;
     const AssuanClientContext *ctx;
 };
 }
 
 static assuan_error_t command_inquire_cb(void *opaque, const char *what)
 {
     if (!opaque) {
         return 0;
     }
     const inquire_data &id = *static_cast<const inquire_data *>(opaque);
     const auto it = id.map->find(what);
     if (it != id.map->end()) {
         const QByteArray &v = it->second;
         assuan_send_data(id.ctx->get(), v.data(), v.size());
     }
     return 0;
 }
 
 static inline std::ostream &operator<<(std::ostream &s, const QByteArray &ba)
 {
     return s << std::string(ba.data(), ba.size());
 }
 
 static assuan_error_t send_option(const AssuanClientContext &ctx, const char *name, const QVariant &value)
 {
     std::stringstream ss;
     ss << "OPTION " << name;
     if (value.isValid()) {
         ss << '=' << value.toString().toUtf8();
     }
     return my_assuan_transact(ctx, ss.str().c_str());
 }
 
 static assuan_error_t send_file(const AssuanClientContext &ctx, const QString &file)
 {
     std::stringstream ss;
     ss << "FILE " << hexencode(QFile::encodeName(file));
     return my_assuan_transact(ctx, ss.str().c_str());
 }
 
 static assuan_error_t send_recipient(const AssuanClientContext &ctx, const QString &recipient, bool info)
 {
     std::stringstream ss;
     ss << "RECIPIENT ";
     if (info) {
         ss << "--info ";
     }
     ss << "--" << hexencode(recipient.toUtf8());
     return my_assuan_transact(ctx, ss.str().c_str());
 }
 
 static assuan_error_t send_sender(const AssuanClientContext &ctx, const QString &sender, bool info)
 {
     std::stringstream ss;
     ss << "SENDER ";
     if (info) {
         ss << "--info ";
     }
     ss << "--" << hexencode(sender.toUtf8());
     return my_assuan_transact(ctx, ss.str().c_str());
 }
 
 void Command::Private::run()
 {
 
     // Take a snapshot of the input data, and clear the output data:
     Inputs in;
     Outputs out;
     {
         const QMutexLocker locker(&mutex);
         in = inputs;
         outputs = out;
     }
 
     out.canceled = false;
 
     if (out.serverLocation.isEmpty()) {
         out.serverLocation = default_socket_name();
     }
 
-#ifndef HAVE_ASSUAN2
-    assuan_context_t naked_ctx = 0;
-#endif
     AssuanClientContext ctx;
     assuan_error_t err = 0;
 
     inquire_data id = { &in.inquireData, &ctx };
 
     const QString socketName = out.serverLocation;
     if (socketName.isEmpty()) {
         out.errorString = i18n("Invalid socket name!");
         goto leave;
     }
 
-#ifndef HAVE_ASSUAN2
-    err = assuan_socket_connect(&naked_ctx, socketName.toUtf8().constData(), -1);
-#else
     {
         assuan_context_t naked_ctx = nullptr;
         err = assuan_new(&naked_ctx);
         if (err) {
             out.errorString = i18n("Could not allocate resources to connect to Kleopatra UI server at %1: %2"
                                    , socketName, to_error_string(err));
             goto leave;
         }
 
         ctx.reset(naked_ctx);
     }
 
     err = assuan_socket_connect(ctx.get(), socketName.toUtf8().constData(), -1, 0);
-#endif
     if (err) {
         qDebug("UI server not running, starting it");
 
         const QString errorString = start_uiserver();
         if (!errorString.isEmpty()) {
             out.errorString = errorString;
             goto leave;
         }
 
         // give it a bit of time to start up and try a couple of times
         for (int i = 0; err && i < 20; ++i) {
             msleep(500);
             err = assuan_socket_connect(ctx.get(), socketName.toUtf8().constData(), -1, 0);
         }
     }
 
     if (err) {
         out.errorString = i18n("Could not connect to Kleopatra UI server at %1: %2",
                                socketName, to_error_string(err));
         goto leave;
     }
 
-#ifndef HAVE_ASSUAN2
-    ctx.reset(naked_ctx);
-    naked_ctx = 0;
-#endif
-
     out.serverPid = -1;
     err = my_assuan_transact(ctx, "GETINFO pid", &getinfo_pid_cb, &out.serverPid);
     if (err || out.serverPid <= 0) {
         out.errorString = i18n("Could not get the process-id of the Kleopatra UI server at %1: %2", socketName, to_error_string(err));
         goto leave;
     }
 
     qCDebug(LIBKLEOPATRACLIENTCORE_LOG) << "Server PID =" << out.serverPid;
 
 #if defined(Q_OS_WIN)
     if (!AllowSetForegroundWindow((pid_t)out.serverPid)) {
         qCDebug(LIBKLEOPATRACLIENTCORE_LOG) << "AllowSetForegroundWindow(" << out.serverPid << ") failed: " << GetLastError();
     }
 #endif
 
     if (in.command.isEmpty()) {
         goto leave;
     }
 
     if (in.parentWId) {
         err = send_option(ctx, "window-id", QString::number(in.parentWId, 16));
         if (err) {
             qDebug("sending option window-id failed - ignoring");
         }
     }
 
     for (auto it = in.options.begin(), end = in.options.end(); it != end; ++it)
         if ((err = send_option(ctx, it->first.c_str(), it->second.hasValue ? it->second.value.toString() : QVariant()))) {
             if (it->second.isCritical) {
                 out.errorString = i18n("Failed to send critical option %1: %2", QString::fromLatin1(it->first.c_str()), to_error_string(err));
                 goto leave;
             } else {
                 qCDebug(LIBKLEOPATRACLIENTCORE_LOG) << "Failed to send non-critical option" << it->first.c_str() << ":" << to_error_string(err);
             }
         }
 
     for (const QString &filePath : std::as_const(in.filePaths)) {
         if ((err = send_file(ctx, filePath))) {
             out.errorString = i18n("Failed to send file path %1: %2", filePath, to_error_string(err));
             goto leave;
         }
     }
 
     for (const QString &sender : std::as_const(in.senders)) {
         if ((err = send_sender(ctx, sender, in.areSendersInformative))) {
             out.errorString = i18n("Failed to send sender %1: %2", sender, to_error_string(err));
             goto leave;
         }
     }
 
     for (const QString &recipient : std::as_const(in.recipients)) {
         if ((err = send_recipient(ctx, recipient, in.areRecipientsInformative))) {
             out.errorString = i18n("Failed to send recipient %1: %2", recipient, to_error_string(err));
             goto leave;
         }
     }
 
 #if 0
     setup I / O;
 #endif
 
     err = my_assuan_transact(ctx, in.command.constData(), &command_data_cb, &out.data, &command_inquire_cb, &id);
     if (err) {
         if (gpg_err_code(err) == GPG_ERR_CANCELED) {
             out.canceled = true;
         } else {
             out.errorString = i18n("Command (%1) failed: %2", QString::fromLatin1(in.command.constData()), to_error_string(err));
         }
         goto leave;
     }
 
 leave:
     const QMutexLocker locker(&mutex);
     // copy outputs to where Command can see them:
     outputs = out;
 }
diff --git a/src/libkleopatraclient/core/initialization.cpp b/src/libkleopatraclient/core/initialization.cpp
index 86a46eb48..d3162f1c0 100644
--- a/src/libkleopatraclient/core/initialization.cpp
+++ b/src/libkleopatraclient/core/initialization.cpp
@@ -1,31 +1,27 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     initialization.h
 
     This file is part of KleopatraClient, the Kleopatra interface library
     SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: LGPL-2.0-or-later
 */
 
 #include <config-kleopatra.h>
 
 #include "initialization.h"
 
 #include <assuan.h>
 #include <gpg-error.h>
 
 using namespace KleopatraClientCopy;
 
 Initialization::Initialization()
 {
-#ifndef HAVE_ASSUAN2
-    assuan_set_assuan_err_source(GPG_ERR_SOURCE_DEFAULT);
-#else
     assuan_set_gpg_err_source(GPG_ERR_SOURCE_DEFAULT);
-#endif
 }
 
 Initialization::~Initialization()
 {
 
 }
diff --git a/src/uiserver/assuancommand.h b/src/uiserver/assuancommand.h
index 445ad4e9a..a0296930d 100644
--- a/src/uiserver/assuancommand.h
+++ b/src/uiserver/assuancommand.h
@@ -1,385 +1,370 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     uiserver/assuancommand.h
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #pragma once
 
 #include <utils/pimpl_ptr.h>
 #include <utils/types.h>
 
 #include <gpgme++/global.h>
 #include <gpgme++/error.h>
 
-#ifdef HAVE_ASSUAN2
 #include <gpg-error.h>
 
-#endif
 #include <KMime/HeaderParsing>
 
 #include <qwindowdefs.h> // for WId
 
 #include <memory>
 #include <string>
 #include <map>
 #include <vector>
 
 class QVariant;
 class QObject;
 #include <QStringList>
 
 struct assuan_context_s;
 
 namespace Kleo
 {
 
 class Input;
 class Output;
 
 class AssuanCommandFactory;
 
 /*!
   \brief Base class for GnuPG UI Server commands
 
   \note large parts of this are outdated by now!
 
   <h3>Implementing a new AssuanCommand</h3>
 
   You do not directly inherit AssuanCommand, unless you want to
   deal with implementing low-level, repetitive things like name()
   in terms of staticName(). Assuming you don't, then you inherit
   your command class from AssuanCommandMixin, passing your class
   as the template argument to AssuanCommandMixin, like this:
 
   \code
   class MyFooCommand : public AssuanCommandMixin<MyFooCommand> {
   \endcode
   (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)
 
   You then choose a command name, and return that from the static
   method staticName(), which is by convention queried by both
   AssuanCommandMixin<> and GenericAssuanCommandFactory<>:
 
   \code
       static const char * staticName() { return "MYFOO"; }
   \endcode
 
   The string should be all-uppercase by convention, but the
   UiServer implementation doesn't enforce this.
 
   The next step is to implement start(), the starting point of
   command execution:
 
   <h3>Executing the command</h3>
 
   \code
       int start( const std::string & line ) {
   \endcode
 
   This should set everything up and check the parameters in \a
   line and any options this command understands. If there's an
   error, choose one of the gpg-error codes and create a
   gpg_error_t from it using the protected makeError() function:
 
   \code
           return makeError( GPG_ERR_NOT_IMPLEMENTED );
   \endcode
 
   But usually, you will want to create a dialog, or call some
   GpgME function from here. In case of errors from GpgME, you
   shouldn't pipe them through makeError(), but return them
   as-is. This will preserve the error source. Error created using
   makeError() will have Kleopatra as their error source, so watch
   out what you're doing :)
 
   In addition to options and the command line, your command might
   require <em>bulk data</em> input or output. That's what the bulk
   input and output channels are for. You can check whether the
   client handed you an input channel by checking that
   bulkInputDevice() isn't NULL, likewise for bulkOutputDevice().
 
   If everything is ok, you return 0. This indicates to the client
   that the command has been accepted and is now in progress.
 
   In this mode (start() returned 0), there are a bunch of options
   for your command to do. Some commands may require additional
   information from the client. The options passed to start() are
   designed to be persistent across commands, and rather limited in
   length (there's a strict line length limit in the assuan
   protocol with no line continuation mechanism). The same is true
   for command line arguments, which, in addition, you have to
   parse yourself. Those usually apply only to this command, and
   not to following ones.
 
   If you need data that might be larger than the line length
   limit, you can either expect it on the bulkInputDevice(), or, if
   you have the need for more than one such data channel, or the
   data is optional or conditional on some condition that can only
   be determined during command execution, you can \em inquire the
   missing information from the client.
 
   As an example, a VERIFY command would expect the signed data on
   the bulkInputDevice(). But if the input stream doesn't contain
   an embedded (opaque) signature, indicating a \em detached
   signature, it would go and inquire that data from the
   client. Here's how it works:
 
   \code
   const int err = inquire( "DETACHED_SIGNATURE",
                            this, SLOT(slotDetachedSignature(int,QByteArray,QByteArray)) );
   if ( err )
       done( err );
   \endcode
 
   This should be self-explanatory: You give a slot to call when
   the data has arrived. The slot's first argument is an error
   code. The second the data (if any), and the third is just
   repeating what you gave as inquire()'s first argument. As usual,
   you can leave argument off of the end, if you are not interested
   in them.
 
   You can do as many inquiries as you want, but only one at a
   time.
 
   You should periodically send status updates to the client. You do
   that by calling sendStatus().
 
   Once your command has finished executing, call done(). If it's
   with an error code, call done(err) like above. <b>Do not
   forget to call done() when done!</b>. It will close
   bulkInputDevice(), bulkOutputDevice(), and send an OK or ERR
   message back to the client.
 
   At that point, your command has finished executing, and a new
   one can be accepted, or the connection closed.
 
   Apropos connection closed. The only way for the client to cancel
   an operation is to shut down the connection. In this case, the
   canceled() function will be called. At that point, the
   connection to the client will have been broken already, and all
   you can do is pack your things and go down gracefully.
 
   If _you_ detect that the user has canceled (your dialog contains
   a cancel button, doesn't it?), then you should instead call
   done( GPG_ERR_CANCELED ), like for normal operation.
 
   <h3>Registering the command with UiServer</h3>
 
   To register a command, you implement a AssuanCommandFactory for
   your AssuanCommand subclass, and register it with the
   UiServer. This can be made considerably easier using
   GenericAssuanCommandFactory:
 
   \code
   UiServer server;
   server.registerCommandFactory( shared_ptr<AssuanCommandFactory>( new GenericAssuanCommandFactory<MyFooCommand> ) );
   // more registerCommandFactory calls...
   server.start();
   \endcode
 
 */
 class AssuanCommand : public ExecutionContext, public std::enable_shared_from_this<AssuanCommand>
 {
     // defined in assuanserverconnection.cpp!
 public:
     AssuanCommand();
     ~AssuanCommand() override;
 
     int start();
     void canceled();
 
     virtual const char *name() const = 0;
 
     class Memento
     {
     public:
         virtual ~Memento() {}
     };
 
     template <typename T>
     class TypedMemento : public Memento
     {
         T m_t;
     public:
         explicit TypedMemento(const T &t) : m_t(t) {}
 
         const T &get() const
         {
             return m_t;
         }
         T &get()
         {
             return m_t;
         }
     };
 
     template <typename T>
     static std::shared_ptr< TypedMemento<T> > make_typed_memento(const T &t)
     {
         return std::shared_ptr< TypedMemento<T> >(new TypedMemento<T>(t));
     }
 
     static int makeError(int code);
 
     // convenience methods:
     enum Mode { NoMode, EMail, FileManager };
     Mode checkMode() const;
 
     enum CheckProtocolOption {
         AllowProtocolMissing = 0x01
     };
 
     GpgME::Protocol checkProtocol(Mode mode, int options = 0) const;
 
     void applyWindowID(QWidget *w) const override
     {
         doApplyWindowID(w);
     }
     WId parentWId() const;
 
     void setNohup(bool on);
     bool isNohup() const;
     bool isDone() const;
 
     QString sessionTitle() const;
     unsigned int sessionId() const;
 
     bool informativeRecipients() const;
     bool informativeSenders() const;
 
     const std::vector<KMime::Types::Mailbox> &recipients() const;
     const std::vector<KMime::Types::Mailbox> &senders() const;
 
     bool hasMemento(const QByteArray &tag) const;
     std::shared_ptr<Memento> memento(const QByteArray &tag) const;
     template <typename T>
     std::shared_ptr<T> mementoAs(const QByteArray &tag) const
     {
         return std::dynamic_pointer_cast<T>(this->memento(tag));
     }
     QByteArray registerMemento(const std::shared_ptr<Memento> &mem);
     QByteArray registerMemento(const QByteArray &tag, const std::shared_ptr<Memento> &mem);
     void removeMemento(const QByteArray &tag);
     template <typename T>
     T mementoContent(const QByteArray &tag) const
     {
         if (std::shared_ptr< TypedMemento<T> > m = mementoAs< TypedMemento<T> >(tag)) {
             return m->get();
         } else {
             return T();
         }
     }
 
     bool hasOption(const char *opt) const;
     QVariant option(const char *opt) const;
     const std::map<std::string, QVariant> &options() const;
 
     const std::vector< std::shared_ptr<Input> > &inputs() const;
     const std::vector< std::shared_ptr<Input> > &messages() const;
     const std::vector< std::shared_ptr<Output> > &outputs() const;
 
     QStringList fileNames() const;
     unsigned int numFiles() const;
 
     void sendStatus(const char *keyword, const QString &text);
     void sendStatusEncoded(const char *keyword, const std::string &text);
     void sendData(const QByteArray &data, bool moreToCome = false);
 
     int inquire(const char *keyword, QObject *receiver, const char *slot, unsigned int maxSize = 0);
 
     void done(const GpgME::Error &err = GpgME::Error());
     void done(const GpgME::Error &err, const QString &details);
     void done(int err)
     {
         done(GpgME::Error(err));
     }
     void done(int err, const QString &details)
     {
         done(GpgME::Error(err), details);
     }
 
 private:
     virtual void doCanceled() = 0;
     virtual int doStart() = 0;
 
 private:
     void doApplyWindowID(QWidget *w) const;
 
 private:
     const std::map< QByteArray, std::shared_ptr<Memento> > &mementos() const;
 
 private:
     friend class ::Kleo::AssuanCommandFactory;
     class Private;
     kdtools::pimpl_ptr<Private> d;
 };
 
 class AssuanCommandFactory
 {
 public:
     virtual ~AssuanCommandFactory() {}
 
     virtual std::shared_ptr<AssuanCommand> create() const = 0;
     virtual const char *name() const = 0;
 
-#ifndef HAVE_ASSUAN2
-    typedef int(*_Handler)(assuan_context_s *, char *);
-#else
     using _Handler = gpg_error_t (*)(assuan_context_s *, char *);
-#endif
     virtual _Handler _handler() const = 0;
 
-#ifndef HAVE_ASSUAN2
-    static int _handle(assuan_context_s *, char *, const char *);
-#else
     static gpg_error_t _handle(assuan_context_s *, char *, const char *);
-#endif
 };
 
 template <typename Command>
 class GenericAssuanCommandFactory : public AssuanCommandFactory
 {
     AssuanCommandFactory::_Handler _handler() const override
     {
         return &GenericAssuanCommandFactory::_handle;
     }
-#ifndef HAVE_ASSUAN2
-    static int _handle(assuan_context_s *_ctx, char *_line)
-    {
-#else
     static gpg_error_t _handle(assuan_context_s *_ctx, char *_line)
     {
-#endif
         return AssuanCommandFactory::_handle(_ctx, _line, Command::staticName());
     }
     std::shared_ptr<AssuanCommand> create() const override
     {
         return make();
     }
     const char *name() const override
     {
         return Command::staticName();
     }
 public:
     static std::shared_ptr<Command> make()
     {
         return std::shared_ptr<Command>(new Command);
     }
 };
 
 template <typename Derived, typename Base = AssuanCommand>
 class AssuanCommandMixin : public Base
 {
 protected:
     /* reimp */ const char *name() const override
     {
         return Derived::staticName();
     }
 };
 
 }
 
diff --git a/src/uiserver/assuanserverconnection.cpp b/src/uiserver/assuanserverconnection.cpp
index fa39c6335..950cc897e 100644
--- a/src/uiserver/assuanserverconnection.cpp
+++ b/src/uiserver/assuanserverconnection.cpp
@@ -1,1693 +1,1503 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     uiserver/assuanserverconnection.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 #ifndef QT_NO_CAST_TO_ASCII
 # define QT_NO_CAST_TO_ASCII
 #endif
 #ifndef QT_NO_CAST_FROM_ASCII
 # define QT_NO_CAST_FROM_ASCII
 #endif
 
 #include <config-kleopatra.h>
 #include <version-kleopatra.h>
 
 #include "assuanserverconnection.h"
 #include "assuancommand.h"
 #include "sessiondata.h"
 
 #include <utils/input.h>
 #include <utils/output.h>
 #include <Libkleo/GnuPG>
 #include <utils/detail_p.h>
 #include <utils/log.h>
 #include <utils/kleo_assert.h>
 
 #include <Libkleo/Hex>
 #include <Libkleo/Stl_Util>
 #include <Libkleo/KleoException>
 #include <Libkleo/KeyCache>
 
 #include <gpgme++/data.h>
 #include <gpgme++/key.h>
 
 #include <KMime/HeaderParsing>
 
 #include "kleopatra_debug.h"
 #include <KLocalizedString>
 #include <KWindowSystem>
 
 #include <QSocketNotifier>
 #include <QTimer>
 #include <QVariant>
 #include <QPointer>
 #include <QFileInfo>
 #include <QStringList>
 #include <QRegularExpression>
 #include <QWidget>
 #include <QCoreApplication>
 
 
 #include <map>
 #include <algorithm>
 #include <functional>
 #include <type_traits>
 
 #include <cerrno>
 
 #ifdef __GLIBCXX__
 # include <ext/algorithm> // for is_sorted
 #endif
 
 #ifdef Q_OS_WIN32
 # include <io.h>
 # include <process.h>
 #else
 # include <sys/types.h>
 # include <unistd.h>
 #endif
 using namespace Kleo;
 
 static const unsigned int INIT_SOCKET_FLAGS = 3; // says info assuan...
 //static int(*USE_DEFAULT_HANDLER)(assuan_context_t,char*) = 0;
 static const int FOR_READING = 0;
 static const unsigned int MAX_ACTIVE_FDS = 32;
 
-#ifdef HAVE_ASSUAN2
 static void my_assuan_release(assuan_context_t ctx)
 {
     if (ctx) {
         assuan_release(ctx);
     }
 }
 
-#endif
 // std::shared_ptr for assuan_context_t w/ deleter enforced to assuan_deinit_server:
 using AssuanContextBase = std::shared_ptr<std::remove_pointer<assuan_context_t>::type>;
 struct AssuanContext : AssuanContextBase {
     AssuanContext() : AssuanContextBase() {}
-#ifndef HAVE_ASSUAN2
-    explicit AssuanContext(assuan_context_t ctx) : AssuanContextBase(ctx, &assuan_deinit_server) {}
-#else
     explicit AssuanContext(assuan_context_t ctx) : AssuanContextBase(ctx, &my_assuan_release) {}
-#endif
 
-#ifndef HAVE_ASSUAN2
-    void reset(assuan_context_t ctx = 0)
-    {
-        AssuanContextBase::reset(ctx, &assuan_deinit_server);
-    }
-#else
     void reset(assuan_context_t ctx = nullptr)
     {
         AssuanContextBase::reset(ctx, &my_assuan_release);
     }
-#endif
 };
 
 static inline gpg_error_t assuan_process_done_msg(assuan_context_t ctx, gpg_error_t err, const char *err_msg)
 {
     return assuan_process_done(ctx, assuan_set_error(ctx, err, err_msg));
 }
 
 static inline gpg_error_t assuan_process_done_msg(assuan_context_t ctx, gpg_error_t err, const std::string &err_msg)
 {
     return assuan_process_done_msg(ctx, err, err_msg.c_str());
 }
 
 static inline gpg_error_t assuan_process_done_msg(assuan_context_t ctx, gpg_error_t err, const QString &err_msg)
 {
     return assuan_process_done_msg(ctx, err, err_msg.toUtf8().constData());
 }
 
 static std::map<std::string, std::string> upcase_option(const char *option, std::map<std::string, std::string> options)
 {
     std::string value;
     bool value_found = false;
     auto it = options.begin();
     while (it != options.end())
         if (qstricmp(it->first.c_str(), option) == 0) {
             value = it->second;
             options.erase(it++);
             value_found = true;
         } else {
             ++it;
         }
     if (value_found) {
         options[option] = value;
     }
     return options;
 }
 
 static std::map<std::string, std::string> parse_commandline(const char *line)
 {
     std::map<std::string, std::string> result;
     if (line) {
         const char *begin = line;
         const char *lastEQ = nullptr;
         while (*line) {
             if (*line == ' ' || *line == '\t') {
                 if (begin != line) {
                     if (begin[0] == '-' && begin[1] == '-') {
                         begin += 2;    // skip initial "--"
                     }
                     if (lastEQ && lastEQ > begin) {
                         result[ std::string(begin, lastEQ - begin) ] = hexdecode(std::string(lastEQ + 1, line - (lastEQ + 1)));
                     } else {
                         result[ std::string(begin,  line  - begin) ] = std::string();
                     }
                 }
                 begin = line + 1;
             } else if (*line == '=') {
                 if (line == begin)
                     throw Exception(gpg_error(GPG_ERR_ASS_SYNTAX),
                                     i18n("No option name given"));
                 else {
                     lastEQ = line;
                 }
             }
             ++line;
         }
         if (begin != line) {
             if (begin[0] == '-' && begin[1] == '-') {
                 begin += 2;    // skip initial "--"
             }
             if (lastEQ && lastEQ > begin) {
                 result[ std::string(begin, lastEQ - begin) ] = hexdecode(std::string(lastEQ + 1, line - (lastEQ + 1)));
             } else {
                 result[ begin ] = std::string();
             }
         }
     }
 
     return result;
 }
 
 static WId wid_from_string(const QString &winIdStr, bool *ok = nullptr)
 {
     return static_cast<WId>(winIdStr.toULongLong(ok, 16));
 }
 
 static void apply_window_id(QWidget *widget, const QString &winIdStr)
 {
     if (!widget || winIdStr.isEmpty()) {
         return;
     }
     bool ok = false;
     const WId wid = wid_from_string(winIdStr, &ok);
     if (!ok) {
         qCDebug(KLEOPATRA_LOG) << "window-id value" << wid << "doesn't look like a number";
         return;
     }
     if (QWidget *pw = QWidget::find(wid)) {
         widget->setParent(pw, widget->windowFlags());
     } else {
         widget->setAttribute(Qt::WA_NativeWindow, true);
         KWindowSystem::setMainWindow(widget->windowHandle(), wid);
     }
 }
 
 //
 //
 // AssuanServerConnection:
 //
 //
 
 class AssuanServerConnection::Private : public QObject
 {
     Q_OBJECT
     friend class ::Kleo::AssuanServerConnection;
     friend class ::Kleo::AssuanCommandFactory;
     friend class ::Kleo::AssuanCommand;
     AssuanServerConnection *const q;
 public:
     Private(assuan_fd_t fd_, const std::vector< std::shared_ptr<AssuanCommandFactory> > &factories_, AssuanServerConnection *qq);
     ~Private() override;
 
 Q_SIGNALS:
     void startKeyManager();
 
 public Q_SLOTS:
     void slotReadActivity(int)
     {
         Q_ASSERT(ctx);
-#ifndef HAVE_ASSUAN2
-        if (const int err = assuan_process_next(ctx.get())) {
-#else
         int done = false;
         if (const int err = assuan_process_next(ctx.get(), &done) || done) {
-#endif
             //if ( err == -1 || gpg_err_code(err) == GPG_ERR_EOF ) {
             topHalfDeletion();
             if (nohupedCommands.empty()) {
                 bottomHalfDeletion();
             }
             //} else {
             //assuan_process_done( ctx.get(), err );
             //return;
             //}
         }
     }
 
     int startCommandBottomHalf();
 
 private:
     void nohupDone(AssuanCommand *cmd)
     {
         const auto it = std::find_if(nohupedCommands.begin(), nohupedCommands.end(),
                                      [cmd](const std::shared_ptr<AssuanCommand> &other) {
                                         return other.get() == cmd;
                                      });
         Q_ASSERT(it != nohupedCommands.end());
         nohupedCommands.erase(it);
         if (nohupedCommands.empty() && closed) {
             bottomHalfDeletion();
         }
     }
 
     void commandDone(AssuanCommand *cmd)
     {
         if (!cmd || cmd != currentCommand.get()) {
             return;
         }
         currentCommand.reset();
     }
 
     void topHalfDeletion()
     {
         if (currentCommand) {
             currentCommand->canceled();
         }
         if (fd != ASSUAN_INVALID_FD) {
 #if defined(Q_OS_WIN32)
             CloseHandle(fd);
 #else
             ::close(fd);
 #endif
         }
         notifiers.clear();
         closed = true;
     }
 
     void bottomHalfDeletion()
     {
         if (sessionId) {
             SessionDataHandler::instance()->exitSession(sessionId);
         }
         cleanup();
         const QPointer<Private> that = this;
         Q_EMIT q->closed(q);
         if (that) { // still there
             q->deleteLater();
         }
     }
 
 private:
-#ifndef HAVE_ASSUAN2
-    static void reset_handler(assuan_context_t ctx_)
-    {
-#else
     static gpg_error_t reset_handler(assuan_context_t ctx_, char *)
     {
-#endif
         Q_ASSERT(assuan_get_pointer(ctx_));
 
         AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx_));
 
         conn.reset();
-#ifdef HAVE_ASSUAN2
 
         return 0;
-#endif
     }
 
-#ifndef HAVE_ASSUAN2
-    static int option_handler(assuan_context_t ctx_, const char *key, const char *value)
-    {
-#else
     static gpg_error_t option_handler(assuan_context_t ctx_, const char *key, const char *value)
     {
-#endif
         Q_ASSERT(assuan_get_pointer(ctx_));
 
         AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx_));
 
         if (key && key[0] == '-' && key[1] == '-') {
             key += 2;    // skip "--"
         }
         conn.options[key] = QString::fromUtf8(value);
 
         return 0;
         //return gpg_error( GPG_ERR_UNKNOWN_OPTION );
     }
 
-#ifndef HAVE_ASSUAN2
-    static int session_handler(assuan_context_t ctx_, char *line)
-    {
-#else
     static gpg_error_t session_handler(assuan_context_t ctx_, char *line)
     {
-#endif
         Q_ASSERT(assuan_get_pointer(ctx_));
         AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx_));
 
         const QString str = QString::fromUtf8(line);
         static const QRegularExpression rx(QRegularExpression::anchoredPattern(uR"((\d+)(?:\s+(.*))?)"));
         const QRegularExpressionMatch match = rx.match(str);
         if (!match.hasMatch()) {
             static const QString errorString = i18n("Parse error");
             return assuan_process_done_msg(ctx_, gpg_error(GPG_ERR_ASS_SYNTAX), errorString);
         }
         bool ok = false;
         if (const qulonglong id = match.captured(1).toULongLong(&ok)) {
             if (ok && id <= std::numeric_limits<unsigned int>::max()) {
                 SessionDataHandler::instance()->enterSession(id);
                 conn.sessionId = id;
             } else {
                 static const QString errorString = i18n("Parse error: numeric session id too large");
                 return assuan_process_done_msg(ctx_, gpg_error(GPG_ERR_ASS_SYNTAX), errorString);
             }
         }
 
         const QString cap2 = match.captured(2);
         if (!cap2.isEmpty()) {
             conn.sessionTitle = cap2;
         }
         qCDebug(KLEOPATRA_LOG) << "session_handler: "
                                << "id=" << static_cast<unsigned long>(conn.sessionId)
                                << ", title=" << qPrintable(conn.sessionTitle);
         return assuan_process_done(ctx_, 0);
     }
 
-#ifndef HAVE_ASSUAN2
-    static int capabilities_handler(assuan_context_t ctx_, char *line)
-    {
-#else
     static gpg_error_t capabilities_handler(assuan_context_t ctx_, char *line)
     {
-#endif
         if (!QByteArray(line).trimmed().isEmpty()) {
             static const QString errorString = i18n("CAPABILITIES does not take arguments");
             return assuan_process_done_msg(ctx_, gpg_error(GPG_ERR_ASS_PARAMETER), errorString);
         }
         static const char capabilities[] =
             "SENDER=info\n"
             "RECIPIENT=info\n"
             "SESSION\n"
             ;
         return assuan_process_done(ctx_, assuan_send_data(ctx_, capabilities, sizeof capabilities - 1));
     }
 
-#ifndef HAVE_ASSUAN2
-    static int getinfo_handler(assuan_context_t ctx_, char *line)
-    {
-#else
     static gpg_error_t getinfo_handler(assuan_context_t ctx_, char *line)
     {
-#endif
         Q_ASSERT(assuan_get_pointer(ctx_));
         AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx_));
 
         if (qstrcmp(line, "version") == 0) {
             static const char version[] = "Kleopatra " KLEOPATRA_VERSION_STRING;
             return assuan_process_done(ctx_, assuan_send_data(ctx_, version, sizeof version - 1));
         }
 
         QByteArray ba;
         if (qstrcmp(line, "pid") == 0) {
             ba = QByteArray::number(QCoreApplication::applicationPid());
         } else if (qstrcmp(line, "options") == 0) {
             ba = conn.dumpOptions();
         } else if (qstrcmp(line, "x-mementos") == 0) {
             ba = conn.dumpMementos();
         } else if (qstrcmp(line, "senders") == 0) {
             ba = conn.dumpSenders();
         } else if (qstrcmp(line, "recipients") == 0) {
             ba = conn.dumpRecipients();
         } else if (qstrcmp(line, "x-files") == 0) {
             ba = conn.dumpFiles();
         } else {
             static const QString errorString = i18n("Unknown value for WHAT");
             return assuan_process_done_msg(ctx_, gpg_error(GPG_ERR_ASS_PARAMETER), errorString);
         }
         return assuan_process_done(ctx_, assuan_send_data(ctx_, ba.constData(), ba.size()));
     }
 
-#ifndef HAVE_ASSUAN2
-    static int start_keymanager_handler(assuan_context_t ctx_, char *line)
-    {
-#else
     static gpg_error_t start_keymanager_handler(assuan_context_t ctx_, char *line)
     {
-#endif
         Q_ASSERT(assuan_get_pointer(ctx_));
         AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx_));
 
         if (line && *line) {
             static const QString errorString = i18n("START_KEYMANAGER does not take arguments");
             return assuan_process_done_msg(ctx_, gpg_error(GPG_ERR_ASS_PARAMETER), errorString);
         }
 
         Q_EMIT conn.q->startKeyManagerRequested();
 
         return assuan_process_done(ctx_, 0);
     }
 
-#ifndef HAVE_ASSUAN2
-    static int start_confdialog_handler(assuan_context_t ctx_, char *line)
-    {
-#else
     static gpg_error_t start_confdialog_handler(assuan_context_t ctx_, char *line)
     {
-#endif
         Q_ASSERT(assuan_get_pointer(ctx_));
         AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx_));
 
         if (line && *line) {
             static const QString errorString = i18n("START_CONFDIALOG does not take arguments");
             return assuan_process_done_msg(ctx_, gpg_error(GPG_ERR_ASS_PARAMETER), errorString);
         }
 
         Q_EMIT conn.q->startConfigDialogRequested();
 
         return assuan_process_done(ctx_, 0);
     }
 
     template <bool in>
     struct Input_or_Output : std::conditional<in, Input, Output> {};
 
     // format: TAG (FD|FD=\d+|FILE=...)
     template <bool in, typename T_memptr>
-#ifndef HAVE_ASSUAN2
-    static int IO_handler(assuan_context_t ctx_, char *line_, T_memptr which)
-    {
-#else
     static gpg_error_t IO_handler(assuan_context_t ctx_, char *line_, T_memptr which)
     {
-#endif
         Q_ASSERT(assuan_get_pointer(ctx_));
         AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx_));
 
         char *binOpt = strstr(line_, "--binary");
 
         if (binOpt && !in) {
             /* Note there is also --armor and --base64 allowed but we don't need
              * to parse those because they are default.
              * We remove it here so that it is not parsed as an Option.*/
             memset(binOpt, ' ', 8);
         }
 
         try {
 
             /*const*/ std::map<std::string, std::string> options = upcase_option("FD", upcase_option("FILE", parse_commandline(line_)));
             if (options.size() < 1 || options.size() > 2) {
                 throw gpg_error(GPG_ERR_ASS_SYNTAX);
             }
 
             std::shared_ptr< typename Input_or_Output<in>::type > io;
 
             if (options.count("FD")) {
 
                 if (options.count("FILE")) {
                     throw gpg_error(GPG_ERR_CONFLICT);
                 }
 
                 assuan_fd_t fd = ASSUAN_INVALID_FD;
 
                 const std::string fdstr = options["FD"];
 
                 if (fdstr.empty()) {
                     if (const gpg_error_t err = assuan_receivefd(conn.ctx.get(), &fd)) {
                         throw err;
                     }
                 } else {
 #if defined(Q_OS_WIN32)
                     fd = (assuan_fd_t)std::stoi(fdstr);
 #else
                     fd = std::stoi(fdstr);
 #endif
                 }
 
                 io = Input_or_Output<in>::type::createFromPipeDevice(fd, in ? i18n("Message #%1", (conn.*which).size() + 1) : QString());
 
                 options.erase("FD");
 
             } else if (options.count("FILE")) {
 
                 if (options.count("FD")) {
                     throw gpg_error(GPG_ERR_CONFLICT);
                 }
 
                 const QString filePath = QFile::decodeName(options["FILE"].c_str());
                 if (filePath.isEmpty()) {
                     throw Exception(gpg_error(GPG_ERR_ASS_SYNTAX), i18n("Empty file path"));
                 }
                 const QFileInfo fi(filePath);
                 if (!fi.isAbsolute()) {
                     throw Exception(gpg_error(GPG_ERR_INV_ARG), i18n("Only absolute file paths are allowed"));
                 }
                 if (!fi.isFile()) {
                     throw Exception(gpg_error(GPG_ERR_INV_ARG), i18n("Only files are allowed in INPUT/OUTPUT FILE"));
                 } else {
                     io = Input_or_Output<in>::type::createFromFile(fi.absoluteFilePath(), true);
                 }
 
                 options.erase("FILE");
 
             } else {
 
                 throw gpg_error(GPG_ERR_ASS_PARAMETER);
 
             }
 
             if (options.size()) {
                 throw gpg_error(GPG_ERR_UNKNOWN_OPTION);
             }
 
             (conn.*which).push_back(io);
 
             if (binOpt && !in) {
                 auto out = reinterpret_cast <Output *>(io.get());
                 out->setBinaryOpt(true);
                 qCDebug(KLEOPATRA_LOG) << "Configured output for binary data";
             }
 
             qCDebug(KLEOPATRA_LOG) << "AssuanServerConnection: added" << io->label();
 
             return assuan_process_done(conn.ctx.get(), 0);
         } catch (const GpgME::Exception &e) {
             return assuan_process_done_msg(conn.ctx.get(), e.error().encodedError(), e.message().c_str());
         } catch (const std::exception &) {
             return assuan_process_done(conn.ctx.get(), gpg_error(GPG_ERR_ASS_SYNTAX));
         } catch (const gpg_error_t &e) {
             return assuan_process_done(conn.ctx.get(), e);
         } catch (...) {
             return assuan_process_done_msg(conn.ctx.get(), gpg_error(GPG_ERR_UNEXPECTED), "unknown exception caught");
         }
 
     }
 
-#ifndef HAVE_ASSUAN2
-    static int input_handler(assuan_context_t ctx, char *line)
-    {
-#else
     static gpg_error_t input_handler(assuan_context_t ctx, char *line)
     {
-#endif
         return IO_handler<true>(ctx, line, &Private::inputs);
     }
 
-#ifndef HAVE_ASSUAN2
-    static int output_handler(assuan_context_t ctx, char *line)
-    {
-#else
     static gpg_error_t output_handler(assuan_context_t ctx, char *line)
     {
-#endif
         return IO_handler<false>(ctx, line, &Private::outputs);
     }
 
-#ifndef HAVE_ASSUAN2
-    static int message_handler(assuan_context_t ctx, char *line)
-    {
-#else
     static gpg_error_t message_handler(assuan_context_t ctx, char *line)
     {
-#endif
         return IO_handler<true>(ctx, line, &Private::messages);
     }
 
-#ifndef HAVE_ASSUAN2
-    static int file_handler(assuan_context_t ctx_, char *line)
-    {
-#else
     static gpg_error_t file_handler(assuan_context_t ctx_, char *line)
     {
-#endif
         Q_ASSERT(assuan_get_pointer(ctx_));
         AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx_));
 
         try {
             const QFileInfo fi(QFile::decodeName(hexdecode(line).c_str()));
             if (!fi.isAbsolute()) {
                 throw Exception(gpg_error(GPG_ERR_INV_ARG), i18n("Only absolute file paths are allowed"));
             }
             if (!fi.exists()) {
                 throw gpg_error(GPG_ERR_ENOENT);
             }
             if (!fi.isReadable() || (fi.isDir() && !fi.isExecutable())) {
                 throw gpg_error(GPG_ERR_EPERM);
             }
 
             conn.files.push_back(fi.absoluteFilePath());
 
             return assuan_process_done(conn.ctx.get(), 0);
         } catch (const Exception &e) {
             return assuan_process_done_msg(conn.ctx.get(), e.error().encodedError(), e.message().toUtf8().constData());
         } catch (const gpg_error_t &e) {
             return assuan_process_done(conn.ctx.get(), e);
         } catch (...) {
             return assuan_process_done_msg(conn.ctx.get(), gpg_error(GPG_ERR_UNEXPECTED), i18n("unknown exception caught").toUtf8().constData());
         }
     }
 
     static bool parse_informative(const char *&begin, GpgME::Protocol &protocol)
     {
         protocol = GpgME::UnknownProtocol;
         bool informative = false;
         const char *pos = begin;
         while (true) {
             while (*pos == ' ' || *pos == '\t') {
                 ++pos;
             }
             if (qstrnicmp(pos, "--info", strlen("--info")) == 0) {
                 informative = true;
                 pos += strlen("--info");
                 if (*pos == '=') {
                     ++pos;
                     break;
                 }
             } else if (qstrnicmp(pos, "--protocol=", strlen("--protocol=")) == 0) {
                 pos += strlen("--protocol=");
                 if (qstrnicmp(pos, "OpenPGP", strlen("OpenPGP")) == 0) {
                     protocol = GpgME::OpenPGP;
                     pos += strlen("OpenPGP");
                 } else if (qstrnicmp(pos, "CMS", strlen("CMS")) == 0) {
                     protocol = GpgME::CMS;
                     pos += strlen("CMS");
                 } else {
                     ;
                 }
             } else if (qstrncmp(pos, "-- ", strlen("-- ")) == 0) {
                 pos += 3;
                 while (*pos == ' ' || *pos == '\t') {
                     ++pos;
                 }
                 break;
             } else {
                 break;
             }
         }
         begin = pos;
         return informative;
     }
 
     template <typename T_memptr, typename T_memptr2>
-#ifndef HAVE_ASSUAN2
-    static int recipient_sender_handler(T_memptr mp, T_memptr2 info, assuan_context_t ctx, char *line, bool sender = false)
-    {
-#else
     static gpg_error_t recipient_sender_handler(T_memptr mp, T_memptr2 info, assuan_context_t ctx, char *line, bool sender = false)
     {
-#endif
         Q_ASSERT(assuan_get_pointer(ctx));
         AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx));
 
         if (!line || !*line) {
             return assuan_process_done(conn.ctx.get(), gpg_error(GPG_ERR_INV_ARG));
         }
         const char *begin     = line;
         const char *const end = begin + qstrlen(line);
         GpgME::Protocol proto = GpgME::UnknownProtocol;
         const bool informative = parse_informative(begin, proto);
         if (!(conn.*mp).empty() && informative != (conn.*info))
             return assuan_process_done_msg(conn.ctx.get(), gpg_error(GPG_ERR_CONFLICT),
                                            i18n("Cannot mix --info with non-info SENDER or RECIPIENT").toUtf8().constData());
         KMime::Types::Mailbox mb;
         if (!KMime::HeaderParsing::parseMailbox(begin, end, mb))
             return assuan_process_done_msg(conn.ctx.get(), gpg_error(GPG_ERR_INV_ARG),
                                            i18n("Argument is not a valid RFC-2822 mailbox").toUtf8().constData());
         if (begin != end)
             return assuan_process_done_msg(conn.ctx.get(), gpg_error(GPG_ERR_INV_ARG),
                                            i18n("Garbage after valid RFC-2822 mailbox detected").toUtf8().constData());
         (conn.*info) = informative;
         (conn.*mp).push_back(mb);
 
         const QString email = mb.addrSpec().asString();
         (void)assuan_write_line(conn.ctx.get(), qPrintable(QString::asprintf("# ok, parsed as \"%s\"", qPrintable(email))));
         if (sender && !informative) {
             return AssuanCommandFactory::_handle(conn.ctx.get(), line, "PREP_SIGN");
         } else {
             return assuan_process_done(ctx, 0);
         }
     }
 
-#ifndef HAVE_ASSUAN2
-    static int recipient_handler(assuan_context_t ctx, char *line)
-    {
-#else
     static gpg_error_t recipient_handler(assuan_context_t ctx, char *line)
     {
-#endif
         return recipient_sender_handler(&Private::recipients, &Private::informativeRecipients, ctx, line);
     }
 
-#ifndef HAVE_ASSUAN2
-    static int sender_handler(assuan_context_t ctx, char *line)
-    {
-#else
     static gpg_error_t sender_handler(assuan_context_t ctx, char *line)
     {
-#endif
         return recipient_sender_handler(&Private::senders, &Private::informativeSenders, ctx, line, true);
     }
 
     QByteArray dumpOptions() const
     {
         QByteArray result;
         for (auto it = options.begin(), end = options.end(); it != end; ++it) {
             result += it->first.c_str() + it->second.toString().toUtf8() + '\n';
         }
         return result;
     }
 
     static QByteArray dumpStringList(const QStringList &sl)
     {
         return sl.join(QLatin1Char('\n')).toUtf8();
     }
 
     template <typename T_container>
     static QByteArray dumpStringList(const T_container &c)
     {
         QStringList sl;
         std::copy(c.begin(), c.end(), std::back_inserter(sl));
         return dumpStringList(sl);
     }
 
     template <typename T_container>
     static QByteArray dumpMailboxes(const T_container &c)
     {
         QStringList sl;
         std::transform(c.begin(), c.end(),
                        std::back_inserter(sl),
                        [](typename T_container::const_reference val) {
                            return val.prettyAddress();
                        });
         return dumpStringList(sl);
     }
 
     QByteArray dumpSenders() const
     {
         return dumpMailboxes(senders);
     }
 
     QByteArray dumpRecipients() const
     {
         return dumpMailboxes(recipients);
     }
 
     QByteArray dumpMementos() const
     {
         QByteArray result;
         for (auto it = mementos.begin(), end = mementos.end(); it != end; ++it) {
             char buf[2 + 2 * sizeof(void *) + 2];
             sprintf(buf, "0x%p\n", (void *)it->second.get());
             buf[sizeof(buf) - 1] = '\0';
             result += it->first + QByteArray::fromRawData(buf, sizeof buf);
         }
         return result;
     }
 
     QByteArray dumpFiles() const
     {
         QStringList rv;
         rv.reserve(files.size());
         std::copy(files.cbegin(), files.cend(), std::back_inserter(rv));
         return dumpStringList(rv);
     }
 
     void cleanup();
     void reset()
     {
         options.clear();
         senders.clear();
         informativeSenders = false;
         recipients.clear();
         informativeRecipients = false;
         sessionTitle.clear();
         sessionId = 0;
         mementos.clear();
         files.clear();
         std::for_each(inputs.begin(), inputs.end(), std::mem_fn(&Input::finalize));
         inputs.clear();
         std::for_each(outputs.begin(), outputs.end(), std::mem_fn(&Output::finalize));
         outputs.clear();
         std::for_each(messages.begin(), messages.end(), std::mem_fn(&Input::finalize));
         messages.clear();
         bias = GpgME::UnknownProtocol;
     }
 
     assuan_fd_t fd;
     AssuanContext ctx;
     bool closed                : 1;
     bool cryptoCommandsEnabled : 1;
     bool commandWaitingForCryptoCommandsEnabled : 1;
     bool currentCommandIsNohup : 1;
     bool informativeSenders;    // address taken, so no : 1
     bool informativeRecipients; // address taken, so no : 1
     GpgME::Protocol bias;
     QString sessionTitle;
     unsigned int sessionId;
     std::vector< std::shared_ptr<QSocketNotifier> > notifiers;
     std::vector< std::shared_ptr<AssuanCommandFactory> > factories; // sorted: _detail::ByName<std::less>
     std::shared_ptr<AssuanCommand> currentCommand;
     std::vector< std::shared_ptr<AssuanCommand> > nohupedCommands;
     std::map<std::string, QVariant> options;
     std::vector<KMime::Types::Mailbox> senders, recipients;
     std::vector< std::shared_ptr<Input> > inputs, messages;
     std::vector< std::shared_ptr<Output> > outputs;
     std::vector<QString> files;
     std::map< QByteArray, std::shared_ptr<AssuanCommand::Memento> > mementos;
 };
 
 void AssuanServerConnection::Private::cleanup()
 {
     Q_ASSERT(nohupedCommands.empty());
     reset();
     currentCommand.reset();
     currentCommandIsNohup = false;
     commandWaitingForCryptoCommandsEnabled = false;
     notifiers.clear();
     ctx.reset();
     fd = ASSUAN_INVALID_FD;
 }
 
 AssuanServerConnection::Private::Private(assuan_fd_t fd_, const std::vector< std::shared_ptr<AssuanCommandFactory> > &factories_, AssuanServerConnection *qq)
     : QObject(),
       q(qq),
       fd(fd_),
       closed(false),
       cryptoCommandsEnabled(false),
       commandWaitingForCryptoCommandsEnabled(false),
       currentCommandIsNohup(false),
       informativeSenders(false),
       informativeRecipients(false),
       bias(GpgME::UnknownProtocol),
       sessionId(0),
       factories(factories_)
 {
 #ifdef __GLIBCXX__
     Q_ASSERT(__gnu_cxx::is_sorted(factories_.begin(), factories_.end(), _detail::ByName<std::less>()));
 #endif
 
     if (fd == ASSUAN_INVALID_FD) {
         throw Exception(gpg_error(GPG_ERR_INV_ARG), "pre-assuan_init_socket_server_ext");
     }
 
-#ifndef HAVE_ASSUAN2
-    assuan_context_t naked_ctx = 0;
-    if (const gpg_error_t err = assuan_init_socket_server_ext(&naked_ctx, fd, INIT_SOCKET_FLAGS))
-#else
     {
         assuan_context_t naked_ctx = nullptr;
         if (const gpg_error_t err = assuan_new(&naked_ctx)) {
             throw Exception(err, "assuan_new");
         }
         ctx.reset(naked_ctx);
     }
     if (const gpg_error_t err = assuan_init_socket_server(ctx.get(), fd, INIT_SOCKET_FLAGS))
-#endif
         throw Exception(err, "assuan_init_socket_server_ext");
 
-#ifndef HAVE_ASSUAN2
-    ctx.reset(naked_ctx); naked_ctx = 0;
-#endif
-
     // for callbacks, associate the context with this connection:
     assuan_set_pointer(ctx.get(), this);
 
     FILE *const logFile = Log::instance()->logFile();
     assuan_set_log_stream(ctx.get(), logFile ? logFile : stderr);
 
     // register FDs with the event loop:
     assuan_fd_t fds[MAX_ACTIVE_FDS];
     const int numFDs = assuan_get_active_fds(ctx.get(), FOR_READING, fds, MAX_ACTIVE_FDS);
     Q_ASSERT(numFDs != -1);   // == 1
 
     if (!numFDs || fds[0] != fd) {
         const std::shared_ptr<QSocketNotifier> sn(new QSocketNotifier((intptr_t)fd, QSocketNotifier::Read), std::mem_fn(&QObject::deleteLater));
         connect(sn.get(), &QSocketNotifier::activated, this, &Private::slotReadActivity);
         notifiers.push_back(sn);
     }
 
     notifiers.reserve(notifiers.size() + numFDs);
     for (int i = 0; i < numFDs; ++i) {
         const std::shared_ptr<QSocketNotifier> sn(new QSocketNotifier((intptr_t)fds[i], QSocketNotifier::Read), std::mem_fn(&QObject::deleteLater));
         connect(sn.get(), &QSocketNotifier::activated, this, &Private::slotReadActivity);
         notifiers.push_back(sn);
     }
 
     // register our INPUT/OUTPUT/MESSGAE/FILE handlers:
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "INPUT",  input_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "INPUT",  input_handler, ""))
-#endif
         throw Exception(err, "register \"INPUT\" handler");
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "MESSAGE",  message_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "MESSAGE",  message_handler, ""))
-#endif
         throw Exception(err, "register \"MESSAGE\" handler");
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "OUTPUT", output_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "OUTPUT", output_handler, ""))
-#endif
         throw Exception(err, "register \"OUTPUT\" handler");
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "FILE", file_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "FILE", file_handler, ""))
-#endif
         throw Exception(err, "register \"FILE\" handler");
 
     // register user-defined commands:
     for (std::shared_ptr<AssuanCommandFactory> fac : std::as_const(factories))
-#ifndef HAVE_ASSUAN2
-        if (const gpg_error_t err = assuan_register_command(ctx.get(), fac->name(), fac->_handler()))
-#else
         if (const gpg_error_t err = assuan_register_command(ctx.get(), fac->name(), fac->_handler(), ""))
-#endif
             throw Exception(err, std::string("register \"") + fac->name() + "\" handler");
 
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "GETINFO", getinfo_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "GETINFO", getinfo_handler, ""))
-#endif
         throw Exception(err, "register \"GETINFO\" handler");
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "START_KEYMANAGER", start_keymanager_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "START_KEYMANAGER", start_keymanager_handler, ""))
-#endif
         throw Exception(err, "register \"START_KEYMANAGER\" handler");
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "START_CONFDIALOG", start_confdialog_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "START_CONFDIALOG", start_confdialog_handler, ""))
-#endif
         throw Exception(err, "register \"START_CONFDIALOG\" handler");
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "RECIPIENT", recipient_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "RECIPIENT", recipient_handler, ""))
-#endif
         throw Exception(err, "register \"RECIPIENT\" handler");
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "SENDER", sender_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "SENDER", sender_handler, ""))
-#endif
         throw Exception(err, "register \"SENDER\" handler");
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "SESSION", session_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "SESSION", session_handler, ""))
-#endif
         throw Exception(err, "register \"SESSION\" handler");
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_register_command(ctx.get(), "CAPABILITIES", capabilities_handler))
-#else
     if (const gpg_error_t err = assuan_register_command(ctx.get(), "CAPABILITIES", capabilities_handler, ""))
-#endif
         throw Exception(err, "register \"CAPABILITIES\" handler");
 
     assuan_set_hello_line(ctx.get(), "GPG UI server (Kleopatra/" KLEOPATRA_VERSION_STRING ") ready to serve");
     //assuan_set_hello_line( ctx.get(), GPG UI server (qApp->applicationName() + " v" + kapp->applicationVersion() + "ready to serve" )
 
     // some notifiers we're interested in:
     if (const gpg_error_t err = assuan_register_reset_notify(ctx.get(), reset_handler)) {
         throw Exception(err, "register reset notify");
     }
     if (const gpg_error_t err = assuan_register_option_handler(ctx.get(), option_handler)) {
         throw Exception(err, "register option handler");
     }
 
     // and last, we need to call assuan_accept, which doesn't block
     // (d/t INIT_SOCKET_FLAGS), but performs vital connection
     // establishing handling:
     if (const gpg_error_t err = assuan_accept(ctx.get())) {
         throw Exception(err, "assuan_accept");
     }
 }
 
 AssuanServerConnection::Private::~Private()
 {
     cleanup();
 }
 
 AssuanServerConnection::AssuanServerConnection(assuan_fd_t fd, const std::vector< std::shared_ptr<AssuanCommandFactory> > &factories, QObject *p)
     : QObject(p), d(new Private(fd, factories, this))
 {
 
 }
 
 AssuanServerConnection::~AssuanServerConnection() {}
 
 void AssuanServerConnection::enableCryptoCommands(bool on)
 {
     if (on == d->cryptoCommandsEnabled) {
         return;
     }
     d->cryptoCommandsEnabled = on;
     if (d->commandWaitingForCryptoCommandsEnabled) {
         QTimer::singleShot(0, d.get(), &Private::startCommandBottomHalf);
     }
 }
 
 //
 //
 // AssuanCommand:
 //
 //
 
 namespace Kleo
 {
 
 class InquiryHandler : public QObject
 {
     Q_OBJECT
 public:
 
-#if defined(HAVE_ASSUAN2) || defined(HAVE_ASSUAN_INQUIRE_EXT)
     explicit InquiryHandler(const char *keyword_, QObject *p = nullptr)
         : QObject(p),
-# if !defined(HAVE_ASSUAN2) && !defined(HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT)
-          buffer(0),
-          buflen(0),
-# endif
           keyword(keyword_)
     {
 
     }
 
-# if defined(HAVE_ASSUAN2) || defined(HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT)
-#  ifndef HAVE_ASSUAN2
-    static int handler(void *cb_data, int rc, unsigned char *buffer, size_t buflen)
-#  else
     static gpg_error_t handler(void *cb_data, gpg_error_t rc, unsigned char *buffer, size_t buflen)
-#  endif
     {
         Q_ASSERT(cb_data);
         auto this_ = static_cast<InquiryHandler *>(cb_data);
         Q_EMIT this_->signal(rc, QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), buflen), this_->keyword);
         std::free(buffer);
         delete this_;
         return 0;
     }
-# else
-    static int handler(void *cb_data, int rc)
-    {
-        Q_ASSERT(cb_data);
-        InquiryHandler *this_ = static_cast<InquiryHandler *>(cb_data);
-        Q_EMIT this_->signal(rc, QByteArray::fromRawData(reinterpret_cast<const char *>(this_->buffer), this_->buflen), this_->keyword);
-        std::free(this_->buffer);
-        delete this_;
-        return 0;
-    }
-# endif
 
 private:
-#if !defined(HAVE_ASSUAN2) && !defined(HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT)
-    friend class ::Kleo::AssuanCommand;
-    unsigned char *buffer;
-    size_t buflen;
-#endif
     const char *keyword;
-#endif // defined(HAVE_ASSUAN2) || defined(HAVE_ASSUAN_INQUIRE_EXT)
 
 Q_SIGNALS:
     void signal(int rc, const QByteArray &data, const QByteArray &keyword);
 };
 
 } // namespace Kleo
 
 class AssuanCommand::Private
 {
 public:
     Private()
         : informativeRecipients(false),
           informativeSenders(false),
           bias(GpgME::UnknownProtocol),
           done(false),
           nohup(false)
     {
 
     }
 
     std::map<std::string, QVariant> options;
     std::vector< std::shared_ptr<Input> > inputs, messages;
     std::vector< std::shared_ptr<Output> > outputs;
     std::vector<QString> files;
     std::vector<KMime::Types::Mailbox> recipients, senders;
     bool informativeRecipients, informativeSenders;
     GpgME::Protocol bias;
     QString sessionTitle;
     unsigned int sessionId;
     QByteArray utf8ErrorKeepAlive;
     AssuanContext ctx;
     bool done;
     bool nohup;
 };
 
 AssuanCommand::AssuanCommand()
     : d(new Private)
 {
 
 }
 
 AssuanCommand::~AssuanCommand()
 {
 
 }
 
 int AssuanCommand::start()
 {
     try {
         if (const int err = doStart())
             if (!d->done) {
                 done(err);
             }
         return 0;
     } catch (const Exception &e) {
         if (!d->done) {
             done(e.error_code(), e.message());
         }
         return 0;
     } catch (const GpgME::Exception &e) {
         if (!d->done) {
             done(e.error(), QString::fromLocal8Bit(e.message().c_str()));
         }
         return 0;
     } catch (const std::exception &e) {
         if (!d->done) {
             done(makeError(GPG_ERR_INTERNAL), i18n("Caught unexpected exception: %1", QString::fromLocal8Bit(e.what())));
         }
         return 0;
     } catch (...) {
         if (!d->done) {
             done(makeError(GPG_ERR_INTERNAL), i18n("Caught unknown exception - please report this error to the developers."));
         }
         return 0;
     }
 }
 
 void AssuanCommand::canceled()
 {
     d->done = true;
     doCanceled();
 }
 
 // static
 int AssuanCommand::makeError(int code)
 {
     return makeGnuPGError(code);
 }
 
 bool AssuanCommand::hasOption(const char *opt) const
 {
     return d->options.count(opt);
 }
 
 QVariant AssuanCommand::option(const char *opt) const
 {
     const auto it = d->options.find(opt);
     if (it == d->options.end()) {
         return QVariant();
     } else {
         return it->second;
     }
 }
 
 const std::map<std::string, QVariant> &AssuanCommand::options() const
 {
     return d->options;
 }
 
 namespace
 {
 template <typename U, typename V>
 std::vector<U> keys(const std::map<U, V> &map)
 {
     std::vector<U> result;
     result.resize(map.size());
     for (typename std::map<U, V>::const_iterator it = map.begin(), end = map.end(); it != end; ++it) {
         result.push_back(it->first);
     }
     return result;
 }
 }
 
 const std::map< QByteArray, std::shared_ptr<AssuanCommand::Memento> > &AssuanCommand::mementos() const
 {
     // oh, hack :(
     Q_ASSERT(assuan_get_pointer(d->ctx.get()));
     const AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(d->ctx.get()));
     return conn.mementos;
 }
 
 bool AssuanCommand::hasMemento(const QByteArray &tag) const
 {
     if (const unsigned int id = sessionId()) {
         return SessionDataHandler::instance()->sessionData(id)->mementos.count(tag) || mementos().count(tag);
     } else {
         return mementos().count(tag);
     }
 }
 
 std::shared_ptr<AssuanCommand::Memento> AssuanCommand::memento(const QByteArray &tag) const
 {
     if (const unsigned int id = sessionId()) {
         const std::shared_ptr<SessionDataHandler> sdh = SessionDataHandler::instance();
         const std::shared_ptr<SessionData> sd = sdh->sessionData(id);
         const auto it = sd->mementos.find(tag);
         if (it != sd->mementos.end()) {
             return it->second;
         }
     }
     const auto it = mementos().find(tag);
     if (it == mementos().end()) {
         return std::shared_ptr<Memento>();
     } else {
         return it->second;
     }
 }
 
 QByteArray AssuanCommand::registerMemento(const std::shared_ptr<Memento> &mem)
 {
     const QByteArray tag = QByteArray::number(reinterpret_cast<qulonglong>(mem.get()), 36);
     return registerMemento(tag, mem);
 }
 
 QByteArray AssuanCommand::registerMemento(const QByteArray &tag, const std::shared_ptr<Memento> &mem)
 {
     // oh, hack :(
     Q_ASSERT(assuan_get_pointer(d->ctx.get()));
     AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(d->ctx.get()));
 
     if (const unsigned int id = sessionId()) {
         SessionDataHandler::instance()->sessionData(id)->mementos[tag] = mem;
     } else {
         conn.mementos[tag] = mem;
     }
     return tag;
 }
 
 void AssuanCommand::removeMemento(const QByteArray &tag)
 {
     // oh, hack :(
     Q_ASSERT(assuan_get_pointer(d->ctx.get()));
     AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(d->ctx.get()));
 
     conn.mementos.erase(tag);
     if (const unsigned int id = sessionId()) {
         SessionDataHandler::instance()->sessionData(id)->mementos.erase(tag);
     }
 }
 
 const std::vector< std::shared_ptr<Input> > &AssuanCommand::inputs() const
 {
     return d->inputs;
 }
 
 const std::vector< std::shared_ptr<Input> > &AssuanCommand::messages() const
 {
     return d->messages;
 }
 
 const std::vector< std::shared_ptr<Output> > &AssuanCommand::outputs() const
 {
     return d->outputs;
 }
 
 QStringList AssuanCommand::fileNames() const
 {
     QStringList rv;
     rv.reserve(d->files.size());
     std::copy(d->files.cbegin(), d->files.cend(), std::back_inserter(rv));
     return rv;
 }
 
 unsigned int AssuanCommand::numFiles() const
 {
     return d->files.size();
 }
 
 void AssuanCommand::sendStatus(const char *keyword, const QString &text)
 {
     sendStatusEncoded(keyword, text.toUtf8().constData());
 }
 
 void AssuanCommand::sendStatusEncoded(const char *keyword, const std::string &text)
 {
     if (d->nohup) {
         return;
     }
     if (const int err = assuan_write_status(d->ctx.get(), keyword, text.c_str())) {
         throw Exception(err, i18n("Cannot send \"%1\" status", QString::fromLatin1(keyword)));
     }
 }
 
 void  AssuanCommand::sendData(const QByteArray &data, bool moreToCome)
 {
     if (d->nohup) {
         return;
     }
     if (const gpg_error_t err = assuan_send_data(d->ctx.get(), data.constData(), data.size())) {
         throw Exception(err, i18n("Cannot send data"));
     }
     if (!moreToCome)
         if (const gpg_error_t err = assuan_send_data(d->ctx.get(), nullptr, 0)) {   // flush
             throw Exception(err, i18n("Cannot flush data"));
         }
 }
 
 int AssuanCommand::inquire(const char *keyword, QObject *receiver, const char *slot, unsigned int maxSize)
 {
     Q_ASSERT(keyword);
     Q_ASSERT(receiver);
     Q_ASSERT(slot);
 
     if (d->nohup) {
         return makeError(GPG_ERR_INV_OP);
     }
 
-#if defined(HAVE_ASSUAN2) || defined(HAVE_ASSUAN_INQUIRE_EXT)
     std::unique_ptr<InquiryHandler> ih(new InquiryHandler(keyword, receiver));
     receiver->connect(ih.get(), SIGNAL(signal(int,QByteArray,QByteArray)), slot);
     if (const gpg_error_t err = assuan_inquire_ext(d->ctx.get(), keyword,
-# if !defined(HAVE_ASSUAN2) && !defined(HAVE_NEW_STYLE_ASSUAN_INQUIRE_EXT)
-                                &ih->buffer, &ih->buflen,
-# endif
                                 maxSize, InquiryHandler::handler, ih.get())) {
         return err;
     }
     ih.release();
     return 0;
-#else
-    return makeError(GPG_ERR_NOT_SUPPORTED);   // libassuan too old
-#endif // defined(HAVE_ASSUAN2) || defined(HAVE_ASSUAN_INQUIRE_EXT)
 }
 
 void AssuanCommand::done(const GpgME::Error &err, const QString &details)
 {
     if (d->ctx && !d->done && !details.isEmpty()) {
         qCDebug(KLEOPATRA_LOG) << "Error: " << details;
         d->utf8ErrorKeepAlive = details.toUtf8();
         if (!d->nohup) {
             assuan_set_error(d->ctx.get(), err.encodedError(), d->utf8ErrorKeepAlive.constData());
         }
     }
     done(err);
 }
 
 void AssuanCommand::done(const GpgME::Error &err)
 {
     if (!d->ctx) {
         qCDebug(KLEOPATRA_LOG) << err.asString() << ": called with NULL ctx.";
         return;
     }
     if (d->done) {
         qCDebug(KLEOPATRA_LOG) << err.asString() << ": called twice!";
         return;
     }
 
     d->done = true;
 
     std::for_each(d->messages.begin(), d->messages.end(), std::mem_fn(&Input::finalize));
     std::for_each(d->inputs.begin(), d->inputs.end(), std::mem_fn(&Input::finalize));
     std::for_each(d->outputs.begin(), d->outputs.end(), std::mem_fn(&Output::finalize));
     d->messages.clear();
     d->inputs.clear();
     d->outputs.clear();
     d->files.clear();
 
     // oh, hack :(
     Q_ASSERT(assuan_get_pointer(d->ctx.get()));
     AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(d->ctx.get()));
 
     if (d->nohup) {
         conn.nohupDone(this);
         return;
     }
 
     const gpg_error_t rc = assuan_process_done(d->ctx.get(), err.encodedError());
     if (gpg_err_code(rc) != GPG_ERR_NO_ERROR)
         qFatal("AssuanCommand::done: assuan_process_done returned error %d (%s)",
                static_cast<int>(rc), gpg_strerror(rc));
 
     d->utf8ErrorKeepAlive.clear();
 
     conn.commandDone(this);
 }
 
 void AssuanCommand::setNohup(bool nohup)
 {
     d->nohup = nohup;
 }
 
 bool AssuanCommand::isNohup() const
 {
     return d->nohup;
 }
 
 bool AssuanCommand::isDone() const
 {
     return d->done;
 }
 
 QString AssuanCommand::sessionTitle() const
 {
     return d->sessionTitle;
 }
 
 unsigned int AssuanCommand::sessionId() const
 {
     return d->sessionId;
 }
 
 bool AssuanCommand::informativeSenders() const
 {
     return d->informativeSenders;
 }
 
 bool AssuanCommand::informativeRecipients() const
 {
     return d->informativeRecipients;
 }
 
 const std::vector<KMime::Types::Mailbox> &AssuanCommand::recipients() const
 {
     return d->recipients;
 }
 
 const std::vector<KMime::Types::Mailbox> &AssuanCommand::senders() const
 {
     return d->senders;
 }
 
-#ifndef HAVE_ASSUAN2
-int AssuanCommandFactory::_handle(assuan_context_t ctx, char *line, const char *commandName)
-{
-#else
 gpg_error_t AssuanCommandFactory::_handle(assuan_context_t ctx, char *line, const char *commandName)
 {
-#endif
     Q_ASSERT(assuan_get_pointer(ctx));
     AssuanServerConnection::Private &conn = *static_cast<AssuanServerConnection::Private *>(assuan_get_pointer(ctx));
 
     try {
 
         const auto it
             = std::lower_bound(conn.factories.begin(), conn.factories.end(), commandName, _detail::ByName<std::less>());
         kleo_assert(it != conn.factories.end());
         kleo_assert(*it);
         kleo_assert(qstricmp((*it)->name(), commandName) == 0);
 
         const std::shared_ptr<AssuanCommand> cmd = (*it)->create();
         kleo_assert(cmd);
 
         cmd->d->ctx     = conn.ctx;
         cmd->d->options = conn.options;
         cmd->d->inputs.swap(conn.inputs);     kleo_assert(conn.inputs.empty());
         cmd->d->messages.swap(conn.messages); kleo_assert(conn.messages.empty());
         cmd->d->outputs.swap(conn.outputs);   kleo_assert(conn.outputs.empty());
         cmd->d->files.swap(conn.files);       kleo_assert(conn.files.empty());
         cmd->d->senders.swap(conn.senders);   kleo_assert(conn.senders.empty());
         cmd->d->recipients.swap(conn.recipients); kleo_assert(conn.recipients.empty());
         cmd->d->informativeRecipients = conn.informativeRecipients;
         cmd->d->informativeSenders    = conn.informativeSenders;
         cmd->d->bias                  = conn.bias;
         cmd->d->sessionTitle          = conn.sessionTitle;
         cmd->d->sessionId             = conn.sessionId;
 
         const std::map<std::string, std::string> cmdline_options = parse_commandline(line);
         for (auto it = cmdline_options.begin(), end = cmdline_options.end(); it != end; ++it) {
             cmd->d->options[it->first] = QString::fromUtf8(it->second.c_str());
         }
 
         bool nohup = false;
         if (cmd->d->options.count("nohup")) {
             if (!cmd->d->options["nohup"].toString().isEmpty()) {
                 return assuan_process_done_msg(conn.ctx.get(), gpg_error(GPG_ERR_ASS_PARAMETER), "--nohup takes no argument");
             }
             nohup = true;
             cmd->d->options.erase("nohup");
         }
 
         conn.currentCommand = cmd;
         conn.currentCommandIsNohup = nohup;
 
         QTimer::singleShot(0, &conn, &AssuanServerConnection::Private::startCommandBottomHalf);
 
         return 0;
 
     } catch (const Exception &e) {
         return assuan_process_done_msg(conn.ctx.get(), e.error_code(), e.message());
     } catch (const std::exception &e) {
         return assuan_process_done_msg(conn.ctx.get(), gpg_error(GPG_ERR_UNEXPECTED), e.what());
     } catch (...) {
         return assuan_process_done_msg(conn.ctx.get(), gpg_error(GPG_ERR_UNEXPECTED), i18n("Caught unknown exception"));
     }
 }
 
 int AssuanServerConnection::Private::startCommandBottomHalf()
 {
 
     commandWaitingForCryptoCommandsEnabled = currentCommand && !cryptoCommandsEnabled;
 
     if (!cryptoCommandsEnabled) {
         return 0;
     }
 
     const std::shared_ptr<AssuanCommand> cmd = currentCommand;
     if (!cmd) {
         return 0;
     }
 
     currentCommand.reset();
 
     const bool nohup = currentCommandIsNohup;
     currentCommandIsNohup = false;
 
     try {
 
         if (const int err = cmd->start()) {
             if (cmd->isDone()) {
                 return err;
             } else {
                 return assuan_process_done(ctx.get(), err);
             }
         }
 
         if (cmd->isDone()) {
             return 0;
         }
 
         if (nohup) {
             cmd->setNohup(true);
             nohupedCommands.push_back(cmd);
             return assuan_process_done_msg(ctx.get(), 0, "Command put in the background to continue executing after connection end.");
         } else {
             currentCommand = cmd;
             return 0;
         }
 
     } catch (const Exception &e) {
         return assuan_process_done_msg(ctx.get(), e.error_code(), e.message());
     } catch (const std::exception &e) {
         return assuan_process_done_msg(ctx.get(), gpg_error(GPG_ERR_UNEXPECTED), e.what());
     } catch (...) {
         return assuan_process_done_msg(ctx.get(), gpg_error(GPG_ERR_UNEXPECTED), i18n("Caught unknown exception"));
     }
 
 }
 
 //
 //
 // AssuanCommand convenience methods
 //
 //
 
 /*!
   Checks the \c --mode parameter.
 
   \returns The parameter as an AssuanCommand::Mode enum value.
 
   If no \c --mode was given, or it's value wasn't recognized, throws
   an Kleo::Exception.
 */
 AssuanCommand::Mode AssuanCommand::checkMode() const
 {
     if (!hasOption("mode")) {
         throw Exception(makeError(GPG_ERR_MISSING_VALUE), i18n("Required --mode option missing"));
     }
 
     const QString modeString = option("mode").toString().toLower();
     if (modeString == QLatin1String("filemanager")) {
         return FileManager;
     }
     if (modeString == QLatin1String("email")) {
         return EMail;
     }
     throw Exception(makeError(GPG_ERR_INV_ARG), i18n("invalid mode: \"%1\"", modeString));
 }
 
 /*!
   Checks the \c --protocol parameter.
 
   \returns The parameter as a GpgME::Protocol enum value.
 
   If \c --protocol was given, but has an invalid value, throws an
   Kleo::Exception.
 
   If no \c --protocol was given, checks the connection bias, if
   available, otherwise, in FileManager mode, returns
   GpgME::UnknownProtocol, but if \a mode == \c EMail, throws an
   Kleo::Exception instead.
 */
 GpgME::Protocol AssuanCommand::checkProtocol(Mode mode, int options) const
 {
     if (!hasOption("protocol"))
         if (d->bias != GpgME::UnknownProtocol) {
             return d->bias;
         } else if (mode == AssuanCommand::EMail && (options & AllowProtocolMissing) == 0) {
             throw Exception(makeError(GPG_ERR_MISSING_VALUE), i18n("Required --protocol option missing"));
         } else {
             return GpgME::UnknownProtocol;
         }
     else if (mode == AssuanCommand::FileManager) {
         throw Exception(makeError(GPG_ERR_INV_FLAG), i18n("--protocol is not allowed here"));
     }
 
     const QString protocolString = option("protocol").toString().toLower();
     if (protocolString == QLatin1String("openpgp")) {
         return GpgME::OpenPGP;
     }
     if (protocolString == QLatin1String("cms")) {
         return GpgME::CMS;
     }
     throw Exception(makeError(GPG_ERR_INV_ARG), i18n("invalid protocol \"%1\"", protocolString));
 }
 
 void AssuanCommand::doApplyWindowID(QWidget *widget) const
 {
     if (!widget || !hasOption("window-id")) {
         return;
     }
     apply_window_id(widget, option("window-id").toString());
 }
 
 WId AssuanCommand::parentWId() const
 {
     return wid_from_string(option("window-id").toString());
 }
 
 #include "assuanserverconnection.moc"
diff --git a/src/uiserver/uiserver.cpp b/src/uiserver/uiserver.cpp
index ab4d2ca71..5901de354 100644
--- a/src/uiserver/uiserver.cpp
+++ b/src/uiserver/uiserver.cpp
@@ -1,297 +1,283 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     uiserver/uiserver.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include <config-kleopatra.h>
 
 #include "uiserver.h"
 #include "uiserver_p.h"
 
 #include "sessiondata.h"
 
 #include <utils/detail_p.h>
 #include <Libkleo/GnuPG>
 
 #include <Libkleo/Stl_Util>
 #include <Libkleo/KleoException>
 
 #include "kleopatra_debug.h"
 #include <KLocalizedString>
 
 #include <gpgme++/global.h>
 
 #include <QTcpSocket>
 #include <QDir>
 #include <QEventLoop>
 #include <QTimer>
 #include <QFile>
 
 #include <algorithm>
 #include <cerrno>
 
 using namespace Kleo;
 
 // static
 void UiServer::setLogStream(FILE *stream)
 {
     assuan_set_assuan_log_stream(stream);
 }
 
 UiServer::Private::Private(UiServer *qq)
     : QTcpServer(),
       q(qq),
       file(),
       factories(),
       connections(),
       suggestedSocketName(),
       actualSocketName(),
       cryptoCommandsEnabled(false)
 {
-#ifndef HAVE_ASSUAN2
-    assuan_set_assuan_err_source(GPG_ERR_SOURCE_DEFAULT);
-#else
     assuan_set_gpg_err_source(GPG_ERR_SOURCE_DEFAULT);
     assuan_sock_init();
-#endif
 }
 
 bool UiServer::Private::isStaleAssuanSocket(const QString &fileName)
 {
     assuan_context_t ctx = nullptr;
-#ifndef HAVE_ASSUAN2
-    const bool error = assuan_socket_connect_ext(&ctx, QFile::encodeName(fileName).constData(), -1, 0);
-#else
     const bool error = assuan_new(&ctx) || assuan_socket_connect(ctx, QFile::encodeName(fileName).constData(), ASSUAN_INVALID_PID, 0);
-#endif
     if (!error)
-#ifndef HAVE_ASSUAN2
-        assuan_disconnect(ctx);
-#else
         assuan_release(ctx);
-#endif
     return error;
 }
 
 UiServer::UiServer(const QString &socket, QObject *p)
     : QObject(p), d(new Private(this))
 {
     d->suggestedSocketName = d->makeFileName(socket);
 }
 
 UiServer::~UiServer()
 {
     if (QFile::exists(d->actualSocketName)) {
         QFile::remove(d->actualSocketName);
     }
 }
 
 namespace {
 using Iterator = std::vector<std::shared_ptr<AssuanCommandFactory>>::iterator;
 static bool empty(std::pair<Iterator, Iterator> iters)
 {
     return iters.first == iters.second;
 }
 }
 
 bool UiServer::registerCommandFactory(const std::shared_ptr<AssuanCommandFactory> &cf)
 {
     if (cf && empty(std::equal_range(d->factories.begin(), d->factories.end(), cf, _detail::ByName<std::less>()))) {
         d->factories.push_back(cf);
         std::inplace_merge(d->factories.begin(), d->factories.end() - 1, d->factories.end(), _detail::ByName<std::less>());
         return true;
     } else {
         if (!cf) {
             qCWarning(KLEOPATRA_LOG) << "NULL factory";
         } else {
             qCWarning(KLEOPATRA_LOG) << (void *)cf.get() << " factory already registered";
         }
 
         return false;
     }
 }
 
 void UiServer::start()
 {
     d->makeListeningSocket();
 }
 
 void UiServer::stop()
 {
 
     d->close();
 
     if (d->file.exists()) {
         d->file.remove();
     }
 
     if (isStopped()) {
         SessionDataHandler::instance()->clear();
         Q_EMIT stopped();
     }
 
 }
 
 void UiServer::enableCryptoCommands(bool on)
 {
     if (on == d->cryptoCommandsEnabled) {
         return;
     }
     d->cryptoCommandsEnabled = on;
     std::for_each(d->connections.cbegin(), d->connections.cend(),
                   [on](std::shared_ptr<AssuanServerConnection> conn) {
                       conn->enableCryptoCommands(on);
                   });
 }
 
 QString UiServer::socketName() const
 {
     return d->actualSocketName;
 }
 
 bool UiServer::waitForStopped(unsigned int ms)
 {
     if (isStopped()) {
         return true;
     }
     QEventLoop loop;
     QTimer timer;
     timer.setInterval(ms);
     timer.setSingleShot(true);
     connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
     connect(this, &UiServer::stopped, &loop, &QEventLoop::quit);
     loop.exec();
     return !timer.isActive();
 }
 
 bool UiServer::isStopped() const
 {
     return d->connections.empty() && !d->isListening();
 }
 
 bool UiServer::isStopping() const
 {
     return !d->connections.empty() && !d->isListening();
 }
 
 void UiServer::Private::slotConnectionClosed(Kleo::AssuanServerConnection *conn)
 {
     qCDebug(KLEOPATRA_LOG) << "UiServer: connection " << (void *)conn << " closed";
     connections.erase(std::remove_if(connections.begin(), connections.end(),
                                      [conn](const std::shared_ptr<AssuanServerConnection> &other) {
                                          return conn == other.get();
                                      }),
                       connections.end());
     if (q->isStopped()) {
         SessionDataHandler::instance()->clear();
         Q_EMIT q->stopped();
     }
 }
 
 void UiServer::Private::incomingConnection(qintptr fd)
 {
     try {
         qCDebug(KLEOPATRA_LOG) << "UiServer: client connect on fd " << fd;
-#if defined(HAVE_ASSUAN_SOCK_GET_NONCE) || defined(HAVE_ASSUAN2)
         if (assuan_sock_check_nonce((assuan_fd_t)fd, &nonce)) {
             qCDebug(KLEOPATRA_LOG) << "UiServer: nonce check failed";
             assuan_sock_close((assuan_fd_t)fd);
             return;
         }
-#endif
         const std::shared_ptr<AssuanServerConnection> c(new AssuanServerConnection((assuan_fd_t)fd, factories));
         connect(c.get(), &AssuanServerConnection::closed,
                 this, &Private::slotConnectionClosed);
         connect(c.get(), &AssuanServerConnection::startKeyManagerRequested,
                 q, &UiServer::startKeyManagerRequested, Qt::QueuedConnection);
         connect(c.get(), &AssuanServerConnection::startConfigDialogRequested,
                 q, &UiServer::startConfigDialogRequested, Qt::QueuedConnection);
         c->enableCryptoCommands(cryptoCommandsEnabled);
         connections.push_back(c);
         qCDebug(KLEOPATRA_LOG) << "UiServer: client connection " << (void *)c.get() << " established successfully";
     } catch (const Exception &e) {
         qCDebug(KLEOPATRA_LOG) << "UiServer: client connection failed: " << e.what();
         QTcpSocket s;
         s.setSocketDescriptor(fd);
         QTextStream(&s) << "ERR " << e.error_code() << " " << e.what() << "\r\n";
         s.waitForBytesWritten();
         s.close();
     } catch (...) {
         qCDebug(KLEOPATRA_LOG) << "UiServer: client connection failed: unknown exception caught";
         // this should never happen...
         QTcpSocket s;
         s.setSocketDescriptor(fd);
         QTextStream(&s) << "ERR 63 unknown exception caught\r\n";
         s.waitForBytesWritten();
         s.close();
     }
 }
 
 QString UiServer::Private::makeFileName(const QString &socket) const
 {
     if (!socket.isEmpty()) {
         return socket;
     }
     const QString socketPath{QString::fromUtf8(GpgME::dirInfo("uiserver-socket"))};
     if (!socketPath.isEmpty()) {
         // Note: The socket directory exists after GpgME::dirInfo() has been called.
         return socketPath;
     }
     // GPGME (or GnuPG) is too old to return the socket path.
     // In this case we fallback to assume that the socket directory is
     // the home directory as we did in the past.  This is not correct but
     // probably the safest fallback we can do despite that it is a
     // bug to assume the socket directory in the home directory.  See
     // https://dev.gnupg.org/T5613
     const QString gnupgHome = gnupgHomeDirectory();
     if (gnupgHome.isEmpty()) {
         throw_<std::runtime_error>(i18n("Could not determine the GnuPG home directory. Consider setting the GNUPGHOME environment variable."));
     }
     // We should not create the home directory, but this only happens for very
     // old and long unsupported versions of gnupg.
     ensureDirectoryExists(gnupgHome);
     const QDir dir(gnupgHome);
     Q_ASSERT(dir.exists());
     return dir.absoluteFilePath(QStringLiteral("S.uiserver"));
 }
 
 void UiServer::Private::ensureDirectoryExists(const QString &path) const
 {
     const QFileInfo info(path);
     if (info.exists() && !info.isDir()) {
         throw_<std::runtime_error>(i18n("Cannot determine the GnuPG home directory: %1 exists but is not a directory.", path));
     }
     if (info.exists()) {
         return;
     }
     const QDir dummy; //there is no static QDir::mkpath()...
     errno = 0;
     if (!dummy.mkpath(path)) {
         throw_<std::runtime_error>(i18n("Could not create GnuPG home directory %1: %2", path, systemErrorString()));
     }
 }
 
 void UiServer::Private::makeListeningSocket()
 {
 
     // First, create a file (we do this only for the name, gmpfh)
     const QString fileName = suggestedSocketName;
 
     if (QFile::exists(fileName)) {
         if (isStaleAssuanSocket(fileName)) {
             QFile::remove(fileName);
         } else {
             throw_<std::runtime_error>(i18n("Detected another running gnupg UI server listening at %1.", fileName));
         }
     }
 
     doMakeListeningSocket(fileName.toUtf8());
 
     actualSocketName = suggestedSocketName;
 }
 
 #include "moc_uiserver_p.cpp"
diff --git a/src/uiserver/uiserver_unix.cpp b/src/uiserver/uiserver_unix.cpp
index 954900b4b..a9312cfe7 100644
--- a/src/uiserver/uiserver_unix.cpp
+++ b/src/uiserver/uiserver_unix.cpp
@@ -1,81 +1,71 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     uiserver/uiserver_unix.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 #include <config-kleopatra.h>
 
 #include "uiserver_p.h"
 
 #include <Libkleo/GnuPG>
 
 #include <KLocalizedString>
 
 #include <stdexcept>
 
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <cstdio>
 #include <cerrno>
 #include <cstring>
 
 using namespace Kleo;
 
 QString UiServer::Private::systemErrorString()
 {
     return QString::fromLocal8Bit(strerror(errno));
 }
 
 void UiServer::Private::doMakeListeningSocket(const QByteArray &encodedFileName)
 {
     // Create a Unix Domain Socket:
-#if defined(HAVE_ASSUAN2) || HAVE_ASSUAN_SOCK_GET_NONCE
     const assuan_fd_t sock = assuan_sock_new(AF_UNIX, SOCK_STREAM, 0);
-#else
-    const assuan_fd_t sock = ::socket(AF_UNIX, SOCK_STREAM, 0);
-#endif
     if (sock == ASSUAN_INVALID_FD) {
         throw_<std::runtime_error>(i18n("Could not create socket: %1", systemErrorString()));
     }
 
     try {
         // Bind
         struct sockaddr_un sa;
         std::memset(&sa, 0, sizeof(sa));
         sa.sun_family = AF_UNIX;
         std::strncpy(sa.sun_path, encodedFileName.constData(), sizeof(sa.sun_path) - 1);
-#if defined(HAVE_ASSUAN2) || defined(HAVE_ASSUAN_SOCK_GET_NONCE)
         if (assuan_sock_bind(sock, (struct sockaddr *)&sa, sizeof(sa)))
-#else
-        if (::bind(sock, (struct sockaddr *)&sa, sizeof(sa)))
-#endif
             throw_<std::runtime_error>(i18n("Could not bind to socket: %1", systemErrorString()));
 
         // ### TODO: permissions?
 
-#if defined(HAVE_ASSUAN2) || defined(HAVE_ASSUAN_SOCK_GET_NONCE)
         if (assuan_sock_get_nonce((struct sockaddr *)&sa, sizeof(sa), &nonce)) {
             throw_<std::runtime_error>(i18n("Could not get socket nonce: %1", systemErrorString()));
         }
-#endif
 
         // Listen
         if (::listen(sock, SOMAXCONN)) {
             throw_<std::runtime_error>(i18n("Could not listen to socket: %1", systemErrorString()));
         }
 
         if (!setSocketDescriptor(sock)) {
             throw_<std::runtime_error>(i18n("Could not pass socket to Qt: %1. This should not happen, please report this bug.", errorString()));
         }
 
     } catch (...) {
         ::close(sock);
         throw;
     }
 }
 
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 40a6e0611..182921fa2 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,86 +1,79 @@
 # SPDX-FileCopyrightText: none
 # SPDX-License-Identifier: BSD-3-Clause
 add_subdirectory(gnupg_home)
 
 set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR})
 include_directories(
   ${CMAKE_SOURCE_DIR}/src/
   ${CMAKE_BINARY_DIR}/src/
   ${GPGME_INCLUDES}
 )
 
 ########### next target ###############
 
 set(test_verify_SRCS test_verify.cpp)
 
 add_definitions(-DKLEO_TEST_GNUPGHOME="${CMAKE_CURRENT_BINARY_DIR}/gnupg_home")
 add_definitions(-DKLEO_TEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}")
 
 
 add_executable(test_verify  ${test_verify_SRCS})
 add_test(NAME test_verify COMMAND test_verify)
 ecm_mark_as_test(test_verify)
 
 target_link_libraries(test_verify
   KF5::Libkleo
   Qt::Test
   KF5::CoreAddons
   KF5::I18n
   Qt::Widgets
 )
 
 if (QT_MAJOR_VERSION STREQUAL "6")
     target_link_libraries(test_verify QGpgmeQt6)
 else()
     target_link_libraries(test_verify QGpgme)
 endif()
 
 
 ########### next target ###############
 
 if(USABLE_ASSUAN_FOUND)
 
   # this doesn't yet work on Windows
 
   add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_2)
 
   set(test_uiserver_SRCS test_uiserver.cpp ${CMAKE_SOURCE_DIR}/src/utils/wsastarter.cpp)
 
 #FIXME: omitting TEST makes test_uiserver print output again on a Win32 console;
 # find a better fix for this issue
   if(WIN32)
     add_executable(test_uiserver ${test_uiserver_SRCS})
   else()
     add_executable(test_uiserver ${test_uiserver_SRCS})
   endif()
   target_link_libraries(test_uiserver KF5::I18n)
 
-  if(ASSUAN2_FOUND)
     target_link_libraries(test_uiserver
       KF5::Libkleo
       ${ASSUAN2_LIBRARIES}
     )
-  else()
-    target_link_libraries(test_uiserver
-      KF5::Libkleo
-      ${ASSUAN_LIBRARIES}
-    )
-  endif()
 
   if(WIN32)
     target_link_libraries(test_uiserver
       ${ASSUAN_VANILLA_LIBRARIES}
       ws2_32
     )
   else()
     target_link_libraries(test_uiserver
       ${ASSUAN_PTHREAD_LIBRARIES}
   )
   endif()
   if (QT_MAJOR_VERSION STREQUAL "6")
       target_link_libraries(test_uiserver QGpgmeQt6)
   else()
       target_link_libraries(test_uiserver QGpgme)
   endif()
 endif()
 
diff --git a/tests/test_uiserver.cpp b/tests/test_uiserver.cpp
index 6f7684b5e..28fdb04d6 100644
--- a/tests/test_uiserver.cpp
+++ b/tests/test_uiserver.cpp
@@ -1,298 +1,270 @@
 /* -*- mode: c++; c-basic-offset:4 -*-
     tests/test_uiserver.cpp
 
     This file is part of Kleopatra, the KDE keymanager
     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
 
     SPDX-License-Identifier: GPL-2.0-or-later
 */
 
 //
 // Usage: test_uiserver <socket> --verify-detached <signed data> <signature>
 //
 
 #include <config-kleopatra.h>
 
 #include <kleo-assuan.h>
 #include <gpg-error.h>
 
 #include <Libkleo/Hex>
 #include <Libkleo/KleoException>
 
 #include "utils/wsastarter.h"
 
 #ifndef Q_OS_WIN32
 # include <unistd.h>
 # include <sys/types.h>
 # include <sys/stat.h>
 # include <fcntl.h>
 # include <errno.h>
 #endif
 
 #include <cstdlib>
 #include <iostream>
 #include <map>
 #include <string>
 #include <vector>
 
 using namespace Kleo;
 
 #ifdef Q_OS_WIN32
 static const bool HAVE_FD_PASSING = false;
 #else
 static const bool HAVE_FD_PASSING = true;
 #endif
 
 static const unsigned int ASSUAN_CONNECT_FLAGS = HAVE_FD_PASSING ? 1 : 0;
 
 static std::vector<int> inFDs, outFDs, msgFDs;
 static std::vector<std::string> inFiles, outFiles, msgFiles;
 static std::map<std::string, std::string> inquireData;
 
 static void usage(const std::string &msg = std::string())
 {
     std::cerr << msg << std::endl <<
               "\n"
               "Usage: test_uiserver <socket> [<io>] [<options>] [<inquire>] command [<args>]\n"
               "where:\n"
 #ifdef Q_OS_WIN32
               "      <io>: [--input[-fd] <file>] [--output[-fd] <file>] [--message[-fd] <file>]\n"
 #else
               "      <io>: [--input <file>] [--output <file>] [--message <file>]\n"
 #endif
               " <options>: *[--option name=value]\n"
               " <inquire>: [--inquire keyword=<file>]\n";
     exit(1);
 }
 
-#ifndef HAVE_ASSUAN2
-static assuan_error_t data(void *void_ctx, const void *buffer, size_t len)
-{
-#else
 static gpg_error_t data(void *void_ctx, const void *buffer, size_t len)
 {
-#endif
     (void)void_ctx; (void)buffer; (void)len;
     return 0; // ### implement me
 }
 
-#ifndef HAVE_ASSUAN2
-static assuan_error_t status(void *void_ctx, const char *line)
-{
-#else
 static gpg_error_t status(void *void_ctx, const char *line)
 {
-#endif
     (void)void_ctx; (void)line;
     return 0;
 }
 
-#ifndef HAVE_ASSUAN2
-static assuan_error_t inquire(void *void_ctx, const char *keyword)
-{
-#else
 static gpg_error_t inquire(void *void_ctx, const char *keyword)
 {
-#endif
     assuan_context_t ctx = (assuan_context_t)void_ctx;
     Q_ASSERT(ctx);
     const std::map<std::string, std::string>::const_iterator it = inquireData.find(keyword);
     if (it == inquireData.end()) {
         return gpg_error(GPG_ERR_UNKNOWN_COMMAND);
     }
 
     if (!it->second.empty() && it->second[0] == '@') {
         return gpg_error(GPG_ERR_NOT_IMPLEMENTED);
     }
 
     if (const gpg_error_t err = assuan_send_data(ctx, it->second.c_str(), it->second.size())) {
         qDebug("assuan_write_data: %s", gpg_strerror(err));
         return err;
     }
 
     return 0;
 }
 
 int main(int argc, char *argv[])
 {
 
     const Kleo::WSAStarter _wsastarter;
 
-#ifndef HAVE_ASSUAN2
-    assuan_set_assuan_err_source(GPG_ERR_SOURCE_DEFAULT);
-#else
     assuan_set_gpg_err_source(GPG_ERR_SOURCE_DEFAULT);
-#endif
 
     if (argc < 3) {
         usage();    // need socket and command, at least
     }
 
     const char *socket = argv[1];
 
     std::vector<const char *> options;
 
     std::string command;
     for (int optind = 2; optind < argc; ++optind) {
         const char *const arg = argv[optind];
         if (qstrcmp(arg, "--input") == 0) {
             const std::string file = argv[++optind];
             inFiles.push_back(file);
         } else if (qstrcmp(arg, "--output") == 0) {
             const std::string file = argv[++optind];
             outFiles.push_back(file);
         } else if (qstrcmp(arg, "--message") == 0) {
             const std::string file = argv[++optind];
             msgFiles.push_back(file);
 #ifndef Q_OS_WIN32
         } else if (qstrcmp(arg, "--input-fd") == 0) {
             int inFD;
             if ((inFD = open(argv[++optind], O_RDONLY)) == -1) {
                 perror("--input-fd open()");
                 return 1;
             }
             inFDs.push_back(inFD);
         } else if (qstrcmp(arg, "--output-fd") == 0) {
             int outFD;
             if ((outFD = open(argv[++optind], O_WRONLY | O_CREAT, 0666)) ==  -1) {
                 perror("--output-fd open()");
                 return 1;
             }
             outFDs.push_back(outFD);
         } else if (qstrcmp(arg, "--message-fd") == 0) {
             int msgFD;
             if ((msgFD = open(argv[++optind], O_RDONLY)) ==  -1) {
                 perror("--message-fd open()");
                 return 1;
             }
             msgFDs.push_back(msgFD);
 #endif
         } else if (qstrcmp(arg, "--option") == 0) {
             options.push_back(argv[++optind]);
         } else if (qstrcmp(arg, "--inquire") == 0) {
             const std::string inqval = argv[++optind];
             const size_t pos = inqval.find('=');
             // ### implement indirection with "@file"...
             inquireData[inqval.substr(0, pos)] = inqval.substr(pos + 1);
         } else {
             while (optind < argc) {
                 if (!command.empty()) {
                     command += ' ';
                 }
                 command += argv[optind++];
             }
         }
     }
     if (command.empty()) {
         usage("Command expected, but only options found");
     }
 
     assuan_context_t ctx = nullptr;
 
-#ifndef HAVE_ASSUAN2
-    if (const gpg_error_t err = assuan_socket_connect_ext(&ctx, socket, -1, ASSUAN_CONNECT_FLAGS)) {
-        qDebug("%s", Exception(err, "assuan_socket_connect_ext").what());
-#else
     if (const gpg_error_t err = assuan_new(&ctx)) {
         qDebug("%s", Exception(err, "assuan_new").what());
         return 1;
     }
 
     if (const gpg_error_t err = assuan_socket_connect(ctx, socket, -1, ASSUAN_CONNECT_FLAGS)) {
         qDebug("%s", Exception(err, "assuan_socket_connect").what());
-#endif
         return 1;
     }
 
     assuan_set_log_stream(ctx, stderr);
 
 #ifndef Q_OS_WIN32
     for (std::vector<int>::const_iterator it = inFDs.begin(), end = inFDs.end(); it != end; ++it) {
         if (const gpg_error_t err = assuan_sendfd(ctx, *it)) {
             qDebug("%s", Exception(err, "assuan_sendfd( inFD )").what());
             return 1;
         }
 
         if (const gpg_error_t err = assuan_transact(ctx, "INPUT FD", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) {
             qDebug("%s", Exception(err, "INPUT FD").what());
             return 1;
         }
     }
 
     for (std::vector<int>::const_iterator it = msgFDs.begin(), end = msgFDs.end(); it != end; ++it) {
         if (const gpg_error_t err = assuan_sendfd(ctx, *it)) {
             qDebug("%s", Exception(err, "assuan_sendfd( msgFD )").what());
             return 1;
         }
 
         if (const gpg_error_t err = assuan_transact(ctx, "MESSAGE FD", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) {
             qDebug("%s", Exception(err, "MESSAGE FD").what());
             return 1;
         }
     }
 
     for (std::vector<int>::const_iterator it = outFDs.begin(), end = outFDs.end(); it != end; ++it) {
         if (const gpg_error_t err = assuan_sendfd(ctx, *it)) {
             qDebug("%s", Exception(err, "assuan_sendfd( outFD )").what());
             return 1;
         }
 
         if (const gpg_error_t err = assuan_transact(ctx, "OUTPUT FD", nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) {
             qDebug("%s", Exception(err, "OUTPUT FD").what());
             return 1;
         }
     }
 #endif
 
     for (std::vector<std::string>::const_iterator it = inFiles.begin(), end = inFiles.end(); it != end; ++it) {
         char buffer[1024];
         sprintf(buffer, "INPUT FILE=%s", hexencode(*it).c_str());
 
         if (const gpg_error_t err = assuan_transact(ctx, buffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) {
             qDebug("%s", Exception(err, buffer).what());
             return 1;
         }
     }
 
     for (std::vector<std::string>::const_iterator it = msgFiles.begin(), end = msgFiles.end(); it != end; ++it) {
         char buffer[1024];
         sprintf(buffer, "MESSAGE FILE=%s", hexencode(*it).c_str());
 
         if (const gpg_error_t err = assuan_transact(ctx, buffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) {
             qDebug("%s", Exception(err, buffer).what());
             return 1;
         }
     }
 
     for (std::vector<std::string>::const_iterator it = outFiles.begin(), end = outFiles.end(); it != end; ++it) {
         char buffer[1024];
         sprintf(buffer, "OUTPUT FILE=%s", hexencode(*it).c_str());
 
         if (const gpg_error_t err = assuan_transact(ctx, buffer, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) {
             qDebug("%s", Exception(err, buffer).what());
             return 1;
         }
     }
 
     for (const char *opt : std::as_const(options)) {
         std::string line = "OPTION ";
         line += opt;
         if (const gpg_error_t err = assuan_transact(ctx, line.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) {
             qDebug("%s", Exception(err, line).what());
             return 1;
         }
     }
 
     if (const gpg_error_t err = assuan_transact(ctx, command.c_str(), data, ctx, inquire, ctx, status, ctx)) {
         qDebug("%s", Exception(err, command).what());
         return 1;
     }
 
-#ifndef HAVE_ASSUAN2
-    assuan_disconnect(ctx);
-#else
     assuan_release(ctx);
-#endif
 
     return 0;
 }