mirror of
https://github.com/docker/docker-credential-helpers.git
synced 2026-06-29 15:52:05 +05:30
Compare commits
34 Commits
v0.9.1
..
d4602cd917
| Author | SHA1 | Date | |
|---|---|---|---|
| d4602cd917 | |||
| ae84c25786 | |||
| 2adf3cf9aa | |||
| 1fdce4c733 | |||
| 962a779645 | |||
| ec5efac3ca | |||
| 8154b98959 | |||
| d075f3cecc | |||
| fdddb02817 | |||
| c07513a69d | |||
| 4142982fb8 | |||
| 860f1459e3 | |||
| d378d46316 | |||
| 4c97a761df | |||
| b61abf1cb8 | |||
| 85841ea0ce | |||
| c32e697324 | |||
| d770c60191 | |||
| 5095e43ecf | |||
| 00313838c6 | |||
| bcf656656f | |||
| fd27520bbd | |||
| 4849c2328b | |||
| 2e8005f3a7 | |||
| 5d4d5150ae | |||
| f9d3010165 | |||
| e7bd3957ae | |||
| cfd6d21216 | |||
| ab29a6c87b | |||
| 576efaa084 | |||
| 9d6cdddf25 | |||
| d8e34f8743 | |||
| b1d5bf0326 | |||
| 50b162c340 |
+10
-10
@@ -15,7 +15,7 @@ on:
|
||||
|
||||
env:
|
||||
DESTDIR: ./bin
|
||||
GO_VERSION: 1.23.6
|
||||
GO_VERSION: 1.24.7
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
@@ -44,19 +44,19 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-24.04
|
||||
- ubuntu-22.04
|
||||
- ubuntu-20.04
|
||||
- macOS-15-intel
|
||||
- macOS-15
|
||||
- macOS-14
|
||||
- macOS-13
|
||||
- windows-2022
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
-
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
-
|
||||
name: GPG conf
|
||||
if: ${{ !startsWith(matrix.os, 'windows-') }}
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
id: gpg
|
||||
with:
|
||||
script: |
|
||||
@@ -139,7 +139,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
-
|
||||
@@ -173,7 +173,7 @@ jobs:
|
||||
-
|
||||
name: GitHub Release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
|
||||
uses: softprops/action-gh-release@6cbd405e2c4e67a21c47fa9e383d020e4e28b836 # v2.3.3
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
@@ -185,7 +185,7 @@ jobs:
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
-
|
||||
|
||||
+12
-20
@@ -1,31 +1,23 @@
|
||||
version: "2"
|
||||
run:
|
||||
timeout: 10m
|
||||
modules-download-mode: vendor
|
||||
|
||||
linters:
|
||||
default: none
|
||||
enable:
|
||||
- gofmt
|
||||
- govet
|
||||
- depguard
|
||||
- goimports
|
||||
- ineffassign
|
||||
- misspell
|
||||
- unused
|
||||
- revive
|
||||
- staticcheck
|
||||
- typecheck
|
||||
disable-all: true
|
||||
- unused
|
||||
settings:
|
||||
revive:
|
||||
rules:
|
||||
- name: package-comments # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#package-comments
|
||||
disabled: true
|
||||
|
||||
linters-settings:
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: "io/ioutil"
|
||||
desc: The io/ioutil package has been deprecated. See https://go.dev/doc/go1.16#ioutil
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- linters:
|
||||
- revive
|
||||
text: "stutters"
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- goimports
|
||||
|
||||
+23
-39
@@ -1,11 +1,11 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.23.6
|
||||
ARG GO_VERSION=1.24.7
|
||||
ARG DEBIAN_VERSION=bookworm
|
||||
|
||||
ARG XX_VERSION=1.6.1
|
||||
ARG OSXCROSS_VERSION=11.3-r7-debian
|
||||
ARG GOLANGCI_LINT_VERSION=v1.64.5
|
||||
ARG XX_VERSION=1.7.0
|
||||
ARG OSXCROSS_VERSION=11.3-r8-debian
|
||||
ARG GOLANGCI_LINT_VERSION=v2.5
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ARG PACKAGE=github.com/docker/docker-credential-helpers
|
||||
@@ -99,21 +99,7 @@ FROM gobase AS version
|
||||
RUN --mount=target=. \
|
||||
echo -n "$(./hack/git-meta version)" | tee /tmp/.version ; echo -n "$(./hack/git-meta revision)" | tee /tmp/.revision
|
||||
|
||||
FROM base AS build-linux
|
||||
ARG PACKAGE
|
||||
RUN --mount=type=bind,target=. \
|
||||
--mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
--mount=type=bind,source=/tmp/.version,target=/tmp/.version,from=version \
|
||||
--mount=type=bind,source=/tmp/.revision,target=/tmp/.revision,from=version <<EOT
|
||||
set -ex
|
||||
xx-go --wrap
|
||||
make build-pass build-secretservice PACKAGE=$PACKAGE VERSION=$(cat /tmp/.version) REVISION=$(cat /tmp/.revision) DESTDIR=/out
|
||||
xx-verify /out/docker-credential-pass
|
||||
xx-verify /out/docker-credential-secretservice
|
||||
EOT
|
||||
|
||||
FROM base AS build-darwin
|
||||
FROM base AS build
|
||||
ARG PACKAGE
|
||||
RUN --mount=type=bind,target=. \
|
||||
--mount=type=cache,target=/root/.cache \
|
||||
@@ -124,28 +110,26 @@ RUN --mount=type=bind,target=. \
|
||||
set -ex
|
||||
export MACOSX_VERSION_MIN=$(make print-MACOSX_DEPLOYMENT_TARGET)
|
||||
xx-go --wrap
|
||||
go install std
|
||||
make build-osxkeychain build-pass PACKAGE=$PACKAGE VERSION=$(cat /tmp/.version) REVISION=$(cat /tmp/.revision) DESTDIR=/out
|
||||
xx-verify /out/docker-credential-osxkeychain
|
||||
xx-verify /out/docker-credential-pass
|
||||
case "$(xx-info os)" in
|
||||
linux)
|
||||
make build-pass build-secretservice PACKAGE=$PACKAGE VERSION=$(cat /tmp/.version) REVISION=$(cat /tmp/.revision) DESTDIR=/out
|
||||
xx-verify /out/docker-credential-pass
|
||||
xx-verify /out/docker-credential-secretservice
|
||||
;;
|
||||
darwin)
|
||||
go install std
|
||||
make build-osxkeychain build-pass PACKAGE=$PACKAGE VERSION=$(cat /tmp/.version) REVISION=$(cat /tmp/.revision) DESTDIR=/out
|
||||
xx-verify /out/docker-credential-osxkeychain
|
||||
xx-verify /out/docker-credential-pass
|
||||
;;
|
||||
windows)
|
||||
make build-wincred PACKAGE=$PACKAGE VERSION=$(cat /tmp/.version) REVISION=$(cat /tmp/.revision) DESTDIR=/out
|
||||
mv /out/docker-credential-wincred /out/docker-credential-wincred.exe
|
||||
xx-verify /out/docker-credential-wincred.exe
|
||||
;;
|
||||
esac
|
||||
EOT
|
||||
|
||||
FROM base AS build-windows
|
||||
ARG PACKAGE
|
||||
RUN --mount=type=bind,target=. \
|
||||
--mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
--mount=type=bind,source=/tmp/.version,target=/tmp/.version,from=version \
|
||||
--mount=type=bind,source=/tmp/.revision,target=/tmp/.revision,from=version <<EOT
|
||||
set -ex
|
||||
xx-go --wrap
|
||||
make build-wincred PACKAGE=$PACKAGE VERSION=$(cat /tmp/.version) REVISION=$(cat /tmp/.revision) DESTDIR=/out
|
||||
mv /out/docker-credential-wincred /out/docker-credential-wincred.exe
|
||||
xx-verify /out/docker-credential-wincred.exe
|
||||
EOT
|
||||
|
||||
FROM build-$TARGETOS AS build
|
||||
|
||||
FROM scratch AS binaries
|
||||
COPY --from=build /out /
|
||||
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG GO_VERSION=1.23.6
|
||||
ARG GO_VERSION=1.24.7
|
||||
ARG DISTRO=ubuntu
|
||||
ARG SUITE=focal
|
||||
ARG SUITE=jammy
|
||||
|
||||
FROM golang:${GO_VERSION}-bullseye AS golang
|
||||
FROM golang:${GO_VERSION}-bookworm AS golang
|
||||
|
||||
FROM ${DISTRO}:${SUITE}
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@ module github.com/docker/docker-credential-helpers
|
||||
|
||||
go 1.21
|
||||
|
||||
retract v0.9.0 // osxkeychain: a regression caused backward-incompatibility with earlier versions
|
||||
retract (
|
||||
v0.9.1 // osxkeychain: a regression caused backward-incompatibility with earlier versions
|
||||
v0.9.0 // osxkeychain: a regression caused backward-incompatibility with earlier versions
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/danieljoos/wincred v1.2.2
|
||||
|
||||
@@ -12,6 +12,8 @@ import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/docker-credential-helpers/credentials"
|
||||
@@ -44,6 +46,17 @@ func (h Osxkeychain) Add(creds *credentials.Credentials) error {
|
||||
item.SetLabel(credentials.CredsLabel)
|
||||
item.SetAccount(creds.Username)
|
||||
item.SetData([]byte(creds.Secret))
|
||||
// Prior to v0.9, the credential helper was searching for credentials with
|
||||
// the "dflt" authentication type (see [1]). Since v0.9.0, Get doesn't use
|
||||
// that attribute anymore, and v0.9.0 - v0.9.2 were not setting it here
|
||||
// either.
|
||||
//
|
||||
// In order to keep compatibility with older versions, we need to store
|
||||
// credentials with this attribute set. This way, credentials stored with
|
||||
// newer versions can be retrieved by older versions.
|
||||
//
|
||||
// [1]: https://github.com/docker/docker-credential-helpers/blob/v0.8.2/osxkeychain/osxkeychain.c#L66
|
||||
item.SetAuthenticationType("dflt")
|
||||
if err := splitServer(creds.ServerURL, item); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -121,10 +134,20 @@ func (h Osxkeychain) List() (map[string]string, error) {
|
||||
|
||||
resp := make(map[string]string)
|
||||
for _, r := range res {
|
||||
if r.Path == "" {
|
||||
continue
|
||||
proto := "http"
|
||||
if r.Protocol == kSecProtocolTypeHTTPS {
|
||||
proto = "https"
|
||||
}
|
||||
resp[r.Path] = r.Account
|
||||
host := r.Server
|
||||
if r.Port != 0 {
|
||||
host = net.JoinHostPort(host, strconv.Itoa(int(r.Port)))
|
||||
}
|
||||
u := url.URL{
|
||||
Scheme: proto,
|
||||
Host: host,
|
||||
Path: r.Path,
|
||||
}
|
||||
resp[u.String()] = r.Account
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -15,11 +15,6 @@ func TestOSXKeychainHelper(t *testing.T) {
|
||||
Username: "foobar",
|
||||
Secret: "foobarbaz",
|
||||
}
|
||||
creds1 := &credentials.Credentials{
|
||||
ServerURL: "https://foobar.example.com:2376/v2",
|
||||
Username: "foobarbaz",
|
||||
Secret: "foobar",
|
||||
}
|
||||
helper := Osxkeychain{}
|
||||
if err := helper.Add(creds); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -43,19 +38,49 @@ func TestOSXKeychainHelper(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
helper.Add(creds1)
|
||||
defer helper.Delete(creds1.ServerURL)
|
||||
newauths, err := helper.List()
|
||||
if len(newauths)-len(auths) != 1 {
|
||||
if err == nil {
|
||||
t.Fatalf("Error: len(newauths): %d, len(auths): %d", len(newauths), len(auths))
|
||||
}
|
||||
t.Fatalf("Error: len(newauths): %d, len(auths): %d\n Error= %v", len(newauths), len(auths), err)
|
||||
if _, ok := auths[creds.ServerURL]; !ok {
|
||||
t.Fatalf("server %s not found in list, got: %+v", creds.ServerURL, auths)
|
||||
}
|
||||
|
||||
// Insert another token and check if it is in the list
|
||||
creds1 := &credentials.Credentials{
|
||||
ServerURL: "https://foobar.example.com:2376/v2",
|
||||
Username: "foobarbaz",
|
||||
Secret: "foobar",
|
||||
}
|
||||
helper.Add(creds1)
|
||||
defer helper.Delete(creds1.ServerURL)
|
||||
|
||||
auths, err = helper.List()
|
||||
if err != nil {
|
||||
t.Fatalf("operation List failed: %+v", err)
|
||||
}
|
||||
|
||||
if _, ok := auths[creds.ServerURL]; !ok {
|
||||
t.Fatalf("server %s not found in list, got: %+v", creds.ServerURL, auths)
|
||||
}
|
||||
if _, ok := auths[creds1.ServerURL]; !ok {
|
||||
t.Fatalf("server %s not found in list, got: %+v", creds1.ServerURL, auths)
|
||||
}
|
||||
|
||||
// Delete the 1st token inserted
|
||||
if err := helper.Delete(creds.ServerURL); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
auths, err = helper.List()
|
||||
if err != nil {
|
||||
t.Fatalf("operation List failed: %+v", err)
|
||||
}
|
||||
|
||||
// First token should have been deleted
|
||||
if _, ok := auths[creds.ServerURL]; ok {
|
||||
t.Fatalf("server %s was not deleted, got: %+v", creds.ServerURL, auths)
|
||||
}
|
||||
// Second token should still be there
|
||||
if _, ok := auths[creds1.ServerURL]; !ok {
|
||||
t.Fatalf("server %s not found in list, got: %+v", creds1.ServerURL, auths)
|
||||
}
|
||||
}
|
||||
|
||||
// TestOSXKeychainHelperRetrieveAliases verifies that secrets can be accessed
|
||||
@@ -116,6 +141,39 @@ func TestOSXKeychainHelperRetrieveAliases(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOSXKeychainHelperStoreWithUncleanPath(t *testing.T) {
|
||||
helper := Osxkeychain{}
|
||||
creds := &credentials.Credentials{
|
||||
ServerURL: "https://::1:8080//////location/../../hello",
|
||||
Username: "testuser",
|
||||
Secret: "testsecret",
|
||||
}
|
||||
|
||||
// Clean store before and after the test.
|
||||
defer helper.Delete(creds.ServerURL)
|
||||
if err := helper.Delete(creds.ServerURL); err != nil && !credentials.IsErrCredentialsNotFound(err) {
|
||||
t.Errorf("prepare: failed to delete '%s': %v", creds.ServerURL, err)
|
||||
}
|
||||
|
||||
// Store the credentials
|
||||
if err := helper.Add(creds); err != nil {
|
||||
t.Fatalf("Error: failed to store credentials with unclean path %q: %s", creds.ServerURL, err)
|
||||
}
|
||||
|
||||
// Retrieve and verify credentials
|
||||
username, secret, err := helper.Get(creds.ServerURL)
|
||||
if err != nil {
|
||||
t.Fatalf("Error: failed to retrieve credentials with unclean path %q: %s", creds.ServerURL, err)
|
||||
}
|
||||
|
||||
if username != creds.Username {
|
||||
t.Errorf("Error: expected username %s, got %s", creds.Username, username)
|
||||
}
|
||||
if secret != creds.Secret {
|
||||
t.Errorf("Error: expected secret %s, got %s", creds.Secret, secret)
|
||||
}
|
||||
}
|
||||
|
||||
// TestOSXKeychainHelperRetrieveStrict verifies that only matching secrets are
|
||||
// returned.
|
||||
func TestOSXKeychainHelperRetrieveStrict(t *testing.T) {
|
||||
|
||||
+2
-2
@@ -83,10 +83,10 @@ func TestPassHelperList(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
for server, username := range credsList {
|
||||
if !(strings.HasSuffix(server, "2376/v1") || strings.HasSuffix(server, "2375/v1")) {
|
||||
if !strings.HasSuffix(server, "2376/v1") && !strings.HasSuffix(server, "2375/v1") {
|
||||
t.Errorf("invalid url: %s", server)
|
||||
}
|
||||
if !(username == "foo" || username == "bar") {
|
||||
if username != "foo" && username != "bar" {
|
||||
t.Errorf("invalid username: %v", username)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user