Skip to content
This repository was archived by the owner on Mar 15, 2024. It is now read-only.

Commit 44d2232

Browse files
author
Michael Weber
committed
Use Splunk compatible password scheme
passwords need to match complexity specified in Splunk Fixes TE-101
1 parent 1220228 commit 44d2232

File tree

7 files changed

+72
-8
lines changed

7 files changed

+72
-8
lines changed

backend_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,11 @@ func TestBackend_RoleCRUD(t *testing.T) {
8787
}
8888

8989
testRoleConfig := roleConfig{
90-
Connection: "testconn",
91-
Roles: []string{"admin"},
92-
UserPrefix: "my-custom-prefix",
90+
Connection: "testconn",
91+
Roles: []string{"admin"},
92+
AllowedNodeTypes: []string{"*"},
93+
PasswordSpec: DefaultPasswordSpec(),
94+
UserPrefix: "my-custom-prefix",
9395
}
9496

9597
logicaltest.Test(t, logicaltest.TestCase{

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ require (
1717
github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect
1818
github.com/fatih/structs v1.1.0
1919
github.com/go-sql-driver/mysql v1.4.1 // indirect
20+
github.com/go-test/deep v1.0.5 // indirect
2021
github.com/golang/snappy v0.0.1 // indirect
2122
github.com/google/go-querystring v1.0.0
2223
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
@@ -48,6 +49,7 @@ require (
4849
github.com/pierrec/lz4 v2.2.6+incompatible // indirect
4950
github.com/prometheus/client_golang v1.1.0 // indirect
5051
github.com/ryanuber/go-glob v1.0.0 // indirect
52+
github.com/sethvargo/go-password v0.1.3
5153
github.com/sirupsen/logrus v1.4.2 // indirect
5254
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
5355
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
5151
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
5252
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
5353
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
54+
github.com/go-test/deep v1.0.5 h1:AKODKU3pDH1RzZzm6YZu77YWtEAq6uh1rLIAQlay2qc=
55+
github.com/go-test/deep v1.0.5/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
5456
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
5557
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
5658
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -185,6 +187,8 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa
185187
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
186188
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
187189
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
190+
github.com/sethvargo/go-password v0.1.3 h1:18KkbGDkw8SuzeohAbWqBLNSfRQblVwEHOLbPa0PvWM=
191+
github.com/sethvargo/go-password v0.1.3/go.mod h1:2tyaaoHK/AlXwh5WWQDYjqQbHcq4cjPj5qb/ciYvu/Q=
188192
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
189193
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
190194
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=

password.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package splunk
2+
3+
import (
4+
"github.com/sethvargo/go-password/password"
5+
)
6+
7+
type PasswordSpec struct {
8+
Length int `json:"length" structs:"length"`
9+
NumDigits int `json:"num_digits" structs:"num_digits"`
10+
NumSymbols int `json:"num_symbols" structs:"num_symbols"`
11+
AllowUpper bool `json:"allow_upper" structs:"allow_upper"`
12+
AllowRepeat bool `json:"allow_repeat" structs:"allow_repeat"`
13+
}
14+
15+
func DefaultPasswordSpec() *PasswordSpec {
16+
return &PasswordSpec{
17+
Length: 32,
18+
NumDigits: 4,
19+
NumSymbols: 4,
20+
AllowUpper: true,
21+
AllowRepeat: true,
22+
}
23+
}
24+
25+
func GeneratePassword(spec *PasswordSpec) (string, error) {
26+
passwdgen, err := password.NewGenerator(&password.GeneratorInput{
27+
LowerLetters: password.LowerLetters,
28+
UpperLetters: password.UpperLetters,
29+
Digits: password.Digits,
30+
Symbols: "_&^%$#@!", // mostly shell-safe set, TE-101
31+
})
32+
if err != nil {
33+
return "", err
34+
}
35+
36+
if spec == nil {
37+
spec = DefaultPasswordSpec()
38+
}
39+
return passwdgen.Generate(spec.Length, spec.NumDigits, spec.NumSymbols, !spec.AllowUpper, spec.AllowRepeat)
40+
}

path_creds_create.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package splunk
33
import (
44
"context"
55
"fmt"
6+
67
"github.com/hashicorp/errwrap"
7-
"github.com/hashicorp/go-uuid"
8+
uuid "github.com/hashicorp/go-uuid"
89
"github.com/hashicorp/vault/helper/strutil"
910
"github.com/hashicorp/vault/logical"
1011
"github.com/hashicorp/vault/logical/framework"
@@ -84,7 +85,7 @@ func (b *backend) credsReadHandlerStandalone(ctx context.Context, req *logical.R
8485
}
8586

8687
// Generate credentials
87-
userUUID, err := uuid.GenerateUUID()
88+
userUUID, err := generateUserID(role)
8889
if err != nil {
8990
return nil, err
9091
}
@@ -93,7 +94,7 @@ func (b *backend) credsReadHandlerStandalone(ctx context.Context, req *logical.R
9394
userPrefix = fmt.Sprintf("%s_%s", role.UserPrefix, req.DisplayName)
9495
}
9596
username := fmt.Sprintf("%s_%s", userPrefix, userUUID)
96-
passwd, err := uuid.GenerateUUID()
97+
passwd, err := generateUserPassword(role)
9798
if err != nil {
9899
return nil, errwrap.Wrapf("error generating new password {{err}}", err)
99100
}
@@ -193,7 +194,7 @@ func (b *backend) credsReadHandlerMulti(ctx context.Context, req *logical.Reques
193194
return nil, err
194195
}
195196
// Generate credentials
196-
userUUID, err := uuid.GenerateUUID()
197+
userUUID, err := generateUserID(role)
197198
if err != nil {
198199
return nil, err
199200
}
@@ -202,7 +203,7 @@ func (b *backend) credsReadHandlerMulti(ctx context.Context, req *logical.Reques
202203
userPrefix = fmt.Sprintf("%s_%s", role.UserPrefix, req.DisplayName)
203204
}
204205
username := fmt.Sprintf("%s_%s", userPrefix, userUUID)
205-
passwd, err := uuid.GenerateUUID()
206+
passwd, err := generateUserPassword(role)
206207
if err != nil {
207208
return nil, errwrap.Wrapf("error generating new password: {{err}}", err)
208209
}
@@ -251,6 +252,19 @@ func (b *backend) credsReadHandler(ctx context.Context, req *logical.Request, d
251252
return b.credsReadHandlerStandalone(ctx, req, d)
252253
}
253254

255+
func generateUserID(roleConfig *roleConfig) (string, error) {
256+
return uuid.GenerateUUID()
257+
}
258+
259+
func generateUserPassword(roleConfig *roleConfig) (string, error) {
260+
passwd, err := GeneratePassword(roleConfig.PasswordSpec)
261+
if err == nil {
262+
return passwd, nil
263+
}
264+
// fallback
265+
return uuid.GenerateUUID()
266+
}
267+
254268
const pathCredsCreateHelpSyn = `
255269
Request Splunk credentials for a certain role.
256270
`

path_roles.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ func (b *backend) rolesWriteHandler(ctx context.Context, req *logical.Request, d
114114
if maxTTLRaw, ok := getValue(data, req.Operation, "max_ttl"); ok {
115115
role.MaxTTL = time.Duration(maxTTLRaw.(int)) * time.Second
116116
}
117+
role.PasswordSpec = DefaultPasswordSpec() // XXX make configurable
117118

118119
if roles, ok := getValue(data, req.Operation, "roles"); ok {
119120
role.Roles = roles.([]string)

role.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type roleConfig struct {
1414
Connection string `json:"connection" structs:"connection"`
1515
DefaultTTL time.Duration `json:"default_ttl" structs:"default_ttl"`
1616
MaxTTL time.Duration `json:"max_ttl" structs:"max_ttl"`
17+
PasswordSpec *PasswordSpec `json:"password_spec" structs:"password_spec"`
1718

1819
// Splunk user attributes
1920
Roles []string `json:"roles" structs:"roles"`

0 commit comments

Comments
 (0)