Merge pull request #2914 from hashicorp/tls-client-options

Add tls client options to api/cli
This commit is contained in:
Kyle Havlovitz 2017-04-14 14:55:17 -07:00 committed by GitHub
commit 43818f53ef
28 changed files with 1404 additions and 41 deletions

View File

@ -4,11 +4,9 @@ import (
"bytes"
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"net"
"net/http"
@ -19,6 +17,7 @@ import (
"time"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-rootcerts"
)
const (
@ -38,6 +37,26 @@ const (
// whether or not to use HTTPS.
HTTPSSLEnvName = "CONSUL_HTTP_SSL"
// HTTPCAFile defines an environment variable name which sets the
// CA file to use for talking to Consul over TLS.
HTTPCAFile = "CONSUL_CACERT"
// HTTPCAPath defines an environment variable name which sets the
// path to a directory of CA certs to use for talking to Consul over TLS.
HTTPCAPath = "CONSUL_CAPATH"
// HTTPClientCert defines an environment variable name which sets the
// client cert file to use for talking to Consul over TLS.
HTTPClientCert = "CONSUL_CLIENT_CERT"
// HTTPClientKey defines an environment variable name which sets the
// client key file to use for talking to Consul over TLS.
HTTPClientKey = "CONSUL_CLIENT_KEY"
// HTTPTLSServerName defines an environment variable name which sets the
// server name to use as the SNI host when connecting via TLS
HTTPTLSServerName = "CONSUL_TLS_SERVER_NAME"
// HTTPSSLVerifyEnvName defines an environment variable name which sets
// whether or not to disable certificate checking.
HTTPSSLVerifyEnvName = "CONSUL_HTTP_SSL_VERIFY"
@ -163,6 +182,8 @@ type Config struct {
// Token is used to provide a per-request ACL token
// which overrides the agent's default token.
Token string
TLSConfig TLSConfig
}
// TLSConfig is used to generate a TLSClientConfig that's useful for talking to
@ -177,6 +198,10 @@ type TLSConfig struct {
// communication, defaults to the system bundle if not specified.
CAFile string
// CAPath is the optional path to a directory of CA certificates to use for
// Consul communication, defaults to the system bundle if not specified.
CAPath string
// CertFile is the optional path to the certificate for Consul
// communication. If this is set then you need to also set KeyFile.
CertFile string
@ -254,27 +279,28 @@ func defaultConfig(transportFn func() *http.Transport) *Config {
}
}
if verify := os.Getenv(HTTPSSLVerifyEnvName); verify != "" {
doVerify, err := strconv.ParseBool(verify)
if v := os.Getenv(HTTPTLSServerName); v != "" {
config.TLSConfig.Address = v
}
if v := os.Getenv(HTTPCAFile); v != "" {
config.TLSConfig.CAFile = v
}
if v := os.Getenv(HTTPCAPath); v != "" {
config.TLSConfig.CAPath = v
}
if v := os.Getenv(HTTPClientCert); v != "" {
config.TLSConfig.CertFile = v
}
if v := os.Getenv(HTTPClientKey); v != "" {
config.TLSConfig.KeyFile = v
}
if v := os.Getenv(HTTPSSLVerifyEnvName); v != "" {
doVerify, err := strconv.ParseBool(v)
if err != nil {
log.Printf("[WARN] client: could not parse %s: %s", HTTPSSLVerifyEnvName, err)
}
if !doVerify {
tlsClientConfig, err := SetupTLSConfig(&TLSConfig{
InsecureSkipVerify: true,
})
// We don't expect this to fail given that we aren't
// parsing any of the input, but we panic just in case
// since this doesn't have an error return.
if err != nil {
panic(err)
}
transport := transportFn()
transport.TLSClientConfig = tlsClientConfig
config.HttpClient.Transport = transport
config.TLSConfig.InsecureSkipVerify = true
}
}
@ -309,17 +335,12 @@ func SetupTLSConfig(tlsConfig *TLSConfig) (*tls.Config, error) {
tlsClientConfig.Certificates = []tls.Certificate{tlsCert}
}
if tlsConfig.CAFile != "" {
data, err := ioutil.ReadFile(tlsConfig.CAFile)
if err != nil {
return nil, fmt.Errorf("failed to read CA file: %v", err)
}
caPool := x509.NewCertPool()
if !caPool.AppendCertsFromPEM(data) {
return nil, fmt.Errorf("failed to parse CA certificate")
}
tlsClientConfig.RootCAs = caPool
rootConfig := &rootcerts.Config{
CAFile: tlsConfig.CAFile,
CAPath: tlsConfig.CAPath,
}
if err := rootcerts.ConfigureTLS(tlsClientConfig, rootConfig); err != nil {
return nil, err
}
return tlsClientConfig, nil
@ -347,6 +368,41 @@ func NewClient(config *Config) (*Client, error) {
config.HttpClient = defConfig.HttpClient
}
if config.TLSConfig.Address == "" {
config.TLSConfig.Address = defConfig.TLSConfig.Address
}
if config.TLSConfig.CAFile == "" {
config.TLSConfig.CAFile = defConfig.TLSConfig.CAFile
}
if config.TLSConfig.CAPath == "" {
config.TLSConfig.CAPath = defConfig.TLSConfig.CAPath
}
if config.TLSConfig.CertFile == "" {
config.TLSConfig.CertFile = defConfig.TLSConfig.CertFile
}
if config.TLSConfig.KeyFile == "" {
config.TLSConfig.KeyFile = defConfig.TLSConfig.KeyFile
}
if !config.TLSConfig.InsecureSkipVerify {
config.TLSConfig.InsecureSkipVerify = defConfig.TLSConfig.InsecureSkipVerify
}
tlsClientConfig, err := SetupTLSConfig(&config.TLSConfig)
// We don't expect this to fail given that we aren't
// parsing any of the input, but we panic just in case
// since this doesn't have an error return.
if err != nil {
return nil, err
}
config.HttpClient.Transport.(*http.Transport).TLSClientConfig = tlsClientConfig
parts := strings.SplitN(config.Address, "://", 2)
if len(parts) == 2 {
switch parts[0] {

View File

@ -14,6 +14,7 @@ import (
"time"
"github.com/hashicorp/consul/testutil"
"strings"
)
type configCallback func(c *Config)
@ -86,6 +87,16 @@ func TestDefaultConfig_env(t *testing.T) {
defer os.Setenv(HTTPAuthEnvName, "")
os.Setenv(HTTPSSLEnvName, "1")
defer os.Setenv(HTTPSSLEnvName, "")
os.Setenv(HTTPCAFile, "ca.pem")
defer os.Setenv(HTTPCAFile, "")
os.Setenv(HTTPCAPath, "certs/")
defer os.Setenv(HTTPCAPath, "")
os.Setenv(HTTPClientCert, "client.crt")
defer os.Setenv(HTTPClientCert, "")
os.Setenv(HTTPClientKey, "client.key")
defer os.Setenv(HTTPClientKey, "")
os.Setenv(HTTPTLSServerName, "consul.test")
defer os.Setenv(HTTPTLSServerName, "")
os.Setenv(HTTPSSLVerifyEnvName, "0")
defer os.Setenv(HTTPSSLVerifyEnvName, "")
@ -108,7 +119,22 @@ func TestDefaultConfig_env(t *testing.T) {
if config.Scheme != "https" {
t.Errorf("expected %q to be %q", config.Scheme, "https")
}
if !config.HttpClient.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify {
if config.TLSConfig.CAFile != "ca.pem" {
t.Errorf("expected %q to be %q", config.TLSConfig.CAFile, "ca.pem")
}
if config.TLSConfig.CAPath != "certs/" {
t.Errorf("expected %q to be %q", config.TLSConfig.CAPath, "certs/")
}
if config.TLSConfig.CertFile != "client.crt" {
t.Errorf("expected %q to be %q", config.TLSConfig.CertFile, "client.crt")
}
if config.TLSConfig.KeyFile != "client.key" {
t.Errorf("expected %q to be %q", config.TLSConfig.KeyFile, "client.key")
}
if config.TLSConfig.Address != "consul.test" {
t.Errorf("expected %q to be %q", config.TLSConfig.Address, "consul.test")
}
if !config.TLSConfig.InsecureSkipVerify {
t.Errorf("expected SSL verification to be off")
}
@ -132,9 +158,9 @@ func TestSetupTLSConfig(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
expected := &tls.Config{}
expected := &tls.Config{RootCAs: cc.RootCAs}
if !reflect.DeepEqual(cc, expected) {
t.Fatalf("bad: %v", cc)
t.Fatalf("bad: \n%v, \n%v", cc, expected)
}
// Try some address variations with and without ports.
@ -215,6 +241,68 @@ func TestSetupTLSConfig(t *testing.T) {
if cc.RootCAs == nil {
t.Fatalf("didn't load root CAs")
}
// Use a directory to load the certs instead
cc, err = SetupTLSConfig(&TLSConfig{
CAPath: "../test/ca_path",
})
if err != nil {
t.Fatalf("err: %v", err)
}
if len(cc.RootCAs.Subjects()) != 2 {
t.Fatalf("didn't load root CAs")
}
}
func TestClientTLSOptions(t *testing.T) {
t.Parallel()
_, s := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) {
conf.CAFile = "../test/client_certs/rootca.crt"
conf.CertFile = "../test/client_certs/server.crt"
conf.KeyFile = "../test/client_certs/server.key"
conf.VerifyIncoming = true
})
defer s.Stop()
// Set up a client without certs
clientWithoutCerts, err := NewClient(&Config{
Address: s.HTTPSAddr,
Scheme: "https",
TLSConfig: TLSConfig{
Address: "consul.test",
CAFile: "../test/client_certs/rootca.crt",
},
})
if err != nil {
t.Fatal(err)
}
// Should fail
_, err = clientWithoutCerts.Agent().Self()
if err == nil || !strings.Contains(err.Error(), "bad certificate") {
t.Fatal(err)
}
// Set up a client with valid certs
clientWithCerts, err := NewClient(&Config{
Address: s.HTTPSAddr,
Scheme: "https",
TLSConfig: TLSConfig{
Address: "consul.test",
CAFile: "../test/client_certs/rootca.crt",
CertFile: "../test/client_certs/client.crt",
KeyFile: "../test/client_certs/client.key",
},
})
if err != nil {
t.Fatal(err)
}
// Should succeed
_, err = clientWithCerts.Agent().Self()
if err != nil {
t.Fatal(err)
}
}
func TestSetQueryOptions(t *testing.T) {

View File

@ -36,8 +36,14 @@ type Command struct {
hidden *flag.FlagSet
// These are the options which correspond to the HTTP API options
httpAddr StringValue
token StringValue
httpAddr StringValue
token StringValue
caFile StringValue
caPath StringValue
certFile StringValue
keyFile StringValue
tlsServerName StringValue
datacenter StringValue
stale BoolValue
}
@ -55,6 +61,11 @@ func (c *Command) HTTPClient() (*api.Client, error) {
config := api.DefaultConfig()
c.httpAddr.Merge(&config.Address)
c.token.Merge(&config.Token)
c.caFile.Merge(&config.TLSConfig.CAFile)
c.caPath.Merge(&config.TLSConfig.CAPath)
c.certFile.Merge(&config.TLSConfig.CertFile)
c.keyFile.Merge(&config.TLSConfig.KeyFile)
c.tlsServerName.Merge(&config.TLSConfig.Address)
c.datacenter.Merge(&config.Datacenter)
return api.NewClient(config)
}
@ -83,6 +94,18 @@ func (c *Command) httpFlagsClient(f *flag.FlagSet) *flag.FlagSet {
f = flag.NewFlagSet("", flag.ContinueOnError)
}
f.Var(&c.caFile, "ca-file",
"Path to a CA file to use for TLS when communicating with Consul. This "+
"can also be specified via the CONSUL_CACERT environment variable.")
f.Var(&c.caPath, "ca-path",
"Path to a directory of CA certificates to use for TLS when communicating "+
"with Consul. This can also be specified via the CONSUL_CAPATH environment variable.")
f.Var(&c.certFile, "client-cert",
"Path to a client cert file to use for TLS when `verify_incoming` is enabled. This "+
"can also be specified via the CONSUL_CLIENT_CERT environment variable.")
f.Var(&c.keyFile, "client-key",
"Path to a client key file to use for TLS when `verify_incoming` is enabled. This "+
"can also be specified via the CONSUL_CLIENT_KEY environment variable.")
f.Var(&c.httpAddr, "http-addr",
"The `address` and port of the Consul HTTP agent. The value can be an IP "+
"address or DNS address, but it must also include the port. This can "+
@ -93,6 +116,9 @@ func (c *Command) httpFlagsClient(f *flag.FlagSet) *flag.FlagSet {
"ACL token to use in the request. This can also be specified via the "+
"CONSUL_HTTP_TOKEN environment variable. If unspecified, the query will "+
"default to the token of the Consul agent at the HTTP address.")
f.Var(&c.tlsServerName, "tls-server-name",
"The server name to use as the SNI host when connecting via TLS. This "+
"can also be specified via the CONSUL_TLS_SERVER_NAME environment variable.")
return f
}

29
test/ca_path/cert1.crt Normal file
View File

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFADCCAuqgAwIBAgIBATALBgkqhkiG9w0BAQswEzERMA8GA1UEAxMIQ2VydEF1
dGgwHhcNMTUwNTExMjI0NjQzWhcNMjUwNTExMjI0NjU0WjATMREwDwYDVQQDEwhD
ZXJ0QXV0aDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALcMByyynHsA
+K4PJwo5+XHygaEZAhPGvHiKQK2Cbc9NDm0ZTzx0rA/dRTZlvouhDyzcJHm+6R1F
j6zQv7iaSC3qQtJiPnPsfZ+/0XhFZ3fQWMnfDiGbZpF1kJF01ofB6vnsuocFC0zG
aGC+SZiLAzs+QMP3Bebw1elCBIeoN+8NWnRYmLsYIaYGJGBSbNo/lCpLTuinofUn
L3ehWEGv1INwpHnSVeN0Ml2GFe23d7PUlj/wNIHgUdpUR+KEJxIP3klwtsI3QpSH
c4VjWdf4aIcka6K3IFuw+K0PUh3xAAPnMpAQOtCZk0AhF5rlvUbevC6jADxpKxLp
OONmvCTer4LtyNURAoBH52vbK0r/DNcTpPEFV0IP66nXUFgkk0mRKsu8HTb4IOkC
X3K4mp18EiWUUtrHZAnNct0iIniDBqKK0yhSNhztG6VakVt/1WdQY9Ey3mNtxN1O
thqWFKdpKUzPKYC3P6PfVpiE7+VbWTLLXba+8BPe8BxWPsVkjJqGSGnCte4COusz
M8/7bbTgifwJfsepwFtZG53tvwjWlO46Exl30VoDNTaIGvs1fO0GqJlh2A7FN5F2
S1rS5VYHtPK8QdmUSvyq+7JDBc1HNT5I2zsIQbNcLwDTZ5EsbU6QR7NHDJKxjv/w
bs3eTXJSSNcFD74wRU10pXjgE5wOFu9TAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIA
BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQHazgZ3Puiuc6K2LzgcX5b6fAC
PzAfBgNVHSMEGDAWgBQHazgZ3Puiuc6K2LzgcX5b6fACPzALBgkqhkiG9w0BAQsD
ggIBAEmeNrSUhpHg1I8dtfqu9hCU/6IZThjtcFA+QcPkkMa+Z1k0SOtsgW8MdlcA
gCf5g5yQZ0DdpWM9nDB6xDIhQdccm91idHgf8wmpEHUj0an4uyn2ESCt8eqrAWf7
AClYORCASTYfguJCxcfvwtI1uqaOeCxSOdmFay79UVitVsWeonbCRGsVgBDifJxw
G2oCQqoYAmXPM4J6syk5GHhB1O9MMq+g1+hOx9s+XHyTui9FL4V+IUO1ygVqEQB5
PSiRBvcIsajSGVao+vK0gf2XfcXzqr3y3NhBky9rFMp1g+ykb2yWekV4WiROJlCj
TsWwWZDRyjiGahDbho/XW8JciouHZhJdjhmO31rqW3HdFviCTdXMiGk3GQIzz/Jg
P+enOaHXoY9lcxzDvY9z1BysWBgNvNrMnVge/fLP9o+a0a0PRIIVl8T0Ef3zeg1O
CLCSy/1Vae5Tx63ZTFvGFdOSusYkG9rlAUHXZE364JRCKzM9Bz0bM+t+LaO0MaEb
YoxcXEPU+gB2IvmARpInN3oHexR6ekuYHVTRGdWrdmuHFzc7eFwygRqTFdoCCU+G
QZEkd+lOEyv0zvQqYg+Jp0AEGz2B2zB53uBVECtn0EqrSdPtRzUBSByXVs6QhSXn
eVmy+z3U3MecP63X6oSPXekqSyZFuegXpNNuHkjNoL4ep2ix
-----END CERTIFICATE-----

28
test/ca_path/cert2.crt Normal file
View File

@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIIEtzCCA5+gAwIBAgIJAIewRMI8OnvTMA0GCSqGSIb3DQEBBQUAMIGYMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xHDAa
BgNVBAoTE0hhc2hpQ29ycCBUZXN0IENlcnQxDDAKBgNVBAsTA0RldjEWMBQGA1UE
AxMNdGVzdC5pbnRlcm5hbDEgMB4GCSqGSIb3DQEJARYRdGVzdEBpbnRlcm5hbC5j
b20wHhcNMTQwNDA3MTkwMTA4WhcNMjQwNDA0MTkwMTA4WjCBmDELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRwwGgYDVQQK
ExNIYXNoaUNvcnAgVGVzdCBDZXJ0MQwwCgYDVQQLEwNEZXYxFjAUBgNVBAMTDXRl
c3QuaW50ZXJuYWwxIDAeBgkqhkiG9w0BCQEWEXRlc3RAaW50ZXJuYWwuY29tMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxrs6JK4NpiOItxrpNR/1ppUU
mH7p2BgLCBZ6eHdclle9J56i68adt8J85zaqphCfz6VDP58DsFx+N50PZyjQaDsU
d0HejRqfHRMtg2O+UQkv4Z66+Vo+gc6uGuANi2xMtSYDVTAqqzF48OOPQDgYkzcG
xcFZzTRFFZt2vPnyHj8cHcaFo/NMNVh7C3yTXevRGNm9u2mrbxCEeiHzFC2WUnvg
U2jQuC7Fhnl33Zd3B6d3mQH6O23ncmwxTcPUJe6xZaIRrDuzwUcyhLj5Z3faag/f
pFIIcHSiHRfoqHLGsGg+3swId/zVJSSDHr7pJUu7Cre+vZa63FqDaooqvnisrQID
AQABo4IBADCB/TAdBgNVHQ4EFgQUo/nrOfqvbee2VklVKIFlyQEbuJUwgc0GA1Ud
IwSBxTCBwoAUo/nrOfqvbee2VklVKIFlyQEbuJWhgZ6kgZswgZgxCzAJBgNVBAYT
AlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEcMBoGA1UE
ChMTSGFzaGlDb3JwIFRlc3QgQ2VydDEMMAoGA1UECxMDRGV2MRYwFAYDVQQDEw10
ZXN0LmludGVybmFsMSAwHgYJKoZIhvcNAQkBFhF0ZXN0QGludGVybmFsLmNvbYIJ
AIewRMI8OnvTMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADa9fV9h
gjapBlkNmu64WX0Ufub5dsJrdHS8672P30S7ILB7Mk0W8sL65IezRsZnG898yHf9
2uzmz5OvNTM9K380g7xFlyobSVq+6yqmmSAlA/ptAcIIZT727P5jig/DB7fzJM3g
jctDlEGOmEe50GQXc25VKpcpjAsNQi5ER5gowQ0v3IXNZs+yU+LvxLHc0rUJ/XSp
lFCAMOqd5uRoMOejnT51G6krvLNzPaQ3N9jQfNVY4Q0zfs0M+6dRWvqfqB9Vyq8/
POLMld+HyAZEBk9zK3ZVIXx6XS4dkDnSNR91njLq7eouf6M7+7s/oMQZZRtAfQ6r
wlW975rYa1ZqEdA=
-----END CERTIFICATE-----

View File

@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFADCCAugCCQCPPTSu2adkQzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTE3MDQxNDE5MTE0MVoXDTIyMDMxOTE5MTE0MVowPzELMAkG
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxGzAZBgNVBAoMEkNvbnN1bCBU
ZXN0IENsaWVudDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOyJwuXC
N+8sOnFmWDx6w5Xs+ADd905EKkfrdLc0qIcrndZwdCx9zOeArLhUS1aoh0ctwz5x
wBsmUgwIQwr/V6Q1+sAEDmPmnuAiR/m3lxE+ZPr1CyNhrrTqs7jXkRRDNtZevw6d
mTE0FC4Tho016NVXckVZRRJL8Svfk2GvZbZ+1HAIi1a/Du7VQPbd1HOLKPkpb0JU
AksdAaks/avzKhRUoHQBR/T4S9GK95WrCqJIZG6iOVK2cymfZ9t/qYdm5czdq8ho
kWNqOtVb+yBx4/zs8JZI3/TZ/K4nSFcpZNZmPI7xsBL0/GG7nqWyAFWFsn/+4q0a
FIBVUe+ydONKoXKZI080b9CLkNXIp1P8rJsodjKZO/xr+/JCeo6D7ZAJymFe1QXJ
aGt7ac08s9scU97n0iuCRn6RXLdii9pbiAlArmAE1zXQKA/hcyVtjfUdeq0kA1RE
308gUab552XstQUHH0/+JcoPhn1UN+D6UOw7CxVQrq6FBDeDt7S/WtJNGM3GYrQW
tbvTQhDW0jBp0Tr+BwIDXYN5QLM6rcnB2GR3+aYVuvre6DrvisA6yKO+0F29n2LM
DdcUu8ZGzoEyFOZAgcw943VlU8bSxWkANoO0e3gKub4AvOaRqvVKyeFuFnwzKjSE
jiZTHVWs/1XVTnK51b9H33uK976O0q9qGlERAgMBAAEwDQYJKoZIhvcNAQELBQAD
ggIBAAGb44gmBikP4KJOLDDQWUX+l6kfIEobKzulmUcZ5puNS68fnQrWYUXTk5MK
IKBfuQSrxux/CEx1nBIZS/IcAnxG6GpxIcVdtzrZ/2yhDsmT3ZlgMo0+kNgqPnB2
hVe19HO44KAkjKpbjzqya2YX5CY83WBbB0kLvbRtBraU74LDyPD8Nb2YgCKkKZuC
WHtvMw/3bGQ74FXRIjLBv1moOiWaOvaMpztn4GzChZuU8Ikyps3YiRKES2gSvPIj
tynzyoED/ddNA6Q/NeLYaCqwzIVScuqBsDCNTvFqZztS4J7VJxxnRztXb/og2yE4
xqXezVV/O+6HhRPnxInYNiMRS++C/cyeKt150t/YS718KlebL4Pd+fQ4fDQzMyYl
ixEOVFLZiT07heUBkNA//Y0thBr/VbMvvcnMKmm3wLKsL/VGznI5akZhBa0DRj/0
y+dSNJ2CL4I11SQ5yIaVgggqVEJ6wUWpE5woLQuvg+P+QVgkBtGR7H5dmREMq06L
dPWFoBNBil5MNDLAt2eoOauoVdba1XWWW6HZJP9lR/qgFeE9yWAFUB0BwonkYJYM
0Tm9+Jv87nJAy+a1RDszjAMV/N1RvCOb9+2g4NnHSXNVqH+gP0BsVYP5e2A31GX0
aftVp7tPN1bSFt7nFZNbbsFhRD/fQvOpCOC/7pTnXx8zhl/2
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEhDCCAmwCAQAwPzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
GzAZBgNVBAoMEkNvbnN1bCBUZXN0IENsaWVudDCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAOyJwuXCN+8sOnFmWDx6w5Xs+ADd905EKkfrdLc0qIcrndZw
dCx9zOeArLhUS1aoh0ctwz5xwBsmUgwIQwr/V6Q1+sAEDmPmnuAiR/m3lxE+ZPr1
CyNhrrTqs7jXkRRDNtZevw6dmTE0FC4Tho016NVXckVZRRJL8Svfk2GvZbZ+1HAI
i1a/Du7VQPbd1HOLKPkpb0JUAksdAaks/avzKhRUoHQBR/T4S9GK95WrCqJIZG6i
OVK2cymfZ9t/qYdm5czdq8hokWNqOtVb+yBx4/zs8JZI3/TZ/K4nSFcpZNZmPI7x
sBL0/GG7nqWyAFWFsn/+4q0aFIBVUe+ydONKoXKZI080b9CLkNXIp1P8rJsodjKZ
O/xr+/JCeo6D7ZAJymFe1QXJaGt7ac08s9scU97n0iuCRn6RXLdii9pbiAlArmAE
1zXQKA/hcyVtjfUdeq0kA1RE308gUab552XstQUHH0/+JcoPhn1UN+D6UOw7CxVQ
rq6FBDeDt7S/WtJNGM3GYrQWtbvTQhDW0jBp0Tr+BwIDXYN5QLM6rcnB2GR3+aYV
uvre6DrvisA6yKO+0F29n2LMDdcUu8ZGzoEyFOZAgcw943VlU8bSxWkANoO0e3gK
ub4AvOaRqvVKyeFuFnwzKjSEjiZTHVWs/1XVTnK51b9H33uK976O0q9qGlERAgMB
AAGgADANBgkqhkiG9w0BAQsFAAOCAgEARWD26zR/JuyER2SmCq0GYc4i5bTmQOZw
BcToQsYQcfTrdZspzKhb4EM560tVqE8V6Ckkl2V97ZbbD7KIRgY6LEsCcr6VCfU5
rSiyHo1M/PDnK6FqYE0qTqqu3jOGmh97RAZi8REy8gfT/PrE8kDaEVfm0nCB8aaW
8wg6ncmStRLKJB4QP1YDpcQH568MMY/0E7xUixp1KjaA4VwE4QEFNoxmpp/Dwpzw
BB6kjlKM2tsjkbm0EHCPU5creAoqPNVQNCIVTDBUgkwhUrU2ljAjlC24tL66L0FP
RKmyk8yWR2PQkkkWlRwarypGmOAE0GMVMICNh5WTaPaa1XTTpZme3ctpZQZO3LRT
Bao4tXM3pA8vApCbkqExR1ow86HvOHv50Y+LQpD1fk7cj18npCR831f1cr/jQw6V
p4Z6bdftF38ZCsCdjUHXbtc3tA0220I+0e8ng1znAfMPQC+KVrHaapt1OFWGHPFk
KDLyxtZN1IOEOkjtI23KOUlEtG4jnm5UjFG43EXA3qmbUrHNCsHhRpHhMBqu4a0Z
ifPQ5+YFyUCmgVUSGeGmpnyxWalmwOT2Ygd/uhn7TnZ0GAv+x1tLHNe78Q8YKi9a
gw4zZcDFJmCPnVkfQ+lVSSY5GjSPI8DZCfr+IJBIPOiknTGP9g2dEbUX8xVyEfK6
18IjYxoATJE=
-----END CERTIFICATE REQUEST-----

View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFXTCCA0WgAwIBAgIJAKkYXwqUpHWIMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTcwNDE0MTkwNjIwWhcNMjIwNDE0MTkwNjIwWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEA0pMZRBhBHaYG1FttDzt+rctrM8NtslfbAbHflM4ly7mibCmrnh/sGYSP
Y/QcrGnCWrjXspUM0dxtmXGmXKj4yRpKhVYw16saDcn2t55dxMw23uEhgfrigtYS
/MoC78OaQryRGvYdxF5unrybBrXDrVfxA8ycYBOV04piS7NlN1/m3TkiNrqkl1up
paPscfFaY59yz3Lgq2vs8U1SLtph8ALwjJcz8O3BbBUQuiZYNuiLLnkRroxT3oSp
Zbdna2aXtdD/H9JJUoJLjoZp6x5fNOtc+5vF8QZ/jKeJDsxqwf4VT4Z6t8sUMFtO
YAR3QEV7wtOhWWfFVzdlCsKZhD8ryemlYSMJ7wfmXUeoiElSPRfvIHUTcJFx37VR
V6LmOzs1gjMpGZxGLk/GtaCbDlyCaT/hae8bqtRhngBy5bvGxmdSBQd0fjYRr2CP
Pz+Gzx3yQx8yb9VV7dTI3H4LWaTjuy2WooITzy3xY4bOvp4UwusFgbIdywwCpDFJ
zzy3FaqoMx06v5D3I9JCanlXk5FErA0GX45pPM4x3FWZfVwrXZtomBFDC6qlRMpH
FH8A/KrbpolwiDklSWUxHbfz32gpzf3kLW2nOVpnZPyAgSYudjSFGW00jRomCXOy
EOgQj/w+M3hKosvVqIE8IQgfMPNRCK9hn11gVqUvkdcYvo/2jUMCAwEAAaNQME4w
HQYDVR0OBBYEFMnRHZ6zGzu/N5MdNv4HKPP5rMqOMB8GA1UdIwQYMBaAFMnRHZ6z
Gzu/N5MdNv4HKPP5rMqOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
AFPWJZiQTupGr5B14PGPkiesyL1VCkO9D7nr6dXgQwAUTIdDuo9+nZg1HzOd1evY
tRWGTAYOsyGNLBIjdhvTZcZz625i1zXFRzkpu0iOUoaH77/XVGkAKyaeYc3oIe9i
bRke37/NQokmM3Eko+M/KoAk31osDxlmdQTOVqqoZN+ag6xsrpN6XUmhu3DNfw1j
xud6RMH6J+SamG/vUg+GyqKZ9WpKNcLliVPJgOfX1XI3wstOIqkhlw/qveIgIfPv
aUVf+rykdgqYMMQvR6qx0k5iHeqj+F1cZRp3P0Uao0hoxi+udgj0X3F7/s/Cbr9c
TPZrIlhicZgli9UOwrjZ4B4mEZ4aD8yDbYO3TZe2DnuhPI7uDFG8lvCuLYu8V/lA
0yRoBaJf5Z1IXI4190Ww6bmxYV/n5EAFi6o46hWRUiYROtKEcP9Rmabodgp+Jxw6
fwzcYqUXTOXR8/gAFPxt5oEfhZ8VJ4nlB9PFTjDi7Gbz+2MnmJokqkxLAR7//FEz
Rdmyfl+CvnPZ4TXLk77tuhf3Os9zHSTLobBdDivrTOpc0LdYw5l9yN9s93bG2TBr
2T0aKInqAduReLE2nhkYCdlY+dbjbELEiLicqSaEiwr9WbaWuLMoy4tDY52pYgTR
lEclafi+O3Y35hEE6VAfZvM1TeR3gvnnQf4ThqIxkRVl
-----END CERTIFICATE-----

View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1 @@
8F3D34AED9A76443

View File

@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFHDCCAwQCCQCPPTSu2adkQjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMB4XDTE3MDQxNDE5MDkzOFoXDTIyMDMxOTE5MDkzOFowWzELMAkG
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLY29uc3VsLnRlc3QwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQDI57K1LPlNXpK4ud6XbqhQAM9w6mym5d+5
utGlq+ojNrnKdhaokzDOcEpELLguQlFevDrTGuBJLxInmDvRN8BmYshZAuwW+odw
iGa4IiT9rN0JeQIQr9DvNjRe7Rhzb3v0CIFIwaBWZyRSdEKuZORyDOvSudATI2p9
Ux9HpWJKG9clHEiAjWeseLfEttkAZgojPgdz/7Nq2CT877QtdbbKO8h+IIKevhVM
JLIyWhwGMy5orlVP42om7wgAIonm8LFCHe84JUVlOjuJgMzfUvz/UuKJFbAku7Dt
UXKL+gZsJg5YHhtMMHQO40UDNTfxNEiIRNyOHaQv4ptRUJq7vIbBng+m1uyYFkJp
NvTf4+OApXzsfhb8bjt8QRn5fsCsYU94oUVy+DSw10EW+IR1F7pGJZX5dYZgm6H7
E+cj0pYV1dKbdP/5L3mv6KJUTaGDRanLiNPQFOyhs6y6Qf1Y7a270oge9UpHAQ6D
KI5jvCuwzW2wDE7KEpo5SGRIjoK9KfouyhlYAaIiJNnVyjVXDXGhzJgH+/2cGW/n
TQAqKl4OtmzyNpihgv9Mhm86nro0XLnZHruJZ/SvZgpmSs8luo70CFK990j65JiM
UTvBdKADfjCZB4NxVo3yUC0UVaMsoMg8mbOGJPErY8WaFCqwsBHLPmbvbZvp8BYs
ve3dDhh+OQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQABCbceu3dDQ+NSRN45vEiB
wiyq7NLVHoSw7UWN0RPg7SVOPNt7lOqQ5ZtYNJQ0XAuBdHzNAZ/sfUgfURJbYhs5
MYalkkmMkpNWZQoMYxdj1sLX6KzLFFOtcACUSuZyOSGCBmuEDuDUTsQp1drZjNqb
fOtCWAuvSSbw8SnO6eTjUCwjcbe482kR5vnoaoRetmtTpIFdxwOXnegDXgkBnMMr
JSx+xIRVn2JzxJwaBmtn16P0/ksEMSPh0rKRvzE9zC7Jm2DvNOgEkdK8ae6DHFYY
zSonWjX3SlT+gpvuCwXC4ZmO2nV4CH34JDUUNRPub7o+t5XTGUxPGo0c/tdQYWZc
k0XTRzK6pLAq4X3NAF83nZ8pEi5z1u0Y+Dcx3AqBfhJSc2wg5++GZbELZGAmgiH2
WZa2/9zkCUGPke4GoctYNNhTmquk6ysJjDO+xOtaEQNwk04mqBwvb7j85iRNBkYX
+9PDF4sumEkkuNFB9vRSEJVrn3onQuZ3n2k1IujR6S6Vojhvideo5aT1NVq+1SQ5
bDe5E4IyrsFuxjYNIyA1hZmX2/qXYJ9U05QbyMs170lNhoKkdOf1voCxG3+sRTfz
yhGNJ2ks0MuEEiEjOFh9Za9lnk4/OHUG4yjWWdE5S/WH1xyyfokIM7xbo3Le8XgJ
ddL0E6Ag/Ow1ey1H7gsNOA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIEoDCCAogCAQAwWzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLY29u
c3VsLnRlc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDI57K1LPlN
XpK4ud6XbqhQAM9w6mym5d+5utGlq+ojNrnKdhaokzDOcEpELLguQlFevDrTGuBJ
LxInmDvRN8BmYshZAuwW+odwiGa4IiT9rN0JeQIQr9DvNjRe7Rhzb3v0CIFIwaBW
ZyRSdEKuZORyDOvSudATI2p9Ux9HpWJKG9clHEiAjWeseLfEttkAZgojPgdz/7Nq
2CT877QtdbbKO8h+IIKevhVMJLIyWhwGMy5orlVP42om7wgAIonm8LFCHe84JUVl
OjuJgMzfUvz/UuKJFbAku7DtUXKL+gZsJg5YHhtMMHQO40UDNTfxNEiIRNyOHaQv
4ptRUJq7vIbBng+m1uyYFkJpNvTf4+OApXzsfhb8bjt8QRn5fsCsYU94oUVy+DSw
10EW+IR1F7pGJZX5dYZgm6H7E+cj0pYV1dKbdP/5L3mv6KJUTaGDRanLiNPQFOyh
s6y6Qf1Y7a270oge9UpHAQ6DKI5jvCuwzW2wDE7KEpo5SGRIjoK9KfouyhlYAaIi
JNnVyjVXDXGhzJgH+/2cGW/nTQAqKl4OtmzyNpihgv9Mhm86nro0XLnZHruJZ/Sv
ZgpmSs8luo70CFK990j65JiMUTvBdKADfjCZB4NxVo3yUC0UVaMsoMg8mbOGJPEr
Y8WaFCqwsBHLPmbvbZvp8BYsve3dDhh+OQIDAQABoAAwDQYJKoZIhvcNAQELBQAD
ggIBAIq+JNjO/pixXFRwYUISRib68ya39C0VKj2T8L4HsAtpP2K7gkKGEoQ5AFhi
wxe0424myEBBZ4kS6y5BCETtKFb3C9K4c2l1Wp5GIR9QUrj2qrorGnZNJSEBrtHm
G4neTxPyepZ+n9C9K5RWC/S/l8nge4+oWU2F0nWIAFK+4GGGTyXFjbfGKtET8CKd
NQ4jcrabkRd49qPrXhEMTWzPkKdtZ4Gh7eFVAi5IrgJJlJPhb5/XnUQ+6L7NrIWG
D1nHCq8XNDm8Gg9KiMuB4/A7dcqyaoyYofojrnZ2HryGTeLbezpwQmMfVy1dM0ht
vueKQwOS7xjiglsV48G5mmql+0auYoBLes2yYGBJ4gLC+Gwokav+FtRhyyRUVZ3+
lta2a8XpzdMpmESQrwvz+v37fC/eBsplhk8tTy0IQUzUp0KVCRkR40UHeH9YKsu1
cvPwfzk3DPt2wHWjBw7b8RKSXQFyszP9QWODqxnOtE7BoNdHiyxF/W4RaysIVrAG
Vs2iRNVSPexiT30BgnfQN1i1HU4eXC/QuTWilo86vwDOjpHhr9FdjPghLk2TbV+g
iO3TX0zy0t6Un5rLGMt066pAFCIqynT1sf3CTVXbaeWpkHj1wjVmYOoG75xxWMsv
GKmSoKRex/SDko3s2pmfQ+vmkCTKQqabayUH5mh1Ron9B043
-----END CERTIFICATE REQUEST-----

View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -39,6 +39,7 @@ type TestPerformanceConfig struct {
type TestPortConfig struct {
DNS int `json:"dns,omitempty"`
HTTP int `json:"http,omitempty"`
HTTPS int `json:"https,omitempty"`
SerfLan int `json:"serf_lan,omitempty"`
SerfWan int `json:"serf_wan,omitempty"`
Server int `json:"server,omitempty"`
@ -74,6 +75,11 @@ type TestServerConfig struct {
ACLDefaultPolicy string `json:"acl_default_policy,omitempty"`
ACLEnforceVersion8 bool `json:"acl_enforce_version_8"`
Encrypt string `json:"encrypt,omitempty"`
CAFile string `json:"ca_file,omitempty"`
CertFile string `json:"cert_file,omitempty"`
KeyFile string `json:"key_file,omitempty"`
VerifyIncoming bool `json:"verify_incoming,omitempty"`
VerifyOutgoing bool `json:"verify_outgoing,omitempty"`
Stdout, Stderr io.Writer `json:"-"`
Args []string `json:"-"`
}
@ -105,6 +111,7 @@ func defaultServerConfig() *TestServerConfig {
Ports: &TestPortConfig{
DNS: randomPort(),
HTTP: randomPort(),
HTTPS: randomPort(),
SerfLan: randomPort(),
SerfWan: randomPort(),
Server: randomPort(),
@ -150,9 +157,10 @@ type TestServer struct {
cmd *exec.Cmd
Config *TestServerConfig
HTTPAddr string
LANAddr string
WANAddr string
HTTPAddr string
HTTPSAddr string
LANAddr string
WANAddr string
HttpClient *http.Client
}
@ -243,9 +251,10 @@ func NewTestServerConfig(cb ServerConfigCallback) (*TestServer, error) {
Config: consulConfig,
cmd: cmd,
HTTPAddr: httpAddr,
LANAddr: fmt.Sprintf("127.0.0.1:%d", consulConfig.Ports.SerfLan),
WANAddr: fmt.Sprintf("127.0.0.1:%d", consulConfig.Ports.SerfWan),
HTTPAddr: httpAddr,
HTTPSAddr: fmt.Sprintf("127.0.0.1:%d", consulConfig.Ports.HTTPS),
LANAddr: fmt.Sprintf("127.0.0.1:%d", consulConfig.Ports.SerfLan),
WANAddr: fmt.Sprintf("127.0.0.1:%d", consulConfig.Ports.SerfWan),
HttpClient: client,
}

363
vendor/github.com/hashicorp/go-rootcerts/LICENSE generated vendored Normal file
View File

@ -0,0 +1,363 @@
Mozilla Public License, version 2.0
1. Definitions
1.1. "Contributor"
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. "Incompatible With Secondary Licenses"
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the terms of
a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in a
separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible, whether
at the time of the initial grant or subsequently, any and all of the
rights conveyed by this License.
1.10. "Modifications"
means any of the following:
a. any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the License,
by the making, using, selling, offering for sale, having made, import,
or transfer of either its Contributions or its Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, "control" means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights to
grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter the
recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty, or
limitations of liability) contained within the Source Code Form of the
Covered Software, except that You may alter any license notices to the
extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute,
judicial order, or regulation then You must: (a) comply with the terms of
this License to the maximum extent possible; and (b) describe the
limitations and the code they affect. Such description must be placed in a
text file included with all distributions of the Covered Software under
this License. Except to the extent prohibited by statute or regulation,
such description must be sufficiently detailed for a recipient of ordinary
skill to be able to understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing
basis, if such Contributor fails to notify You of the non-compliance by
some reasonable means prior to 60 days after You have come back into
compliance. Moreover, Your grants from a particular Contributor are
reinstated on an ongoing basis if such Contributor notifies You of the
non-compliance by some reasonable means, this is the first time You have
received notice of non-compliance with this License from such
Contributor, and You become compliant prior to 30 days after Your receipt
of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an "as is" basis,
without warranty of any kind, either expressed, implied, or statutory,
including, without limitation, warranties that the Covered Software is free
of defects, merchantable, fit for a particular purpose or non-infringing.
The entire risk as to the quality and performance of the Covered Software
is with You. Should any Covered Software prove defective in any respect,
You (not any Contributor) assume the cost of any necessary servicing,
repair, or correction. This disclaimer of warranty constitutes an essential
part of this License. No use of any Covered Software is authorized under
this License except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from
such party's negligence to the extent applicable law prohibits such
limitation. Some jurisdictions do not allow the exclusion or limitation of
incidental or consequential damages, so this exclusion and limitation may
not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts
of a jurisdiction where the defendant maintains its principal place of
business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions. Nothing
in this Section shall prevent a party's ability to bring cross-claims or
counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides that
the language of a contract shall be construed against the drafter shall not
be used to construe this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses If You choose to distribute Source Code Form that is
Incompatible With Secondary Licenses under the terms of this version of
the License, the notice described in Exhibit B of this License must be
attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file,
then You may include the notice in a location (such as a LICENSE file in a
relevant directory) where a recipient would be likely to look for such a
notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
This Source Code Form is "Incompatible
With Secondary Licenses", as defined by
the Mozilla Public License, v. 2.0.

8
vendor/github.com/hashicorp/go-rootcerts/Makefile generated vendored Normal file
View File

@ -0,0 +1,8 @@
TEST?=./...
test:
go test $(TEST) $(TESTARGS) -timeout=3s -parallel=4
go vet $(TEST)
go test $(TEST) -race
.PHONY: test

43
vendor/github.com/hashicorp/go-rootcerts/README.md generated vendored Normal file
View File

@ -0,0 +1,43 @@
# rootcerts
Functions for loading root certificates for TLS connections.
-----
Go's standard library `crypto/tls` provides a common mechanism for configuring
TLS connections in `tls.Config`. The `RootCAs` field on this struct is a pool
of certificates for the client to use as a trust store when verifying server
certificates.
This library contains utility functions for loading certificates destined for
that field, as well as one other important thing:
When the `RootCAs` field is `nil`, the standard library attempts to load the
host's root CA set. This behavior is OS-specific, and the Darwin
implementation contains [a bug that prevents trusted certificates from the
System and Login keychains from being loaded][1]. This library contains
Darwin-specific behavior that works around that bug.
[1]: https://github.com/golang/go/issues/14514
## Example Usage
Here's a snippet demonstrating how this library is meant to be used:
```go
func httpClient() (*http.Client, error)
tlsConfig := &tls.Config{}
err := rootcerts.ConfigureTLS(tlsConfig, &rootcerts.Config{
CAFile: os.Getenv("MYAPP_CAFILE"),
CAPath: os.Getenv("MYAPP_CAPATH"),
})
if err != nil {
return nil, err
}
c := cleanhttp.DefaultClient()
t := cleanhttp.DefaultTransport()
t.TLSClientConfig = tlsConfig
c.Transport = t
return c, nil
}
```

9
vendor/github.com/hashicorp/go-rootcerts/doc.go generated vendored Normal file
View File

@ -0,0 +1,9 @@
// Package rootcerts contains functions to aid in loading CA certificates for
// TLS connections.
//
// In addition, its default behavior on Darwin works around an open issue [1]
// in Go's crypto/x509 that prevents certicates from being loaded from the
// System or Login keychains.
//
// [1] https://github.com/golang/go/issues/14514
package rootcerts

103
vendor/github.com/hashicorp/go-rootcerts/rootcerts.go generated vendored Normal file
View File

@ -0,0 +1,103 @@
package rootcerts
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
// Config determines where LoadCACerts will load certificates from. When both
// CAFile and CAPath are blank, this library's functions will either load
// system roots explicitly and return them, or set the CertPool to nil to allow
// Go's standard library to load system certs.
type Config struct {
// CAFile is a path to a PEM-encoded certificate file or bundle. Takes
// precedence over CAPath.
CAFile string
// CAPath is a path to a directory populated with PEM-encoded certificates.
CAPath string
}
// ConfigureTLS sets up the RootCAs on the provided tls.Config based on the
// Config specified.
func ConfigureTLS(t *tls.Config, c *Config) error {
if t == nil {
return nil
}
pool, err := LoadCACerts(c)
if err != nil {
return err
}
t.RootCAs = pool
return nil
}
// LoadCACerts loads a CertPool based on the Config specified.
func LoadCACerts(c *Config) (*x509.CertPool, error) {
if c == nil {
c = &Config{}
}
if c.CAFile != "" {
return LoadCAFile(c.CAFile)
}
if c.CAPath != "" {
return LoadCAPath(c.CAPath)
}
return LoadSystemCAs()
}
// LoadCAFile loads a single PEM-encoded file from the path specified.
func LoadCAFile(caFile string) (*x509.CertPool, error) {
pool := x509.NewCertPool()
pem, err := ioutil.ReadFile(caFile)
if err != nil {
return nil, fmt.Errorf("Error loading CA File: %s", err)
}
ok := pool.AppendCertsFromPEM(pem)
if !ok {
return nil, fmt.Errorf("Error loading CA File: Couldn't parse PEM in: %s", caFile)
}
return pool, nil
}
// LoadCAPath walks the provided path and loads all certificates encounted into
// a pool.
func LoadCAPath(caPath string) (*x509.CertPool, error) {
pool := x509.NewCertPool()
walkFn := func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
pem, err := ioutil.ReadFile(path)
if err != nil {
return fmt.Errorf("Error loading file from CAPath: %s", err)
}
ok := pool.AppendCertsFromPEM(pem)
if !ok {
return fmt.Errorf("Error loading CA Path: Couldn't parse PEM in: %s", path)
}
return nil
}
err := filepath.Walk(caPath, walkFn)
if err != nil {
return nil, err
}
return pool, nil
}

View File

@ -0,0 +1,12 @@
// +build !darwin
package rootcerts
import "crypto/x509"
// LoadSystemCAs does nothing on non-Darwin systems. We return nil so that
// default behavior of standard TLS config libraries is triggered, which is to
// load system certs.
func LoadSystemCAs() (*x509.CertPool, error) {
return nil, nil
}

View File

@ -0,0 +1,48 @@
package rootcerts
import (
"crypto/x509"
"os/exec"
"path"
"github.com/mitchellh/go-homedir"
)
// LoadSystemCAs has special behavior on Darwin systems to work around
func LoadSystemCAs() (*x509.CertPool, error) {
pool := x509.NewCertPool()
for _, keychain := range certKeychains() {
err := addCertsFromKeychain(pool, keychain)
if err != nil {
return nil, err
}
}
return pool, nil
}
func addCertsFromKeychain(pool *x509.CertPool, keychain string) error {
cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", keychain)
data, err := cmd.Output()
if err != nil {
return err
}
pool.AppendCertsFromPEM(data)
return nil
}
func certKeychains() []string {
keychains := []string{
"/System/Library/Keychains/SystemRootCertificates.keychain",
"/Library/Keychains/System.keychain",
}
home, err := homedir.Dir()
if err == nil {
loginKeychain := path.Join(home, "Library", "Keychains", "login.keychain")
keychains = append(keychains, loginKeychain)
}
return keychains
}

21
vendor/github.com/mitchellh/go-homedir/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2013 Mitchell Hashimoto
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

14
vendor/github.com/mitchellh/go-homedir/README.md generated vendored Normal file
View File

@ -0,0 +1,14 @@
# go-homedir
This is a Go library for detecting the user's home directory without
the use of cgo, so the library can be used in cross-compilation environments.
Usage is incredibly simple, just call `homedir.Dir()` to get the home directory
for a user, and `homedir.Expand()` to expand the `~` in a path to the home
directory.
**Why not just use `os/user`?** The built-in `os/user` package requires
cgo on Darwin systems. This means that any Go code that uses that package
cannot cross compile. But 99% of the time the use for `os/user` is just to
retrieve the home directory, which we can do for the current user without
cgo. This library does that, enabling cross-compilation.

137
vendor/github.com/mitchellh/go-homedir/homedir.go generated vendored Normal file
View File

@ -0,0 +1,137 @@
package homedir
import (
"bytes"
"errors"
"os"
"os/exec"
"path/filepath"
"runtime"
"strconv"
"strings"
"sync"
)
// DisableCache will disable caching of the home directory. Caching is enabled
// by default.
var DisableCache bool
var homedirCache string
var cacheLock sync.RWMutex
// Dir returns the home directory for the executing user.
//
// This uses an OS-specific method for discovering the home directory.
// An error is returned if a home directory cannot be detected.
func Dir() (string, error) {
if !DisableCache {
cacheLock.RLock()
cached := homedirCache
cacheLock.RUnlock()
if cached != "" {
return cached, nil
}
}
cacheLock.Lock()
defer cacheLock.Unlock()
var result string
var err error
if runtime.GOOS == "windows" {
result, err = dirWindows()
} else {
// Unix-like system, so just assume Unix
result, err = dirUnix()
}
if err != nil {
return "", err
}
homedirCache = result
return result, nil
}
// Expand expands the path to include the home directory if the path
// is prefixed with `~`. If it isn't prefixed with `~`, the path is
// returned as-is.
func Expand(path string) (string, error) {
if len(path) == 0 {
return path, nil
}
if path[0] != '~' {
return path, nil
}
if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
return "", errors.New("cannot expand user-specific home dir")
}
dir, err := Dir()
if err != nil {
return "", err
}
return filepath.Join(dir, path[1:]), nil
}
func dirUnix() (string, error) {
// First prefer the HOME environmental variable
if home := os.Getenv("HOME"); home != "" {
return home, nil
}
// If that fails, try getent
var stdout bytes.Buffer
cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid()))
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
// If the error is ErrNotFound, we ignore it. Otherwise, return it.
if err != exec.ErrNotFound {
return "", err
}
} else {
if passwd := strings.TrimSpace(stdout.String()); passwd != "" {
// username:password:uid:gid:gecos:home:shell
passwdParts := strings.SplitN(passwd, ":", 7)
if len(passwdParts) > 5 {
return passwdParts[5], nil
}
}
}
// If all else fails, try the shell
stdout.Reset()
cmd = exec.Command("sh", "-c", "cd && pwd")
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
return "", err
}
result := strings.TrimSpace(stdout.String())
if result == "" {
return "", errors.New("blank output when reading home directory")
}
return result, nil
}
func dirWindows() (string, error) {
// First prefer the HOME environmental variable
if home := os.Getenv("HOME"); home != "" {
return home, nil
}
drive := os.Getenv("HOMEDRIVE")
path := os.Getenv("HOMEPATH")
home := drive + path
if drive == "" || path == "" {
home = os.Getenv("USERPROFILE")
}
if home == "" {
return "", errors.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank")
}
return home, nil
}

12
vendor/vendor.json vendored
View File

@ -479,6 +479,12 @@
"revision": "6e85be8fee1dcaa02c0eaaac2df5a8fbecf94145",
"revisionTime": "2016-09-30T03:51:02Z"
},
{
"checksumSHA1": "A1PcINvF3UiwHRKn8UcgARgvGRs=",
"path": "github.com/hashicorp/go-rootcerts",
"revision": "6bb64b370b90e7ef1fa532be9e591a81c3493e00",
"revisionTime": "2016-05-03T14:34:40Z"
},
{
"checksumSHA1": "BGODc7juQbdG3vNXHZG07kt+lKI=",
"path": "github.com/hashicorp/go-sockaddr",
@ -681,6 +687,12 @@
"revision": "cdac8253d00f2ecf0a0b19fbff173a9a72de4f82",
"revisionTime": "2016-08-04T03:23:30Z"
},
{
"checksumSHA1": "V/quM7+em2ByJbWBLOsEwnY3j/Q=",
"path": "github.com/mitchellh/go-homedir",
"revision": "b8bc1bf767474819792c23f32d8286a45736f1c6",
"revisionTime": "2016-12-03T19:45:07Z"
},
{
"checksumSHA1": "LUrnGREfnifW4WDMaavmc9MlLI0=",
"path": "github.com/mitchellh/mapstructure",

View File

@ -1,3 +1,18 @@
* `-ca-file=<value>` - Path to a CA file to use for TLS when communicating with Consul.
This can also be specified via the `CONSUL_CACERT` environment variable.
* `-ca-path=<value>` - Path to a directory of CA certificates to use for TLS when
communicating with Consul. This can also be specified via the `CONSUL_CAPATH`
environment variable.
* `-client-cert=<value>` - Path to a client cert file to use for TLS when
`verify_incoming` is enabled. This can also be specified via the `CONSUL_CLIENT_CERT`
environment variable.
* `-client-key=<value>` - Path to a client key file to use for TLS when
`verify_incoming` is enabled. This can also be specified via the `CONSUL_CLIENT_KEY`
environment variable.
* `-http-addr=<addr>` - Address of the Consul agent with the port. This can be
an IP address or DNS address, but it must include the port. This can also be
specified via the `CONSUL_HTTP_ADDR` environment variable. In Consul 0.8 and
@ -5,6 +20,10 @@
be used instead. The scheme can also be set to HTTPS by setting the
environment variable `CONSUL_HTTP_SSL=true`.
* `-tls-server-name=<value>` - The server name to use as the SNI host when
connecting via TLS. This can also be specified via the `CONSUL_TLS_SERVER_NAME`
environment variable.
* `-token=<value>` - ACL token to use in the request. This can also be specified
via the `CONSUL_HTTP_TOKEN` environment variable. If unspecified, the query
will default to the token of the Consul agent at the HTTP address.

View File

@ -137,3 +137,43 @@ for development purposes:
```
CONSUL_HTTP_SSL_VERIFY=false
```
### `CONSUL_CACERT`
Path to a CA file to use for TLS when communicating with Consul.
```
CONSUL_CACERT=ca.crt
```
### `CONSUL_CAPATH`
Path to a directory of CA certificates to use for TLS when communicating with Consul.
```
CONSUL_CAPATH=ca_certs/
```
### `CONSUL_CLIENT_CERT`
Path to a client cert file to use for TLS when `verify_incoming` is enabled.
```
CONSUL_CLIENT_CERT=client.crt
```
### `CONSUL_CLIENT_KEY`
Path to a client key file to use for TLS when `verify_incoming` is enabled.
```
CONSUL_CLIENT_KEY=client.key
```
### `CONSUL_TLS_SERVER_NAME`
The server name to use as the SNI host when connecting via TLS.
```
CONSUL_TLS_SERVER_NAME=consulserver.domain
```