#include <Security/SecKeychain.h>
#include <Security/SecKeychainPriv.h>
#include <stdlib.h>
#include <unistd.h>
#include "testenv.h"
#include "testleaks.h"
#include "testmore.h"
#include "testsecevent.h"
void tests(int dont_skip)
{
const char *user = getenv("USER");
ok((user != NULL && strlen(user) != 0), "USER must be non-nil and non-zero length");
fprintf(stdout, "Testing login for user \"%s\"\n", user);
ok_status(test_sec_event_register(kSecEveryEventMask),
"register for all events");
ok_status(SecKeychainLogin(strlen(user), user, 4, "test"), "login user");
is_sec_event(kSecKeychainListChangedEvent, NULL, NULL, NULL,
"list changed event");
no_sec_event("no event");
SecKeychainRef default_keychain = NULL;
ok_status(SecKeychainCopyDefault(&default_keychain), "get default");
SecKeychainStatus status = 0;
ok_status(SecKeychainGetStatus(default_keychain, &status), "get status");
is(status, kSecUnlockStateStatus|kSecReadPermStatus|kSecWritePermStatus,
"default should be read/write/unlocked");
char path[1024];
UInt32 path_len = sizeof(path) - 1;
ok_status(SecKeychainGetPath(default_keychain, &path_len, path),
"get path");
fprintf(stdout, "Default keychain path is %s\n", path);
path[path_len] = 0;
const char *login_path = "Library/Keychains/login.keychain";
cmp_ok(path_len, >, strlen(login_path), "path len is enough");
eq_string(path + path_len - strlen(login_path), login_path, "check path");
is(CFGetRetainCount(default_keychain), 1, "default retain count is 1");
CFRelease(default_keychain);
default_keychain = NULL;
ok_status(test_sec_event_deregister(), "deregister events.");
char testuser_path[1024];
sprintf(testuser_path, "Library/Keychains/%s", user);
ok_unix(rename(login_path, testuser_path),
"rename login.keychain to $USER");
ok_status(SecKeychainLogin(strlen(user), user, 4, "test"), "login again");
ok_status(SecKeychainCopyDefault(&default_keychain), "get default");
path_len = sizeof(path) - 1;
ok_status(SecKeychainGetPath(default_keychain, &path_len, path),
"get path");
path[path_len] = 0;
cmp_ok(path_len, >, strlen(testuser_path), "path len is enough");
ok_status(SecKeychainLock(default_keychain), "lock default");
CFRelease(default_keychain);
ok(tests_end(1), "cleanup");
}
int main(int argc, char *const *argv)
{
int dont_skip = argc > 1 && !strcmp(argv[1], "-s");
plan_tests(21);
if (!tests_begin(argc, argv))
BAIL_OUT("tests_begin failed");
tests(dont_skip);
ok_leaks("no leaks");
return 0;
}