diff -Nru qtkeychain-0.1.0/ChangeLog qtkeychain-0.3.0/ChangeLog --- qtkeychain-0.1.0/ChangeLog 1970-01-01 00:00:00.000000000 +0000 +++ qtkeychain-0.3.0/ChangeLog 2014-03-13 13:31:53.000000000 +0000 @@ -0,0 +1,16 @@ +ChangeLog +========= + +version 0.3.0 (release 2014-03-13) + * Gnome Keyring supported added (Francois Ferrand ) + * Improved Qt 5 support + * KWallet: Distinguish empty passwords from non-existing entries + * KWallet: Do not use hardcoded wallet name + * German translation (Daniel Molkentin ) + * Romanian translation (Arthur Țițeică ) + +version 0.2.0: no official release + +version 0.1.0 (release 2013-01-16) + * Initial release + diff -Nru qtkeychain-0.1.0/CMakeLists.txt qtkeychain-0.3.0/CMakeLists.txt --- qtkeychain-0.1.0/CMakeLists.txt 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/CMakeLists.txt 2014-03-13 13:31:53.000000000 +0000 @@ -3,7 +3,7 @@ ### -set(QTKEYCHAIN_VERSION 0.1.0) +set(QTKEYCHAIN_VERSION 0.3.0) set(QTKEYCHAIN_SOVERSION 0) ### @@ -11,9 +11,16 @@ set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${PROJECT_SOURCE_DIR}/cmake/Modules") include(GNUInstallDirs) -# try Qt5 first, and prefer that if found -find_package(Qt5Core QUIET) +option(BUILD_WITH_QT4 "Build qtkeychain with Qt4 no matter if Qt5 was found" OFF) + + +if( NOT BUILD_WITH_QT4 ) + # try Qt5 first, and prefer that if found + find_package(Qt5Core QUIET) +endif() + if (Qt5Core_FOUND) + set(QTKEYCHAIN_VERSION_INFIX 5) if(UNIX AND NOT APPLE) find_package(Qt5DBus REQUIRED) include_directories(${Qt5DBus_INCLUDE_DIRS}) @@ -22,6 +29,13 @@ qt5_add_dbus_interface(${ARGN}) endmacro() endif() + find_package(Qt5LinguistTools REQUIRED) + macro(qt_add_translation) + qt5_add_translation(${ARGN}) + endmacro(qt_add_translation) + macro(qt_create_translation) + qt5_create_translation(${ARGN}) + endmacro(qt_create_translation) macro(qt_wrap_cpp) qt5_wrap_cpp(${ARGN}) endmacro() @@ -37,6 +51,7 @@ endif() endif() else() + set(QTKEYCHAIN_VERSION_INFIX "") if(UNIX AND NOT APPLE) find_package(Qt4 COMPONENTS QtCore QtDBus REQUIRED) set(QTDBUS_LIBRARIES ${QT_QTDBUS_LIBRARY}) @@ -48,6 +63,12 @@ endif() include_directories(${QT_INCLUDES}) set(QTCORE_LIBRARIES ${QT_QTCORE_LIBRARY}) + macro(qt_add_translation) + qt4_add_translation(${ARGN}) + endmacro(qt_add_translation) + macro(qt_create_translation) + qt4_create_translation(${ARGN}) + endmacro(qt_create_translation) macro(qt_wrap_cpp) qt4_wrap_cpp(${ARGN}) endmacro() @@ -61,7 +82,6 @@ keychain.cpp ) - if(WIN32) list(APPEND qtkeychain_SOURCES keychain_win.cpp) list(APPEND qtkeychain_LIBRARIES crypt32) @@ -82,62 +102,93 @@ endif() if(UNIX AND NOT APPLE) - list(APPEND qtkeychain_SOURCES keychain_dbus.cpp) + list(APPEND qtkeychain_SOURCES keychain_unix.cpp gnomekeyring.cpp) qt_add_dbus_interface(qtkeychain_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.KWallet.xml kwallet_interface KWalletInterface) list(APPEND qtkeychain_LIBRARIES ${QTDBUS_LIBRARIES}) endif() QT_WRAP_CPP(qtkeychain_MOC_OUTFILES keychain.h keychain_p.h) +set(qtkeychain_TR_FILES + translations/qtkeychain_de.ts + translations/qtkeychain_ro.ts +) + +file(GLOB qtkeychain_TR_SOURCES *.cpp *.h *.ui) +qt_create_translation(qtkeychain_MESSAGES ${qtkeychain_TR_SOURCES} ${qtkeychain_TR_FILES}) +qt_add_translation(qtkeychain_QM_FILES ${qtkeychain_TR_FILES}) +add_custom_target(messages DEPENDS ${qtkeychain_MESSAGES}) +add_custom_target(translations DEPENDS ${qtkeychain_QM_FILES}) + +if(NOT QT_TRANSLATIONS_DIR) + # If this directory is missing, we are in a Qt5 environment. + # Extract the qmake executable location + get_target_property(QT5_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) + # Ask Qt5 where to put the translations + EXEC_PROGRAM( ${QT5_QMAKE_EXECUTABLE} + ARGS -query QT_INSTALL_TRANSLATIONS + OUTPUT_VARIABLE qt_translations_dir ) + # make sure we have / and not \ as qmake gives on windows + FILE(TO_CMAKE_PATH "${qt_translations_dir}" qt_translations_dir) + SET(QT_TRANSLATIONS_DIR ${qt_translations_dir} CACHE PATH "The + location of the Qt translations" FORCE) +endif() + +install(FILES ${qtkeychain_QM_FILES} + DESTINATION ${QT_TRANSLATIONS_DIR}) + +set(QTKEYCHAIN_TARGET_NAME qt${QTKEYCHAIN_VERSION_INFIX}keychain) if(NOT QTKEYCHAIN_STATIC) - add_library(qtkeychain SHARED ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES}) - set_target_properties(qtkeychain PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_BUILD_QKEYCHAIN_LIB) - target_link_libraries(qtkeychain ${qtkeychain_LIBRARIES}) + add_library(${QTKEYCHAIN_TARGET_NAME} SHARED ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES} ${qtkeychain_QM_FILES}) + set_target_properties(${QTKEYCHAIN_TARGET_NAME} PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_BUILD_QKEYCHAIN_LIB) + target_link_libraries(${QTKEYCHAIN_TARGET_NAME} ${qtkeychain_LIBRARIES}) else() - add_library(qtkeychain STATIC ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES}) - set_target_properties(qtkeychain PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_STATICLIB) + add_library(${QTKEYCHAIN_TARGET_NAME} STATIC ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES} ${qtkeychain_QM_FILES}) + set_target_properties(${QTKEYCHAIN_TARGET_NAME} PROPERTIES COMPILE_DEFINITIONS QKEYCHAIN_STATICLIB) endif() -set_target_properties(qtkeychain PROPERTIES +set_target_properties(${QTKEYCHAIN_TARGET_NAME} PROPERTIES VERSION ${QTKEYCHAIN_VERSION} SOVERSION ${QTKEYCHAIN_SOVERSION} + MACOSX_RPATH 1 + INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" ) install(FILES keychain.h qkeychain_export.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/qtkeychain/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/qt${QTKEYCHAIN_VERSION_INFIX}keychain/ ) -install(TARGETS qtkeychain - EXPORT QtKeychainLibraryDepends +install(TARGETS ${QTKEYCHAIN_TARGET_NAME} + EXPORT Qt${QTKEYCHAIN_VERSION_INFIX}KeychainLibraryDepends RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) add_executable( testclient testclient.cpp ) -target_link_libraries( testclient qtkeychain) +target_link_libraries( testclient ${QTKEYCHAIN_TARGET_NAME}) ### ### CMake config file ### -export(TARGETS qtkeychain FILE "${PROJECT_BINARY_DIR}/QtKeychainLibraryDepends.cmake") -export(PACKAGE QtKeychain) +export(TARGETS ${QTKEYCHAIN_TARGET_NAME} FILE "${PROJECT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainLibraryDepends.cmake") +export(PACKAGE Qt${QTKEYCHAIN_VERSION_INFIX}Keychain) configure_file(QtKeychainBuildTreeSettings.cmake.in - "${PROJECT_BINARY_DIR}/QtKeychainBuildTreeSettings.cmake" @ONLY) + "${PROJECT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainBuildTreeSettings.cmake" @ONLY) configure_file(QtKeychainConfig.cmake.in - "${PROJECT_BINARY_DIR}/QtKeychainConfig.cmake" @ONLY) + "${PROJECT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfig.cmake" @ONLY) configure_file(QtKeychainConfigVersion.cmake.in - "${PROJECT_BINARY_DIR}/QtKeychainConfigVersion.cmake" @ONLY) + "${PROJECT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfigVersion.cmake" @ONLY) -install(EXPORT QtKeychainLibraryDepends - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/QtKeychain" +install(EXPORT Qt${QTKEYCHAIN_VERSION_INFIX}KeychainLibraryDepends + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Qt${QTKEYCHAIN_VERSION_INFIX}Keychain" ) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/QtKeychainConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/QtKeychainConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/QtKeychain +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Qt${QTKEYCHAIN_VERSION_INFIX}Keychain ) diff -Nru qtkeychain-0.1.0/debian/changelog qtkeychain-0.3.0/debian/changelog --- qtkeychain-0.1.0/debian/changelog 2014-01-31 16:35:34.000000000 +0000 +++ qtkeychain-0.3.0/debian/changelog 2014-05-30 06:14:49.000000000 +0000 @@ -1,18 +1,33 @@ -qtkeychain (0.1.0-1~ubuntu2~ppa1) precise; urgency=low +qtkeychain (0.3.0-1~ubuntu1~precise1) precise; urgency=low * Build for Precise. - * Disable symbol handling. + * debian/libqtkeychain0.symbols: removed. + * debian/qtkeychain-dev.install: delete multiarch support. + * debian/libqtkeychain0.install: DITTO. + * debian/patches/fix-store-password.patch: added for GNOME support. - -- Ikuya Awashiro Sat, 01 Feb 2014 01:35:00 +0900 + -- Ikuya Awashiro Fri, 30 May 2014 15:14:01 +0900 -qtkeychain (0.1.0-1ubuntu1) raring; urgency=low +qtkeychain (0.3.0-1) unstable; urgency=medium - * Ubuntu upload + * New upstream release. (Closes: #735043) + * Added gnome-keyring|kwalletmanager as recommends + * Updated debian/libqtkeychain0.symbols + * Updated debian/copyright + * Bumped Standards-Version - -- Jonathan Riddell Wed, 06 Mar 2013 17:22:59 +0000 + -- Sandro Knauß Thu, 20 Mar 2014 13:09:16 +0100 -qtkeychain (0.1.0-1) UNRELEASED; urgency=low +qtkeychain (0.1.0-2) unstable; urgency=low + + * FTBFS on !linux: libraries left in /usr/lib (Closes: #710340) + * Added patch use_system_GNUInstallDirs.cmake + * use githubredir.debian.net for watch file + + -- Sandro Knauß Fri, 27 Sep 2013 14:19:13 +0200 + +qtkeychain (0.1.0-1) unstable; urgency=low * Initial release (Closes: #699687) - -- Sandro Knauß Sun, 06 Jan 2013 13:10:17 +0100 + -- Sandro Knauß Mon, 13 May 2013 01:39:05 +0200 diff -Nru qtkeychain-0.1.0/debian/control qtkeychain-0.3.0/debian/control --- qtkeychain-0.1.0/debian/control 2013-03-06 17:26:06.000000000 +0000 +++ qtkeychain-0.3.0/debian/control 2014-03-23 18:47:02.000000000 +0000 @@ -1,34 +1,37 @@ Source: qtkeychain Priority: extra -Maintainer: Kubuntu Developers -XSBC-Original-Maintainer: ownCloud for Debian maintainers +Maintainer: ownCloud for Debian maintainers Uploaders: Sandro Knauß -Build-Depends: debhelper (>= 8.0.0), cmake, libqt4-dev (>= 4.7), pkg-kde-tools (>= 0.5), hardening-wrapper -Standards-Version: 3.9.3 +Build-Depends: cmake, + debhelper (>= 8.0.0), + hardening-wrapper, + libqt4-dev, + pkg-kde-tools +Standards-Version: 3.9.5 Section: libs Homepage: https://github.com/frankosterfeld/qtkeychain -Vcs-Git: git://git.debian.org/collab-maint/qtkeychain.git -Vcs-Browser: http://git.debian.org/?p=collab-maint/qtkeychain.git;a=summary +Vcs-Git: git://anonscm.debian.org/pkg-owncloud/qtkeychain.git +Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-owncloud/qtkeychain.git Package: libqtkeychain0 Architecture: any Multi-Arch: same -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: ${misc:Depends}, ${shlibs:Depends} Pre-Depends: ${misc:Pre-Depends} -Description: Developement files for qtkeychain - A Qt API to store passwords and other secret data securely - . - It uses KWallet (via D-Bus) if available. - Support for the GNOME Keyring via freedesktop.org's Secret Storage - D-Bus specification is planned but not yet implemented. +Recommends: gnome-keyring | kde-runtime +Description: Qt API to store passwords + It can use KWallet or GNOME Keyring, if one of them is available. + If none of them is available, qtkeychain will report an error or writes + with explicit request the password unencrypted at a file. Package: qtkeychain-dev Section: libdevel Architecture: any Multi-Arch: same Depends: libqtkeychain0 (= ${binary:Version}), ${misc:Depends} -Description: Qt API to store passwords and other secret data securely - It uses KWallet (via D-Bus) if available. - Support for the GNOME Keyring via freedesktop.org's Secret Storage - D-Bus specification is planned but not yet implemented. - +Description: Development files for qtkeychain + Qt API to store passwords + . + It can use KWallet or GNOME Keyring, if one of them is available. + If none of them is available, qtkeychain will report an error or writes + with explicit request the password unencrypted at a file. diff -Nru qtkeychain-0.1.0/debian/copyright qtkeychain-0.3.0/debian/copyright --- qtkeychain-0.1.0/debian/copyright 2013-03-06 17:22:24.000000000 +0000 +++ qtkeychain-0.3.0/debian/copyright 2014-03-23 18:47:02.000000000 +0000 @@ -3,8 +3,14 @@ Source: https://github.com/frankosterfeld/qtkeychain Files: * -Copyright: 2011 Frank Osterfeld -License: BSD-3-clause +Copyright: 2011-2014 Frank Osterfeld +License: BSD-2-clause + +Files: debian/* +Copyright: 2013 Sandro Knauß +License: BSD-2-clause + +License: BSD-2-clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -29,27 +35,30 @@ Files: cmake/Modules/GNUInstallDirs.cmake Copyright: 2011 Nikita Krupen'ko 2011 Kitware, Inc. -License: BSD - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. - -Files: debian/* -Copyright: 2013 Sandro Knauß -License: GPL-2+ - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +License: BSD-3-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: . - You should have received a copy of the GNU General Public License - along with this program. If not, see + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. . - On Debian systems, the complete text of the GNU General - Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". - + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + . + * The names of Kitware, Inc., the Insight Consortium, or the names of + any consortium members, or of any contributors, may not be used to + endorse or promote products derived from this software without + specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff -Nru qtkeychain-0.1.0/debian/libqtkeychain0.dirs qtkeychain-0.3.0/debian/libqtkeychain0.dirs --- qtkeychain-0.1.0/debian/libqtkeychain0.dirs 2013-03-06 17:22:24.000000000 +0000 +++ qtkeychain-0.3.0/debian/libqtkeychain0.dirs 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -usr/lib diff -Nru qtkeychain-0.1.0/debian/libqtkeychain0.install qtkeychain-0.3.0/debian/libqtkeychain0.install --- qtkeychain-0.1.0/debian/libqtkeychain0.install 2013-03-06 17:22:24.000000000 +0000 +++ qtkeychain-0.3.0/debian/libqtkeychain0.install 2014-05-30 06:03:42.000000000 +0000 @@ -1 +1 @@ -usr/lib/*/lib*.so.* +usr/lib/lib*.so.* diff -Nru qtkeychain-0.1.0/debian/patches/fix-store-password.patch qtkeychain-0.3.0/debian/patches/fix-store-password.patch --- qtkeychain-0.1.0/debian/patches/fix-store-password.patch 1970-01-01 00:00:00.000000000 +0000 +++ qtkeychain-0.3.0/debian/patches/fix-store-password.patch 2014-05-30 06:12:50.000000000 +0000 @@ -0,0 +1,304 @@ +From 70c4feda0969560ff6ff2eb8c05efb817a1402d1 Mon Sep 17 00:00:00 2001 +From: Frank Osterfeld +Date: Sun, 16 Mar 2014 10:44:21 +0100 +Subject: [PATCH 1/5] bump version + +--- + CMakeLists.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 94c5b0d..da3b633 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -3,7 +3,7 @@ project(qtkeychain) + + ### + +-set(QTKEYCHAIN_VERSION 0.3.0) ++set(QTKEYCHAIN_VERSION 0.3.90) + set(QTKEYCHAIN_SOVERSION 0) + + ### +-- +1.9.3 + + +From 97d50f65d9362c1fc0cc03b1b3d6aafe5d14241b Mon Sep 17 00:00:00 2001 +From: Daniel Molkentin +Date: Tue, 1 Apr 2014 10:11:25 +0200 +Subject: [PATCH 2/5] Detect GNOME keychain daemons presence using official API + +The previous approach was hacky and broke often, as +variables kept changing again and again. +--- + gnomekeyring.cpp | 15 +++++++++------ + gnomekeyring_p.h | 6 +++++- + keychain_unix.cpp | 2 +- + 3 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/gnomekeyring.cpp b/gnomekeyring.cpp +index 4191df9..9cef00f 100644 +--- a/gnomekeyring.cpp ++++ b/gnomekeyring.cpp +@@ -2,21 +2,23 @@ + + const char* GnomeKeyring::GNOME_KEYRING_DEFAULT = NULL; + +-bool GnomeKeyring::isSupported() ++bool GnomeKeyring::isAvailable() + { + const GnomeKeyring& keyring = instance(); + return keyring.isLoaded() && + keyring.NETWORK_PASSWORD && ++ keyring.is_available && + keyring.find_password && + keyring.store_password && +- keyring.delete_password; ++ keyring.delete_password && ++ keyring.is_available(); + } + + GnomeKeyring::gpointer GnomeKeyring::store_network_password( const gchar* keyring, const gchar* display_name, + const gchar* user, const gchar* server, const gchar* password, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ) + { +- if ( !isSupported() ) ++ if ( !isAvailable() ) + return 0; + return instance().store_password( instance().NETWORK_PASSWORD, + keyring, display_name, password, callback, data, destroy_data, +@@ -26,7 +28,7 @@ GnomeKeyring::gpointer GnomeKeyring::store_network_password( const gchar* keyrin + GnomeKeyring::gpointer GnomeKeyring::find_network_password( const gchar* user, const gchar* server, + OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data ) + { +- if ( !isSupported() ) ++ if ( !isAvailable() ) + return 0; + return instance().find_password( instance().NETWORK_PASSWORD, + callback, data, destroy_data, +@@ -39,7 +41,7 @@ GnomeKeyring::gpointer GnomeKeyring::delete_network_password( const gchar* user, + gpointer data, + GDestroyNotify destroy_data ) + { +- if ( !isSupported() ) ++ if ( !isAvailable() ) + return 0; + return instance().delete_password( instance().NETWORK_PASSWORD, + callback, data, destroy_data, +@@ -57,7 +59,8 @@ GnomeKeyring::GnomeKeyring() + }; + + NETWORK_PASSWORD = &schema; +- find_password = reinterpret_cast( resolve( "gnome_keyring_find_password" ) ); ++ is_available = reinterpret_cast( resolve( "gnome_keyring_is_available" ) ); ++ find_password = reinterpret_cast( resolve( "gnome_keyring_find_password" ) ); + store_password = reinterpret_cast( resolve( "gnome_keyring_store_password" ) ); + delete_password = reinterpret_cast( resolve( "gnome_keyring_delete_password" ) ); + } +diff --git a/gnomekeyring_p.h b/gnomekeyring_p.h +index abe049e..6d150ba 100644 +--- a/gnomekeyring_p.h ++++ b/gnomekeyring_p.h +@@ -34,6 +34,7 @@ class GnomeKeyring : private QLibrary { + + typedef char gchar; + typedef void* gpointer; ++ typedef bool gboolean; + typedef struct { + ItemType item_type; + struct { +@@ -48,7 +49,7 @@ class GnomeKeyring : private QLibrary { + + static const char* GNOME_KEYRING_DEFAULT; + +- static bool isSupported(); ++ static bool isAvailable(); + + static gpointer store_network_password( const gchar* keyring, const gchar* display_name, + const gchar* user, const gchar* server, const gchar* password, +@@ -65,6 +66,7 @@ class GnomeKeyring : private QLibrary { + static GnomeKeyring& instance(); + + const PasswordSchema* NETWORK_PASSWORD; ++ typedef gboolean ( is_available_fn )( void ); + typedef gpointer ( store_password_fn )( const PasswordSchema* schema, const gchar* keyring, + const gchar* display_name, const gchar* password, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data, +@@ -75,6 +77,8 @@ class GnomeKeyring : private QLibrary { + typedef gpointer ( delete_password_fn )( const PasswordSchema* schema, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data, + ... ); ++ ++ is_available_fn* is_available; + find_password_fn* find_password; + store_password_fn* store_password; + delete_password_fn* delete_password; +diff --git a/keychain_unix.cpp b/keychain_unix.cpp +index 6bd1f25..87f3656 100644 +--- a/keychain_unix.cpp ++++ b/keychain_unix.cpp +@@ -32,7 +32,7 @@ enum KeyringBackend { + + static KeyringBackend detectKeyringBackend() + { +- if ( !( qgetenv( "GNOME_KEYRING_CONTROL" ).isNull() && qgetenv("GNOME_KEYRING_SOCKET").isNull() ) && GnomeKeyring::isSupported() ) ++ if ( GnomeKeyring::isAvailable() ) + return Backend_GnomeKeyring; + else + return Backend_Kwallet; +-- +1.9.3 + + +From affe9dcaed3a705d7c93ebda0724ca1cf6625438 Mon Sep 17 00:00:00 2001 +From: Daniel Molkentin +Date: Fri, 4 Apr 2014 15:00:07 +0200 +Subject: [PATCH 3/5] Add desktop environment detection + +My last patch causes Gnome Keyring to be launched even though the +desktop environment is KDE. This patch detects the running desktop +environments and tries to pick the matching storage backend. +--- + keychain_unix.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 67 insertions(+), 3 deletions(-) + +diff --git a/keychain_unix.cpp b/keychain_unix.cpp +index 87f3656..527a676 100644 +--- a/keychain_unix.cpp ++++ b/keychain_unix.cpp +@@ -30,12 +30,76 @@ enum KeyringBackend { + Backend_Kwallet + }; + ++enum DesktopEnvironment { ++ DesktopEnv_Gnome, ++ DesktopEnv_Kde4, ++ DesktopEnv_Unity, ++ DesktopEnv_Xfce, ++ DesktopEnv_Other ++}; ++ ++// the following detection algorithm is derived from chromium, ++// licensed under BSD, see base/nix/xdg_util.cc ++ ++static const char kKDE4SessionEnvVar[] = "KDE_SESSION_VERSION"; ++ ++static DesktopEnvironment detectDesktopEnvironment() { ++ QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP"); ++ if ( xdgCurrentDesktop == "GNOME" ) { ++ return DesktopEnv_Gnome; ++ } else if ( xdgCurrentDesktop == "Unity" ) { ++ return DesktopEnv_Unity; ++ } else if ( xdgCurrentDesktop == "KDE" ) { ++ return DesktopEnv_Kde4; ++ } ++ ++ QByteArray desktopSession = qgetenv("DESKTOP_SESSION"); ++ if ( desktopSession == "gnome" ) { ++ return DesktopEnv_Gnome; ++ } else if ( desktopSession == "kde" ) { ++ if ( qgetenv(kKDE4SessionEnvVar).isEmpty() ) { ++ // most likely KDE3 ++ return DesktopEnv_Other; ++ } else { ++ return DesktopEnv_Kde4; ++ } ++ } else if ( desktopSession == "kde4" ) { ++ return DesktopEnv_Kde4; ++ } else if ( desktopSession.contains("xfce") || desktopSession == "xubuntu" ) { ++ return DesktopEnv_Xfce; ++ } ++ ++ if ( !qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty() ) { ++ return DesktopEnv_Gnome; ++ } else if ( !qgetenv("KDE_FULL_SESSION").isEmpty() ) { ++ if ( qgetenv(kKDE4SessionEnvVar).isEmpty() ) { ++ // most likely KDE3 ++ return DesktopEnv_Other; ++ } else { ++ return DesktopEnv_Kde4; ++ } ++ } ++} ++ + static KeyringBackend detectKeyringBackend() + { +- if ( GnomeKeyring::isAvailable() ) +- return Backend_GnomeKeyring; +- else ++ switch (detectDesktopEnvironment()) { ++ case DesktopEnv_Kde4: + return Backend_Kwallet; ++ break; ++ // fall through ++ case DesktopEnv_Gnome: ++ case DesktopEnv_Unity: ++ case DesktopEnv_Xfce: ++ case DesktopEnv_Other: ++ default: ++ if ( GnomeKeyring::isAvailable() ) { ++ return Backend_GnomeKeyring; ++ } else { ++ return Backend_Kwallet; ++ } ++ } ++ + } + + static KeyringBackend getKeyringBackend() +-- +1.9.3 + + +From 3a6b0814f7f0ca36b57ac5d0096854e991ab9724 Mon Sep 17 00:00:00 2001 +From: "Uwe L. Korn" +Date: Mon, 7 Apr 2014 20:35:17 +0100 +Subject: [PATCH 4/5] Default to DesktopEnv_Other. + +--- + keychain_unix.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/keychain_unix.cpp b/keychain_unix.cpp +index 527a676..ec9d26c 100644 +--- a/keychain_unix.cpp ++++ b/keychain_unix.cpp +@@ -79,6 +79,8 @@ static DesktopEnvironment detectDesktopEnvironment() { + return DesktopEnv_Kde4; + } + } ++ ++ return DesktopEnv_Other; + } + + static KeyringBackend detectKeyringBackend() +-- +1.9.3 + + +From 0353028de18937fedaab691b88177dbfbbde4963 Mon Sep 17 00:00:00 2001 +From: "Uwe L. Korn" +Date: Mon, 7 Apr 2014 20:43:22 +0100 +Subject: [PATCH 5/5] Show all warnings + +--- + CMakeLists.txt | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index da3b633..000eab4 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -82,6 +82,8 @@ set(qtkeychain_SOURCES + keychain.cpp + ) + ++ADD_DEFINITIONS( -Wall ) ++ + if(WIN32) + list(APPEND qtkeychain_SOURCES keychain_win.cpp) + list(APPEND qtkeychain_LIBRARIES crypt32) +-- +1.9.3 + diff -Nru qtkeychain-0.1.0/debian/patches/series qtkeychain-0.3.0/debian/patches/series --- qtkeychain-0.1.0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ qtkeychain-0.3.0/debian/patches/series 2014-05-30 06:13:10.000000000 +0000 @@ -0,0 +1,2 @@ +use_system_GNUInstallDirs.cmake +fix-store-password.patch diff -Nru qtkeychain-0.1.0/debian/patches/use_system_GNUInstallDirs.cmake qtkeychain-0.3.0/debian/patches/use_system_GNUInstallDirs.cmake --- qtkeychain-0.1.0/debian/patches/use_system_GNUInstallDirs.cmake 1970-01-01 00:00:00.000000000 +0000 +++ qtkeychain-0.3.0/debian/patches/use_system_GNUInstallDirs.cmake 2014-03-20 18:54:04.000000000 +0000 @@ -0,0 +1,202 @@ +Description: FTBFS on !linux: libraries left in /usr/lib + Remove cmake/Modules/GNUInstallDirs.cmake to use the shipped version from debian. +Author: Sandro Knauß +Origin: debian +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=710340 +Forwarded: https://github.com/frankosterfeld/qtkeychain/issues/20 +Last-Update: 2013-09-27 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: qtkeychain/cmake/Modules/GNUInstallDirs.cmake +=================================================================== +--- qtkeychain.orig/cmake/Modules/GNUInstallDirs.cmake 2013-09-27 14:21:48.499137669 +0200 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,188 +0,0 @@ +-# - Define GNU standard installation directories +-# Provides install directory variables as defined for GNU software: +-# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html +-# Inclusion of this module defines the following variables: +-# CMAKE_INSTALL_ - destination for files of a given type +-# CMAKE_INSTALL_FULL_ - corresponding absolute path +-# where is one of: +-# BINDIR - user executables (bin) +-# SBINDIR - system admin executables (sbin) +-# LIBEXECDIR - program executables (libexec) +-# SYSCONFDIR - read-only single-machine data (etc) +-# SHAREDSTATEDIR - modifiable architecture-independent data (com) +-# LOCALSTATEDIR - modifiable single-machine data (var) +-# LIBDIR - object code libraries (lib or lib64 or lib/ on Debian) +-# INCLUDEDIR - C header files (include) +-# OLDINCLUDEDIR - C header files for non-gcc (/usr/include) +-# DATAROOTDIR - read-only architecture-independent data root (share) +-# DATADIR - read-only architecture-independent data (DATAROOTDIR) +-# INFODIR - info documentation (DATAROOTDIR/info) +-# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale) +-# MANDIR - man documentation (DATAROOTDIR/man) +-# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME) +-# Each CMAKE_INSTALL_ value may be passed to the DESTINATION options of +-# install() commands for the corresponding file type. If the includer does +-# not define a value the above-shown default will be used and the value will +-# appear in the cache for editing by the user. +-# Each CMAKE_INSTALL_FULL_ value contains an absolute path constructed +-# from the corresponding destination by prepending (if necessary) the value +-# of CMAKE_INSTALL_PREFIX. +- +-#============================================================================= +-# Copyright 2011 Nikita Krupen'ko +-# Copyright 2011 Kitware, Inc. +-# +-# Distributed under the OSI-approved BSD License (the "License"); +-# see accompanying file Copyright.txt for details. +-# +-# This software is distributed WITHOUT ANY WARRANTY; without even the +-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +-# See the License for more information. +-#============================================================================= +-# (To distribute this file outside of CMake, substitute the full +-# License text for the above reference.) +- +-# Installation directories +-# +-if(NOT DEFINED CMAKE_INSTALL_BINDIR) +- set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)") +-endif() +- +-if(NOT DEFINED CMAKE_INSTALL_SBINDIR) +- set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)") +-endif() +- +-if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR) +- set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)") +-endif() +- +-if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR) +- set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)") +-endif() +- +-if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR) +- set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)") +-endif() +- +-if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR) +- set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)") +-endif() +- +-if(NOT DEFINED CMAKE_INSTALL_LIBDIR) +- set(_LIBDIR_DEFAULT "lib") +- # Override this default 'lib' with 'lib64' iff: +- # - we are on Linux system but NOT cross-compiling +- # - we are NOT on debian +- # - we are on a 64 bits system +- # reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf +- # For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if +- # CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu" +- # See http://wiki.debian.org/Multiarch +- if(CMAKE_SYSTEM_NAME MATCHES "Linux" +- AND NOT CMAKE_CROSSCOMPILING) +- if (EXISTS "/etc/debian_version") # is this a debian system ? +- if(CMAKE_LIBRARY_ARCHITECTURE) +- set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}") +- endif() +- else() # not debian, rely on CMAKE_SIZEOF_VOID_P: +- if(NOT DEFINED CMAKE_SIZEOF_VOID_P) +- message(AUTHOR_WARNING +- "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. " +- "Please enable at least one language before including GNUInstallDirs.") +- else() +- if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") +- set(_LIBDIR_DEFAULT "lib64") +- endif() +- endif() +- endif() +- endif() +- set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})") +-endif() +- +-if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR) +- set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)") +-endif() +- +-if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR) +- set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)") +-endif() +- +-if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR) +- set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)") +-endif() +- +-#----------------------------------------------------------------------------- +-# Values whose defaults are relative to DATAROOTDIR. Store empty values in +-# the cache and store the defaults in local variables if the cache values are +-# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes. +- +-if(NOT CMAKE_INSTALL_DATADIR) +- set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)") +- set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}") +-endif() +- +-if(NOT CMAKE_INSTALL_INFODIR) +- set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)") +- set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info") +-endif() +- +-if(NOT CMAKE_INSTALL_LOCALEDIR) +- set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)") +- set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale") +-endif() +- +-if(NOT CMAKE_INSTALL_MANDIR) +- set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)") +- set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man") +-endif() +- +-if(NOT CMAKE_INSTALL_DOCDIR) +- set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)") +- set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}") +-endif() +- +-#----------------------------------------------------------------------------- +- +-mark_as_advanced( +- CMAKE_INSTALL_BINDIR +- CMAKE_INSTALL_SBINDIR +- CMAKE_INSTALL_LIBEXECDIR +- CMAKE_INSTALL_SYSCONFDIR +- CMAKE_INSTALL_SHAREDSTATEDIR +- CMAKE_INSTALL_LOCALSTATEDIR +- CMAKE_INSTALL_LIBDIR +- CMAKE_INSTALL_INCLUDEDIR +- CMAKE_INSTALL_OLDINCLUDEDIR +- CMAKE_INSTALL_DATAROOTDIR +- CMAKE_INSTALL_DATADIR +- CMAKE_INSTALL_INFODIR +- CMAKE_INSTALL_LOCALEDIR +- CMAKE_INSTALL_MANDIR +- CMAKE_INSTALL_DOCDIR +- ) +- +-# Result directories +-# +-foreach(dir +- BINDIR +- SBINDIR +- LIBEXECDIR +- SYSCONFDIR +- SHAREDSTATEDIR +- LOCALSTATEDIR +- LIBDIR +- INCLUDEDIR +- OLDINCLUDEDIR +- DATAROOTDIR +- DATADIR +- INFODIR +- LOCALEDIR +- MANDIR +- DOCDIR +- ) +- if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}}) +- set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}") +- else() +- set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}") +- endif() +-endforeach() diff -Nru qtkeychain-0.1.0/debian/qtkeychain-dev.dirs qtkeychain-0.3.0/debian/qtkeychain-dev.dirs --- qtkeychain-0.1.0/debian/qtkeychain-dev.dirs 2013-03-06 17:22:24.000000000 +0000 +++ qtkeychain-0.3.0/debian/qtkeychain-dev.dirs 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -usr/lib -usr/include diff -Nru qtkeychain-0.1.0/debian/qtkeychain-dev.install qtkeychain-0.3.0/debian/qtkeychain-dev.install --- qtkeychain-0.1.0/debian/qtkeychain-dev.install 2013-03-06 17:22:24.000000000 +0000 +++ qtkeychain-0.3.0/debian/qtkeychain-dev.install 2014-05-30 06:04:26.000000000 +0000 @@ -1,3 +1,3 @@ usr/include/* -usr/lib/*/lib*.so -usr/lib/*/cmake/QtKeychain/*.cmake +usr/lib/cmake/QtKeychain/*.cmake +usr/lib/lib*.so diff -Nru qtkeychain-0.1.0/debian/rules qtkeychain-0.3.0/debian/rules --- qtkeychain-0.1.0/debian/rules 2014-01-31 16:33:40.000000000 +0000 +++ qtkeychain-0.3.0/debian/rules 2014-03-20 18:54:04.000000000 +0000 @@ -3,14 +3,13 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 +export QT_SELECT := qt4 export DEB_BUILD_HARDENING=1 export DEB_CXXFLAGS_MAINT_APPEND = -fvisibility=hidden -fvisibility-inlines-hidden %: - #dh $@ --parallel --with pkgkde_symbolshelper - dh $@ --parallel - + dh $@ --parallel --with kde --with pkgkde_symbolshelper override_dh_install: dh_install --list-missing diff -Nru qtkeychain-0.1.0/debian/watch qtkeychain-0.3.0/debian/watch --- qtkeychain-0.1.0/debian/watch 2013-03-06 17:22:24.000000000 +0000 +++ qtkeychain-0.3.0/debian/watch 2014-03-20 18:54:04.000000000 +0000 @@ -3,4 +3,4 @@ # See uscan(1) for format version=3 -https://github.com/frankosterfeld/qtkeychain/tags /frankosterfeld/qtkeychain/archive/v(.*)\.tar\.gz +http://githubredir.debian.net/github/frankosterfeld/qtkeychain/ v(.*).tar.gz diff -Nru qtkeychain-0.1.0/gnomekeyring.cpp qtkeychain-0.3.0/gnomekeyring.cpp --- qtkeychain-0.1.0/gnomekeyring.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qtkeychain-0.3.0/gnomekeyring.cpp 2014-03-13 13:31:53.000000000 +0000 @@ -0,0 +1,68 @@ +#include "gnomekeyring_p.h" + +const char* GnomeKeyring::GNOME_KEYRING_DEFAULT = NULL; + +bool GnomeKeyring::isSupported() +{ + const GnomeKeyring& keyring = instance(); + return keyring.isLoaded() && + keyring.NETWORK_PASSWORD && + keyring.find_password && + keyring.store_password && + keyring.delete_password; +} + +GnomeKeyring::gpointer GnomeKeyring::store_network_password( const gchar* keyring, const gchar* display_name, + const gchar* user, const gchar* server, const gchar* password, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ) +{ + if ( !isSupported() ) + return 0; + return instance().store_password( instance().NETWORK_PASSWORD, + keyring, display_name, password, callback, data, destroy_data, + "user", user, "server", server, static_cast(0) ); +} + +GnomeKeyring::gpointer GnomeKeyring::find_network_password( const gchar* user, const gchar* server, + OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data ) +{ + if ( !isSupported() ) + return 0; + return instance().find_password( instance().NETWORK_PASSWORD, + callback, data, destroy_data, + "user", user, "server", server, static_cast(0) ); +} + +GnomeKeyring::gpointer GnomeKeyring::delete_network_password( const gchar* user, + const gchar* server, + OperationDoneCallback callback, + gpointer data, + GDestroyNotify destroy_data ) +{ + if ( !isSupported() ) + return 0; + return instance().delete_password( instance().NETWORK_PASSWORD, + callback, data, destroy_data, + "user", user, "server", server, static_cast(0) ); +} + +GnomeKeyring::GnomeKeyring() + : QLibrary("gnome-keyring", 0) +{ + static const PasswordSchema schema = { + ITEM_NETWORK_PASSWORD, + {{ "user", ATTRIBUTE_TYPE_STRING }, + { "server", ATTRIBUTE_TYPE_STRING }, + { 0, static_cast( 0 ) }} + }; + + NETWORK_PASSWORD = &schema; + find_password = reinterpret_cast( resolve( "gnome_keyring_find_password" ) ); + store_password = reinterpret_cast( resolve( "gnome_keyring_store_password" ) ); + delete_password = reinterpret_cast( resolve( "gnome_keyring_delete_password" ) ); +} + +GnomeKeyring& GnomeKeyring::instance() { + static GnomeKeyring keyring; + return keyring; +} diff -Nru qtkeychain-0.1.0/gnomekeyring_p.h qtkeychain-0.3.0/gnomekeyring_p.h --- qtkeychain-0.1.0/gnomekeyring_p.h 1970-01-01 00:00:00.000000000 +0000 +++ qtkeychain-0.3.0/gnomekeyring_p.h 2014-03-13 13:31:53.000000000 +0000 @@ -0,0 +1,84 @@ +#ifndef QTKEYCHAIN_GNOME_P_H +#define QTKEYCHAIN_GNOME_P_H + +#include + +class GnomeKeyring : private QLibrary { +public: + enum Result { + RESULT_OK, + RESULT_DENIED, + RESULT_NO_KEYRING_DAEMON, + RESULT_ALREADY_UNLOCKED, + RESULT_NO_SUCH_KEYRING, + RESULT_BAD_ARGUMENTS, + RESULT_IO_ERROR, + RESULT_CANCELLED, + RESULT_KEYRING_ALREADY_EXISTS, + RESULT_NO_MATCH + }; + + enum ItemType { + ITEM_GENERIC_SECRET = 0, + ITEM_NETWORK_PASSWORD, + ITEM_NOTE, + ITEM_CHAINED_KEYRING_PASSWORD, + ITEM_ENCRYPTION_KEY_PASSWORD, + ITEM_PK_STORAGE = 0x100 + }; + + enum AttributeType { + ATTRIBUTE_TYPE_STRING, + ATTRIBUTE_TYPE_UINT32 + }; + + typedef char gchar; + typedef void* gpointer; + typedef struct { + ItemType item_type; + struct { + const gchar* name; + AttributeType type; + } attributes[32]; + } PasswordSchema; + + typedef void ( *OperationGetStringCallback )( Result result, const char* string, gpointer data ); + typedef void ( *OperationDoneCallback )( Result result, gpointer data ); + typedef void ( *GDestroyNotify )( gpointer data ); + + static const char* GNOME_KEYRING_DEFAULT; + + static bool isSupported(); + + static gpointer store_network_password( const gchar* keyring, const gchar* display_name, + const gchar* user, const gchar* server, const gchar* password, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ); + + static gpointer find_network_password( const gchar* user, const gchar* server, + OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data ); + + static gpointer delete_network_password( const gchar* user, const gchar* server, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ); +private: + GnomeKeyring(); + + static GnomeKeyring& instance(); + + const PasswordSchema* NETWORK_PASSWORD; + typedef gpointer ( store_password_fn )( const PasswordSchema* schema, const gchar* keyring, + const gchar* display_name, const gchar* password, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data, + ... ); + typedef gpointer ( find_password_fn )( const PasswordSchema* schema, + OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data, + ... ); + typedef gpointer ( delete_password_fn )( const PasswordSchema* schema, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data, + ... ); + find_password_fn* find_password; + store_password_fn* store_password; + delete_password_fn* delete_password; +}; + + +#endif diff -Nru qtkeychain-0.1.0/keychain.cpp qtkeychain-0.3.0/keychain.cpp --- qtkeychain-0.1.0/keychain.cpp 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/keychain.cpp 2014-03-13 13:31:53.000000000 +0000 @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (C) 2011 Frank Osterfeld * + * Copyright (C) 2011-2014 Frank Osterfeld * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * @@ -154,8 +154,10 @@ //In all current implementations, this deletes the entry so this is sufficient WritePasswordJob* job = new WritePasswordJob( service(), this ); connect( job, SIGNAL(finished(QKeychain::Job*)), d, SLOT(jobFinished(QKeychain::Job*)) ); + job->setInsecureFallback(true); + job->setSettings(settings()); job->setKey( d->key ); - job->start(); + job->doStart(); } QString DeletePasswordJob::key() const { diff -Nru qtkeychain-0.1.0/keychain_dbus.cpp qtkeychain-0.3.0/keychain_dbus.cpp --- qtkeychain-0.1.0/keychain_dbus.cpp 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/keychain_dbus.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2011 Frank Osterfeld * - * * - * This program is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * - * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * - * details, check the accompanying file 'COPYING'. * - *****************************************************************************/ -#include "keychain_p.h" - -#include - -#include - -using namespace QKeychain; - -void ReadPasswordJobPrivate::scheduledStart() { - iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this ); - const QDBusPendingReply reply = iface->open( QLatin1String("kdewallet"), 0, q->service() ); - QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this ); - connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) ); -} - -void ReadPasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) { - watcher->deleteLater(); - const QDBusPendingReply reply = *watcher; - - std::auto_ptr local( !q->settings() ? new QSettings( q->service() ) : 0 ); - QSettings* actual = q->settings() ? q->settings() : local.get(); - WritePasswordJobPrivate::Mode mode; - - const QString typeKey = QString( "%1/type" ).arg( key ); - const QString dataKey = QString( "%1/data" ).arg( key ); - if ( reply.isError() ) { - const QDBusError err = reply.error(); - - if ( q->insecureFallback() && actual->contains( dataKey ) ) { - - mode = (WritePasswordJobPrivate::Mode)actual->value( typeKey ).toInt(); - data = actual->value( dataKey ).toByteArray(); - - q->emitFinished(); - - return; - } else { - if ( err.type() == QDBusError::ServiceUnknown ) //KWalletd not running - q->emitFinishedWithError( NoBackendAvailable, tr("No keychain service available") ); - else - q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); - - return; - } - } - - if ( actual->contains( dataKey ) ) { - // We previously stored data in the insecure QSettings, but now have KWallet available. - // Do the migration - - data = actual->value( dataKey ).toByteArray(); - mode = (WritePasswordJobPrivate::Mode)actual->value( typeKey ).toInt(); - actual->remove( key ); - - q->emitFinished(); - - - WritePasswordJob* j = new WritePasswordJob( q->service(), 0 ); - j->setSettings( q->settings() ); - j->setKey( key ); - j->setAutoDelete( true ); - if ( mode == WritePasswordJobPrivate::Binary ) - j->setBinaryData( data ); - else if ( mode == WritePasswordJobPrivate::Text ) - j->setTextData( QString::fromUtf8( data ) ); - else - Q_ASSERT( false ); - - j->start(); - - return; - } - - walletHandle = reply.value(); - - if ( walletHandle < 0 ) { - q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") ); - return; - } - - const QDBusPendingReply nextReply = iface->entryType( walletHandle, q->service(), key, q->service() ); - QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this ); - connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletEntryTypeFinished(QDBusPendingCallWatcher*)) ); -} - -void ReadPasswordJobPrivate::kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher ) { - watcher->deleteLater(); - if ( watcher->isError() ) { - const QDBusError err = watcher->error(); - q->emitFinishedWithError( OtherError, tr("Could not determine data type: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); - return; - } - - const QDBusPendingReply reply = *watcher; - - dataType = reply.value() == 1/*Password*/ ? Text : Binary; - - const QDBusPendingCall nextReply = dataType == Text - ? QDBusPendingCall( iface->readPassword( walletHandle, q->service(), key, q->service() ) ) - : QDBusPendingCall( iface->readEntry( walletHandle, q->service(), key, q->service() ) ); - QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this ); - connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletReadFinished(QDBusPendingCallWatcher*)) ); -} - -void ReadPasswordJobPrivate::kwalletReadFinished( QDBusPendingCallWatcher* watcher ) { - watcher->deleteLater(); - if ( watcher->isError() ) { - const QDBusError err = watcher->error(); - q->emitFinishedWithError( OtherError, tr("Could not read password: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); - return; - } - - if ( dataType == Binary ) { - QDBusPendingReply reply = *watcher; - data = reply.value(); - } else { - QDBusPendingReply reply = *watcher; - data = reply.value().toUtf8(); - } - q->emitFinished(); -} - -void WritePasswordJobPrivate::scheduledStart() { - iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this ); - const QDBusPendingReply reply = iface->open( QLatin1String("kdewallet"), 0, q->service() ); - QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this ); - connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) ); -} - -void WritePasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) { - watcher->deleteLater(); - QDBusPendingReply reply = *watcher; - - std::auto_ptr local( !q->settings() ? new QSettings( q->service() ) : 0 ); - QSettings* actual = q->settings() ? q->settings() : local.get(); - - if ( reply.isError() ) { - if ( q->insecureFallback() ) { - if ( mode == Delete ) { - actual->remove( key ); - actual->sync(); - - q->emitFinished(); - return; - } - - actual->setValue( QString( "%1/type" ).arg( key ), (int)mode ); - if ( mode == Text ) - actual->setValue( QString( "%1/data" ).arg( key ), textData.toUtf8() ); - else if ( mode == Binary ) - actual->setValue( QString( "%1/data" ).arg( key ), binaryData ); - actual->sync(); - - q->emitFinished(); - } else { - const QDBusError err = reply.error(); - q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); - } - return; - } - - if ( actual->contains( key ) ) - { - // If we had previously written to QSettings, but we now have a kwallet available, migrate and delete old insecure data - actual->remove( key ); - actual->sync(); - } - - const int handle = reply.value(); - - if ( handle < 0 ) { - q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") ); - return; - } - - QDBusPendingReply nextReply; - - if ( !textData.isEmpty() ) - nextReply = iface->writePassword( handle, q->service(), key, textData, q->service() ); - else if ( !binaryData.isEmpty() ) - nextReply = iface->writeEntry( handle, q->service(), key, binaryData, q->service() ); - else - nextReply = iface->removeEntry( handle, q->service(), key, q->service() ); - - QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this ); - connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletWriteFinished(QDBusPendingCallWatcher*)) ); -} - -void WritePasswordJobPrivate::kwalletWriteFinished( QDBusPendingCallWatcher* watcher ) { - watcher->deleteLater(); - QDBusPendingReply reply = *watcher; - if ( reply.isError() ) { - const QDBusError err = reply.error(); - q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); - return; - } - - q->emitFinished(); -} diff -Nru qtkeychain-0.1.0/keychain.h qtkeychain-0.3.0/keychain.h --- qtkeychain-0.1.0/keychain.h 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/keychain.h 2014-03-13 13:31:53.000000000 +0000 @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (C) 2011 Frank Osterfeld * + * Copyright (C) 2011-2014 Frank Osterfeld * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * @@ -117,6 +117,7 @@ private: friend class QKeychain::JobExecutor; friend class QKeychain::WritePasswordJobPrivate; + friend class DeletePasswordJob; WritePasswordJobPrivate* const d; }; diff -Nru qtkeychain-0.1.0/keychain_mac.cpp qtkeychain-0.3.0/keychain_mac.cpp --- qtkeychain-0.1.0/keychain_mac.cpp 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/keychain_mac.cpp 2014-03-13 13:31:53.000000000 +0000 @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (C) 2011 Frank Osterfeld * + * Copyright (C) 2011-2014 Frank Osterfeld * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * @@ -28,8 +28,10 @@ const Releaser str( SecCopyErrorMessageString( os, 0 ) ); const char * const buf = CFStringGetCStringPtr( str.value, kCFStringEncodingUTF8 ); if ( !buf ) - return QString(); - return QString::fromUtf8( buf, strlen( buf ) ); + return QObject::tr( "%1 (OSStatus %2)" ) + .arg( "OSX Keychain Error" ).arg( os ); + return QObject::tr( "%1 (OSStatus %2)" ) + .arg( QString::fromUtf8( buf, strlen( buf ) ) ).arg( os ); } static OSStatus readPw( QByteArray* pw, diff -Nru qtkeychain-0.1.0/keychain_p.h qtkeychain-0.3.0/keychain_p.h --- qtkeychain-0.1.0/keychain_p.h 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/keychain_p.h 2014-03-13 13:31:53.000000000 +0000 @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (C) 2011 Frank Osterfeld * + * Copyright (C) 2011-2014 Frank Osterfeld * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * @@ -67,14 +67,18 @@ #if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) org::kde::KWallet* iface; + static void gnomeKeyring_cb( int result, const char* string, ReadPasswordJobPrivate* data ); friend class QKeychain::JobExecutor; + void fallbackOnError(const QDBusError& err); private Q_SLOTS: + void kwalletWalletFound( QDBusPendingCallWatcher* watcher ); void kwalletOpenFinished( QDBusPendingCallWatcher* watcher ); void kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher ); void kwalletReadFinished( QDBusPendingCallWatcher* watcher ); #else //moc's too dumb to respect above macros, so just define empty slot implementations private Q_SLOTS: + void kwalletWalletFound( QDBusPendingCallWatcher* ) {} void kwalletOpenFinished( QDBusPendingCallWatcher* ) {} void kwalletEntryTypeFinished( QDBusPendingCallWatcher* ) {} void kwalletReadFinished( QDBusPendingCallWatcher* ) {} @@ -93,6 +97,10 @@ Text, Binary }; + + static QString modeToString(Mode m); + static Mode stringToMode(const QString& s); + WritePasswordJob* const q; Mode mode; QString key; @@ -101,8 +109,9 @@ #if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) org::kde::KWallet* iface; + static void gnomeKeyring_cb( int result, WritePasswordJobPrivate* self ); friend class QKeychain::JobExecutor; - + void fallbackOnError(const QDBusError& err); private Q_SLOTS: void kwalletOpenFinished( QDBusPendingCallWatcher* watcher ); diff -Nru qtkeychain-0.1.0/keychain_unix.cpp qtkeychain-0.3.0/keychain_unix.cpp --- qtkeychain-0.1.0/keychain_unix.cpp 1970-01-01 00:00:00.000000000 +0000 +++ qtkeychain-0.3.0/keychain_unix.cpp 2014-03-13 13:31:53.000000000 +0000 @@ -0,0 +1,415 @@ +/****************************************************************************** + * Copyright (C) 2011-2014 Frank Osterfeld * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * + * details, check the accompanying file 'COPYING'. * + *****************************************************************************/ +#include "keychain_p.h" +#include "gnomekeyring_p.h" + +#include + +#include + +using namespace QKeychain; + +static QString typeKey( const QString& key ) +{ + return QString::fromLatin1( "%1/type" ).arg( key ); +} + +static QString dataKey( const QString& key ) +{ + return QString::fromLatin1( "%1/data" ).arg( key ); +} + +enum KeyringBackend { + Backend_GnomeKeyring, + Backend_Kwallet +}; + +static KeyringBackend detectKeyringBackend() +{ + if ( !( qgetenv( "GNOME_KEYRING_CONTROL" ).isNull() && qgetenv("GNOME_KEYRING_SOCKET").isNull() ) && GnomeKeyring::isSupported() ) + return Backend_GnomeKeyring; + else + return Backend_Kwallet; +} + +static KeyringBackend getKeyringBackend() +{ + static KeyringBackend backend = detectKeyringBackend(); + return backend; +} + +void ReadPasswordJobPrivate::scheduledStart() { + switch ( getKeyringBackend() ) { + case Backend_GnomeKeyring: + if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(), q->service().toUtf8().constData(), + reinterpret_cast( &ReadPasswordJobPrivate::gnomeKeyring_cb ), + this, 0 ) ) + q->emitFinishedWithError( OtherError, tr("Unknown error") ); + break; + + case Backend_Kwallet: + if ( QDBusConnection::sessionBus().isConnected() ) + { + iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this ); + const QDBusPendingReply reply = iface->networkWallet(); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this ); + connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletWalletFound(QDBusPendingCallWatcher*)) ); + } + else + { + // D-Bus is not reachable so none can tell us something about KWalletd + QDBusError err( QDBusError::NoServer, tr("D-Bus is not running") ); + fallbackOnError( err ); + } + break; + } +} + +void ReadPasswordJobPrivate::kwalletWalletFound(QDBusPendingCallWatcher *watcher) +{ + watcher->deleteLater(); + const QDBusPendingReply reply = *watcher; + const QDBusPendingReply pendingReply = iface->open( reply.value(), 0, q->service() ); + QDBusPendingCallWatcher* pendingWatcher = new QDBusPendingCallWatcher( pendingReply, this ); + connect( pendingWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) ); +} + +static QPair mapGnomeKeyringError( int result ) +{ + Q_ASSERT( result != GnomeKeyring::RESULT_OK ); + + switch ( result ) { + case GnomeKeyring::RESULT_DENIED: + return qMakePair( AccessDenied, QObject::tr("Access to keychain denied") ); + case GnomeKeyring::RESULT_NO_KEYRING_DAEMON: + return qMakePair( NoBackendAvailable, QObject::tr("No keyring daemon") ); + case GnomeKeyring::RESULT_ALREADY_UNLOCKED: + return qMakePair( OtherError, QObject::tr("Already unlocked") ); + case GnomeKeyring::RESULT_NO_SUCH_KEYRING: + return qMakePair( OtherError, QObject::tr("No such keyring") ); + case GnomeKeyring::RESULT_BAD_ARGUMENTS: + return qMakePair( OtherError, QObject::tr("Bad arguments") ); + case GnomeKeyring::RESULT_IO_ERROR: + return qMakePair( OtherError, QObject::tr("I/O error") ); + case GnomeKeyring::RESULT_CANCELLED: + return qMakePair( OtherError, QObject::tr("Cancelled") ); + case GnomeKeyring::RESULT_KEYRING_ALREADY_EXISTS: + return qMakePair( OtherError, QObject::tr("Keyring already exists") ); + case GnomeKeyring::RESULT_NO_MATCH: + return qMakePair( EntryNotFound, QObject::tr("No match") ); + default: + break; + } + + return qMakePair( OtherError, QObject::tr("Unknown error") ); +} + +void ReadPasswordJobPrivate::gnomeKeyring_cb( int result, const char* string, ReadPasswordJobPrivate* self ) +{ + if ( result == GnomeKeyring::RESULT_OK ) { + if ( self->dataType == ReadPasswordJobPrivate::Text ) + self->data = string; + else + self->data = QByteArray::fromBase64( string ); + self->q->emitFinished(); + } else { + const QPair errorResult = mapGnomeKeyringError( result ); + self->q->emitFinishedWithError( errorResult.first, errorResult.second ); + } +} + +void ReadPasswordJobPrivate::fallbackOnError(const QDBusError& err ) +{ + QScopedPointer local( !q->settings() ? new QSettings( q->service() ) : 0 ); + QSettings* actual = q->settings() ? q->settings() : local.data(); + + if ( q->insecureFallback() && actual->contains( dataKey( key ) ) ) { + + const WritePasswordJobPrivate::Mode mode = WritePasswordJobPrivate::stringToMode( actual->value( typeKey( key ) ).toString() ); + if (mode == WritePasswordJobPrivate::Binary) + dataType = Binary; + else + dataType = Text; + data = actual->value( dataKey( key ) ).toByteArray(); + + q->emitFinished(); + } else { + if ( err.type() == QDBusError::ServiceUnknown ) //KWalletd not running + q->emitFinishedWithError( NoBackendAvailable, tr("No keychain service available") ); + else + q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); + } +} + +void ReadPasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) { + watcher->deleteLater(); + const QDBusPendingReply reply = *watcher; + + QScopedPointer local( !q->settings() ? new QSettings( q->service() ) : 0 ); + QSettings* actual = q->settings() ? q->settings() : local.data(); + + if ( reply.isError() ) { + fallbackOnError( reply.error() ); + return; + } + + if ( actual->contains( dataKey( key ) ) ) { + // We previously stored data in the insecure QSettings, but now have KWallet available. + // Do the migration + + data = actual->value( dataKey( key ) ).toByteArray(); + const WritePasswordJobPrivate::Mode mode = WritePasswordJobPrivate::stringToMode( actual->value( typeKey( key ) ).toString() ); + actual->remove( key ); + + q->emitFinished(); + + + WritePasswordJob* j = new WritePasswordJob( q->service(), 0 ); + j->setSettings( q->settings() ); + j->setKey( key ); + j->setAutoDelete( true ); + if ( mode == WritePasswordJobPrivate::Binary ) + j->setBinaryData( data ); + else if ( mode == WritePasswordJobPrivate::Text ) + j->setTextData( QString::fromUtf8( data ) ); + else + Q_ASSERT( false ); + + j->start(); + + return; + } + + walletHandle = reply.value(); + + if ( walletHandle < 0 ) { + q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") ); + return; + } + + const QDBusPendingReply nextReply = iface->entryType( walletHandle, q->service(), key, q->service() ); + QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this ); + connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletEntryTypeFinished(QDBusPendingCallWatcher*)) ); +} + +//Must be in sync with KWallet::EntryType (kwallet.h) +enum KWalletEntryType { + Unknown=0, + Password, + Stream, + Map +}; + +void ReadPasswordJobPrivate::kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher ) { + watcher->deleteLater(); + if ( watcher->isError() ) { + const QDBusError err = watcher->error(); + q->emitFinishedWithError( OtherError, tr("Could not determine data type: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); + return; + } + + const QDBusPendingReply reply = *watcher; + const int value = reply.value(); + + switch ( value ) { + case Unknown: + q->emitFinishedWithError( EntryNotFound, tr("Entry not found") ); + return; + case Password: + dataType = Text; + break; + case Stream: + dataType = Binary; + break; + case Map: + q->emitFinishedWithError( EntryNotFound, tr("Unsupported entry type 'Map'") ); + return; + default: + q->emitFinishedWithError( OtherError, tr("Unknown kwallet entry type '%1'").arg( value ) ); + return; + } + + const QDBusPendingCall nextReply = dataType == Text + ? QDBusPendingCall( iface->readPassword( walletHandle, q->service(), key, q->service() ) ) + : QDBusPendingCall( iface->readEntry( walletHandle, q->service(), key, q->service() ) ); + QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this ); + connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletReadFinished(QDBusPendingCallWatcher*)) ); +} + +void ReadPasswordJobPrivate::kwalletReadFinished( QDBusPendingCallWatcher* watcher ) { + watcher->deleteLater(); + if ( watcher->isError() ) { + const QDBusError err = watcher->error(); + q->emitFinishedWithError( OtherError, tr("Could not read password: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); + return; + } + + if ( dataType == Binary ) { + QDBusPendingReply reply = *watcher; + data = reply.value(); + } else { + QDBusPendingReply reply = *watcher; + data = reply.value().toUtf8(); + } + q->emitFinished(); +} + +void WritePasswordJobPrivate::scheduledStart() { + switch ( getKeyringBackend() ) { + case Backend_GnomeKeyring: + if ( mode == WritePasswordJobPrivate::Delete ) { + if ( !GnomeKeyring::delete_network_password( key.toUtf8().constData(), q->service().toUtf8().constData(), + reinterpret_cast( &WritePasswordJobPrivate::gnomeKeyring_cb ), + this, 0 ) ) + q->emitFinishedWithError( OtherError, tr("Unknown error") ); + } else { + QByteArray password = mode == WritePasswordJobPrivate::Text ? textData.toUtf8() : binaryData.toBase64(); + QByteArray service = q->service().toUtf8(); + if ( !GnomeKeyring::store_network_password( GnomeKeyring::GNOME_KEYRING_DEFAULT, service.constData(), + key.toUtf8().constData(), service.constData(), password.constData(), + reinterpret_cast( &WritePasswordJobPrivate::gnomeKeyring_cb ), + this, 0 ) ) + q->emitFinishedWithError( OtherError, tr("Unknown error") ); + } + break; + + case Backend_Kwallet: + if ( QDBusConnection::sessionBus().isConnected() ) + { + iface = new org::kde::KWallet( QLatin1String("org.kde.kwalletd"), QLatin1String("/modules/kwalletd"), QDBusConnection::sessionBus(), this ); + const QDBusPendingReply reply = iface->open( QLatin1String("kdewallet"), 0, q->service() ); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, this ); + connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) ); + } + else + { + // D-Bus is not reachable so none can tell us something about KWalletd + QDBusError err( QDBusError::NoServer, tr("D-Bus is not running") ); + fallbackOnError( err ); + } + } +} + +QString WritePasswordJobPrivate::modeToString(Mode m) +{ + switch (m) { + case Delete: + return QLatin1String("Delete"); + case Text: + return QLatin1String("Text"); + case Binary: + return QLatin1String("Binary"); + } + + Q_ASSERT_X(false, Q_FUNC_INFO, "Unhandled Mode value"); + return QString(); +} + +WritePasswordJobPrivate::Mode WritePasswordJobPrivate::stringToMode(const QString& s) +{ + if (s == QLatin1String("Delete") || s == QLatin1String("0")) + return Delete; + if (s == QLatin1String("Text") || s == QLatin1String("1")) + return Text; + if (s == QLatin1String("Binary") || s == QLatin1String("2")) + return Binary; + + qCritical("Unexpected mode string '%s'", qPrintable(s)); + + return Text; +} + +void WritePasswordJobPrivate::fallbackOnError(const QDBusError &err) +{ + QScopedPointer local( !q->settings() ? new QSettings( q->service() ) : 0 ); + QSettings* actual = q->settings() ? q->settings() : local.data(); + + if ( !q->insecureFallback() ) { + q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); + return; + } + + if ( mode == Delete ) { + actual->remove( key ); + actual->sync(); + + q->emitFinished(); + return; + } + + actual->setValue( QString::fromLatin1( "%1/type" ).arg( key ), mode ); + if ( mode == Text ) + actual->setValue( QString::fromLatin1( "%1/data" ).arg( key ), textData.toUtf8() ); + else if ( mode == Binary ) + actual->setValue( QString::fromLatin1( "%1/data" ).arg( key ), binaryData ); + actual->sync(); + + q->emitFinished(); +} + +void WritePasswordJobPrivate::gnomeKeyring_cb( int result, WritePasswordJobPrivate* self ) +{ + if ( result == GnomeKeyring::RESULT_OK ) { + self->q->emitFinished(); + } else { + const QPair errorResult = mapGnomeKeyringError( result ); + self->q->emitFinishedWithError( errorResult.first, errorResult.second ); + } +} + +void WritePasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) { + watcher->deleteLater(); + QDBusPendingReply reply = *watcher; + + QScopedPointer local( !q->settings() ? new QSettings( q->service() ) : 0 ); + QSettings* actual = q->settings() ? q->settings() : local.data(); + + if ( reply.isError() ) { + fallbackOnError( reply.error() ); + return; + } + + if ( actual->contains( key ) ) + { + // If we had previously written to QSettings, but we now have a kwallet available, migrate and delete old insecure data + actual->remove( key ); + actual->sync(); + } + + const int handle = reply.value(); + + if ( handle < 0 ) { + q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") ); + return; + } + + QDBusPendingReply nextReply; + + if ( !textData.isEmpty() ) + nextReply = iface->writePassword( handle, q->service(), key, textData, q->service() ); + else if ( !binaryData.isEmpty() ) + nextReply = iface->writeEntry( handle, q->service(), key, binaryData, q->service() ); + else + nextReply = iface->removeEntry( handle, q->service(), key, q->service() ); + + QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this ); + connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletWriteFinished(QDBusPendingCallWatcher*)) ); +} + +void WritePasswordJobPrivate::kwalletWriteFinished( QDBusPendingCallWatcher* watcher ) { + watcher->deleteLater(); + QDBusPendingReply reply = *watcher; + if ( reply.isError() ) { + const QDBusError err = reply.error(); + q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); + return; + } + + q->emitFinished(); +} diff -Nru qtkeychain-0.1.0/keychain_win.cpp qtkeychain-0.3.0/keychain_win.cpp --- qtkeychain-0.1.0/keychain_win.cpp 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/keychain_win.cpp 2014-03-13 13:31:53.000000000 +0000 @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (C) 2011 Frank Osterfeld * + * Copyright (C) 2011-2014 Frank Osterfeld * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * diff -Nru qtkeychain-0.1.0/QtKeychainConfig.cmake.in qtkeychain-0.3.0/QtKeychainConfig.cmake.in --- qtkeychain-0.1.0/QtKeychainConfig.cmake.in 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/QtKeychainConfig.cmake.in 2014-03-13 13:31:53.000000000 +0000 @@ -7,15 +7,15 @@ get_filename_component(QTKEYCHAIN_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) if(EXISTS "${QTKEYCHAIN_CMAKE_DIR}/CMakeCache.txt") # In build tree - include("${QTKEYCHAIN_CMAKE_DIR}/QtKeychainBuildTreeSettings.cmake") + include("${QTKEYCHAIN_CMAKE_DIR}/Qt@QTKEYCHAIN_VERSION_INFIX@KeychainBuildTreeSettings.cmake") else() set(QTKEYCHAIN_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@") endif() # Our library dependencies (contains definitions for IMPORTED targets) -include("${QTKEYCHAIN_CMAKE_DIR}/QtKeychainLibraryDepends.cmake") +include("${QTKEYCHAIN_CMAKE_DIR}/Qt@QTKEYCHAIN_VERSION_INFIX@KeychainLibraryDepends.cmake") # These are IMPORTED targets created by FooBarLibraryDepends.cmake -set(QTKEYCHAIN_LIBRARIES qtkeychain) +set(QTKEYCHAIN_LIBRARIES "@QTKEYCHAIN_TARGET_NAME@") set(QTKEYCHAIN_FOUND TRUE) diff -Nru qtkeychain-0.1.0/ReadMe.markdown qtkeychain-0.3.0/ReadMe.markdown --- qtkeychain-0.1.0/ReadMe.markdown 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/ReadMe.markdown 2014-03-13 13:31:53.000000000 +0000 @@ -5,9 +5,8 @@ * **Mac OS X:** Passwords are stored in the OS X Keychain. - * **Linux/Unix:** If running, KWallet (via D-Bus) is used. -Support for the GNOME Keyring via freedesktop.org's -[Secret Storage D-Bus specification](http://freedesktop.org/wiki/Specifications/secret-storage-spec "Secret Storage specification") is planned but not yet implemented. + * **Linux/Unix:** If running, GNOME Keyring is used, otherwise +qtkeychain tries to use KWallet (via D-Bus), if available. * **Windows:** Windows does not provide a service for secure storage. QtKeychain uses the Windows API function [CryptProtectData](http://msdn.microsoft.com/en-us/library/windows/desktop/aa380261%28v=vs.85%29.aspx "CryptProtectData function") to encrypt the password with the user's logon credentials. The encrypted data is then persisted via QSettings. diff -Nru qtkeychain-0.1.0/ReadMe.txt qtkeychain-0.3.0/ReadMe.txt --- qtkeychain-0.1.0/ReadMe.txt 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/ReadMe.txt 2014-03-13 13:31:53.000000000 +0000 @@ -5,9 +5,8 @@ * **Mac OS X:** Passwords are stored in the OS X Keychain. - * **Linux/Unix:** If running, KWallet (via D-Bus) is used. -Support for the GNOME Keyring via freedesktop.org's -[Secret Storage D-Bus specification](http://freedesktop.org/wiki/Specifications/secret-storage-spec "Secret Storage specification") is planned but not yet implemented. + * **Linux/Unix:** If running, GNOME Keyring is used, otherwise +qtkeychain tries to use KWallet (via D-Bus), if available. * **Windows:** Windows does not provide a service for secure storage. QtKeychain uses the Windows API function [CryptProtectData](http://msdn.microsoft.com/en-us/library/windows/desktop/aa380261%28v=vs.85%29.aspx "CryptProtectData function") to encrypt the password with the user's logon credentials. The encrypted data is then persisted via QSettings. diff -Nru qtkeychain-0.1.0/testclient.cpp qtkeychain-0.3.0/testclient.cpp --- qtkeychain-0.1.0/testclient.cpp 2013-01-23 01:29:06.000000000 +0000 +++ qtkeychain-0.3.0/testclient.cpp 2014-03-13 13:31:53.000000000 +0000 @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (C) 2011 Frank Osterfeld * + * Copyright (C) 2011-2014 Frank Osterfeld * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * diff -Nru qtkeychain-0.1.0/translations/qtkeychain_de.ts qtkeychain-0.3.0/translations/qtkeychain_de.ts --- qtkeychain-0.1.0/translations/qtkeychain_de.ts 1970-01-01 00:00:00.000000000 +0000 +++ qtkeychain-0.3.0/translations/qtkeychain_de.ts 2014-03-13 13:31:53.000000000 +0000 @@ -0,0 +1,177 @@ + + + + + QKeychain::ReadPasswordJobPrivate + + + Unknown error + Unbekannter Fehler + + + + D-Bus is not running + + + + + No keychain service available + Kein Schlüsselbund-Dienst verfügbar + + + + Could not open wallet: %1; %2 + Konnte Brieftasche nicht öffnen: %1; %2 + + + + Access to keychain denied + Zugriff auf Schlüsselbund verweigert + + + + Could not determine data type: %1; %2 + Datentyp kann nicht ermittelt werden: %1: %2 + + + + Unsupported entry type 'Map' + + + + + Unknown kwallet entry type '%1' + + + + + Could not read password: %1; %2 + Passwort konnte nicht ausgelesen werden: %1; %2 + + + + Password not found + Passwort nicht gefunden + + + + + Entry not found + Eintrag nicht gefunden + + + + Could not decrypt data + Kann Daten nicht entschlüsseln + + + + QKeychain::WritePasswordJobPrivate + + + + Unknown error + Unbekannter Fehler + + + + D-Bus is not running + + + + + + Could not open wallet: %1; %2 + Konnte Brieftasche nicht öffnen: %1; %2 + + + + Access to keychain denied + Zugriff auf Schlüsselbund verweigert + + + + Could not delete encrypted data from settings: access error + Kann verschlüsselte Daten nicht aus den Einstellungen entfernen: Zugriffsfehler + + + + Could not delete encrypted data from settings: format error + Kann verschlüsselte Daten nicht aus den Einstellungen entfernen: Formatfehler + + + + Encryption failed + Verschlüsselung fehlgeschlagen + + + + Could not store encrypted data in settings: access error + Kann verschlüsselte Daten nicht in den Einstellungen speichern: Zugriffsfehler + + + + Could not store encrypted data in settings: format error + Kann verschlüsselte Daten nicht in den Einstellungen speichern: Formatfehler + + + + QObject + + + Access to keychain denied + Zugriff auf Schlüsselbund verweigert + + + + No keyring daemon + Kein Schlüsselbund-Dienst + + + + Already unlocked + Bereits entsperrt + + + + No such keyring + Kein solcher Schlüsselbund + + + + Bad arguments + Ungültige Argumente + + + + I/O error + Ein-/Ausgabe-Fehler + + + + Cancelled + Abgebrochen + + + + Keyring already exists + Schlüsselbund existiert bereits + + + + No match + Kein Treffer + + + + Unknown error + Unbekannter Fehler + + + + + %1 (OSStatus %2) + + + + diff -Nru qtkeychain-0.1.0/translations/qtkeychain_ro.ts qtkeychain-0.3.0/translations/qtkeychain_ro.ts --- qtkeychain-0.1.0/translations/qtkeychain_ro.ts 1970-01-01 00:00:00.000000000 +0000 +++ qtkeychain-0.3.0/translations/qtkeychain_ro.ts 2014-03-13 13:31:53.000000000 +0000 @@ -0,0 +1,178 @@ + + + + + QKeychain::ReadPasswordJobPrivate + + + Unknown error + Eroare necunoscută + + + + D-Bus is not running + D-Bus nu rulează + + + + No keychain service available + Nu există niciun serviciu de chei disponibil + Kein Schlüsselbund-Dienst verfügbar + + + + Could not open wallet: %1; %2 + Nu se poate deschide portofelul: %1; %2 + + + + Access to keychain denied + Acces interzis la serviciul de chei + + + + Could not determine data type: %1; %2 + Nu se poate stabili tipul de date: %1: %2 + + + + Unsupported entry type 'Map' + Tip de înregistrare nesuportat 'Map' + + + + Unknown kwallet entry type '%1' + Tip de înregistrare kwallet necunoscut '%1' + + + + Could not read password: %1; %2 + Nu se poate citi parola: %1; %2 + + + + Password not found + Parola nu a fost găsită + + + + + Entry not found + Înregistrarea nu a fost găsită + + + + Could not decrypt data + Nu se poate decripta data + + + + QKeychain::WritePasswordJobPrivate + + + + Unknown error + Eroare necunoscută + + + + D-Bus is not running + D-Bus nu rulează + + + + + Could not open wallet: %1; %2 + Nu se poate deschide portofelul: %1; %2 + + + + Access to keychain denied + Acces interzis la serviciul de chei + + + + Could not delete encrypted data from settings: access error + Nu se pot șterge datele criptate din setări: eroare de acces + + + + Could not delete encrypted data from settings: format error + Nu se pot șterge datele criptate din setări: eroare de format + + + + Encryption failed + Criptarea a eșuat + + + + Could not store encrypted data in settings: access error + Nu se pot stoca datele criptate în setări: eroare de acces + + + + Could not store encrypted data in settings: format error + Nu se pot stoca datele criptate în setări: eroare de format + + + + QObject + + + Access to keychain denied + Acces interzis la serviciul de chei + + + + No keyring daemon + Niciun demon pentru inelul de chei + + + + Already unlocked + Deja deblocat + + + + No such keyring + Nu există astfel de inel de chei + + + + Bad arguments + Argumente greșite + + + + I/O error + Eroare de I/E + + + + Cancelled + Anulat + + + + Keyring already exists + Inelul de chei deja există + + + + No match + Nicio potrivire + + + + Unknown error + Eroare necunoscută + + + + + %1 (OSStatus %2) + %1 (OSStatus %2) + + +