libimage: Fix getDockerAuthConfig() for authentication

- We need to set DockerAuthConfig even if we use of
non-IdentityToken credentials.

- This function should be failed when there are multiple
  credential sources, not only `Username` + `Credentials`.

Signed-off-by: Toshiki Sonoda <sonoda.toshiki@fujitsu.com>
This commit is contained in:
Toshiki Sonoda 2023-02-22 14:14:24 +09:00
parent bdaecd9e8d
commit 0bffdb0df5
2 changed files with 32 additions and 52 deletions

View File

@ -167,39 +167,37 @@ var storageAllowedPolicyScopes = signature.PolicyTransportScopes{
}, },
} }
// getDockerAuthConfig extracts a docker auth config from the CopyOptions. Returns // getDockerAuthConfig extracts a docker auth config. Returns nil if
// nil if no credentials are set. // no credentials are set.
func (options *CopyOptions) getDockerAuthConfig() (*types.DockerAuthConfig, error) { func getDockerAuthConfig(name, passwd, creds, idToken string) (*types.DockerAuthConfig, error) {
authConf := &types.DockerAuthConfig{IdentityToken: options.IdentityToken} numCredsSources := 0
if options.Username != "" { if name != "" {
if options.Credentials != "" { numCredsSources++
return nil, errors.New("username/password cannot be used with credentials")
} }
authConf.Username = options.Username if creds != "" {
authConf.Password = options.Password name, passwd, _ = strings.Cut(creds, ":")
return authConf, nil numCredsSources++
} }
if idToken != "" {
if options.Credentials != "" { numCredsSources++
split := strings.SplitN(options.Credentials, ":", 2) }
switch len(split) { authConf := &types.DockerAuthConfig{
case 1: Username: name,
authConf.Username = split[0] Password: passwd,
default: IdentityToken: idToken,
authConf.Username = split[0]
authConf.Password = split[1]
}
return authConf, nil
}
// We should return nil unless a token was set. That's especially
// useful for Podman's remote API.
if options.IdentityToken != "" {
return authConf, nil
} }
switch numCredsSources {
case 0:
// Return nil if there is no credential source.
return nil, nil return nil, nil
case 1:
return authConf, nil
default:
// Cannot use the multiple credential sources.
return nil, errors.New("cannot use the multiple credential sources")
}
} }
// newCopier creates a copier. Note that fields in options *may* overwrite the // newCopier creates a copier. Note that fields in options *may* overwrite the
@ -237,7 +235,7 @@ func (r *Runtime) newCopier(options *CopyOptions) (*copier, error) {
c.systemContext.SignaturePolicyPath = options.SignaturePolicyPath c.systemContext.SignaturePolicyPath = options.SignaturePolicyPath
} }
dockerAuthConfig, err := options.getDockerAuthConfig() dockerAuthConfig, err := getDockerAuthConfig(options.Username, options.Password, options.Credentials, options.IdentityToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -2,7 +2,6 @@ package libimage
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
@ -219,29 +218,12 @@ func (r *Runtime) searchImageInRegistry(ctx context.Context, term, registry stri
sys.DockerCertPath = options.CertDirPath sys.DockerCertPath = options.CertDirPath
} }
authConf := &types.DockerAuthConfig{IdentityToken: options.IdentityToken} dockerAuthConfig, err := getDockerAuthConfig(options.Username, options.Password, options.Credentials, options.IdentityToken)
if options.Username != "" { if err != nil {
if options.Credentials != "" { return nil, err
return nil, errors.New("username/password cannot be used with credentials")
} }
authConf.Username = options.Username if dockerAuthConfig != nil {
authConf.Password = options.Password sys.DockerAuthConfig = dockerAuthConfig
}
if options.Credentials != "" {
split := strings.SplitN(options.Credentials, ":", 2)
switch len(split) {
case 1:
authConf.Username = split[0]
default:
authConf.Username = split[0]
authConf.Password = split[1]
}
}
// We should set the authConf unless a token was set. That's especially
// useful for Podman's remote API.
if options.IdentityToken != "" {
sys.DockerAuthConfig = authConf
} }
if options.ListTags { if options.ListTags {