2 * Copyright (c) 2003-2013 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 * SecKeychainAddIToolsPassword.c
25 * Based on Keychain item access control example
26 * -- added "always allow" ACL support
29 #include <Security/SecKeychain.h>
30 #include <Security/SecKeychainItem.h>
31 #include <Security/SecAccess.h>
32 #include <Security/SecAccessPriv.h>
33 #include <Security/SecTrustedApplicationPriv.h>
34 #include <Security/SecACL.h>
35 #include "SecBridge.h"
36 #include <CoreFoundation/CoreFoundation.h>
37 #include <security_utilities/cfutilities.h>
40 OSStatus
SecKeychainAddIToolsPassword(SecKeychainRef keychain
, UInt32 accountNameLength
, const char *accountName
,
41 UInt32 passwordLength
, const void *passwordData
, SecKeychainItemRef
*itemRef
)
45 const char *serviceUTF8
= "iTools";
47 // create the initial ACL label string (use the account name, not "iTools")
48 CFRef
<CFStringRef
> itemLabel
= CFStringCreateWithBytes(kCFAllocatorDefault
,
49 (const UInt8
*)accountName
, accountNameLength
, kCFStringEncodingUTF8
, FALSE
);
51 // accumulate applications in this list
52 CFRef
<CFMutableArrayRef
> apps
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
54 // add entries for application groups
55 CFRef
<SecTrustedApplicationRef
> dotMacGroup
, accountsGroup
;
56 MacOSError::check(SecTrustedApplicationCreateApplicationGroup("dot-mac", NULL
, &dotMacGroup
.aref()));
57 CFArrayAppendValue(apps
, dotMacGroup
);
58 MacOSError::check(SecTrustedApplicationCreateApplicationGroup("InternetAccounts", NULL
, &accountsGroup
.aref()));
59 CFArrayAppendValue(apps
, accountsGroup
);
61 // now add "myself" as an ordinary application
62 CFRef
<SecTrustedApplicationRef
> myself
;
63 MacOSError::check(SecTrustedApplicationCreateFromPath(NULL
, &myself
.aref()));
64 CFArrayAppendValue(apps
, myself
);
66 // now add the pre-cooked list of .Mac applications for systems that don't understand the group semantics
67 if (CFRef
<CFBundleRef
> myBundle
= CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")))
68 if (CFRef
<CFURLRef
> url
= CFBundleCopyResourceURL(myBundle
,
69 CFSTR("iToolsTrustedApps"), CFSTR("plist"), NULL
)) {
70 CFRef
<CFDataRef
> data
;
71 if (CFURLCreateDataAndPropertiesFromResource(NULL
, url
, &data
.aref(), NULL
, NULL
, NULL
))
72 if (CFRef
<CFArrayRef
> list
=
73 CFArrayRef(CFPropertyListCreateFromXMLData(NULL
, data
, kCFPropertyListImmutable
, NULL
))) {
74 CFIndex size
= CFArrayGetCount(list
);
75 for (CFIndex n
= 0; n
< size
; n
++) {
76 CFStringRef path
= (CFStringRef
)CFArrayGetValueAtIndex(list
, n
);
77 CFRef
<SecTrustedApplicationRef
> app
;
78 if (SecTrustedApplicationCreateFromPath(cfString(path
).c_str(), &app
.aref()) == errSecSuccess
)
79 CFArrayAppendValue(apps
, app
);
84 // form a SecAccess from this
85 CFRef
<SecAccessRef
> access
;
86 MacOSError::check(SecAccessCreate(itemLabel
, (CFArrayRef
)apps
, &access
.aref()));
88 // set up attribute vector (each attribute consists of {tag, length, pointer})
89 SecKeychainAttribute attrs
[] = {
90 { kSecLabelItemAttr
, accountNameLength
, (char *)accountName
}, // use the account name as the label for display purposes [3787371]
91 { kSecAccountItemAttr
, accountNameLength
, (char *)accountName
},
92 { kSecServiceItemAttr
, (UInt32
)strlen(serviceUTF8
), (char *)serviceUTF8
}
94 SecKeychainAttributeList attributes
= { sizeof(attrs
) / sizeof(attrs
[0]), attrs
};
96 return SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass
,
99 (const char *)passwordData
,