From 4bc243261f23e4edc25826300a8f77d9705c70be Mon Sep 17 00:00:00 2001 From: Tomasz Pawelczak Date: Fri, 26 Jan 2018 16:14:40 +0100 Subject: [PATCH] Version 0.0.1 --- .gitignore | 2 + Gopkg.lock | 292 +++++++++++++++++++++++++++++++++++++++ Gopkg.toml | 29 ++++ authfile/backend.go | 57 ++++++++ authfile/backend_test.go | 104 ++++++++++++++ authfile/path_config.go | 113 +++++++++++++++ authfile/path_login.go | 192 +++++++++++++++++++++++++ authfile/version.go | 12 ++ main.go | 26 ++++ test/config.hcl | 1 + test/get_vault.sh | 6 + test/password-file | 5 + test/stderr.log | 45 ++++++ test/stdout.log | 33 +++++ test/tests.sh | 41 ++++++ 15 files changed, 958 insertions(+) create mode 100644 Gopkg.lock create mode 100644 Gopkg.toml create mode 100644 authfile/backend.go create mode 100644 authfile/backend_test.go create mode 100644 authfile/path_config.go create mode 100644 authfile/path_login.go create mode 100644 authfile/version.go create mode 100644 main.go create mode 100644 test/config.hcl create mode 100755 test/get_vault.sh create mode 100644 test/password-file create mode 100644 test/stderr.log create mode 100644 test/stdout.log create mode 100755 test/tests.sh diff --git a/.gitignore b/.gitignore index a1338d6..4d3cf0d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 .glide/ + +vendor/ diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..8369119 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,292 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/SermoDigital/jose" + packages = [ + ".", + "crypto", + "jws", + "jwt" + ] + revision = "f6df55f235c24f236d11dbcf665249a59ac2021f" + version = "1.1" + +[[projects]] + branch = "master" + name = "github.com/armon/go-radix" + packages = ["."] + revision = "1fca145dffbcaa8fe914309b1ec0cfc67500fe61" + +[[projects]] + name = "github.com/fatih/structs" + packages = ["."] + revision = "a720dfa8df582c51dee1b36feabb906bde1588bd" + version = "v1.0" + +[[projects]] + branch = "master" + name = "github.com/golang/protobuf" + packages = [ + "proto", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp" + ] + revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845" + +[[projects]] + branch = "master" + name = "github.com/golang/snappy" + packages = ["."] + revision = "553a641470496b2327abcac10b36396bd98e45c9" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/errwrap" + packages = ["."] + revision = "7554cd9344cec97297fa6649b055a8c98c2a1e55" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-cleanhttp" + packages = ["."] + revision = "d5fe4b57a186c716b0e00b8c301cbd9b4182694d" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-hclog" + packages = ["."] + revision = "ca137eb4b4389c9bc6f1a6d887f056bf16c00510" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-multierror" + packages = ["."] + revision = "b7773ae218740a7be65057fc60b366a49b538a44" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-plugin" + packages = ["."] + revision = "1fc09c47b843b73705f51ffb0520e3ac1bfecf99" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-rootcerts" + packages = ["."] + revision = "6bb64b370b90e7ef1fa532be9e591a81c3493e00" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-uuid" + packages = ["."] + revision = "64130c7a86d732268a38cb04cfbaf0cc987fda98" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/hcl" + packages = [ + ".", + "hcl/ast", + "hcl/parser", + "hcl/scanner", + "hcl/strconv", + "hcl/token", + "json/parser", + "json/scanner", + "json/token" + ] + revision = "23c074d0eceb2b8a5bfdbb271ab780cde70f05a8" + +[[projects]] + name = "github.com/hashicorp/vault" + packages = [ + "api", + "helper/certutil", + "helper/compressutil", + "helper/consts", + "helper/errutil", + "helper/jsonutil", + "helper/logformat", + "helper/mlock", + "helper/parseutil", + "helper/password", + "helper/pluginutil", + "helper/policyutil", + "helper/salt", + "helper/strutil", + "helper/wrapping", + "logical", + "logical/framework", + "logical/plugin" + ] + revision = "87b6919dea55da61d7cd444b2442cabb8ede8ab1" + version = "v0.9.1" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/yamux" + packages = ["."] + revision = "683f49123a33db61abfb241b7ac5e4af4dc54d55" + +[[projects]] + name = "github.com/mattn/go-colorable" + packages = ["."] + revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" + version = "v0.0.9" + +[[projects]] + name = "github.com/mattn/go-isatty" + packages = ["."] + revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" + version = "v0.0.3" + +[[projects]] + branch = "master" + name = "github.com/mgutz/ansi" + packages = ["."] + revision = "9520e82c474b0a04dd04f8a40959027271bab992" + +[[projects]] + name = "github.com/mgutz/logxi" + packages = ["v1"] + revision = "aebf8a7d67ab4625e0fd4a665766fef9a709161b" + version = "v1" + +[[projects]] + branch = "master" + name = "github.com/mitchellh/go-homedir" + packages = ["."] + revision = "b8bc1bf767474819792c23f32d8286a45736f1c6" + +[[projects]] + branch = "master" + name = "github.com/mitchellh/go-testing-interface" + packages = ["."] + revision = "a61a99592b77c9ba629d254a693acffaeb4b7e28" + +[[projects]] + branch = "master" + name = "github.com/mitchellh/mapstructure" + packages = ["."] + revision = "b4575eea38cca1123ec2dc90c26529b5c5acfcff" + +[[projects]] + name = "github.com/oklog/run" + packages = ["."] + revision = "4dadeb3030eda0273a12382bb2348ffc7c9d1a39" + version = "v1.0.0" + +[[projects]] + name = "github.com/pkg/errors" + packages = ["."] + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + name = "github.com/ryanuber/go-glob" + packages = ["."] + revision = "572520ed46dbddaed19ea3d9541bdd0494163693" + version = "v0.1" + +[[projects]] + branch = "master" + name = "github.com/sethgrid/pester" + packages = ["."] + revision = "760f8913c0483b776294e1bee43f1d687527127b" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = ["ssh/terminal"] + revision = "39efaea5da11abd5e2b90a435b1f338cdb94619c" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = [ + "context", + "http2", + "http2/hpack", + "idna", + "internal/timeseries", + "lex/httplex", + "trace" + ] + revision = "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = [ + "unix", + "windows" + ] + revision = "af50095a40f9041b3b38960738837185c26e9419" + +[[projects]] + branch = "master" + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "language", + "secure/bidirule", + "transform", + "unicode/bidi", + "unicode/cldr", + "unicode/norm", + "unicode/rangetable" + ] + revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3" + +[[projects]] + branch = "master" + name = "google.golang.org/genproto" + packages = ["googleapis/rpc/status"] + revision = "a8101f21cf983e773d0c1133ebc5424792003214" + +[[projects]] + name = "google.golang.org/grpc" + packages = [ + ".", + "balancer", + "balancer/base", + "balancer/roundrobin", + "codes", + "connectivity", + "credentials", + "encoding", + "grpclb/grpc_lb_v1/messages", + "grpclog", + "health", + "health/grpc_health_v1", + "internal", + "keepalive", + "metadata", + "naming", + "peer", + "resolver", + "resolver/dns", + "resolver/passthrough", + "stats", + "status", + "tap", + "transport" + ] + revision = "6b51017f791ae1cfbec89c52efdf444b13b550ef" + version = "v1.9.2" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "3effe701637a909054576651410d87ba352de7f03ead1adba90480f41c39d263" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..3e26abe --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,29 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + + +[[constraint]] + name = "github.com/fatih/structs" + version = "1.0.0" + +[[constraint]] + name = "github.com/hashicorp/vault" + version = "0.9.1" diff --git a/authfile/backend.go b/authfile/backend.go new file mode 100644 index 0000000..00827bd --- /dev/null +++ b/authfile/backend.go @@ -0,0 +1,57 @@ +package authfile + +import ( + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/logical/framework" + log "github.com/mgutz/logxi/v1" +) + +func Factory(conf *logical.BackendConfig) (logical.Backend, error) { + b := Backend(conf) + err := b.Setup(conf) + if err != nil { + return nil, err + } + return b, nil +} + +func Backend(conf *logical.BackendConfig) *backend { + var b backend + + b.logger = conf.Logger + if b.logger.IsInfo() { + b.logger.Info("vault-auth-file: starting...", "version", HumanVersion) + } + + + b.Backend = &framework.Backend{ + Help: backendHelp, + BackendType: logical.TypeCredential, + PathsSpecial: &logical.Paths{ + Unauthenticated: []string{ + "login", + }, + }, + + Paths: append([]*framework.Path{ + pathLogin(&b), + pathConfig(&b), + }), + + AuthRenew: b.pathLoginRenew, + } + return &b +} + +type backend struct { + *framework.Backend + logger log.Logger +} + +const backendHelp = ` +File authentication backend takes a username and password and verify +them against passwords like unix file. Passwords hash are in glibc compatible +SHA512 format (see man crypt). + +Policies are assigned also in password file, as coma separated list. +` diff --git a/authfile/backend_test.go b/authfile/backend_test.go new file mode 100644 index 0000000..9ae3e01 --- /dev/null +++ b/authfile/backend_test.go @@ -0,0 +1,104 @@ +package authfile + +import ( +/* "io/ioutil" + "math/rand" + "net/http" + "net/url" + "os" + + "fmt" + + "bytes" + "encoding/json" + + "crypto/rsa" +*/ +// "github.com/hashicorp/vault/helper/policyutil" +// "time" + "testing" + "github.com/hashicorp/vault/logical" + //logicaltest "github.com/hashicorp/vault/logical/testing" +) + +func TestBackend_Config(t *testing.T) { + cfg := logical.TestBackendConfig() + storage := &logical.InmemStorage{} + cfg.StorageView = storage + + b := Backend(cfg) + err := b.Setup(cfg) + if err != nil { + t.Fatal(err) + } + + // Valid Case + data := map[string]interface{}{ + "path": "/etc/vault/password-file", + } + + _, err = b.HandleRequest(&logical.Request{ + Operation: logical.UpdateOperation, + Path: "config", + Data: data, + Storage: storage, + }) + if err != nil { + t.Fatal(err) + } + + resp, err := b.HandleRequest(&logical.Request{ + Operation: logical.ReadOperation, + Path: "config", + Storage: storage, + }) + if err != nil { + t.Fatal(err) + } + if resp == nil || resp.IsError() { + t.Fatal("Couldn't read config data") + } + if resp.Data["path"].(string) != data["path"].(string) { + t.Fatal("Couldn't read path from config") + } + + // Missing path + data2 := map[string]interface{}{ + } + + _, err = b.HandleRequest(&logical.Request{ + Operation: logical.UpdateOperation, + Path: "config", + Data: data2, + Storage: storage, + }) + if err == nil { + t.Fatal("Config accepted data with missing path") + } + + // Bad ttl + data3 := map[string]interface{}{ + "path": "/etc/vault/password-file", + "ttl": "auioe", + } + + _, err = b.HandleRequest(&logical.Request{ + Operation: logical.UpdateOperation, + Path: "config", + Data: data3, + Storage: storage, + }) + if err == nil { + t.Fatal("Config accepted bad ttl") + } +} +func TestBackend_Authenticate(t *testing.T) { + var user users + user.User = "gites" + user.Hash = "$6$spfjUPN4$6ap3h.6Fac23HO/CFTZpQYdwvZ8zFflZkCQMWVO.13pCFEOjw8sjVljiIU6SgAhRDwwUBK1DYvHmBdoz/3wef0" + user.Policies = []string{"dev","ops","ping"} + pass := "gitesgites" + if !authenticate(user, pass, nil) { + t.Fatal("Couldn't authenticate request") + } +} diff --git a/authfile/path_config.go b/authfile/path_config.go new file mode 100644 index 0000000..22d8b97 --- /dev/null +++ b/authfile/path_config.go @@ -0,0 +1,113 @@ +package authfile + +import ( + "fmt" + "time" + + "github.com/fatih/structs" + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/logical/framework" + "github.com/pkg/errors" +) + +func pathConfig(b *backend) *framework.Path { + return &framework.Path{ + Pattern: "config", + Fields: map[string]*framework.FieldSchema{ + "path": &framework.FieldSchema{ + Type: framework.TypeString, + Description: "The path to the file with users, passwords hashes and roles", + }, + "ttl": &framework.FieldSchema{ + Type: framework.TypeDurationSecond, + Description: "Duration after which authentication will expire.", + }, + "max_ttl": &framework.FieldSchema{ + Type: framework.TypeDurationSecond, + Description: "Maximum duration after which authentication will expire.", + }, + }, + Callbacks: map[logical.Operation]framework.OperationFunc{ + logical.ReadOperation: b.pathConfigRead, + logical.UpdateOperation: b.pathConfigWrite, + }, + HelpSynopsis: pathConfigHelpSyn, + HelpDescription: pathConfigHelpDesc, + } +} + +func (b *backend) pathConfigRead(req *logical.Request, data *framework.FieldData) (*logical.Response, error) { + cfg, err := b.Config(req.Storage) + if err != nil { + return nil, errors.Wrapf(err, "failed to get configuration from storage") + } + if cfg == nil { + return nil, nil + } + + cfg.TTL /= time.Second + cfg.MaxTTL /= time.Second + + resp := &logical.Response{ + Data: structs.New(cfg).Map(), + } + return resp, nil +} + +func (b *backend) pathConfigWrite(req *logical.Request, data *framework.FieldData) (*logical.Response, error) { + //TODO: validate data + path := data.Get("path").(string) + if path == "" { + return nil, fmt.Errorf(`missing field "path"`) + } + ttl := time.Duration(data.Get("ttl").(int)) * time.Second + maxTTL := time.Duration(data.Get("max_ttl").(int)) * time.Second + + var err error + entry, err := logical.StorageEntryJSON("config", &config{ + Path: path, + TTL: ttl, + MaxTTL: maxTTL, + }) + + if err != nil { + return nil, err + } + + if err := req.Storage.Put(entry); err != nil { + return nil, err + } + + return nil, nil +} + +func (b *backend) Config(s logical.Storage) (*config, error) { + entry, err := s.Get("config") + if err != nil { + return nil, err + } + + var result config + if entry != nil { + if err := entry.DecodeJSON(&result); err != nil { + return nil, fmt.Errorf("error reading configuration: %s", err) + } + } + + return &result, nil +} + +type config struct { + // Path to file with users, passwords and polices + Path string `json:"path" structs:"path"` + // TTL and MaxTTL are the default TTLs. + TTL time.Duration `json:"ttl" structs:"ttl,omitempty"` + MaxTTL time.Duration `json:"max_ttl" structs:"max_ttl,omitempty"` +} + +const pathConfigHelpSyn = ` +Configure Vault to use local file with users. +` +const pathConfigHelpDesc = ` +Configure Vault to use local file with users. +` diff --git a/authfile/path_login.go b/authfile/path_login.go new file mode 100644 index 0000000..463103d --- /dev/null +++ b/authfile/path_login.go @@ -0,0 +1,192 @@ +package authfile + +import ( + "bufio" + "io" + "os" + "strings" + "time" + + "github.com/hashicorp/vault/helper/policyutil" + "github.com/hashicorp/vault/logical" + "github.com/hashicorp/vault/logical/framework" + "github.com/amoghe/go-crypt" +) + +func pathLogin(b *backend) *framework.Path { + return &framework.Path{ + Pattern: "login", + Fields: map[string]*framework.FieldSchema{ + "username": &framework.FieldSchema{ + Type: framework.TypeString, + Description: "Username of the user.", + }, + "password": &framework.FieldSchema{ + Type: framework.TypeString, + Description: "Password of the user.", + }, + }, + Callbacks: map[logical.Operation]framework.OperationFunc{ + logical.UpdateOperation: b.pathLogin, + }, + HelpSynopsis: pathLoginSyn, + HelpDescription: pathLoginDesc, + } +} + +func (b *backend) pathLogin(req *logical.Request, data *framework.FieldData) (*logical.Response, error) { + user := data.Get("username").(string) + pass := data.Get("password").(string) + + config, err := b.Config(req.Storage) + + var fileTTL time.Duration = 300 + //TODO: add caching for passwd file + userMap, err := getUsers(config.Path, fileTTL, b) + if err != nil { + b.logger.Info("vault-auth-file", err) + return nil, err + } + + auth := authenticate(userMap[user], pass, b) + if !auth { + return logical.ErrorResponse("Couldn't authenticate client"), nil + } + + return &logical.Response{ + Auth: &logical.Auth{ + Policies: userMap[user].Policies, + DisplayName: user, + LeaseOptions: logical.LeaseOptions{ + Renewable: true, + TTL: config.TTL, + }, + Metadata: map[string]string{ + "username": user, + "woop": "woop.sh", + }, + InternalData: map[string]interface{}{ + "username": user, + "password": pass, + }, + }, + }, nil +} + +func (b *backend) pathLoginRenew(req *logical.Request, data *framework.FieldData) (*logical.Response, error) { + + if req.Auth == nil { + return logical.ErrorResponse("Couldn't authenticate client"), nil + } + + user, ok := req.Auth.InternalData["username"].(string) + if !ok { + return logical.ErrorResponse("No internal username data in request"), nil + } + pass, ok := req.Auth.InternalData["password"].(string) + if !ok { + return logical.ErrorResponse("No internal password data in request"), nil + } + + config, err := b.Config(req.Storage) + + var fileTTL time.Duration = 300 + //TODO: add caching for passwd file + userMap, err := getUsers(config.Path, fileTTL, b) + if err != nil { + b.logger.Info("vault-auth-file", err) + return nil, err + } + + auth := authenticate(userMap[user], pass, b) + if !auth { + return logical.ErrorResponse("Couldn't authenticate client"), nil + } + if !policyutil.EquivalentPolicies(userMap[user].Policies, req.Auth.Policies) { + return logical.ErrorResponse("Policies have changed, not renewing"), nil + } + return framework.LeaseExtend(config.TTL, config.MaxTTL, b.System())(req, data) +} + +func authenticate(user users, pass string, b *backend) bool { + + hash := strings.Split(user.Hash, "$") + switch hashType := hash[1]; hashType { + case "6": + sha512Hash, err := crypt.Crypt(pass, "$6$"+hash[2]+"$") + if err != nil { + b.logger.Error("vault-auth-file", "error", err) + return false + } + if user.Hash == sha512Hash { + return true + } + //TODO: add others hashing func (md5/blowfish/sha-256) + default: + return false + } + + return false +} + +func getUsers(filePath string, fileTTL time.Duration, b *backend) (map[string]users, error) { + + file, err := os.Open(filePath) + defer file.Close() + + if err != nil { + b.logger.Error("vault-auth-file", "error", err) + return nil, err + } + + reader := bufio.NewReader(file) + + var ( + line string + lineNum int = 1 + tabUsers users + ) + userMap := make(map[string]users) + + for { + line, err = reader.ReadString('\n') + lineNum++ + splitLine := strings.Split(line, ":") + if len(splitLine) == 3 { + tabUsers = users { + strings.Trim(splitLine[0], " "), + strings.Trim(splitLine[1], " "), + strings.Split(strings.Trim(splitLine[2], " \n"), ","), + } + userMap[tabUsers.User] = tabUsers + } else { + b.logger.Info("vault-auth-file: malformed line", + "line", lineNum, "path", filePath) + } + + if err != nil { + break + } + } + + if err != io.EOF { + b.logger.Error("vault-auth-file", "error", err) + return nil, err + } + + return userMap, nil +} + +type users struct { + User string + Hash string + Policies []string +} + +const pathLoginSyn = ` +Authenticate a User in Vault. +` + +const pathLoginDesc = ` +A User is authenticated against a user password file using a username and password. +` diff --git a/authfile/version.go b/authfile/version.go new file mode 100644 index 0000000..c11e14b --- /dev/null +++ b/authfile/version.go @@ -0,0 +1,12 @@ +package authfile + +import "fmt" + +const Version = "0.0.1.dev" + +var ( + Name string + GitCommit string + + HumanVersion = fmt.Sprintf("%s v%s (%s)", Name, Version, GitCommit) +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..b3f3335 --- /dev/null +++ b/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "log" + "os" + + "github.com/hashicorp/vault/helper/pluginutil" + "github.com/hashicorp/vault/logical/plugin" + "github.com/gites/vault-auth-file/authfile" +) + +func main() { + apiClientMeta := &pluginutil.APIClientMeta{} + flags := apiClientMeta.FlagSet() + flags.Parse(os.Args[1:]) + + tlsConfig := apiClientMeta.GetTLSConfig() + tlsProviderFunc := pluginutil.VaultPluginTLSProvider(tlsConfig) + + if err := plugin.Serve(&plugin.ServeOpts{ + BackendFactoryFunc: authfile.Factory, + TLSProviderFunc: tlsProviderFunc, + }); err != nil { + log.Fatal(err) + } +} diff --git a/test/config.hcl b/test/config.hcl new file mode 100644 index 0000000..7dc510c --- /dev/null +++ b/test/config.hcl @@ -0,0 +1 @@ +plugin_directory="/home/wac/go/src/vault-auth-file" diff --git a/test/get_vault.sh b/test/get_vault.sh new file mode 100755 index 0000000..77a1253 --- /dev/null +++ b/test/get_vault.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +VER=0.9.1 +wget -q https://releases.hashicorp.com/vault/$VER/vault_${VER}_linux_amd64.zip +unzip vault_${VER}_linux_amd64.zip +chmod +x vault diff --git a/test/password-file b/test/password-file new file mode 100644 index 0000000..08d3dc2 --- /dev/null +++ b/test/password-file @@ -0,0 +1,5 @@ +wac:$6$.R4zGSdU$UQbNz4pV/AuDxD0Su6qfeVRaKz6gsq3w7zD8ywhFFpF7vbtiBxEFq49SbNI8kNGPmZyMzJIelUFvf12tUknjE0:ops,dev +wacek:$6$AwBd/60MqRG8M1V2$mXPJ39lAs26otEjY4YvObn7lEN2UeZgsEE6ueeN0zWS96QBJQuJLUhLmf1LuvCk7.MYpNik7tl5CEdqr.3Is80:ops,dev,netops +zenek:$6$jG6ZxCOkrXI$r4za9aGwb/VVw3nB3vRyvO2njCzgyKKCPxMn.GOYkW0/WaEMQENpbEufrX6CAQqlsIDr0x9DUsAhIS8bL3OGf1:ops,dev,netops +gites:$6$spfjUPN4$6ap3h.6Fac23HO/CFTZpQYdwvZ8zFflZkCQMWVO.13pCFEOjw8sjVljiIU6SgAhRDwwUBK1DYvHmBdoz/3wef0:ops +gites2:$6$EBzUEPlL$sLnPV5wKqvWloHNf7rfaO2bG1wxGl7zda6Jy/qU3ChLuIlK2EujMIaIdJfHhwbCst60IHqkFAiZXMVhFTQx3b1:ops diff --git a/test/stderr.log b/test/stderr.log new file mode 100644 index 0000000..651e4d9 --- /dev/null +++ b/test/stderr.log @@ -0,0 +1,45 @@ +2018/01/26 15:55:24.298221 [INFO ] core: security barrier not initialized +2018/01/26 15:55:24.298303 [INFO ] core: security barrier initialized: shares=1 threshold=1 +2018/01/26 15:55:24.298378 [INFO ] core: post-unseal setup starting +2018/01/26 15:55:24.306425 [INFO ] core: loaded wrapping token key +2018/01/26 15:55:24.306434 [INFO ] core: successfully setup plugin catalog: plugin-directory=/home/wac/go/src/vault-auth-file +2018/01/26 15:55:24.306917 [INFO ] core: successfully mounted backend: type=kv path=secret/ +2018/01/26 15:55:24.306925 [INFO ] core: successfully mounted backend: type=cubbyhole path=cubbyhole/ +2018/01/26 15:55:24.306996 [INFO ] core: successfully mounted backend: type=system path=sys/ +2018/01/26 15:55:24.307109 [INFO ] core: successfully mounted backend: type=identity path=identity/ +2018/01/26 15:55:24.308579 [INFO ] expiration: restoring leases +2018/01/26 15:55:24.308608 [INFO ] rollback: starting rollback manager +2018/01/26 15:55:24.308738 [INFO ] expiration: lease restore complete +2018/01/26 15:55:24.308826 [INFO ] identity: entities restored +2018/01/26 15:55:24.308830 [INFO ] identity: groups restored +2018/01/26 15:55:24.308836 [INFO ] core: post-unseal setup complete +2018/01/26 15:55:24.308919 [INFO ] core: root token generated +2018/01/26 15:55:24.308920 [INFO ] core: pre-seal teardown starting +2018/01/26 15:55:24.308923 [INFO ] core: cluster listeners not running +2018/01/26 15:55:24.308927 [INFO ] rollback: stopping rollback manager +2018/01/26 15:55:24.308963 [INFO ] core: pre-seal teardown complete +2018/01/26 15:55:24.309013 [INFO ] core: vault is unsealed +2018/01/26 15:55:24.309022 [INFO ] core: post-unseal setup starting +2018/01/26 15:55:24.309055 [INFO ] core: loaded wrapping token key +2018/01/26 15:55:24.309057 [INFO ] core: successfully setup plugin catalog: plugin-directory=/home/wac/go/src/vault-auth-file +2018/01/26 15:55:24.309156 [INFO ] core: successfully mounted backend: type=kv path=secret/ +2018/01/26 15:55:24.309221 [INFO ] core: successfully mounted backend: type=system path=sys/ +2018/01/26 15:55:24.309314 [INFO ] core: successfully mounted backend: type=identity path=identity/ +2018/01/26 15:55:24.309321 [INFO ] core: successfully mounted backend: type=cubbyhole path=cubbyhole/ +2018/01/26 15:55:24.310474 [INFO ] expiration: restoring leases +2018/01/26 15:55:24.310510 [INFO ] rollback: starting rollback manager +2018/01/26 15:55:24.310544 [INFO ] identity: entities restored +2018/01/26 15:55:24.310557 [INFO ] identity: groups restored +2018/01/26 15:55:24.310565 [INFO ] core: post-unseal setup complete +2018/01/26 15:55:24.310588 [INFO ] expiration: lease restore complete +2018/01/26 15:55:25.456538 [INFO ] core: enabled credential backend: path=file/ type=plugin +2018/01/26 15:55:25.537806 [INFO ] core: enabled audit backend: path=file/ type=file +2018/01/26 15:55:25.713520 [INFO ] vault-auth-file: starting...: version=" v0.0.1.dev ()" +2018/01/26 15:55:25.919575 [INFO ] vault-auth-file: malformed line: line=7 path=/home/wac/go/src/vault-auth-file/test/password-file +2018/01/26 15:55:25.976531 [INFO ] vault-auth-file: malformed line: line=7 path=/home/wac/go/src/vault-auth-file/test/password-file +2018/01/26 15:55:26.021050 [INFO ] vault-auth-file: malformed line: line=7 path=/home/wac/go/src/vault-auth-file/test/password-file +2018/01/26 15:55:26.024811 [INFO ] core: pre-seal teardown starting +2018/01/26 15:55:26.024842 [INFO ] core: cluster listeners not running +2018/01/26 15:55:26.034386 [INFO ] rollback: stopping rollback manager +2018/01/26 15:55:26.034453 [INFO ] core: pre-seal teardown complete +2018/01/26 15:55:26.034470 [INFO ] core: vault is sealed diff --git a/test/stdout.log b/test/stdout.log new file mode 100644 index 0000000..01ee030 --- /dev/null +++ b/test/stdout.log @@ -0,0 +1,33 @@ +==> Vault server configuration: + + Cgo: disabled + Cluster Address: https://127.0.0.1:8201 + Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", tls: "disabled") + Log Level: + Mlock: supported: true, enabled: false + Redirect Address: http://127.0.0.1:8200 + Storage: inmem + Version: Vault v0.9.1 + Version Sha: 87b6919dea55da61d7cd444b2442cabb8ede8ab1 + +==> WARNING: Dev mode is enabled! + +In this mode, Vault is completely in-memory and unsealed. +Vault is configured to only have a single unseal key. The root +token has already been authenticated with the CLI, so you can +immediately begin using the Vault CLI. + +The only step you need to take is to set the following +environment variables: + + export VAULT_ADDR='http://127.0.0.1:8200' + +The unseal key and root token are reproduced below in case you +want to seal/unseal the Vault or play with authentication. + +Unseal Key: jdnqvJJeAnzIawg8xaLM3YYQi7D3lQ4y2WMz8+qkZIA= +Root Token: 5745e937-e456-021e-324c-4ea8895eac3f + +==> Vault server started! Log data will stream in below: + +==> Vault shutdown triggered diff --git a/test/tests.sh b/test/tests.sh new file mode 100755 index 0000000..ae97ef6 --- /dev/null +++ b/test/tests.sh @@ -0,0 +1,41 @@ +#!/bin/bash + + +set -ex +go test -v ../... + +cd /home/wac/go/src/vault-auth-file/test +./vault server -dev -config config.hcl 2>stderr.log 1>stdout.log & +PID=$! +sleep 1 +export VAULT_ADDR=http://127.0.0.1:8200 +SHA_256SUM=`sha256sum /home/wac/go/src/vault-auth-file/vault-auth-file|cut -d' ' -f1` +./vault write sys/plugins/catalog/vault-auth-file sha_256=$SHA_256SUM command=vault-auth-file + +./vault auth-enable -path=file -plugin-name vault-auth-file plugin + +./vault auth -methods + +./vault audit-enable file file_path=./vault_audit.log log_raw=true + +set +e +./vault write auth/file/login username=wac password=lubieplacki && exit 1 +set -e + +./vault write auth/file/config path=/home/wac/go/src/vault-auth-file/test/password-file + +./vault read auth/file/config + +./vault write auth/file/config path=/home/wac/go/src/vault-auth-file/test/password-file ttl=123 max_ttl=456 + +./vault read auth/file/config +set +e +./vault write -format=json auth/file/login username=wac password=nielubueplackow && exit 1 +set -e +./vault write -format=json auth/file/login username=wac password=lubieplacki | tee wac.json + +./vault token-renew `cat wac.json | grep client_token | cut -d'"' -f 4` + +set +e +kill $PID +rm wac.json