Revision: 28552
          http://sourceforge.net/p/bibdesk/svn/28552
Author:   hofman
Date:     2024-01-05 18:47:56 +0000 (Fri, 05 Jan 2024)
Log Message:
-----------
use CFMutableDictionary for query and attributes for security access

Modified Paths:
--------------
    trunk/bibdesk/BDSKPasswordController.m

Modified: trunk/bibdesk/BDSKPasswordController.m
===================================================================
--- trunk/bibdesk/BDSKPasswordController.m      2024-01-05 18:06:57 UTC (rev 
28551)
+++ trunk/bibdesk/BDSKPasswordController.m      2024-01-05 18:47:56 UTC (rev 
28552)
@@ -56,28 +56,33 @@
     NSString *passwordString = nil;
     CFTypeRef passwordData = nil;
     OSStatus err;
-    NSMutableDictionary *query = [NSMutableDictionary dictionary];
+    CFMutableDictionaryRef query = 
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     
-    [query setObject:(NSString *)kSecClassGenericPassword forKey:(__bridge 
NSString *)kSecClass];
-    [query setObject:@YES forKey:(__bridge NSString *)kSecReturnData];
-    [query setObject:service forKey:(__bridge NSString *)kSecAttrService];
+    CFDictionarySetValue(query, kSecClass, kSecClassGenericPassword);
+    CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
+    CFDictionarySetValue(query, kSecAttrService, (__bridge 
CFStringRef)service);
     if (account)
-        [query setObject:account forKey:(__bridge NSString *)kSecAttrAccount];
+        CFDictionarySetValue(query, kSecAttrAccount, (__bridge 
CFStringRef)account);
     
     // see if the password exists in the keychain
-    err = SecItemCopyMatching((__bridge CFDictionaryRef)query, &passwordData);
+    err = SecItemCopyMatching(query, &passwordData);
     if (err == errSecItemNotFound && name) {
         // see if an item in the old format exists
-        [query setObject:name forKey:(__bridge NSString *)kSecAttrService];
-        [query removeObjectForKey:(__bridge NSString *)kSecAttrAccount];
-        err = SecItemCopyMatching((__bridge CFDictionaryRef)query, 
&passwordData);
+        CFDictionarySetValue(query, kSecAttrService, (__bridge 
CFStringRef)name);
+        CFDictionaryRemoveValue(query, kSecAttrAccount);
+        err = SecItemCopyMatching(query, &passwordData);
         if (err == errSecSuccess) {
             // item in old format exists, update to new format
-            NSDictionary *attributes = [NSDictionary 
dictionaryWithObjectsAndKeys:service, (__bridge NSString *)kSecAttrService, 
account ?: [NSUserName() dataUsingEncoding:NSUTF8StringEncoding], (__bridge 
NSString *)kSecAttrAccount, name, (__bridge NSString *)kSecAttrLabel, nil];
-            [query removeObjectForKey:(__bridge NSString *)kSecReturnData];
-            SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge 
CFDictionaryRef)attributes);
+            CFMutableDictionaryRef attributes = 
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+            CFDictionarySetValue(attributes, kSecAttrService, (__bridge 
CFStringRef)service);
+            CFDictionarySetValue(attributes, kSecAttrAccount, (__bridge 
CFStringRef)(account ?: NSUserName()));
+            CFDictionarySetValue(attributes, kSecAttrLabel, (__bridge 
CFStringRef)name);
+            CFDictionaryRemoveValue(query, kSecReturnData);
+            SecItemUpdate(query, attributes);
+            CFRelease(attributes);
         }
     }
