Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions cli/command/registry/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package registry

import (
"fmt"
"io/ioutil"

"golang.org/x/net/context"

Expand All @@ -16,6 +17,7 @@ type loginOptions struct {
serverAddress string
user string
password string
passwordFile string
}

// NewLoginCommand creates a new `docker login` command
Expand All @@ -39,14 +41,64 @@ func NewLoginCommand(dockerCli command.Cli) *cobra.Command {

flags.StringVarP(&opts.user, "username", "u", "", "Username")
flags.StringVarP(&opts.password, "password", "p", "", "Password")
flags.StringVarP(&opts.passwordFile, "password-file", "", "", "Password file whose contents are the password itself")

return cmd
}

// getPasswordFromFile reads the contents of the file, or stdin if the file is
// == "-".
//
// It also trims off the last \n in the file, if it exists. Most people don't
// have \ns in their password, and this allows stuff like echo "password" >
// foo, without having to remember to pass -n, or vi, which can be configured
// to automatically append newlines, etc.
//
// For users that do have a \n as the last character of their password, they
// need to store it as \n\n. I think this conforms to the principle of least
// surprise, but I could be wrong :)
func getPasswordFromFile(dockerCli command.Cli, name string) (string, error) {
var err error
var raw []byte

if name == "-" {
raw, err = ioutil.ReadAll(dockerCli.In())
} else {
raw, err = ioutil.ReadFile(name)
}

if err != nil {
return "", err
}

contents := string(raw)
if contents[len(contents)-1] == '\n' {
contents = contents[:len(contents)-1]
}

return contents, nil
}

func runLogin(dockerCli command.Cli, opts loginOptions) error {
ctx := context.Background()
clnt := dockerCli.Client()

if opts.password != "" {
fmt.Fprintf(dockerCli.Err(), "Using --password via the CLI is insecure. Please use --password-file.\n")
if opts.passwordFile != "" {
return errors.Errorf("--password and --password-file are mutually exclusive")
}
}

if opts.passwordFile != "" {
contents, err := getPasswordFromFile(dockerCli, opts.passwordFile)
if err != nil {
return err
}

opts.password = contents
}

var (
serverAddress string
authServer = command.ElectAuthServer(ctx, dockerCli)
Expand Down