From f243c228e144e7c765bca8bd1e145f7ee86fe9d4 Mon Sep 17 00:00:00 2001 From: David Goodlad Date: Mon, 22 Aug 2016 08:12:59 +1000 Subject: [PATCH] Use `.keychain-db` extension on macOS Sierra As of macOS Sierra, Keychain files are stored with the extension `.keychain-db` rather than `.keychain`. This is a quick kernel-version check so that we use the correct extension on the user's OS. --- keyring/keychain.go | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/keyring/keychain.go b/keyring/keychain.go index 5d02a4d4c..ea604438a 100644 --- a/keyring/keychain.go +++ b/keyring/keychain.go @@ -20,6 +20,9 @@ import ( "log" "os" "os/user" + "strconv" + "strings" + "syscall" "unicode/utf8" "unsafe" ) @@ -30,18 +33,44 @@ type keychain struct { Passphrase string } +func keychainPath(name string) (string, error) { + usr, err := user.Current() + if err != nil { + return "", err + } + + // As of macOS Sierra, Keychain files are stored with the `.keychain-db` + // extension, rather than `.keychain`. The result of the kern.osrelease + // sysctl is the kernel version number in the form "major.minor.patch", + // and Sierra is the first macOS release to use kernel major version 16 + osver, err := syscall.Sysctl("kern.osrelease") + if err != nil { + return "", err + } + + major, err := strconv.Atoi(strings.Split(osver, ".")[0]) + if err != nil { + return "", err + } + + if major >= 16 { + return usr.HomeDir + "/Library/Keychains/" + name + ".keychain-db", nil + } else { + return usr.HomeDir + "/Library/Keychains/" + name + ".keychain", nil + } +} + func init() { supportedBackends[KeychainBackend] = opener(func(name string) (Keyring, error) { if name == "" { name = "login" } - usr, err := user.Current() + path, err := keychainPath(name) if err != nil { return nil, err } - - return &keychain{Path: usr.HomeDir + "/Library/Keychains/" + name + ".keychain", Service: name}, nil + return &keychain{Path: path, Service: name}, nil }) DefaultBackend = KeychainBackend