davidafsilva / jkeychain

Simple Java API to operate on macOS keychain generic passwords
BSD 2-Clause "Simplified" License
19 stars 3 forks source link

Keychain API calls fail after a period of time (long running process) #3

Open cloudshiftchris opened 2 years ago

cloudshiftchris commented 2 years ago

After a period of time (presumably, possibly some other undetermined factor) all keychain API calls fail with 'Invalid Record' exception. This persists until the process is restarted.

Context:

Workaround:

As noted above, stopping the Gradle daemon and restarting is the only identified workaround.

Calling code:

The below Kotlin code is what makes the OSX Keychain API calls; note the delete/add, in an attempt to compensate (this does not work). When the failure mode is active, all API calls here consistently fail - modify, find, delete, add.


internal object OSXKeychainService {
    private val logger: Logger =
        Logging.getLogger(OSXKeychainService::class.java)

    private val keychain = OSXKeychain.getInstance()

    fun modifyGenericPassword(serviceName: String, accountName: String, password: String) {
        try {
            keychain.modifyGenericPassword(serviceName, accountName, password)
        } catch (e: OSXKeychainException) {
            logger.error("Unable to update token in OS X keychain: ${e.message}; deleting token & retrying")
            keychain.deleteGenericPassword(serviceName, accountName)
            keychain.addGenericPassword(serviceName, accountName, password)
        }
    }

    fun findGenericPassword(serviceName: String, accountName: String): String? {
        return try {
            keychain.findGenericPassword(serviceName, accountName).orElse(null)
        } catch (e: OSXKeychainException) {
            logger.error("Unable to lookup token in OS X keychain: ${e.message}")
            null
        }
    }
}

pt.davidafsilva.apple:jkeychain:1.1.0

Gradle: 7.4.2, 7.5.1

openjdk 17.0.5 2022-10-18 LTS OpenJDK Runtime Environment Corretto-17.0.5.8.1 (build 17.0.5+8-LTS) OpenJDK 64-Bit Server VM Corretto-17.0.5.8.1 (build 17.0.5+8-LTS, mixed mode, sharing)

MacBook Pro / M1 Pro chip / 32GB RAM ProductName: macOS ProductVersion: 12.6 BuildVersion: 21G115

cloudshiftchris commented 2 years ago

Perhaps the context here is relevant.

It talks about releasing a resource, otherwise "invalid record" errors will be encountered.

cloudshiftchris commented 2 years ago

Issue is likely in modifyGenericPassword - it isn't calling CFRelease on the pointer passed to SecKeychainItemModifyContent

davidafsilva commented 2 years ago

Hey, thanks for the detailed report @cloudshiftchris. I'll have a better look at it when I manage to find a whole in my schedule. Feel free to submit a PR in the meantime if you want.