1// 2// si-76-shared-credentials.c 3// sec 4// 5 6 7#include <CoreFoundation/CoreFoundation.h> 8#include <Security/SecBasePriv.h> 9#include <Security/SecCertificate.h> 10#include <Security/SecCertificatePriv.h> 11#include <Security/SecCertificateInternal.h> 12#include <Security/SecItem.h> 13#include <Security/SecItemPriv.h> 14#include <Security/SecIdentityPriv.h> 15#include <Security/SecIdentity.h> 16#include <Security/SecPolicy.h> 17#include <Security/SecPolicyPriv.h> 18#include <Security/SecPolicyInternal.h> 19#include <Security/SecSharedCredential.h> 20#include <Security/SecCMS.h> 21#include <utilities/SecCFWrappers.h> 22#include <stdlib.h> 23#include <unistd.h> 24 25#include "Security_regressions.h" 26 27#define WAIT_WHILE(X) { while ((X)) { (void)CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, TRUE); } } 28 29static bool expected_failure(OSStatus status) 30{ 31 return ((status == errSecMissingEntitlement) || 32 (status == errSecBadReq)); 33} 34 35static void tests(void) 36{ 37 // look up our entry for localhost 38 CFStringRef acct1 = CFSTR("local"); 39 CFStringRef acct2 = CFSTR("admin"); 40 CFStringRef fqdn = CFSTR("localhost"); 41 CFStringRef not_my_fqdn = CFSTR("store.apple.com"); // something we aren't entitled to share 42 __block bool adding; 43 __block bool requesting; 44 __block bool deleting; 45 46// UInt8 buf[6] = { 'l', 'o', 'c', 'a', 'l', '\0' }; 47// CFDataRef cred = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)&buf, sizeof(buf)); 48 CFStringRef cred = CFStringCreateCopy(kCFAllocatorDefault, CFSTR("local")); 49 50 // should get denied if we request a fqdn which is not in our entitlement 51 requesting = true; 52 SecRequestSharedWebCredential(not_my_fqdn, NULL, ^void (CFArrayRef credentials, CFErrorRef error) { 53 OSStatus status = (OSStatus)((error) ? CFErrorGetCode(error) : errSecSuccess); 54 is(status == errSecItemNotFound || expected_failure(status), true, "fqdn not entitled"); 55 is(CFArrayGetCount(credentials) > 0, false, "returned credential array == 0"); 56 requesting = false; 57 }); 58 WAIT_WHILE(requesting); 59 60 // add (or update) credentials for two different accounts on the same server 61 adding = true; 62 SecAddSharedWebCredential(fqdn, acct1, cred, ^void (CFErrorRef error) { 63 OSStatus status = (OSStatus)((error) ? CFErrorGetCode(error) : errSecSuccess); 64 // TODO: need a proper teamID-enabled application identifier to succeed; expect auth failure 65 if (status == errSecAuthFailed || expected_failure(status)) { status = errSecSuccess; } 66 ok_status(status); 67 adding = false; 68 }); 69 WAIT_WHILE(adding); 70 71 adding = true; 72 SecAddSharedWebCredential(fqdn, acct2, cred, ^void (CFErrorRef error) { 73 OSStatus status = (OSStatus)((error) ? CFErrorGetCode(error) : errSecSuccess); 74 // TODO: need a proper teamID-enabled application identifier to succeed; expect auth failure 75 if (status == errSecAuthFailed || expected_failure(status)) { status = errSecSuccess; } 76 ok_status(status); 77 adding = false; 78 }); 79 WAIT_WHILE(adding); 80 81 // look up credential with specific account 82 requesting = true; 83 SecRequestSharedWebCredential(fqdn, acct1, ^void (CFArrayRef credentials, CFErrorRef error) { 84 OSStatus status = (OSStatus)((error) ? CFErrorGetCode(error) : errSecSuccess); 85 // TODO: need a proper teamID-enabled application identifier to succeed; expect no items 86 bool notFound = false; 87 if (status == errSecItemNotFound || expected_failure(status)) { 88 status = errSecSuccess; notFound = true; 89 } 90 ok_status(status); 91 92 // should find only one credential if a specific account is provided 93 CFIndex credentialCount = CFArrayGetCount(credentials); 94 // TODO: need a proper teamID-enabled application identifier to succeed; expect 0 items 95 if (credentialCount == 0 && notFound) { credentialCount = 1; } 96 is(credentialCount == 1, true, "returned credentials == 1"); 97 requesting = false; 98 }); 99 WAIT_WHILE(requesting); 100 101 // look up credential with NULL account parameter 102 requesting = true; 103 SecRequestSharedWebCredential(fqdn, NULL, ^void (CFArrayRef credentials, CFErrorRef error) { 104 OSStatus status = (OSStatus)((error) ? CFErrorGetCode(error) : errSecSuccess); 105 // TODO: need a proper teamID-enabled application identifier to succeed; expect auth failure 106 bool notFound = false; 107 if (status == errSecItemNotFound || expected_failure(status)) { 108 status = errSecSuccess; notFound = true; 109 } 110 ok_status(status); 111 112 // should find only one credential if no account is provided 113 // (since UI dialog only permits one credential to be selected) 114 CFIndex credentialCount = CFArrayGetCount(credentials); 115 // TODO: need a proper teamID-enabled application identifier to succeed 116 if (credentialCount == 0 && notFound) { credentialCount = 1; } 117 is(credentialCount == 1, true, "returned credentials == 1"); 118 requesting = false; 119 }); 120 WAIT_WHILE(requesting); 121 122 // pass NULL to delete our credentials 123 deleting = true; 124 SecAddSharedWebCredential(fqdn, acct1, NULL, ^void (CFErrorRef error) { 125 OSStatus status = (OSStatus)((error) ? CFErrorGetCode(error) : errSecSuccess); 126 // TODO: need a proper teamID-enabled application identifier to succeed; expect auth failure 127 if (status == errSecAuthFailed || expected_failure(status)) { status = errSecSuccess; } 128 ok_status(status); 129 deleting = false; 130 }); 131 WAIT_WHILE(deleting); 132 133 deleting = true; 134 SecAddSharedWebCredential(fqdn, acct2, NULL, ^void (CFErrorRef error) { 135 OSStatus status = (OSStatus)((error) ? CFErrorGetCode(error) : errSecSuccess); 136 // TODO: need a proper teamID-enabled application identifier to succeed; expect auth failure 137 if (status == errSecAuthFailed || expected_failure(status)) { status = errSecSuccess; } 138 ok_status(status); 139 deleting = false; 140 }); 141 WAIT_WHILE(deleting); 142 143 // look up credentials again; should find nothing this time 144 requesting = true; 145 SecRequestSharedWebCredential(fqdn, NULL, ^void (CFArrayRef credentials, CFErrorRef error) { 146 OSStatus status = (OSStatus)((error) ? CFErrorGetCode(error) : errSecSuccess); 147 // TODO: need a proper teamID-enabled application identifier to succeed; expect auth failure 148 if (status == errSecAuthFailed || expected_failure(status)) { status = errSecItemNotFound; } 149 is_status(status, errSecItemNotFound); 150 is(CFArrayGetCount(credentials) > 0, false, "returned credential array == 0"); 151 requesting = false; 152 }); 153 WAIT_WHILE(requesting); 154 155 CFRelease(cred); 156} 157 158int si_76_shared_credentials(int argc, char *const *argv) 159{ 160 plan_tests(12); 161 tests(); 162 return 0; 163} 164