Exemple #1
0
func getConfig(address, cert, key, caCert string) (*vaultapi.Config, error) {
	conf := vaultapi.DefaultConfig()
	conf.Address = address

	tlsConfig := &tls.Config{}
	if cert != "" && key != "" {
		clientCert, err := tls.LoadX509KeyPair(cert, key)
		if err != nil {
			return nil, err
		}
		tlsConfig.Certificates = []tls.Certificate{clientCert}
		tlsConfig.BuildNameToCertificate()
	}

	if caCert != "" {
		ca, err := ioutil.ReadFile(caCert)
		if err != nil {
			return nil, err
		}
		caCertPool := x509.NewCertPool()
		caCertPool.AppendCertsFromPEM(ca)
		tlsConfig.RootCAs = caCertPool
	}

	conf.HttpClient.Transport = &http.Transport{
		TLSClientConfig: tlsConfig,
	}

	return conf, nil
}
Exemple #2
0
func (d *driver) mountServer(mountpoint string) (*fuse.Server, error) {
	if err := os.MkdirAll(filepath.Dir(mountpoint), 0755); err != nil {
		return nil, err
	}

	conf := api.DefaultConfig()
	client, err := api.NewClient(conf)
	if err != nil {
		return nil, err
	}

	ownership := keywhizfs.NewOwnership("root", "root")
	kwfs, root := NewFs(client, ownership)

	mountOptions := &fuse.MountOptions{
		AllowOther: true,
		Name:       kwfs.String(),
		Options:    []string{"default_permissions"},
	}

	// Empty Options struct avoids setting a global uid/gid override.
	conn := nodefs.NewFileSystemConnector(root, &nodefs.Options{})
	server, err := fuse.NewServer(conn.RawFS(), mountpoint, mountOptions)
	if err != nil {
		log.Printf("Mount fail: %v\n", err)
		return nil, err
	}

	go server.Serve()

	return server, nil
}
Exemple #3
0
func remove(keyname string) error {

	TOKEN = vLogin("", "", "ldap")
	if TOKEN == "" {
		return fmt.Errorf("%s", "User Login failed")
	}

	// Get element list
	EPATH := fmt.Sprint("secret/usr/", ADNAME)
	ELIST := getVaultValue(EPATH, TOKEN)

	//Split the list into an array
	EARRAY := strings.Split(ELIST.Data[LISTNAME].(string), ",")
	TNUM := -1
	// Search the array for the keyname value
	for lup, v := range EARRAY {
		if v == keyname {
			TNUM = lup
			break
		}
	}
	// If value isn't found, report it
	if TNUM == -1 {
		fmt.Println("Key name was not found in the list")
		return &errorString{"KeyError"}
	}

	// Delete the keyname
	config := tls.Config{InsecureSkipVerify: true}
	cnfg := vault.DefaultConfig()
	cnfg.Address = VAULTSERVER
	cnfg.HttpClient.Transport = &http.Transport{
		TLSClientConfig: &config,
	}
	client, err := vault.NewClient(cnfg)
	if err != nil {
		return err
	}
	client.SetToken(TOKEN)
	SPATH := fmt.Sprint("secret/usr/", ADNAME, "/", keyname)
	_, err = client.Logical().Delete(SPATH)
	if err != nil {
		return err
	}

	//Remove the key from the key list
	var s map[string]interface{}
	if TNUM == -1 || TNUM == 0 {
		s = map[string]interface{}{LISTNAME: ""}
	} else if TNUM > 0 {
		elst1 := strings.Join(EARRAY[:TNUM], ",")
		elst2 := strings.Join(EARRAY[TNUM+1:], ",")
		elst := strings.Join([]string{elst1, elst2}, ",")
		s = map[string]interface{}{LISTNAME: elst}
	}
	// And write it to the Vault
	err = putVaultValue(EPATH, TOKEN, s)
	return err
}
Exemple #4
0
func TestHTTP_Fallback_Disabled(t *testing.T) {
	handler1 := http.NewServeMux()
	handler2 := http.NewServeMux()
	handler3 := http.NewServeMux()

	coreConfig := &vault.CoreConfig{
		LogicalBackends: map[string]logical.Factory{
			"transit": transit.Factory,
		},
		ClusterAddr: "empty",
	}

	// Chicken-and-egg: Handler needs a core. So we create handlers first, then
	// add routes chained to a Handler-created handler.
	cores := vault.TestCluster(t, []http.Handler{handler1, handler2, handler3}, coreConfig, true)
	for _, core := range cores {
		defer core.CloseListeners()
	}
	handler1.Handle("/", Handler(cores[0].Core))
	handler2.Handle("/", Handler(cores[1].Core))
	handler3.Handle("/", Handler(cores[2].Core))

	// make it easy to get access to the active
	core := cores[0].Core
	vault.TestWaitActive(t, core)

	root := cores[0].Root

	addrs := []string{
		fmt.Sprintf("https://127.0.0.1:%d", cores[1].Listeners[0].Address.Port),
		fmt.Sprintf("https://127.0.0.1:%d", cores[2].Listeners[0].Address.Port),
	}

	for _, addr := range addrs {
		config := api.DefaultConfig()
		config.Address = addr
		config.HttpClient = cleanhttp.DefaultClient()
		config.HttpClient.Transport.(*http.Transport).TLSClientConfig = cores[0].TLSConfig
		client, err := api.NewClient(config)
		if err != nil {
			t.Fatal(err)
		}
		client.SetToken(root)

		secret, err := client.Auth().Token().LookupSelf()
		if err != nil {
			t.Fatal(err)
		}
		if secret == nil {
			t.Fatal("secret is nil")
		}
		if secret.Data["id"].(string) != root {
			t.Fatal("token mismatch")
		}
	}
}
Exemple #5
0
// newVaultClient creates a new client for connecting to vault.
func newVaultClient(config *Config) (*vaultapi.Client, error) {
	log.Printf("[INFO] (runner) creating vault/api client")

	vaultConfig := vaultapi.DefaultConfig()

	if config.Vault.Address != "" {
		log.Printf("[DEBUG] (runner) setting vault address to %s", config.Vault.Address)
		vaultConfig.Address = config.Vault.Address
	}

	if config.Vault.SSL.Enabled {
		log.Printf("[DEBUG] (runner) enabling vault SSL")
		tlsConfig := &tls.Config{}

		if config.Vault.SSL.Cert != "" {
			cert, err := tls.LoadX509KeyPair(config.Vault.SSL.Cert, config.Vault.SSL.Cert)
			if err != nil {
				return nil, err
			}
			tlsConfig.Certificates = []tls.Certificate{cert}
		}

		if config.Vault.SSL.CaCert != "" {
			cacert, err := ioutil.ReadFile(config.Vault.SSL.CaCert)
			if err != nil {
				return nil, err
			}
			caCertPool := x509.NewCertPool()
			caCertPool.AppendCertsFromPEM(cacert)

			tlsConfig.RootCAs = caCertPool
		}
		tlsConfig.BuildNameToCertificate()

		if !config.Vault.SSL.Verify {
			log.Printf("[WARN] (runner) disabling vault SSL verification")
			tlsConfig.InsecureSkipVerify = true
		}

		vaultConfig.HttpClient.Transport = &http.Transport{
			TLSClientConfig: tlsConfig,
		}
	}

	client, err := vaultapi.NewClient(vaultConfig)
	if err != nil {
		return nil, err
	}

	if config.Vault.Token != "" {
		log.Printf("[DEBUG] (runner) setting vault token")
		client.SetToken(config.Vault.Token)
	}

	return client, nil
}
Exemple #6
0
func testClient(t *testing.T, addr string, token string) *api.Client {
	config := api.DefaultConfig()
	config.Address = addr
	client, err := api.NewClient(config)
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	client.SetToken(token)

	return client
}
Exemple #7
0
func (vb *vaultBackend) vaultAuthenticate(vaultURI string, token string) error {
	vb.config = api.DefaultConfig()
	vb.config.Address = vaultURI
	client, err := api.NewClient(vb.config) //can probably be global
	if err != nil {
		glog.Errorf("Error authenticating %s\n", err.Error())
		return err
	}
	client.SetToken(token) //TODO put here the howler token to be read from file
	vb.client = client
	return nil
}
Exemple #8
0
func initVault() {
	// set up vault client
	var client *vault.Client
	if viper.GetString("vault-cubbyhole-token") != "" || viper.GetString("vault-token") != "" {
		config := vault.DefaultConfig()
		err := config.ReadEnvironment()
		if err != nil {
			log.WithError(err).Fatal("Error reading environment for Vault configuration")
		}
		client, err = vault.NewClient(config)
		if err != nil {
			log.WithError(err).Fatal("Error initializing Vault client")
		}
	}

	// unwrap real token
	if wrapped := viper.GetString("vault-cubbyhole-token"); wrapped != "" {
		token, err := client.Logical().Unwrap(wrapped)
		if err != nil {
			log.WithError(err).Fatal("Error unwrapping token")
		} else if token.WrapInfo != nil {
			log.Fatal("Secret appears to be doubly wrapped")
		} else if token.Auth == nil {
			log.Fatal("Secret contained no auth data")
		}

		viper.Set("vault-token", token.Auth.ClientToken)
	}

	// read secrets from vault
	if token := viper.GetString("vault-token"); token != "" {
		client.SetToken(token)

		secret, err := client.Logical().Read("secret/mantl-api")
		if err != nil {
			log.WithError(err).Fatal("Error reading secret/mantl-api")
		}

		for _, secretName := range []string{
			"mesos-principal", "mesos-secret",
			"marathon-user", "marathon-password",
		} {
			secretValue, ok := secret.Data[secretName].(string)
			if ok {
				viper.Set(secretName, secretValue)
			} else {
				log.Warnf("secret/mantl-api didn't contain %s", secretName)
			}
		}
	}
}
Exemple #9
0
func (s *VaultService) newConfig() (*api.Config, error) {
	// Create a vault client
	config := api.DefaultConfig()
	if err := config.ReadEnvironment(); err != nil {
		return nil, maskAny(err)
	}
	if s.address != "" {
		config.Address = s.address
	}
	if s.certPool != nil {
		clientTLSConfig := config.HttpClient.Transport.(*http.Transport).TLSClientConfig
		clientTLSConfig.RootCAs = s.certPool
		clientTLSConfig.ServerName = s.serverName
	}
	return config, nil
}
Exemple #10
0
// ApiConfig() returns a usable Vault config that can be passed directly to
// hashicorp/vault/api.
func (c *VaultConfig) ApiConfig() (*vault.Config, error) {
	conf := vault.DefaultConfig()
	tlsConf := &vault.TLSConfig{
		CACert:        c.TLSCaFile,
		CAPath:        c.TLSCaPath,
		ClientCert:    c.TLSCertFile,
		ClientKey:     c.TLSKeyFile,
		TLSServerName: c.TLSServerName,
		Insecure:      c.TLSSkipVerify,
	}
	if err := conf.ConfigureTLS(tlsConf); err != nil {
		return nil, err
	}

	conf.Address = c.Addr
	return conf, nil
}
Exemple #11
0
func (s *VaultSource) client() (*api.Client, error) {
	conf := api.DefaultConfig()
	if err := conf.ReadEnvironment(); err != nil {
		return nil, err
	}
	if s.Addr != "" {
		conf.Address = s.Addr
	}
	c, err := api.NewClient(conf)
	if err != nil {
		return nil, err
	}
	if err := s.setToken(c); err != nil {
		return nil, err
	}
	return c, nil
}
func NewVaultClient(vaultEndpoint string, token string) (interfaces.VaultClient, error) {
	cfg := api.DefaultConfig()
	cfg.ReadEnvironment()
	cfg.Address = vaultEndpoint

	vault, err := api.NewClient(cfg)
	if err != nil {
		return nil, err
	}

	vault.SetToken(token)

	return &VaultClient{
		vaultClient: vault,
		config:      cfg,
	}, nil
}
Exemple #13
0
func main() {
	config := api.DefaultConfig()
	client, err := api.NewClient(config)
	if err != nil {
		log.Fatal("err: %s", err)
	}

	if token := client.Token(); token != "" {
		log.Printf("using token client %s", token)
	} else {
		log.Fatal("no VAULT_TOKEN supplied!")
	}

	path := `secret/hello`
	_, err = client.Logical().Write(path, map[string]interface{}{"audience": "world"})
	if err != nil {
		log.Fatal("error writing %s: %s", path, err)
	} else {
		log.Printf("wrote %s successfully", path)
	}

	secret, err := client.Logical().Read(path)
	if err != nil {
		log.Fatal("error reading %s: %s", path, err)
	} else {
		data, err := json.Marshal(secret.Data)
		if err != nil {
			log.Fatal("error decoding %s: %s", path, err)
		} else {
			log.Printf("read %s as: %s", path, data)
		}
	}

	_, err = client.Logical().Delete(path)
	if err != nil {
		log.Fatal("error deleting %s: %s", path, err)
	} else {
		secret, _ := client.Logical().Read(path)
		if secret != nil {
			log.Fatal("error deleting %s: still readable after delete", path)
		} else {
			log.Printf("deleted %s successfully", path)
		}
	}
}
Exemple #14
0
// NewVaultClient creates a new vault client
func NewVaultClient(vaultURL, caFile string, skipTLSVerify bool) (VaultService, error) {
	var err error

	config := api.DefaultConfig()
	config.Address = vaultURL
	config.HttpClient.Transport, err = buildTransport(skipTLSVerify, caFile)
	if err != nil {
		return nil, err
	}

	client, err := api.NewClient(config)
	if err != nil {
		return nil, err
	}

	return &vault{
		client: client,
	}, nil
}
Exemple #15
0
func putVaultValue(keypath, tokenstr string, s map[string]interface{}) error {

	config := tls.Config{InsecureSkipVerify: true}
	cnfg := vault.DefaultConfig()
	cnfg.Address = VAULTSERVER
	cnfg.HttpClient.Transport = &http.Transport{
		TLSClientConfig: &config,
	}
	client, err := vault.NewClient(cnfg)
	if err != nil {
		panic(err.Error())
	}
	client.SetToken(tokenstr)
	SPATH := keypath
	_, err = client.Logical().Write(SPATH, s)

	return err

}
Exemple #16
0
func NewVault(srvCfg VaultConfig, log *logging.Logger) (*Vault, error) {
	// Create a vault client
	config := api.DefaultConfig()
	if err := config.ReadEnvironment(); err != nil {
		return nil, maskAny(err)
	}
	var serverName string
	if srvCfg.VaultAddr != "" {
		log.Debugf("Setting vault address to %s", srvCfg.VaultAddr)
		config.Address = srvCfg.VaultAddr
		url, err := url.Parse(config.Address)
		if err != nil {
			return nil, maskAny(err)
		}
		host, _, err := net.SplitHostPort(url.Host)
		if err != nil {
			return nil, maskAny(err)
		}
		serverName = host
	}
	if srvCfg.VaultCACert != "" || srvCfg.VaultCAPath != "" {
		clientTLSConfig := config.HttpClient.Transport.(*http.Transport).TLSClientConfig
		if err := rootcerts.ConfigureTLS(clientTLSConfig, &rootcerts.Config{
			CAFile: srvCfg.VaultCACert,
			CAPath: srvCfg.VaultCAPath,
		}); err != nil {
			return nil, maskAny(err)
		}
		clientTLSConfig.ServerName = serverName
	}
	client, err := api.NewClient(config)
	if err != nil {
		return nil, maskAny(err)
	}

	return &Vault{
		log:         log,
		vaultClient: client,
	}, nil

}
Exemple #17
0
func (vaultSource *VaultSource) Get() (map[string]interface{}, error) {
	config := api.DefaultConfig()
	config.Address = vaultSource.Address

	client, err := api.NewClient(config)

	if err != nil {
		return nil, err
	}

	client.SetToken(vaultSource.Token)

	secret, err := client.Logical().Read(vaultSource.Path)

	if err != nil {
		return nil, err
	}

	return secret.Data, nil

}
Exemple #18
0
func getVaultValue(keypath, tokenstr string) *vault.Secret {

	config := tls.Config{InsecureSkipVerify: true}
	cnfg := vault.DefaultConfig()
	cnfg.Address = VAULTSERVER
	cnfg.HttpClient.Transport = &http.Transport{
		TLSClientConfig: &config,
	}
	client, err := vault.NewClient(cnfg)
	if err != nil {
		panic(err.Error())
	}
	client.SetToken(tokenstr)
	SPATH := keypath
	response, err := client.Logical().Read(SPATH)
	if err != nil {
		fmt.Println("Error Reading Path")
	}
	return response

}
// testVaultServer is a helper for creating a Vault server and returning the
// appropriate client to connect to it.
func testVaultServer(t *testing.T) (*ClientSet, *vaultServer) {
	core, _, token := vault.TestCoreUnsealed(t)
	ln, addr := http.TestServer(t, core)

	config := vaultapi.DefaultConfig()
	config.Address = addr
	client, err := vaultapi.NewClient(config)
	if err != nil {
		defer ln.Close()
		t.Fatal(err)
	}

	client.SetToken(token)

	clients := NewClientSet()
	if err := clients.Add(client); err != nil {
		defer ln.Close()
		t.Fatal(err)
	}

	return clients, &vaultServer{Token: token, core: core, ln: ln}
}
Exemple #20
0
// newVaultClient creates and authenticates a vault client
func newVaultClient(opts *config) (*api.Client, error) {
	var err error
	var token string

	config := api.DefaultConfig()
	config.Address = opts.vaultURL

	config.HttpClient.Transport, err = buildHTTPTransport(opts)
	if err != nil {
		return nil, err
	}

	// step: create the actual client
	client, err := api.NewClient(config)
	if err != nil {
		return nil, err
	}

	plugin, _ := opts.vaultAuthOptions[VaultAuth]
	switch plugin {
	case "userpass":
		token, err = NewUserPassPlugin(client).Create(opts.vaultAuthOptions)
	case "approle":
		token, err = NewAppRolePlugin(client).Create(opts.vaultAuthOptions)
	case "token":
		opts.vaultAuthOptions["filename"] = options.vaultAuthFile
		token, err = NewUserTokenPlugin(client).Create(opts.vaultAuthOptions)
	default:
		return nil, fmt.Errorf("unsupported authentication plugin: %s", plugin)
	}
	if err != nil {
		return nil, err
	}

	// step: set the token for the client
	client.SetToken(token)

	return client, nil
}
func NewVault(addr string, config *store.Config) (store.SecretStore, error) {
	defaultCfg := api.DefaultConfig()
	defaultCfg.Address = addr

	if addr == "" {
		return nil, ErrAddressNotSpecified
	}

	c, err := api.NewClient(defaultCfg)
	if err != nil {
		return nil, err
	}

	if t, ok := config.StoreOpts["token"]; ok {
		log.Debugf("using token: %s", t)
		c.SetToken(t.(string))
	}

	return &Vault{
		client: c,
	}, nil
}
Exemple #22
0
// NewTestVault returns a new TestVault instance that has yet to be started
func NewTestVault(t *testing.T) *TestVault {
	port := getPort()
	token := structs.GenerateUUID()
	bind := fmt.Sprintf("-dev-listen-address=127.0.0.1:%d", port)
	http := fmt.Sprintf("http://127.0.0.1:%d", port)
	root := fmt.Sprintf("-dev-root-token-id=%s", token)

	cmd := exec.Command("vault", "server", "-dev", bind, root)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// Build the config
	conf := vapi.DefaultConfig()
	conf.Address = http

	// Make the client and set the token to the root token
	client, err := vapi.NewClient(conf)
	if err != nil {
		t.Fatalf("failed to build Vault API client: %v", err)
	}
	client.SetToken(token)

	tv := &TestVault{
		cmd:       cmd,
		t:         t,
		Addr:      bind,
		HTTPAddr:  http,
		RootToken: token,
		Client:    client,
		Config: &config.VaultConfig{
			Enabled: true,
			Token:   token,
			Addr:    http,
		},
	}

	return tv
}
Exemple #23
0
func ConfigFromVault(addr, token string) (Config, error) {
	var c Config
	vfg := vault.DefaultConfig()
	vfg.Address = addr

	vc, err := vault.NewClient(vfg)
	if err != nil {
		return c, err
	}
	vc.SetToken(token)

	return walk(configKeys, func(key string) (string, error) {
		key = fmt.Sprintf("secret/%s", key)
		secret, err := vc.Logical().Read(key)
		if err != nil {
			return "", err
		}
		if secret != nil {
			return secret.Data["value"].(string), nil
		}
		return "", nil
	})
}
Exemple #24
0
func TestRun_vaultPrecedenceOverConsul(t *testing.T) {
	t.Parallel()

	consul := testutil.NewTestServerConfig(t, func(c *testutil.TestServerConfig) {
		c.Stdout = ioutil.Discard
		c.Stderr = ioutil.Discard
	})
	defer consul.Stop()

	consul.SetKV("secret/foo/secret_foo_zip", []byte("baz"))

	vaultCore, _, token := vault.TestCoreUnsealed(t)
	ln, vaultAddr := http.TestServer(t, vaultCore)
	defer ln.Close()

	req := &logical.Request{
		Operation: logical.WriteOperation,
		Path:      "secret/foo",
		Data: map[string]interface{}{
			"zip":  "zap",
			"ding": "dong",
		},
		ClientToken: token,
	}
	if _, err := vaultCore.HandleRequest(req); err != nil {
		t.Fatal(err)
	}

	vaultconfig := vaultapi.DefaultConfig()
	vaultconfig.Address = vaultAddr
	client, err := vaultapi.NewClient(vaultconfig)
	if err != nil {
		t.Fatal(err)
	}
	client.SetToken(token)

	// Create a new token - the core token is a root token and is therefore
	// not renewable
	secret, err := client.Auth().Token().Create(&vaultapi.TokenCreateRequest{
		Lease: "1h",
	})
	if err != nil {
		t.Fatal(err)
	}

	config := testConfig(fmt.Sprintf(`
		consul = "%s"

		vault {
			address = "%s"
			token   = "%s"
			ssl {
				enabled = false
			}
		}

		secret {
			path = "secret/foo"
		}

		prefix {
			path = "secret/foo"
		}
	`, consul.HTTPAddr, vaultAddr, secret.Auth.ClientToken), t)

	runner, err := NewRunner(config, []string{"env"}, true)
	if err != nil {
		t.Fatal(err)
	}

	outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
	runner.outStream, runner.errStream = outStream, errStream

	go runner.Start()
	defer runner.Stop()

	select {
	case err := <-runner.ErrCh:
		t.Fatal(err)
	case <-runner.ExitCh:
	case <-time.After(250 * time.Millisecond):
	}

	expected := "secret_foo_zip=zap"
	if !strings.Contains(outStream.String(), expected) {
		t.Errorf("expected %q to include %q", outStream.String(), expected)
	}

	expected = "secret_foo_ding=dong"
	if !strings.Contains(outStream.String(), expected) {
		t.Errorf("expected %q to include %q", outStream.String(), expected)
	}
}
Exemple #25
0
// Client returns the API client to a Vault server given the configured
// flag settings for this command.
func (m *Meta) Client() (*api.Client, error) {
	config := api.DefaultConfig()

	err := config.ReadEnvironment()
	if err != nil {
		return nil, errwrap.Wrapf("error reading environment: {{err}}", err)
	}

	if m.flagAddress != "" {
		config.Address = m.flagAddress
	}
	if m.ForceAddress != "" {
		config.Address = m.ForceAddress
	}
	// If we need custom TLS configuration, then set it
	if m.flagCACert != "" || m.flagCAPath != "" || m.flagClientCert != "" || m.flagClientKey != "" || m.flagInsecure {
		// We may have set items from the environment so start with the
		// existing TLS config
		tlsConfig := config.HttpClient.Transport.(*http.Transport).TLSClientConfig

		var certPool *x509.CertPool
		var err error
		if m.flagCACert != "" {
			certPool, err = api.LoadCACert(m.flagCACert)
		} else if m.flagCAPath != "" {
			certPool, err = api.LoadCAPath(m.flagCAPath)
		}
		if err != nil {
			return nil, errwrap.Wrapf("Error setting up CA path: {{err}}", err)
		}

		if certPool != nil {
			tlsConfig.RootCAs = certPool
		}
		if m.flagInsecure {
			tlsConfig.InsecureSkipVerify = true
		}

		if m.flagClientCert != "" && m.flagClientKey != "" {
			tlsCert, err := tls.LoadX509KeyPair(m.flagClientCert, m.flagClientKey)
			if err != nil {
				return nil, err
			}
			tlsConfig.Certificates = []tls.Certificate{tlsCert}
		} else if m.flagClientCert != "" || m.flagClientKey != "" {
			return nil, fmt.Errorf("Both client cert and client key must be provided")
		}
	}

	// Build the client
	client, err := api.NewClient(config)
	if err != nil {
		return nil, err
	}

	// If we have a token directly, then set that
	token := m.ClientToken

	// Try to set the token to what is already stored
	if token == "" {
		token = client.Token()
	}

	// If we don't have a token, check the token helper
	if token == "" {
		if m.TokenHelper != nil {
			// If we have a token, then set that
			tokenHelper, err := m.TokenHelper()
			if err != nil {
				return nil, err
			}
			token, err = tokenHelper.Get()
			if err != nil {
				return nil, err
			}
		}
	}

	// Set the token
	if token != "" {
		client.SetToken(token)
	}

	return client, nil
}
Exemple #26
0
// This tests TLS connection state forwarding by ensuring that we can use a
// client TLS to authenticate against the cert backend
func TestHTTP_Forwarding_ClientTLS(t *testing.T) {
	handler1 := http.NewServeMux()
	handler2 := http.NewServeMux()
	handler3 := http.NewServeMux()

	coreConfig := &vault.CoreConfig{
		CredentialBackends: map[string]logical.Factory{
			"cert": credCert.Factory,
		},
	}

	// Chicken-and-egg: Handler needs a core. So we create handlers first, then
	// add routes chained to a Handler-created handler.
	cores := vault.TestCluster(t, []http.Handler{handler1, handler2, handler3}, coreConfig, true)
	for _, core := range cores {
		defer core.CloseListeners()
	}
	handler1.Handle("/", Handler(cores[0].Core))
	handler2.Handle("/", Handler(cores[1].Core))
	handler3.Handle("/", Handler(cores[2].Core))

	// make it easy to get access to the active
	core := cores[0].Core
	vault.TestWaitActive(t, core)

	root := cores[0].Root

	transport := cleanhttp.DefaultTransport()
	transport.TLSClientConfig = cores[0].TLSConfig

	client := &http.Client{
		Transport: transport,
	}

	req, err := http.NewRequest("POST", fmt.Sprintf("https://127.0.0.1:%d/v1/sys/auth/cert", cores[0].Listeners[0].Address.Port),
		bytes.NewBuffer([]byte("{\"type\": \"cert\"}")))
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Set(AuthHeaderName, root)
	_, err = client.Do(req)
	if err != nil {
		t.Fatal(err)
	}

	type certConfig struct {
		Certificate string `json:"certificate"`
		Policies    string `json:"policies"`
	}
	encodedCertConfig, err := json.Marshal(&certConfig{
		Certificate: vault.TestClusterCACert,
		Policies:    "default",
	})
	if err != nil {
		t.Fatal(err)
	}
	req, err = http.NewRequest("POST", fmt.Sprintf("https://127.0.0.1:%d/v1/auth/cert/certs/test", cores[0].Listeners[0].Address.Port),
		bytes.NewBuffer(encodedCertConfig))
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Set(AuthHeaderName, root)
	_, err = client.Do(req)
	if err != nil {
		t.Fatal(err)
	}

	addrs := []string{
		fmt.Sprintf("https://127.0.0.1:%d", cores[1].Listeners[0].Address.Port),
		fmt.Sprintf("https://127.0.0.1:%d", cores[2].Listeners[0].Address.Port),
	}

	// Ensure we can't possibly use lingering connections even though it should be to a different address

	transport = cleanhttp.DefaultTransport()
	transport.TLSClientConfig = cores[0].TLSConfig

	client = &http.Client{
		Transport: transport,
		CheckRedirect: func(*http.Request, []*http.Request) error {
			return fmt.Errorf("redirects not allowed in this test")
		},
	}

	//cores[0].Logger().Printf("root token is %s", root)
	//time.Sleep(4 * time.Hour)

	for _, addr := range addrs {
		config := api.DefaultConfig()
		config.Address = addr
		config.HttpClient = client
		client, err := api.NewClient(config)
		if err != nil {
			t.Fatal(err)
		}

		secret, err := client.Logical().Write("auth/cert/login", nil)
		if err != nil {
			t.Fatal(err)
		}
		if secret == nil {
			t.Fatal("secret is nil")
		}
		if secret.Auth == nil {
			t.Fatal("auth is nil")
		}
		if secret.Auth.Policies == nil || len(secret.Auth.Policies) == 0 || secret.Auth.Policies[0] != "default" {
			t.Fatalf("bad policies: %#v", secret.Auth.Policies)
		}
	}
}
func (c *ClientSet) CreateVaultClient(i *CreateVaultClientInput) error {
	vaultConfig := vaultapi.DefaultConfig()

	if i.Address != "" {
		vaultConfig.Address = i.Address
	}

	// This transport will attempt to keep connections open to the Vault server.
	transport := cleanhttp.DefaultPooledTransport()

	// Configure SSL
	if i.SSLEnabled {
		var tlsConfig tls.Config

		// Custom certificate or certificate and key
		if i.SSLCert != "" && i.SSLKey != "" {
			cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLKey)
			if err != nil {
				return fmt.Errorf("client set: vault: %s", err)
			}
			tlsConfig.Certificates = []tls.Certificate{cert}
		} else if i.SSLCert != "" {
			cert, err := tls.LoadX509KeyPair(i.SSLCert, i.SSLCert)
			if err != nil {
				return fmt.Errorf("client set: vault: %s", err)
			}
			tlsConfig.Certificates = []tls.Certificate{cert}
		}

		// Custom CA certificate
		if i.SSLCACert != "" || i.SSLCAPath != "" {
			rootConfig := &rootcerts.Config{
				CAFile: i.SSLCACert,
				CAPath: i.SSLCAPath,
			}
			if err := rootcerts.ConfigureTLS(&tlsConfig, rootConfig); err != nil {
				return fmt.Errorf("client set: vault configuring TLS failed: %s", err)
			}
		}

		// Construct all the certificates now
		tlsConfig.BuildNameToCertificate()

		// SSL verification
		if i.ServerName != "" {
			tlsConfig.ServerName = i.ServerName
			tlsConfig.InsecureSkipVerify = false
		}
		if !i.SSLVerify {
			log.Printf("[WARN] (clients) disabling vault SSL verification")
			tlsConfig.InsecureSkipVerify = true
		}

		// Save the TLS config on our transport
		transport.TLSClientConfig = &tlsConfig
	}

	// Setup the new transport
	vaultConfig.HttpClient.Transport = transport

	// Create the client
	client, err := vaultapi.NewClient(vaultConfig)
	if err != nil {
		return fmt.Errorf("client set: vault: %s", err)
	}

	// Set the token if given
	if i.Token != "" {
		client.SetToken(i.Token)
	}

	// Check if we are unwrapping
	if i.UnwrapToken {
		secret, err := client.Logical().Unwrap(i.Token)
		if err != nil {
			return fmt.Errorf("client set: vault unwrap: %s", err)
		}

		if secret == nil {
			return fmt.Errorf("client set: vault unwrap: no secret")
		}

		if secret.Auth == nil {
			return fmt.Errorf("client set: vault unwrap: no secret auth")
		}

		if secret.Auth.ClientToken == "" {
			return fmt.Errorf("client set: vault unwrap: no token returned")
		}

		client.SetToken(secret.Auth.ClientToken)
	}

	// Save the data on ourselves
	c.Lock()
	c.vault = &vaultClient{
		client:     client,
		httpClient: vaultConfig.HttpClient,
	}
	c.Unlock()

	return nil
}
//RetrieveUser simple retrieve option for POC
//BUG(dejan) We need to add some context and potentiall a pool of clients
func (c *VaultClient) RetrieveUser(namespace, user string) (*VaultUser, *HTTPAuthError) {

	config := api.DefaultConfig()
	config.Address = c.Config.Proto + "://" + c.Config.Host + ":" + strconv.Itoa(c.Config.Port)
	client, err := api.NewClient(config)
	if err != nil {
		log.Printf("error creating client: %v", err)
		return nil, ErrInternal
	}
	client.SetToken(c.Config.AuthToken)
	url := "/v1/" + namespace + "/" + user
	req := client.NewRequest("GET", url)
	resp, err := client.RawRequest(req)
	if err != nil {
		//log.Printf("DEBUG error calling vault API - %v", err)
		if resp != nil {
			log.Printf("error while retrieving vault data: %s with code: %d", url, resp.StatusCode)
			// that means we don't have access to this resource
			// so we should log an error but response to client
			// that he has no access
			switch resp.StatusCode {
			case 403:
				// log.Print("DEBUG error vault token does not have enough permissions")
				return nil, ErrInternal
			case 404:
				return nil, ErrForbidden
			default:
				return nil, NewHTTPError(err.Error(), resp.StatusCode)
			}
		}
		log.Print(err)
		return nil, ErrInternal
	}

	// fmt.Printf("%v\n", resp)
	respData := struct {
		Data struct {
			Access   string `json:"access"`
			Password string `json:"password"`
		} `json:"data"`
	}{}

	dec := json.NewDecoder(resp.Body)
	err = dec.Decode(&respData)
	if err != nil {
		log.Printf("error parsing JSON response: %v", err)
		return nil, ErrInternal
	}

	accessMap := make(map[string]Priv)
	semiColonSplit := strings.Split(respData.Data.Access, ";")
	for _, x := range semiColonSplit {
		xx := strings.Split(x, ":")
		if len(xx) != 3 {
			log.Printf("expected length 3: %v", err)
			return nil, ErrInternal
		}
		accessMap[xx[1]] = NewPriv(xx[2])
	}

	return &VaultUser{
		Username: user,
		Password: respData.Data.Password,
		Access:   accessMap,
	}, nil
}
Exemple #29
0
// Test performs an acceptance test on a backend with the given test case.
//
// Tests are not run unless an environmental variable "TF_ACC" is
// set to some non-empty value. This is to avoid test cases surprising
// a user by creating real resources.
//
// Tests will fail unless the verbose flag (`go test -v`, or explicitly
// the "-test.v" flag) is set. Because some acceptance tests take quite
// long, we require the verbose flag so users are able to see progress
// output.
func Test(t TestT, c TestCase) {
	// We only run acceptance tests if an env var is set because they're
	// slow and generally require some outside configuration.
	if os.Getenv(TestEnvVar) == "" {
		t.Skip(fmt.Sprintf(
			"Acceptance tests skipped unless env '%s' set",
			TestEnvVar))
		return
	}

	// We require verbose mode so that the user knows what is going on.
	if !testTesting && !testing.Verbose() {
		t.Fatal("Acceptance tests must be run with the -v flag on tests")
		return
	}

	// Run the PreCheck if we have it
	if c.PreCheck != nil {
		c.PreCheck()
	}

	// Check that something is provided
	if c.Backend == nil && c.Factory == nil {
		t.Fatal("Must provide either Backend or Factory")
	}

	// Create an in-memory Vault core
	core, err := vault.NewCore(&vault.CoreConfig{
		Physical: physical.NewInmem(),
		LogicalBackends: map[string]logical.Factory{
			"test": func(conf *logical.BackendConfig) (logical.Backend, error) {
				if c.Backend != nil {
					return c.Backend, nil
				}
				return c.Factory(conf)
			},
		},
	})
	if err != nil {
		t.Fatal("error initializing core: ", err)
		return
	}

	// Initialize the core
	init, err := core.Initialize(&vault.SealConfig{
		SecretShares:    1,
		SecretThreshold: 1,
	})
	if err != nil {
		t.Fatal("error initializing core: ", err)
	}

	// Unseal the core
	if unsealed, err := core.Unseal(init.SecretShares[0]); err != nil {
		t.Fatal("error unsealing core: ", err)
		return
	} else if !unsealed {
		t.Fatal("vault shouldn't be sealed")
		return
	}

	// Create an HTTP API server and client
	ln, addr := http.TestServer(nil, core)
	defer ln.Close()
	clientConfig := api.DefaultConfig()
	clientConfig.Address = addr
	client, err := api.NewClient(clientConfig)
	if err != nil {
		t.Fatal("error initializing HTTP client: ", err)
		return
	}

	// Set the token so we're authenticated
	client.SetToken(init.RootToken)

	// Mount the backend
	prefix := "mnt"
	if err := client.Sys().Mount(prefix, "test", "acceptance test"); err != nil {
		t.Fatal("error mounting backend: ", err)
		return
	}

	// Make requests
	var revoke []*logical.Request
	for i, s := range c.Steps {
		log.Printf("[WARN] Executing test step %d", i+1)

		// Make sure to prefix the path with where we mounted the thing
		path := fmt.Sprintf("%s/%s", prefix, s.Path)

		// Create the request
		req := &logical.Request{
			Operation: s.Operation,
			Path:      path,
			Data:      s.Data,
		}
		if !s.Unauthenticated {
			req.ClientToken = client.Token()
		}
		if s.RemoteAddr != "" {
			req.Connection = &logical.Connection{RemoteAddr: s.RemoteAddr}
		}
		if s.ConnState != nil {
			req.Connection = &logical.Connection{ConnState: s.ConnState}
		}

		// Make the request
		resp, err := core.HandleRequest(req)
		if resp != nil && resp.Secret != nil {
			// Revoke this secret later
			revoke = append(revoke, &logical.Request{
				Operation: logical.WriteOperation,
				Path:      "sys/revoke/" + resp.Secret.LeaseID,
			})
		}
		if err == nil && resp.IsError() && !s.ErrorOk {
			err = fmt.Errorf("Erroneous response:\n\n%#v", resp)
		}
		if err == nil && s.Check != nil {
			// Call the test method
			err = s.Check(resp)
		}
		if err != nil {
			t.Error(fmt.Sprintf("Failed step %d: %s", i+1, err))
			break
		}
	}

	// Revoke any secrets we might have.
	var failedRevokes []*logical.Secret
	for _, req := range revoke {
		log.Printf("[WARN] Revoking secret: %#v", req)
		req.ClientToken = client.Token()
		resp, err := core.HandleRequest(req)
		if err == nil && resp.IsError() {
			err = fmt.Errorf("Erroneous response:\n\n%#v", resp)
		}
		if err != nil {
			failedRevokes = append(failedRevokes, req.Secret)
			t.Error(fmt.Sprintf("[ERR] Revoke error: %s", err))
		}
	}

	// Perform any rollbacks. This should no-op if there aren't any.
	// We set the "immediate" flag here that any backend can pick up on
	// to do all rollbacks immediately even if the WAL entries are new.
	log.Printf("[WARN] Requesting RollbackOperation")
	req := logical.RollbackRequest(prefix + "/")
	req.Data["immediate"] = true
	req.ClientToken = client.Token()
	resp, err := core.HandleRequest(req)
	if err == nil && resp.IsError() {
		err = fmt.Errorf("Erroneous response:\n\n%#v", resp)
	}
	if err != nil && err != logical.ErrUnsupportedOperation {
		t.Error(fmt.Sprintf("[ERR] Rollback error: %s", err))
	}

	// If we have any failed revokes, log it.
	if len(failedRevokes) > 0 {
		for _, s := range failedRevokes {
			t.Error(fmt.Sprintf(
				"WARNING: Revoking the following secret failed. It may\n"+
					"still exist. Please verify:\n\n%#v",
				s))
		}
	}

	// Cleanup
	if c.Teardown != nil {
		c.Teardown()
	}
}
Exemple #30
0
// Test performs an acceptance test on a backend with the given test case.
//
// Tests are not run unless an environmental variable "VAULT_ACC" is
// set to some non-empty value. This is to avoid test cases surprising
// a user by creating real resources.
//
// Tests will fail unless the verbose flag (`go test -v`, or explicitly
// the "-test.v" flag) is set. Because some acceptance tests take quite
// long, we require the verbose flag so users are able to see progress
// output.
func Test(tt TestT, c TestCase) {
	// We only run acceptance tests if an env var is set because they're
	// slow and generally require some outside configuration.
	if c.AcceptanceTest && os.Getenv(TestEnvVar) == "" {
		tt.Skip(fmt.Sprintf(
			"Acceptance tests skipped unless env '%s' set",
			TestEnvVar))
		return
	}

	// We require verbose mode so that the user knows what is going on.
	if c.AcceptanceTest && !testTesting && !testing.Verbose() {
		tt.Fatal("Acceptance tests must be run with the -v flag on tests")
		return
	}

	// Run the PreCheck if we have it
	if c.PreCheck != nil {
		c.PreCheck()
	}

	// Check that something is provided
	if c.Backend == nil && c.Factory == nil {
		tt.Fatal("Must provide either Backend or Factory")
		return
	}

	// Create an in-memory Vault core
	core, err := vault.NewCore(&vault.CoreConfig{
		Physical: physical.NewInmem(logger),
		LogicalBackends: map[string]logical.Factory{
			"test": func(conf *logical.BackendConfig) (logical.Backend, error) {
				if c.Backend != nil {
					return c.Backend, nil
				}
				return c.Factory(conf)
			},
		},
		DisableMlock: true,
	})
	if err != nil {
		tt.Fatal("error initializing core: ", err)
		return
	}

	// Initialize the core
	init, err := core.Initialize(&vault.SealConfig{
		SecretShares:    1,
		SecretThreshold: 1,
	}, nil)
	if err != nil {
		tt.Fatal("error initializing core: ", err)
		return
	}

	// Unseal the core
	if unsealed, err := core.Unseal(init.SecretShares[0]); err != nil {
		tt.Fatal("error unsealing core: ", err)
		return
	} else if !unsealed {
		tt.Fatal("vault shouldn't be sealed")
		return
	}

	// Create an HTTP API server and client
	ln, addr := http.TestServer(nil, core)
	defer ln.Close()
	clientConfig := api.DefaultConfig()
	clientConfig.Address = addr
	client, err := api.NewClient(clientConfig)
	if err != nil {
		tt.Fatal("error initializing HTTP client: ", err)
		return
	}

	// Set the token so we're authenticated
	client.SetToken(init.RootToken)

	// Mount the backend
	prefix := "mnt"
	mountInfo := &api.MountInput{
		Type:        "test",
		Description: "acceptance test",
	}
	if err := client.Sys().Mount(prefix, mountInfo); err != nil {
		tt.Fatal("error mounting backend: ", err)
		return
	}

	// Make requests
	var revoke []*logical.Request
	for i, s := range c.Steps {
		log.Printf("[WARN] Executing test step %d", i+1)

		// Create the request
		req := &logical.Request{
			Operation: s.Operation,
			Path:      s.Path,
			Data:      s.Data,
		}
		if !s.Unauthenticated {
			req.ClientToken = client.Token()
		}
		if s.RemoteAddr != "" {
			req.Connection = &logical.Connection{RemoteAddr: s.RemoteAddr}
		}
		if s.ConnState != nil {
			req.Connection = &logical.Connection{ConnState: s.ConnState}
		}

		if s.PreFlight != nil {
			ct := req.ClientToken
			req.ClientToken = ""
			if err := s.PreFlight(req); err != nil {
				tt.Error(fmt.Sprintf("Failed preflight for step %d: %s", i+1, err))
				break
			}
			req.ClientToken = ct
		}

		// Make sure to prefix the path with where we mounted the thing
		req.Path = fmt.Sprintf("%s/%s", prefix, req.Path)

		// Make the request
		resp, err := core.HandleRequest(req)
		if resp != nil && resp.Secret != nil {
			// Revoke this secret later
			revoke = append(revoke, &logical.Request{
				Operation: logical.UpdateOperation,
				Path:      "sys/revoke/" + resp.Secret.LeaseID,
			})
		}

		// Test step returned an error.
		if err != nil {
			// But if an error is expected, do not fail the test step,
			// regardless of whether the error is a 'logical.ErrorResponse'
			// or not. Set the err to nil. If the error is a logical.ErrorResponse,
			// it will be handled later.
			if s.ErrorOk {
				err = nil
			} else {
				// If the error is not expected, fail right away.
				tt.Error(fmt.Sprintf("Failed step %d: %s", i+1, err))
				break
			}
		}

		// If the error is a 'logical.ErrorResponse' and if error was not expected,
		// set the error so that this can be caught below.
		if resp.IsError() && !s.ErrorOk {
			err = fmt.Errorf("Erroneous response:\n\n%#v", resp)
		}

		// Either the 'err' was nil or if an error was expected, it was set to nil.
		// Call the 'Check' function if there is one.
		//
		// TODO: This works perfectly for now, but it would be better if 'Check'
		// function takes in both the response object and the error, and decide on
		// the action on its own.
		if err == nil && s.Check != nil {
			// Call the test method
			err = s.Check(resp)
		}

		if err != nil {
			tt.Error(fmt.Sprintf("Failed step %d: %s", i+1, err))
			break
		}
	}

	// Revoke any secrets we might have.
	var failedRevokes []*logical.Secret
	for _, req := range revoke {
		log.Printf("[WARN] Revoking secret: %#v", req)
		req.ClientToken = client.Token()
		resp, err := core.HandleRequest(req)
		if err == nil && resp.IsError() {
			err = fmt.Errorf("Erroneous response:\n\n%#v", resp)
		}
		if err != nil {
			failedRevokes = append(failedRevokes, req.Secret)
			tt.Error(fmt.Sprintf("[ERR] Revoke error: %s", err))
		}
	}

	// Perform any rollbacks. This should no-op if there aren't any.
	// We set the "immediate" flag here that any backend can pick up on
	// to do all rollbacks immediately even if the WAL entries are new.
	log.Printf("[WARN] Requesting RollbackOperation")
	req := logical.RollbackRequest(prefix + "/")
	req.Data["immediate"] = true
	req.ClientToken = client.Token()
	resp, err := core.HandleRequest(req)
	if err == nil && resp.IsError() {
		err = fmt.Errorf("Erroneous response:\n\n%#v", resp)
	}
	if err != nil {
		if !errwrap.Contains(err, logical.ErrUnsupportedOperation.Error()) {
			tt.Error(fmt.Sprintf("[ERR] Rollback error: %s", err))
		}
	}

	// If we have any failed revokes, log it.
	if len(failedRevokes) > 0 {
		for _, s := range failedRevokes {
			tt.Error(fmt.Sprintf(
				"WARNING: Revoking the following secret failed. It may\n"+
					"still exist. Please verify:\n\n%#v",
				s))
		}
	}

	// Cleanup
	if c.Teardown != nil {
		c.Teardown()
	}
}