+    CFRelease(query);
     
     if (err == errSecSuccess) {
         passwordString = [[[NSString alloc] 
initWithData:CFBridgingRelease(passwordData) encoding:NSUTF8StringEncoding] 
autorelease];
@@ -90,33 +95,33 @@
 
 + (BOOL)addOrModifyPassword:(NSString *)password forKeychainService:(NSString 
*)service account:(NSString *)account name:(NSString *)name {
     OSStatus err;
-    NSMutableDictionary *query = [NSMutableDictionary dictionary];
-    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
+    CFMutableDictionaryRef query = 
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFMutableDictionaryRef attributes = 
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     
     // first try to update an existing item
-    [query setObject:(__bridge NSString *)kSecClassGenericPassword 
forKey:(__bridge NSString *)kSecClass];
-    [query setObject:service forKey:(__bridge NSString *)kSecAttrService];
+    CFDictionarySetValue(query, kSecClass, kSecClassGenericPassword);
+    CFDictionarySetValue(query, kSecAttrService, (__bridge 
CFStringRef)service);
     if (account)
-        [query setObject:account forKey:(__bridge NSString *)kSecAttrAccount];
+        CFDictionarySetValue(query, kSecAttrAccount, (__bridge 
CFStringRef)account);
     
-    [attributes setObject:[password dataUsingEncoding:NSUTF8StringEncoding] 
forKey:(__bridge NSString *)kSecValueData];
+    CFDictionarySetValue(attributes, kSecValueData, (__bridge 
CFDataRef)[password dataUsingEncoding:NSUTF8StringEncoding]);
     
-    err = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge 
CFDictionaryRef)attributes);
+    err = SecItemUpdate(query, attributes);
     
     logError(@"updating", err);
     
     if (err == errSecItemNotFound) {
-        [attributes setObject:service forKey:(__bridge NSString 
*)kSecAttrService];
-        [attributes setObject:account ?: [NSUserName() 
dataUsingEncoding:NSUTF8StringEncoding] forKey:(__bridge NSString 
*)kSecAttrAccount];
+        CFDictionarySetValue(attributes, kSecAttrService, (__bridge 
CFStringRef)service);
+        CFDictionarySetValue(attributes, kSecAttrAccount, (__bridge 
CFStringRef)(account ?: NSUserName()));
         
         if (name) {
             // see if an item in the old format exists
-            [attributes setObject:name forKey:(__bridge NSString 
*)kSecAttrLabel];
+            CFDictionarySetValue(attributes, kSecAttrLabel, (__bridge 
CFStringRef)name);
             
-            [query setObject:name forKey:(__bridge NSString *)kSecAttrService];
-            [query removeObjectForKey:(__bridge NSString *)kSecAttrAccount];
+            CFDictionarySetValue(query, kSecAttrService, (__bridge 
CFStringRef)name);
+            CFDictionaryRemoveValue(query, kSecAttrAccount);
             
-            err = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge 
CFDictionaryRef)attributes);
+            err = SecItemUpdate(query, attributes);
             
             logError(@"updating", err);
         }
@@ -123,13 +128,15 @@
         
         if (err == errSecItemNotFound) {
             // password not yet on keychain, so add it
-            [attributes setObject:(__bridge NSString 
*)kSecClassGenericPassword forKey:(__bridge NSString *)kSecClass];
+            CFDictionarySetValue(attributes, kSecClass, 
kSecClassGenericPassword);
             
-            err = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL);
+            err = SecItemAdd(attributes, NULL);
             
             logError(@"adding", err);
         }
     }
+    CFRelease(query);
+    CFRelease(attributes);
     
     return (err == errSecSuccess);
 }
@@ -138,18 +145,18 @@
     // use the service name to get password from keychain and hash it with 
sha1 for comparison purposes
     NSString *passwordString = nil;
     CFTypeRef passwordData = nil;
+    CFMutableDictionaryRef query = 
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     OSStatus err;
-    NSMutableDictionary *query = [NSMutableDictionary dictionary];
     
-    [query setObject:(__bridge NSString *)kSecClassInternetPassword 
forKey:(__bridge NSString *)kSecClass];
-    [query setObject:@YES forKey:(__bridge NSString *)kSecReturnData];
-    [query setObject:server forKey:(__bridge NSString *)kSecAttrServer];
-    [query setObject:account forKey:(__bridge NSString *)kSecAttrAccount];
+    CFDictionarySetValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
+    CFDictionarySetValue(query, kSecAttrServer, (__bridge CFStringRef)server);
+    CFDictionarySetValue(query, kSecAttrAccount, (__bridge 
CFStringRef)account);
     if (port != 0)
