[Pkg-owncloud-commits] [qtkeychain] 30/63: Extract PlainTextStore

Sandro Knauß hefee at debian.org
Sat Jun 10 14:39:29 UTC 2017


This is an automated email from the git hooks/post-receive script.

hefee pushed a commit to branch master
in repository qtkeychain.

commit d077333d7c4bb2846b9de9f3b8631a0b58f70a7e
Author: Mathias Hasselmann <mathias.hasselmann at kdab.com>
Date:   Wed Aug 10 21:23:21 2016 +0200

    Extract PlainTextStore
---
 CMakeLists.txt     |   7 +++-
 keychain_p.h       |   1 +
 keychain_unix.cpp  |  66 ++++++++++++--------------------
 keychain_win.cpp   |  45 +++++++---------------
 plaintextstore.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 plaintextstore_p.h |  47 +++++++++++++++++++++++
 6 files changed, 200 insertions(+), 76 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3201c81..167081e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -127,7 +127,10 @@ add_definitions( -Wall )
 
 if(WIN32)
     list(APPEND qtkeychain_SOURCES keychain_win.cpp)
-    list(APPEND qtkeychain_LIBRARIES crypt32)
+    if (!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 )
@@ -145,7 +148,7 @@ if(APPLE)
 endif()
 
 if(UNIX AND NOT APPLE AND NOT ANDROID)
