[lxc-devel] [lxd/master] Properly handle domains and cookies with candid

stgraber on Github lxc-bot at linuxcontainers.org
Sat Feb 16 03:22:17 UTC 2019


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/20190215/a2753a46/attachment.bin>
-------------- next part --------------
From 7b408f01fec21212c6eb9f958b738cc66b7c14f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 15 Feb 2019 22:20:12 -0500
Subject: [PATCH 1/2] config: Keep candid domains and cookies per-remote
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxc/config/config.go | 26 ++++++-----------
 lxc/config/remote.go | 69 +++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 70 insertions(+), 25 deletions(-)

diff --git a/lxc/config/config.go b/lxc/config/config.go
index 2c77df6523..01cb785530 100644
--- a/lxc/config/config.go
+++ b/lxc/config/config.go
@@ -5,7 +5,6 @@ import (
 	"path/filepath"
 
 	"github.com/juju/persistent-cookiejar"
-	"gopkg.in/macaroon-bakery.v2/httpbakery"
 )
 
 // Config holds settings to be used by a client or daemon
@@ -33,9 +32,8 @@ type Config struct {
 	// ProjectOverride allows overriding the default project for container queries
 	ProjectOverride string `yaml:"-"`
 
-	authInteractor []httpbakery.Interactor
-
-	cookiejar *cookiejar.Jar
+	// Cookie jars
+	cookieJars map[string]*cookiejar.Jar
 }
 
 // ConfigPath returns a joined path of the configuration directory and passed arguments
@@ -46,20 +44,20 @@ func (c *Config) ConfigPath(paths ...string) string {
 	return filepath.Join(path...)
 }
 
+// CookiesPath returns the path for the remote's cookie jar
+func (c *Config) CookiesPath(remote string) string {
+	return c.ConfigPath("jars", remote)
+}
+
 // ServerCertPath returns the path for the remote's server certificate
 func (c *Config) ServerCertPath(remote string) string {
 	return c.ConfigPath("servercerts", fmt.Sprintf("%s.crt", remote))
 }
 
-// SetAuthInteractor sets the interactor for macaroon-based authorization
-func (c *Config) SetAuthInteractor(interactor []httpbakery.Interactor) {
-	c.authInteractor = interactor
-}
-
 // SaveCookies saves cookies to file
 func (c *Config) SaveCookies() {
-	if c.cookiejar != nil {
-		c.cookiejar.Save()
+	for _, jar := range c.cookieJars {
+		jar.Save()
 	}
 }
 
@@ -71,11 +69,5 @@ func NewConfig(configDir string, defaults bool) *Config {
 		config.DefaultRemote = "local"
 	}
 
-	if configDir != "" {
-		config.cookiejar, _ = cookiejar.New(
-			&cookiejar.Options{
-				Filename: filepath.Join(configDir, "cookies")})
-	}
-
 	return config
 }
diff --git a/lxc/config/remote.go b/lxc/config/remote.go
index 39e3d20a36..8e950989f4 100644
--- a/lxc/config/remote.go
+++ b/lxc/config/remote.go
@@ -4,9 +4,16 @@ import (
 	"crypto/x509"
 	"encoding/pem"
 	"fmt"
+	"net/url"
+	"os"
 	"io/ioutil"
 	"strings"
 
+	"github.com/juju/persistent-cookiejar"
+	"gopkg.in/macaroon-bakery.v2/httpbakery"
+	"gopkg.in/macaroon-bakery.v2/httpbakery/form"
+	schemaform "gopkg.in/juju/environschema.v1/form"
+
 	"github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/shared"
 )
