[Pkg-owncloud-commits] [qtkeychain] 43/63: Add iOS support

Sandro Knauß hefee at debian.org
Sat Jun 10 14:39:31 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 f7d6700f80bcfbcb57f5647d8b58f65b2ca7d881
Author: Mathias Hasselmann <mathias.hasselmann at kdab.com>
Date:   Thu Nov 10 23:34:13 2016 +0100

    Add iOS support
---
 CMakeLists.txt  |   6 ++-
 keychain_ios.mm | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 151 insertions(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 167081e..6ac5b88 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -138,7 +138,11 @@ if(WIN32)
 endif()
 
 if(APPLE)
-    list(APPEND qtkeychain_SOURCES keychain_mac.cpp)
+    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})
diff --git a/keychain_ios.mm b/keychain_ios.mm
new file mode 100644
index 0000000..0e2829f
--- /dev/null
+++ b/keychain_ios.mm
@@ -0,0 +1,146 @@
+/******************************************************************************
+ *   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 "keychain_p.h"
+
+#import <Foundation/Foundation.h>
+#import <Security/Security.h>
+
+using namespace QKeychain;
+
+struct ErrorDescription
+{
+    QKeychain::Error code;
+    QString message;
+
+    ErrorDescription(QKeychain::Error code, const QString &message)
+        : code(code), message(message) {}
+
+    static ErrorDescription fromStatus(OSStatus status)
+    {
+        switch(status) {
+        case errSecSuccess:
+            return ErrorDescription(QKeychain::NoError, Job::tr("No error"));
+        case errSecItemNotFound:
+            return ErrorDescription(QKeychain::EntryNotFound, Job::tr("The specified item could not be found in the keychain"));
+        case errSecUserCanceled:
+            return ErrorDescription(QKeychain::AccessDeniedByUser, Job::tr("User canceled the operation"));
+        case errSecInteractionNotAllowed:
+            return ErrorDescription(QKeychain::AccessDenied, Job::tr("User interaction is not allowed"));
+        case errSecNotAvailable:
+            return ErrorDescription(QKeychain::AccessDenied, Job::tr("No keychain is available. You may need to restart your computer"));
+        case errSecAuthFailed:
+            return ErrorDescription(QKeychain::AccessDenied, Job::tr("The user name or passphrase you entered is not correct"));
+        case errSecVerifyFailed:
+            return ErrorDescription(QKeychain::AccessDenied, Job::tr("A cryptographic verification failure has occurred"));
+        case errSecUnimplemented:
+            return ErrorDescription(QKeychain::NotImplemented, Job::tr("Function or operation not implemented"));
+        case errSecIO:
+            return ErrorDescription(QKeychain::OtherError, Job::tr("I/O error"));
+        case errSecOpWr:
+            return ErrorDescription(QKeychain::OtherError, Job::tr("Already open with with write permission"));
+        case errSecParam:
+            return ErrorDescription(QKeychain::OtherError, Job::tr("Invalid parameters passed to a function"));
+        case errSecAllocate:
+            return ErrorDescription(QKeychain::OtherError, Job::tr("Failed to allocate memory"));
+        case errSecBadReq:
+            return ErrorDescription(QKeychain::OtherError, Job::tr("Bad parameter or invalid state for operation"));
+        case errSecInternalComponent:
+            return ErrorDescription(QKeychain::OtherError, Job::tr("An internal component failed"));
+        case errSecDuplicateItem:
+            return ErrorDescription(QKeychain::OtherError, Job::tr("The specified item already exists in the keychain"));
+        case errSecDecode:
+            return ErrorDescription(QKeychain::OtherError, Job::tr("Unable to decode the provided data"));
+        }
+
+        return ErrorDescription(QKeychain::OtherError, Job::tr("Unknown error"));
+    }
+};
+
+void ReadPasswordJobPrivate::scheduledStart()
+{
+    NSDictionary *const query = @{
+        (__bridge id) kSecClass: (__bridge id) kSecClassGenericPassword,
+            (__bridge id) kSecAttrService: (__bridge NSString *) service.toCFString(),
+            (__bridge id) kSecAttrAccount: (__bridge NSString *) key.toCFString(),
+            (__bridge id) kSecReturnData: @YES,
+    };
+
+    CFTypeRef dataRef = nil;
+    const OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef) query, &dataRef);
+
+    data.clear();
+    mode = Binary;
+
+    if (status == errSecSuccess) {
+        if (dataRef)
+            data = QByteArray::fromCFData((CFDataRef) dataRef);
+
+        q->emitFinished();
+    } else {
+        const ErrorDescription error = ErrorDescription::fromStatus(status);
+        q->emitFinishedWithError(error.code, Job::tr("Could not retreive private key from keystore: %1").arg(error.message));
+    }
+
+    if (dataRef)
+        [dataRef release];
+}
+
+void WritePasswordJobPrivate::scheduledStart()
+{
+    NSDictionary *const query = @{
+            (__bridge id) kSecClass: (__bridge id) kSecClassGenericPassword,
+            (__bridge id) kSecAttrService: (__bridge NSString *) service.toCFString(),
+            (__bridge id) kSecAttrAccount: (__bridge NSString *) key.toCFString(),
+    };
+
+    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef) query, nil);
+
+    if (status == errSecSuccess) {
+        NSDictionary *const update = @{
+                (__bridge id) kSecValueData: (__bridge NSData *) data.toCFData(),
+        };
+
+        status = SecItemUpdate((__bridge CFDictionaryRef) query, (__bridge CFDictionaryRef) update);
+    } else {
+        NSDictionary *const insert = @{
+                (__bridge id) kSecClass: (__bridge id) kSecClassGenericPassword,
+                (__bridge id) kSecAttrService: (__bridge NSString *) service.toCFString(),
+                (__bridge id) kSecAttrAccount: (__bridge NSString *) key.toCFString(),
+                (__bridge id) kSecValueData: (__bridge NSData *) data.toCFData(),
+        };
+
+        status = SecItemAdd((__bridge CFDictionaryRef) insert, nil);
+    }
+
+    if (status == errSecSuccess) {
+        q->emitFinished();
+    } else {
+        const ErrorDescription error = ErrorDescription::fromStatus(status);
+        q->emitFinishedWithError(error.code,  tr("Could not store data in settings: %1").arg(error.message));
+    }
+}
+
+void DeletePasswordJobPrivate::scheduledStart()
+{
+    const NSDictionary *const query = @{
+            (__bridge id) kSecClass: (__bridge id) kSecClassGenericPassword,
+            (__bridge id) kSecAttrService: (__bridge NSString *) service.toCFString(),
+            (__bridge id) kSecAttrAccount: (__bridge NSString *) key.toCFString(),
+    };
+
+    const OSStatus status = SecItemDelete((__bridge CFDictionaryRef) query);
+
+    if (status == errSecSuccess) {
+        q->emitFinished();
+    } else {
+        const ErrorDescription error = ErrorDescription::fromStatus(status);
+        q->emitFinishedWithError(error.code, Job::tr("Could not remove private key from keystore: %1").arg(error.message));
+    }
+}

-- 
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