qtkeychain-0.10.0/ 0000755 0001750 0001750 00000000000 13576175767 012672 5 ustar hefee hefee qtkeychain-0.10.0/appveyor.yml 0000644 0001750 0001750 00000001454 13576175767 015266 0 ustar hefee hefee version: '{build}'
build_script:
- ps: |
$ErrorActionPreference="Stop"
Import-Module $env:APPVEYOR_BUILD_FOLDER\appveyorHelp.psm1
Init @("ninja")
mkdir -Force $env:APPVEYOR_BUILD_FOLDER\work\build\$env:APPVEYOR_PROJECT_NAME
cd $env:APPVEYOR_BUILD_FOLDER\work\build\$env:APPVEYOR_PROJECT_NAME
LogExec cmake -G"Ninja" $env:APPVEYOR_BUILD_FOLDER -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$CMAKE_INSTALL_ROOT"
CmakeImageInstall
test: off
cache:
- work\install -> appveyor.yml
- C:\ProgramData\chocolatey\bin -> appveyor.yml
- C:\ProgramData\chocolatey\lib -> appveyor.yml
environment:
QT_VER: 5.7
matrix:
- COMPILER: msvc2015
- COMPILER: msvc2015_64
- COMPILER: mingw53_32
qtkeychain-0.10.0/org.kde.KWallet.xml 0000644 0001750 0001750 00000025012 13576175767 016307 0 ustar hefee hefee
qtkeychain-0.10.0/qt5keychain.pri 0000644 0001750 0001750 00000004642 13576175767 015641 0 ustar hefee hefee # Minimal qmake support.
# This file is provided as is without any warranty.
# It can break at anytime or be removed without notice.
QT5KEYCHAIN_PWD = $$PWD
CONFIG += depend_includepath
DEFINES += QTKEYCHAIN_NO_EXPORT
INCLUDEPATH += \
$$PWD/.. \
$$QT5KEYCHAIN_PWD
HEADERS += \
$$QT5KEYCHAIN_PWD/keychain_p.h \
$$QT5KEYCHAIN_PWD/keychain.h
SOURCES += \
$$QT5KEYCHAIN_PWD/keychain.cpp
unix:!macx:!ios {
# Remove the following LIBSECRET_SUPPORT line
# to build without libsecret support.
DEFINES += LIBSECRET_SUPPORT
contains(DEFINES, LIBSECRET_SUPPORT) {
packagesExist(libsecret-1) {
!build_pass:message("Libsecret support: on")
CONFIG += link_pkgconfig
PKGCONFIG += libsecret-1
DEFINES += HAVE_LIBSECRET
} else {
!build_pass:warning("Libsecret not found.")
!build_pass:message("Libsecret support: off")
}
} else {
!build_pass:message("Libsecret support: off")
}
# Generate D-Bus interface:
QT += dbus
kwallet_interface.files = $$PWD/org.kde.KWallet.xml
DBUS_INTERFACES += kwallet_interface
HEADERS += \
$$QT5KEYCHAIN_PWD/gnomekeyring_p.h \
$$QT5KEYCHAIN_PWD/plaintextstore_p.h \
$$QT5KEYCHAIN_PWD/libsecret_p.h
SOURCES += \
$$QT5KEYCHAIN_PWD/keychain_unix.cpp \
$$QT5KEYCHAIN_PWD/plaintextstore.cpp \
$$QT5KEYCHAIN_PWD/gnomekeyring.cpp \
$$QT5KEYCHAIN_PWD/libsecret.cpp
}
win32 {
# Remove the following USE_CREDENTIAL_STORE line
# to use the CryptProtectData Windows API function
# instead of the Windows Credential Store.
DEFINES += USE_CREDENTIAL_STORE
contains(DEFINES, USE_CREDENTIAL_STORE) {
!build_pass:message("Windows Credential Store support: on")
LIBS += -lAdvapi32
} else {
!build_pass:message("Windows Credential Store support: off")
LIBS += -lCrypt32
HEADERS += $$QT5KEYCHAIN_PWD/plaintextstore_p.h
SOURCES += $$QT5KEYCHAIN_PWD/plaintextstore.cpp
}
HEADERS += $$QT5KEYCHAIN_PWD/libsecret_p.h
SOURCES += \
$$QT5KEYCHAIN_PWD/keychain_win.cpp \
$$QT5KEYCHAIN_PWD/libsecret.cpp
}
macx:!ios {
LIBS += -framework Security -framework Foundation
SOURCES += $$QT5KEYCHAIN_PWD/keychain_mac.cpp
}
ios {
LIBS += -framework Security -framework Foundation
OBJECTIVE_SOURCES += $$QT5KEYCHAIN_PWD/keychain_ios.mm
}
qtkeychain-0.10.0/translations/ 0000755 0001750 0001750 00000000000 13576175767 015413 5 ustar hefee hefee qtkeychain-0.10.0/translations/qtkeychain_fr.ts 0000644 0001750 0001750 00000026226 13576175767 020622 0 ustar hefee hefee
QKeychain::DeletePasswordJobPrivate
Password entry not found
Mot de passe non trouvé
Could not decrypt data
Impossible de déchiffrer les données
Unknown error
Erreur inconnue
Could not open wallet: %1; %2
Impossible d'ouvrir le trousseau : %1; %2
Password not found
Mot de passe non trouvé
QKeychain::JobPrivate
Unknown error
Erreur inconnue
Access to keychain denied
Accès au trousseau refusé
QKeychain::PlainTextStore
Could not store data in settings: access error
Impossible de stocker les paramètres : Erreur d'accès
Could not store data in settings: format error
Impossible de stocker les paramètres : Erreur de format
Could not delete data from settings: access error
Impossible de supprimer des paramètres : Erreur d'accès
Could not delete data from settings: format error
Impossible de supprimer des paramètres : Erreur de format
Entry not found
Entrée non trouvée
QKeychain::ReadPasswordJobPrivate
Unknown error
Erreur inconnue
D-Bus is not running
D-Bus non disponible
No keychain service available
Aucun service de trousseau disponible
Could not open wallet: %1; %2
Impossible d'ouvrir le trousseau : %1; %2
Access to keychain denied
Accès au trousseau refusé
Could not determine data type: %1; %2
Impossible de déterminer le type de données : %1: %2
Unsupported entry type 'Map'
Type d'entrée non supporté «Map»
Unknown kwallet entry type '%1'
Type de trousseau inconnu «%1»
Could not read password: %1; %2
Impossible de lire le mot de passe : %1; %2
Password not found
Mot de passe non trouvé
Entry not found
Entrée non trouvée
Password entry not found
Entrée non trouvée
Could not decrypt data
Impossible de déchiffrer les données
QKeychain::WritePasswordJobPrivate
Unknown error
Erreur inconnue
D-Bus is not running
D-Bus non disponible
Could not open wallet: %1; %2
Impossible d'ouvrir le trousseau : %1; %2
Access to keychain denied
Accès au trousseau refusé
Could not delete encrypted data from settings: access error
Impossible de supprimer des données chiffrées dans les paramètres : Erreur d'accès
Could not delete encrypted data from settings: format error
Impossible de supprimer des données chiffrées dans les paramètres : Erreur de format
Encryption failed
Le chiffrement a échoué
Could not store encrypted data in settings: access error
Impossible de stocker des données chiffrées dans les paramètres : Erreur d'accès
Could not store encrypted data in settings: format error
Impossible de stocker des données chiffrées dans les paramètres : Erreur de format
Password not found
Mot de passe non trouvé
QObject
Access to keychain denied
Accès au trousseau refusé
No keyring daemon
Aucun démon de trousseau
Already unlocked
Déjà déverrouillé
No such keyring
Trousseau non trouvé
Bad arguments
Mauvais arguments
I/O error
Erreur d'E/S
Cancelled
Annulé
Keyring already exists
Trousseau déjà existant
No match
Aucune correspondance
Unknown error
Erreur inconnue
OS X Keychain error (OSStatus %1)
%1 (OSStatus %2)
Entry not found
Entrée non trouvée
error 0x%1: %2
Erreur 0x%1 : %2
qtkeychain-0.10.0/translations/qtkeychain_de.ts 0000644 0001750 0001750 00000016220 13576175767 020574 0 ustar hefee hefee
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)
qtkeychain-0.10.0/translations/qtkeychain_zh.ts 0000644 0001750 0001750 00000015614 13576175767 020633 0 ustar hefee hefee
QKeychain::ReadPasswordJobPrivate
Unknown error
未知的錯誤
D-Bus is not running
D-Bus 不在執行中
No keychain service available
沒有可用的鑰匙圈服務
Could not open wallet: %1; %2
無法開啟錢包:%1; %2
Access to keychain denied
鑰匙圈存取被拒絕
Could not determine data type: %1; %2
無法判斷資料型別:%1; %2
Unsupported entry type 'Map'
不支援的項目類型 'Map'
Unknown kwallet entry type '%1'
未知的 kwallet 項目類型 '%1'
Could not read password: %1; %2
無法讀取密碼:%1; %2
Password not found
找不到密碼
Entry not found
找不到項目
Could not decrypt data
無法解密資料
QKeychain::WritePasswordJobPrivate
Unknown error
未知的錯誤
D-Bus is not running
D-Bus 不在執行中
Could not open wallet: %1; %2
無法開啟錢包:%1; %2
Access to keychain denied
鑰匙圈存取被拒絕
Could not delete encrypted data from settings: access error
無法從設定刪除加密資料:存取錯誤
Could not delete encrypted data from settings: format error
無法從設定刪除加密資料:格式錯誤
Encryption failed
加密失敗
Could not store encrypted data in settings: access error
無法將加密資料儲存至設定:存取錯誤
Could not store encrypted data in settings: format error
無法將加密資料儲存至設定:格式錯誤
QObject
Access to keychain denied
鑰匙圈存取被拒絕
No keyring daemon
沒有可用的鑰匙圈背景程式
Already unlocked
已解鎖
No such keyring
鑰匙圈不存在
Bad arguments
引數錯誤
I/O error
I/O 錯誤
Cancelled
已取消
Keyring already exists
鑰匙圈已存在
No match
無相符項目
Unknown error
未知的錯誤
%1 (OSStatus %2)
%1 (OSStatus %2)
qtkeychain-0.10.0/translations/qtkeychain_ro.ts 0000644 0001750 0001750 00000016302 13576175767 020625 0 ustar hefee hefee
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)
qtkeychain-0.10.0/ReadMe.txt 0000644 0001750 0001750 00000002121 13576175767 014564 0 ustar hefee hefee QtKeychain
==========
QtKeychain is a Qt API to store passwords and other secret data securely. How the data is stored depends on the platform:
* **Mac OS X:** Passwords are stored in the OS X Keychain.
* **Linux/Unix:** If running, GNOME Keyring is used, otherwise qtkeychain tries to use KWallet (via D-Bus), if available.
* **Windows:** By default, the Windows Credential Store is used (requires Windows 7 or newer).
Pass -DUSE_CREDENTIAL_STORE=OFF to cmake use disable it. If disabled, 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.
In unsupported environments QtKeychain will report an error. It will not store any data unencrypted unless explicitly requested (setInsecureFallback( true )).
**License:** QtKeychain is available under the [Modified BSD License](http://www.gnu.org/licenses/license-list.html#ModifiedBSD). See the file COPYING for details.
qtkeychain-0.10.0/ChangeLog 0000644 0001750 0001750 00000005612 13576175767 014450 0 ustar hefee hefee ChangeLog
=========
version 0.10.0 (release 2019-12-17)
* Detect XFCE desktop correctly. (Sandro Knauß )
* Windows Use CRED_PERSIST_ENTERPRISE (Olivier Goffart )
* Windows: Improve CredWrite() error handling (Christian Kamm )
* Fix build with Qt 5.12.x (Sergey Ilinykh )
* Fix Qt 4 build (Robert-André Mauchin )
* Translation: Mandarin (Taiwan) (Poren Chiang )
* Translation: French (François Revol )
version 0.9.1 (release 2018-08-20)
* Windows Credential Store: Use CRED_PERSIST_ENTERPRISE (Olivier Goffart )
* Secret: Don't match the schema name #114 (Christian Kamm )
* Fix qmake build on Windows (Alexander Gorishnyak )
version 0.9.0 (release 2018-07-13)
* Fall back on libsecret if kwallet is not available (Christian Kamm )
* Only require QtLinguist if building translations (Victor Kropp )
* Fix building on Windows without credential store (Dmitry Ivanov )
* Fix Qt 4 build (Sandro Knauß )
* Make build of test application optional (Boris Pek )
version 0.8.0 (release 2017-04-19)
* Buildsystem improvements (Kristofer Tingdahl , Hannah von Reth , Giuseppe D'Angelo )
* Enable C++11 support for Qt >= 5.7 (Dmitry Ivanov )
* Doxygen documentation ( Elvis Angelaccio )
* Libsecret support (Armin Novak )
* iOS support (Mathias Hasselmann )
version 0.7.0 (release 2016-05-23)
* Bump SO version due to 0.6 being binary-incompatible to previous releases
version 0.6.2 (release 2016-04-04)
* KWallet: Fixes a crash when storing passwords, seen on Debian/KDE4
version 0.6.1 (release 2016-03-31)
* Fix KWallet not working (regressions in 0.6.0)
version 0.6.0 (release 2016-03-18)
* Added support for the Windows Credential Store
version 0.5.0 (release 2015-05-04)
* Added support for KWallet5 (KDE5/KF)
version 0.4.0 (release 2014-09-01)
* KWallet: Handle case where no wallet exists yet (Liviu Cristian Mirea Ghiban )
* Improved desktop environment detection at runtime (Daniel Molkentin )
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
qtkeychain-0.10.0/gnomekeyring_p.h 0000644 0001750 0001750 00000006645 13576175767 016073 0 ustar hefee hefee #ifndef QTKEYCHAIN_GNOME_P_H
#define QTKEYCHAIN_GNOME_P_H
#include
class GnomeKeyring : private QLibrary {
Q_OBJECT
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 bool gboolean;
typedef struct {
ItemType item_type;
struct {
const gchar* name;
AttributeType type;
} attributes[32];
} PasswordSchema;
typedef void ( *OperationGetStringCallback )( Result result, bool binary,
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 isAvailable();
static gpointer store_network_password( const gchar* keyring, const gchar* display_name,
const gchar* user, const gchar* server,
const gchar* type, const gchar* password,
OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data );
static gpointer find_network_password( const gchar* user, const gchar* server,
const gchar* type,
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 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,
... );
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,
... );
is_available_fn* is_available;
find_password_fn* find_password;
store_password_fn* store_password;
delete_password_fn* delete_password;
};
#endif
qtkeychain-0.10.0/libsecret_p.h 0000644 0001750 0001750 00000001376 13576175767 015345 0 ustar hefee hefee #ifndef QTKEYCHAIN_LIBSECRET_P_H
#define QTKEYCHAIN_LIBSECRET_P_H
#include
#include "keychain_p.h"
class LibSecretKeyring : public QLibrary {
public:
static bool isAvailable();
static bool findPassword(const QString& user,
const QString& server,
QKeychain::JobPrivate* self);
static bool writePassword(const QString& display_name,
const QString& user,
const QString& server,
const QKeychain::JobPrivate::Mode type,
const QByteArray& password,
QKeychain::JobPrivate* self);
static bool deletePassword(const QString &key, const QString &service,
QKeychain::JobPrivate* self);
private:
LibSecretKeyring();
static LibSecretKeyring &instance();
};
#endif
qtkeychain-0.10.0/keychain_p.h 0000644 0001750 0001750 00000010676 13576175767 015167 0 ustar hefee hefee /******************************************************************************
* Copyright (C) 2011-2015 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'. *
*****************************************************************************/
#ifndef KEYCHAIN_P_H
#define KEYCHAIN_P_H
#include
#include
#include
#include
#include
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID)
#include
#include "kwallet_interface.h"
#else
class QDBusPendingCallWatcher;
#endif
#include "keychain.h"
namespace QKeychain {
class JobExecutor;
class JobPrivate : public QObject {
Q_OBJECT
public:
enum Mode {
Text,
Binary
};
virtual void scheduledStart() = 0;
static QString modeToString(Mode m);
static Mode stringToMode(const QString& s);
Job* const q;
Mode mode;
QByteArray data;
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID)
org::kde::KWallet* iface;
int walletHandle;
static void gnomeKeyring_readCb( int result, const char* string, JobPrivate* data );
static void gnomeKeyring_writeCb( int result, JobPrivate* self );
virtual void fallbackOnError(const QDBusError& err) = 0;
protected Q_SLOTS:
void kwalletWalletFound( QDBusPendingCallWatcher* watcher );
virtual void kwalletFinished( QDBusPendingCallWatcher* watcher );
virtual void kwalletOpenFinished( QDBusPendingCallWatcher* watcher );
#else
void kwalletWalletFound( QDBusPendingCallWatcher* ) {}
virtual void kwalletFinished( QDBusPendingCallWatcher* ) {}
virtual void kwalletOpenFinished( QDBusPendingCallWatcher* ) {}
#endif
protected:
JobPrivate( const QString& service_, Job *q );
protected:
QKeychain::Error error;
QString errorString;
QString service;
bool autoDelete;
bool insecureFallback;
QPointer settings;
QString key;
friend class Job;
friend class JobExecutor;
friend class ReadPasswordJob;
friend class WritePasswordJob;
friend class PlainTextStore;
};
class ReadPasswordJobPrivate : public JobPrivate {
Q_OBJECT
public:
explicit ReadPasswordJobPrivate( const QString &service_, ReadPasswordJob* qq );
void scheduledStart();
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID)
void fallbackOnError(const QDBusError& err);
private Q_SLOTS:
void kwalletOpenFinished( QDBusPendingCallWatcher* watcher );
void kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher );
void kwalletFinished( QDBusPendingCallWatcher* watcher );
#else //moc's too dumb to respect above macros, so just define empty slot implementations
private Q_SLOTS:
void kwalletOpenFinished( QDBusPendingCallWatcher* ) {}
void kwalletEntryTypeFinished( QDBusPendingCallWatcher* ) {}
void kwalletFinished( QDBusPendingCallWatcher* ) {}
#endif
friend class ReadPasswordJob;
};
class WritePasswordJobPrivate : public JobPrivate {
Q_OBJECT
public:
explicit WritePasswordJobPrivate( const QString &service_, WritePasswordJob* qq );
void scheduledStart();
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID)
void fallbackOnError(const QDBusError& err);
#endif
friend class WritePasswordJob;
};
class DeletePasswordJobPrivate : public JobPrivate {
Q_OBJECT
public:
explicit DeletePasswordJobPrivate( const QString &service_, DeletePasswordJob* qq );
void scheduledStart();
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID)
void fallbackOnError(const QDBusError& err);
#endif
protected:
void doStart();
friend class DeletePasswordJob;
};
class JobExecutor : public QObject {
Q_OBJECT
public:
static JobExecutor* instance();
void enqueue( Job* job );
private:
explicit JobExecutor();
void startNextIfNoneRunning();
private Q_SLOTS:
void jobFinished( QKeychain::Job* );
void jobDestroyed( QObject* object );
private:
static JobExecutor* s_instance;
QQueue > m_queue;
bool m_jobRunning;
};
}
#endif // KEYCHAIN_P_H
qtkeychain-0.10.0/CMakeLists.txt 0000644 0001750 0001750 00000022147 13576175767 015440 0 ustar hefee hefee cmake_minimum_required(VERSION 2.8.11)
project(qtkeychain)
include(FindPkgConfig)
###
set(QTKEYCHAIN_VERSION 0.10.0)
set(QTKEYCHAIN_SOVERSION 1)
###
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${PROJECT_SOURCE_DIR}/cmake/Modules")
include(GNUInstallDirs)
include(GenerateExportHeader)
include(ECMPackageConfigHelpers)
include(ECMSetupVersion)
include(ECMGeneratePriFile)
option(BUILD_WITH_QT4 "Build qtkeychain with Qt4 no matter if Qt5 was found" OFF)
option(BUILD_TEST_APPLICATION "Build test application" ON)
option(BUILD_TRANSLATIONS "Build translations" ON)
option(QTKEYCHAIN_STATIC "Build static library" OFF)
if(CMAKE_SYSTEM_NAME STREQUAL Android)
set(ANDROID 1)
endif()
if (WIN32)
option(USE_CREDENTIAL_STORE "Build with windows CredentialStore support" ON)
if (USE_CREDENTIAL_STORE)
add_definitions(-DUSE_CREDENTIAL_STORE=1)
endif()
endif()
if( NOT BUILD_WITH_QT4 )
# try Qt5 first, and prefer that if found
find_package(Qt5Core QUIET)
endif()
if (Qt5Core_FOUND AND NOT BUILD_WITH_QT4)
set(QTKEYCHAIN_VERSION_INFIX 5)
if(UNIX AND NOT APPLE AND NOT ANDROID)
find_package(Qt5DBus REQUIRED)
include_directories(${Qt5DBus_INCLUDE_DIRS})
set(QTDBUS_LIBRARIES ${Qt5DBus_LIBRARIES})
macro(qt_add_dbus_interface)
qt5_add_dbus_interface(${ARGN})
endmacro()
endif()
if(BUILD_TRANSLATIONS)
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)
endif()
macro(qt_wrap_cpp)
qt5_wrap_cpp(${ARGN})
endmacro()
set(QTCORE_LIBRARIES ${Qt5Core_LIBRARIES})
include_directories(${Qt5Core_INCLUDE_DIRS})
if (NOT Qt5Core_VERSION VERSION_LESS "5.7.0")
if (CMAKE_COMPILER_IS_GNUCXX)
if ((NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.1.0"))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7.0")
message(FATAL_ERROR "Can't build QtKeychain using g++-${CMAKE_CXX_COMPILER_VERSION} and Qt ${Qt5Core_VERSION}: compiler supporting C++11 is required")
endif()
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if (NOT ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 3.3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
message(FATAL_ERROR "Can't build QtKeychain using clang++-${CMAKE_CXX_COMPILER_VERSION} and Qt ${Qt5Core_VERSION}: compiler supporting C++11 is required")
endif()
elseif ((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND (MSVC_VERSION LESS 1700))
message(FATAL_ERROR "Can't build QtKeychain using VC++-${MSVC_VERSION} and Qt ${Qt5Core_VERSION}: compiler supporting C++11 is required")
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})
macro(qt_add_dbus_interface)
qt4_add_dbus_interface(${ARGN})
endmacro()
else()
find_package(Qt4 COMPONENTS QtCore REQUIRED)
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()
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR})
list(APPEND qtkeychain_LIBRARIES ${QTCORE_LIBRARIES})
set(qtkeychain_SOURCES
keychain.cpp
qkeychain_export.h
keychain.h
)
add_definitions( -Wall )
if(WIN32)
list(APPEND qtkeychain_SOURCES keychain_win.cpp)
if (NOT USE_CREDENTIAL_STORE)
list(APPEND qtkeychain_LIBRARIES crypt32)
list(APPEND qtkeychain_SOURCES plaintextstore.cpp)
endif()
#FIXME: mingw bug; otherwise getting undefined refs to RtlSecureZeroMemory there
if(MINGW)
add_definitions( -O2 )
endif()
endif()
if(APPLE)
if(IOS)
list(APPEND qtkeychain_SOURCES keychain_ios.cpp)
else()
list(APPEND qtkeychain_SOURCES keychain_mac.cpp)
endif()
find_library(COREFOUNDATION_LIBRARY CoreFoundation REQUIRED)
list(APPEND qtkeychain_LIBRARIES ${COREFOUNDATION_LIBRARY})
find_library(SECURITY_LIBRARY Security REQUIRED)
list(APPEND qtkeychain_LIBRARIES ${SECURITY_LIBRARY})
endif()
if(UNIX AND NOT APPLE AND NOT ANDROID)
option(LIBSECRET_SUPPORT "Build with libsecret support" ON)
if(LIBSECRET_SUPPORT)
pkg_check_modules(LIBSECRET libsecret-1)
if (LIBSECRET_FOUND)
add_definitions(-DHAVE_LIBSECRET=1)
endif()
INCLUDE_DIRECTORIES(${LIBSECRET_INCLUDE_DIRS})
list(APPEND qtkeychain_LIBRARIES ${LIBSECRET_LIBRARIES})
endif()
list(APPEND qtkeychain_SOURCES keychain_unix.cpp gnomekeyring.cpp libsecret.cpp plaintextstore.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 gnomekeyring_p.h)
set(qtkeychain_TR_FILES
translations/qtkeychain_de.ts
translations/qtkeychain_ro.ts
)
file(GLOB qtkeychain_TR_SOURCES *.cpp *.h *.ui)
if ( BUILD_TRANSLATIONS )
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
execute_process( COMMAND ${QT5_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
OUTPUT_VARIABLE qt_translations_dir OUTPUT_STRIP_TRAILING_WHITESPACE )
# 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})
endif( BUILD_TRANSLATIONS )
set(QTKEYCHAIN_TARGET_NAME qt${QTKEYCHAIN_VERSION_INFIX}keychain)
if(NOT QTKEYCHAIN_STATIC)
add_library(${QTKEYCHAIN_TARGET_NAME} SHARED ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES} ${qtkeychain_QM_FILES})
else()
add_library(${QTKEYCHAIN_TARGET_NAME} STATIC ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES} ${qtkeychain_QM_FILES})
endif()
target_link_libraries(${QTKEYCHAIN_TARGET_NAME} PUBLIC ${qtkeychain_LIBRARIES})
target_include_directories(${QTKEYCHAIN_TARGET_NAME} PUBLIC $)
generate_export_header(${QTKEYCHAIN_TARGET_NAME}
EXPORT_FILE_NAME qkeychain_export.h
EXPORT_MACRO_NAME QKEYCHAIN_EXPORT
)
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_RPATH_USE_LINK_PATH TRUE
)
install(FILES keychain.h ${CMAKE_CURRENT_BINARY_DIR}/qkeychain_export.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/qt${QTKEYCHAIN_VERSION_INFIX}keychain/
)
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}
)
if(BUILD_TEST_APPLICATION)
add_executable( testclient testclient.cpp )
target_link_libraries( testclient ${QTKEYCHAIN_TARGET_NAME})
endif()
###
### CMake config file
###
ecm_configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/QtKeychainConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfig.cmake"
INSTALL_DESTINATION Qt${QTKEYCHAIN_VERSION_INFIX}Keychain)
ecm_setup_version("${QTKEYCHAIN_VERSION}" VARIABLE_PREFIX SNORE
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/Qt${QTKEYCHAIN_VERSION_INFIX}KeychainConfigVersion.cmake"
SOVERSION ${QTKEYCHAIN_VERSION})
if(UNIX AND NOT APPLE AND NOT ANDROID)
set(PRI_EXTRA_DEPS "dbus")
endif()
ecm_generate_pri_file(BASE_NAME Qt${QTKEYCHAIN_VERSION_INFIX}Keychain
LIB_NAME ${QTKEYCHAIN_TARGET_NAME}
DEPS "core ${PRI_EXTRA_DEPS}"
INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}
FILENAME_VAR pri_filename)
install(FILES ${pri_filename} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
install(EXPORT Qt${QTKEYCHAIN_VERSION_INFIX}KeychainLibraryDepends
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Qt${QTKEYCHAIN_VERSION_INFIX}Keychain"
)
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
)
qtkeychain-0.10.0/keychain_unix.cpp 0000644 0001750 0001750 00000053031 13576175767 016236 0 ustar hefee hefee /******************************************************************************
* Copyright (C) 2011-2015 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 "libsecret_p.h"
#include "plaintextstore_p.h"
#include
using namespace QKeychain;
enum KeyringBackend {
Backend_LibSecretKeyring,
Backend_GnomeKeyring,
Backend_Kwallet4,
Backend_Kwallet5
};
enum DesktopEnvironment {
DesktopEnv_Gnome,
DesktopEnv_Kde4,
DesktopEnv_Plasma5,
DesktopEnv_Unity,
DesktopEnv_Xfce,
DesktopEnv_Other
};
// the following detection algorithm is derived from chromium,
// licensed under BSD, see base/nix/xdg_util.cc
static DesktopEnvironment getKdeVersion() {
QByteArray value = qgetenv("KDE_SESSION_VERSION");
if ( value == "5" ) {
return DesktopEnv_Plasma5;
} else if (value == "4" ) {
return DesktopEnv_Kde4;
} else {
// most likely KDE3
return DesktopEnv_Other;
}
}
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 getKdeVersion();
} else if ( xdgCurrentDesktop == "XFCE" ) {
return DesktopEnv_Xfce;
}
QByteArray desktopSession = qgetenv("DESKTOP_SESSION");
if ( desktopSession == "gnome" ) {
return DesktopEnv_Gnome;
} else if ( desktopSession == "kde" ) {
return getKdeVersion();
} 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() ) {
return getKdeVersion();
}
return DesktopEnv_Other;
}
static bool isKwallet5Available()
{
if (!QDBusConnection::sessionBus().isConnected())
return false;
org::kde::KWallet iface(
QLatin1String("org.kde.kwalletd5"),
QLatin1String("/modules/kwalletd5"),
QDBusConnection::sessionBus());
// At this point iface.isValid() can return false even though the
// interface is activatable by making a call. Hence we check whether
// a wallet can be opened.
iface.setTimeout(500);
QDBusMessage reply = iface.call(QLatin1String("networkWallet"));
return reply.type() == QDBusMessage::ReplyMessage;
}
static KeyringBackend detectKeyringBackend()
{
/* The secret service dbus api, accessible through libsecret, is supposed
* to unify password services.
*
* Unfortunately at the time of Kubuntu 18.04 the secret service backend
* in KDE is gnome-keyring-daemon - using it has several complications:
* - the default collection isn't opened on session start, so users need
* to manually unlock it when the first application uses it
* - it's separate from the kwallet5 keyring, so switching to it means the
* existing keyring data can't be accessed anymore
*
* Thus we still prefer kwallet backends on KDE even if libsecret is
* available.
*/
switch (detectDesktopEnvironment()) {
case DesktopEnv_Kde4:
return Backend_Kwallet4;
case DesktopEnv_Plasma5:
if (isKwallet5Available()) {
return Backend_Kwallet5;
}
if (LibSecretKeyring::isAvailable()) {
return Backend_LibSecretKeyring;
}
if (GnomeKeyring::isAvailable()) {
return Backend_GnomeKeyring;
}
// During startup the keychain backend might just not have started yet
return Backend_Kwallet5;
case DesktopEnv_Gnome:
case DesktopEnv_Unity:
case DesktopEnv_Xfce:
case DesktopEnv_Other:
default:
if (LibSecretKeyring::isAvailable()) {
return Backend_LibSecretKeyring;
}
if (GnomeKeyring::isAvailable()) {
return Backend_GnomeKeyring;
}
if (isKwallet5Available()) {
return Backend_Kwallet5;
}
// During startup the keychain backend might just not have started yet
//
// This doesn't need to be libsecret because LibSecretKeyring::isAvailable()
// only fails if the libsecret shared library couldn't be loaded. In contrast
// to that GnomeKeyring::isAvailable() can return false if the shared library
// *was* loaded but its libgnome_keyring::is_available() returned false.
//
// In the future there should be a difference between "API available" and
// "keychain available".
return Backend_GnomeKeyring;
}
}
static KeyringBackend getKeyringBackend()
{
static KeyringBackend backend = detectKeyringBackend();
return backend;
}
static void kwalletReadPasswordScheduledStartImpl(const char * service, const char * path, ReadPasswordJobPrivate * priv) {
if ( QDBusConnection::sessionBus().isConnected() )
{
priv->iface = new org::kde::KWallet( QLatin1String(service), QLatin1String(path), QDBusConnection::sessionBus(), priv );
const QDBusPendingReply reply = priv->iface->networkWallet();
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, priv );
priv->connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), priv, SLOT(kwalletWalletFound(QDBusPendingCallWatcher*)) );
}
else
{
// D-Bus is not reachable so none can tell us something about KWalletd
QDBusError err( QDBusError::NoServer, ReadPasswordJobPrivate::tr("D-Bus is not running") );
priv->fallbackOnError( err );
}
}
void ReadPasswordJobPrivate::scheduledStart() {
switch ( getKeyringBackend() ) {
case Backend_LibSecretKeyring: {
if ( !LibSecretKeyring::findPassword(key, q->service(), this) ) {
q->emitFinishedWithError( OtherError, tr("Unknown error") );
}
} break;
case Backend_GnomeKeyring:
this->mode = JobPrivate::Text;
if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(),
q->service().toUtf8().constData(),
"plaintext",
reinterpret_cast( &JobPrivate::gnomeKeyring_readCb ),
this, 0 ) )
q->emitFinishedWithError( OtherError, tr("Unknown error") );
break;
case Backend_Kwallet4:
kwalletReadPasswordScheduledStartImpl("org.kde.kwalletd", "/modules/kwalletd", this);
break;
case Backend_Kwallet5:
kwalletReadPasswordScheduledStartImpl("org.kde.kwalletd5", "/modules/kwalletd5", this);
break;
}
}
void JobPrivate::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 JobPrivate::gnomeKeyring_readCb( int result, const char* string, JobPrivate* self )
{
if ( result == GnomeKeyring::RESULT_OK ) {
if (self->mode == JobPrivate::Text)
self->data = QByteArray(string);
else
self->data = QByteArray::fromBase64(string);
self->q->emitFinished();
} else if (self->mode == JobPrivate::Text) {
self->mode = JobPrivate::Binary;
if ( !GnomeKeyring::find_network_password( self->key.toUtf8().constData(),
self->q->service().toUtf8().constData(),
"base64",
reinterpret_cast( &JobPrivate::gnomeKeyring_readCb ),
self, 0 ) )
self->q->emitFinishedWithError( OtherError, tr("Unknown error") );
} else {
const QPair errorResult = mapGnomeKeyringError( result );
self->q->emitFinishedWithError( errorResult.first, errorResult.second );
}
}
void ReadPasswordJobPrivate::fallbackOnError(const QDBusError& err )
{
PlainTextStore plainTextStore( q->service(), q->settings() );
if ( q->insecureFallback() && plainTextStore.contains( key ) ) {
mode = plainTextStore.readMode( key );
data = plainTextStore.readData( key );
if ( plainTextStore.error() != NoError )
q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() );
else
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;
if ( reply.isError() ) {
fallbackOnError( reply.error() );
return;
}
PlainTextStore plainTextStore( q->service(), q->settings() );
if ( plainTextStore.contains( key ) ) {
// We previously stored data in the insecure QSettings, but now have KWallet available.
// Do the migration
data = plainTextStore.readData( key );
const WritePasswordJobPrivate::Mode mode = plainTextStore.readMode( key );
plainTextStore.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:
mode = Text;
break;
case Stream:
mode = 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 = (mode == 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(kwalletFinished(QDBusPendingCallWatcher*)) );
}
void ReadPasswordJobPrivate::kwalletFinished( QDBusPendingCallWatcher* watcher ) {
if ( !watcher->isError() ) {
if ( mode == Binary ) {
QDBusPendingReply reply = *watcher;
if (reply.isValid()) {
data = reply.value();
}
} else {
QDBusPendingReply reply = *watcher;
if (reply.isValid()) {
data = reply.value().toUtf8();
}
}
}
JobPrivate::kwalletFinished(watcher);
}
static void kwalletWritePasswordScheduledStart( const char * service, const char * path, JobPrivate * priv ) {
if ( QDBusConnection::sessionBus().isConnected() )
{
priv->iface = new org::kde::KWallet( QLatin1String(service), QLatin1String(path), QDBusConnection::sessionBus(), priv );
const QDBusPendingReply reply = priv->iface->networkWallet();
QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, priv );
priv->connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), priv, SLOT(kwalletWalletFound(QDBusPendingCallWatcher*)) );
}
else
{
// D-Bus is not reachable so none can tell us something about KWalletd
QDBusError err( QDBusError::NoServer, WritePasswordJobPrivate::tr("D-Bus is not running") );
priv->fallbackOnError( err );
}
}
void WritePasswordJobPrivate::scheduledStart() {
switch ( getKeyringBackend() ) {
case Backend_LibSecretKeyring: {
if ( !LibSecretKeyring::writePassword(service, key, service, mode,
data, this) ) {
q->emitFinishedWithError( OtherError, tr("Unknown error") );
}
} break;
case Backend_GnomeKeyring: {
QString type;
QByteArray password;
switch(mode) {
case JobPrivate::Text:
type = QLatin1String("plaintext");
password = data;
break;
default:
type = QLatin1String("base64");
password = data.toBase64();
break;
}
QByteArray service = q->service().toUtf8();
if ( !GnomeKeyring::store_network_password( GnomeKeyring::GNOME_KEYRING_DEFAULT,
service.constData(),
key.toUtf8().constData(),
service.constData(),
type.toUtf8().constData(),
password.constData(),
reinterpret_cast( &JobPrivate::gnomeKeyring_writeCb ),
this, 0 ) )
q->emitFinishedWithError( OtherError, tr("Unknown error") );
}
break;
case Backend_Kwallet4:
kwalletWritePasswordScheduledStart("org.kde.kwalletd", "/modules/kwalletd", this);
break;
case Backend_Kwallet5:
kwalletWritePasswordScheduledStart("org.kde.kwalletd5", "/modules/kwalletd5", this);
break;
}
}
void WritePasswordJobPrivate::fallbackOnError(const QDBusError &err)
{
if ( !q->insecureFallback() ) {
q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) );
return;
}
PlainTextStore plainTextStore( q->service(), q->settings() );
plainTextStore.write( key, data, mode );
if ( plainTextStore.error() != NoError )
q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() );
else
q->emitFinished();
}
void JobPrivate::gnomeKeyring_writeCb(int result, JobPrivate* self )
{
if ( result == GnomeKeyring::RESULT_OK ) {
self->q->emitFinished();
} else {
const QPair errorResult = mapGnomeKeyringError( result );
self->q->emitFinishedWithError( errorResult.first, errorResult.second );
}
}
void JobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) {
watcher->deleteLater();
QDBusPendingReply reply = *watcher;
if ( reply.isError() ) {
fallbackOnError( reply.error() );
return;
}
PlainTextStore plainTextStore( q->service(), q->settings() );
if ( plainTextStore.contains( key ) ) {
// If we had previously written to QSettings, but we now have a kwallet available, migrate and delete old insecure data
plainTextStore.remove( key );
}
const int handle = reply.value();
if ( handle < 0 ) {
q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") );
return;
}
QDBusPendingReply nextReply;
if ( mode == Text )
nextReply = iface->writePassword( handle, q->service(), key, QString::fromUtf8(data), q->service() );
else if ( mode == Binary )
nextReply = iface->writeEntry( handle, q->service(), key, data, 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(kwalletFinished(QDBusPendingCallWatcher*)) );
}
void JobPrivate::kwalletFinished( QDBusPendingCallWatcher* watcher ) {
if ( !watcher->isError() ) {
if ( mode == Binary ) {
QDBusPendingReply reply = *watcher;
if (reply.isValid()) {
data = reply.value();
}
} else {
QDBusPendingReply reply = *watcher;
if (reply.isValid()) {
data = reply.value().toUtf8();
}
}
}
q->emitFinished();
}
void DeletePasswordJobPrivate::scheduledStart() {
switch ( getKeyringBackend() ) {
case Backend_LibSecretKeyring: {
if ( !LibSecretKeyring::deletePassword(key, q->service(), this) ) {
q->emitFinishedWithError( OtherError, tr("Unknown error") );
}
} break;
case Backend_GnomeKeyring: {
if ( !GnomeKeyring::delete_network_password(
key.toUtf8().constData(), q->service().toUtf8().constData(),
reinterpret_cast( &JobPrivate::gnomeKeyring_writeCb ),
this, 0 ) )
q->emitFinishedWithError( OtherError, tr("Unknown error") );
}
break;
case Backend_Kwallet4:
kwalletWritePasswordScheduledStart("org.kde.kwalletd", "/modules/kwalletd", this);
break;
case Backend_Kwallet5:
kwalletWritePasswordScheduledStart("org.kde.kwalletd5", "/modules/kwalletd5", this);
break;
}
}
void DeletePasswordJobPrivate::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;
}
actual->remove( key );
actual->sync();
q->emitFinished();
q->emitFinished();
}
qtkeychain-0.10.0/cmake/ 0000755 0001750 0001750 00000000000 13576175767 013752 5 ustar hefee hefee qtkeychain-0.10.0/cmake/Modules/ 0000755 0001750 0001750 00000000000 13576175767 015362 5 ustar hefee hefee qtkeychain-0.10.0/cmake/Modules/ECMPackageConfigHelpers.cmake 0000644 0001750 0001750 00000020310 13576175767 022711 0 ustar hefee hefee #.rst:
# ECMPackageConfigHelpers
# -----------------------
#
# Helper macros for generating CMake package config files.
#
# ``write_basic_package_version_file()`` is the same as the one provided by the
# `CMakePackageConfigHelpers
# `_
# module in CMake; see that module's documentation for
# more information.
#
# ::
#
# ecm_configure_package_config_file(