TLS verify is skipped per registry.

Signed-off-by: haircommander <pehunt@redhat.com>

Closes: #952
Approved by: rhatdan
This commit is contained in:
haircommander
2018-06-15 19:41:00 -04:00
committed by Atomic Bot
parent 0f2ea23de5
commit d8f2cb8622
3 changed files with 81 additions and 34 deletions

View File

@ -2,19 +2,16 @@ package main
import ( import (
"context" "context"
"fmt"
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
"github.com/containers/image/docker" "github.com/containers/image/docker"
"github.com/containers/image/types"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats" "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime" "github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod/common" "github.com/projectatomic/libpod/libpod/common"
sysreg "github.com/projectatomic/libpod/pkg/registries" sysreg "github.com/projectatomic/libpod/pkg/registries"
"github.com/projectatomic/libpod/pkg/util"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -113,7 +110,7 @@ func searchCmd(c *cli.Context) error {
limit: c.Int("limit"), limit: c.Int("limit"),
filter: c.StringSlice("filter"), filter: c.StringSlice("filter"),
} }
registries, sc, err := getSystemContextAndRegistries(c) regAndSkipTLS, err := getRegistriesAndSkipTLS(c)
if err != nil { if err != nil {
return err return err
} }
@ -123,7 +120,7 @@ func searchCmd(c *cli.Context) error {
return err return err
} }
return generateSearchOutput(term, registries, opts, *filter, sc) return generateSearchOutput(term, regAndSkipTLS, opts, *filter)
} }
func genSearchFormat(format string) string { func genSearchFormat(format string) string {
@ -154,11 +151,8 @@ func (s *searchParams) headerMap() map[string]string {
return values return values
} }
// A wrapper for GetSystemContext and GetInsecureRegistries // A function for finding which registries can skip TLS
// Sets up system context and active list of registries to search with func getRegistriesAndSkipTLS(c *cli.Context) (map[string]bool, error) {
func getSystemContextAndRegistries(c *cli.Context) ([]string, *types.SystemContext, error) {
sc := common.GetSystemContext("", "", false)
// Variables for setting up Registry and TLSVerify // Variables for setting up Registry and TLSVerify
tlsVerify := c.BoolT("tls-verify") tlsVerify := c.BoolT("tls-verify")
forceSecure := false forceSecure := false
@ -174,42 +168,49 @@ func getSystemContextAndRegistries(c *cli.Context) ([]string, *types.SystemConte
var err error var err error
registries, err = sysreg.GetRegistries() registries, err = sysreg.GetRegistries()
if err != nil { if err != nil {
return nil, nil, errors.Wrapf(err, "error getting registries to search") return nil, errors.Wrapf(err, "error getting registries to search")
} }
} }
regAndSkipTLS := make(map[string]bool)
// If user flagged to skip verify for HTTP connections, set System Context as such
if !tlsVerify {
// If tls-verify is set to false, allow insecure always. // If tls-verify is set to false, allow insecure always.
sc.DockerInsecureSkipTLSVerify = true if !tlsVerify {
} else if !forceSecure { for _, reg := range registries {
regAndSkipTLS[reg] = true
}
} else {
// initially set all registries to verify with TLS
for _, reg := range registries {
regAndSkipTLS[reg] = false
}
// if the user didn't allow nor disallow insecure registries, check to see if the registry is insecure // if the user didn't allow nor disallow insecure registries, check to see if the registry is insecure
if !forceSecure {
insecureRegistries, err := sysreg.GetInsecureRegistries() insecureRegistries, err := sysreg.GetInsecureRegistries()
if err != nil { if err != nil {
return nil, nil, errors.Wrapf(err, "error getting insecure registries to search") return nil, errors.Wrapf(err, "error getting insecure registries to search")
} }
for _, reg := range insecureRegistries { for _, reg := range insecureRegistries {
// if there are any insecure registries in registries, allow for HTTP // if there are any insecure registries in registries, allow for HTTP
if util.StringInSlice(reg, registries) { if _, ok := regAndSkipTLS[reg]; ok {
sc.DockerInsecureSkipTLSVerify = true regAndSkipTLS[reg] = true
logrus.Info(fmt.Sprintf("%s is an insecure registry; searching with tls-verify=false", reg))
break
} }
} }
} }
return registries, sc, nil }
return regAndSkipTLS, nil
} }
func getSearchOutput(term string, registries []string, opts searchOpts, filter searchFilterParams, sc *types.SystemContext) ([]searchParams, error) { func getSearchOutput(term string, regAndSkipTLS map[string]bool, opts searchOpts, filter searchFilterParams) ([]searchParams, error) {
// Max number of queries by default is 25 // Max number of queries by default is 25
limit := maxQueries limit := maxQueries
if opts.limit != 0 { if opts.limit != 0 {
limit = opts.limit limit = opts.limit
} }
sc := common.GetSystemContext("", "", false)
var paramsArr []searchParams var paramsArr []searchParams
for _, reg := range registries { for reg, skipTLS := range regAndSkipTLS {
// set the SkipTLSVerify bool depending on the registry being searched through
sc.DockerInsecureSkipTLSVerify = skipTLS
results, err := docker.SearchRegistry(context.TODO(), sc, reg, term, limit) results, err := docker.SearchRegistry(context.TODO(), sc, reg, term, limit)
if err != nil { if err != nil {
logrus.Errorf("error searching registry %q: %v", reg, err) logrus.Errorf("error searching registry %q: %v", reg, err)
@ -269,8 +270,8 @@ func getSearchOutput(term string, registries []string, opts searchOpts, filter s
return paramsArr, nil return paramsArr, nil
} }
func generateSearchOutput(term string, registries []string, opts searchOpts, filter searchFilterParams, sc *types.SystemContext) error { func generateSearchOutput(term string, regAndSkipTLS map[string]bool, opts searchOpts, filter searchFilterParams) error {
searchOutput, err := getSearchOutput(term, registries, opts, filter, sc) searchOutput, err := getSearchOutput(term, regAndSkipTLS, opts, filter)
if err != nil { if err != nil {
return err return err
} }

View File

@ -73,8 +73,9 @@ Specific registry to search (only the given registry will be searched, not the d
**--tls-verify** **--tls-verify**
Require HTTPS and verify certificates when contacting registries (default: true). If explicitly set to true, Require HTTPS and verify certificates when contacting registries (default: true). If explicitly set to true,
then tls verification will be used, If set to false then tls verification will not be used. If not specified then tls verification will be used. If set to false then tls verification will not be used if needed. If not specified
both insecured and default registries will be searched through, and tls will be used when possible. default registries will be searched through (in /etc/containers/registries.conf), and tls will be skipped if a default
registry is listed in the insecure registries.
## EXAMPLES ## EXAMPLES

View File

@ -29,6 +29,13 @@ var _ = Describe("Podman search", func() {
# empty # empty
[registries.insecure] [registries.insecure]
registries = []` registries = []`
const regFileContents2 = `
[registries.search]
registries = ['localhost:5000', 'localhost:6000']
[registries.insecure]
registries = ['localhost:5000']`
BeforeEach(func() { BeforeEach(func() {
tempdir, err = CreateTempDirInTempDir() tempdir, err = CreateTempDirInTempDir()
if err != nil { if err != nil {
@ -240,4 +247,42 @@ var _ = Describe("Podman search", func() {
// cleanup // cleanup
os.Setenv("REGISTRIES_CONFIG_PATH", "") os.Setenv("REGISTRIES_CONFIG_PATH", "")
}) })
It("podman search doesn't attempt HTTP if one registry is not listed as insecure", func() {
registry := podmanTest.Podman([]string{"run", "-d", "-p", "5000:5000", "--name", "registry7", "registry:2"})
registry.WaitWithDefaultTimeout()
Expect(registry.ExitCode()).To(Equal(0))
if !WaitContainerReady(&podmanTest, "registry7", "listening on", 20, 1) {
Skip("Can not start docker registry.")
}
registry = podmanTest.Podman([]string{"run", "-d", "-p", "6000:5000", "--name", "registry8", "registry:2"})
registry.WaitWithDefaultTimeout()
Expect(registry.ExitCode()).To(Equal(0))
if !WaitContainerReady(&podmanTest, "registry8", "listening on", 20, 1) {
Skip("Can not start docker registry.")
}
push := podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:6000/my-alpine"})
push.WaitWithDefaultTimeout()
Expect(push.ExitCode()).To(Equal(0))
// registries.conf set up
regFileBytes := []byte(regFileContents2)
outfile := filepath.Join(podmanTest.TempDir, "registries.conf")
os.Setenv("REGISTRIES_CONFIG_PATH", outfile)
ioutil.WriteFile(outfile, regFileBytes, 0644)
search := podmanTest.Podman([]string{"search", "my-alpine"})
search.WaitWithDefaultTimeout()
Expect(search.ExitCode()).To(Equal(0))
Expect(search.OutputToString()).Should(BeEmpty())
match, _ := search.ErrorGrepString("error")
Expect(match).Should(BeTrue())
// cleanup
os.Setenv("REGISTRIES_CONFIG_PATH", "")
})
}) })