Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

Commit

Permalink
print a big warning about cleartext passwords
Browse files Browse the repository at this point in the history
Signed-off-by: Tycho Andersen <tycho@docker.com>
Upstream-commit: 4290df395808d1780afcb1a4c2656497050d5fae
Component: cli
  • Loading branch information
vdemeester committed Mar 26, 2018
1 parent 6b1c8c0 commit 72976c8
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
43 changes: 41 additions & 2 deletions components/cli/cli/command/registry/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import (
"github.com/spf13/cobra"
)

const unencryptedWarning = `WARNING! Your password will be stored unencrypted in %s.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
`

type loginOptions struct {
serverAddress string
user string
Expand Down Expand Up @@ -50,6 +55,29 @@ func NewLoginCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}

// unencryptedPrompt prompts the user to find out whether they want to continue
// with insecure credential storage. If stdin is not a terminal, we assume they
// want it (sadly), because people may have been scripting insecure logins and
// we don't want to break them. Maybe they'll see the warning in their logs and
// fix things.
func unencryptedPrompt(dockerCli command.Streams, filename string) error {
fmt.Fprintln(dockerCli.Err(), fmt.Sprintf(unencryptedWarning, filename))

if dockerCli.In().IsTerminal() {
if command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), "") {
return nil
}
return errors.Errorf("User refused unencrypted credentials storage.")
}

return nil
}

type isFileStore interface {
IsFileStore() bool
GetFilename() string
}

func verifyloginOptions(dockerCli command.Cli, opts *loginOptions) error {
if opts.password != "" {
fmt.Fprintln(dockerCli.Err(), "WARNING! Using --password via the CLI is insecure. Use --password-stdin.")
Expand All @@ -74,7 +102,7 @@ func verifyloginOptions(dockerCli command.Cli, opts *loginOptions) error {
return nil
}

func runLogin(dockerCli command.Cli, opts loginOptions) error {
func runLogin(dockerCli command.Cli, opts loginOptions) error { //nolint: gocyclo
ctx := context.Background()
clnt := dockerCli.Client()
if err := verifyloginOptions(dockerCli, &opts); err != nil {
Expand Down Expand Up @@ -113,7 +141,18 @@ func runLogin(dockerCli command.Cli, opts loginOptions) error {
authConfig.Password = ""
authConfig.IdentityToken = response.IdentityToken
}
if err := dockerCli.ConfigFile().GetCredentialsStore(serverAddress).Store(*authConfig); err != nil {

creds := dockerCli.ConfigFile().GetCredentialsStore(serverAddress)

store, isDefault := creds.(isFileStore)
if isDefault {
err = unencryptedPrompt(dockerCli, store.GetFilename())
if err != nil {
return err
}
}

if err := creds.Store(*authConfig); err != nil {
return errors.Errorf("Error saving credentials: %v", err)
}

Expand Down
5 changes: 5 additions & 0 deletions components/cli/cli/config/configfile/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,8 @@ func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig,
}
return auths, nil
}

// GetFilename returns the file name that this config file is based on.
func (configFile *ConfigFile) GetFilename() string {
return configFile.Filename
}
9 changes: 9 additions & 0 deletions components/cli/cli/config/credentials/file_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
type store interface {
Save() error
GetAuthConfigs() map[string]types.AuthConfig
GetFilename() string
}

// fileStore implements a credentials store using
Expand Down Expand Up @@ -53,3 +54,11 @@ func (c *fileStore) Store(authConfig types.AuthConfig) error {
c.file.GetAuthConfigs()[authConfig.ServerAddress] = authConfig
return c.file.Save()
}

func (c *fileStore) GetFilename() string {
return c.file.GetFilename()
}

func (c *fileStore) IsFileStore() bool {
return true
}
4 changes: 4 additions & 0 deletions components/cli/cli/config/credentials/file_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ func (f *fakeStore) GetAuthConfigs() map[string]types.AuthConfig {
return f.configs
}

func (f *fakeStore) GetFilename() string {
return "/tmp/docker-fakestore"
}

func newStore(auths map[string]types.AuthConfig) store {
return &fakeStore{configs: auths}
}
Expand Down

0 comments on commit 72976c8

Please sign in to comment.