@@ -14,11 +21,12 @@ import (
 // Remote holds details for communication with a remote daemon
 type Remote struct {
 	Addr     string `yaml:"addr"`
-	Public   bool   `yaml:"public"`
-	Protocol string `yaml:"protocol,omitempty"`
 	AuthType string `yaml:"auth_type,omitempty"`
-	Static   bool   `yaml:"-"`
+	Domain   string `yaml:"domain,omitempty"`
 	Project  string `yaml:"project,omitempty"`
+	Protocol string `yaml:"protocol,omitempty"`
+	Public   bool   `yaml:"public"`
+	Static   bool   `yaml:"-"`
 }
 
 // ParseRemote splits remote and object
@@ -171,13 +179,58 @@ func (c *Config) GetImageServer(name string) (lxd.ImageServer, error) {
 func (c *Config) getConnectionArgs(name string) (*lxd.ConnectionArgs, error) {
 	remote, _ := c.Remotes[name]
 	args := lxd.ConnectionArgs{
-		UserAgent:      c.UserAgent,
-		AuthType:       remote.AuthType,
-		AuthInteractor: c.authInteractor,
+		UserAgent: c.UserAgent,
+		AuthType:  remote.AuthType,
 	}
 
-	if c.cookiejar != nil {
-		args.CookieJar = c.cookiejar
+	if args.AuthType == "candid" {
+		args.AuthInteractor = []httpbakery.Interactor{
+			form.Interactor{Filler: schemaform.IOFiller{}},
+			httpbakery.WebBrowserInteractor{
+				OpenWebBrowser: func(uri *url.URL) error {
+					if remote.Domain != "" {
+						query := uri.Query()
+						query.Set("domain", remote.Domain)
+						uri.RawQuery = query.Encode()
+					}
+
+					return httpbakery.OpenWebBrowser(uri)
+				},
+			},
+		}
+
+		if c.cookieJars == nil || c.cookieJars[name] == nil {
+			if !shared.PathExists(c.ConfigPath("jars")) {
+				err := os.MkdirAll(c.ConfigPath("jars"), 0700)
+				if err != nil {
+					return nil, err
+				}
+			}
+
+			if !shared.PathExists(c.CookiesPath(name)) {
+				if shared.PathExists(c.ConfigPath("cookies")) {
+					err := shared.FileCopy(c.ConfigPath("cookies"), c.CookiesPath(name))
+					if err != nil {
+						return nil, err
+					}
+				}
+			}
+
+			jar, err := cookiejar.New(
+				&cookiejar.Options{
+					Filename: c.CookiesPath(name),
+				})
+			if err != nil {
+				return nil, err
+			}
+
+			if c.cookieJars == nil {
+				c.cookieJars = map[string]*cookiejar.Jar{}
+			}
+			c.cookieJars[name] = jar
+		}
+
+		args.CookieJar = c.cookieJars[name]
 	}
 
 	// Stop here if no TLS involved

From a5b2c5c43be29bca3556b4a30b00589c0cd28b99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 15 Feb 2019 22:20:40 -0500
Subject: [PATCH 2/2] lxc: Update for per-remote candid domain/cookies
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxc/main.go   | 13 -------------
 lxc/remote.go | 24 +++---------------------
 2 files changed, 3 insertions(+), 34 deletions(-)

diff --git a/lxc/main.go b/lxc/main.go
index c42ee186be..144bca8775 100644
--- a/lxc/main.go
+++ b/lxc/main.go
@@ -8,8 +8,6 @@ import (
 	"path/filepath"
 
 	"github.com/spf13/cobra"
-	"gopkg.in/macaroon-bakery.v2/httpbakery"
-	"gopkg.in/macaroon-bakery.v2/httpbakery/form"
 
 	"github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxc/config"
@@ -19,8 +17,6 @@ import (
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/logging"
 	"github.com/lxc/lxd/shared/version"
-
-	schemaform "gopkg.in/juju/environschema.v1/form"
 )
 
 type cmdGlobal struct {
@@ -320,15 +316,6 @@ func (c *cmdGlobal) PreRun(cmd *cobra.Command, args []string) error {
 		fmt.Fprintf(os.Stderr, i18n.G("To start your first container, try: lxc launch ubuntu:18.04")+"\n\n")
 	}
 
-	// Only setup macaroons if a config path exists (so the jar can be saved)
-	if shared.PathExists(c.confPath) {
-		// Add interactor for external authentication
-		c.conf.SetAuthInteractor([]httpbakery.Interactor{
-			form.Interactor{Filler: schemaform.IOFiller{}},
-			httpbakery.WebBrowserInteractor{},
-		})
-	}
-
 	// Set the user agent
 	c.conf.UserAgent = version.UserAgent
 
diff --git a/lxc/remote.go b/lxc/remote.go
index d359a38728..ebaa3d2007 100644
--- a/lxc/remote.go
+++ b/lxc/remote.go
@@ -16,9 +16,6 @@ import (
 	"github.com/olekukonko/tablewriter"
 	"github.com/spf13/cobra"
 	"golang.org/x/crypto/ssh/terminal"
-	schemaform "gopkg.in/juju/environschema.v1/form"
-	"gopkg.in/macaroon-bakery.v2/httpbakery"
-	"gopkg.in/macaroon-bakery.v2/httpbakery/form"
 	"gopkg.in/yaml.v2"
 
 	"github.com/lxc/lxd/client"
@@ -223,22 +220,7 @@ func (c *cmdRemoteAdd) Run(cmd *cobra.Command, args []string) error {
 			}
 		}
 	}
-	conf.Remotes[server] = config.Remote{Addr: addr, Protocol: c.flagProtocol, AuthType: c.flagAuthType}
-
-	conf.SetAuthInteractor([]httpbakery.Interactor{
-		form.Interactor{Filler: schemaform.IOFiller{}},
-		httpbakery.WebBrowserInteractor{
-			OpenWebBrowser: func(uri *url.URL) error {
-				if c.flagDomain != "" {
-					query := uri.Query()
-					query.Set("domain", c.flagDomain)
-					uri.RawQuery = query.Encode()
-				}
-
-				return httpbakery.OpenWebBrowser(uri)
-			},
-		},
-	})
+	conf.Remotes[server] = config.Remote{Addr: addr, Protocol: c.flagProtocol, AuthType: c.flagAuthType, Domain: c.flagDomain}
 
 	// Attempt to connect
 	var d lxd.ImageServer
@@ -636,8 +618,8 @@ func (c *cmdRemoteRemove) Run(cmd *cobra.Command, args []string) error {
 
 	delete(conf.Remotes, args[0])
 
-	certf := conf.ServerCertPath(args[0])
-	os.Remove(certf)
+	os.Remove(conf.ServerCertPath(args[0]))
+	os.Remove(conf.CookiesPath(args[0]))
 
 	return conf.SaveConfig(c.global.confPath)
 }


More information about the lxc-devel mailing list