From 548997f9ef8da50ed822621dcb1b268ec5e1b841 Mon Sep 17 00:00:00 2001 From: 0xdcarns Date: Fri, 10 Dec 2021 21:09:42 -0500 Subject: [PATCH] optimize further --- controllers/auth_grpc.go | 12 ++++++------ controllers/dns_test.go | 2 +- controllers/ext_client.go | 5 ++--- controllers/network_test.go | 5 ----- controllers/node.go | 28 ++++++---------------------- controllers/node_grpc.go | 25 +++++++++---------------- controllers/node_test.go | 6 +++--- controllers/server.go | 5 +---- logic/accesskeys.go | 1 + logic/extpeers.go | 4 ++-- logic/networks.go | 8 ++++---- logic/server.go | 4 ++-- logic/util.go | 29 +++++++++++++---------------- logic/wireguard.go | 1 + main.go | 12 +++--------- models/node.go | 10 +++++----- models/structs.go | 2 +- netclient/config/config.go | 2 +- 18 files changed, 61 insertions(+), 100 deletions(-) diff --git a/controllers/auth_grpc.go b/controllers/auth_grpc.go index 511c8aa0..d457a2d1 100644 --- a/controllers/auth_grpc.go +++ b/controllers/auth_grpc.go @@ -103,7 +103,7 @@ func grpcAuthorize(ctx context.Context) error { return nil } -//Node authenticates using its password and retrieves a JWT for authorization. +// Login - node authenticates using its password and retrieves a JWT for authorization. func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) { //out := new(LoginResponse) @@ -117,15 +117,15 @@ func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nod password := reqNode.Password var result models.NodeAuth - - err := errors.New("Generic server error.") + var err error + // err := errors.New("generic server error") if macaddress == "" { //TODO: Set Error response - err = errors.New("Missing Mac Address.") + err = errors.New("missing mac address") return nil, err } else if password == "" { - err = errors.New("Missing Password.") + err = errors.New("missing password") return nil, err } else { //Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API until approved). @@ -156,7 +156,7 @@ func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nod return nil, err } if tokenString == "" { - err = errors.New("Something went wrong. Could not retrieve token.") + err = errors.New("something went wrong, could not retrieve token") return nil, err } diff --git a/controllers/dns_test.go b/controllers/dns_test.go index 659feedc..47070a9a 100644 --- a/controllers/dns_test.go +++ b/controllers/dns_test.go @@ -55,7 +55,7 @@ func TestGetNodeDNS(t *testing.T) { }) t.Run("MultipleNodes", func(t *testing.T) { createnode := &models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Endpoint: "10.100.100.3", MacAddress: "01:02:03:04:05:07", Password: "password", Network: "skynet"} - _, err := logic.CreateNode(createnode, "skynet") + err := logic.CreateNode(createnode) assert.Nil(t, err) dns, err := logic.GetNodeDNS("skynet") assert.Nil(t, err) diff --git a/controllers/ext_client.go b/controllers/ext_client.go index e8d30b76..d27f299b 100644 --- a/controllers/ext_client.go +++ b/controllers/ext_client.go @@ -232,8 +232,7 @@ func createExtClient(w http.ResponseWriter, r *http.Request) { returnErrorResponse(w, r, formatError(err, "internal")) return } - err = logic.CreateExtClient(extclient) - + err = logic.CreateExtClient(&extclient) if err != nil { returnErrorResponse(w, r, formatError(err, "internal")) return @@ -264,7 +263,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) { returnErrorResponse(w, r, formatError(err, "internal")) return } - newclient, err := logic.UpdateExtClient(newExtClient.ClientID, params["network"], oldExtClient) + newclient, err := logic.UpdateExtClient(newExtClient.ClientID, params["network"], &oldExtClient) if err != nil { returnErrorResponse(w, r, formatError(err, "internal")) return diff --git a/controllers/network_test.go b/controllers/network_test.go index 7f3bf3e8..81c75301 100644 --- a/controllers/network_test.go +++ b/controllers/network_test.go @@ -350,8 +350,3 @@ func createNet() { logic.CreateNetwork(network) } } - -func getNet() models.Network { - network, _ := logic.GetNetwork("skynet") - return network -} diff --git a/controllers/node.go b/controllers/node.go index 5a25913b..12727f1e 100644 --- a/controllers/node.go +++ b/controllers/node.go @@ -35,20 +35,17 @@ func nodeHandlers(r *mux.Router) { } -//Node authenticates using its password and retrieves a JWT for authorization. func authenticate(response http.ResponseWriter, request *http.Request) { var params = mux.Vars(request) networkname := params["network"] - //Auth request consists of Mac Address and Password (from node that is authorizing - //in case of Master, auth is ignored and mac is set to "mastermac" + var authRequest models.AuthParams var result models.Node var errorResponse = models.ErrorResponse{ Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.", } - //Get password fnd mac rom request decoder := json.NewDecoder(request.Body) decoderErr := decoder.Decode(&authRequest) defer request.Body.Close() @@ -70,7 +67,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) { return } else { - //Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API until approved). collection, err := database.FetchRecords(database.NODES_TABLE_NAME) if err != nil { errorResponse.Code = http.StatusBadRequest @@ -94,9 +90,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) { return } - //compare password from request to stored password in database - //might be able to have a common hash (certificates?) and compare those so that a password isn't passed in in plain text... - //TODO: Consider a way of hashing the password client side before sending, or using certificates err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password)) if err != nil { errorResponse.Code = http.StatusBadRequest @@ -104,7 +97,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) { returnErrorResponse(response, request, errorResponse) return } else { - //Create a new JWT for the node tokenString, _ := logic.CreateJWT(authRequest.MacAddress, result.Network) if tokenString == "" { @@ -122,7 +114,6 @@ func authenticate(response http.ResponseWriter, request *http.Request) { MacAddress: authRequest.MacAddress, }, } - //Send back the JWT successJSONResponse, jsonError := json.Marshal(successResponse) if jsonError != nil { @@ -185,10 +176,6 @@ func authorize(networkCheck bool, authNetwork string, next http.Handler) http.Ha return } - //This checks if - //A: the token is the master password - //B: the token corresponds to a mac address, and if so, which one - //TODO: There's probably a better way of dealing with the "master token"/master password. Plz Help. var isAuthorized = false var macaddress = "" username, networks, isadmin, errN := logic.VerifyUserToken(authToken) @@ -379,10 +366,10 @@ func createNode(w http.ResponseWriter, r *http.Request) { return } - var node = &models.Node{} + var node = models.Node{} //get node from body of request - err = json.NewDecoder(r.Body).Decode(node) + err = json.NewDecoder(r.Body).Decode(&node) if err != nil { returnErrorResponse(w, r, formatError(err, "internal")) return @@ -390,14 +377,12 @@ func createNode(w http.ResponseWriter, r *http.Request) { node.Network = networkName - network, err := logic.GetNetworkByNode(node) + network, err := logic.GetNetworkByNode(&node) if err != nil { returnErrorResponse(w, r, formatError(err, "internal")) return } - //Check to see if key is valid - //TODO: Triple inefficient!!! This is the third call to the DB we make for networks validKey := logic.IsKeyValid(networkName, node.AccessKey) if !validKey { @@ -414,7 +399,7 @@ func createNode(w http.ResponseWriter, r *http.Request) { } } - node, err = logic.CreateNode(node, networkName) + err = logic.CreateNode(&node) if err != nil { returnErrorResponse(w, r, formatError(err, "internal")) return @@ -476,6 +461,7 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) { } // == INGRESS == + func createIngressGateway(w http.ResponseWriter, r *http.Request) { var params = mux.Vars(r) w.Header().Set("Content-Type", "application/json") @@ -562,8 +548,6 @@ func updateNode(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(newNode) } -//Delete a node -//Pretty straightforward func deleteNode(w http.ResponseWriter, r *http.Request) { // Set header w.Header().Set("Content-Type", "application/json") diff --git a/controllers/node_grpc.go b/controllers/node_grpc.go index 80440470..8e9cd71f 100644 --- a/controllers/node_grpc.go +++ b/controllers/node_grpc.go @@ -49,49 +49,42 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (* // NodeServiceServer.CreateNode - creates a node and responds over gRPC func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) { - // Get the protobuf node type from the protobuf request type - // Essentially doing req.Node to access the struct with a nil check - var node = &models.Node{} + var node = models.Node{} + var err error data := req.GetData() - if err := json.Unmarshal([]byte(data), node); err != nil { + if err := json.Unmarshal([]byte(data), &node); err != nil { return nil, err } - //Check to see if key is valid - //TODO: Triple inefficient!!! This is the third call to the DB we make for networks validKey := logic.IsKeyValid(node.Network, node.AccessKey) - network, err := logic.GetParentNetwork(node.Network) + node.NetworkSettings, err = logic.GetNetworkSettings(node.Network) if err != nil { return nil, err } if !validKey { - //Check to see if network will allow manual sign up - //may want to switch this up with the valid key check and avoid a DB call that way. - if network.AllowManualSignUp == "yes" { + if node.NetworkSettings.AllowManualSignUp == "yes" { node.IsPending = "yes" } else { return nil, errors.New("invalid key, and network does not allow no-key signups") } } - node, err = logic.CreateNode(node, node.Network) - if err != nil { - return nil, err - } - node.NetworkSettings, err = logic.GetNetworkSettings(node.Network) + err = logic.CreateNode(&node) if err != nil { return nil, err } + nodeData, errN := json.Marshal(&node) if errN != nil { return nil, err } - // return the node in a CreateNodeRes type + response := &nodepb.Object{ Data: string(nodeData), Type: nodepb.NODE_TYPE, } + err = logic.SetNetworkNodesLastModified(node.Network) if err != nil { return nil, err diff --git a/controllers/node_test.go b/controllers/node_test.go index de2f5570..d1e6ae92 100644 --- a/controllers/node_test.go +++ b/controllers/node_test.go @@ -152,7 +152,7 @@ func deleteAllNodes() { } func createTestNode() *models.Node { - createnode := &models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Name: "testnode", Endpoint: "10.0.0.1", MacAddress: "01:02:03:04:05:06", Password: "password", Network: "skynet"} - node, _ := logic.CreateNode(createnode, "skynet") - return node + createnode := models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Name: "testnode", Endpoint: "10.0.0.1", MacAddress: "01:02:03:04:05:06", Password: "password", Network: "skynet"} + logic.CreateNode(&createnode) + return &createnode } diff --git a/controllers/server.go b/controllers/server.go index 64e21450..fc94b41d 100644 --- a/controllers/server.go +++ b/controllers/server.go @@ -60,10 +60,7 @@ func securityCheckServer(adminonly bool, next http.Handler) http.HandlerFunc { //Consider a more secure way of setting master key func authenticateMasterServer(tokenString string) bool { - if tokenString == servercfg.GetMasterKey() { - return true - } - return false + return tokenString == servercfg.GetMasterKey() } func removeNetwork(w http.ResponseWriter, r *http.Request) { diff --git a/logic/accesskeys.go b/logic/accesskeys.go index afae7cc2..0aedb4ee 100644 --- a/logic/accesskeys.go +++ b/logic/accesskeys.go @@ -196,6 +196,7 @@ func IsKeyValid(networkname string, keyvalue string) bool { return isvalid } +// RemoveKeySensitiveInfo - remove sensitive key info func RemoveKeySensitiveInfo(keys []models.AccessKey) []models.AccessKey { var returnKeys []models.AccessKey for _, key := range keys { diff --git a/logic/extpeers.go b/logic/extpeers.go index a6841487..2fba619d 100644 --- a/logic/extpeers.go +++ b/logic/extpeers.go @@ -114,7 +114,7 @@ func GetExtClient(clientid string, network string) (models.ExtClient, error) { } // CreateExtClient - creates an extclient -func CreateExtClient(extclient models.ExtClient) error { +func CreateExtClient(extclient *models.ExtClient) error { if extclient.PrivateKey == "" { privateKey, err := wgtypes.GeneratePrivateKey() if err != nil { @@ -155,7 +155,7 @@ func CreateExtClient(extclient models.ExtClient) error { } // UpdateExtClient - only supports name changes right now -func UpdateExtClient(newclientid string, network string, client models.ExtClient) (models.ExtClient, error) { +func UpdateExtClient(newclientid string, network string, client *models.ExtClient) (*models.ExtClient, error) { err := DeleteExtClient(network, client.ClientID) if err != nil { diff --git a/logic/networks.go b/logic/networks.go index a8d1464f..2398a85a 100644 --- a/logic/networks.go +++ b/logic/networks.go @@ -155,15 +155,15 @@ func GetParentNetwork(networkname string) (models.Network, error) { } // GetParentNetwork - get parent network -func GetNetworkSettings(networkname string) (*models.Network, error) { +func GetNetworkSettings(networkname string) (models.Network, error) { - var network *models.Network + var network models.Network networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname) if err != nil { return network, err } - if err = json.Unmarshal([]byte(networkData), network); err != nil { - return &models.Network{}, err + if err = json.Unmarshal([]byte(networkData), &network); err != nil { + return models.Network{}, err } network.AccessKeys = []models.AccessKey{} return network, nil diff --git a/logic/server.go b/logic/server.go index d6c8d4a7..f6f5213c 100644 --- a/logic/server.go +++ b/logic/server.go @@ -79,7 +79,7 @@ func ServerJoin(network string, serverID string, privateKey string) error { node.Network = network logger.Log(2, "adding a server instance on network", node.Network) - node, err = CreateNode(node, network) + err = CreateNode(node) if err != nil { return err } @@ -283,7 +283,7 @@ func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []stri // handle egress gateway peers if node.IsEgressGateway == "yes" { hasGateway = true - ranges := node.EgressGatewayRanges[:] + ranges := node.EgressGatewayRanges for _, iprange := range ranges { // go through each cidr for egress gateway _, ipnet, err := net.ParseCIDR(iprange) // confirming it's valid cidr if err != nil { diff --git a/logic/util.go b/logic/util.go index bd4077a2..62fd5070 100644 --- a/logic/util.go +++ b/logic/util.go @@ -76,18 +76,15 @@ func DeleteNode(node *models.Node, exterminate bool) error { } // CreateNode - creates a node in database -func CreateNode(node *models.Node, networkName string) (*models.Node, error) { +func CreateNode(node *models.Node) error { //encrypt that password so we never see it hash, err := bcrypt.GenerateFromPassword([]byte(node.Password), 5) - if err != nil { - return node, err + return err } //set password to encrypted password node.Password = string(hash) - - node.Network = networkName if node.Name == models.NODE_SERVER_NAME { node.IsServer = "yes" } @@ -99,35 +96,35 @@ func CreateNode(node *models.Node, networkName string) (*models.Node, error) { } } SetNodeDefaults(node) - node.Address, err = UniqueAddress(networkName) + node.Address, err = UniqueAddress(node.Network) if err != nil { - return node, err + return err } - node.Address6, err = UniqueAddress6(networkName) + node.Address6, err = UniqueAddress6(node.Network) if err != nil { - return node, err + return err } //Create a JWT for the node - tokenString, _ := CreateJWT(node.MacAddress, networkName) + tokenString, _ := CreateJWT(node.MacAddress, node.Network) if tokenString == "" { //returnErrorResponse(w, r, errorResponse) - return node, err + return err } err = ValidateNode(node, false) if err != nil { - return node, err + return err } key, err := GetRecordKey(node.MacAddress, node.Network) if err != nil { - return node, err + return err } nodebytes, err := json.Marshal(&node) if err != nil { - return node, err + return err } err = database.Insert(key, string(nodebytes), database.NODES_TABLE_NAME) if err != nil { - return node, err + return err } if node.IsPending != "yes" { DecrimentKey(node.Network, node.AccessKey) @@ -136,7 +133,7 @@ func CreateNode(node *models.Node, networkName string) (*models.Node, error) { if servercfg.IsDNSMode() { err = SetDNS() } - return node, err + return err } // SetNetworkNodesLastModified - sets the network nodes last modified diff --git a/logic/wireguard.go b/logic/wireguard.go index 51cbeaa5..eff360c6 100644 --- a/logic/wireguard.go +++ b/logic/wireguard.go @@ -300,6 +300,7 @@ func setWGConfig(node *models.Node, peerupdate bool) error { err = initWireguard(node, privkey, peers[:], hasGateway, gateways[:]) logger.Log(3, "finished setting wg config on server", node.Name) } + peers = nil return err } diff --git a/main.go b/main.go index 5bab2c9b..384302d7 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "log" "net" "os" "os/signal" @@ -38,8 +37,7 @@ func initialize() { // Client Mode Prereq Check var err error if err = database.InitializeDatabase(); err != nil { - logger.Log(0, "Error connecting to database") - log.Fatal(err) + logger.FatalLog("Error connecting to database") } logger.Log(0, "database successfully connected") @@ -134,16 +132,12 @@ func runGRPC(wg *sync.WaitGroup) { defer wg.Done() - // Configure 'log' package to give file name and line number on eg. log.Fatal - // Pipe flags to one another (log.LstdFLags = log.Ldate | log.Ltime) - log.SetFlags(log.LstdFlags | log.Lshortfile) - grpcport := servercfg.GetGRPCPort() listener, err := net.Listen("tcp", ":"+grpcport) // Handle errors if any if err != nil { - log.Fatalf("[netmaker] Unable to listen on port "+grpcport+", error: %v", err) + logger.FatalLog("[netmaker] Unable to listen on port", grpcport, ": error:", err.Error()) } s := grpc.NewServer( @@ -158,7 +152,7 @@ func runGRPC(wg *sync.WaitGroup) { // Start the server in a child routine go func() { if err := s.Serve(listener); err != nil { - log.Fatalf("Failed to serve: %v", err) + logger.FatalLog("Failed to serve:", err.Error()) } }() logger.Log(0, "Agent Server successfully started on port ", grpcport, "(gRPC)") diff --git a/models/node.go b/models/node.go index 099c10ae..c6dc623b 100644 --- a/models/node.go +++ b/models/node.go @@ -31,7 +31,7 @@ type Node struct { Address6 string `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"` LocalAddress string `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"` Name string `json:"name" bson:"name" yaml:"name" validate:"omitempty,max=62,in_charset"` - NetworkSettings *Network `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"` + NetworkSettings Network `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"` ListenPort int32 `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"` PublicKey string `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"` Endpoint string `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"` @@ -239,7 +239,7 @@ func (newNode *Node) Fill(currentNode *Node) { newNode.PostDown = currentNode.PostDown } if newNode.AllowedIPs == nil { - newNode.AllowedIPs = currentNode.AllowedIPs[:] + newNode.AllowedIPs = currentNode.AllowedIPs } if newNode.PersistentKeepalive == 0 { newNode.PersistentKeepalive = currentNode.PersistentKeepalive @@ -298,10 +298,10 @@ func (newNode *Node) Fill(currentNode *Node) { newNode.IsIngressGateway = currentNode.IsIngressGateway } if newNode.EgressGatewayRanges == nil { - newNode.EgressGatewayRanges = currentNode.EgressGatewayRanges[:] + newNode.EgressGatewayRanges = currentNode.EgressGatewayRanges } if newNode.IngressGatewayRange == "" { - newNode.IngressGatewayRange = currentNode.IngressGatewayRange[:] + newNode.IngressGatewayRange = currentNode.IngressGatewayRange } if newNode.IsStatic == "" { newNode.IsStatic = currentNode.IsStatic @@ -343,7 +343,7 @@ func (newNode *Node) Fill(currentNode *Node) { newNode.OS = currentNode.OS } if newNode.RelayAddrs == nil { - newNode.RelayAddrs = currentNode.RelayAddrs[:] + newNode.RelayAddrs = currentNode.RelayAddrs } if newNode.IsRelay == "" { newNode.IsRelay = currentNode.IsRelay diff --git a/models/structs.go b/models/structs.go index a368ac41..0742c516 100644 --- a/models/structs.go +++ b/models/structs.go @@ -85,7 +85,7 @@ type AccessKey struct { Name string `json:"name" bson:"name" validate:"omitempty,max=20"` Value string `json:"value" bson:"value" validate:"omitempty,alphanum,max=16"` AccessString string `json:"accessstring" bson:"accessstring"` - Uses int `json:"uses" bson:"uses"` + Uses int `json:"uses" bson:"uses" validate:"numeric,min=0"` } // DisplayKey - what is displayed for key diff --git a/netclient/config/config.go b/netclient/config/config.go index e704e607..91b8b8c0 100644 --- a/netclient/config/config.go +++ b/netclient/config/config.go @@ -122,7 +122,7 @@ func ModConfig(node *models.Node) error { } modconfig.Node = (*node) - modconfig.NetworkSettings = (*node.NetworkSettings) + modconfig.NetworkSettings = node.NetworkSettings err = Write(&modconfig, network) return err }