-
Notifications
You must be signed in to change notification settings - Fork 9.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
*: make bcrypt-cost configurable #9633
Changes from 4 commits
334263c
ea3b601
d18422e
9005333
d70369e
e159331
94dd681
3f23c99
596e9c0
5b51eb9
21fdde5
9e7a3e5
d80ef1f
2afd827
5e06955
9e1b58f
53f51b2
859172e
8893c66
ad1be4e
e1d05d0
d923b1d
c16a8d9
afcf163
7328865
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1048,12 +1048,18 @@ func decomposeOpts(optstr string) (string, map[string]string, error) { | |
|
||
} | ||
|
||
func NewTokenProvider(lg *zap.Logger, tokenOpts string, indexWaiter func(uint64) <-chan struct{}) (TokenProvider, error) { | ||
func NewTokenProvider(lg *zap.Logger, tokenOpts string, bcryptCost int, indexWaiter func(uint64) <-chan struct{}) (TokenProvider, error) { | ||
tokenType, typeSpecificOpts, err := decomposeOpts(tokenOpts) | ||
if err != nil { | ||
return nil, ErrInvalidAuthOpts | ||
} | ||
|
||
if bcryptCost < bcrypt.MinCost || bcryptCost > bcrypt.MaxCost { | ||
plog.Errorf("Invalid bcrypt-cost: %d", bcryptCost) | ||
return nil, ErrInvalidAuthOpts | ||
} | ||
BcryptCost = bcryptCost | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will make it private. BcryptCost is only referenced in clientv3/main_test.go and clientv3/main_test.go does not trigger anything related to bcrypt. |
||
|
||
switch tokenType { | ||
case "simple": | ||
if lg != nil { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ import ( | |
"testing" | ||
|
||
"github.com/coreos/etcd/auth" | ||
"golang.org/x/crypto/bcrypt" | ||
) | ||
|
||
// TestStartEtcdWrongToken ensures that StartEtcd with wrong configs returns with error. | ||
|
@@ -36,3 +37,33 @@ func TestStartEtcdWrongToken(t *testing.T) { | |
t.Fatalf("expected %v, got %v", auth.ErrInvalidAuthOpts, err) | ||
} | ||
} | ||
|
||
// TestStartEtcdLargeBcryptCost ensures that StartEtcd with invalid large bcrypt-cost returns with error. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tests in |
||
func TestStartEtcdLargeBcryptCost(t *testing.T) { | ||
tdir, err := ioutil.TempDir(os.TempDir(), "large-bcrypt-cost-test") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.RemoveAll(tdir) | ||
cfg := NewConfig() | ||
cfg.Dir = tdir | ||
cfg.BcryptCost = uint(bcrypt.MaxCost) + 1 | ||
if _, err = StartEtcd(cfg); err != auth.ErrInvalidAuthOpts { | ||
t.Fatalf("expected %v, got %v", auth.ErrInvalidAuthOpts, err) | ||
} | ||
} | ||
|
||
// TestStartEtcdSmallBcryptCost ensures that StartEtcd with invalid small bcrypt-cost returns with error. | ||
func TestStartEtcdSmallBcryptCost(t *testing.T) { | ||
tdir, err := ioutil.TempDir(os.TempDir(), "small-bcrypt-cost-test") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.RemoveAll(tdir) | ||
cfg := NewConfig() | ||
cfg.Dir = tdir | ||
cfg.BcryptCost = uint(bcrypt.MinCost) - 1 | ||
if _, err = StartEtcd(cfg); err != auth.ErrInvalidAuthOpts { | ||
t.Fatalf("expected %v, got %v", auth.ErrInvalidAuthOpts, err) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -237,6 +237,7 @@ func newConfig() *config { | |
|
||
// auth | ||
fs.StringVar(&cfg.ec.AuthToken, "auth-token", cfg.ec.AuthToken, "Specify auth token specific options.") | ||
fs.UintVar(&cfg.ec.BcryptCost, "bcrypt-cost", cfg.ec.BcryptCost, "Bcrypt algorithm cost / strength for hashing auth passwords") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Specify bcrypt algorithm cost factor for auth password hashing." |
||
|
||
// experimental | ||
fs.BoolVar(&cfg.ec.ExperimentalInitialCorruptCheck, "experimental-initial-corrupt-check", cfg.ec.ExperimentalInitialCorruptCheck, "Enable to check data corruption before serving any client/peer traffic.") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -148,6 +148,8 @@ Security: | |
Auth: | ||
--auth-token 'simple' | ||
Specify a v3 authentication token type and its options ('simple' or 'jwt'). | ||
--bcrypt-cost 10 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
Specify the cost / strength of the bcrypt algorithm for hashing auth passwords. Valid values are between 4 and 31. | ||
|
||
Profiling: | ||
--enable-pprof 'false' | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,6 +53,7 @@ import ( | |
|
||
"github.com/coreos/pkg/capnslog" | ||
"github.com/soheilhy/cmux" | ||
"golang.org/x/crypto/bcrypt" | ||
"google.golang.org/grpc" | ||
"google.golang.org/grpc/grpclog" | ||
"google.golang.org/grpc/keepalive" | ||
|
@@ -605,6 +606,7 @@ func mustNewMember(t *testing.T, mcfg memberConfig) *member { | |
m.MaxRequestBytes = embed.DefaultMaxRequestBytes | ||
} | ||
m.AuthToken = "simple" // for the purpose of integration testing, simple token is enough | ||
m.BcryptCost = uint(bcrypt.MinCost) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed when we have unit tests inside |
||
|
||
m.grpcServerOpts = []grpc.ServerOption{} | ||
if mcfg.grpcKeepAliveMinTime > time.Duration(0) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,6 +123,7 @@ type etcdProcessClusterConfig struct { | |
noStrictReconfig bool | ||
initialCorruptCheck bool | ||
authTokenOpts string | ||
bcryptCost int | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove changes from |
||
} | ||
|
||
// newEtcdProcessCluster launches a new cluster from etcd processes, returning | ||
|
@@ -249,6 +250,12 @@ func (cfg *etcdProcessClusterConfig) etcdServerProcessConfigs() []*etcdServerPro | |
args = append(args, "--auth-token", cfg.authTokenOpts) | ||
} | ||
|
||
if cfg.bcryptCost > 0 { | ||
args = append(args, | ||
"--bcrypt-cost", fmt.Sprintf("%d", cfg.bcryptCost), | ||
) | ||
} | ||
|
||
etcdCfgs[i] = &etcdServerProcessConfig{ | ||
execPath: cfg.execPath, | ||
args: args, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.