mirror of
https://github.com/docker/docker-credential-helpers.git
synced 2026-06-13 16:01:28 +05:30
Merge pull request #8 from calavera/secret_name
Move away from password as a name. We store secrets.
This commit is contained in:
@@ -45,7 +45,7 @@ Set the `credsStore` option in your `.docker/config.json` file with the suffix o
|
||||
|
||||
A credential helper can be any program that can read values from the standard input. We use the first argument in the command line to differentiate the kind of command to execute. There are three valid values:
|
||||
|
||||
- `store`: Adds credentials to the keychain. The payload in the standard input is a JSON document with `ServerURL`, `Username` and `Password`.
|
||||
- `store`: Adds credentials to the keychain. The payload in the standard input is a JSON document with `ServerURL`, `Username` and `Secret`.
|
||||
- `get`: Retrieves credentials from the keychain. The payload in the standard input is the raw value for the `ServerURL`.
|
||||
- `erase`: Removes credentials from the keychain. The payload in the standard input is the raw value for the `ServerURL`.
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
type credentialsGetResponse struct {
|
||||
Username string
|
||||
Password string
|
||||
Secret string
|
||||
}
|
||||
|
||||
// Serve initializes the credentials helper and parses the action argument.
|
||||
@@ -73,14 +73,14 @@ func get(helper Helper, reader io.Reader, writer io.Writer) error {
|
||||
|
||||
serverURL := strings.TrimSpace(buffer.String())
|
||||
|
||||
username, password, err := helper.Get(serverURL)
|
||||
username, secret, err := helper.Get(serverURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp := credentialsGetResponse{
|
||||
Username: username,
|
||||
Password: password,
|
||||
Secret: secret,
|
||||
}
|
||||
|
||||
buffer.Reset()
|
||||
|
||||
@@ -33,7 +33,7 @@ func (m *memoryStore) Get(serverURL string) (string, string, error) {
|
||||
if !ok {
|
||||
return "", "", fmt.Errorf("creds not found for %s", serverURL)
|
||||
}
|
||||
return c.Username, c.Password, nil
|
||||
return c.Username, c.Secret, nil
|
||||
}
|
||||
|
||||
func TestStore(t *testing.T) {
|
||||
@@ -41,7 +41,7 @@ func TestStore(t *testing.T) {
|
||||
creds := &Credentials{
|
||||
ServerURL: serverURL,
|
||||
Username: "foo",
|
||||
Password: "bar",
|
||||
Secret: "bar",
|
||||
}
|
||||
b, err := json.Marshal(creds)
|
||||
if err != nil {
|
||||
@@ -63,8 +63,8 @@ func TestStore(t *testing.T) {
|
||||
t.Fatalf("expected username foo, got %s\n", c.Username)
|
||||
}
|
||||
|
||||
if c.Password != "bar" {
|
||||
t.Fatalf("expected username bar, got %s\n", c.Password)
|
||||
if c.Secret != "bar" {
|
||||
t.Fatalf("expected username bar, got %s\n", c.Secret)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func TestGet(t *testing.T) {
|
||||
creds := &Credentials{
|
||||
ServerURL: serverURL,
|
||||
Username: "foo",
|
||||
Password: "bar",
|
||||
Secret: "bar",
|
||||
}
|
||||
b, err := json.Marshal(creds)
|
||||
if err != nil {
|
||||
@@ -105,8 +105,8 @@ func TestGet(t *testing.T) {
|
||||
t.Fatalf("expected username foo, got %s\n", c.Username)
|
||||
}
|
||||
|
||||
if c.Password != "bar" {
|
||||
t.Fatalf("expected username bar, got %s\n", c.Password)
|
||||
if c.Secret != "bar" {
|
||||
t.Fatalf("expected username bar, got %s\n", c.Secret)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ func TestErase(t *testing.T) {
|
||||
creds := &Credentials{
|
||||
ServerURL: serverURL,
|
||||
Username: "foo",
|
||||
Password: "bar",
|
||||
Secret: "bar",
|
||||
}
|
||||
b, err := json.Marshal(creds)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,7 +6,7 @@ import "errors"
|
||||
type Credentials struct {
|
||||
ServerURL string
|
||||
Username string
|
||||
Password string
|
||||
Secret string
|
||||
}
|
||||
|
||||
// Helper is the interface a credentials store helper must implement.
|
||||
|
||||
@@ -10,7 +10,7 @@ char *get_error(OSStatus status) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *keychain_add(struct Server *server, char *username, char *password) {
|
||||
char *keychain_add(struct Server *server, char *username, char *secret) {
|
||||
OSStatus status = SecKeychainAddInternetPassword(
|
||||
NULL,
|
||||
strlen(server->host), server->host,
|
||||
@@ -20,7 +20,7 @@ char *keychain_add(struct Server *server, char *username, char *password) {
|
||||
server->port,
|
||||
server->proto,
|
||||
kSecAuthenticationTypeDefault,
|
||||
strlen(password), password,
|
||||
strlen(secret), secret,
|
||||
NULL
|
||||
);
|
||||
if (status) {
|
||||
@@ -29,7 +29,7 @@ char *keychain_add(struct Server *server, char *username, char *password) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *keychain_get(struct Server *server, unsigned int *username_l, char **username, unsigned int *password_l, char **password) {
|
||||
char *keychain_get(struct Server *server, unsigned int *username_l, char **username, unsigned int *secret_l, char **secret) {
|
||||
char *tmp;
|
||||
SecKeychainItemRef item;
|
||||
|
||||
@@ -42,14 +42,14 @@ char *keychain_get(struct Server *server, unsigned int *username_l, char **usern
|
||||
server->port,
|
||||
server->proto,
|
||||
kSecAuthenticationTypeDefault,
|
||||
password_l, (void **)&tmp,
|
||||
secret_l, (void **)&tmp,
|
||||
&item);
|
||||
|
||||
if (status) {
|
||||
return get_error(status);
|
||||
}
|
||||
|
||||
*password = strdup(tmp);
|
||||
*secret = strdup(tmp);
|
||||
SecKeychainItemFreeContent(NULL, tmp);
|
||||
|
||||
SecKeychainAttributeList list;
|
||||
|
||||
@@ -39,10 +39,10 @@ func (h osxkeychain) Add(creds *credentials.Credentials) error {
|
||||
|
||||
username := C.CString(creds.Username)
|
||||
defer C.free(unsafe.Pointer(username))
|
||||
password := C.CString(creds.Password)
|
||||
defer C.free(unsafe.Pointer(password))
|
||||
secret := C.CString(creds.Secret)
|
||||
defer C.free(unsafe.Pointer(secret))
|
||||
|
||||
errMsg := C.keychain_add(s, username, password)
|
||||
errMsg := C.keychain_add(s, username, secret)
|
||||
if errMsg != nil {
|
||||
defer C.free(unsafe.Pointer(errMsg))
|
||||
return errors.New(C.GoString(errMsg))
|
||||
@@ -68,7 +68,7 @@ func (h osxkeychain) Delete(serverURL string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the username and password to use for a given registry server URL.
|
||||
// Get returns the username and secret to use for a given registry server URL.
|
||||
func (h osxkeychain) Get(serverURL string) (string, string, error) {
|
||||
s, err := splitServer(serverURL)
|
||||
if err != nil {
|
||||
@@ -78,12 +78,12 @@ func (h osxkeychain) Get(serverURL string) (string, string, error) {
|
||||
|
||||
var usernameLen C.uint
|
||||
var username *C.char
|
||||
var passwordLen C.uint
|
||||
var password *C.char
|
||||
var secretLen C.uint
|
||||
var secret *C.char
|
||||
defer C.free(unsafe.Pointer(username))
|
||||
defer C.free(unsafe.Pointer(password))
|
||||
defer C.free(unsafe.Pointer(secret))
|
||||
|
||||
errMsg := C.keychain_get(s, &usernameLen, &username, &passwordLen, &password)
|
||||
errMsg := C.keychain_get(s, &usernameLen, &username, &secretLen, &secret)
|
||||
if errMsg != nil {
|
||||
defer C.free(unsafe.Pointer(errMsg))
|
||||
goMsg := C.GoString(errMsg)
|
||||
@@ -96,7 +96,7 @@ func (h osxkeychain) Get(serverURL string) (string, string, error) {
|
||||
}
|
||||
|
||||
user := C.GoStringN(username, C.int(usernameLen))
|
||||
pass := C.GoStringN(password, C.int(passwordLen))
|
||||
pass := C.GoStringN(secret, C.int(secretLen))
|
||||
return user, pass, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,6 @@ struct Server {
|
||||
unsigned int port;
|
||||
};
|
||||
|
||||
char *keychain_add(struct Server *server, char *username, char *password);
|
||||
char *keychain_get(struct Server *server, unsigned int *username_l, char **username, unsigned int *password_l, char **password);
|
||||
char *keychain_add(struct Server *server, char *username, char *secret);
|
||||
char *keychain_get(struct Server *server, unsigned int *username_l, char **username, unsigned int *secret_l, char **secret);
|
||||
char *keychain_delete(struct Server *server);
|
||||
|
||||
@@ -10,7 +10,7 @@ func TestOSXKeychainHelper(t *testing.T) {
|
||||
creds := &credentials.Credentials{
|
||||
ServerURL: "https://foobar.docker.io:2376/v1",
|
||||
Username: "foobar",
|
||||
Password: "foobarbaz",
|
||||
Secret: "foobarbaz",
|
||||
}
|
||||
|
||||
helper := New()
|
||||
@@ -18,7 +18,7 @@ func TestOSXKeychainHelper(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
username, password, err := helper.Get(creds.ServerURL)
|
||||
username, secret, err := helper.Get(creds.ServerURL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -27,8 +27,8 @@ func TestOSXKeychainHelper(t *testing.T) {
|
||||
t.Fatalf("expected %s, got %s\n", "foobar", username)
|
||||
}
|
||||
|
||||
if password != "foobarbaz" {
|
||||
t.Fatalf("expected %s, got %s\n", "foobarbaz", password)
|
||||
if secret != "foobarbaz" {
|
||||
t.Fatalf("expected %s, got %s\n", "foobarbaz", secret)
|
||||
}
|
||||
|
||||
if err := helper.Delete(creds.ServerURL); err != nil {
|
||||
|
||||
@@ -15,11 +15,11 @@ const SecretSchema *docker_get_schema(void)
|
||||
return &docker_schema;
|
||||
}
|
||||
|
||||
GError *add(char *server, char *username, char *password) {
|
||||
GError *add(char *server, char *username, char *secret) {
|
||||
GError *err = NULL;
|
||||
|
||||
secret_password_store_sync (DOCKER_SCHEMA, SECRET_COLLECTION_DEFAULT,
|
||||
server, password, NULL, &err,
|
||||
server, secret, NULL, &err,
|
||||
"server", server,
|
||||
"username", username,
|
||||
"docker_cli", "1",
|
||||
@@ -54,13 +54,13 @@ char *get_username(SecretItem *item) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GError *get(char *server, char **username, char **password) {
|
||||
GError *get(char *server, char **username, char **secret) {
|
||||
GError *err = NULL;
|
||||
GHashTable *attributes;
|
||||
SecretService *service;
|
||||
GList *items, *l;
|
||||
SecretSearchFlags flags = SECRET_SEARCH_LOAD_SECRETS | SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK;
|
||||
SecretValue *secret;
|
||||
SecretValue *secretValue;
|
||||
gsize length;
|
||||
gchar *value;
|
||||
|
||||
@@ -79,10 +79,10 @@ GError *get(char *server, char **username, char **password) {
|
||||
continue;
|
||||
}
|
||||
g_free(value);
|
||||
secret = secret_item_get_secret(l->data);
|
||||
secretValue = secret_item_get_secret(l->data);
|
||||
if (secret != NULL) {
|
||||
*password = strdup(secret_value_get(secret, &length));
|
||||
secret_value_unref(secret);
|
||||
*secret = strdup(secret_value_get(secretValue, &length));
|
||||
secret_value_unref(secretValue);
|
||||
}
|
||||
*username = get_username(l->data);
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ func (h secretservice) Add(creds *credentials.Credentials) error {
|
||||
defer C.free(unsafe.Pointer(server))
|
||||
username := C.CString(creds.Username)
|
||||
defer C.free(unsafe.Pointer(username))
|
||||
password := C.CString(creds.Password)
|
||||
defer C.free(unsafe.Pointer(password))
|
||||
secret := C.CString(creds.Secret)
|
||||
defer C.free(unsafe.Pointer(secret))
|
||||
|
||||
if err := C.add(server, username, password); err != nil {
|
||||
if err := C.add(server, username, secret); err != nil {
|
||||
defer C.g_error_free(err)
|
||||
errMsg := (*C.char)(unsafe.Pointer(err.message))
|
||||
return errors.New(C.GoString(errMsg))
|
||||
@@ -57,26 +57,26 @@ func (h secretservice) Delete(serverURL string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the username and password to use for a given registry server URL.
|
||||
// Get returns the username and secret to use for a given registry server URL.
|
||||
func (h secretservice) Get(serverURL string) (string, string, error) {
|
||||
if serverURL == "" {
|
||||
return "", "", errors.New("missing server url")
|
||||
}
|
||||
var username *C.char
|
||||
defer C.free(unsafe.Pointer(username))
|
||||
var password *C.char
|
||||
defer C.free(unsafe.Pointer(password))
|
||||
var secret *C.char
|
||||
defer C.free(unsafe.Pointer(secret))
|
||||
server := C.CString(serverURL)
|
||||
defer C.free(unsafe.Pointer(server))
|
||||
|
||||
err := C.get(server, &username, &password)
|
||||
err := C.get(server, &username, &secret)
|
||||
if err != nil {
|
||||
defer C.g_error_free(err)
|
||||
errMsg := (*C.char)(unsafe.Pointer(err.message))
|
||||
return "", "", errors.New(C.GoString(errMsg))
|
||||
}
|
||||
user := C.GoString(username)
|
||||
pass := C.GoString(password)
|
||||
pass := C.GoString(secret)
|
||||
if pass == "" {
|
||||
return "", "", credentials.ErrCredentialsNotFound
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@ const SecretSchema *docker_get_schema(void) G_GNUC_CONST;
|
||||
|
||||
#define DOCKER_SCHEMA docker_get_schema()
|
||||
|
||||
GError *add(char *server, char *username, char *password);
|
||||
GError *add(char *server, char *username, char *secret);
|
||||
GError *delete(char *server);
|
||||
GError *get(char *server, char **username, char **password);
|
||||
GError *get(char *server, char **username, char **secret);
|
||||
|
||||
@@ -12,7 +12,7 @@ func TestSecretServiceHelper(t *testing.T) {
|
||||
creds := &credentials.Credentials{
|
||||
ServerURL: "https://foobar.docker.io:2376/v1",
|
||||
Username: "foobar",
|
||||
Password: "foobarbaz",
|
||||
Secret: "foobarbaz",
|
||||
}
|
||||
|
||||
helper := New()
|
||||
@@ -20,7 +20,7 @@ func TestSecretServiceHelper(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
username, password, err := helper.Get(creds.ServerURL)
|
||||
username, secret, err := helper.Get(creds.ServerURL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -29,8 +29,8 @@ func TestSecretServiceHelper(t *testing.T) {
|
||||
t.Fatalf("expected %s, got %s\n", "foobar", username)
|
||||
}
|
||||
|
||||
if password != "foobarbaz" {
|
||||
t.Fatalf("expected %s, got %s\n", "foobarbaz", password)
|
||||
if secret != "foobarbaz" {
|
||||
t.Fatalf("expected %s, got %s\n", "foobarbaz", secret)
|
||||
}
|
||||
|
||||
if err := helper.Delete(creds.ServerURL); err != nil {
|
||||
|
||||
@@ -16,7 +16,7 @@ func New() credentials.Helper {
|
||||
func (h wincred) Add(creds *credentials.Credentials) error {
|
||||
g := winc.NewGenericCredential(creds.ServerURL)
|
||||
g.UserName = creds.Username
|
||||
g.CredentialBlob = []byte(creds.Password)
|
||||
g.CredentialBlob = []byte(creds.Secret)
|
||||
g.Persist = winc.PersistLocalMachine
|
||||
return g.Write()
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ func TestWinCredHelper(t *testing.T) {
|
||||
creds := &credentials.Credentials{
|
||||
ServerURL: "https://foobar.docker.io:2376/v1",
|
||||
Username: "foobar",
|
||||
Password: "foobarbaz",
|
||||
Secret: "foobarbaz",
|
||||
}
|
||||
|
||||
helper := New()
|
||||
@@ -18,7 +18,7 @@ func TestWinCredHelper(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
username, password, err := helper.Get(creds.ServerURL)
|
||||
username, secret, err := helper.Get(creds.ServerURL)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -27,8 +27,8 @@ func TestWinCredHelper(t *testing.T) {
|
||||
t.Fatalf("expected %s, got %s\n", "foobar", username)
|
||||
}
|
||||
|
||||
if password != "foobarbaz" {
|
||||
t.Fatalf("expected %s, got %s\n", "foobarbaz", password)
|
||||
if secret != "foobarbaz" {
|
||||
t.Fatalf("expected %s, got %s\n", "foobarbaz", secret)
|
||||
}
|
||||
|
||||
if err := helper.Delete(creds.ServerURL); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user