Browse Source

Merge pull request #772 from gravitl/feature_v0.10.1_chunking_0

Feature v0.10.1 chunking 0
Matthew R Kasun 3 years ago
parent
commit
6c583567d4
5 changed files with 125 additions and 34 deletions
  1. 5 4
      mq/mq.go
  2. 12 3
      mq/util.go
  3. 3 3
      netclient/functions/daemon.go
  4. 105 0
      netclient/ncutils/encryption.go
  5. 0 24
      netclient/ncutils/netclientutils.go

+ 5 - 4
mq/mq.go

@@ -53,12 +53,13 @@ func Ping(client mqtt.Client, msg mqtt.Message) {
 		}
 		}
 		_, decryptErr := decryptMsg(&node, msg.Payload())
 		_, decryptErr := decryptMsg(&node, msg.Payload())
 		if decryptErr != nil {
 		if decryptErr != nil {
-			logger.Log(0, "error updating node ", node.ID, err.Error())
+			logger.Log(0, "error decrypting when updating node ", node.ID, decryptErr.Error())
 			return
 			return
 		}
 		}
 		node.SetLastCheckIn()
 		node.SetLastCheckIn()
 		if err := logic.UpdateNode(&node, &node); err != nil {
 		if err := logic.UpdateNode(&node, &node); err != nil {
-			logger.Log(0, "error updating node ", err.Error())
+			logger.Log(0, "error updating node", node.Name, node.ID, " on checkin", err.Error())
+			return
 		}
 		}
 		logger.Log(3, "ping processed for node", node.ID)
 		logger.Log(3, "ping processed for node", node.ID)
 		// --TODO --set client version once feature is implemented.
 		// --TODO --set client version once feature is implemented.
@@ -84,7 +85,6 @@ func UpdateNode(client mqtt.Client, msg mqtt.Message) {
 			logger.Log(1, "failed to decrypt message for node ", id, decryptErr.Error())
 			logger.Log(1, "failed to decrypt message for node ", id, decryptErr.Error())
 			return
 			return
 		}
 		}
-		logger.Log(1, "Update Node Handler", id)
 		var newNode models.Node
 		var newNode models.Node
 		if err := json.Unmarshal(decrypted, &newNode); err != nil {
 		if err := json.Unmarshal(decrypted, &newNode); err != nil {
 			logger.Log(1, "error unmarshaling payload ", err.Error())
 			logger.Log(1, "error unmarshaling payload ", err.Error())
@@ -92,12 +92,13 @@ func UpdateNode(client mqtt.Client, msg mqtt.Message) {
 		}
 		}
 		if err := logic.UpdateNode(&currentNode, &newNode); err != nil {
 		if err := logic.UpdateNode(&currentNode, &newNode); err != nil {
 			logger.Log(1, "error saving node", err.Error())
 			logger.Log(1, "error saving node", err.Error())
+			return
 		}
 		}
 		if err := PublishPeerUpdate(&newNode); err != nil {
 		if err := PublishPeerUpdate(&newNode); err != nil {
 			logger.Log(1, "error publishing peer update ", err.Error())
 			logger.Log(1, "error publishing peer update ", err.Error())
 			return
 			return
 		}
 		}
-		logger.Log(1, "no need to update peers")
+		logger.Log(1, "Updated node", id, newNode.Name)
 	}()
 	}()
 }
 }
 
 

+ 12 - 3
mq/util.go

