]> git.saurik.com Git - apple/security.git/blob - Keychain/SecKeychainAddIToolsPassword.c
Security-179.tar.gz
[apple/security.git] / Keychain / SecKeychainAddIToolsPassword.c
1 /*
2 * SecKeychainAddIToolsPassword.c
3 *
4 * Created by jhurley on Thu Jun 19 2003.
5 * Copyright (c) 2003 Apple. All rights reserved.
6 *
7 * Based on Keychain item access control example
8 * Created by Perry Kiehtreiber on Wed Jun 19 2002
9 * Modified by Ken McLeod, Mon Apr 21 2003 -- added "always allow" ACL support
10 */
11
12 #include <Security/SecKeychain.h>
13 #include <Security/SecKeychainItem.h>
14 #include <Security/SecAccess.h>
15 #include <Security/SecAccessPriv.h>
16 #include <Security/SecTrustedApplication.h>
17 #include <Security/SecACL.h>
18 #include <CoreFoundation/CoreFoundation.h>
19 #include <sys/param.h>
20
21 static CFArrayRef CopyTrustedAppListFromBundle();
22 static SecAccessRef createAccess(CFStringRef accessLabel,const int allowAny);
23
24 OSStatus SecKeychainAddIToolsPassword(SecKeychainRef keychain, UInt32 accountNameLength, const char *accountName,
25 UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef)
26 {
27 OSStatus err;
28 SecKeychainItemRef item = nil;
29 const char *serviceUTF8 = "iTools";
30 CFStringRef itemLabel = CFSTR("iTools");
31 const int allowAny = 0;
32
33 // create initial access control settings for the item
34 SecAccessRef access = createAccess(itemLabel, allowAny);
35
36 // below is the lower-layer equivalent to the SecKeychainAddGenericPassword() function;
37 // it does the same thing (except specify the access controls)
38
39 // set up attribute vector (each attribute consists of {tag, length, pointer})
40 SecKeychainAttribute attrs[] =
41 {
42 { kSecLabelItemAttr, strlen(serviceUTF8), (char *)serviceUTF8 }, // use the service string as the name of this item for display purposes
43 { kSecAccountItemAttr, accountNameLength, (char *)accountName },
44 { kSecServiceItemAttr, strlen(serviceUTF8), (char *)serviceUTF8 }
45 };
46 SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
47
48 err = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass,
49 &attributes,
50 passwordLength,
51 (const char *)passwordData,
52 keychain,
53 access,
54 &item);
55
56 if (access)
57 CFRelease(access);
58 if (item)
59 CFRelease(item);
60 return noErr;
61 }
62
63 SecAccessRef createAccess(CFStringRef accessLabel,const int allowAny)
64 {
65 OSStatus err;
66 SecAccessRef access=nil;
67 CFMutableArrayRef trustedApplications=nil;
68
69 if (!allowAny) // use default access ("confirm access")
70 {
71 // make an exception list of applications you want to trust,
72 // which are allowed to access the item without requiring user confirmation
73 SecTrustedApplicationRef myself=NULL, someOther=NULL;
74 CFArrayRef trustedAppListFromBundle=NULL;
75
76 trustedApplications=CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
77 err = SecTrustedApplicationCreateFromPath(NULL, &myself);
78 if (!err)
79 CFArrayAppendValue(trustedApplications,myself);
80
81 trustedAppListFromBundle=CopyTrustedAppListFromBundle();
82 if (trustedAppListFromBundle)
83 {
84 int ix,top;
85 char buffer[MAXPATHLEN];
86 top = CFArrayGetCount(trustedAppListFromBundle);
87 for (ix=0;ix<top;ix++)
88 {
89 CFStringRef filename = CFArrayGetValueAtIndex(trustedAppListFromBundle,ix);
90 CFIndex stringLength = CFStringGetLength(filename);
91 CFIndex usedBufLen;
92 // CFShow(filename); // debug
93
94 if (stringLength != CFStringGetBytes(filename,CFRangeMake(0,stringLength),kCFStringEncodingUTF8,0,
95 false,(UInt8 *)&buffer,MAXPATHLEN, &usedBufLen))
96 break;
97 buffer[usedBufLen] = 0;
98 // printf("converted filename: [sl=%d, ubl=%d %s\n",stringLength,usedBufLen,buffer);
99 err = SecTrustedApplicationCreateFromPath(buffer,&someOther);
100 if (!err)
101 CFArrayAppendValue(trustedApplications,someOther);
102 }
103 CFRelease(trustedAppListFromBundle);
104 }
105 }
106
107 err = SecAccessCreate((CFStringRef)accessLabel, (CFArrayRef)trustedApplications, &access);
108 if (err)
109 return nil;
110
111 if (allowAny) // change access to be wide-open for decryption ("always allow access")
112 {
113 // get the access control list for decryption operations
114 CFArrayRef aclList=nil;
115 err = SecAccessCopySelectedACLList(access, CSSM_ACL_AUTHORIZATION_DECRYPT, &aclList);
116
117 if (!err)
118 {
119 // get the first entry in the access control list
120 SecACLRef aclRef=(SecACLRef)CFArrayGetValueAtIndex(aclList, 0);
121 CFArrayRef appList=nil;
122 CFStringRef promptDescription=nil;
123 CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR promptSelector;
124 err = SecACLCopySimpleContents(aclRef, &appList, &promptDescription, &promptSelector);
125
126 // modify the default ACL to not require the passphrase, and have a nil application list
127 promptSelector.flags &= ~CSSM_ACL_KEYCHAIN_PROMPT_REQUIRE_PASSPHRASE;
128 err = SecACLSetSimpleContents(aclRef, NULL, promptDescription, &promptSelector);
129
130 if (appList) CFRelease(appList);
131 if (promptDescription) CFRelease(promptDescription);
132 }
133 }
134
135 return access;
136 }
137
138 CFArrayRef CopyTrustedAppListFromBundle()
139 {
140 CFStringRef errorString = nil;
141 CFURLRef bundleURL,trustedAppsURL = NULL;
142 CFBundleRef secBundle = NULL;
143 CFPropertyListRef trustedAppsPlist = NULL;
144 CFDataRef xmlDataRef = NULL;
145 SInt32 errorCode;
146 CFArrayRef trustedAppList = NULL;
147
148 // Make a CFURLRef from the CFString representation of the bundleƕs path.
149 bundleURL = CFURLCreateWithFileSystemPath(
150 kCFAllocatorDefault,CFSTR("/System/Library/Frameworks/Security.framework/Resources/"),kCFURLPOSIXPathStyle,true);
151 if (!bundleURL)
152 goto xit;
153
154 // Make a bundle instance using the URLRef.
155 secBundle = CFBundleCreate(kCFAllocatorDefault,bundleURL);
156 if (!secBundle)
157 goto xit;
158
159 // Look for a resource in the bundle by name and type
160 trustedAppsURL = CFBundleCopyResourceURL(secBundle,CFSTR("iToolsTrustedApps"),CFSTR("plist"),NULL);
161 if (!trustedAppsURL)
162 goto xit;
163
164 if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,trustedAppsURL,&xmlDataRef,NULL,NULL,&errorCode))
165 goto xit;
166
167 trustedAppsPlist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault,xmlDataRef,kCFPropertyListImmutable,&errorString);
168
169 // if (!CFPropertyListIsValid(trustedAppsPlist,kCFPropertyListXMLFormat_v1_0))
170 // goto xit;
171
172 /*
173 if (CFGetTypeID(trustedAppsPlist) != CFGetTypeID(trustedAppList))
174 {
175 CFRelease(trustedAppsPlist);
176 goto xit;
177 }
178 */
179 trustedAppList = (CFArrayRef)trustedAppsPlist;
180
181 xit:
182 if (bundleURL)
183 CFRelease(bundleURL);
184 if (secBundle)
185 CFRelease(secBundle);
186 if (trustedAppsURL)
187 CFRelease(trustedAppsURL);
188 if (xmlDataRef)
189 CFRelease(xmlDataRef);
190 if (errorString)
191 CFRelease(errorString);
192
193 return trustedAppList;
194 }
195