/* * Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ * * SecKeychainAddIToolsPassword.c * * Based on Keychain item access control example * -- added "always allow" ACL support */ #include #include #include #include #include #include #include "SecBridge.h" #include #include OSStatus SecKeychainAddIToolsPassword(SecKeychainRef keychain, UInt32 accountNameLength, const char *accountName, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) { BEGIN_SECAPI const char *serviceUTF8 = "iTools"; // create the initial ACL label string (use the account name, not "iTools") CFRef itemLabel = CFStringCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)accountName, accountNameLength, kCFStringEncodingUTF8, FALSE); // accumulate applications in this list CFRef apps = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); // add the new-fangled dot-mac application group CFRef group; MacOSError::check(SecTrustedApplicationCreateApplicationGroup("dot-mac", NULL, &group.aref())); CFArrayAppendValue(apps, group); // now add "myself" as an ordinary application CFRef myself; MacOSError::check(SecTrustedApplicationCreateFromPath(NULL, &myself.aref())); CFArrayAppendValue(apps, myself); // now add the pre-cooked list of .Mac applications for systems that don't understand the group semantics if (CFRef myBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security"))) if (CFRef url = CFBundleCopyResourceURL(myBundle, CFSTR("iToolsTrustedApps"), CFSTR("plist"), NULL)) { CFRef data; if (CFURLCreateDataAndPropertiesFromResource(NULL, url, &data.aref(), NULL, NULL, NULL)) if (CFRef list = CFArrayRef(CFPropertyListCreateFromXMLData(NULL, data, kCFPropertyListImmutable, NULL))) { CFIndex size = CFArrayGetCount(list); for (CFIndex n = 0; n < size; n++) { CFStringRef path = (CFStringRef)CFArrayGetValueAtIndex(list, n); CFRef app; if (SecTrustedApplicationCreateFromPath(cfString(path).c_str(), &app.aref()) == noErr) CFArrayAppendValue(apps, app); } } } // form a SecAccess from this CFRef access; MacOSError::check(SecAccessCreate(itemLabel, (CFArrayRef)apps, &access.aref())); // set up attribute vector (each attribute consists of {tag, length, pointer}) SecKeychainAttribute attrs[] = { { kSecLabelItemAttr, accountNameLength, (char *)accountName }, // use the account name as the label for display purposes [3787371] { kSecAccountItemAttr, accountNameLength, (char *)accountName }, { kSecServiceItemAttr, strlen(serviceUTF8), (char *)serviceUTF8 } }; SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs }; return SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, &attributes, passwordLength, (const char *)passwordData, keychain, access, itemRef); END_SECAPI }