-        [query setObject:[NSNumber numberWithInteger:port] forKey:(__bridge 
NSString *)kSecAttrPort];
+        CFDictionarySetValue(query, kSecAttrPort, (__bridge 
CFNumberRef)[NSNumber numberWithInteger:port]);
     
     // see if the password exists in the keychain
-    err = SecItemCopyMatching((__bridge CFDictionaryRef)query, &passwordData);
+    err = SecItemCopyMatching(query, &passwordData);
     
     if (err == errSecSuccess) {
         passwordString = [[[NSString alloc] 
initWithData:CFBridgingRelease(passwordData) encoding:NSUTF8StringEncoding] 
autorelease];
@@ -156,6 +163,7 @@
     } else {
         logError(@"getting", err);
     }
+    CFRelease(query);
     
     return passwordString;
 }
@@ -162,32 +170,38 @@
 
 + (BOOL)addOrModifyPassword:(NSString *)password forKeychainServer:(NSString 
*)server port:(NSInteger)port account:(NSString *)account {
     OSStatus err;
-    NSMutableDictionary *query = [NSMutableDictionary dictionary];
-    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
+    CFMutableDictionaryRef query = 
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFMutableDictionaryRef attributes = 
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, 
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     
     // first try to update an existing item
-    [query setObject:(__bridge NSString *)kSecClassInternetPassword 
forKey:(__bridge NSString *)kSecClass];
-    [query setObject:server forKey:(__bridge NSString *)kSecAttrServer];
-    [query setObject:account forKey:(__bridge NSString *)kSecAttrAccount];
+    CFDictionarySetValue(query, kSecClass, kSecClassInternetPassword);
+    CFDictionarySetValue(query, kSecAttrServer, (__bridge CFStringRef)server);
+    CFDictionarySetValue(query, kSecAttrAccount, (__bridge 
CFStringRef)account);
     if (port != 0)
-        [query setObject:[NSNumber numberWithInteger:port] forKey:(__bridge 
NSString *)kSecAttrPort];
-
-    [attributes setObject:[password dataUsingEncoding:NSUTF8StringEncoding] 
forKey:(__bridge NSString *)kSecValueData];
+        CFDictionarySetValue(query, kSecAttrPort, (__bridge 
CFNumberRef)[NSNumber numberWithInteger:port]);
     
-    err = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge 
CFDictionaryRef)attributes);
+    CFDictionarySetValue(attributes, kSecValueData, (__bridge 
CFDataRef)[password dataUsingEncoding:NSUTF8StringEncoding]);
     
+    err = SecItemUpdate(query, attributes);
+    
     logError(@"updating", err);
     
     if (err == errSecItemNotFound) {
         // password not yet on keychain, so add it
-        [attributes addEntriesFromDictionary:query];
-        [attributes setObject:(__bridge NSString *)kSecAttrProtocolHTTPS 
forKey:(__bridge NSString *)kSecAttrProtocol];
-        [attributes setObject:[NSNumber numberWithUnsignedInt:'BDsg'] 
forKey:(__bridge NSString *)kSecAttrType];
+        CFDictionarySetValue(attributes, kSecClass, kSecClassInternetPassword);
+        CFDictionarySetValue(attributes, kSecAttrServer, (__bridge 
CFStringRef)server);
+        CFDictionarySetValue(attributes, kSecAttrAccount, (__bridge 
CFStringRef)account);
+        if (port != 0)
+            CFDictionarySetValue(attributes, kSecAttrPort, (__bridge 
CFNumberRef)[NSNumber numberWithInteger:port]);
+        CFDictionarySetValue(attributes, kSecAttrProtocol, 
kSecAttrProtocolHTTPS);
+        CFDictionarySetValue(attributes, kSecAttrType, (__bridge 
CFNumberRef)[NSNumber numberWithUnsignedInt:'BDsg']);
         
-        err = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL);
+        err = SecItemAdd(attributes, NULL);
         
         logError(@"adding", err);
     }
+    CFRelease(query);
+    CFRelease(attributes);
     
     return (err == errSecSuccess);
 }

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to