Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v0.9.0] osxkeychain: fix regressions on get and list #361

Merged
merged 2 commits into from
Feb 28, 2025

Conversation

akerouanton
Copy link
Member

@akerouanton akerouanton commented Feb 28, 2025

- What I did

osxkeychain: list: do not error out when keychain is empty

Commit 4cdcdc2 replaced the in-tree Objective-C code with github.com/keybase/go-keychain and inadvertently introduced a new failure mode on the List operation - it now fails when the keychain is empty.

Before:

$ ./bin/build/docker-credential-osxkeychain list
{}

After:

$ ./bin/build/docker-credential-osxkeychain list
credentials not found in native keychain

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.

- How to verify it

# Create credentials with an older version of docker-credential-osxkeychain

$ ~/.local/bin/docker-credential-osxkeychain version     
docker-credential-osxkeychain (github.com/docker/docker-credential-helpers) v0.8.2

$ echo '{"ServerURL":"https://index.docker.io/v1/","Username":"albinkerouanton006","Secret":"some valid token"}' | ~/.local/bin/docker-credential-osxkeychain store

# Then with these commits applied:

$ ./bin/build/docker-credential-osxkeychain list                                                                                                                   
{"/v1/":"albinkerouanton006"}

$ echo 'https://index.docker.io/v1/' | ./bin/build/docker-credential-osxkeychain get
{"ServerURL":"https://index.docker.io/v1/","Username":"albinkerouanton006","Secret":"some valid token"}

- Description for the changelog

osxkeychain: fix a regression that caused credentials stored with an older version of the credentials-helper to not be found

- A picture of a cute animal (not mandatory but encouraged)

Commit 4cdcdc2 replaced the in-tree Objective-C code with github.com/keybase/go-keychain
and inadvertently introduced a new failure mode on the `List` operation -
it now fails when the keychain is empty.

Before:

```
$ ./bin/build/docker-credential-osxkeychain list
{}
```

After:

```
$ ./bin/build/docker-credential-osxkeychain list
credentials not found in native keychain
```

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
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 <albinker@gmail.com>
@codecov-commenter
Copy link

codecov-commenter commented Feb 28, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 50.15%. Comparing base (36a3c50) to head (f4cdabf).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #361      +/-   ##
==========================================
+ Coverage   49.92%   50.15%   +0.23%     
==========================================
  Files          13       13              
  Lines         653      650       -3     
==========================================
  Hits          326      326              
+ Misses        281      279       -2     
+ Partials       46       45       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@akerouanton akerouanton changed the title Fix regressions v0.9.0 [v0.9.0] osxkeychain: fix regressions on get and list Feb 28, 2025
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thaJeztah thaJeztah merged commit 26274da into docker:master Feb 28, 2025
12 checks passed
@akerouanton akerouanton deleted the fix-regressions-v0.9.0 branch February 28, 2025 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants