From f4cdabf9161dca552f71886ca11b756531c39093 Mon Sep 17 00:00:00 2001 From: Albin Kerouanton Date: Fri, 28 Feb 2025 11:56:00 +0100 Subject: [PATCH] osxkeychain: store: use Apple's proto consts Commit 4cdcdc2 swapped consts `kSecProtocolTypeHTTPS` and `kSecProtocolTypeHTTP` with plain-text "https" and "http" strings. This is causing a regression where credentials stored with prior versions (< v0.9.0) can't be fetched anymore. Unfortunately we can't just revert back to using Objective-C consts, as these are unsigned integers that need to be converted into `CFStringRef` and then passed to an helper like `keychain.CFStringToString`. Although `keychain.CFStringToString` is exported, it takes a C type `C.CFStringRef` so it's not consumable from other packages due to Cgo restrictions: > Cgo translates C types into equivalent unexported Go types. Because > the translations are unexported, a Go package should not expose C > types in its exported API: a C type used in one Go package is > different from the same C type used in another. We could alternatively copy `keychain.CFStringToString` into the `osxkeychain` package, but this commit takes a simpler approach: just hardcode the value of `kSecProtocolTypeHTTPS` and `kSecProtocolTypeHTTP` as strings. (These consts are very unlikely to ever change since it'd break all existing consumers.) This is **NOT** handling backward compatibility with v0.9.0, since it was released only 12hrs ago. So this fix won't work with credentials created with v0.9.0. Signed-off-by: Albin Kerouanton --- osxkeychain/osxkeychain.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osxkeychain/osxkeychain.go b/osxkeychain/osxkeychain.go index 1dfa2a5..b513763 100644 --- a/osxkeychain/osxkeychain.go +++ b/osxkeychain/osxkeychain.go @@ -129,14 +129,22 @@ func (h Osxkeychain) List() (map[string]string, error) { return resp, nil } +const ( + // Hardcoded protocol types matching their Objective-C equivalents. + // https://developer.apple.com/documentation/security/ksecattrprotocolhttps?language=objc + kSecProtocolTypeHTTPS = "htps" // This is NOT a typo. + // https://developer.apple.com/documentation/security/ksecattrprotocolhttp?language=objc + kSecProtocolTypeHTTP = "http" +) + func splitServer(serverURL string, item keychain.Item) error { u, err := registryurl.Parse(serverURL) if err != nil { return err } - item.SetProtocol("https") + item.SetProtocol(kSecProtocolTypeHTTPS) if u.Scheme == "http" { - item.SetProtocol("http") + item.SetProtocol(kSecProtocolTypeHTTP) } item.SetServer(u.Hostname()) if p := u.Port(); p != "" {