diff --git a/logic/jwts.go b/logic/jwts.go index 067717802..b87a476a3 100644 --- a/logic/jwts.go +++ b/logic/jwts.go @@ -2,6 +2,7 @@ package logic import ( "errors" + "log" "time" "github.com/golang-jwt/jwt/v4" @@ -9,7 +10,24 @@ import ( "github.com/gravitl/netmaker/servercfg" ) -var jwtSecretKey = []byte("(BytesOverTheWire)") +var jwtSecretKey []byte + +// SetJWTSecret - sets the jwt secret on server startup +func SetJWTSecret() { + currentSecret, jwtErr := FetchJWTSecret() + if jwtErr != nil { + newValue, err := GenerateRandString(64) + if err != nil { + log.Fatalln("something went wrong when generating signature") + } + jwtSecretKey = []byte(newValue) // 512 bit random password + if err := StoreJWTSecret(string(jwtSecretKey)); err != nil { + log.Fatalln("something went wrong when configuring JWT authentication") + } + } else { + jwtSecretKey = []byte(currentSecret) + } +} // CreateJWT func will used to create the JWT while signing in and signing out func CreateJWT(macaddress string, network string) (response string, err error) { diff --git a/logic/serverconf.go b/logic/serverconf.go index f3f4295ad..e3b073533 100644 --- a/logic/serverconf.go +++ b/logic/serverconf.go @@ -45,3 +45,32 @@ func FetchPrivKey(serverID string) (string, error) { func RemovePrivKey(serverID string) error { return database.DeleteRecord(database.SERVERCONF_TABLE_NAME, serverID) } + +// FetchJWTSecret - fetches jwt secret from db +func FetchJWTSecret() (string, error) { + var dbData string + var err error + var fetchedData = serverData{} + dbData, err = database.FetchRecord(database.SERVERCONF_TABLE_NAME, "nm-jwt-secret") + if err != nil { + return "", err + } + err = json.Unmarshal([]byte(dbData), &fetchedData) + if err != nil { + return "", err + } + return fetchedData.PrivateKey, nil +} + +// StoreJWTSecret - stores server jwt secret if needed +func StoreJWTSecret(privateKey string) error { + var newData = serverData{} + var err error + var data []byte + newData.PrivateKey = privateKey + data, err = json.Marshal(&newData) + if err != nil { + return err + } + return database.Insert("nm-jwt-secret", string(data), database.SERVERCONF_TABLE_NAME) +} diff --git a/logic/util.go b/logic/util.go index b6adde41d..cb7a740e6 100644 --- a/logic/util.go +++ b/logic/util.go @@ -2,9 +2,11 @@ package logic import ( + crand "crypto/rand" "encoding/base64" "encoding/json" "log" + "math/big" "math/rand" "strconv" "strings" @@ -288,6 +290,21 @@ func RandomString(length int) string { return string(b) } +// GenerateRandString - generates random string of n length +func GenerateRandString(n int) (string, error) { + const chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" + ret := make([]byte, n) + for i := range ret { + num, err := crand.Int(crand.Reader, big.NewInt(int64(len(chars)))) + if err != nil { + return "", err + } + ret[i] = chars[num.Int64()] + } + + return string(ret), nil +} + func setPeerInfo(node models.Node) models.Node { var peer models.Node peer.RelayAddrs = node.RelayAddrs diff --git a/main.go b/main.go index 3ffafa5f7..c85cee9a9 100644 --- a/main.go +++ b/main.go @@ -42,6 +42,7 @@ func initialize() { // Client Mode Prereq Check log.Fatal(err) } logic.Log("database successfully connected", 0) + logic.SetJWTSecret() var authProvider = auth.InitializeAuthProvider() if authProvider != "" {