From c08135309f803585d902b352d2e865bdd718afd7 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 6 Aug 2025 15:41:25 +0300 Subject: [PATCH] add random salt and result/error checksum --- internal/server/gateway/route.go | 8 +++--- internal/server/rpc/definition.go | 11 ++++++--- internal/server/rpc/writers.go | 39 ++++++++++++++++++++++++++---- internal/server/sv1/lua_handler.go | 9 ++----- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/internal/server/gateway/route.go b/internal/server/gateway/route.go index 18de8cc..b18d5cc 100644 --- a/internal/server/gateway/route.go +++ b/internal/server/gateway/route.go @@ -26,7 +26,7 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Session-UUID", sessionUUID) if !gs.sm.Add(sessionUUID) { gs.x.SLog.Debug("session is busy", slog.String("session-uuid", sessionUUID)) - rpc.WriteError(w, &rpc.RPCResponse{ + rpc.WriteError(gs.cs.UUID32, w, &rpc.RPCResponse{ Error: map[string]any{ "code": rpc.ErrSessionIsBusy, "message": rpc.ErrSessionIsBusyS, @@ -40,7 +40,7 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) { if err != nil { gs.x.SLog.Debug("failed to read body", slog.String("err", err.Error())) w.WriteHeader(http.StatusBadRequest) - rpc.WriteError(w, &rpc.RPCResponse{ + rpc.WriteError(gs.cs.UUID32, w, &rpc.RPCResponse{ JSONRPC: rpc.JSONRPCVersion, ID: nil, Error: map[string]any{ @@ -60,7 +60,7 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) { if err := json.Unmarshal(body, &single); err != nil { gs.x.SLog.Debug("failed to parse json", slog.String("err", err.Error())) w.WriteHeader(http.StatusBadRequest) - rpc.WriteError(w, &rpc.RPCResponse{ + rpc.WriteError(gs.cs.UUID32, w, &rpc.RPCResponse{ JSONRPC: rpc.JSONRPCVersion, ID: nil, Error: map[string]any{ @@ -76,7 +76,7 @@ func (gs *GatewayServer) Handle(w http.ResponseWriter, r *http.Request) { w.Write([]byte("")) return } - rpc.WriteResponse(w, resp) + rpc.WriteResponse(gs.cs.UUID32, w, resp) return } diff --git a/internal/server/rpc/definition.go b/internal/server/rpc/definition.go index 68039f7..426c266 100644 --- a/internal/server/rpc/definition.go +++ b/internal/server/rpc/definition.go @@ -11,10 +11,13 @@ type RPCRequest struct { } type RPCResponse struct { - JSONRPC string `json:"jsonrpc"` - ID *json.RawMessage `json:"id"` - Result any `json:"result,omitempty"` - Error any `json:"error,omitempty"` + JSONRPC string `json:"jsonrpc"` + ID *json.RawMessage `json:"id"` + Result any `json:"result,omitempty"` + Error any `json:"error,omitempty"` + ResponsibleNode string `json:"responsible-node,omitempty"` + Salt string `json:"salt,omitempty"` + Checksum string `json:"checksum,omitempty"` } const ( diff --git a/internal/server/rpc/writers.go b/internal/server/rpc/writers.go index aa1c519..e02bbd8 100644 --- a/internal/server/rpc/writers.go +++ b/internal/server/rpc/writers.go @@ -1,11 +1,40 @@ package rpc import ( + "crypto/md5" "encoding/json" + "fmt" "net/http" + + "github.com/google/uuid" ) -func write(w http.ResponseWriter, msg *RPCResponse) error { +func generateChecksum(result any) string { + if result == nil { + return "" + } + data, err := json.Marshal(result) + if err != nil { + return "" + } + return fmt.Sprintf("%x", md5.Sum(data)) +} + +func generateSalt() string { + return uuid.NewString() +} + +func write(nid string, w http.ResponseWriter, msg *RPCResponse) error { + msg.Salt = generateSalt() + if msg.Result != nil { + msg.Checksum = generateChecksum(msg.Result) + } else { + msg.Checksum = generateChecksum(msg.Error) + } + + if nid != "" { + msg.ResponsibleNode = nid + } data, err := json.Marshal(msg) if err != nil { return err @@ -14,10 +43,10 @@ func write(w http.ResponseWriter, msg *RPCResponse) error { return err } -func WriteError(w http.ResponseWriter, errm *RPCResponse) error { - return write(w, errm) +func WriteError(nid string, w http.ResponseWriter, errm *RPCResponse) error { + return write(nid, w, errm) } -func WriteResponse(w http.ResponseWriter, response *RPCResponse) error { - return write(w, response) +func WriteResponse(nid string, w http.ResponseWriter, response *RPCResponse) error { + return write(nid, w, response) } diff --git a/internal/server/sv1/lua_handler.go b/internal/server/sv1/lua_handler.go index 7837b66..c82c622 100644 --- a/internal/server/sv1/lua_handler.go +++ b/internal/server/sv1/lua_handler.go @@ -447,17 +447,13 @@ func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest, sessionVal := loadedTbl.RawGetString("internal.session") sessionTbl, ok := sessionVal.(*lua.LTable) if !ok { - return rpc.NewResponse(map[string]any{ - "responsible-node": h.cs.UUID32, - }, req.ID) + return rpc.NewResponse(nil, req.ID) } tag := sessionTbl.RawGetString("__gosally_internal") if tag.Type() != lua.LTString || tag.String() != fmt.Sprint(seed) { llog.Debug("stock session module is not imported: wrong seed", slog.String("script", path)) - return rpc.NewResponse(map[string]any{ - "responsible-node": h.cs.UUID32, - }, req.ID) + return rpc.NewResponse(nil, req.ID) } outVal := sessionTbl.RawGetString("response") @@ -500,6 +496,5 @@ func (h *HandlerV1) handleLUA(sid string, r *http.Request, req *rpc.RPCRequest, } else { payload["message"] = ConvertLuaTypesToGolang(resultVal) } - payload["responsible-node"] = h.cs.UUID32 return rpc.NewResponse(payload, req.ID) }