mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add libtrust key identity management
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
parent
a049ac32d1
commit
ea6a480128
6 changed files with 96 additions and 24 deletions
|
@ -13,6 +13,7 @@ import (
|
|||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/docker/pkg/term"
|
||||
"github.com/docker/docker/registry"
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
type DockerCli struct {
|
||||
|
@ -22,6 +23,7 @@ type DockerCli struct {
|
|||
in io.ReadCloser
|
||||
out io.Writer
|
||||
err io.Writer
|
||||
key libtrust.PrivateKey
|
||||
tlsConfig *tls.Config
|
||||
scheme string
|
||||
// inFd holds file descriptor of the client's STDIN, if it's a valid file
|
||||
|
@ -98,7 +100,7 @@ func (cli *DockerCli) LoadConfigFile() (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string, tlsConfig *tls.Config) *DockerCli {
|
||||
func NewDockerCli(in io.ReadCloser, out, err io.Writer, key libtrust.PrivateKey, proto, addr string, tlsConfig *tls.Config) *DockerCli {
|
||||
var (
|
||||
inFd uintptr
|
||||
outFd uintptr
|
||||
|
@ -135,6 +137,7 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string, tlsC
|
|||
in: in,
|
||||
out: out,
|
||||
err: err,
|
||||
key: key,
|
||||
inFd: inFd,
|
||||
outFd: outFd,
|
||||
isTerminalIn: isTerminalIn,
|
||||
|
|
|
@ -79,6 +79,7 @@ func mainDaemon() {
|
|||
job.Setenv("TlsCa", *flCa)
|
||||
job.Setenv("TlsCert", *flCert)
|
||||
job.Setenv("TlsKey", *flKey)
|
||||
job.Setenv("TrustKey", *flTrustKey)
|
||||
job.SetenvBool("BufferRequests", true)
|
||||
if err := job.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api"
|
||||
|
@ -15,9 +16,11 @@ import (
|
|||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/docker/reexec"
|
||||
"github.com/docker/docker/utils"
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultTrustKeyFile = "key.json"
|
||||
defaultCaFile = "ca.pem"
|
||||
defaultKeyFile = "key.pem"
|
||||
defaultCertFile = "cert.pem"
|
||||
|
@ -61,6 +64,20 @@ func main() {
|
|||
}
|
||||
protoAddrParts := strings.SplitN(flHosts[0], "://", 2)
|
||||
|
||||
err := os.MkdirAll(path.Dir(*flTrustKey), 0700)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
trustKey, keyErr := libtrust.LoadKeyFile(*flTrustKey)
|
||||
if keyErr == libtrust.ErrKeyFileDoesNotExist {
|
||||
trustKey, keyErr = libtrust.GenerateECP256PrivateKey()
|
||||
if keyErr == nil {
|
||||
keyErr = libtrust.SaveKey(*flTrustKey, trustKey)
|
||||
}
|
||||
}
|
||||
if keyErr != nil {
|
||||
log.Fatal(keyErr)
|
||||
}
|
||||
var (
|
||||
cli *client.DockerCli
|
||||
tlsConfig tls.Config
|
||||
|
@ -95,9 +112,9 @@ func main() {
|
|||
}
|
||||
|
||||
if *flTls || *flTlsVerify {
|
||||
cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], &tlsConfig)
|
||||
cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, trustKey, protoAddrParts[0], protoAddrParts[1], &tlsConfig)
|
||||
} else {
|
||||
cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], nil)
|
||||
cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, trustKey, protoAddrParts[0], protoAddrParts[1], nil)
|
||||
}
|
||||
|
||||
if err := cli.Cmd(flag.Args()...); err != nil {
|
||||
|
|
|
@ -29,6 +29,7 @@ var (
|
|||
flTlsVerify = flag.Bool([]string{"-tlsverify"}, false, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)")
|
||||
|
||||
// these are initialized in init() below since their default values depend on dockerCertPath which isn't fully initialized until init() runs
|
||||
flTrustKey *string
|
||||
flCa *string
|
||||
flCert *string
|
||||
flKey *string
|
||||
|
@ -36,6 +37,10 @@ var (
|
|||
)
|
||||
|
||||
func init() {
|
||||
// placeholder for trust key flag
|
||||
trustKeyDefault := filepath.Join(dockerCertPath, defaultTrustKeyFile)
|
||||
flTrustKey = &trustKeyDefault
|
||||
|
||||
flCa = flag.String([]string{"-tlscacert"}, filepath.Join(dockerCertPath, defaultCaFile), "Trust only remotes providing a certificate signed by the CA given here")
|
||||
flCert = flag.String([]string{"-tlscert"}, filepath.Join(dockerCertPath, defaultCertFile), "Path to TLS certificate file")
|
||||
flKey = flag.String([]string{"-tlskey"}, filepath.Join(dockerCertPath, defaultKeyFile), "Path to TLS key file")
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/docker/docker/pkg/log"
|
||||
"github.com/docker/docker/pkg/term"
|
||||
"github.com/docker/docker/utils"
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
func closeWrap(args ...io.Closer) error {
|
||||
|
@ -117,8 +118,12 @@ func TestRunDisconnect(t *testing.T) {
|
|||
|
||||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c1 := make(chan struct{})
|
||||
|
@ -163,8 +168,12 @@ func TestRunDisconnectTty(t *testing.T) {
|
|||
|
||||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c1 := make(chan struct{})
|
||||
|
@ -213,8 +222,12 @@ func TestRunDetach(t *testing.T) {
|
|||
|
||||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
@ -260,8 +273,12 @@ func TestRunDetach(t *testing.T) {
|
|||
func TestAttachDetach(t *testing.T) {
|
||||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
@ -294,7 +311,7 @@ func TestAttachDetach(t *testing.T) {
|
|||
|
||||
stdin, stdinPipe = io.Pipe()
|
||||
stdout, stdoutPipe = io.Pipe()
|
||||
cli = client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli = client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
|
||||
ch = make(chan struct{})
|
||||
go func() {
|
||||
|
@ -341,8 +358,12 @@ func TestAttachDetach(t *testing.T) {
|
|||
func TestAttachDetachTruncatedID(t *testing.T) {
|
||||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
// Discard the CmdRun output
|
||||
|
@ -360,7 +381,7 @@ func TestAttachDetachTruncatedID(t *testing.T) {
|
|||
|
||||
stdin, stdinPipe = io.Pipe()
|
||||
stdout, stdoutPipe = io.Pipe()
|
||||
cli = client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli = client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
|
@ -406,8 +427,12 @@ func TestAttachDetachTruncatedID(t *testing.T) {
|
|||
func TestAttachDisconnect(t *testing.T) {
|
||||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli := client.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
go func() {
|
||||
|
@ -461,7 +486,7 @@ func TestAttachDisconnect(t *testing.T) {
|
|||
|
||||
// We closed stdin, expect /bin/cat to still be running
|
||||
// Wait a little bit to make sure container.monitor() did his thing
|
||||
_, err := container.WaitStop(500 * time.Millisecond)
|
||||
_, err = container.WaitStop(500 * time.Millisecond)
|
||||
if err == nil || !container.IsRunning() {
|
||||
t.Fatalf("/bin/cat is not running after closing stdin")
|
||||
}
|
||||
|
@ -476,7 +501,11 @@ func TestAttachDisconnect(t *testing.T) {
|
|||
func TestRunAutoRemove(t *testing.T) {
|
||||
t.Skip("Fixme. Skipping test for now, race condition")
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
cli := client.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cli := client.NewDockerCli(nil, stdoutPipe, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c := make(chan struct{})
|
||||
|
@ -512,8 +541,12 @@ func TestRunAutoRemove(t *testing.T) {
|
|||
|
||||
// Expected behaviour: error out when attempting to bind mount non-existing source paths
|
||||
func TestRunErrorBindNonExistingSource(t *testing.T) {
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cli := client.NewDockerCli(nil, nil, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli := client.NewDockerCli(nil, nil, ioutil.Discard, key, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c := make(chan struct{})
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/docker/docker/api/client"
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -37,7 +38,11 @@ func getTlsConfig(certFile, keyFile string, t *testing.T) *tls.Config {
|
|||
|
||||
// TestHttpsInfo connects via two-way authenticated HTTPS to the info endpoint
|
||||
func TestHttpsInfo(t *testing.T) {
|
||||
cli := client.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto,
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cli := client.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, key, testDaemonProto,
|
||||
testDaemonHttpsAddr, getTlsConfig("client-cert.pem", "client-key.pem", t))
|
||||
|
||||
setTimeout(t, "Reading command output time out", 10*time.Second, func() {
|
||||
|
@ -50,7 +55,11 @@ func TestHttpsInfo(t *testing.T) {
|
|||
// TestHttpsInfoRogueCert connects via two-way authenticated HTTPS to the info endpoint
|
||||
// by using a rogue client certificate and checks that it fails with the expected error.
|
||||
func TestHttpsInfoRogueCert(t *testing.T) {
|
||||
cli := client.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto,
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cli := client.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, key, testDaemonProto,
|
||||
testDaemonHttpsAddr, getTlsConfig("client-rogue-cert.pem", "client-rogue-key.pem", t))
|
||||
|
||||
setTimeout(t, "Reading command output time out", 10*time.Second, func() {
|
||||
|
@ -67,7 +76,11 @@ func TestHttpsInfoRogueCert(t *testing.T) {
|
|||
// TestHttpsInfoRogueServerCert connects via two-way authenticated HTTPS to the info endpoint
|
||||
// which provides a rogue server certificate and checks that it fails with the expected error
|
||||
func TestHttpsInfoRogueServerCert(t *testing.T) {
|
||||
cli := client.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto,
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cli := client.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, key, testDaemonProto,
|
||||
testDaemonRogueHttpsAddr, getTlsConfig("client-cert.pem", "client-key.pem", t))
|
||||
|
||||
setTimeout(t, "Reading command output time out", 10*time.Second, func() {
|
||||
|
|
Loading…
Reference in a new issue