The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/3651
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) ===
From e7202775af5dc122a845eea75b8c53a10ea11a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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 +}
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel