]> git.saurik.com Git - apple/security.git/blobdiff - sec/securityd/Regressions/SOSAccountTesting.h
Security-55471.tar.gz
[apple/security.git] / sec / securityd / Regressions / SOSAccountTesting.h
diff --git a/sec/securityd/Regressions/SOSAccountTesting.h b/sec/securityd/Regressions/SOSAccountTesting.h
new file mode 100644 (file)
index 0000000..00c1ec1
--- /dev/null
@@ -0,0 +1,254 @@
+//
+//  SOSAccountTesting.h
+//  sec
+//
+//  Created by Mitch Adler on 6/18/13.
+//
+//
+
+#ifndef SEC_SOSAccountTesting_h
+#define SEC_SOSAccountTesting_h
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <SecureObjectSync/SOSAccount.h>
+
+//
+// Account comparison
+//
+
+#define kAccountsAgreeTestMin 9
+#define kAccountsAgreeTestPerPeer 1
+#define accountsAgree(x) (kAccountsAgreeTestMin + kAccountsAgreeTestPerPeer * (x))
+
+static void unretired_peers_is_subset(const char* label, CFArrayRef peers, CFArrayRef allowed_peers)
+{
+    CFArrayForEach(peers, ^(const void *value) {
+        SOSPeerInfoRef pi = (SOSPeerInfoRef) value;
+        CFErrorRef leftError = NULL;
+        CFErrorRef rightError = NULL;
+        
+        ok(SOSPeerInfoIsRetirementTicket(pi) || SOSPeerInfoIsCloudIdentity(pi) || CFArrayContainsValue(allowed_peers, CFRangeMake(0, CFArrayGetCount(allowed_peers)), pi), "Peer is allowed (%s) Peer: %@, Allowed %@", label, pi, allowed_peers);
+        
+        CFReleaseNull(leftError);
+        CFReleaseNull(rightError);
+    });
+}
+
+static void accounts_agree_internal(char *label, SOSAccountRef left, SOSAccountRef right, bool check_peers)
+{
+    CFErrorRef error = NULL;
+    {
+        CFArrayRef leftPeers = SOSAccountCopyActivePeers(left, &error);
+        ok(leftPeers, "Left peers (%@) - %s", error, label);
+        CFReleaseNull(error);
+
+        CFArrayRef rightPeers = SOSAccountCopyActivePeers(right, &error);
+        ok(rightPeers, "Right peers (%@) - %s", error, label);
+        CFReleaseNull(error);
+
+        ok(CFEqual(leftPeers, rightPeers), "Matching peers (%s) Left: %@, Right: %@", label, leftPeers, rightPeers);
+
+        if (check_peers) {
+            CFMutableArrayRef allowed_identities = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+
+            CFArrayRef leftIdentities = SOSAccountCopyAccountIdentityPeerInfos(left, kCFAllocatorDefault, &error);
+            ok(leftIdentities, "Get identities (%@)", error);
+            CFReleaseNull(error);
+            
+            CFArrayAppendArray(allowed_identities, leftIdentities, CFRangeMake(0, CFArrayGetCount(leftIdentities)));
+            
+            CFReleaseNull(leftIdentities);
+            
+            CFArrayRef rightIdentities = SOSAccountCopyAccountIdentityPeerInfos(right, kCFAllocatorDefault, &error);
+            ok(rightIdentities, "Get identities (%@)", error);
+            CFReleaseNull(error);
+            
+            CFArrayAppendArray(allowed_identities, rightIdentities, CFRangeMake(0, CFArrayGetCount(rightIdentities)));
+            
+            CFReleaseNull(rightIdentities);
+
+            unretired_peers_is_subset(label, leftPeers, allowed_identities);
+        }
+
+        CFReleaseNull(leftPeers);
+        CFReleaseNull(rightPeers);
+    }
+    {
+        CFArrayRef leftConcurringPeers = SOSAccountCopyConcurringPeers(left, &error);
+        ok(leftConcurringPeers, "Left peers (%@) - %s", error, label);
+
+        CFArrayRef rightConcurringPeers = SOSAccountCopyConcurringPeers(right, &error);
+        ok(rightConcurringPeers, "Right peers (%@) - %s", error, label);
+
+        ok(CFEqual(leftConcurringPeers, rightConcurringPeers), "Matching concurring peers Left: %@, Right: %@", leftConcurringPeers, rightConcurringPeers);
+
+        CFReleaseNull(leftConcurringPeers);
+        CFReleaseNull(rightConcurringPeers);
+    }
+    {
+        CFArrayRef leftApplicants = SOSAccountCopyApplicants(left, &error);
+        ok(leftApplicants, "Left Applicants (%@) - %s", error, label);
+
+        CFArrayRef rightApplicants = SOSAccountCopyApplicants(right, &error);
+        ok(rightApplicants, "Left Applicants (%@) - %s", error, label);
+
+        ok(CFEqual(leftApplicants, rightApplicants), "Matching applicants (%s) Left: %@, Right: %@", label, leftApplicants, rightApplicants);
+
+        CFReleaseNull(leftApplicants);
+        CFReleaseNull(rightApplicants);
+    }
+}
+
+static inline void accounts_agree(char *label, SOSAccountRef left, SOSAccountRef right)
+{
+    accounts_agree_internal(label, left, right, true);
+}
+
+
+//
+// Change handling
+//
+
+static CFMutableDictionaryRef ExtractPendingChanges(CFMutableDictionaryRef changes)
+{
+    CFMutableDictionaryRef extracted = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, changes);
+
+    CFDictionaryRemoveAllValues(changes);
+
+    return extracted;
+}
+
+#define kFeedChangesToMultieTestCountPer 1
+static inline void FeedChangesToMulti(CFMutableDictionaryRef changes, ...)
+{
+    CFDictionaryRef changes_to_send = ExtractPendingChanges(changes);
+
+    SOSAccountRef account;
+
+    secerror("Change block: %@", changes_to_send);
+
+    CFErrorRef error = NULL;
+       va_list argp;
+       va_start(argp, changes);
+    while((account = va_arg(argp, SOSAccountRef)) != NULL) {
+        ok(SOSAccountHandleUpdates(account, changes_to_send, &error), "SOSAccountHandleUpdates failed (%@)", error);
+        CFReleaseNull(error);
+    }
+}
+
+static inline void InjectChangeToMulti(CFStringRef changeKey, CFStringRef changeValue, ...)
+{
+    CFMutableDictionaryRef changes_to_send = CFDictionaryCreateMutable(NULL, 1, NULL, NULL);
+    CFDictionaryAddValue(changes_to_send, changeKey, changeValue);
+    
+    SOSAccountRef account;
+    
+    secerror("Change block: %@", changes_to_send);
+    
+    CFErrorRef error = NULL;
+       va_list argp;
+       va_start(argp, changeValue);
+    while((account = va_arg(argp, SOSAccountRef)) != NULL) {
+        ok(SOSAccountHandleUpdates(account, changes_to_send, &error), "SOSAccountHandleUpdates failed (%@)", error);
+        CFReleaseNull(error);
+    }
+    CFReleaseNull(changes_to_send);
+}
+
+
+
+#define kFeedChangesToTestCount 1
+static inline void FeedChangesTo(CFMutableDictionaryRef changes, SOSAccountRef account)
+{
+    CFDictionaryRef changes_to_send = ExtractPendingChanges(changes);
+
+    secerror("Change block: %@", changes_to_send);
+
+    CFErrorRef error = NULL;
+    ok(SOSAccountHandleUpdates(account, changes_to_send, &error), "SOSAccountHandleUpdates failed (%@)", error);
+    CFReleaseNull(error);
+    CFReleaseNull(changes_to_send);
+}
+
+
+static SOSAccountRef CreateAccountForLocalChanges(CFMutableDictionaryRef changes, CFStringRef name, CFStringRef data_source_name)
+{
+    SOSAccountKeyInterestBlock interest_block = ^(bool getNewKeysOnly, CFArrayRef alwaysKeys, CFArrayRef afterFirstUnlockKeys, CFArrayRef unlockedKeys) {};
+    SOSAccountDataUpdateBlock update_block = ^ bool (CFDictionaryRef keys, CFErrorRef *error) {
+        CFDictionaryForEach(keys, ^(const void *key, const void *value) {
+            CFDictionarySetValue(changes, key, value);
+        });
+        return true;
+    };
+
+    SOSDataSourceFactoryRef factory = SOSTestDataSourceFactoryCreate();
+    SOSTestDataSourceFactoryAddDataSource(factory, data_source_name, SOSTestDataSourceCreate());
+
+    CFDictionaryRef gestalt = SOSCreatePeerGestaltFromName(name);
+
+    SOSAccountRef result = SOSAccountCreate(kCFAllocatorDefault, gestalt, factory, interest_block, update_block);
+
+    CFReleaseNull(gestalt);
+
+    return result;
+}
+
+
+static inline int countPeers(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+    
+    peers = SOSAccountCopyPeers(account, &error);
+    int retval = (int) CFArrayGetCount(peers);
+    CFReleaseNull(error);
+    CFReleaseNull(peers);
+    return retval;
+}
+
+static inline int countActivePeers(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+    
+    peers = SOSAccountCopyActivePeers(account, &error);
+    int retval = (int) CFArrayGetCount(peers);
+    CFReleaseNull(error);
+    CFReleaseNull(peers);
+    return retval;
+}
+
+static inline int countActiveValidPeers(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+    
+    peers = SOSAccountCopyActiveValidPeers(account, &error);
+    int retval = (int) CFArrayGetCount(peers);
+    CFReleaseNull(error);
+    CFReleaseNull(peers);
+    return retval;
+}
+
+static inline int countApplicants(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef applicants = SOSAccountCopyApplicants(account, &error);
+    int retval = 0;
+    
+    if(applicants) retval = (int)CFArrayGetCount(applicants);
+    CFReleaseNull(error);
+    CFReleaseNull(applicants);
+    return retval;
+}
+
+
+static inline void showActiveValidPeers(SOSAccountRef account) {
+    CFErrorRef error = NULL;
+    CFArrayRef peers;
+    
+    peers = SOSAccountCopyActiveValidPeers(account, &error);
+    CFArrayForEach(peers, ^(const void *value) {
+        SOSPeerInfoRef pi = (SOSPeerInfoRef) value;
+        ok(0, "Active Valid Peer %@", pi);
+    });
+    CFReleaseNull(peers);
+}
+
+#endif