[lxc-devel] [lxd/master] Expose some certificate functions used by downstreams

stgraber on Github lxc-bot at linuxcontainers.org
Thu Aug 10 21:40:31 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170810/025be2e6/attachment.bin>
-------------- next part --------------
From e7202775af5dc122a845eea75b8c53a10ea11a4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 10 Aug 2017 17:20:01 -0400
Subject: [PATCH 1/2] lxc/config: Expose extra certificate functions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #3606

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxc/config/cert.go | 28 ++++++++++++++++++++++++++++
 lxc/remote.go      | 32 ++++++--------------------------
 2 files changed, 34 insertions(+), 26 deletions(-)
 create mode 100644 lxc/config/cert.go

diff --git a/lxc/config/cert.go b/lxc/config/cert.go
new file mode 100644
index 000000000..17b3f426a
--- /dev/null
+++ b/lxc/config/cert.go
@@ -0,0 +1,28 @@
+package config
+
+import (
+	"github.com/lxc/lxd/shared"
+)
+
+// HasClientCertificate will return true if a client certificate has already been generated
+func (c *Config) HasClientCertificate() bool {
+	certf := c.ConfigPath("client.crt")
+	keyf := c.ConfigPath("client.key")
+	if !shared.PathExists(certf) || !shared.PathExists(keyf) {
+		return false
+	}
+
+	return true
+}
+
+// GenerateClientCertificate will generate the needed client.crt and client.key if needed
+func (c *Config) GenerateClientCertificate() error {
+	if c.HasClientCertificate() {
+		return nil
+	}
+
+	certf := c.ConfigPath("client.crt")
+	keyf := c.ConfigPath("client.key")
+
+	return shared.FindOrGenCert(certf, keyf, true)
+}
diff --git a/lxc/remote.go b/lxc/remote.go
index 5296d250b..2424af8f0 100644
--- a/lxc/remote.go
+++ b/lxc/remote.go
@@ -71,29 +71,6 @@ func (c *remoteCmd) flags() {
 	gnuflag.BoolVar(&c.public, "public", false, i18n.G("Public image server"))
 }
 
