How do you write to the OSX System keychain?

浪尽此生 提交于 2019-12-05 04:03:20

问题


As part of the process of creating a VPN connection programatically in OSX, using Cocoa, I need to store the PPP password in the System keychain. When I try to do this using the keychain API, I get the following error as a result of calling SecKeychainAddGenericPassword:

"Could not write to the file. It may have been opened with insufficient access privileges."

Here is the code I am using:

- (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));
    }
}

The discussion How to write to the System.keychain? makes it seem like I need to make a command line call to /usr/bin/security from within my program, but the point of the Keychain API seems to be to avoid that kind of hackery.

Can anybody point me in the right direction for storing a new password in the System keychain? Thanks.


回答1:


You need root privilege when you write something to system keychain. For xcode debugging, you just "EditScheme"(From Menu by "Product->EditScheme...->Run->Info->Debug process as->root"). Well,my xcode version is 6.1, maybe there is some difference in different xcode version. Or just use command line by sudo your app. Hope this helps.




回答2:


It is true that the credentials need to go into the system keychain and not the user keychain. You will not need the SMJobBless to do that.

After you unlocked the keychain, create an SecAccessRef like so:

SecAccessRef access = nil;
status = SecAccessCreate(CFSTR("Some VPN Test"), (__bridge CFArrayRef)(self.trustedApps), &access);

Then build your keychain item

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},
};

And finally store it to the keychain:

  SecKeychainAttributeList attributes = {sizeof(attrs) / sizeof(attrs[0]), attrs};
  status = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, &attributes, (int)strlen(passwordUTF8), passwordUTF8, keychain, access, &item);

There is a project on Github which does just that. Have a look at the VPNKeychain.m file to see the whole implementation. https://github.com/halo/macosvpn




回答3:


Surely a VPN username & password belong to a particular user, do you really mean the system keychain and not the user keychain?

Try dropping the calls to SecKeychainCopyDomainDefault & SecKeychainUnlock and just pass NULL as the first argument to SecKeychainAddGenericPassword - this should add the item to the default keychain.




回答4:


Apple's current recommendation for privileged access is to use the Service Management API. They have a sample project: SMJobBless. I'm not sure if the sandbox will allow system keychain access if you are targeting the Mac App Store.

The other question you point to seems to be recommending the Authorization Services API which Service Management replaced (in 10.6) and which is explicitly stated as not being allowed at all when sandboxed.



来源:https://stackoverflow.com/questions/9837784/how-do-you-write-to-the-osx-system-keychain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!