Permalink
Browse files

cmd: per command tls flags

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
  • Loading branch information...
1 parent 93cde78 commit 1215f5fe69f4275fa43fd36cc5d6d5ca300074bb @runcom runcom committed Dec 3, 2016
View
@@ -13,12 +13,12 @@ import (
// contextsFromGlobalOptions returns source and destionation types.SystemContext depending on c.
func contextsFromGlobalOptions(c *cli.Context) (*types.SystemContext, *types.SystemContext, error) {
- sourceCtx, err := contextFromGlobalOptions(c, "src-creds")
+ sourceCtx, err := contextFromGlobalOptions(c, "src-")
if err != nil {
return nil, nil, err
}
- destinationCtx, err := contextFromGlobalOptions(c, "dest-creds")
+ destinationCtx, err := contextFromGlobalOptions(c, "dest-")
if err != nil {
return nil, nil, err
}
@@ -87,5 +87,23 @@ var copyCmd = cli.Command{
Value: "",
Usage: "Use `USERNAME[:PASSWORD]` for accessing the destination registry",
},
+ cli.StringFlag{
+ Name: "src-cert-dir",
+ Value: "",
+ Usage: "use certificates at `PATH` (*.crt, *.cert, *.key) to connect to the source registry",
+ },
+ cli.BoolTFlag{
+ Name: "src-tls-verify",
+ Usage: "require HTTPS and verify certificates when talking to the docker source registry (defaults to true)",
+ },
+ cli.StringFlag{
+ Name: "dest-cert-dir",
+ Value: "",
+ Usage: "use certificates at `PATH` (*.crt, *.cert, *.key) to connect to the destination registry",
+ },
+ cli.BoolTFlag{
+ Name: "dest-tls-verify",
+ Usage: "require HTTPS and verify certificates when talking to the docker destination registry (defaults to true)",
+ },
},
}
View
@@ -18,7 +18,7 @@ func deleteHandler(context *cli.Context) error {
return fmt.Errorf("Invalid source name %s: %v", context.Args()[0], err)
}
- ctx, err := contextFromGlobalOptions(context, "creds")
+ ctx, err := contextFromGlobalOptions(context, "")
if err != nil {
return err
}
@@ -39,5 +39,14 @@ var deleteCmd = cli.Command{
Value: "",
Usage: "Use `USERNAME[:PASSWORD]` for accessing the registry",
},
+ cli.StringFlag{
+ Name: "cert-dir",
+ Value: "",
+ Usage: "use certificates at `PATH` (*.crt, *.cert, *.key) to connect to the registry",
+ },
+ cli.BoolTFlag{
+ Name: "tls-verify",
+ Usage: "require HTTPS and verify certificates when talking to docker registries (defaults to true)",
+ },
},
}
@@ -30,6 +30,15 @@ var inspectCmd = cli.Command{
Usage: "Inspect image IMAGE-NAME",
ArgsUsage: "IMAGE-NAME",
Flags: []cli.Flag{
+ cli.StringFlag{
+ Name: "cert-path",
+ Value: "",
+ Usage: "use certificates at `PATH` (*.crt, *.cert, *.key) to connect to the registry",
+ },
+ cli.BoolTFlag{
+ Name: "tls-verify",
+ Usage: "require HTTPS and verify certificates when talking to docker registries (defaults to true)",
+ },
cli.BoolFlag{
Name: "raw",
Usage: "output raw manifest",
View
@@ -30,14 +30,10 @@ func createApp() *cli.App {
Name: "debug",
Usage: "enable debug output",
},
- cli.StringFlag{
- Name: "cert-path",
- Value: "",
- Usage: "use certificates at `PATH` (cert.pem, key.pem) to connect to the registry",
- },
cli.BoolTFlag{
- Name: "tls-verify",
- Usage: "require HTTPS and verify certificates when talking to docker registries (defaults to true)",
+ Name: "tls-verify",
+ Usage: "require HTTPS and verify certificates when talking to docker registries (defaults to true)",
+ Hidden: true,
},
cli.StringFlag{
Name: "policy",
@@ -54,6 +50,9 @@ func createApp() *cli.App {
if c.GlobalBool("debug") {
logrus.SetLevel(logrus.DebugLevel)
}
+ if c.GlobalIsSet("tls-verify") {
+ logrus.Warn("'--tls-verify' is deprecated, please set this on the specific subcommand")
+ }
return nil
}
app.Commands = []cli.Command{
View
@@ -9,15 +9,20 @@ import (
"github.com/urfave/cli"
)
-func contextFromGlobalOptions(c *cli.Context, credsFlag string) (*types.SystemContext, error) {
+func contextFromGlobalOptions(c *cli.Context, flagPrefix string) (*types.SystemContext, error) {
ctx := &types.SystemContext{
- RegistriesDirPath: c.GlobalString("registries.d"),
- DockerCertPath: c.GlobalString("cert-path"),
+ RegistriesDirPath: c.GlobalString("registries.d"),
+ DockerCertPath: c.String(flagPrefix + "cert-dir"),
+ // DEPRECATED: keep this here for backward compatibility, but override
+ // them if per subcommand flags are provided (see below).
DockerInsecureSkipTLSVerify: !c.GlobalBoolT("tls-verify"),
}
- if c.IsSet(credsFlag) {
+ if c.IsSet(flagPrefix + "tls-verify") {
+ ctx.DockerInsecureSkipTLSVerify = !c.BoolT(flagPrefix + "tls-verify")
+ }
+ if c.IsSet(flagPrefix + "creds") {
var err error
- ctx.DockerAuthConfig, err = getDockerAuth(c.String(credsFlag))
+ ctx.DockerAuthConfig, err = getDockerAuth(c.String(flagPrefix + "creds"))
if err != nil {
return nil, err
}
@@ -58,7 +63,7 @@ func parseImage(c *cli.Context) (types.Image, error) {
if err != nil {
return nil, err
}
- ctx, err := contextFromGlobalOptions(c, "creds")
+ ctx, err := contextFromGlobalOptions(c, "")
if err != nil {
return nil, err
}
@@ -73,7 +78,7 @@ func parseImageSource(c *cli.Context, name string, requestedManifestMIMETypes []
if err != nil {
return nil, err
}
- ctx, err := contextFromGlobalOptions(c, "creds")
+ ctx, err := contextFromGlobalOptions(c, "")
if err != nil {
return nil, err
}
@@ -23,7 +23,11 @@ _skopeo_copy() {
local options_with_args="
--sign-by
--src-creds --screds
+ --src-cert-path
+ --src-tls-verify
--dest-creds --dcreds
+ --dest-cert-path
+ --dest-tls-verify
"
local boolean_options="
--remove-signatures
@@ -34,9 +38,11 @@ _skopeo_copy() {
_skopeo_inspect() {
local options_with_args="
--creds
+ --cert-path
"
local boolean_options="
--raw
+ --tls-verify
"
_complete_ "$options_with_args" "$boolean_options"
}
@@ -68,30 +74,33 @@ _skopeo_manifest_digest() {
_skopeo_delete() {
local options_with_args="
- --creds
+ --creds
+ --cert-path
"
local boolean_options="
+ --tls-verify
"
_complete_ "$options_with_args" "$boolean_options"
}
_skopeo_layers() {
local options_with_args="
+ --creds
+ --cert-path
"
local boolean_options="
+ --tls-verify
"
_complete_ "$options_with_args" "$boolean_options"
}
_skopeo_skopeo() {
local options_with_args="
- --cert-path
--policy
--registries.d
"
local boolean_options="
--debug
- --tls-verify
--version -v
--help -h
"
View
@@ -37,14 +37,10 @@ Most commands refer to container images, using a _transport_`:`_details_ format.
**--debug** enable debug output
- **--cert-path** _path_ Use certificates at _path_ (cert.pem, key.pem) to connect to the registry
-
**--policy** _path-to-policy_ Path to a policy.json file to use for verifying signatures and deciding whether an image is trusted, overriding the default trust policy file.
**--registries.d** _dir_ use registry configuration files in _dir_ (e.g. for docker signature storage), overriding the default path.
- **--tls-verify** _bool-value_ Require HTTPS and verify certificates when talking to docker registries (defaults to true)
-
**--help**|**-h** Show help
**--version**|**-v** print the version number
@@ -70,6 +66,14 @@ Uses the system's trust policy to validate images, rejects images not trusted by
**--dest-creds** _username[:password]_ for accessing the destination registry
+ **--src-cert-dir** _path_ Use certificates at _path_ (*.crt, *.cert, *.key) to connect to the source registry
+
+ **--src-tls-verify** _bool-value_ Require HTTPS and verify certificates when talking to docker source registry (defaults to true)
+
+ **--dest-cert-dir** _path_ Use certificates at _path_ (*.crt, *.cert, *.key) to connect to the destination registry
+
+ **--dest-tls-verify** _bool-value_ Require HTTPS and verify certificates when talking to docker destination registry (defaults to true)
+
Existing signatures, if any, are preserved as well.
## skopeo delete
@@ -83,6 +87,10 @@ $ docker exec -it registry bin/registry garbage-collect /etc/docker/registry/con
**--creds** _username[:password]_ for accessing the registry
+ **--cert-dir** _path_ Use certificates at _path_ (*.crt, *.cert, *.key) to connect to the registry
+
+ **--tls-verify** _bool-value_ Require HTTPS and verify certificates when talking to docker registries (defaults to true)
+
Additionally, the registry must allow deletions by setting `REGISTRY_STORAGE_DELETE_ENABLED=true` for the registry daemon.
## skopeo inspect
@@ -96,12 +104,9 @@ Return low-level information about _image-name_ in a registry
**--creds** _username[:password]_ for accessing the registry
-## skopeo layers
-**skopeo layers** _image-name_
-
-Get image layers of _image-name_
+ **--cert-dir** _path_ Use certificates at _path_ (*.crt, *.cert, *.key) to connect to the registry
- _image-name_ name of the image to retrieve layers
+ **--tls-verify** _bool-value_ Require HTTPS and verify certificates when talking to docker registries (defaults to true)
## skopeo manifest-digest
**skopeo manifest-digest** _manifest-file_
View
@@ -16,7 +16,7 @@ clone git github.com/pmezard/go-difflib master
# docker deps from https://github.com/docker/docker/blob/v1.11.2/hack/vendor.sh
clone git github.com/docker/docker v1.12.1
clone git github.com/docker/engine-api 4eca04ae18f4f93f40196a17b9aa6e11262a7269
-clone git github.com/docker/go-connections v0.2.0
+clone git github.com/docker/go-connections 4ccf312bf1d35e5dbda654e57a9be4c3f3cd0366
clone git github.com/vbatts/tar-split v0.9.11
clone git github.com/gorilla/context 14f550f51a
clone git github.com/gorilla/mux e444e69cbd
@@ -87,6 +87,64 @@ func newTransport() *http.Transport {
return tr
}
+func setupCertificates(dir string, tlsc *tls.Config) error {
+ if dir == "" {
+ return nil
+ }
+ fs, err := ioutil.ReadDir(dir)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
+ for _, f := range fs {
+ fullPath := filepath.Join(dir, f.Name())
+ if strings.HasSuffix(f.Name(), ".crt") {
+ systemPool, err := tlsconfig.SystemCertPool()
+ if err != nil {
+ return fmt.Errorf("unable to get system cert pool: %v", err)
+ }
+ tlsc.RootCAs = systemPool
+ logrus.Debugf("crt: %s", fullPath)
+ data, err := ioutil.ReadFile(fullPath)
+ if err != nil {
+ return err
+ }
+ tlsc.RootCAs.AppendCertsFromPEM(data)
+ }
+ if strings.HasSuffix(f.Name(), ".cert") {
+ certName := f.Name()
+ keyName := certName[:len(certName)-5] + ".key"
+ logrus.Debugf("cert: %s", fullPath)
+ if !hasFile(fs, keyName) {
+ return fmt.Errorf("missing key %s for client certificate %s. Note that CA certificates should use the extension .crt", keyName, certName)
+ }
+ cert, err := tls.LoadX509KeyPair(filepath.Join(dir, certName), filepath.Join(dir, keyName))
+ if err != nil {
+ return err
+ }
+ tlsc.Certificates = append(tlsc.Certificates, cert)
+ }
+ if strings.HasSuffix(f.Name(), ".key") {
+ keyName := f.Name()
+ certName := keyName[:len(keyName)-4] + ".cert"
+ logrus.Debugf("key: %s", fullPath)
+ if !hasFile(fs, certName) {
+ return fmt.Errorf("missing client certificate %s for key %s", certName, keyName)
+ }
+ }
+ }
+ return nil
+}
+
+func hasFile(files []os.FileInfo, name string) bool {
+ for _, f := range files {
+ if f.Name() == name {
+ return true
+ }
+ }
+ return false
+}
+
// newDockerClient returns a new dockerClient instance for refHostname (a host a specified in the Docker image reference, not canonicalized to dockerRegistry)
// “write” specifies whether the client will be used for "write" access (in particular passed to lookaside.go:toplevelFromSection)
func newDockerClient(ctx *types.SystemContext, ref dockerReference, write bool) (*dockerClient, error) {
@@ -102,13 +160,10 @@ func newDockerClient(ctx *types.SystemContext, ref dockerReference, write bool)
if ctx != nil && (ctx.DockerCertPath != "" || ctx.DockerInsecureSkipTLSVerify) {
tlsc := &tls.Config{}
- if ctx.DockerCertPath != "" {
- cert, err := tls.LoadX509KeyPair(filepath.Join(ctx.DockerCertPath, "cert.pem"), filepath.Join(ctx.DockerCertPath, "key.pem"))
- if err != nil {
- return nil, fmt.Errorf("Error loading x509 key pair: %s", err)
- }
- tlsc.Certificates = append(tlsc.Certificates, cert)
+ if err := setupCertificates(ctx.DockerCertPath, tlsc); err != nil {
+ return nil, err
}
+
tlsc.InsecureSkipVerify = ctx.DockerInsecureSkipTLSVerify
tr.TLSClientConfig = tlsc
}
@@ -270,8 +270,11 @@ type SystemContext struct {
RegistriesDirPath string
// === docker.Transport overrides ===
- DockerCertPath string // If not "", a directory containing "cert.pem" and "key.pem" used when talking to a Docker Registry
- DockerInsecureSkipTLSVerify bool // Allow contacting docker registries over HTTP, or HTTPS with failed TLS verification. Note that this does not affect other TLS connections.
+ // If not "", a directory containing a CA certificate (ending with ".crt"),
+ // a client certificate (ending with ".cert") and a client ceritificate key
+ // (ending with ".key") used when talking to a Docker Registry.
+ DockerCertPath string
+ DockerInsecureSkipTLSVerify bool // Allow contacting docker registries over HTTP, or HTTPS with failed TLS verification. Note that this does not affect other TLS connections.
// if nil, the library tries to parse ~/.docker/config.json to retrieve credentials
DockerAuthConfig *DockerAuthConfig
// if not "", an User-Agent header is added to each request when contacting a registry.
Oops, something went wrong.

0 comments on commit 1215f5f

Please sign in to comment.