@@ -18,9 +18,12 @@ package commands
1818
1919import (
2020 "bufio"
21+ "bytes"
2122 gocontext "context"
2223 "crypto/tls"
2324 "crypto/x509"
25+ "encoding/base64"
26+ "encoding/json"
2427 "fmt"
2528 "io"
2629 "io/ioutil"
@@ -56,18 +59,45 @@ func passwordPrompt() (string, error) {
5659 return string (line ), nil
5760}
5861
62+ type authConfig struct {
63+ Auths map [string ]authRecord `json:"auths"`
64+ }
65+
66+ type authRecord struct {
67+ Auth string `json:"auth"`
68+ }
69+
5970// GetResolver prepares the resolver from the environment and options
6071func GetResolver (ctx gocontext.Context , clicontext * cli.Context ) (remotes.Resolver , error ) {
6172 username := clicontext .String ("user" )
6273 var secret string
63- if i := strings .IndexByte (username , ':' ); i > 0 {
74+ if i := strings .IndexByte (username , ':' ); ! strings . HasPrefix ( username , "file:" ) && i > 0 {
6475 secret = username [i + 1 :]
6576 username = username [0 :i ]
6677 }
6778 options := docker.ResolverOptions {
6879 Tracker : PushTracker ,
6980 }
70- if username != "" {
81+ var cfg authConfig
82+ if strings .HasPrefix (username , "file:" ) {
83+ username = strings .TrimPrefix (username , "file:" )
84+ dt , err := ioutil .ReadFile (username )
85+ if err != nil {
86+ return nil , err
87+ }
88+
89+ if err := json .Unmarshal (dt , & cfg ); err != nil {
90+ return nil , err
91+ }
92+
93+ if len (cfg .Auths ) == 0 {
94+ cfg .Auths = map [string ]authRecord {}
95+ if err := json .Unmarshal (dt , & cfg .Auths ); err != nil {
96+ return nil , err
97+ }
98+ }
99+
100+ } else if username != "" {
71101 if secret == "" {
72102 fmt .Printf ("Password: " )
73103
@@ -85,7 +115,22 @@ func GetResolver(ctx gocontext.Context, clicontext *cli.Context) (remotes.Resolv
85115
86116 hostOptions := config.HostOptions {}
87117 hostOptions .Credentials = func (host string ) (string , string , error ) {
88- // If host doesn't match...
118+ if host == "registry-1.docker.io" {
119+ host = "https://index.docker.io/v1/"
120+ }
121+ ac , ok := cfg .Auths [host ]
122+ if ok {
123+ dt , err := base64 .StdEncoding .DecodeString (ac .Auth )
124+ if err != nil {
125+ return "" , "" , err
126+ }
127+ parts := bytes .SplitN (dt , []byte (":" ), 2 )
128+ if len (parts ) != 2 {
129+ return "" , "" , errors .Errorf ("invalid auth config" )
130+ }
131+ username = string (parts [0 ])
132+ secret = string (parts [1 ])
133+ }
89134 // Only one host
90135 return username , secret , nil
91136 }
0 commit comments