]>
Commit | Line | Data |
---|---|---|
29654253 A |
1 | /* |
2 | * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved. | |
3 | * | |
4 | * The contents of this file constitute Original Code as defined in and are | |
5 | * subject to the Apple Public Source License Version 1.2 (the 'License'). | |
6 | * You may not use this file except in compliance with the License. Please obtain | |
7 | * a copy of the License at http://www.apple.com/publicsource and read it before | |
8 | * using this file. | |
9 | * | |
10 | * This Original Code and all software distributed under the License are | |
11 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS | |
12 | * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT | |
13 | * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
14 | * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the | |
15 | * specific language governing rights and limitations under the License. | |
16 | */ | |
17 | ||
18 | #include <Security/SecKeychainAPIPriv.h> | |
19 | #include <Security/SecKeychain.h> | |
df0e469f | 20 | #include <Security/KCCursor.h> |
29654253 A |
21 | #include <Security/cssmdata.h> |
22 | #include <Security/KCExceptions.h> | |
23 | #include "SecBridge.h" | |
24 | #include "CCallbackMgr.h" | |
25 | #include "Schema.h" | |
df0e469f A |
26 | #include <Security/ktracecodes.h> |
27 | #include <pwd.h> | |
29654253 A |
28 | |
29 | CFTypeID | |
30 | SecKeychainGetTypeID(void) | |
31 | { | |
32 | BEGIN_SECAPI | |
33 | ||
df0e469f A |
34 | secdebug("kc", "SecKeychainGetTypeID()"); |
35 | return gTypes().KeychainImpl.typeID; | |
29654253 A |
36 | |
37 | END_SECAPI1(_kCFRuntimeNotATypeID) | |
38 | } | |
39 | ||
40 | ||
41 | OSStatus | |
42 | SecKeychainGetVersion(UInt32 *returnVers) | |
43 | { | |
df0e469f | 44 | secdebug("kc", "SecKeychainGetVersion(%p)", returnVers); |
29654253 A |
45 | if (!returnVers) |
46 | return noErr; | |
47 | ||
48 | *returnVers = 0x02028000; | |
49 | return noErr; | |
50 | } | |
51 | ||
52 | ||
53 | OSStatus | |
54 | SecKeychainOpen(const char *pathName, SecKeychainRef *keychainRef) | |
55 | { | |
56 | BEGIN_SECAPI | |
57 | ||
df0e469f A |
58 | secdebug("kc", "SecKeychainOpen(\"%s\", %p)", pathName, keychainRef); |
59 | RequiredParam(keychainRef)=globals().storageManager.make(pathName, false)->handle(); | |
29654253 A |
60 | |
61 | END_SECAPI | |
62 | } | |
63 | ||
64 | ||
65 | OSStatus | |
66 | SecKeychainCreate(const char *pathName, UInt32 passwordLength, const void *password, | |
67 | Boolean promptUser, SecAccessRef initialAccess, SecKeychainRef *keychainRef) | |
68 | { | |
69 | BEGIN_SECAPI | |
70 | ||
df0e469f | 71 | secdebug("kc", "SecKeychainCreate(\"%s\", %lu, %p, %d, %p, %p)", pathName, passwordLength, password, promptUser, initialAccess, keychainRef); |
29654253 A |
72 | KCThrowParamErrIf_(!pathName); |
73 | Keychain keychain = globals().storageManager.make(pathName); | |
74 | ||
75 | // @@@ the call to StorageManager::make above leaves keychain the the cache. | |
76 | // If the create below fails we should probably remove it. | |
77 | if(promptUser) | |
78 | keychain->create(); | |
79 | else | |
80 | { | |
81 | KCThrowParamErrIf_(!password); | |
82 | keychain->create(passwordLength, password); | |
83 | } | |
df0e469f | 84 | RequiredParam(keychainRef)=keychain->handle(); |
29654253 A |
85 | |
86 | END_SECAPI | |
87 | } | |
88 | ||
89 | ||
90 | OSStatus | |
91 | SecKeychainDelete(SecKeychainRef keychainOrArray) | |
92 | { | |
93 | BEGIN_SECAPI | |
94 | ||
df0e469f A |
95 | secdebug("kc", "SecKeychainDelete(%p)", keychainOrArray); |
96 | KCThrowIf_(!keychainOrArray, errSecInvalidKeychain); | |
29654253 A |
97 | StorageManager::KeychainList keychains; |
98 | globals().storageManager.optionalSearchList(keychainOrArray, keychains); | |
99 | globals().storageManager.remove(keychains, true); | |
100 | ||
101 | END_SECAPI | |
102 | } | |
103 | ||
104 | ||
105 | OSStatus | |
106 | SecKeychainSetSettings(SecKeychainRef keychainRef, const SecKeychainSettings *newSettings) | |
107 | { | |
108 | BEGIN_SECAPI | |
109 | ||
df0e469f | 110 | secdebug("kc", "SecKeychainSetSettings(%p, %p)", keychainRef, newSettings); |
29654253 A |
111 | Keychain keychain = Keychain::optional(keychainRef); |
112 | if (newSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1) | |
113 | { | |
114 | UInt32 lockInterval=newSettings->lockInterval; | |
115 | bool lockOnSleep=newSettings->lockOnSleep; | |
116 | keychain->setSettings(lockInterval, lockOnSleep); | |
117 | } | |
118 | ||
119 | END_SECAPI | |
120 | } | |
121 | ||
122 | ||
123 | OSStatus | |
124 | SecKeychainCopySettings(SecKeychainRef keychainRef, SecKeychainSettings *outSettings) | |
125 | { | |
126 | BEGIN_SECAPI | |
127 | ||
df0e469f | 128 | secdebug("kc", "SecKeychainCopySettings(%p, %p)", keychainRef, outSettings); |
29654253 A |
129 | Keychain keychain = Keychain::optional(keychainRef); |
130 | if (outSettings->version==SEC_KEYCHAIN_SETTINGS_VERS1) | |
131 | { | |
132 | UInt32 lockInterval; | |
133 | bool lockOnSleep; | |
134 | ||
135 | keychain->getSettings(lockInterval, lockOnSleep); | |
136 | outSettings->lockInterval=lockInterval; | |
137 | outSettings->lockOnSleep=lockOnSleep; | |
138 | } | |
139 | ||
140 | END_SECAPI | |
141 | } | |
142 | ||
143 | ||
144 | OSStatus | |
145 | SecKeychainUnlock(SecKeychainRef keychainRef, UInt32 passwordLength, void *password, Boolean usePassword) | |
146 | { | |
147 | BEGIN_SECAPI | |
148 | ||
df0e469f | 149 | secdebug("kc", "SecKeychainUnlock(%p, %lu, %p, %d)", keychainRef, passwordLength, password, usePassword); |
29654253 | 150 | Keychain keychain = Keychain::optional(keychainRef); |
df0e469f A |
151 | |
152 | if (usePassword) | |
29654253 A |
153 | keychain->unlock(CssmData(password,passwordLength)); |
154 | else | |
155 | keychain->unlock(); | |
156 | ||
157 | END_SECAPI | |
158 | } | |
159 | ||
160 | ||
161 | OSStatus | |
162 | SecKeychainLock(SecKeychainRef keychainRef) | |
163 | { | |
164 | BEGIN_SECAPI | |
165 | ||
df0e469f | 166 | secdebug("kc", "SecKeychainLock(%p)", keychainRef); |
29654253 A |
167 | Keychain keychain = Keychain::optional(keychainRef); |
168 | keychain->lock(); | |
169 | ||
170 | END_SECAPI | |
171 | } | |
172 | ||
173 | ||
174 | OSStatus | |
175 | SecKeychainLockAll(void) | |
176 | { | |
177 | BEGIN_SECAPI | |
178 | ||
df0e469f | 179 | secdebug("kc", "SecKeychainLockAll()"); |
29654253 A |
180 | globals().storageManager.lockAll(); |
181 | ||
182 | END_SECAPI | |
183 | } | |
184 | ||
185 | ||
df0e469f A |
186 | OSStatus SecKeychainResetLogin(UInt32 passwordLength, const void* password, Boolean resetSearchList) |
187 | { | |
188 | BEGIN_SECAPI | |
189 | KCThrowParamErrIf_(password==NULL); | |
190 | // | |
191 | // Get the current user (using fallback method if necessary) | |
192 | // | |
193 | char* uName = getenv("USER"); | |
194 | string userName = uName ? uName : ""; | |
195 | if ( userName.length() == 0 ) | |
196 | { | |
197 | uid_t uid = geteuid(); | |
198 | if (!uid) uid = getuid(); | |
199 | struct passwd *pw = getpwuid(uid); // fallback case... | |
200 | if (pw) | |
201 | userName = pw->pw_name; | |
202 | endpwent(); | |
203 | } | |
204 | if ( userName.length() == 0 ) // did we ultimately get one? | |
205 | MacOSError::throwMe(errAuthorizationInternal); | |
206 | // | |
207 | // Clears the plist and moves aside (renames) an existing login.keychain | |
208 | // | |
209 | globals().storageManager.resetKeychain(resetSearchList); | |
210 | // | |
211 | // Creates a login keychain and sets it to the default. | |
212 | // | |
213 | globals().storageManager.login(userName.length(), userName.c_str(), passwordLength, password); | |
214 | Keychain keychain = globals().storageManager.loginKeychain(); | |
215 | globals().storageManager.defaultKeychain(keychain); | |
216 | END_SECAPI | |
217 | } | |
218 | ||
29654253 A |
219 | OSStatus |
220 | SecKeychainCopyDefault(SecKeychainRef *keychainRef) | |
221 | { | |
222 | BEGIN_SECAPI | |
223 | ||
df0e469f A |
224 | secdebug("kc", "SecKeychainCopyDefault(%p)", keychainRef); |
225 | RequiredParam(keychainRef)=globals().storageManager.defaultKeychain()->handle(); | |
29654253 A |
226 | |
227 | END_SECAPI | |
228 | } | |
229 | ||
230 | ||
231 | OSStatus | |
232 | SecKeychainSetDefault(SecKeychainRef keychainRef) | |
233 | { | |
234 | BEGIN_SECAPI | |
235 | ||
df0e469f A |
236 | secdebug("kc", "SecKeychainSetDefault(%p)", keychainRef); |
237 | globals().storageManager.defaultKeychain(Keychain::optional(keychainRef)); | |
29654253 A |
238 | |
239 | END_SECAPI | |
240 | } | |
241 | ||
df0e469f | 242 | OSStatus SecKeychainCopySearchList(CFArrayRef *searchList) |
29654253 A |
243 | { |
244 | BEGIN_SECAPI | |
245 | ||
df0e469f | 246 | secdebug("kc", "SecKeychainCopySearchList(%p)", searchList); |
29654253 A |
247 | RequiredParam(searchList); |
248 | StorageManager &smr = globals().storageManager; | |
249 | StorageManager::KeychainList keychainList; | |
250 | smr.getSearchList(keychainList); | |
251 | *searchList = smr.convertFromKeychainList(keychainList); | |
252 | ||
253 | END_SECAPI | |
254 | } | |
255 | ||
256 | OSStatus SecKeychainSetSearchList(CFArrayRef searchList) | |
257 | { | |
258 | BEGIN_SECAPI | |
259 | ||
df0e469f | 260 | secdebug("kc", "SecKeychainSetSearchList(%p)", searchList); |
29654253 A |
261 | RequiredParam(searchList); |
262 | StorageManager &smr = globals().storageManager; | |
263 | StorageManager::KeychainList keychainList; | |
264 | smr.convertToKeychainList(searchList, keychainList); | |
265 | smr.setSearchList(keychainList); | |
266 | ||
267 | END_SECAPI | |
268 | } | |
269 | ||
df0e469f A |
270 | OSStatus SecKeychainCopyDomainDefault(SecPreferencesDomain domain, SecKeychainRef *keychainRef) |
271 | { | |
272 | BEGIN_SECAPI | |
273 | ||
274 | secdebug("kc", "SecKeychainCopyDefault(%p)", keychainRef); | |
275 | RequiredParam(keychainRef)=globals().storageManager.defaultKeychain(domain)->handle(); | |
276 | ||
277 | END_SECAPI | |
278 | } | |
279 | ||
280 | OSStatus SecKeychainSetDomainDefault(SecPreferencesDomain domain, SecKeychainRef keychainRef) | |
281 | { | |
282 | BEGIN_SECAPI | |
283 | ||
284 | secdebug("kc", "SecKeychainSetDefault(%p)", keychainRef); | |
285 | globals().storageManager.defaultKeychain(domain, Keychain::optional(keychainRef)); | |
286 | ||
287 | END_SECAPI | |
288 | } | |
289 | ||
290 | OSStatus SecKeychainCopyDomainSearchList(SecPreferencesDomain domain, CFArrayRef *searchList) | |
291 | { | |
292 | BEGIN_SECAPI | |
293 | ||
294 | secdebug("kc", "SecKeychainCopyDomainSearchList(%p)", searchList); | |
295 | RequiredParam(searchList); | |
296 | StorageManager &smr = globals().storageManager; | |
297 | StorageManager::KeychainList keychainList; | |
298 | smr.getSearchList(domain, keychainList); | |
299 | *searchList = smr.convertFromKeychainList(keychainList); | |
300 | ||
301 | END_SECAPI | |
302 | } | |
303 | ||
304 | OSStatus SecKeychainSetDomainSearchList(SecPreferencesDomain domain, CFArrayRef searchList) | |
305 | { | |
306 | BEGIN_SECAPI | |
307 | ||
308 | secdebug("kc", "SecKeychainSetDomainSearchList(%p)", searchList); | |
309 | RequiredParam(searchList); | |
310 | StorageManager &smr = globals().storageManager; | |
311 | StorageManager::KeychainList keychainList; | |
312 | smr.convertToKeychainList(searchList, keychainList); | |
313 | smr.setSearchList(domain, keychainList); | |
314 | ||
315 | END_SECAPI | |
316 | } | |
317 | ||
318 | OSStatus SecKeychainSetPreferenceDomain(SecPreferencesDomain domain) | |
319 | { | |
320 | BEGIN_SECAPI | |
321 | ||
322 | globals().storageManager.domain(domain); | |
323 | ||
324 | END_SECAPI | |
325 | } | |
326 | ||
327 | OSStatus SecKeychainGetPreferenceDomain(SecPreferencesDomain *domain) | |
328 | { | |
329 | BEGIN_SECAPI | |
330 | ||
331 | *domain = globals().storageManager.domain(); | |
332 | ||
333 | END_SECAPI | |
334 | } | |
335 | ||
336 | ||
29654253 A |
337 | OSStatus |
338 | SecKeychainGetStatus(SecKeychainRef keychainRef, SecKeychainStatus *keychainStatus) | |
339 | { | |
340 | BEGIN_SECAPI | |
341 | ||
df0e469f | 342 | secdebug("kc", "SecKeychainGetStatus(%p): %p", keychainRef, keychainStatus); |
29654253 A |
343 | RequiredParam(keychainStatus) = (SecKeychainStatus)Keychain::optional(keychainRef)->status(); |
344 | ||
345 | END_SECAPI | |
346 | } | |
347 | ||
348 | ||
349 | OSStatus | |
df0e469f | 350 | SecKeychainGetPath(SecKeychainRef keychainRef, UInt32 *ioPathLength, char *pathName) |
29654253 A |
351 | { |
352 | BEGIN_SECAPI | |
353 | ||
df0e469f | 354 | secdebug("kc", "SecKeychainGetPath(%p, %p, %p)", keychainRef, ioPathLength, pathName); |
29654253 | 355 | RequiredParam(pathName); |
df0e469f | 356 | RequiredParam(ioPathLength); |
29654253 A |
357 | |
358 | const char *name = Keychain::optional(keychainRef)->name(); | |
359 | UInt32 nameLen = strlen(name); | |
360 | if (nameLen+1 > *ioPathLength) // if the client's buffer is too small (including null-termination), throw | |
361 | CssmError::throwMe(CSSMERR_CSSM_BUFFER_TOO_SMALL); | |
362 | strncpy(pathName, name, nameLen); | |
363 | pathName[nameLen] = 0; | |
364 | *ioPathLength = nameLen; // set the length. | |
365 | ||
366 | END_SECAPI | |
367 | } | |
368 | ||
369 | ||
370 | // @@@ Depricated | |
371 | UInt16 | |
372 | SecKeychainListGetCount(void) | |
373 | { | |
374 | BEGIN_SECAPI | |
375 | ||
df0e469f | 376 | secdebug("kc", "SecKeychainListGetCount()"); |
29654253 A |
377 | return globals().storageManager.size(); |
378 | ||
379 | END_SECAPI1(0) | |
380 | } | |
381 | ||
382 | ||
383 | // @@@ Depricated | |
384 | OSStatus | |
385 | SecKeychainListCopyKeychainAtIndex(UInt16 index, SecKeychainRef *keychainRef) | |
386 | { | |
387 | BEGIN_SECAPI | |
388 | ||
df0e469f | 389 | secdebug("kc", "SecKeychainListCopyKeychainAtIndex(%d, %p)", index, keychainRef); |
29654253 | 390 | KeychainCore::StorageManager &smgr=KeychainCore::globals().storageManager; |
df0e469f | 391 | RequiredParam(keychainRef)=smgr[index]->handle(); |
29654253 A |
392 | |
393 | END_SECAPI | |
394 | } | |
395 | ||
396 | ||
397 | // @@@ Depricated | |
398 | OSStatus | |
399 | SecKeychainListRemoveKeychain(SecKeychainRef *keychainRef) | |
400 | { | |
401 | BEGIN_SECAPI | |
402 | ||
df0e469f | 403 | secdebug("kc", "SecKeychainListRemoveKeychain(%p)", keychainRef); |
29654253 A |
404 | Required(keychainRef); |
405 | Keychain keychain = Keychain::optional(*keychainRef); | |
406 | StorageManager::KeychainList keychainList; | |
407 | keychainList.push_back(keychain); | |
408 | globals().storageManager.remove(keychainList); | |
409 | *keychainRef = NULL; | |
410 | ||
411 | END_SECAPI | |
412 | } | |
413 | ||
414 | ||
415 | OSStatus | |
416 | SecKeychainAttributeInfoForItemID(SecKeychainRef keychainRef, UInt32 itemID, SecKeychainAttributeInfo **info) | |
417 | { | |
418 | BEGIN_SECAPI | |
419 | ||
df0e469f | 420 | secdebug("kc", "SecKeychainAttributeInfoForItemID(%p, %lu, %p)", keychainRef, itemID, info); |
29654253 A |
421 | Keychain keychain = Keychain::optional(keychainRef); |
422 | keychain->getAttributeInfoForItemID(itemID, info); | |
423 | ||
424 | END_SECAPI | |
425 | } | |
426 | ||
427 | ||
428 | OSStatus | |
429 | SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info) | |
430 | { | |
431 | BEGIN_SECAPI | |
432 | ||
df0e469f | 433 | secdebug("kc", "SecKeychainFreeAttributeInfo(%p)", info); |
29654253 A |
434 | KeychainImpl::freeAttributeInfo(info); |
435 | ||
436 | END_SECAPI | |
437 | } | |
438 | ||
439 | ||
440 | pascal OSStatus | |
441 | SecKeychainAddCallback(SecKeychainCallback callbackFunction, SecKeychainEventMask eventMask, void* userContext) | |
442 | { | |
443 | BEGIN_SECAPI | |
444 | ||
df0e469f | 445 | secdebug("kc", "SecKeychainAddCallback(%p, %08lx, %p)", callbackFunction, eventMask, userContext); |
29654253 A |
446 | RequiredParam(callbackFunction); |
447 | CCallbackMgr::AddCallback(callbackFunction,eventMask,userContext); | |
448 | ||
449 | END_SECAPI | |
450 | } | |
451 | ||
452 | ||
453 | OSStatus | |
454 | SecKeychainRemoveCallback(SecKeychainCallback callbackFunction) | |
455 | { | |
456 | BEGIN_SECAPI | |
457 | ||
df0e469f | 458 | secdebug("kc", "SecKeychainRemoveCallback(%p)", callbackFunction); |
29654253 A |
459 | RequiredParam(callbackFunction); |
460 | CCallbackMgr::RemoveCallback(callbackFunction); | |
461 | ||
462 | END_SECAPI | |
463 | } | |
464 | ||
29654253 A |
465 | OSStatus |
466 | SecKeychainAddInternetPassword(SecKeychainRef keychainRef, UInt32 serverNameLength, const char *serverName, UInt32 securityDomainLength, const char *securityDomain, UInt32 accountNameLength, const char *accountName, UInt32 pathLength, const char *path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) | |
467 | { | |
468 | BEGIN_SECAPI | |
469 | ||
df0e469f | 470 | secdebug("kc", "SecKeychainAddInternetPassword(%p)", keychainRef); |
29654253 A |
471 | KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL); |
472 | // @@@ Get real itemClass | |
473 | Item item(kSecInternetPasswordItemClass, 'aapl', passwordLength, passwordData); | |
474 | ||
475 | if (serverName && serverNameLength) | |
df0e469f A |
476 | { |
477 | CssmData server(const_cast<void *>(reinterpret_cast<const void *>(serverName)), serverNameLength); | |
478 | item->setAttribute(Schema::attributeInfo(kSecServerItemAttr), server); | |
479 | // use server name as default label | |
480 | item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), server); | |
481 | } | |
29654253 A |
482 | |
483 | if (accountName && accountNameLength) | |
484 | { | |
485 | CssmData account(const_cast<void *>(reinterpret_cast<const void *>(accountName)), accountNameLength); | |
486 | item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account); | |
29654253 A |
487 | } |
488 | ||
489 | if (securityDomain && securityDomainLength) | |
490 | item->setAttribute(Schema::attributeInfo(kSecSecurityDomainItemAttr), | |
491 | CssmData(const_cast<void *>(reinterpret_cast<const void *>(securityDomain)), securityDomainLength)); | |
492 | ||
493 | item->setAttribute(Schema::attributeInfo(kSecPortItemAttr), UInt32(port)); | |
494 | item->setAttribute(Schema::attributeInfo(kSecProtocolItemAttr), protocol); | |
495 | item->setAttribute(Schema::attributeInfo(kSecAuthenticationTypeItemAttr), authenticationType); | |
496 | ||
497 | if (path && pathLength) | |
498 | item->setAttribute(Schema::attributeInfo(kSecPathItemAttr), | |
499 | CssmData(const_cast<void *>(reinterpret_cast<const void *>(path)), pathLength)); | |
500 | ||
df0e469f A |
501 | Keychain keychain = nil; |
502 | try | |
503 | { | |
504 | keychain = Keychain::optional(keychainRef); | |
505 | if ( !keychain->exists() ) | |
506 | { | |
507 | MacOSError::throwMe(errSecNoSuchKeychain); // Might be deleted or not available at this time. | |
508 | } | |
509 | } | |
510 | catch(...) | |
511 | { | |
512 | keychain = globals().storageManager.defaultKeychainUI(item); | |
513 | } | |
514 | ||
515 | keychain->add(item); | |
516 | ||
517 | if (itemRef) | |
518 | *itemRef = item->handle(); | |
29654253 A |
519 | |
520 | END_SECAPI | |
521 | } | |
522 | ||
523 | ||
524 | OSStatus | |
525 | SecKeychainFindInternetPassword(CFTypeRef keychainOrArray, UInt32 serverNameLength, const char *serverName, UInt32 securityDomainLength, const char *securityDomain, UInt32 accountNameLength, const char *accountName, UInt32 pathLength, const char *path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef) | |
526 | ||
527 | { | |
528 | BEGIN_SECAPI | |
529 | ||
df0e469f | 530 | secdebug("kc", "SecKeychainFindInternetPassword(%p)", keychainOrArray); |
29654253 A |
531 | StorageManager::KeychainList keychains; |
532 | globals().storageManager.optionalSearchList(keychainOrArray, keychains); | |
533 | KCCursor cursor(keychains, kSecInternetPasswordItemClass, NULL); | |
534 | ||
535 | if (serverName && serverNameLength) | |
536 | { | |
537 | cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServerItemAttr), | |
538 | CssmData(const_cast<char *>(serverName), serverNameLength)); | |
539 | } | |
540 | ||
541 | if (securityDomain && securityDomainLength) | |
542 | { | |
543 | cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecSecurityDomainItemAttr), | |
544 | CssmData (const_cast<char*>(securityDomain), securityDomainLength)); | |
545 | } | |
546 | ||
547 | if (accountName && accountNameLength) | |
548 | { | |
549 | cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecAccountItemAttr), | |
550 | CssmData (const_cast<char*>(accountName), accountNameLength)); | |
551 | } | |
552 | ||
553 | if (port) | |
554 | { | |
555 | cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecPortItemAttr), | |
556 | UInt32(port)); | |
557 | } | |
558 | ||
559 | if (protocol) | |
560 | { | |
561 | cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecProtocolItemAttr), | |
562 | protocol); | |
563 | } | |
564 | ||
565 | if (authenticationType) | |
566 | { | |
567 | cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecAuthenticationTypeItemAttr), | |
568 | authenticationType); | |
569 | } | |
570 | ||
571 | if (path && pathLength) | |
572 | { | |
573 | cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecPathItemAttr), path); | |
574 | } | |
575 | ||
576 | Item item; | |
577 | if (!cursor->next(item)) | |
578 | return errSecItemNotFound; | |
579 | ||
580 | // Get its data (only if necessary) | |
581 | if (passwordData || passwordLength) | |
582 | { | |
583 | CssmDataContainer outData; | |
584 | item->getData(outData); | |
585 | *passwordLength=outData.length(); | |
586 | outData.Length=0; | |
587 | *passwordData=outData.data(); | |
588 | outData.Data=NULL; | |
589 | } | |
590 | ||
591 | if (itemRef) | |
df0e469f | 592 | *itemRef=item->handle(); |
29654253 A |
593 | |
594 | END_SECAPI | |
595 | } | |
596 | ||
597 | ||
598 | OSStatus | |
599 | SecKeychainAddGenericPassword(SecKeychainRef keychainRef, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) | |
29654253 A |
600 | { |
601 | BEGIN_SECAPI | |
602 | ||
df0e469f | 603 | secdebug("kc", "SecKeychainAddGenericPassword(%p)", keychainRef); |
29654253 A |
604 | KCThrowParamErrIf_(passwordLength!=0 && passwordData==NULL); |
605 | // @@@ Get real itemClass | |
606 | Item item(kSecGenericPasswordItemClass, 'aapl', passwordLength, passwordData); | |
607 | ||
608 | if (serviceName && serviceNameLength) | |
df0e469f A |
609 | { |
610 | CssmData service(const_cast<void *>(reinterpret_cast<const void *>(serviceName)), serviceNameLength); | |
611 | item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), service); | |
612 | // use service name as default label | |
613 | item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), service); | |
614 | } | |
29654253 A |
615 | |
616 | if (accountName && accountNameLength) | |
617 | { | |
618 | CssmData account(const_cast<void *>(reinterpret_cast<const void *>(accountName)), accountNameLength); | |
619 | item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account); | |
29654253 A |
620 | } |
621 | ||
df0e469f A |
622 | Keychain keychain = nil; |
623 | try | |
624 | { | |
625 | keychain = Keychain::optional(keychainRef); | |
626 | if ( !keychain->exists() ) | |
627 | { | |
628 | MacOSError::throwMe(errSecNoSuchKeychain); // Might be deleted or not available at this time. | |
629 | } | |
630 | } | |
631 | catch(...) | |
632 | { | |
633 | keychain = globals().storageManager.defaultKeychainUI(item); | |
634 | } | |
635 | ||
636 | keychain->add(item); | |
29654253 | 637 | if (itemRef) |
df0e469f | 638 | *itemRef = item->handle(); |
29654253 A |
639 | |
640 | END_SECAPI | |
641 | } | |
642 | ||
643 | ||
644 | OSStatus | |
645 | SecKeychainFindGenericPassword(CFTypeRef keychainOrArray, UInt32 serviceNameLength, const char *serviceName, UInt32 accountNameLength, const char *accountName, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef) | |
646 | ||
647 | { | |
df0e469f A |
648 | Debug::trace (kSecTraceSecurityFrameworkSecKeychainFindGenericPasswordBegin); |
649 | ||
29654253 A |
650 | BEGIN_SECAPI |
651 | ||
df0e469f | 652 | secdebug("kc", "SecKeychainFindGenericPassword(%p)", keychainOrArray); |
29654253 A |
653 | StorageManager::KeychainList keychains; |
654 | globals().storageManager.optionalSearchList(keychainOrArray, keychains); | |
655 | KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL); | |
656 | ||
657 | if (serviceName && serviceNameLength) | |
658 | { | |
659 | cursor->add (CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), | |
660 | const_cast<char*>(serviceName)); | |
661 | } | |
662 | ||
663 | if (accountName && accountNameLength) | |
664 | { | |
665 | cursor->add (CSSM_DB_EQUAL, Schema::attributeInfo(kSecAccountItemAttr), | |
666 | const_cast<char*>(accountName)); | |
667 | } | |
668 | ||
669 | Item item; | |
670 | if (!cursor->next(item)) | |
671 | return errSecItemNotFound; | |
672 | ||
673 | // Get its data (only if necessary) | |
674 | if (passwordData || passwordLength) | |
675 | { | |
676 | CssmDataContainer outData; | |
677 | item->getData(outData); | |
678 | *passwordLength=outData.length(); | |
679 | outData.Length=0; | |
680 | *passwordData=outData.data(); | |
681 | outData.Data=NULL; | |
682 | } | |
683 | ||
684 | if (itemRef) | |
df0e469f | 685 | *itemRef=item->handle(); |
29654253 A |
686 | |
687 | END_SECAPI | |
688 | } | |
689 | ||
690 | ||
691 | OSStatus | |
692 | SecKeychainSetUserInteractionAllowed(Boolean state) | |
693 | { | |
694 | BEGIN_SECAPI | |
695 | ||
df0e469f | 696 | secdebug("kc", "SecKeychainSetUserInteractionAllowed(%d)", state); |
29654253 A |
697 | globals().setUserInteractionAllowed(state); |
698 | ||
699 | END_SECAPI | |
700 | } | |
701 | ||
702 | ||
703 | OSStatus | |
704 | SecKeychainGetUserInteractionAllowed(Boolean *state) | |
705 | { | |
706 | BEGIN_SECAPI | |
707 | ||
df0e469f | 708 | secdebug("kc", "SecKeychainGetUserInteractionAllowed()"); |
29654253 A |
709 | Required(state)=globals().getUserInteractionAllowed(); |
710 | ||
711 | END_SECAPI | |
712 | } | |
713 | ||
714 | ||
715 | OSStatus | |
716 | SecKeychainGetDLDBHandle(SecKeychainRef keychainRef, CSSM_DL_DB_HANDLE *dldbHandle) | |
717 | { | |
718 | BEGIN_SECAPI | |
719 | ||
df0e469f | 720 | secdebug("kc", "SecKeychainGetDLDBHandle(%p, %p)", keychainRef, dldbHandle); |
29654253 A |
721 | RequiredParam(dldbHandle); |
722 | ||
723 | Keychain keychain = Keychain::optional(keychainRef); | |
724 | *dldbHandle = keychain->database()->handle(); | |
725 | ||
726 | END_SECAPI | |
727 | } | |
728 | ||
729 | ||
730 | OSStatus | |
731 | SecKeychainGetCSPHandle(SecKeychainRef keychainRef, CSSM_CSP_HANDLE *cspHandle) | |
732 | { | |
733 | BEGIN_SECAPI | |
734 | ||
df0e469f | 735 | secdebug("kc", "SecKeychainGetCSPHandle(%p, %p)", keychainRef, cspHandle); |
29654253 A |
736 | RequiredParam(cspHandle); |
737 | ||
738 | Keychain keychain = Keychain::optional(keychainRef); | |
739 | *cspHandle = keychain->csp()->handle(); | |
740 | ||
741 | END_SECAPI | |
742 | } | |
743 | ||
744 | ||
745 | OSStatus | |
746 | SecKeychainCopyAccess(SecKeychainRef keychainRef, SecAccessRef *accessRef) | |
747 | { | |
748 | BEGIN_SECAPI | |
749 | ||
df0e469f | 750 | secdebug("kc", "SecKeychainCopyAccess(%p, %p)", keychainRef, accessRef); |
29654253 A |
751 | MacOSError::throwMe(unimpErr);//%%%for now |
752 | ||
753 | END_SECAPI | |
754 | } | |
755 | ||
756 | ||
757 | OSStatus | |
758 | SecKeychainSetAccess(SecKeychainRef keychainRef, SecAccessRef accessRef) | |
759 | { | |
760 | BEGIN_SECAPI | |
761 | ||
df0e469f | 762 | secdebug("kc", "SecKeychainSetAccess(%p, %p)", keychainRef, accessRef); |
29654253 A |
763 | MacOSError::throwMe(unimpErr);//%%%for now |
764 | ||
765 | END_SECAPI | |
766 | } | |
767 | ||
768 | ||
769 | #pragma mark ---- Private API ---- | |
770 | ||
771 | ||
772 | OSStatus | |
773 | SecKeychainChangePassword(SecKeychainRef keychainRef, UInt32 oldPasswordLength, const void *oldPassword, UInt32 newPasswordLength, const void *newPassword) | |
774 | { | |
775 | BEGIN_SECAPI | |
776 | ||
df0e469f A |
777 | secdebug("kc", "SecKeychainChangePassword(%p, %lu, %p, %lu, %p)", keychainRef, |
778 | oldPasswordLength, oldPassword, newPasswordLength, newPassword); | |
29654253 A |
779 | Keychain keychain = Keychain::optional(keychainRef); |
780 | keychain->changePassphrase (oldPasswordLength, oldPassword, newPasswordLength, newPassword); | |
781 | ||
782 | END_SECAPI | |
783 | } | |
784 | ||
785 | ||
786 | OSStatus | |
787 | SecKeychainCopyLogin(SecKeychainRef *keychainRef) | |
788 | { | |
789 | BEGIN_SECAPI | |
790 | ||
df0e469f A |
791 | secdebug("kc", "SecKeychainCopyLogin(%p)", keychainRef); |
792 | RequiredParam(keychainRef)=globals().storageManager.loginKeychain()->handle(); | |
29654253 A |
793 | |
794 | END_SECAPI | |
795 | } | |
796 | ||
797 | ||
798 | OSStatus | |
799 | SecKeychainLogin(UInt32 nameLength, void* name, UInt32 passwordLength, void* password) | |
800 | { | |
801 | BEGIN_SECAPI | |
802 | ||
df0e469f | 803 | secdebug("kc", "SecKeychainLogin(%lu, %p, %lu, %p)", nameLength, name, passwordLength, password); |
29654253 A |
804 | globals().storageManager.login(nameLength, name, passwordLength, password); |
805 | ||
806 | END_SECAPI | |
807 | } | |
808 | ||
809 | ||
810 | OSStatus | |
811 | SecKeychainLogout() | |
812 | { | |
813 | BEGIN_SECAPI | |
814 | ||
df0e469f | 815 | secdebug("kc", "SecKeychainLogout()"); |
29654253 A |
816 | globals().storageManager.logout(); |
817 | ||
818 | END_SECAPI | |
819 | } | |
df0e469f A |
820 | |
821 | static CFStringRef copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName); | |
822 | ||
823 | // caller MUST release the string, since it is gotten with "CFCopyLocalizedStringFromTableInBundle" | |
824 | // intended use of reserved param is to pass in CFStringRef with name of the Table for lookup | |
825 | // Will look by default in "SecErrorMessages.strings" in the resources of Security.framework. | |
826 | ||
827 | ||
828 | CFStringRef SecCopyErrorMessageString(OSStatus status, void *reserved) | |
829 | { | |
830 | BEGIN_SECAPI | |
831 | ||
832 | return copyErrorMessageFromBundle(status,CFSTR("SecErrorMessages")); | |
833 | ||
834 | END_SECAPI1(NULL) | |
835 | } | |
836 | ||
837 | CFStringRef copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName) | |
838 | { | |
839 | CFStringRef errorString = nil; | |
840 | CFStringRef keyString = nil; | |
841 | CFURLRef bundleURL = NULL; | |
842 | CFBundleRef secBundle = NULL; | |
843 | ||
844 | Content-type: text/html ]>