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 }
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 }
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 }
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") } } }
// 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 }
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 }
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 }
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) } } } }
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 }
// 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 }
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 }
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) } } }
// 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 }
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 }
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 }
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 }
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} }
// 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 }
// 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 }
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 }) }
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) } }
// 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 }
// 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 }
// 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() } }
// 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() } }