From c6aab9893a06600bc597d09ee50828c7b3ec142d Mon Sep 17 00:00:00 2001 From: registergoofy <70151212+registergoofy@users.noreply.github.com> Date: Tue, 29 Sep 2020 13:17:33 +0200 Subject: [PATCH] add randomness to machine-id when registering. (#261) * add randomness to machine-id when registering. * add some regexp check for machine_id * typo fix * fix cwapi unit tests --- cmd/crowdsec-cli/api.go | 17 ++++++------ cmd/crowdsec-cli/dashboard.go | 2 +- go.mod | 2 ++ go.sum | 3 ++ pkg/cwapi/auth.go | 15 +++++++++- pkg/cwapi/auth_test.go | 52 ++++++++--------------------------- 6 files changed, 40 insertions(+), 51 deletions(-) diff --git a/cmd/crowdsec-cli/api.go b/cmd/crowdsec-cli/api.go index 41ea0c49a..70c8ef2fe 100644 --- a/cmd/crowdsec-cli/api.go +++ b/cmd/crowdsec-cli/api.go @@ -20,10 +20,9 @@ import ( ) var ( - passwordLength = 64 - upper = "ABCDEFGHIJKLMNOPQRSTUVWXY" - lower = "abcdefghijklmnopqrstuvwxyz" - digits = "0123456789" + upper = "ABCDEFGHIJKLMNOPQRSTUVWXY" + lower = "abcdefghijklmnopqrstuvwxyz" + digits = "0123456789" ) var ( @@ -53,7 +52,7 @@ func dumpCredentials() error { return nil } -func generatePassword() string { +func generatePassword(passwordLength int) string { rand.Seed(time.Now().UnixNano()) charset := upper + lower + digits @@ -191,9 +190,9 @@ cscli api credentials # Display your API credentials id = string(bID) id = strings.ReplaceAll(id, "-", "")[:32] } - password := generatePassword() + password := generatePassword(64) - if err := outputCTX.API.RegisterMachine(id, password); err != nil { + if err := outputCTX.API.RegisterMachine(fmt.Sprintf("%s%s", id, generatePassword(16)), password); err != nil { log.Fatalf(err.Error()) } fmt.Printf("machine_id: %s\n", outputCTX.API.Creds.User) @@ -237,8 +236,8 @@ cscli api credentials # Display your API credentials id = strings.ReplaceAll(id, "-", "")[:32] } - password := generatePassword() - if err := outputCTX.API.ResetPassword(id, password); err != nil { + password := generatePassword(64) + if err := outputCTX.API.ResetPassword(fmt.Sprintf("%s%s", id, generatePassword(16)), password); err != nil { log.Fatalf(err.Error()) } fmt.Printf("machine_id: %s\n", outputCTX.API.Creds.User) diff --git a/cmd/crowdsec-cli/dashboard.go b/cmd/crowdsec-cli/dashboard.go index 4930912ba..37f36d17c 100644 --- a/cmd/crowdsec-cli/dashboard.go +++ b/cmd/crowdsec-cli/dashboard.go @@ -75,7 +75,7 @@ cscli dashboard setup -l 0.0.0.0 -p 443 log.Fatalf("Failed to start metabase container : %s", err) } log.Infof("Started metabase") - newpassword := generatePassword() + newpassword := generatePassword(64) if err := resetMetabasePassword(newpassword); err != nil { log.Fatalf("Failed to reset password : %s", err) } diff --git a/go.mod b/go.mod index 12ca23037..fcb446bff 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,9 @@ require ( github.com/sevlyar/go-daemon v0.1.5 github.com/sirupsen/logrus v1.5.0 github.com/spf13/cobra v0.0.7 + github.com/stretchr/testify v1.5.1 golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect + golang.org/x/mod v0.2.0 golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e // indirect diff --git a/go.sum b/go.sum index 472e3c7db..beef02757 100644 --- a/go.sum +++ b/go.sum @@ -163,6 +163,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -219,6 +220,7 @@ github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRci github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -240,6 +242,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/pkg/cwapi/auth.go b/pkg/cwapi/auth.go index f6b33ac1f..f62e665b6 100644 --- a/pkg/cwapi/auth.go +++ b/pkg/cwapi/auth.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "net/http" + "regexp" "strings" "time" @@ -162,11 +163,14 @@ func (ctx *ApiCtx) Signin() error { } func (ctx *ApiCtx) RegisterMachine(machineID string, password string) error { + if !validate(machineID) { + log.Fatalf("Machine ID %s is not compliant to '^[a-zA-Z0-9]+$'", machineID) + } + ctx.Creds.User = machineID ctx.Creds.Password = password jsonResp := &ApiResp{} errResp := &ApiResp{} - resp, err := ctx.Http.New().Post(ctx.RegisterPath).BodyJSON(ctx.Creds).Receive(jsonResp, errResp) if err != nil { return fmt.Errorf("api register machine: HTTP request creation failed: %s", err) @@ -183,6 +187,10 @@ func (ctx *ApiCtx) RegisterMachine(machineID string, password string) error { } func (ctx *ApiCtx) ResetPassword(machineID string, password string) error { + if !validate(machineID) { + log.Fatalf("Machine ID %s is not compliant to '^[a-zA-Z0-9]+$'", machineID) + } + ctx.Creds.User = machineID ctx.Creds.Password = password jsonResp := &ApiResp{} @@ -203,3 +211,8 @@ func (ctx *ApiCtx) ResetPassword(machineID string, password string) error { } return nil } + +func validate(machineID string) bool { + re := regexp.MustCompile("^[a-zA-Z0-9]+$") + return re.MatchString(machineID) +} diff --git a/pkg/cwapi/auth_test.go b/pkg/cwapi/auth_test.go index d5e1a57e8..29e9432dd 100644 --- a/pkg/cwapi/auth_test.go +++ b/pkg/cwapi/auth_test.go @@ -8,7 +8,6 @@ import ( "github.com/dghubble/sling" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" - "gopkg.in/tomb.v2" "gopkg.in/yaml.v2" ) @@ -267,7 +266,7 @@ func TestRegisterMachine(t *testing.T) { ApiVersion: "v1", RegisterPath: "register", BaseURL: "https://my_testendpoint.com", - CfgUser: "machine_id", + CfgUser: "machineid", CfgPassword: "machine_password", Creds: ApiCreds{ Profile: "crowdsec/test1,crowdsec/test2", @@ -275,7 +274,7 @@ func TestRegisterMachine(t *testing.T) { Http: sling.New().Client(newMockClient()).Base(apiBaseURL), }, expectedAPICreds: &ApiCreds{ - User: "machine_id", + User: "machineid", Password: "machine_password", Profile: "crowdsec/test1,crowdsec/test2", }, @@ -287,30 +286,16 @@ func TestRegisterMachine(t *testing.T) { ApiVersion: "v1", RegisterPath: "unknown_path", BaseURL: "https://my_testendpoint.com", - CfgUser: "machine_id", + CfgUser: "machineid", CfgPassword: "machine_password", Creds: ApiCreds{ - User: "machine_id", + User: "machineid", Password: "machine_password", Profile: "crowdsec/test1,crowdsec/test2", }, Http: sling.New().Client(newMockClient()).Base(apiBaseURL), }, }, - { - name: "api register malformed response", - expectedErr: true, - givenAPICtx: &ApiCtx{ - ApiVersion: "v1", - RegisterPath: "malformed_response", - BaseURL: "https://my_testendpoint.com", - Creds: ApiCreds{ - Profile: "crowdsec/test1,crowdsec/test2", - }, - Http: sling.New().Client(newMockClient()).Base(apiBaseURL), - PusherTomb: tomb.Tomb{}, - }, - }, { name: "api register bad response", expectedErr: true, @@ -318,7 +303,7 @@ func TestRegisterMachine(t *testing.T) { ApiVersion: "v1", RegisterPath: "bad_response", BaseURL: "https://my_testendpoint.com", - CfgUser: "machine_id", + CfgUser: "machineid", CfgPassword: "machine_password", Creds: ApiCreds{ Profile: "crowdsec/test1,crowdsec/test2", @@ -329,6 +314,7 @@ func TestRegisterMachine(t *testing.T) { } for _, test := range tests { + log.Printf("test '%s'", test.name) err := test.givenAPICtx.RegisterMachine(test.givenAPICtx.CfgUser, test.givenAPICtx.CfgPassword) if !test.expectedErr && err != nil { t.Fatalf("test '%s' failed : %s", test.name, err) @@ -360,7 +346,7 @@ func TestResetPassword(t *testing.T) { ApiVersion: "v1", ResetPwdPath: "resetpassword", BaseURL: "https://my_testendpoint.com", - CfgUser: "machine_id", + CfgUser: "machineid", CfgPassword: "new_machine_password", Creds: ApiCreds{ Profile: "crowdsec/test1,crowdsec/test2", @@ -368,7 +354,7 @@ func TestResetPassword(t *testing.T) { Http: sling.New().Client(newMockClient()).Base(apiBaseURL), }, expectedAPICreds: &ApiCreds{ - User: "machine_id", + User: "machineid", Password: "new_machine_password", Profile: "crowdsec/test1,crowdsec/test2", }, @@ -380,30 +366,16 @@ func TestResetPassword(t *testing.T) { ApiVersion: "v1", ResetPwdPath: "unknown_path", BaseURL: "https://my_testendpoint.com", - CfgUser: "machine_id", + CfgUser: "machineid", CfgPassword: "machine_password", Creds: ApiCreds{ - User: "machine_id", + User: "machineid", Password: "machine_password", Profile: "crowdsec/test1,crowdsec/test2", }, Http: sling.New().Client(newMockClient()).Base(apiBaseURL), }, }, - { - name: "api reset password malformed response", - expectedErr: true, - givenAPICtx: &ApiCtx{ - ApiVersion: "v1", - ResetPwdPath: "malformed_response", - BaseURL: "https://my_testendpoint.com", - Creds: ApiCreds{ - Profile: "crowdsec/test1,crowdsec/test2", - }, - Http: sling.New().Client(newMockClient()).Base(apiBaseURL), - PusherTomb: tomb.Tomb{}, - }, - }, { name: "api reset password bad response", expectedErr: true, @@ -411,7 +383,7 @@ func TestResetPassword(t *testing.T) { ApiVersion: "v1", ResetPwdPath: "bad_response", BaseURL: "https://my_testendpoint.com", - CfgUser: "machine_id", + CfgUser: "machineid", CfgPassword: "machine_password", Creds: ApiCreds{ Profile: "crowdsec/test1,crowdsec/test2", @@ -426,7 +398,7 @@ func TestResetPassword(t *testing.T) { ApiVersion: "v1", ResetPwdPath: "resestpassword_unknown_user", BaseURL: "https://my_testendpoint.com", - CfgUser: "machine_id", + CfgUser: "machineid", CfgPassword: "machine_password", Creds: ApiCreds{ Profile: "crowdsec/test1,crowdsec/test2",