Browse Source

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
registergoofy 4 years ago
parent
commit
c6aab9893a
6 changed files with 40 additions and 51 deletions
  1. 8 9
      cmd/crowdsec-cli/api.go
  2. 1 1
      cmd/crowdsec-cli/dashboard.go
  3. 2 0
      go.mod
  4. 3 0
      go.sum
  5. 14 1
      pkg/cwapi/auth.go
  6. 12 40
      pkg/cwapi/auth_test.go

+ 8 - 9
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)

+ 1 - 1
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)
 			}

+ 2 - 0
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

+ 3 - 0
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=

+ 14 - 1
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)
+}

+ 12 - 40
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",