-    list(APPEND qtkeychain_SOURCES keychain_unix.cpp gnomekeyring.cpp)
+    list(APPEND qtkeychain_SOURCES keychain_unix.cpp gnomekeyring.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()
diff --git a/keychain_p.h b/keychain_p.h
index f51b1db..d6a2f10 100644
--- a/keychain_p.h
+++ b/keychain_p.h
@@ -84,6 +84,7 @@ friend class Job;
 friend class JobExecutor;
 friend class ReadPasswordJob;
 friend class WritePasswordJob;
+friend class PlainTextStore;
 };
 
 class ReadPasswordJobPrivate : public JobPrivate {
diff --git a/keychain_unix.cpp b/keychain_unix.cpp
index a364a7c..d2e275d 100644
--- a/keychain_unix.cpp
+++ b/keychain_unix.cpp
@@ -8,23 +8,10 @@
  *****************************************************************************/
 #include "keychain_p.h"
 #include "gnomekeyring_p.h"
-
-#include <QSettings>
-
-#include <QScopedPointer>
+#include "plaintextstore_p.h"
 
 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_Kwallet4,
@@ -217,15 +204,16 @@ void JobPrivate::gnomeKeyring_readCb( int result, const char* string, JobPrivate
 
 void ReadPasswordJobPrivate::fallbackOnError(const QDBusError& err )
 {
-    QScopedPointer<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
-    QSettings* actual = q->settings() ? q->settings() : local.data();
-
-    if ( q->insecureFallback() && actual->contains( dataKey( key ) ) ) {
+    PlainTextStore plainTextStore( q->service(), q->settings() );
 
-        mode = JobPrivate::stringToMode( actual->value( typeKey( key ) ).toString() );
-        data = actual->value( dataKey( key ) ).toByteArray();
+    if ( q->insecureFallback() && plainTextStore.contains( key ) ) {
+        mode = plainTextStore.readMode( key );
+        data = plainTextStore.readData( key );
 
-        q->emitFinished();
+        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") );
@@ -238,21 +226,20 @@ void ReadPasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watch
     watcher->deleteLater();
     const QDBusPendingReply<int> reply = *watcher;
 
-    QScopedPointer<QSettings> 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 ) ) ) {
+    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 = actual->value( dataKey( key ) ).toByteArray();
-        const WritePasswordJobPrivate::Mode mode = WritePasswordJobPrivate::stringToMode( actual->value( typeKey( key ) ).toString() );
-        actual->remove( key );
+        data = plainTextStore.readData( key );
+        const WritePasswordJobPrivate::Mode mode = plainTextStore.readMode( key );
+        plainTextStore.remove( key );
 
         q->emitFinished();
 
@@ -404,19 +391,18 @@ void WritePasswordJobPrivate::scheduledStart() {
 
 void WritePasswordJobPrivate::fallbackOnError(const QDBusError &err)
 {
-    QScopedPointer<QSettings> 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->setValue( QString::fromLatin1( "%1/type" ).arg( key ), mode );
-    actual->setValue( QString::fromLatin1( "%1/data" ).arg( key ), data );
-    actual->sync();
+    PlainTextStore plainTextStore( q->service(), q->settings() );
+    plainTextStore.write( key, data, mode );
 
-    q->emitFinished();
+    if ( plainTextStore.error() != NoError )
+        q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() );
+    else
+        q->emitFinished();
 }
 
 void JobPrivate::gnomeKeyring_writeCb(int result, JobPrivate* self )
@@ -433,19 +419,15 @@ void JobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) {
     watcher->deleteLater();
     QDBusPendingReply<int> reply = *watcher;
 
-    QScopedPointer<QSettings> 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 ) )
-    {
+    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
-        actual->remove( key );
-        actual->sync();
+        plainTextStore.remove( key );
     }
 
     const int handle = reply.value();
diff --git a/keychain_win.cpp b/keychain_win.cpp
index 4edd92e..03e36d6 100644
--- a/keychain_win.cpp
+++ b/keychain_win.cpp
@@ -7,8 +7,7 @@
  * details, check the accompanying file 'COPYING'.                            *
  *****************************************************************************/
 #include "keychain_p.h"
-
-#include <QSettings>
+#include "plaintextstore_p.h"
 
 #include <windows.h>
 #include <wincrypt.h>
@@ -22,8 +21,6 @@ using namespace QKeychain;
 
 void ReadPasswordJobPrivate::scheduledStart() {
     LPCWSTR name = (LPCWSTR)key.utf16();
-    //Use settings member if there, create local settings object if not
-    std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
     PCREDENTIALW cred;
 
     if (!CredReadW(name, CRED_TYPE_GENERIC, 0, &cred)) {
@@ -94,13 +91,10 @@ void DeletePasswordJobPrivate::scheduledStart() {
 }
 #else
 void ReadPasswordJobPrivate::scheduledStart() {
-    //Use settings member if there, create local settings object if not
-    std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
-    QSettings* actual = q->settings() ? q->settings() : local.get();
-
-    QByteArray encrypted = actual->value( key ).toByteArray();
-    if ( encrypted.isNull() ) {
-        q->emitFinishedWithError( EntryNotFound, tr("Entry not found") );
+    PlainTextStore plainTextStore( q->service(), q->settings() );
+    QByteArray encrypted = plainTextStore.readData( key );
+    if ( plainTextStore.error() != NoError ) {
+        q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() );
         return;
     }
 
@@ -147,17 +141,10 @@ void WritePasswordJobPrivate::scheduledStart() {
     const QByteArray encrypted( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
     LocalFree( blob_out.pbData );
 
-    //Use settings member if there, create local settings object if not
-    std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
-    QSettings* actual = q->settings() ? q->settings() : local.get();
-    actual->setValue( key, encrypted );
-    actual->sync();
-    if ( actual->status() != QSettings::NoError ) {
-
-        const QString errorString = actual->status() == QSettings::AccessError
-                ? tr("Could not store encrypted data in settings: access error")
-                : tr("Could not store encrypted data in settings: format error");
-        q->emitFinishedWithError( OtherError, errorString );
+    PlainTextStore plainTextStore( q->service(), q->settings() );
+    plainTextStore.write( key, encrypted, Binary );
+    if ( plainTextStore.error() != NoError ) {
+        q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() );
         return;
     }
 
@@ -165,16 +152,10 @@ void WritePasswordJobPrivate::scheduledStart() {
 }
 
 void DeletePasswordJobPrivate::scheduledStart() {
-    //Use settings member if there, create local settings object if not
-    std::auto_ptr<QSettings> local( !q->settings() ? new QSettings( q->service() ) : 0 );
-    QSettings* actual = q->settings() ? q->settings() : local.get();
-    actual->remove( key );
-    actual->sync();
-    if ( actual->status() != QSettings::NoError ) {
-        const QString err = actual->status() == QSettings::AccessError
-                ? tr("Could not delete encrypted data from settings: access error")
-                : tr("Could not delete encrypted data from settings: format error");
-        q->emitFinishedWithError( OtherError, err );
+    PlainTextStore plainTextStore( q->service(), q->settings() );
+    plainTextStore.remove( key );
+    if ( plainTextStore.error() != NoError ) {
+        q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() );
     } else {
         q->emitFinished();
     }
diff --git a/plaintextstore.cpp b/plaintextstore.cpp
new file mode 100644
index 0000000..b9d0272
--- /dev/null
+++ b/plaintextstore.cpp
@@ -0,0 +1,110 @@
+/******************************************************************************
+ *   Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld at gmail.com>      *
+ *   Copyright (C) 2016 Mathias Hasselmann <mathias.hasselmann at kdab.com>      *
+ *                                                                            *
+ * 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 "plaintextstore_p.h"
+
+using namespace QKeychain;
+
+namespace {
+#ifdef Q_OS_WIN
+inline QString dataKey(const QString &key) { return key; }
+#else // Q_OS_WIN
+inline QString dataKey(const QString &key) { return key + QLatin1String("/data"); }
+inline QString typeKey(const QString &key) { return key + QLatin1String("/type"); }
+#endif // Q_OS_WIN
+}
+
+
+PlainTextStore::PlainTextStore(const QString &service, QSettings *settings)
+    : m_localSettings(settings ? 0 : new QSettings(service))
+    , m_actualSettings(settings ? settings : m_localSettings.data())
+    , m_error(NoError)
+{
+}
+
+bool PlainTextStore::contains(const QString &key) const
+{
+    return m_actualSettings->contains(dataKey(key));
+}
+
+QByteArray PlainTextStore::readData(const QString &key)
+{
+    return read(dataKey(key)).toByteArray();
+}
+
+#ifndef Q_OS_WIN
+
+JobPrivate::Mode PlainTextStore::readMode(const QString &key)
+{
+    return JobPrivate::stringToMode(read(typeKey(key)).toString());
+}
+
+#endif // Q_OS_WIN
+
+void PlainTextStore::write(const QString &key, const QByteArray &data, JobPrivate::Mode mode)
+{
+    if (m_actualSettings->status() != QSettings::NoError)
+        return;
+
+#ifndef Q_OS_WIN
+    m_actualSettings->setValue(typeKey(key), JobPrivate::modeToString(mode));
+#else // Q_OS_WIN
+    Q_UNUSED(mode);
+#endif // Q_OS_WIN
+    m_actualSettings->setValue(dataKey(key), data);
+    m_actualSettings->sync();
+
+    if (m_actualSettings->status() == QSettings::AccessError) {
+        setError(AccessDenied, tr("Could not store data in settings: access error"));
+    } else if (m_actualSettings->status() != QSettings::NoError) {
+        setError(OtherError, tr("Could not store data in settings: format error"));
+    } else {
+        setError(NoError, QString());
+    }
+}
+
+void PlainTextStore::remove(const QString &key)
+{
+    if (m_actualSettings->status() != QSettings::NoError)
+        return;
+
+#ifndef Q_OS_WIN
+    m_actualSettings->remove(typeKey(key));
+#endif // Q_OS_WIN
+    m_actualSettings->remove(dataKey(key));
+    m_actualSettings->sync();
+
+    if (m_actualSettings->status() == QSettings::AccessError) {
+        setError(AccessDenied, tr("Could not delete data from settings: access error"));
+    } else if (m_actualSettings->status() != QSettings::NoError) {
+        setError(OtherError, tr("Could not delete data from settings: format error"));
+    } else {
+        setError(NoError, QString());
+    }
+}
+
+void PlainTextStore::setError(Error error, const QString &errorString)
+{
+    m_error = error;
+    m_errorString = errorString;
+}
+
+QVariant PlainTextStore::read(const QString &key)
+{
+    const QVariant value = m_actualSettings->value(key);
+
+    if (value.isNull()) {
+        setError(EntryNotFound, tr("Entry not found"));
+    } else {
+        setError(NoError, QString());
+    }
+
+    return value;
+}
diff --git a/plaintextstore_p.h b/plaintextstore_p.h
new file mode 100644
index 0000000..7ec05aa
--- /dev/null
+++ b/plaintextstore_p.h
@@ -0,0 +1,47 @@
+/******************************************************************************
+ *   Copyright (C) 2011-2015 Frank Osterfeld <frank.osterfeld at gmail.com>      *
+ *   Copyright (C) 2016 Mathias Hasselmann <mathias.hasselmann at kdab.com>      *
+ *                                                                            *
+ * 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 QTKEYCHAIN_PLAINTEXTSTORE_P_H
+#define QTKEYCHAIN_PLAINTEXTSTORE_P_H
+
+#include "keychain_p.h"
+
+namespace QKeychain {
+
+class PlainTextStore {
+    Q_DECLARE_TR_FUNCTIONS(QKeychain::PlainTextStore)
+
+public:
+    explicit PlainTextStore(const QString &service, QSettings *settings);
+
+    Error error() const { return m_error; }
+    QString errorString() const { return m_errorString; }
+
+    bool contains(const QString &key) const;
+
+    QByteArray readData(const QString &key);
+    JobPrivate::Mode readMode(const QString &key);
+
+    void write(const QString &key, const QByteArray &data, JobPrivate::Mode mode);
+    void remove(const QString &key);
+
+private:
+    void setError(Error error, const QString &errorString);
+    QVariant read(const QString &key);
+
+    const QScopedPointer<QSettings> m_localSettings;
+    QSettings *const m_actualSettings;
+    QString m_errorString;
+    Error m_error;
+};
+
+}
+
+#endif // QTKEYCHAIN_PLAINTEXTSTORE_P_H

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/qtkeychain.git



More information about the Pkg-owncloud-commits mailing list