Cannot add neagent to access control

Hello there. I'm trying to create VPN app for macos. I'm using ikev2 protocol, with NEVPNIKEAuthenticationMethod.none, but with extendedAuth. So to establish VPN I need to add my password to keychain and obtaint password reference. And I want to skip prompt for password, that neagent is asking for, when VPN connection is established for the first time.

I've created SecAccess instance, and added 'neagent' app as trsuted for my keychain item. And I can see 'neagent' app in access list for just created item. But 'neagent' is still asking for password.


https://photos.app.goo.gl/YSN6KTFGPsEAVqTS7


    static func createAccess() -> SecAccess {
  
        var app: SecTrustedApplication?
        var status = SecTrustedApplicationCreateFromPath("/usr/libexec/neagent", &app)
        
        var myApp: SecTrustedApplication?
        status = SecTrustedApplicationCreateFromPath(nil, &myApp)
        
        var access: SecAccess?
        status = SecAccessCreate("description" as CFString, [app, myApp] as CFArray, &access)

        return access!
    }
    
    static func savePassword(pass: String, account: String = "default_account") {
        
        guard let passData = pass.data(using: String.Encoding.utf8, allowLossyConversion: false) else {
            return
        }
        //Delete previous value if exists
        
        if updatePassword(pass, account: account) { return }
        
        let access = createAccess()
        let keychainQuery = [kSecAttrAccess: access,
                             kSecAttrService: service,
                             kSecClass: kSecClassGenericPassword,
                             kSecAttrLabel: "App label",
                             kSecAttrAccount: account,
                             kSecValueData: passData] as [CFString : Any]
        
        
        let status = SecItemAdd(keychainQuery as CFDictionary, nil)
        if (status != errSecSuccess),
            let err = SecCopyErrorMessageString(status, nil) {
            print("Write failed: \(err)")
        }
    }
Post not yet marked as solved Up vote post of lyksa88 Down vote post of lyksa88
1.5k views

Replies

But 'neagent' is still asking for password.

Right. This is fallout from a security hardening feature of modern versions of macOS, one that prevents you from being able to grant other programs access to keychain items without explicit user consent.

I’ve investigated this on behalf of other developers and, alas, was unable to find a workaround. The only solution would be to fix

NEVPNManager
to write the credentials with the correct ACL (it can do this because it’s part of the OS). We have a bug on file about this already but I’m not able to track down the bug number right now so I’m going to recommend that you file your own bug as well.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks, for the response. Here is bug number 40413518.

One more question. Maybe I can create another SecKeychain instance to keep passwordRef for my connection, and setup SecAccess attribute for the whole kaychain not for single item?

My understanding is that the problem you’re seeing is the result of a deliberate security hardening, and thus if you’re suggestion worked it would be considered a security bug.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hello lyksa88,could you solved the issue? I've got some similar issue and i can't find any suggestion or workaround to fix it. Mac is always asking for keychain user password, when i try to connect to the VPN, although when i click "always allow" in the neagent popup. I mean the neagent popup is not shown only the first time, it is shown always.