From 0cc8f629b5a8301d35e4a31c496ab1f2c9d8882c Mon Sep 17 00:00:00 2001 From: p0t4t0sandwich Date: Sun, 9 Jun 2024 01:36:39 -0600 Subject: [PATCH] Reworked Switchboard protocol some more --- modules/switchboard/encryption.go | 48 ++++++++ modules/switchboard/handler.go | 82 +++++++++++++ modules/switchboard/switchboard.go | 181 ----------------------------- modules/switchboard/types.go | 9 +- 4 files changed, 135 insertions(+), 185 deletions(-) create mode 100644 modules/switchboard/encryption.go create mode 100644 modules/switchboard/handler.go delete mode 100644 modules/switchboard/switchboard.go diff --git a/modules/switchboard/encryption.go b/modules/switchboard/encryption.go new file mode 100644 index 0000000..dc3fde3 --- /dev/null +++ b/modules/switchboard/encryption.go @@ -0,0 +1,48 @@ +package switchboard + +import ( + "github.com/NeuralNexusDev/neuralnexus-api/modules/encryption" + "github.com/goccy/go-json" +) + +// EncryptMessage encrypts a message +func EncryptMessage(message *Packet, key string) ([]byte, error) { + // Convert message to JSON + messageJSON, err := json.Marshal(message) + if err != nil { + return nil, err + } + + // Encrypt message + encryptedMessage, err := encryption.EncryptAES(messageJSON, key) + if err != nil { + return nil, err + } + + return encryptedMessage, nil +} + +// DecryptMessage decrypts a message +func DecryptMessage(encryptedMessage []byte, key string) (*Packet, error) { + // Decrypt message + decryptedMessage, err := encryption.DecryptAES(encryptedMessage, key) + + if err != nil { + return nil, err + } + + // Take off the padding at the front of the byte array + // Thanks google common for having nice byte buffers that add padding, + // In which case I forgot about it and it took me 2 hours to figure out why the message was not decrypting + // TODO: Convert Java-side to just plain ol byte arrays with no fancy helper classes + decryptedMessage = decryptedMessage[2:] + + // Convert message from JSON + var message Packet + err = json.Unmarshal(decryptedMessage, &message) + if err != nil { + return nil, err + } + + return &message, nil +} diff --git a/modules/switchboard/handler.go b/modules/switchboard/handler.go new file mode 100644 index 0000000..e7d66ac --- /dev/null +++ b/modules/switchboard/handler.go @@ -0,0 +1,82 @@ +package switchboard + +import ( + "log" + "net/http" + + "github.com/goccy/go-json" + "github.com/gorilla/websocket" +) + +// -------------- Globals -------------- +var ( + upgrader = websocket.Upgrader{} +) + +// -------------- Routes -------------- +// ApplyRoutes - Apply the routes +func ApplyRoutes(mux *http.ServeMux) *http.ServeMux { + // mux.HandleFunc("GET /ws/v1/switchboard/relay", ebSocketRelayHandler) + mux.HandleFunc("GET /websocket/{id}", WebSocketRelayHandler) + return mux +} + +// WebSocketRelayHandler relays switchboard messages +func WebSocketRelayHandler(w http.ResponseWriter, r *http.Request) { + ws, err := upgrader.Upgrade(w, r, nil) + if err != nil { + log.Println(err.Error()) + return + } + defer ws.Close() + + for { + // Write + packet := &Packet{ + Header: Header{ + Version: 1, + Origin: "server", + Dest: "client", + }, + Body: Body{ + MessageID: "1", + MessageType: "message", + Encrypted: true, + EncScheme: "AES", + Content: "Hello, client!", + }, + } + var packetBuffer []byte + if packet.Body.Encrypted { + packetBuffer, err = EncryptMessage(packet, "dgwjgsemfouvauxc") + if err != nil { + log.Println(err.Error()) + } + } else { + packetBuffer, err = json.Marshal(packet) + if err != nil { + log.Println(err.Error()) + } + } + + err = ws.WriteMessage(websocket.BinaryMessage, packetBuffer) + if err != nil { + log.Println(err.Error()) + } + + // Read + msgType, msg, err := ws.ReadMessage() + + if err != nil { + log.Println(err.Error()) + } else if msgType != websocket.BinaryMessage { + log.Println("Message type is not binary") + } + + packet, err = DecryptMessage(msg, "dgwjgsemfouvauxc") + if err != nil { + log.Println(err.Error()) + } + log.Println(packet.Body.Content) + } +} diff --git a/modules/switchboard/switchboard.go b/modules/switchboard/switchboard.go deleted file mode 100644 index 75e1b1d..0000000 --- a/modules/switchboard/switchboard.go +++ /dev/null @@ -1,181 +0,0 @@ -package switchboard - -import ( - "log" - "net/http" - - "github.com/NeuralNexusDev/neuralnexus-api/modules/encryption" - "github.com/goccy/go-json" - "github.com/gorilla/websocket" -) - -// -------------- Globals -------------- -var ( - upgrader = websocket.Upgrader{} -) - -// -------------- Structs -------------- - -type Message struct { - Sender MessageSender `json:"sender"` - Channel MessageType `json:"channel"` - Message string `json:"message"` - TimeStamp int64 `json:"timestamp"` - PlaceHolderMessage string `json:"placeHolderMessage"` - PlaceHolders map[string]string `json:"placeholders"` - IsRemote bool `json:"isRemote"` - IsGlobal bool `json:"isGlobal"` -} - -type MessageSender struct { - Name string `json:"name"` - Prefix string `json:"prefix"` - Suffix string `json:"suffix"` - DisplayName string `json:"displayName"` - UUID string `json:"uuid"` - Server SimpleServer `json:"server"` -} - -type SimpleServer struct { - Name string `json:"name"` -} - -// -------------- Enums -------------- - -// MessageType -type MessageType string - -var ( - MessageTypeMap = map[string]string{ - "PLAYER_ADVANCEMENT_FINISHED": "tc:p_adv_fin", - "PLAYER_DEATH": "tc:p_death", - "PLAYER_LOGIN": "tc:p_login", - "PLAYER_LOGOUT": "tc:p_logout", - "PLAYER_MESSAGE": "tc:p_msg", - "SERVER_STARTED": "tc:s_start", - "SERVER_STOPPED": "tc:s_stop", - "CUSTOM": "tc:custom", - } - - MessageTypeMapReverse = map[string]string{ - "tc:p_adv_fin": "PLAYER_ADVANCEMENT_FINISHED", - "tc:p_death": "PLAYER_DEATH", - "tc:p_login": "PLAYER_LOGIN", - "tc:p_logout": "PLAYER_LOGOUT", - "tc:p_msg": "PLAYER_MESSAGE", - "tc:s_start": "SERVER_STARTED", - "tc:s_stop": "SERVER_STOPPED", - "tc:custom": "CUSTOM", - } -) - -func (mt MessageType) String() string { - if val, ok := MessageTypeMapReverse[string(mt)]; ok { - return val - } - return "CUSTOM" -} - -// -------------- Functions -------------- - -// EncryptMessage encrypts a message -func EncryptMessage(message Message, key string) ([]byte, error) { - // Convert message to JSON - messageJSON, err := json.Marshal(message) - if err != nil { - return nil, err - } - - // Encrypt message - encryptedMessage, err := encryption.EncryptAES(messageJSON, key) - if err != nil { - return nil, err - } - - return encryptedMessage, nil -} - -// DecryptMessage decrypts a message -func DecryptMessage(encryptedMessage []byte, key string) (Message, error) { - // Decrypt message - decryptedMessage, err := encryption.DecryptAES(encryptedMessage, key) - - if err != nil { - return Message{}, err - } - - // Take off the padding at the front of the byte array - // Thanks google common for having nice byte buffers that add padding, - // In which case I forgot about it and it took me 2 hours to figure out why the message was not decrypting - // TODO: Convert Java-side to just plain ol byte arrays with no fancy helper classes - decryptedMessage = decryptedMessage[2:] - - // Convert message from JSON - var message Message - err = json.Unmarshal(decryptedMessage, &message) - if err != nil { - return Message{}, err - } - - return message, nil -} - -// -------------- Routes -------------- -// ApplyRoutes - Apply the routes -func ApplyRoutes(mux *http.ServeMux) *http.ServeMux { - // mux.HandleFunc("GET /ws/v1/switchboard/relay", ebSocketRelayHandler) - mux.HandleFunc("GET /websocket/{id}", WebSocketRelayHandler) - return mux -} - -// WebSocketRelayHandler relays switchboard messages -func WebSocketRelayHandler(w http.ResponseWriter, r *http.Request) { - ws, err := upgrader.Upgrade(w, r, nil) - if err != nil { - log.Println(err.Error()) - return - } - defer ws.Close() - - for { - // Write - message := Message{ - Sender: MessageSender{ - Name: "NeuralNexus", - Prefix: "§7", - Suffix: "§r", - DisplayName: "NeuralNexus", - UUID: "00000000-0000-0000-0000-000000000000", - Server: SimpleServer{ - Name: "NeuralNexus", - }, - }, - Channel: MessageType("PLAYER_MESSAGE"), - Message: "Hello, world!", - } - encryptedMessage, err := EncryptMessage(message, "dgwjgsemfouvauxc") - if err != nil { - log.Println(err.Error()) - } - - err = ws.WriteMessage(websocket.BinaryMessage, encryptedMessage) - if err != nil { - log.Println(err.Error()) - } - - // Read - msgType, msg, err := ws.ReadMessage() - - if err != nil { - log.Println(err.Error()) - } else if msgType != websocket.BinaryMessage { - log.Println("Message type is not binary") - } - - message, err = DecryptMessage(msg, "dgwjgsemfouvauxc") - if err != nil { - log.Println(err.Error()) - } - log.Println(message.Message) - } -} diff --git a/modules/switchboard/types.go b/modules/switchboard/types.go index 2d5e9b3..5bcd102 100644 --- a/modules/switchboard/types.go +++ b/modules/switchboard/types.go @@ -7,10 +7,11 @@ type Header struct { } type Body struct { - MessageID string `json:"message_id"` - Encrypted bool `json:"encrypted,omitempty"` - EncScheme string `json:"enc_scheme,omitempty"` - Content string `json:"content"` + MessageID string `json:"message_id"` + MessageType string `json:"message_type,omitempty"` + Encrypted bool `json:"encrypted,omitempty"` + EncScheme string `json:"enc_scheme,omitempty"` + Content string `json:"content"` } type Packet struct {