1
0
mirror of https://github.com/docker/docker-credential-helpers.git synced 2026-06-13 16:01:28 +05:30

Move away from password as a name. We store secrets.

Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
David Calavera
2016-03-09 15:18:48 -05:00
parent 0fb2225199
commit 2275377a31
14 changed files with 59 additions and 59 deletions
+1 -1
View File
@@ -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: 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`. - `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`. - `erase`: Removes credentials from the keychain. The payload in the standard input is the raw value for the `ServerURL`.
+3 -3
View File
@@ -12,7 +12,7 @@ import (
type credentialsGetResponse struct { type credentialsGetResponse struct {
Username string Username string
Password string Secret string
} }
// Serve initializes the credentials helper and parses the action argument. // 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()) serverURL := strings.TrimSpace(buffer.String())
username, password, err := helper.Get(serverURL) username, secret, err := helper.Get(serverURL)
if err != nil { if err != nil {
return err return err
} }
resp := credentialsGetResponse{ resp := credentialsGetResponse{
Username: username, Username: username,
Password: password, Secret: secret,
} }
buffer.Reset() buffer.Reset()
+8 -8
View File
@@ -33,7 +33,7 @@ func (m *memoryStore) Get(serverURL string) (string, string, error) {
if !ok { if !ok {
return "", "", fmt.Errorf("creds not found for %s", serverURL) 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) { func TestStore(t *testing.T) {
@@ -41,7 +41,7 @@ func TestStore(t *testing.T) {
creds := &Credentials{ creds := &Credentials{
ServerURL: serverURL, ServerURL: serverURL,
Username: "foo", Username: "foo",
Password: "bar", Secret: "bar",
} }
b, err := json.Marshal(creds) b, err := json.Marshal(creds)
if err != nil { if err != nil {
@@ -63,8 +63,8 @@ func TestStore(t *testing.T) {
t.Fatalf("expected username foo, got %s\n", c.Username) t.Fatalf("expected username foo, got %s\n", c.Username)
} }
if c.Password != "bar" { if c.Secret != "bar" {
t.Fatalf("expected username bar, got %s\n", c.Password) t.Fatalf("expected username bar, got %s\n", c.Secret)
} }
} }
@@ -73,7 +73,7 @@ func TestGet(t *testing.T) {
creds := &Credentials{ creds := &Credentials{
ServerURL: serverURL, ServerURL: serverURL,
Username: "foo", Username: "foo",
Password: "bar", Secret: "bar",
} }
b, err := json.Marshal(creds) b, err := json.Marshal(creds)
if err != nil { if err != nil {
@@ -105,8 +105,8 @@ func TestGet(t *testing.T) {
t.Fatalf("expected username foo, got %s\n", c.Username) t.Fatalf("expected username foo, got %s\n", c.Username)
} }
if c.Password != "bar" { if c.Secret != "bar" {
t.Fatalf("expected username bar, got %s\n", c.Password) t.Fatalf("expected username bar, got %s\n", c.Secret)
} }
} }
@@ -115,7 +115,7 @@ func TestErase(t *testing.T) {
creds := &Credentials{ creds := &Credentials{
ServerURL: serverURL, ServerURL: serverURL,
Username: "foo", Username: "foo",
Password: "bar", Secret: "bar",
} }
b, err := json.Marshal(creds) b, err := json.Marshal(creds)
if err != nil { if err != nil {
+1 -1
View File
@@ -6,7 +6,7 @@ import "errors"
type Credentials struct { type Credentials struct {
ServerURL string ServerURL string
Username string Username string
Password string Secret string
} }
// Helper is the interface a credentials store helper must implement. // Helper is the interface a credentials store helper must implement.
+5 -5
View File
@@ -10,7 +10,7 @@ char *get_error(OSStatus status) {
return buf; 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( OSStatus status = SecKeychainAddInternetPassword(
NULL, NULL,
strlen(server->host), server->host, strlen(server->host), server->host,
@@ -20,7 +20,7 @@ char *keychain_add(struct Server *server, char *username, char *password) {
server->port, server->port,
server->proto, server->proto,
kSecAuthenticationTypeDefault, kSecAuthenticationTypeDefault,
strlen(password), password, strlen(secret), secret,
NULL NULL
); );
if (status) { if (status) {
@@ -29,7 +29,7 @@ char *keychain_add(struct Server *server, char *username, char *password) {
return NULL; 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; char *tmp;
SecKeychainItemRef item; SecKeychainItemRef item;
@@ -42,14 +42,14 @@ char *keychain_get(struct Server *server, unsigned int *username_l, char **usern
server->port, server->port,
server->proto, server->proto,
kSecAuthenticationTypeDefault, kSecAuthenticationTypeDefault,
password_l, (void **)&tmp, secret_l, (void **)&tmp,
&item); &item);
if (status) { if (status) {
return get_error(status); return get_error(status);
} }
*password = strdup(tmp); *secret = strdup(tmp);
SecKeychainItemFreeContent(NULL, tmp); SecKeychainItemFreeContent(NULL, tmp);
SecKeychainAttributeList list; SecKeychainAttributeList list;
+9 -9
View File
@@ -39,10 +39,10 @@ func (h osxkeychain) Add(creds *credentials.Credentials) error {
username := C.CString(creds.Username) username := C.CString(creds.Username)
defer C.free(unsafe.Pointer(username)) defer C.free(unsafe.Pointer(username))
password := C.CString(creds.Password) secret := C.CString(creds.Secret)
defer C.free(unsafe.Pointer(password)) defer C.free(unsafe.Pointer(secret))
errMsg := C.keychain_add(s, username, password) errMsg := C.keychain_add(s, username, secret)
if errMsg != nil { if errMsg != nil {
defer C.free(unsafe.Pointer(errMsg)) defer C.free(unsafe.Pointer(errMsg))
return errors.New(C.GoString(errMsg)) return errors.New(C.GoString(errMsg))
@@ -68,7 +68,7 @@ func (h osxkeychain) Delete(serverURL string) error {
return nil 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) { func (h osxkeychain) Get(serverURL string) (string, string, error) {
s, err := splitServer(serverURL) s, err := splitServer(serverURL)
if err != nil { if err != nil {
@@ -78,12 +78,12 @@ func (h osxkeychain) Get(serverURL string) (string, string, error) {
var usernameLen C.uint var usernameLen C.uint
var username *C.char var username *C.char
var passwordLen C.uint var secretLen C.uint
var password *C.char var secret *C.char
defer C.free(unsafe.Pointer(username)) 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 { if errMsg != nil {
defer C.free(unsafe.Pointer(errMsg)) defer C.free(unsafe.Pointer(errMsg))
goMsg := C.GoString(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)) 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 return user, pass, nil
} }
+2 -2
View File
@@ -7,6 +7,6 @@ struct Server {
unsigned int port; unsigned int port;
}; };
char *keychain_add(struct Server *server, char *username, 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 *password_l, char **password); char *keychain_get(struct Server *server, unsigned int *username_l, char **username, unsigned int *secret_l, char **secret);
char *keychain_delete(struct Server *server); char *keychain_delete(struct Server *server);
+4 -4
View File
@@ -10,7 +10,7 @@ func TestOSXKeychainHelper(t *testing.T) {
creds := &credentials.Credentials{ creds := &credentials.Credentials{
ServerURL: "https://foobar.docker.io:2376/v1", ServerURL: "https://foobar.docker.io:2376/v1",
Username: "foobar", Username: "foobar",
Password: "foobarbaz", Secret: "foobarbaz",
} }
helper := New() helper := New()
@@ -18,7 +18,7 @@ func TestOSXKeychainHelper(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
username, password, err := helper.Get(creds.ServerURL) username, secret, err := helper.Get(creds.ServerURL)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -27,8 +27,8 @@ func TestOSXKeychainHelper(t *testing.T) {
t.Fatalf("expected %s, got %s\n", "foobar", username) t.Fatalf("expected %s, got %s\n", "foobar", username)
} }
if password != "foobarbaz" { if secret != "foobarbaz" {
t.Fatalf("expected %s, got %s\n", "foobarbaz", password) t.Fatalf("expected %s, got %s\n", "foobarbaz", secret)
} }
if err := helper.Delete(creds.ServerURL); err != nil { if err := helper.Delete(creds.ServerURL); err != nil {
+7 -7
View File
@@ -15,11 +15,11 @@ const SecretSchema *docker_get_schema(void)
return &docker_schema; return &docker_schema;
} }
GError *add(char *server, char *username, char *password) { GError *add(char *server, char *username, char *secret) {
GError *err = NULL; GError *err = NULL;
secret_password_store_sync (DOCKER_SCHEMA, SECRET_COLLECTION_DEFAULT, secret_password_store_sync (DOCKER_SCHEMA, SECRET_COLLECTION_DEFAULT,
server, password, NULL, &err, server, secret, NULL, &err,
"server", server, "server", server,
"username", username, "username", username,
"docker_cli", "1", "docker_cli", "1",
@@ -54,13 +54,13 @@ char *get_username(SecretItem *item) {
return NULL; return NULL;
} }
GError *get(char *server, char **username, char **password) { GError *get(char *server, char **username, char **secret) {
GError *err = NULL; GError *err = NULL;
GHashTable *attributes; GHashTable *attributes;
SecretService *service; SecretService *service;
GList *items, *l; GList *items, *l;
SecretSearchFlags flags = SECRET_SEARCH_LOAD_SECRETS | SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK; SecretSearchFlags flags = SECRET_SEARCH_LOAD_SECRETS | SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK;
SecretValue *secret; SecretValue *secretValue;
gsize length; gsize length;
gchar *value; gchar *value;
@@ -79,10 +79,10 @@ GError *get(char *server, char **username, char **password) {
continue; continue;
} }
g_free(value); g_free(value);
secret = secret_item_get_secret(l->data); secretValue = secret_item_get_secret(l->data);
if (secret != NULL) { if (secret != NULL) {
*password = strdup(secret_value_get(secret, &length)); *secret = strdup(secret_value_get(secretValue, &length));
secret_value_unref(secret); secret_value_unref(secretValue);
} }
*username = get_username(l->data); *username = get_username(l->data);
} }
+8 -8
View File
@@ -30,10 +30,10 @@ func (h secretservice) Add(creds *credentials.Credentials) error {
defer C.free(unsafe.Pointer(server)) defer C.free(unsafe.Pointer(server))
username := C.CString(creds.Username) username := C.CString(creds.Username)
defer C.free(unsafe.Pointer(username)) defer C.free(unsafe.Pointer(username))
password := C.CString(creds.Password) secret := C.CString(creds.Secret)
defer C.free(unsafe.Pointer(password)) 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) defer C.g_error_free(err)
errMsg := (*C.char)(unsafe.Pointer(err.message)) errMsg := (*C.char)(unsafe.Pointer(err.message))
return errors.New(C.GoString(errMsg)) return errors.New(C.GoString(errMsg))
@@ -57,26 +57,26 @@ func (h secretservice) Delete(serverURL string) error {
return nil 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) { func (h secretservice) Get(serverURL string) (string, string, error) {
if serverURL == "" { if serverURL == "" {
return "", "", errors.New("missing server url") return "", "", errors.New("missing server url")
} }
var username *C.char var username *C.char
defer C.free(unsafe.Pointer(username)) defer C.free(unsafe.Pointer(username))
var password *C.char var secret *C.char
defer C.free(unsafe.Pointer(password)) defer C.free(unsafe.Pointer(secret))
server := C.CString(serverURL) server := C.CString(serverURL)
defer C.free(unsafe.Pointer(server)) defer C.free(unsafe.Pointer(server))
err := C.get(server, &username, &password) err := C.get(server, &username, &secret)
if err != nil { if err != nil {
defer C.g_error_free(err) defer C.g_error_free(err)
errMsg := (*C.char)(unsafe.Pointer(err.message)) errMsg := (*C.char)(unsafe.Pointer(err.message))
return "", "", errors.New(C.GoString(errMsg)) return "", "", errors.New(C.GoString(errMsg))
} }
user := C.GoString(username) user := C.GoString(username)
pass := C.GoString(password) pass := C.GoString(secret)
if pass == "" { if pass == "" {
return "", "", credentials.ErrCredentialsNotFound return "", "", credentials.ErrCredentialsNotFound
} }
+2 -2
View File
@@ -6,6 +6,6 @@ const SecretSchema *docker_get_schema(void) G_GNUC_CONST;
#define DOCKER_SCHEMA docker_get_schema() #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 *delete(char *server);
GError *get(char *server, char **username, char **password); GError *get(char *server, char **username, char **secret);
+4 -4
View File
@@ -12,7 +12,7 @@ func TestSecretServiceHelper(t *testing.T) {
creds := &credentials.Credentials{ creds := &credentials.Credentials{
ServerURL: "https://foobar.docker.io:2376/v1", ServerURL: "https://foobar.docker.io:2376/v1",
Username: "foobar", Username: "foobar",
Password: "foobarbaz", Secret: "foobarbaz",
} }
helper := New() helper := New()
@@ -20,7 +20,7 @@ func TestSecretServiceHelper(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
username, password, err := helper.Get(creds.ServerURL) username, secret, err := helper.Get(creds.ServerURL)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -29,8 +29,8 @@ func TestSecretServiceHelper(t *testing.T) {
t.Fatalf("expected %s, got %s\n", "foobar", username) t.Fatalf("expected %s, got %s\n", "foobar", username)
} }
if password != "foobarbaz" { if secret != "foobarbaz" {
t.Fatalf("expected %s, got %s\n", "foobarbaz", password) t.Fatalf("expected %s, got %s\n", "foobarbaz", secret)
} }
if err := helper.Delete(creds.ServerURL); err != nil { if err := helper.Delete(creds.ServerURL); err != nil {
+1 -1
View File
@@ -16,7 +16,7 @@ func New() credentials.Helper {
func (h wincred) Add(creds *credentials.Credentials) error { func (h wincred) Add(creds *credentials.Credentials) error {
g := winc.NewGenericCredential(creds.ServerURL) g := winc.NewGenericCredential(creds.ServerURL)
g.UserName = creds.Username g.UserName = creds.Username
g.CredentialBlob = []byte(creds.Password) g.CredentialBlob = []byte(creds.Secret)
g.Persist = winc.PersistLocalMachine g.Persist = winc.PersistLocalMachine
return g.Write() return g.Write()
} }
+4 -4
View File
@@ -10,7 +10,7 @@ func TestWinCredHelper(t *testing.T) {
creds := &credentials.Credentials{ creds := &credentials.Credentials{
ServerURL: "https://foobar.docker.io:2376/v1", ServerURL: "https://foobar.docker.io:2376/v1",
Username: "foobar", Username: "foobar",
Password: "foobarbaz", Secret: "foobarbaz",
} }
helper := New() helper := New()
@@ -18,7 +18,7 @@ func TestWinCredHelper(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
username, password, err := helper.Get(creds.ServerURL) username, secret, err := helper.Get(creds.ServerURL)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -27,8 +27,8 @@ func TestWinCredHelper(t *testing.T) {
t.Fatalf("expected %s, got %s\n", "foobar", username) t.Fatalf("expected %s, got %s\n", "foobar", username)
} }
if password != "foobarbaz" { if secret != "foobarbaz" {
t.Fatalf("expected %s, got %s\n", "foobarbaz", password) t.Fatalf("expected %s, got %s\n", "foobarbaz", secret)
} }
if err := helper.Delete(creds.ServerURL); err != nil { if err := helper.Delete(creds.ServerURL); err != nil {