Skip to content

Commit 43a41e5

Browse files
jkatzJonathan S. Katz
authored andcommitted
Modify character space for random password generation
This removes a couple of characters from consideration for the randomly generated passwords, as these characters could pose problems when applying them in shell environments. The character entropy is still quite large even with this removal.
1 parent 84f65ff commit 43a41e5

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

internal/util/secrets.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ const (
4545
// passwordCharUpper is the highest ASCII character to use for generating a
4646
// password, which is 126
4747
passwordCharUpper = 126
48+
// passwordCharExclude is a map of characters that we choose to exclude from
49+
// the password to simplify usage in the shell. There is still enough entropy
50+
// that exclusion of these characters is OK.
51+
passwordCharExclude = "`\\"
4852
)
4953

5054
// passwordCharSelector is a "big int" that we need to select the random ASCII
@@ -77,16 +81,24 @@ func CreateSecret(clientset kubernetes.Interface, db, secretName, username, pass
7781
// ASCII characters suitable for a password
7882
func GeneratePassword(length int) (string, error) {
7983
password := make([]byte, length)
84+
i := 0
8085

81-
for i := 0; i < length; i++ {
82-
char, err := rand.Int(rand.Reader, passwordCharSelector)
83-
86+
for i < length {
87+
val, err := rand.Int(rand.Reader, passwordCharSelector)
8488
// if there is an error generating the random integer, return
8589
if err != nil {
8690
return "", err
8791
}
8892

89-
password[i] = byte(passwordCharLower + char.Int64())
93+
char := byte(passwordCharLower + val.Int64())
94+
95+
// if the character is in the exclusion list, continue
96+
if idx := strings.IndexAny(string(char), passwordCharExclude); idx > -1 {
97+
continue
98+
}
99+
100+
password[i] = char
101+
i++
90102
}
91103

92104
return string(password), nil

internal/util/secrets_test.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,20 @@ import (
2323

2424
func TestGeneratePassword(t *testing.T) {
2525
// different lengths
26-
for _, length := range []int{1, 2, 3, 5, 20} {
26+
for _, length := range []int{1, 2, 3, 5, 20, 200} {
2727
password, err := GeneratePassword(length)
2828
if err != nil {
2929
t.Fatalf("expected no error, got %v", err)
3030
}
3131
if expected, actual := length, len(password); expected != actual {
3232
t.Fatalf("expected length %v, got %v", expected, actual)
3333
}
34-
if i := strings.IndexFunc(password, unicode.IsPrint); i > 0 {
34+
if i := strings.IndexFunc(password, func(r rune) bool { return !unicode.IsPrint(r) }); i > -1 {
3535
t.Fatalf("expected only printable characters, got %q in %q", password[i], password)
3636
}
37+
if i := strings.IndexAny(password, passwordCharExclude); i > -1 {
38+
t.Fatalf("expected no exclude characters, got %q in %q", password[i], password)
39+
}
3740
}
3841

3942
// random contents
@@ -44,9 +47,12 @@ func TestGeneratePassword(t *testing.T) {
4447
if err != nil {
4548
t.Fatalf("expected no error, got %v", err)
4649
}
47-
if i := strings.IndexFunc(password, unicode.IsPrint); i > 0 {
50+
if i := strings.IndexFunc(password, func(r rune) bool { return !unicode.IsPrint(r) }); i > -1 {
4851
t.Fatalf("expected only printable characters, got %q in %q", password[i], password)
4952
}
53+
if i := strings.IndexAny(password, passwordCharExclude); i > -1 {
54+
t.Fatalf("expected no exclude characters, got %q in %q", password[i], password)
55+
}
5056

5157
for i := range previous {
5258
if password == previous[i] {

0 commit comments

Comments
 (0)