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

View File

@ -73,8 +73,9 @@ Specific registry to search (only the given registry will be searched, not the d
**--tls-verify**
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
both insecured and default registries will be searched through, and tls will be used when possible.
then tls verification will be used. If set to false then tls verification will not be used if needed. If not specified
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

View File

@ -29,6 +29,13 @@ var _ = Describe("Podman search", func() {
# empty
[registries.insecure]
registries = []`
const regFileContents2 = `
[registries.search]
registries = ['localhost:5000', 'localhost:6000']
[registries.insecure]
registries = ['localhost:5000']`
BeforeEach(func() {
tempdir, err = CreateTempDirInTempDir()
if err != nil {
@ -240,4 +247,42 @@ var _ = Describe("Podman search", func() {
// cleanup
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", "")
})
})