作为在OSX中以编程方式创建VPN连接的过程的一部分,使用Cocoa,我需要将PPP密码存储在System keychain中。当我尝试使用keychain API执行此操作时,由于调用SecKeychainAddGenericPassword而出现以下错误:
“无法写入文件。它可能是在访问权限不足的情况下打开的。”
以下是我正在使用的代码:
- (void)storePasswordInKeychain
{
SecKeychainRef keychain = nil;
err = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &keychain);
if (err != errSecSuccess) {
NSLog(@"Error getting system keychain: %@", SecCopyErrorMessageString(err, NULL));
} else {
NSLog(@"Succeeded opening keychain: %@", SecCopyErrorMessageString(err, NULL));
SecKeychainItemRef item = nil;
err = SecKeychainUnlock(keychain, 0, NULL, FALSE);
NSLog(@"Keychain unlocked: %@", SecCopyErrorMessageString(err, NULL));
err = SecKeychainAddGenericPassword (keychain,
3, "VPN",
8, "username",
8, "password",
&item);
NSLog(@"Result of storing password: %@", SecCopyErrorMessageString(err, NULL));
}
}
讨论How to write to the System.keychain?使得我似乎需要从我的程序中对/ usr / bin / security进行命令行调用,但Keychain API的重点似乎是避免这种hackery 。
有人能指出我在系统钥匙串中存储新密码的正确方向吗?谢谢。
答案 0 :(得分:1)
当您向系统密钥链写入内容时,您需要root权限。 对于xcode调试,只需“EditScheme”(从菜单按“Product-> EditScheme ...-> Run-> Info-> Debug process as-> root”)。好吧,我的xcode版本是6.1,也许在不同的xcode版本中有一些区别。 或者只是通过sudo你的应用程序使用命令行。 希望这会有所帮助。
答案 1 :(得分:1)
确实,凭据需要进入系统密钥链而不是用户密钥链。你不需要SMJobBless来做到这一点。
解锁钥匙串后,创建一个SecAccessRef,如下所示:
SecAccessRef access = nil;
status = SecAccessCreate(CFSTR("Some VPN Test"), (__bridge CFArrayRef)(self.trustedApps), &access);
然后构建您的钥匙串项目
SecKeychainAttribute attrs[] = {
{kSecLabelItemAttr, (int)strlen(labelUTF8), (char *)labelUTF8},
{kSecAccountItemAttr, (int)strlen(accountUTF8), (char *)accountUTF8},
{kSecServiceItemAttr, (int)strlen(serviceUTF8), (char *)serviceUTF8},
{kSecDescriptionItemAttr, (int)strlen(descriptionUTF8), (char *)descriptionUTF8},
};
最后将它存储到钥匙串中:
SecKeychainAttributeList attributes = {sizeof(attrs) / sizeof(attrs[0]), attrs};
status = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, &attributes, (int)strlen(passwordUTF8), passwordUTF8, keychain, access, &item);
Github上有一个项目可以做到这一点。查看VPNKeychain.m
文件以查看整个实现。 https://github.com/halo/macosvpn
答案 2 :(得分:0)
当然是VPN用户名&密码属于特定用户,您真的是指系统密钥链而不是用户密钥链吗?
尝试放弃对SecKeychainCopyDomainDefault
& SecKeychainUnlock
只是将NULL
作为SecKeychainAddGenericPassword
的第一个参数传递 - 这应该将项目添加到默认的钥匙串。
答案 3 :(得分:0)
您指出的另一个问题似乎是推荐服务管理所取代的Authorization Services API(在10.6中),并明确声明在沙箱时根本不允许。