The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/5100
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Signed-off-by: Stéphane Graber <[email protected]>
From 018ec48c3d92415ed02aadf3ca393ec542cb99e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <[email protected]> Date: Wed, 3 Oct 2018 17:45:33 -0400 Subject: [PATCH] candid: Fix client when using https candid server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <[email protected]> --- client/connection.go | 28 +++++++++++++++++++++------- client/util.go | 15 ++++++++++++++- shared/network.go | 5 ++++- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/client/connection.go b/client/connection.go index b300cae198..f5d0e218ac 100644 --- a/client/connection.go +++ b/client/connection.go @@ -129,7 +129,7 @@ func ConnectPublicLXD(url string, args *ConnectionArgs) (ImageServer, error) { // ConnectSimpleStreams lets you connect to a remote SimpleStreams image server over HTTPs. // // Unless the remote server is trusted by the system CA, the remote certificate must be provided (TLSServerCert). -func ConnectSimpleStreams(url string, args *ConnectionArgs) (ImageServer, error) { +func ConnectSimpleStreams(uri string, args *ConnectionArgs) (ImageServer, error) { logger.Debugf("Connecting to a remote simplestreams server") // Use empty args if not specified @@ -139,27 +139,34 @@ func ConnectSimpleStreams(url string, args *ConnectionArgs) (ImageServer, error) // Initialize the client struct server := ProtocolSimpleStreams{ - httpHost: url, + httpHost: uri, httpUserAgent: args.UserAgent, httpCertificate: args.TLSServerCert, } + // Parse the URL + u, err := url.Parse(uri) + if err != nil { + return nil, err + } + tlsServerHost := u.Host + // Setup the HTTP client - httpClient, err := tlsHTTPClient(args.HTTPClient, args.TLSClientCert, args.TLSClientKey, args.TLSCA, args.TLSServerCert, args.InsecureSkipVerify, args.Proxy) + httpClient, err := tlsHTTPClient(args.HTTPClient, args.TLSClientCert, args.TLSClientKey, args.TLSCA, tlsServerHost, args.TLSServerCert, args.InsecureSkipVerify, args.Proxy) if err != nil { return nil, err } server.http = httpClient // Get simplestreams client - ssClient := simplestreams.NewClient(url, *httpClient, args.UserAgent) + ssClient := simplestreams.NewClient(uri, *httpClient, args.UserAgent) server.ssClient = ssClient return &server, nil } // Internal function called by ConnectLXD and ConnectPublicLXD -func httpsLXD(url string, args *ConnectionArgs) (ContainerServer, error) { +func httpsLXD(uri string, args *ConnectionArgs) (ContainerServer, error) { // Use empty args if not specified if args == nil { args = &ConnectionArgs{} @@ -168,7 +175,7 @@ func httpsLXD(url string, args *ConnectionArgs) (ContainerServer, error) { // Initialize the client struct server := ProtocolLXD{ httpCertificate: args.TLSServerCert, - httpHost: url, + httpHost: uri, httpProtocol: "https", httpUserAgent: args.UserAgent, bakeryInteractor: args.AuthInteractor, @@ -177,8 +184,15 @@ func httpsLXD(url string, args *ConnectionArgs) (ContainerServer, error) { server.RequireAuthenticated(true) } + // Parse the URL + u, err := url.Parse(uri) + if err != nil { + return nil, err + } + tlsServerHost := u.Host + // Setup the HTTP client - httpClient, err := tlsHTTPClient(args.HTTPClient, args.TLSClientCert, args.TLSClientKey, args.TLSCA, args.TLSServerCert, args.InsecureSkipVerify, args.Proxy) + httpClient, err := tlsHTTPClient(args.HTTPClient, args.TLSClientCert, args.TLSClientKey, args.TLSCA, tlsServerHost, args.TLSServerCert, args.InsecureSkipVerify, args.Proxy) if err != nil { return nil, err } diff --git a/client/util.go b/client/util.go index 3826c138e1..0a5704a83d 100644 --- a/client/util.go +++ b/client/util.go @@ -1,6 +1,7 @@ package lxd import ( + "crypto/tls" "fmt" "io" "net" @@ -11,7 +12,7 @@ import ( "github.com/lxc/lxd/shared" ) -func tlsHTTPClient(client *http.Client, tlsClientCert string, tlsClientKey string, tlsCA string, tlsServerCert string, insecureSkipVerify bool, proxy func(req *http.Request) (*url.URL, error)) (*http.Client, error) { +func tlsHTTPClient(client *http.Client, tlsClientCert string, tlsClientKey string, tlsCA string, tlsServerHost string, tlsServerCert string, insecureSkipVerify bool, proxy func(req *http.Request) (*url.URL, error)) (*http.Client, error) { // Get the TLS configuration tlsConfig, err := shared.GetTLSConfigMem(tlsClientCert, tlsClientKey, tlsCA, tlsServerCert, insecureSkipVerify) if err != nil { @@ -31,6 +32,18 @@ func tlsHTTPClient(client *http.Client, tlsClientCert string, tlsClientKey strin transport.Proxy = proxy } + // Special TLS handling + transport.DialTLS = func(network string, addr string) (net.Conn, error) { + config := transport.TLSClientConfig.Clone() + + // If forwarded to another host, clear ServerName + if addr != tlsServerHost { + config.ServerName = "" + } + + return tls.Dial(network, addr, config) + } + // Define the http client if client == nil { client = &http.Client{} diff --git a/shared/network.go b/shared/network.go index 1a82c7bca9..78da2966b7 100644 --- a/shared/network.go +++ b/shared/network.go @@ -69,7 +69,10 @@ func finalizeTLSConfig(tlsConfig *tls.Config, tlsRemoteCert *x509.Certificate) { if tlsRemoteCert != nil { caCertPool := tlsConfig.RootCAs if caCertPool == nil { - caCertPool = x509.NewCertPool() + caCertPool, _ = x509.SystemCertPool() + if caCertPool == nil { + caCertPool = x509.NewCertPool() + } } // Make it a valid RootCA
_______________________________________________ lxc-devel mailing list [email protected] http://lists.linuxcontainers.org/listinfo/lxc-devel