-func (c *remoteCmd) generateClientCertificate(conf *config.Config) error {
-	// Create the config path if needed
-	if !shared.PathExists(conf.ConfigDir) {
-		err := os.MkdirAll(conf.ConfigDir, 0750)
-		if err != nil {
-			return fmt.Errorf(i18n.G("Could not create config dir"))
-		}
-	}
-
-	// Generate a client certificate if necessary.  The default repositories are
-	// either local or public, neither of which requires a client certificate.
-	// Generation of the cert is delayed to avoid unnecessary overhead, e.g in
-	// testing scenarios where only the default repositories are used.
-	certf := conf.ConfigPath("client.crt")
-	keyf := conf.ConfigPath("client.key")
-	if !shared.PathExists(certf) || !shared.PathExists(keyf) {
-		fmt.Fprintf(os.Stderr, i18n.G("Generating a client certificate. This may take a minute...")+"\n")
-
-		return shared.FindOrGenCert(certf, keyf, true)
-	}
-	return nil
-}
-
 func (c *remoteCmd) getRemoteCertificate(address string) (*x509.Certificate, error) {
 	// Setup a permissive TLS config
 	tlsConfig, err := shared.GetTLSConfig("", "", "", nil)
@@ -204,9 +181,12 @@ func (c *remoteCmd) addServer(conf *config.Config, server string, addr string, a
 	// HTTPS server then we need to ensure we have a client certificate before
 	// adding the remote server.
 	if rScheme != "unix" && !public {
-		err = c.generateClientCertificate(conf)
-		if err != nil {
-			return err
+		if !conf.HasClientCertificate() {
+			fmt.Fprintf(os.Stderr, i18n.G("Generating a client certificate. This may take a minute...")+"\n")
+			err = conf.GenerateClientCertificate()
+			if err != nil {
+				return err
+			}
 		}
 	}
 	conf.Remotes[server] = config.Remote{Addr: addr, Protocol: protocol}

From 413b2816324b2690e81ad4fbdda78a1e06eeb259 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 10 Aug 2017 17:33:19 -0400
Subject: [PATCH 2/2] shared: Move GetRemoteCertificate from lxc/remote
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #3606

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxc/remote.go  | 32 +-------------------------------
 shared/cert.go | 30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/lxc/remote.go b/lxc/remote.go
index 2424af8f0..2dd5feed0 100644
--- a/lxc/remote.go
+++ b/lxc/remote.go
@@ -5,7 +5,6 @@ import (
 	"encoding/pem"
 	"fmt"
 	"net"
-	"net/http"
 	"net/url"
 	"os"
 	"path/filepath"
@@ -71,35 +70,6 @@ func (c *remoteCmd) flags() {
 	gnuflag.BoolVar(&c.public, "public", false, i18n.G("Public image server"))
 }
 
-func (c *remoteCmd) getRemoteCertificate(address string) (*x509.Certificate, error) {
-	// Setup a permissive TLS config
-	tlsConfig, err := shared.GetTLSConfig("", "", "", nil)
-	if err != nil {
-		return nil, err
-	}
-
-	tlsConfig.InsecureSkipVerify = true
-	tr := &http.Transport{
-		TLSClientConfig: tlsConfig,
-		Dial:            shared.RFC3493Dialer,
-		Proxy:           shared.ProxyFromEnvironment,
-	}
-
-	// Connect
-	client := &http.Client{Transport: tr}
-	resp, err := client.Get(address)
-	if err != nil {
-		return nil, err
-	}
-
-	// Retrieve the certificate
-	if resp.TLS == nil || len(resp.TLS.PeerCertificates) == 0 {
-		return nil, fmt.Errorf(i18n.G("Unable to read remote TLS certificate"))
-	}
-
-	return resp.TLS.PeerCertificates[0], nil
-}
-
 func (c *remoteCmd) addServer(conf *config.Config, server string, addr string, acceptCert bool, password string, public bool, protocol string) error {
 	var rScheme string
 	var rHost string
@@ -208,7 +178,7 @@ func (c *remoteCmd) addServer(conf *config.Config, server string, addr string, a
 	var certificate *x509.Certificate
 	if err != nil {
 		// Failed to connect using the system CA, so retrieve the remote certificate
-		certificate, err = c.getRemoteCertificate(addr)
+		certificate, err = shared.GetRemoteCertificate(addr)
 		if err != nil {
 			return err
 		}
diff --git a/shared/cert.go b/shared/cert.go
index b264ee1d8..d9f19df5b 100644
--- a/shared/cert.go
+++ b/shared/cert.go
@@ -17,6 +17,7 @@ import (
 	"log"
 	"math/big"
 	"net"
+	"net/http"
 	"os"
 	"os/user"
 	"path"
@@ -222,3 +223,32 @@ func CertFingerprintStr(c string) (string, error) {
 
 	return CertFingerprint(cert), nil
 }
+
+func GetRemoteCertificate(address string) (*x509.Certificate, error) {
+	// Setup a permissive TLS config
+	tlsConfig, err := GetTLSConfig("", "", "", nil)
+	if err != nil {
+		return nil, err
+	}
+
+	tlsConfig.InsecureSkipVerify = true
+	tr := &http.Transport{
+		TLSClientConfig: tlsConfig,
+		Dial:            RFC3493Dialer,
+		Proxy:           ProxyFromEnvironment,
+	}
+
+	// Connect
+	client := &http.Client{Transport: tr}
+	resp, err := client.Get(address)
+	if err != nil {
+		return nil, err
+	}
+
+	// Retrieve the certificate
+	if resp.TLS == nil || len(resp.TLS.PeerCertificates) == 0 {
+		return nil, fmt.Errorf("Unable to read remote TLS certificate")
+	}
+
+	return resp.TLS.PeerCertificates[0], nil
+}


More information about the lxc-devel mailing list