Merge branch 'https_client' of github.com:discordianfish/docker into discordianfish-https_client
Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
This commit is contained in:
commit
12687b7c10
19 changed files with 809 additions and 47 deletions
|
@ -3,6 +3,7 @@ package api
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
@ -2077,6 +2078,13 @@ func (cli *DockerCli) CmdLoad(args ...string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cli *DockerCli) dial() (net.Conn, error) {
|
||||
if cli.tlsConfig != nil && cli.proto != "unix" {
|
||||
return tls.Dial(cli.proto, cli.addr, cli.tlsConfig)
|
||||
}
|
||||
return net.Dial(cli.proto, cli.addr)
|
||||
}
|
||||
|
||||
func (cli *DockerCli) call(method, path string, data interface{}, passAuthInfo bool) (io.ReadCloser, int, error) {
|
||||
params := bytes.NewBuffer(nil)
|
||||
if data != nil {
|
||||
|
@ -2129,7 +2137,7 @@ func (cli *DockerCli) call(method, path string, data interface{}, passAuthInfo b
|
|||
} else if method == "POST" {
|
||||
req.Header.Set("Content-Type", "plain/text")
|
||||
}
|
||||
dial, err := net.Dial(cli.proto, cli.addr)
|
||||
dial, err := cli.dial()
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
return nil, -1, ErrConnectionRefused
|
||||
|
@ -2191,7 +2199,7 @@ func (cli *DockerCli) stream(method, path string, in io.Reader, out io.Writer, h
|
|||
}
|
||||
}
|
||||
|
||||
dial, err := net.Dial(cli.proto, cli.addr)
|
||||
dial, err := cli.dial()
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
return fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker -d' running on this host?")
|
||||
|
@ -2247,7 +2255,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
|
|||
req.Header.Set("Content-Type", "plain/text")
|
||||
req.Host = cli.addr
|
||||
|
||||
dial, err := net.Dial(cli.proto, cli.addr)
|
||||
dial, err := cli.dial()
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
return fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker -d' running on this host?")
|
||||
|
@ -2444,7 +2452,7 @@ func readBody(stream io.ReadCloser, statusCode int, err error) ([]byte, int, err
|
|||
return body, statusCode, nil
|
||||
}
|
||||
|
||||
func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string) *DockerCli {
|
||||
func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string, tlsConfig *tls.Config) *DockerCli {
|
||||
var (
|
||||
isTerminal = false
|
||||
terminalFd uintptr
|
||||
|
@ -2468,6 +2476,7 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string) *Doc
|
|||
err: err,
|
||||
isTerminal: isTerminal,
|
||||
terminalFd: terminalFd,
|
||||
tlsConfig: tlsConfig,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2480,4 +2489,5 @@ type DockerCli struct {
|
|||
err io.Writer
|
||||
isTerminal bool
|
||||
terminalFd uintptr
|
||||
tlsConfig *tls.Config
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"code.google.com/p/go.net/websocket"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"expvar"
|
||||
|
@ -1135,9 +1137,8 @@ func changeGroup(addr string, nameOrGid string) error {
|
|||
|
||||
// ListenAndServe sets up the required http.Server and gets it listening for
|
||||
// each addr passed in and does protocol specific checking.
|
||||
func ListenAndServe(proto, addr string, eng *engine.Engine, logging, enableCors bool, dockerVersion, socketGroup string) error {
|
||||
r, err := createRouter(eng, logging, enableCors, dockerVersion)
|
||||
|
||||
func ListenAndServe(proto, addr string, job *engine.Job) error {
|
||||
r, err := createRouter(job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1157,17 +1158,43 @@ func ListenAndServe(proto, addr string, eng *engine.Engine, logging, enableCors
|
|||
return err
|
||||
}
|
||||
|
||||
if proto != "unix" && (job.GetenvBool("Tls") || job.GetenvBool("TlsVerify")) {
|
||||
tlsCert := job.Getenv("TlsCert")
|
||||
tlsKey := job.Getenv("TlsKey")
|
||||
cert, err := tls.LoadX509KeyPair(tlsCert, tlsKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't load X509 key pair (%s, %s): %s. Key encrypted?",
|
||||
tlsCert, tlsKey, err)
|
||||
}
|
||||
tlsConfig := &tls.Config{
|
||||
NextProtos: []string{"http/1.1"},
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
if job.GetenvBool("TlsVerify") {
|
||||
certPool := x509.NewCertPool()
|
||||
file, err := ioutil.ReadFile(job.Getenv("TlsCa"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't read CA certificate: %s", err)
|
||||
}
|
||||
certPool.AppendCertsFromPEM(file)
|
||||
|
||||
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
tlsConfig.ClientCAs = certPool
|
||||
}
|
||||
l = tls.NewListener(l, tlsConfig)
|
||||
}
|
||||
|
||||
// Basic error and sanity checking
|
||||
switch proto {
|
||||
case "tcp":
|
||||
if !strings.HasPrefix(addr, "127.0.0.1") {
|
||||
if !strings.HasPrefix(addr, "127.0.0.1") && !job.GetenvBool("TlsVerify") {
|
||||
log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
|
||||
}
|
||||
case "unix":
|
||||
if err := os.Chmod(addr, 0660); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
socketGroup := job.Getenv("SocketGroup")
|
||||
if socketGroup != "" {
|
||||
if err := changeGroup(addr, socketGroup); err != nil {
|
||||
if socketGroup == "docker" {
|
||||
|
@ -1203,7 +1230,7 @@ func ServeApi(job *engine.Job) engine.Status {
|
|||
protoAddrParts := strings.SplitN(protoAddr, "://", 2)
|
||||
go func() {
|
||||
log.Printf("Listening for HTTP on %s (%s)\n", protoAddrParts[0], protoAddrParts[1])
|
||||
chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], job.Eng, job.GetenvBool("Logging"), job.GetenvBool("EnableCors"), job.Getenv("Version"), job.Getenv("SocketGroup"))
|
||||
chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], job)
|
||||
}()
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ func main() {
|
|||
bufErr := bytes.NewBuffer(nil)
|
||||
|
||||
// Instanciate the Docker CLI
|
||||
cli := docker.NewDockerCli(nil, bufOut, bufErr, "unix", "/var/run/docker.sock")
|
||||
cli := docker.NewDockerCli(nil, bufOut, bufErr, "unix", "/var/run/docker.sock", false, nil)
|
||||
// Retrieve the container info
|
||||
if err := cli.CmdInspect(flag.Arg(0)); err != nil {
|
||||
// As of docker v0.6.3, CmdInspect always returns nil
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -16,6 +19,16 @@ import (
|
|||
"github.com/dotcloud/docker/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultCaFile = "ca.pem"
|
||||
defaultKeyFile = "key.pem"
|
||||
defaultCertFile = "cert.pem"
|
||||
)
|
||||
|
||||
var (
|
||||
dockerConfDir = os.Getenv("HOME") + "/.docker/"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if selfPath := utils.SelfPath(); strings.Contains(selfPath, ".dockerinit") {
|
||||
// Running in init mode
|
||||
|
@ -43,6 +56,11 @@ func main() {
|
|||
flExecDriver = flag.String([]string{"e", "-exec-driver"}, "native", "Force the docker runtime to use a specific exec driver")
|
||||
flHosts = opts.NewListOpts(api.ValidateHost)
|
||||
flMtu = flag.Int([]string{"#mtu", "-mtu"}, 0, "Set the containers network MTU; if no value is provided: default to the default route MTU or 1500 if no default route is available")
|
||||
flTls = flag.Bool([]string{"-tls"}, false, "Use TLS; implied by tls-verify flags")
|
||||
flTlsVerify = flag.Bool([]string{"-tlsverify"}, false, "Use TLS and verify the remote (daemon: verify client, client: verify daemon)")
|
||||
flCa = flag.String([]string{"-tlscacert"}, dockerConfDir+defaultCaFile, "Trust only remotes providing a certificate signed by the CA given here")
|
||||
flCert = flag.String([]string{"-tlscert"}, dockerConfDir+defaultCertFile, "Path to TLS certificate file")
|
||||
flKey = flag.String([]string{"-tlskey"}, dockerConfDir+defaultKeyFile, "Path to TLS key file")
|
||||
)
|
||||
flag.Var(&flDns, []string{"#dns", "-dns"}, "Force docker to use specific DNS servers")
|
||||
flag.Var(&flHosts, []string{"H", "-host"}, "tcp://host:port, unix://path/to/socket, fd://* or fd://socketfd to use in daemon mode. Multiple sockets can be specified")
|
||||
|
@ -73,6 +91,7 @@ func main() {
|
|||
if *flDebug {
|
||||
os.Setenv("DEBUG", "1")
|
||||
}
|
||||
|
||||
if *flDaemon {
|
||||
if flag.NArg() != 0 {
|
||||
flag.Usage()
|
||||
|
@ -140,6 +159,12 @@ func main() {
|
|||
job.SetenvBool("EnableCors", *flEnableCors)
|
||||
job.Setenv("Version", dockerversion.VERSION)
|
||||
job.Setenv("SocketGroup", *flSocketGroup)
|
||||
|
||||
job.SetenvBool("Tls", *flTls)
|
||||
job.SetenvBool("TlsVerify", *flTlsVerify)
|
||||
job.Setenv("TlsCa", *flCa)
|
||||
job.Setenv("TlsCert", *flCert)
|
||||
job.Setenv("TlsKey", *flKey)
|
||||
if err := job.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -148,7 +173,46 @@ func main() {
|
|||
log.Fatal("Please specify only one -H")
|
||||
}
|
||||
protoAddrParts := strings.SplitN(flHosts.GetAll()[0], "://", 2)
|
||||
cli := api.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1])
|
||||
|
||||
var (
|
||||
cli *api.DockerCli
|
||||
tlsConfig tls.Config
|
||||
)
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
|
||||
// If we should verify the server, we need to load a trusted ca
|
||||
if *flTlsVerify {
|
||||
*flTls = true
|
||||
certPool := x509.NewCertPool()
|
||||
file, err := ioutil.ReadFile(*flCa)
|
||||
if err != nil {
|
||||
log.Fatalf("Couldn't read ca cert %s: %s", *flCa, err)
|
||||
}
|
||||
certPool.AppendCertsFromPEM(file)
|
||||
tlsConfig.RootCAs = certPool
|
||||
tlsConfig.InsecureSkipVerify = false
|
||||
}
|
||||
|
||||
// If tls is enabled, try to load and send client certificates
|
||||
if *flTls || *flTlsVerify {
|
||||
_, errCert := os.Stat(*flCert)
|
||||
_, errKey := os.Stat(*flKey)
|
||||
if errCert == nil && errKey == nil {
|
||||
*flTls = true
|
||||
cert, err := tls.LoadX509KeyPair(*flCert, *flKey)
|
||||
if err != nil {
|
||||
log.Fatalf("Couldn't load X509 key pair: %s. Key encrypted?", err)
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{cert}
|
||||
}
|
||||
}
|
||||
|
||||
if *flTls || *flTlsVerify {
|
||||
cli = api.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], &tlsConfig)
|
||||
} else {
|
||||
cli = api.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts[0], protoAddrParts[1], nil)
|
||||
}
|
||||
|
||||
if err := cli.ParseCommands(flag.Args()...); err != nil {
|
||||
if sterr, ok := err.(*utils.StatusError); ok {
|
||||
if sterr.Status != "" {
|
||||
|
|
126
docs/sources/examples/https.rst
Normal file
126
docs/sources/examples/https.rst
Normal file
|
@ -0,0 +1,126 @@
|
|||
:title: Docker HTTPS Setup
|
||||
:description: How to setup docker with https
|
||||
:keywords: docker, example, https, daemon
|
||||
|
||||
.. _running_docker_https:
|
||||
|
||||
Running Docker with https
|
||||
=========================
|
||||
|
||||
By default, Docker runs via a non-networked Unix socket. It can also optionally
|
||||
communicate using a HTTP socket.
|
||||
|
||||
If you need Docker reachable via the network in a safe manner, you can enable
|
||||
TLS by specifying the `tlsverify` flag and pointing Docker's `tlscacert` flag to a
|
||||
trusted CA certificate.
|
||||
|
||||
In daemon mode, it will only allow connections from clients authenticated by a
|
||||
certificate signed by that CA. In client mode, it will only connect to servers
|
||||
with a certificate signed by that CA.
|
||||
|
||||
.. warning::
|
||||
|
||||
Using TLS and managing a CA is an advanced topic. Please make you self familiar
|
||||
with openssl, x509 and tls before using it in production.
|
||||
|
||||
Create a CA, server and client keys with OpenSSL
|
||||
------------------------------------------------
|
||||
|
||||
First, initialize the CA serial file and generate CA private and public keys:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ echo 01 > ca.srl
|
||||
$ openssl genrsa -des3 -out ca-key.pem
|
||||
$ openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem
|
||||
|
||||
Now that we have a CA, you can create a server key and certificate signing request.
|
||||
Make sure that `"Common Name (e.g. server FQDN or YOUR name)"` matches the hostname you will use
|
||||
to connect to Docker or just use '*' for a certificate valid for any hostname:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl genrsa -des3 -out server-key.pem
|
||||
$ openssl req -new -key server-key.pem -out server.csr
|
||||
|
||||
Next we're going to sign the key with our CA:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem \
|
||||
-out server-cert.pem
|
||||
|
||||
For client authentication, create a client key and certificate signing request:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl genrsa -des3 -out client-key.pem
|
||||
$ openssl req -new -key client-key.pem -out client.csr
|
||||
|
||||
|
||||
To make the key suitable for client authentication, create a extensions config file:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ echo extendedKeyUsage = clientAuth > extfile.cnf
|
||||
|
||||
Now sign the key:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem \
|
||||
-out client-cert.pem -extfile extfile.cnf
|
||||
|
||||
Finally you need to remove the passphrase from the client and server key:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ openssl rsa -in server-key.pem -out server-key.pem
|
||||
$ openssl rsa -in client-key.pem -out client-key.pem
|
||||
|
||||
Now you can make the Docker daemon only accept connections from clients providing
|
||||
a certificate trusted by our CA:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo docker -d --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \
|
||||
-H=0.0.0.0:4243
|
||||
|
||||
To be able to connect to Docker and validate its certificate, you now need to provide your client keys,
|
||||
certificates and trusted CA:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ docker --tlsverify --tlscacert=ca.pem --tlscert=client-cert.pem --tlskey=client-key.pem \
|
||||
-H=dns-name-of-docker-host:4243
|
||||
|
||||
.. warning::
|
||||
|
||||
As shown in the example above, you don't have to run the ``docker``
|
||||
client with ``sudo`` or the ``docker`` group when you use
|
||||
certificate authentication. That means anyone with the keys can
|
||||
give any instructions to your Docker daemon, giving them root
|
||||
access to the machine hosting the daemon. Guard these keys as you
|
||||
would a root password!
|
||||
|
||||
Other modes
|
||||
-----------
|
||||
If you don't want to have complete two-way authentication, you can run Docker in
|
||||
various other modes by mixing the flags.
|
||||
|
||||
Daemon modes
|
||||
~~~~~~~~~~~~
|
||||
- tlsverify, tlscacert, tlscert, tlskey set: Authenticate clients
|
||||
- tls, tlscert, tlskey: Do not authenticate clients
|
||||
|
||||
Client modes
|
||||
~~~~~~~~~~~~
|
||||
- tls: Authenticate server based on public/default CA pool
|
||||
- tlsverify, tlscacert: Authenticate server based on given CA
|
||||
- tls, tlscert, tlskey: Authenticate with client certificate, do not authenticate
|
||||
server based on given CA
|
||||
- tlsverify, tlscacert, tlscert, tlskey: Authenticate with client certificate,
|
||||
authenticate server based on given CA
|
||||
|
||||
The client will send its client certificate if found, so you just need to drop
|
||||
your keys into `~/.docker/<ca, cert or key>.pem`
|
|
@ -27,3 +27,4 @@ to more substantial services like those which you might find in production.
|
|||
cfengine_process_management
|
||||
python_web_app
|
||||
apt-cacher-ng
|
||||
https
|
||||
|
|
|
@ -87,6 +87,11 @@ Commands
|
|||
-s, --storage-driver="": Force the docker runtime to use a specific storage driver
|
||||
-e, --exec-driver="native": Force the docker runtime to use a specific exec driver
|
||||
-v, --version=false: Print version information and quit
|
||||
--tls=false: Use TLS; implied by tls-verify flags
|
||||
--tlscacert="~/.docker/ca.pem": Trust only remotes providing a certificate signed by the CA given here
|
||||
--tlscert="~/.docker/cert.pem": Path to TLS certificate file
|
||||
--tlskey="~/.docker/key.pem": Path to TLS key file
|
||||
--tlsverify=false: Use TLS and verify the remote (daemon: verify client, client: verify daemon)
|
||||
--mtu=0: Set the containers network MTU; if no value is provided: default to the default route MTU or 1500 if no default route is available
|
||||
|
||||
The Docker daemon is the persistent process that manages containers. Docker uses the same binary for both the
|
||||
|
|
|
@ -121,7 +121,7 @@ func assertPipe(input, output string, r io.Reader, w io.Writer, count int) error
|
|||
func TestRunHostname(t *testing.T) {
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c := make(chan struct{})
|
||||
|
@ -166,7 +166,7 @@ func TestRunHostname(t *testing.T) {
|
|||
func TestRunWorkdir(t *testing.T) {
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c := make(chan struct{})
|
||||
|
@ -211,7 +211,7 @@ func TestRunWorkdir(t *testing.T) {
|
|||
func TestRunWorkdirExists(t *testing.T) {
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c := make(chan struct{})
|
||||
|
@ -256,7 +256,7 @@ func TestRunExit(t *testing.T) {
|
|||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c1 := make(chan struct{})
|
||||
|
@ -309,7 +309,7 @@ func TestRunDisconnect(t *testing.T) {
|
|||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c1 := make(chan struct{})
|
||||
|
@ -355,7 +355,7 @@ func TestRunDisconnectTty(t *testing.T) {
|
|||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c1 := make(chan struct{})
|
||||
|
@ -407,7 +407,7 @@ func TestRunAttachStdin(t *testing.T) {
|
|||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
@ -471,7 +471,7 @@ func TestRunDetach(t *testing.T) {
|
|||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
@ -518,7 +518,7 @@ func TestAttachDetach(t *testing.T) {
|
|||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
@ -551,7 +551,7 @@ func TestAttachDetach(t *testing.T) {
|
|||
|
||||
stdin, stdinPipe = io.Pipe()
|
||||
stdout, stdoutPipe = io.Pipe()
|
||||
cli = api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli = api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
|
||||
ch = make(chan struct{})
|
||||
go func() {
|
||||
|
@ -599,7 +599,7 @@ func TestAttachDetachTruncatedID(t *testing.T) {
|
|||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
// Discard the CmdRun output
|
||||
|
@ -617,7 +617,7 @@ func TestAttachDetachTruncatedID(t *testing.T) {
|
|||
|
||||
stdin, stdinPipe = io.Pipe()
|
||||
stdout, stdoutPipe = io.Pipe()
|
||||
cli = api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli = api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
|
@ -664,7 +664,7 @@ func TestAttachDisconnect(t *testing.T) {
|
|||
stdin, stdinPipe := io.Pipe()
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
go func() {
|
||||
|
@ -733,7 +733,7 @@ func TestAttachDisconnect(t *testing.T) {
|
|||
func TestRunAutoRemove(t *testing.T) {
|
||||
t.Skip("Fixme. Skipping test for now, race condition")
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c := make(chan struct{})
|
||||
|
@ -769,7 +769,7 @@ func TestRunAutoRemove(t *testing.T) {
|
|||
|
||||
func TestCmdLogs(t *testing.T) {
|
||||
t.Skip("Test not impemented")
|
||||
cli := api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
if err := cli.CmdRun(unitTestImageID, "sh", "-c", "ls -l"); err != nil {
|
||||
|
@ -787,7 +787,7 @@ func TestCmdLogs(t *testing.T) {
|
|||
// Expected behaviour: error out when attempting to bind mount non-existing source paths
|
||||
func TestRunErrorBindNonExistingSource(t *testing.T) {
|
||||
|
||||
cli := api.NewDockerCli(nil, nil, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, nil, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c := make(chan struct{})
|
||||
|
@ -807,7 +807,7 @@ func TestRunErrorBindNonExistingSource(t *testing.T) {
|
|||
func TestImagesViz(t *testing.T) {
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
image := buildTestImages(t, globalEngine)
|
||||
|
@ -857,7 +857,7 @@ func TestImagesViz(t *testing.T) {
|
|||
func TestImagesTree(t *testing.T) {
|
||||
stdout, stdoutPipe := io.Pipe()
|
||||
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
image := buildTestImages(t, globalEngine)
|
||||
|
@ -940,7 +940,7 @@ func TestRunCidFileCheckIDLength(t *testing.T) {
|
|||
}
|
||||
tmpCidFile := path.Join(tmpDir, "cid")
|
||||
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c := make(chan struct{})
|
||||
|
@ -989,7 +989,7 @@ func TestRunCidFileCleanupIfEmpty(t *testing.T) {
|
|||
}
|
||||
tmpCidFile := path.Join(tmpDir, "cid")
|
||||
|
||||
cli := api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
c := make(chan struct{})
|
||||
|
@ -1019,7 +1019,7 @@ func TestContainerOrphaning(t *testing.T) {
|
|||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// setup a CLI and server
|
||||
cli := api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli := api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
defer cleanup(globalEngine, t)
|
||||
srv := mkServerFromEngine(globalEngine, t)
|
||||
|
||||
|
@ -1079,8 +1079,8 @@ func TestCmdKill(t *testing.T) {
|
|||
var (
|
||||
stdin, stdinPipe = io.Pipe()
|
||||
stdout, stdoutPipe = io.Pipe()
|
||||
cli = api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli2 = api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr)
|
||||
cli = api.NewDockerCli(stdin, stdoutPipe, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
cli2 = api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto, testDaemonAddr, nil)
|
||||
)
|
||||
defer cleanup(globalEngine, t)
|
||||
|
||||
|
|
23
integration/fixtures/https/ca.pem
Normal file
23
integration/fixtures/https/ca.pem
Normal file
|
@ -0,0 +1,23 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIID0TCCAzqgAwIBAgIJAP2r7GqEJwSnMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD
|
||||
VQQGEwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNjbzEVMBMG
|
||||
A1UEChMMRm9ydC1GdW5zdG9uMREwDwYDVQQLEwhjaGFuZ2VtZTERMA8GA1UEAxMI
|
||||
Y2hhbmdlbWUxETAPBgNVBCkTCGNoYW5nZW1lMR8wHQYJKoZIhvcNAQkBFhBtYWls
|
||||
QGhvc3QuZG9tYWluMB4XDTEzMTIwMzE2NTYzMFoXDTIzMTIwMTE2NTYzMFowgaIx
|
||||
CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2Nv
|
||||
MRUwEwYDVQQKEwxGb3J0LUZ1bnN0b24xETAPBgNVBAsTCGNoYW5nZW1lMREwDwYD
|
||||
VQQDEwhjaGFuZ2VtZTERMA8GA1UEKRMIY2hhbmdlbWUxHzAdBgkqhkiG9w0BCQEW
|
||||
EG1haWxAaG9zdC5kb21haW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALAn
|
||||
0xDw+5y7ZptQacq66pUhRu82JP2WU6IDgo5QUtNU6/CX5PwQATe/OnYTZQFbksxp
|
||||
AU9boG0FCkgxfsgPYXEuZxVEGKI2fxfKHOZZI8mrkWmj6eWU/0cvCjGVc9rTITP5
|
||||
sNQvg+hORyVDdNp2IdsbMJayiB3AQYMFx3vSDOMTAgMBAAGjggELMIIBBzAdBgNV
|
||||
HQ4EFgQUZu7DFz09q0QBa2+ymRm9qgK1NPswgdcGA1UdIwSBzzCBzIAUZu7DFz09
|
||||
q0QBa2+ymRm9qgK1NPuhgaikgaUwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJD
|
||||
QTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMRUwEwYDVQQKEwxGb3J0LUZ1bnN0b24x
|
||||
ETAPBgNVBAsTCGNoYW5nZW1lMREwDwYDVQQDEwhjaGFuZ2VtZTERMA8GA1UEKRMI
|
||||
Y2hhbmdlbWUxHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW6CCQD9q+xq
|
||||
hCcEpzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAF8fJKKM+/oOdnNi
|
||||
zEd0M1+PmZOyqvjYQn/2ZR8UHH6Imgc/OPQKZXf0bVE1Txc/DaUNn9Isd1SuCuaE
|
||||
ic3vAIYYU7PmgeNN6vwec48V96T7jr+GAi6AVMhQEc2hHCfVtx11Xx+x6aHDZzJt
|
||||
Zxtf5lL6KSO9Y+EFwM+rju6hm5hW
|
||||
-----END CERTIFICATE-----
|
73
integration/fixtures/https/client-cert.pem
Normal file
73
integration/fixtures/https/client-cert.pem
Normal file
|
@ -0,0 +1,73 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 3 (0x3)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: C=US, ST=CA, L=SanFrancisco, O=Fort-Funston, OU=changeme, CN=changeme/name=changeme/emailAddress=mail@host.domain
|
||||
Validity
|
||||
Not Before: Dec 4 14:17:54 2013 GMT
|
||||
Not After : Dec 2 14:17:54 2023 GMT
|
||||
Subject: C=US, ST=CA, L=SanFrancisco, O=Fort-Funston, OU=changeme, CN=client/name=changeme/emailAddress=mail@host.domain
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:ca:c9:05:d0:09:4e:3e:a4:fc:d5:14:f4:a5:e8:
|
||||
34:d3:6b:51:e3:f3:62:ea:a1:f0:e8:ed:c4:2a:bc:
|
||||
f0:4f:ca:07:df:e3:88:fa:f4:21:99:35:0e:3d:ea:
|
||||
b0:86:e7:c4:d2:8a:83:2b:42:b8:ec:a3:99:62:70:
|
||||
81:46:cc:fc:a5:1d:d2:63:e8:eb:07:25:9a:e2:25:
|
||||
6d:11:56:f2:1a:51:a1:b6:3e:1c:57:32:e9:7b:2c:
|
||||
aa:1b:cc:97:2d:89:2d:b1:c9:5e:35:28:4d:7c:fa:
|
||||
65:31:3e:f7:70:dd:6e:0b:3c:58:af:a8:2e:24:c0:
|
||||
7e:4e:78:7d:0a:9e:8f:42:43
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Comment:
|
||||
Easy-RSA Generated Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
DE:42:EF:2D:98:A3:6C:A8:AA:E0:8C:71:2C:9D:64:23:A9:E2:7E:81
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:66:EE:C3:17:3D:3D:AB:44:01:6B:6F:B2:99:19:BD:AA:02:B5:34:FB
|
||||
DirName:/C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=changeme/CN=changeme/name=changeme/emailAddress=mail@host.domain
|
||||
serial:FD:AB:EC:6A:84:27:04:A7
|
||||
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Client Authentication
|
||||
X509v3 Key Usage:
|
||||
Digital Signature
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
1c:44:26:ea:e1:66:25:cb:e4:8e:57:1c:f6:b9:17:22:62:40:
|
||||
12:90:8f:3b:b2:61:7a:54:94:8f:b1:20:0b:bf:a3:51:e3:fa:
|
||||
1c:a1:be:92:3a:d0:76:44:c0:57:83:ab:6a:e4:1a:45:49:a4:
|
||||
af:39:0d:60:32:fc:3a:be:d7:fb:5d:99:7a:1f:87:e7:d5:ab:
|
||||
84:a2:5e:90:d8:bf:fa:89:6d:32:26:02:5e:31:35:68:7f:31:
|
||||
f5:6b:51:46:bc:af:70:ed:5a:09:7d:ec:b2:48:4f:fe:c5:2f:
|
||||
56:04:ad:f6:c1:d2:2a:e4:6a:c4:87:fe:08:35:c5:38:cb:5e:
|
||||
4a:c4
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEFTCCA36gAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMCVVMx
|
||||
CzAJBgNVBAgTAkNBMRUwEwYDVQQHEwxTYW5GcmFuY2lzY28xFTATBgNVBAoTDEZv
|
||||
cnQtRnVuc3RvbjERMA8GA1UECxMIY2hhbmdlbWUxETAPBgNVBAMTCGNoYW5nZW1l
|
||||
MREwDwYDVQQpEwhjaGFuZ2VtZTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0LmRv
|
||||
bWFpbjAeFw0xMzEyMDQxNDE3NTRaFw0yMzEyMDIxNDE3NTRaMIGgMQswCQYDVQQG
|
||||
EwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNjbzEVMBMGA1UE
|
||||
ChMMRm9ydC1GdW5zdG9uMREwDwYDVQQLEwhjaGFuZ2VtZTEPMA0GA1UEAxMGY2xp
|
||||
ZW50MREwDwYDVQQpEwhjaGFuZ2VtZTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0
|
||||
LmRvbWFpbjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyskF0AlOPqT81RT0
|
||||
peg002tR4/Ni6qHw6O3EKrzwT8oH3+OI+vQhmTUOPeqwhufE0oqDK0K47KOZYnCB
|
||||
Rsz8pR3SY+jrByWa4iVtEVbyGlGhtj4cVzLpeyyqG8yXLYktscleNShNfPplMT73
|
||||
cN1uCzxYr6guJMB+Tnh9Cp6PQkMCAwEAAaOCAVkwggFVMAkGA1UdEwQCMAAwLQYJ
|
||||
YIZIAYb4QgENBCAWHkVhc3ktUlNBIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV
|
||||
HQ4EFgQU3kLvLZijbKiq4IxxLJ1kI6nifoEwgdcGA1UdIwSBzzCBzIAUZu7DFz09
|
||||
q0QBa2+ymRm9qgK1NPuhgaikgaUwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJD
|
||||
QTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMRUwEwYDVQQKEwxGb3J0LUZ1bnN0b24x
|
||||
ETAPBgNVBAsTCGNoYW5nZW1lMREwDwYDVQQDEwhjaGFuZ2VtZTERMA8GA1UEKRMI
|
||||
Y2hhbmdlbWUxHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21haW6CCQD9q+xq
|
||||
hCcEpzATBgNVHSUEDDAKBggrBgEFBQcDAjALBgNVHQ8EBAMCB4AwDQYJKoZIhvcN
|
||||
AQEFBQADgYEAHEQm6uFmJcvkjlcc9rkXImJAEpCPO7JhelSUj7EgC7+jUeP6HKG+
|
||||
kjrQdkTAV4OrauQaRUmkrzkNYDL8Or7X+12Zeh+H59WrhKJekNi/+oltMiYCXjE1
|
||||
aH8x9WtRRryvcO1aCX3sskhP/sUvVgSt9sHSKuRqxIf+CDXFOMteSsQ=
|
||||
-----END CERTIFICATE-----
|
16
integration/fixtures/https/client-key.pem
Normal file
16
integration/fixtures/https/client-key.pem
Normal file
|
@ -0,0 +1,16 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMrJBdAJTj6k/NUU
|
||||
9KXoNNNrUePzYuqh8OjtxCq88E/KB9/jiPr0IZk1Dj3qsIbnxNKKgytCuOyjmWJw
|
||||
gUbM/KUd0mPo6wclmuIlbRFW8hpRobY+HFcy6XssqhvMly2JLbHJXjUoTXz6ZTE+
|
||||
93Ddbgs8WK+oLiTAfk54fQqej0JDAgMBAAECgYBOFEzKp2qbMEexe9ofL2N3rDDh
|
||||
xkrl8OijpzkLA6i78BxMFn4dsnZlWUpciMrjhsYAExkiRRSS+QMMJimAq1jzQqc3
|
||||
FAQV2XGYwkd0cUn7iZGvfNnEPysjsfyYQM+m+sT0ATj4BZjVShC6kkSjTdm1leLN
|
||||
OSvcHdcu3Xxg9ufF0QJBAPYdnNt5sIndt2WECePuRVi+uF4mlxTobFY0fjn26yhC
|
||||
4RsnhhD3Vldygo9gvnkwrAZYaALGSPBewes2InxvjA8CQQDS7erKiNXpwoqz5XiU
|
||||
SVEsIIVTdWzBjGbIqMOu/hUwM5FK4j6JTBks0aTGMyh0YV9L1EzM0X79J29JahCe
|
||||
iQKNAkBKNMOGqTpBV0hko1sYDk96YobUXG5RL4L6uvkUIQ7mJMQam+AgXXL7Ctuy
|
||||
v0iu4a38e8tgisiTMP7nHHtpaXihAkAOiN54/lzfMsykANgCP9scE1GcoqbP34Dl
|
||||
qttxH4kOPT9xzY1JoLjLYdbc4YGUI3GRpBt2sajygNkmUey7P+2xAkBBsVCZFvTw
|
||||
qHvOpPS2kX5ml5xoc/QAHK9N7kR+X7XFYx82RTVSqJEK4lPb+aEWn+CjiIewO4Q5
|
||||
ksDFuNxAzbhl
|
||||
-----END PRIVATE KEY-----
|
73
integration/fixtures/https/client-rogue-cert.pem
Normal file
73
integration/fixtures/https/client-rogue-cert.pem
Normal file
|
@ -0,0 +1,73 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 2 (0x2)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: C=US, ST=CA, L=SanFrancisco, O=Evil Inc, OU=changeme, CN=changeme/name=changeme/emailAddress=mail@host.domain
|
||||
Validity
|
||||
Not Before: Feb 24 17:54:59 2014 GMT
|
||||
Not After : Feb 22 17:54:59 2024 GMT
|
||||
Subject: C=US, ST=CA, L=SanFrancisco, O=Fort-Funston, OU=changeme, CN=client/name=changeme/emailAddress=mail@host.domain
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:e8:e2:2c:b8:d4:db:89:50:4f:47:1e:68:db:f7:
|
||||
e4:cc:47:41:63:75:03:37:50:7a:a8:4d:27:36:d5:
|
||||
15:01:08:b6:cf:56:f7:56:6d:3d:f9:e2:8d:1a:5d:
|
||||
bf:a0:24:5e:07:55:8e:d0:dc:f1:fa:19:87:1d:d6:
|
||||
b6:58:82:2e:ba:69:6d:e9:d9:c8:16:0d:1d:59:7f:
|
||||
f4:8e:58:10:01:3d:21:14:16:3c:ec:cd:8c:b7:0e:
|
||||
e6:7b:77:b4:f9:90:a5:17:01:bb:84:c6:b2:12:87:
|
||||
70:eb:9f:6d:4f:d0:68:8b:96:c0:e7:0b:51:b4:9d:
|
||||
1d:7b:6c:7b:be:89:6b:88:8b
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Comment:
|
||||
Easy-RSA Generated Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
9E:F8:49:D0:A2:76:30:5C:AB:2B:8A:B5:8D:C6:45:1F:A7:F8:CF:85
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:DC:A5:F1:76:DB:4E:CD:8E:EF:B1:23:56:1D:92:80:99:74:3B:EA:6F
|
||||
DirName:/C=US/ST=CA/L=SanFrancisco/O=Evil Inc/OU=changeme/CN=changeme/name=changeme/emailAddress=mail@host.domain
|
||||
serial:E7:21:1E:18:41:1B:96:83
|
||||
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Client Authentication
|
||||
X509v3 Key Usage:
|
||||
Digital Signature
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
48:76:c0:18:fa:0a:ee:4e:1a:ec:02:9d:d4:83:ca:94:54:a1:
|
||||
3f:51:2f:3e:4b:95:c3:42:9b:71:a0:4b:d9:af:47:23:b9:1c:
|
||||
fb:85:ba:76:e2:09:cb:65:bb:d2:7d:44:3d:4b:67:ba:80:83:
|
||||
be:a8:ed:c4:b9:ea:1a:1b:c7:59:3b:d9:5c:0d:46:d8:c9:92:
|
||||
cb:10:c5:f2:1a:38:a4:aa:07:2c:e3:84:16:79:c7:95:09:e3:
|
||||
01:d2:15:a2:77:0b:8b:bf:94:04:e9:7f:c0:cd:e6:2e:64:cd:
|
||||
1e:a3:32:ec:11:cc:62:ce:c7:4e:cd:ad:48:5c:b1:b8:e9:76:
|
||||
b3:f9
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEDTCCA3agAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx
|
||||
CzAJBgNVBAgTAkNBMRUwEwYDVQQHEwxTYW5GcmFuY2lzY28xETAPBgNVBAoTCEV2
|
||||
aWwgSW5jMREwDwYDVQQLEwhjaGFuZ2VtZTERMA8GA1UEAxMIY2hhbmdlbWUxETAP
|
||||
BgNVBCkTCGNoYW5nZW1lMR8wHQYJKoZIhvcNAQkBFhBtYWlsQGhvc3QuZG9tYWlu
|
||||
MB4XDTE0MDIyNDE3NTQ1OVoXDTI0MDIyMjE3NTQ1OVowgaAxCzAJBgNVBAYTAlVT
|
||||
MQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMRUwEwYDVQQKEwxG
|
||||
b3J0LUZ1bnN0b24xETAPBgNVBAsTCGNoYW5nZW1lMQ8wDQYDVQQDEwZjbGllbnQx
|
||||
ETAPBgNVBCkTCGNoYW5nZW1lMR8wHQYJKoZIhvcNAQkBFhBtYWlsQGhvc3QuZG9t
|
||||
YWluMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo4iy41NuJUE9HHmjb9+TM
|
||||
R0FjdQM3UHqoTSc21RUBCLbPVvdWbT354o0aXb+gJF4HVY7Q3PH6GYcd1rZYgi66
|
||||
aW3p2cgWDR1Zf/SOWBABPSEUFjzszYy3DuZ7d7T5kKUXAbuExrISh3Drn21P0GiL
|
||||
lsDnC1G0nR17bHu+iWuIiwIDAQABo4IBVTCCAVEwCQYDVR0TBAIwADAtBglghkgB
|
||||
hvhCAQ0EIBYeRWFzeS1SU0EgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW
|
||||
BBSe+EnQonYwXKsrirWNxkUfp/jPhTCB0wYDVR0jBIHLMIHIgBTcpfF2207Nju+x
|
||||
I1YdkoCZdDvqb6GBpKSBoTCBnjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRUw
|
||||
EwYDVQQHEwxTYW5GcmFuY2lzY28xETAPBgNVBAoTCEV2aWwgSW5jMREwDwYDVQQL
|
||||
EwhjaGFuZ2VtZTERMA8GA1UEAxMIY2hhbmdlbWUxETAPBgNVBCkTCGNoYW5nZW1l
|
||||
MR8wHQYJKoZIhvcNAQkBFhBtYWlsQGhvc3QuZG9tYWluggkA5yEeGEEbloMwEwYD
|
||||
VR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMA0GCSqGSIb3DQEBBQUAA4GB
|
||||
AEh2wBj6Cu5OGuwCndSDypRUoT9RLz5LlcNCm3GgS9mvRyO5HPuFunbiCctlu9J9
|
||||
RD1LZ7qAg76o7cS56hobx1k72VwNRtjJkssQxfIaOKSqByzjhBZ5x5UJ4wHSFaJ3
|
||||
C4u/lATpf8DN5i5kzR6jMuwRzGLOx07NrUhcsbjpdrP5
|
||||
-----END CERTIFICATE-----
|
16
integration/fixtures/https/client-rogue-key.pem
Normal file
16
integration/fixtures/https/client-rogue-key.pem
Normal file
|
@ -0,0 +1,16 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOjiLLjU24lQT0ce
|
||||
aNv35MxHQWN1AzdQeqhNJzbVFQEIts9W91ZtPfnijRpdv6AkXgdVjtDc8foZhx3W
|
||||
tliCLrppbenZyBYNHVl/9I5YEAE9IRQWPOzNjLcO5nt3tPmQpRcBu4TGshKHcOuf
|
||||
bU/QaIuWwOcLUbSdHXtse76Ja4iLAgMBAAECgYADs+TmI2xCKKa6CL++D5jxrohZ
|
||||
nnionnz0xBVFh+nHlG3jqgxQsXf0yydXLfpn/2wHTdLxezHVuiYt0UYg7iD0CglW
|
||||
+IjcgMebzyjLeYqYOE5llPlMvhp2HoEMYJNb+7bRrZ1WCITbu+Su0w1cgA7Cs+Ej
|
||||
VlfvGzN+qqnDThRUYQJBAPY0sMWZJKly8QhUmUvmcXdPczzSOf6Mm7gc5LR6wzxd
|
||||
vW7syuqk50qjqVqFpN81vCV7GoDxRUWbTM9ftf7JGFkCQQDyJc/1RMygE2o+enU1
|
||||
6UBxJyclXITEYtDn8aoEpLNc7RakP1WoPUKjZOnjkcoKcIkFNkSPeCfQujrb5f3F
|
||||
MkuDAkByAI/hzzmkpK5rFxEsjfX4Mve/L/DepyjrpaVY1IdWimlO1aJX6CeY7hNa
|
||||
8QsYt/74s/nfvtg+lNyKIV1aLq9xAkB+WSSNgfyTeg3x08vc+Xxajmdqoz/TiQwg
|
||||
OoTQL3A3iK5LvZBgXLasszcnOycFE3srcQmNItEDpGiZ3QPxJTEpAkEA45EE9NMJ
|
||||
SA7EGWSFlbz4f4u4oBeiDiJRJbGGfAyVxZlpCWUjPpg9+swsWoFEOjnGYaChAMk5
|
||||
nrOdMf15T6QF7Q==
|
||||
-----END PRIVATE KEY-----
|
76
integration/fixtures/https/server-cert.pem
Normal file
76
integration/fixtures/https/server-cert.pem
Normal file
|
@ -0,0 +1,76 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4 (0x4)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: C=US, ST=CA, L=SanFrancisco, O=Fort-Funston, OU=changeme, CN=changeme/name=changeme/emailAddress=mail@host.domain
|
||||
Validity
|
||||
Not Before: Dec 4 15:01:20 2013 GMT
|
||||
Not After : Dec 2 15:01:20 2023 GMT
|
||||
Subject: C=US, ST=CA, L=SanFrancisco, O=Fort-Funston, OU=changeme, CN=*/name=changeme/emailAddress=mail@host.domain
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:c1:ff:7d:30:6f:64:4a:b1:92:b1:71:d1:c1:74:
|
||||
e2:1d:db:2d:11:24:e1:00:d4:00:ae:6f:c8:9e:ae:
|
||||
67:b3:4a:bd:f7:e6:9e:57:6d:19:4c:3c:23:94:2d:
|
||||
3d:d6:63:84:d8:fa:76:2b:38:12:c1:ed:20:9d:32:
|
||||
e0:e8:c2:bf:9a:77:70:04:3f:7f:ca:8c:2c:82:d6:
|
||||
3d:25:5c:02:1a:4f:64:93:03:dd:9c:42:97:5e:09:
|
||||
49:af:f0:c2:e1:30:08:0e:21:46:95:d1:13:59:c0:
|
||||
c8:76:be:94:0d:8b:43:67:21:33:b2:08:60:9d:76:
|
||||
a8:05:32:1e:f9:95:09:14:75
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Cert Type:
|
||||
SSL Server
|
||||
Netscape Comment:
|
||||
Easy-RSA Generated Server Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
14:02:FD:FD:DD:13:38:E0:71:EA:D1:BE:C0:0E:89:1A:2D:B6:19:06
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:66:EE:C3:17:3D:3D:AB:44:01:6B:6F:B2:99:19:BD:AA:02:B5:34:FB
|
||||
DirName:/C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=changeme/CN=changeme/name=changeme/emailAddress=mail@host.domain
|
||||
serial:FD:AB:EC:6A:84:27:04:A7
|
||||
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication
|
||||
X509v3 Key Usage:
|
||||
Digital Signature, Key Encipherment
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
40:0f:10:39:c4:b7:0f:0d:2f:bf:d2:16:cc:8e:d3:9a:fb:8b:
|
||||
ce:4b:7b:0d:48:77:ce:f1:fe:d5:8f:ea:b1:71:ed:49:1d:9f:
|
||||
23:3a:16:d4:70:7c:c5:29:bf:e4:90:34:d0:f0:00:24:f4:e4:
|
||||
df:2c:c3:83:01:66:61:c9:a8:ab:29:e7:98:6d:27:89:4a:76:
|
||||
c9:2e:19:8e:fe:6e:d5:f8:99:11:0e:97:67:4b:34:e3:1e:e3:
|
||||
9f:35:00:a5:32:f9:b5:2c:f2:e0:c5:2e:cc:81:bd:18:dd:5c:
|
||||
12:c8:6b:fa:0c:17:74:30:55:f6:6e:20:9a:6c:1e:09:b4:0c:
|
||||
15:42
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEKjCCA5OgAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMCVVMx
|
||||
CzAJBgNVBAgTAkNBMRUwEwYDVQQHEwxTYW5GcmFuY2lzY28xFTATBgNVBAoTDEZv
|
||||
cnQtRnVuc3RvbjERMA8GA1UECxMIY2hhbmdlbWUxETAPBgNVBAMTCGNoYW5nZW1l
|
||||
MREwDwYDVQQpEwhjaGFuZ2VtZTEfMB0GCSqGSIb3DQEJARYQbWFpbEBob3N0LmRv
|
||||
bWFpbjAeFw0xMzEyMDQxNTAxMjBaFw0yMzEyMDIxNTAxMjBaMIGbMQswCQYDVQQG
|
||||
EwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNjbzEVMBMGA1UE
|
||||
ChMMRm9ydC1GdW5zdG9uMREwDwYDVQQLEwhjaGFuZ2VtZTEKMAgGA1UEAxQBKjER
|
||||
MA8GA1UEKRMIY2hhbmdlbWUxHzAdBgkqhkiG9w0BCQEWEG1haWxAaG9zdC5kb21h
|
||||
aW4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMH/fTBvZEqxkrFx0cF04h3b
|
||||
LREk4QDUAK5vyJ6uZ7NKvffmnldtGUw8I5QtPdZjhNj6dis4EsHtIJ0y4OjCv5p3
|
||||
cAQ/f8qMLILWPSVcAhpPZJMD3ZxCl14JSa/wwuEwCA4hRpXRE1nAyHa+lA2LQ2ch
|
||||
M7IIYJ12qAUyHvmVCRR1AgMBAAGjggFzMIIBbzAJBgNVHRMEAjAAMBEGCWCGSAGG
|
||||
+EIBAQQEAwIGQDA0BglghkgBhvhCAQ0EJxYlRWFzeS1SU0EgR2VuZXJhdGVkIFNl
|
||||
cnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUFAL9/d0TOOBx6tG+wA6JGi22GQYw
|
||||
gdcGA1UdIwSBzzCBzIAUZu7DFz09q0QBa2+ymRm9qgK1NPuhgaikgaUwgaIxCzAJ
|
||||
BgNVBAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMRUw
|
||||
EwYDVQQKEwxGb3J0LUZ1bnN0b24xETAPBgNVBAsTCGNoYW5nZW1lMREwDwYDVQQD
|
||||
EwhjaGFuZ2VtZTERMA8GA1UEKRMIY2hhbmdlbWUxHzAdBgkqhkiG9w0BCQEWEG1h
|
||||
aWxAaG9zdC5kb21haW6CCQD9q+xqhCcEpzATBgNVHSUEDDAKBggrBgEFBQcDATAL
|
||||
BgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQEFBQADgYEAQA8QOcS3Dw0vv9IWzI7TmvuL
|
||||
zkt7DUh3zvH+1Y/qsXHtSR2fIzoW1HB8xSm/5JA00PAAJPTk3yzDgwFmYcmoqynn
|
||||
mG0niUp2yS4Zjv5u1fiZEQ6XZ0s04x7jnzUApTL5tSzy4MUuzIG9GN1cEshr+gwX
|
||||
dDBV9m4gmmweCbQMFUI=
|
||||
-----END CERTIFICATE-----
|
16
integration/fixtures/https/server-key.pem
Normal file
16
integration/fixtures/https/server-key.pem
Normal file
|
@ -0,0 +1,16 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMH/fTBvZEqxkrFx
|
||||
0cF04h3bLREk4QDUAK5vyJ6uZ7NKvffmnldtGUw8I5QtPdZjhNj6dis4EsHtIJ0y
|
||||
4OjCv5p3cAQ/f8qMLILWPSVcAhpPZJMD3ZxCl14JSa/wwuEwCA4hRpXRE1nAyHa+
|
||||
lA2LQ2chM7IIYJ12qAUyHvmVCRR1AgMBAAECgYAmwckb9RUfSwyYgLm8IYLPHiuJ
|
||||
wkllZfVg5Bo7gXJcQnFjZmJ56uTj8xvUjZlODIHM63TSO5ibv6kFXtXKCqZGd2M+
|
||||
wGbhZ0f+2GvKcwMmJERnIQjuoNaYSQLT0tM0VB9Iz0rJlZC+tzPZ+5pPqEumRdsS
|
||||
IzWNXfF42AhcbwAQYQJBAPVXtMYIJc9EZsz86ZcQiMPWUpCX5vnRmtwL8kKyR8D5
|
||||
4KfYeiowyFffSRMMcclwNHq7TgSXN+nIXM9WyzyzwikCQQDKbNA28AgZp9aT54HP
|
||||
WnbeE2pmt+uk/zl/BtxJSoK6H+69Jec+lf7EgL7HgOWYRSNot4uQWu8IhsHLTiUq
|
||||
+0FtAkEAqwlRxRy4/x24bP+D+QRV0/D97j93joFJbE4Hved7jlSlAV4xDGilwlyv
|
||||
HNB4Iu5OJ6Gcaibhm+FKkmD3noHSwQJBAIpu3fokLzX0bS+bDFBU6qO3HXX/47xj
|
||||
+tsfQvkwZrSI8AkU6c8IX0HdVhsz0FBRQAT2ORDQz1XCarfxykNZrwUCQQCGCBIc
|
||||
BBCWzhHlswlGidWJg3HqqO6hPPClEr3B5G87oCsdeYwiO23XT6rUnoJXfJHp6oCW
|
||||
5nCwDu5ZTP+khltg
|
||||
-----END PRIVATE KEY-----
|
76
integration/fixtures/https/server-rogue-cert.pem
Normal file
76
integration/fixtures/https/server-rogue-cert.pem
Normal file
|
@ -0,0 +1,76 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 3 (0x3)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: C=US, ST=CA, L=SanFrancisco, O=Evil Inc, OU=changeme, CN=changeme/name=changeme/emailAddress=mail@host.domain
|
||||
Validity
|
||||
Not Before: Feb 28 18:49:31 2014 GMT
|
||||
Not After : Feb 26 18:49:31 2024 GMT
|
||||
Subject: C=US, ST=CA, L=SanFrancisco, O=Fort-Funston, OU=changeme, CN=localhost/name=changeme/emailAddress=mail@host.domain
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:d1:08:58:24:60:a1:69:65:4b:76:46:8f:88:75:
|
||||
7c:49:3a:d8:03:cc:5b:58:c5:d1:bb:e5:f9:54:b9:
|
||||
75:65:df:7e:bb:fb:54:d4:b2:e9:6f:58:a2:a4:84:
|
||||
43:94:77:24:81:38:36:36:f0:66:65:26:e5:5b:2a:
|
||||
14:1c:a9:ae:57:7f:75:00:23:14:4b:61:58:e4:82:
|
||||
aa:15:97:94:bd:50:35:0d:5d:18:18:ed:10:6a:bb:
|
||||
d3:64:5a:eb:36:98:5b:58:a7:fe:67:48:c1:6c:3f:
|
||||
51:2f:02:65:96:54:77:9b:34:f9:a7:d2:63:54:6a:
|
||||
9e:02:5c:be:65:98:a4:b4:b5
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Cert Type:
|
||||
SSL Server
|
||||
Netscape Comment:
|
||||
Easy-RSA Generated Server Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
1F:E0:57:CA:CB:76:C9:C4:86:B9:EA:69:17:C0:F3:51:CE:95:40:EC
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:DC:A5:F1:76:DB:4E:CD:8E:EF:B1:23:56:1D:92:80:99:74:3B:EA:6F
|
||||
DirName:/C=US/ST=CA/L=SanFrancisco/O=Evil Inc/OU=changeme/CN=changeme/name=changeme/emailAddress=mail@host.domain
|
||||
serial:E7:21:1E:18:41:1B:96:83
|
||||
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Server Authentication
|
||||
X509v3 Key Usage:
|
||||
Digital Signature, Key Encipherment
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
04:93:0e:28:01:94:18:f0:8c:7c:d3:0c:ad:e9:b7:46:b1:30:
|
||||
65:ed:68:7c:8c:91:cd:1a:86:66:87:4a:4f:c0:97:bc:f7:85:
|
||||
4b:38:79:31:b2:65:88:b1:76:16:9e:80:93:38:f4:b9:eb:65:
|
||||
00:6d:bb:89:e0:a1:bf:95:5e:80:13:8e:01:73:d3:f1:08:73:
|
||||
85:a5:33:75:0b:42:8a:a3:07:09:35:ef:d7:c6:58:eb:60:a3:
|
||||
06:89:a0:53:99:e2:aa:41:90:e0:1a:d2:12:4b:48:7d:c3:9c:
|
||||
ad:bd:0e:5e:5f:f7:09:0c:5d:7c:86:24:dd:92:d5:b3:14:06:
|
||||
c7:9f
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEKjCCA5OgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx
|
||||
CzAJBgNVBAgTAkNBMRUwEwYDVQQHEwxTYW5GcmFuY2lzY28xETAPBgNVBAoTCEV2
|
||||
aWwgSW5jMREwDwYDVQQLEwhjaGFuZ2VtZTERMA8GA1UEAxMIY2hhbmdlbWUxETAP
|
||||
BgNVBCkTCGNoYW5nZW1lMR8wHQYJKoZIhvcNAQkBFhBtYWlsQGhvc3QuZG9tYWlu
|
||||
MB4XDTE0MDIyODE4NDkzMVoXDTI0MDIyNjE4NDkzMVowgaMxCzAJBgNVBAYTAlVT
|
||||
MQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMRUwEwYDVQQKEwxG
|
||||
b3J0LUZ1bnN0b24xETAPBgNVBAsTCGNoYW5nZW1lMRIwEAYDVQQDEwlsb2NhbGhv
|
||||
c3QxETAPBgNVBCkTCGNoYW5nZW1lMR8wHQYJKoZIhvcNAQkBFhBtYWlsQGhvc3Qu
|
||||
ZG9tYWluMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRCFgkYKFpZUt2Ro+I
|
||||
dXxJOtgDzFtYxdG75flUuXVl3367+1TUsulvWKKkhEOUdySBODY28GZlJuVbKhQc
|
||||
qa5Xf3UAIxRLYVjkgqoVl5S9UDUNXRgY7RBqu9NkWus2mFtYp/5nSMFsP1EvAmWW
|
||||
VHebNPmn0mNUap4CXL5lmKS0tQIDAQABo4IBbzCCAWswCQYDVR0TBAIwADARBglg
|
||||
hkgBhvhCAQEEBAMCBkAwNAYJYIZIAYb4QgENBCcWJUVhc3ktUlNBIEdlbmVyYXRl
|
||||
ZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFB/gV8rLdsnEhrnqaRfA81HO
|
||||
lUDsMIHTBgNVHSMEgcswgciAFNyl8XbbTs2O77EjVh2SgJl0O+pvoYGkpIGhMIGe
|
||||
MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAcTDFNhbkZyYW5jaXNj
|
||||
bzERMA8GA1UEChMIRXZpbCBJbmMxETAPBgNVBAsTCGNoYW5nZW1lMREwDwYDVQQD
|
||||
EwhjaGFuZ2VtZTERMA8GA1UEKRMIY2hhbmdlbWUxHzAdBgkqhkiG9w0BCQEWEG1h
|
||||
aWxAaG9zdC5kb21haW6CCQDnIR4YQRuWgzATBgNVHSUEDDAKBggrBgEFBQcDATAL
|
||||
BgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQEFBQADgYEABJMOKAGUGPCMfNMMrem3RrEw
|
||||
Ze1ofIyRzRqGZodKT8CXvPeFSzh5MbJliLF2Fp6Akzj0uetlAG27ieChv5VegBOO
|
||||
AXPT8QhzhaUzdQtCiqMHCTXv18ZY62CjBomgU5niqkGQ4BrSEktIfcOcrb0OXl/3
|
||||
CQxdfIYk3ZLVsxQGx58=
|
||||
-----END CERTIFICATE-----
|
16
integration/fixtures/https/server-rogue-key.pem
Normal file
16
integration/fixtures/https/server-rogue-key.pem
Normal file
|
@ -0,0 +1,16 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANEIWCRgoWllS3ZG
|
||||
j4h1fEk62APMW1jF0bvl+VS5dWXffrv7VNSy6W9YoqSEQ5R3JIE4NjbwZmUm5Vsq
|
||||
FByprld/dQAjFEthWOSCqhWXlL1QNQ1dGBjtEGq702Ra6zaYW1in/mdIwWw/US8C
|
||||
ZZZUd5s0+afSY1RqngJcvmWYpLS1AgMBAAECgYAJXh9dGfuB1qlIFqduDR3RxlJR
|
||||
8UGSu+LHUeoXkuwg8aAjWoMVuSLe+5DmYIsKx0AajmNXmPRtyg1zRXJ7SltmubJ8
|
||||
6qQVDsRk6biMdkpkl6a9Gk2av40psD9/VPGxagEoop7IKYhf3AeKPvPiwVB2qFrl
|
||||
1aYMZm0aMR55pgRajQJBAOk8IsJDf0beooDZXVdv/oe4hcbM9fxO8Cn3qzoGImqD
|
||||
37LL+PCzDP7AEV3fk43SsZDeSk+LDX+h0o9nPyhzHasCQQDlb3aDgcQY9NaGLUWO
|
||||
moOCB3148eBVcAwCocu+OSkf7sbQdvXxgThBOrZl11wwRIMQqh99c2yeUwj+tELl
|
||||
3VcfAkBZTiNpCvtDIaBLge9RuZpWUXs3wec2cutWxnSTxSGMc25GQf/R+l0xdk2w
|
||||
ChmvpktDUzpU9sN2aXn8WuY+EMX9AkEApbLpUbKPUELLB958RLA819TW/lkZXjrs
|
||||
wZ3eSoR3ufM1rOqtVvyvBxUDE+wETWu9iHSFB5Ir2PA5J9JCGkbPmwJAFI1ndfBj
|
||||
iuyU93nFX0p+JE2wVHKx4dMzKCearNKiJh/lGDtUq3REGgamTNUnG8RAITUbxFs+
|
||||
Z1hrIq8xYl2LOQ==
|
||||
-----END PRIVATE KEY-----
|
82
integration/https_test.go
Normal file
82
integration/https_test.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"github.com/dotcloud/docker/api"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
errBadCertificate = "remote error: bad certificate"
|
||||
errCaUnknown = "x509: certificate signed by unknown authority"
|
||||
)
|
||||
|
||||
func getTlsConfig(certFile, keyFile string, t *testing.T) *tls.Config {
|
||||
certPool := x509.NewCertPool()
|
||||
file, err := ioutil.ReadFile("fixtures/https/ca.pem")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
certPool.AppendCertsFromPEM(file)
|
||||
|
||||
cert, err := tls.LoadX509KeyPair("fixtures/https/"+certFile, "fixtures/https/"+keyFile)
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't load X509 key pair: %s", err)
|
||||
}
|
||||
tlsConfig := &tls.Config{
|
||||
RootCAs: certPool,
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
return tlsConfig
|
||||
}
|
||||
|
||||
// TestHttpsInfo connects via two-way authenticated HTTPS to the info endpoint
|
||||
func TestHttpsInfo(t *testing.T) {
|
||||
cli := api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto,
|
||||
testDaemonHttpsAddr, getTlsConfig("client-cert.pem", "client-key.pem", t))
|
||||
|
||||
setTimeout(t, "Reading command output time out", 10*time.Second, func() {
|
||||
if err := cli.CmdInfo(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 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 := api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto,
|
||||
testDaemonHttpsAddr, getTlsConfig("client-rogue-cert.pem", "client-rogue-key.pem", t))
|
||||
|
||||
setTimeout(t, "Reading command output time out", 10*time.Second, func() {
|
||||
err := cli.CmdInfo()
|
||||
if err == nil {
|
||||
t.Fatal("Expected error but got nil")
|
||||
}
|
||||
if err.Error() != errBadCertificate {
|
||||
t.Fatalf("Expected error: %s, got instead: %s", errBadCertificate, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 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 := api.NewDockerCli(nil, ioutil.Discard, ioutil.Discard, testDaemonProto,
|
||||
testDaemonRogueHttpsAddr, getTlsConfig("client-cert.pem", "client-key.pem", t))
|
||||
|
||||
setTimeout(t, "Reading command output time out", 10*time.Second, func() {
|
||||
err := cli.CmdInfo()
|
||||
if err == nil {
|
||||
t.Fatal("Expected error but got nil")
|
||||
}
|
||||
|
||||
if err.Error() != errCaUnknown {
|
||||
t.Fatalf("Expected error: %s, got instead: %s", errBadCertificate, err)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
|
@ -25,21 +25,26 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
unitTestImageName = "docker-test-image"
|
||||
unitTestImageID = "83599e29c455eb719f77d799bc7c51521b9551972f5a850d7ad265bc1b5292f6" // 1.0
|
||||
unitTestImageIDShort = "83599e29c455"
|
||||
unitTestNetworkBridge = "testdockbr0"
|
||||
unitTestStoreBase = "/var/lib/docker/unit-tests"
|
||||
testDaemonAddr = "127.0.0.1:4270"
|
||||
testDaemonProto = "tcp"
|
||||
unitTestImageName = "docker-test-image"
|
||||
unitTestImageID = "83599e29c455eb719f77d799bc7c51521b9551972f5a850d7ad265bc1b5292f6" // 1.0
|
||||
unitTestImageIDShort = "83599e29c455"
|
||||
unitTestNetworkBridge = "testdockbr0"
|
||||
unitTestStoreBase = "/var/lib/docker/unit-tests"
|
||||
testDaemonAddr = "127.0.0.1:4270"
|
||||
testDaemonProto = "tcp"
|
||||
testDaemonHttpsProto = "tcp"
|
||||
testDaemonHttpsAddr = "localhost:4271"
|
||||
testDaemonRogueHttpsAddr = "localhost:4272"
|
||||
)
|
||||
|
||||
var (
|
||||
// FIXME: globalRuntime is deprecated by globalEngine. All tests should be converted.
|
||||
globalRuntime *runtime.Runtime
|
||||
globalEngine *engine.Engine
|
||||
startFds int
|
||||
startGoroutines int
|
||||
globalRuntime *runtime.Runtime
|
||||
globalEngine *engine.Engine
|
||||
globalHttpsEngine *engine.Engine
|
||||
globalRogueHttpsEngine *engine.Engine
|
||||
startFds int
|
||||
startGoroutines int
|
||||
)
|
||||
|
||||
// FIXME: nuke() is deprecated by Runtime.Nuke()
|
||||
|
@ -118,8 +123,10 @@ func init() {
|
|||
// (no tests are run directly in the base)
|
||||
setupBaseImage()
|
||||
|
||||
// Create the "global runtime" with a long-running daemon for integration tests
|
||||
// Create the "global runtime" with a long-running daemons for integration tests
|
||||
spawnGlobalDaemon()
|
||||
spawnLegitHttpsDaemon()
|
||||
spawnRogueHttpsDaemon()
|
||||
startFds, startGoroutines = utils.GetTotalUsedFds(), goruntime.NumGoroutine()
|
||||
}
|
||||
|
||||
|
@ -171,6 +178,61 @@ func spawnGlobalDaemon() {
|
|||
}
|
||||
}
|
||||
|
||||
func spawnLegitHttpsDaemon() {
|
||||
if globalHttpsEngine != nil {
|
||||
return
|
||||
}
|
||||
globalHttpsEngine = spawnHttpsDaemon(testDaemonHttpsAddr, "fixtures/https/ca.pem",
|
||||
"fixtures/https/server-cert.pem", "fixtures/https/server-key.pem")
|
||||
}
|
||||
|
||||
func spawnRogueHttpsDaemon() {
|
||||
if globalRogueHttpsEngine != nil {
|
||||
return
|
||||
}
|
||||
globalRogueHttpsEngine = spawnHttpsDaemon(testDaemonRogueHttpsAddr, "fixtures/https/ca.pem",
|
||||
"fixtures/https/server-rogue-cert.pem", "fixtures/https/server-rogue-key.pem")
|
||||
}
|
||||
|
||||
func spawnHttpsDaemon(addr, cacert, cert, key string) *engine.Engine {
|
||||
t := log.New(os.Stderr, "", 0)
|
||||
root, err := newTestDirectory(unitTestStoreBase)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// FIXME: here we don't use NewTestEngine because it calls initserver with Autorestart=false,
|
||||
// and we want to set it to true.
|
||||
|
||||
eng := newTestEngine(t, true, root)
|
||||
|
||||
// Spawn a Daemon
|
||||
go func() {
|
||||
utils.Debugf("Spawning https daemon for integration tests")
|
||||
listenURL := &url.URL{
|
||||
Scheme: testDaemonHttpsProto,
|
||||
Host: addr,
|
||||
}
|
||||
job := eng.Job("serveapi", listenURL.String())
|
||||
job.SetenvBool("Logging", true)
|
||||
job.SetenvBool("Tls", true)
|
||||
job.SetenvBool("TlsVerify", true)
|
||||
job.Setenv("TlsCa", cacert)
|
||||
job.Setenv("TlsCert", cert)
|
||||
job.Setenv("TlsKey", key)
|
||||
if err := job.Run(); err != nil {
|
||||
log.Fatalf("Unable to spawn the test daemon: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Give some time to ListenAndServer to actually start
|
||||
time.Sleep(time.Second)
|
||||
|
||||
if err := eng.Job("acceptconnections").Run(); err != nil {
|
||||
log.Fatalf("Unable to accept connections for test api: %s", err)
|
||||
}
|
||||
return eng
|
||||
}
|
||||
|
||||
// FIXME: test that ImagePull(json=true) send correct json output
|
||||
|
||||
func GetTestImage(runtime *runtime.Runtime) *image.Image {
|
||||
|
|
Loading…
Reference in a new issue