@@ -2,6 +2,7 @@ package mq
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"strings"
 
 
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/models"
@@ -10,7 +11,7 @@ import (
 
 
 func decryptMsg(node *models.Node, msg []byte) ([]byte, error) {
 func decryptMsg(node *models.Node, msg []byte) ([]byte, error) {
 	if len(msg) <= 24 { // make sure message is of appropriate length
 	if len(msg) <= 24 { // make sure message is of appropriate length
-		return nil, fmt.Errorf("recieved invalid message from broker %s", string(msg))
+		return nil, fmt.Errorf("recieved invalid message from broker %v", msg)
 	}
 	}
 
 
 	trafficKey, trafficErr := logic.RetrievePrivateTrafficKey() // get server private key
 	trafficKey, trafficErr := logic.RetrievePrivateTrafficKey() // get server private key
@@ -26,7 +27,11 @@ func decryptMsg(node *models.Node, msg []byte) ([]byte, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	return ncutils.BoxDecrypt(msg, nodePubTKey, serverPrivTKey)
+	if strings.Contains(node.Version, "0.10.0") {
+		return ncutils.BoxDecrypt(msg, nodePubTKey, serverPrivTKey)
+	}
+
+	return ncutils.DeChunk(msg, nodePubTKey, serverPrivTKey)
 }
 }
 
 
 func encryptMsg(node *models.Node, msg []byte) ([]byte, error) {
 func encryptMsg(node *models.Node, msg []byte) ([]byte, error) {
@@ -46,7 +51,11 @@ func encryptMsg(node *models.Node, msg []byte) ([]byte, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	return ncutils.BoxEncrypt(msg, nodePubKey, serverPrivKey)
+	if strings.Contains(node.Version, "0.10.0") {
+		return ncutils.BoxEncrypt(msg, nodePubKey, serverPrivKey)
+	}
+
+	return ncutils.Chunk(msg, nodePubKey, serverPrivKey)
 }
 }
 
 
 func publish(node *models.Node, dest string, msg []byte) error {
 func publish(node *models.Node, dest string, msg []byte) error {

+ 3 - 3
netclient/functions/daemon.go

@@ -553,7 +553,7 @@ func publish(cfg *config.ClientConfig, dest string, msg []byte) error {
 
 
 	client := SetupMQTT(cfg, true)
 	client := SetupMQTT(cfg, true)
 	defer client.Disconnect(250)
 	defer client.Disconnect(250)
-	encrypted, err := ncutils.BoxEncrypt(msg, serverPubKey, trafficPrivKey)
+	encrypted, err := ncutils.Chunk(msg, serverPubKey, trafficPrivKey)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -570,7 +570,7 @@ func parseNetworkFromTopic(topic string) string {
 
 
 func decryptMsg(cfg *config.ClientConfig, msg []byte) ([]byte, error) {
 func decryptMsg(cfg *config.ClientConfig, msg []byte) ([]byte, error) {
 	if len(msg) <= 24 { // make sure message is of appropriate length
 	if len(msg) <= 24 { // make sure message is of appropriate length
-		return nil, fmt.Errorf("recieved invalid message from broker %s", string(msg))
+		return nil, fmt.Errorf("recieved invalid message from broker %v", msg)
 	}
 	}
 
 
 	// setup the keys
 	// setup the keys
@@ -584,7 +584,7 @@ func decryptMsg(cfg *config.ClientConfig, msg []byte) ([]byte, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	return ncutils.BoxDecrypt(msg, serverPubKey, diskKey)
+	return ncutils.DeChunk(msg, serverPubKey, diskKey)
 }
 }
 
 
 func pingServer(cfg *config.ClientConfig) error {
 func pingServer(cfg *config.ClientConfig) error {

+ 105 - 0
netclient/ncutils/encryption.go

@@ -0,0 +1,105 @@
+package ncutils
+
+import (
+	"bytes"
+	"crypto/rand"
+	"fmt"
+	"io"
+
+	"golang.org/x/crypto/nacl/box"
+)
+
+const (
+	chunkSize = 16000 // 16000 bytes max message size
+)
+
+// BoxEncrypt - encrypts traffic box
+func BoxEncrypt(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
+	var nonce [24]byte // 192 bits of randomization
+	if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
+		return nil, err
+	}
+
+	encrypted := box.Seal(nonce[:], message, &nonce, recipientPubKey, senderPrivateKey)
+	return encrypted, nil
+}
+
+// BoxDecrypt - decrypts traffic box
+func BoxDecrypt(encrypted []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
+	var decryptNonce [24]byte
+	copy(decryptNonce[:], encrypted[:24])
+	decrypted, ok := box.Open(nil, encrypted[24:], &decryptNonce, senderPublicKey, recipientPrivateKey)
+	if !ok {
+		return nil, fmt.Errorf("could not decrypt message, %v", encrypted)
+	}
+	return decrypted, nil
+}
+
+// Chunk - chunks a message and encrypts each chunk
+func Chunk(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
+	var chunks [][]byte
+	for i := 0; i < len(message); i += chunkSize {
+		end := i + chunkSize
+
+		if end > len(message) {
+			end = len(message)
+		}
+
+		encryptedMsgSlice, err := BoxEncrypt(message[i:end], recipientPubKey, senderPrivateKey)
+		if err != nil {
+			return nil, err
+		}
+
+		chunks = append(chunks, encryptedMsgSlice)
+	}
+
+	chunkedMsg, err := convertBytesToMsg(chunks) // encode the array into some bytes to decode on receiving end
+	if err != nil {
+		return nil, err
+	}
+
+	return chunkedMsg, nil
+}
+
+// DeChunk - "de" chunks and decrypts a message
+func DeChunk(chunkedMsg []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
+	chunks, err := convertMsgToBytes(chunkedMsg) // convert the message to it's original chunks form
+	if err != nil {
+		return nil, err
+	}
+
+	var totalMsg []byte
+	for i := range chunks {
+		decodedMsg, err := BoxDecrypt(chunks[i], senderPublicKey, recipientPrivateKey)
+		if err != nil {
+			return nil, err
+		}
+		totalMsg = append(totalMsg, decodedMsg...)
+	}
+	return totalMsg, nil
+}
+
+// == private ==
+
+var splitKey = []byte("|(,)(,)|")
+
+// ConvertMsgToBytes - converts a message (MQ) to it's chunked version
+// decode action
+func convertMsgToBytes(msg []byte) ([][]byte, error) {
+	splitMsg := bytes.Split(msg, splitKey)
+	return splitMsg, nil
+}
+
+// ConvertBytesToMsg - converts the chunked message into a MQ message
+// encode action
+func convertBytesToMsg(b [][]byte) ([]byte, error) {
+
+	var buffer []byte  // allocate a buffer with adequate sizing
+	for i := range b { // append bytes to it with key
+		buffer = append(buffer, b[i]...)
+		if i != len(b)-1 {
+			buffer = append(buffer, splitKey...)
+		}
+	}
+	return buffer, nil
+}

+ 0 - 24
netclient/ncutils/netclientutils.go

@@ -2,7 +2,6 @@ package ncutils
 
 
 import (
 import (
 	"bytes"
 	"bytes"
-	crand "crypto/rand"
 	"crypto/tls"
 	"crypto/tls"
 	"encoding/gob"
 	"encoding/gob"
 	"errors"
 	"errors"
@@ -22,7 +21,6 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/models"
-	"golang.org/x/crypto/nacl/box"
 	"golang.zx2c4.com/wireguard/wgctrl"
 	"golang.zx2c4.com/wireguard/wgctrl"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc"
@@ -613,28 +611,6 @@ func ServerAddrSliceContains(slice []models.ServerAddr, item models.ServerAddr)
 	return false
 	return false
 }
 }
 
 
-// BoxEncrypt - encrypts traffic box
-func BoxEncrypt(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
-	var nonce [24]byte // 192 bits of randomization
-	if _, err := io.ReadFull(crand.Reader, nonce[:]); err != nil {
-		return nil, err
-	}
-
-	encrypted := box.Seal(nonce[:], message, &nonce, recipientPubKey, senderPrivateKey)
-	return encrypted, nil
-}
-
-// BoxDecrypt - decrypts traffic box
-func BoxDecrypt(encrypted []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
-	var decryptNonce [24]byte
-	copy(decryptNonce[:], encrypted[:24])
-	decrypted, ok := box.Open(nil, encrypted[24:], &decryptNonce, senderPublicKey, recipientPrivateKey)
-	if !ok {
-		return nil, fmt.Errorf("could not decrypt message")
-	}
-	return decrypted, nil
-}
-
 // MakeRandomString - generates a random string of len n
 // MakeRandomString - generates a random string of len n
 func MakeRandomString(n int) string {
 func MakeRandomString(n int) string {
 	sb := strings.Builder{}
 	sb := strings.Builder{}