1 #include <Security/SecKeychain.h>
2 #include <Security/SecKeychainPriv.h>
9 #include "testsecevent.h"
11 void tests(int dont_skip
)
13 const char *user
= getenv("USER");
14 ok((user
!= NULL
&& strlen(user
) != 0), "USER must be non-nil and non-zero length");
15 fprintf(stdout
, "Testing login for user \"%s\"\n", user
);
17 ok_status(test_sec_event_register(kSecEveryEventMask
),
18 "register for all events");
20 // test SecKeychainLogin for $USER with password "test"
21 ok_status(SecKeychainLogin(strlen(user
), user
, 4, "test"), "login user");
23 // wait for a list changed event
24 is_sec_event(kSecKeychainListChangedEvent
, NULL
, NULL
, NULL
,
25 "list changed event");
26 no_sec_event("no event");
28 // get the default keychain (should be login.keychain if none is explicitly set)
29 SecKeychainRef default_keychain
= NULL
;
30 ok_status(SecKeychainCopyDefault(&default_keychain
), "get default");
32 // test status of default keychain (should be read/write and unlocked)
33 SecKeychainStatus status
= 0;
34 ok_status(SecKeychainGetStatus(default_keychain
, &status
), "get status");
35 is(status
, kSecUnlockStateStatus
|kSecReadPermStatus
|kSecWritePermStatus
,
36 "default should be read/write/unlocked");
38 // get the path for the default keychain
40 UInt32 path_len
= sizeof(path
) - 1;
41 ok_status(SecKeychainGetPath(default_keychain
, &path_len
, path
),
43 fprintf(stdout
, "Default keychain path is %s\n", path
);
45 const char *login_path
= "Library/Keychains/login.keychain";
46 cmp_ok(path_len
, >, strlen(login_path
), "path len is enough");
47 eq_string(path
+ path_len
- strlen(login_path
), login_path
, "check path");
49 // check retain count on default keychain (why??)
50 is(CFGetRetainCount(default_keychain
), 1, "default retain count is 1");
51 CFRelease(default_keychain
);
52 default_keychain
= NULL
;
54 // lock and unlock events have been removed because they can't be made reliable
56 ok_status(test_sec_event_deregister(), "deregister events.");
58 // rename login.keychain to $USER to simulate a Panther-style keychain
59 char testuser_path
[1024];
60 sprintf(testuser_path
, "Library/Keychains/%s", user
);
61 ok_unix(rename(login_path
, testuser_path
),
62 "rename login.keychain to $USER");
64 // login and verify that SecKeychainLogin cleans up the $USER keychain
65 // (either by renaming to $USER.keychain, or renaming to login.keychain)
66 ok_status(SecKeychainLogin(strlen(user
), user
, 4, "test"), "login again");
68 // get the default keychain (should be login.keychain if none is explicitly set)
69 ok_status(SecKeychainCopyDefault(&default_keychain
), "get default");
70 path_len
= sizeof(path
) - 1;
71 ok_status(SecKeychainGetPath(default_keychain
, &path_len
, path
),
74 cmp_ok(path_len
, >, strlen(testuser_path
), "path len is enough");
76 // lock the default keychain
77 ok_status(SecKeychainLock(default_keychain
), "lock default");
78 CFRelease(default_keychain
);
80 ok(tests_end(1), "cleanup");
83 int main(int argc
, char *const *argv
)
85 int dont_skip
= argc
> 1 && !strcmp(argv
[1], "-s");
88 if (!tests_begin(argc
, argv
))
89 BAIL_OUT("tests_begin failed");