From 4ffb17604982eb60963e88b4f304a9a3c9ad787f Mon Sep 17 00:00:00 2001 From: wish Date: Mon, 10 Apr 2023 18:52:12 +1000 Subject: [PATCH] prevent reading past message board packet --- .../msg_mhf_update_guild_message_board.go | 42 ++++++++++++++++--- server/channelserver/handlers_guild.go | 36 ++++------------ 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/network/mhfpacket/msg_mhf_update_guild_message_board.go b/network/mhfpacket/msg_mhf_update_guild_message_board.go index b8c4ee5e0..94316cc52 100644 --- a/network/mhfpacket/msg_mhf_update_guild_message_board.go +++ b/network/mhfpacket/msg_mhf_update_guild_message_board.go @@ -2,6 +2,7 @@ package mhfpacket import ( "errors" + "erupe-ce/common/stringsupport" "erupe-ce/common/byteframe" "erupe-ce/network" @@ -10,9 +11,16 @@ import ( // MsgMhfUpdateGuildMessageBoard represents the MSG_MHF_UPDATE_GUILD_MESSAGE_BOARD type MsgMhfUpdateGuildMessageBoard struct { - AckHandle uint32 - MessageOp uint32 - Request []byte + AckHandle uint32 + MessageOp uint32 + PostType uint32 + StampID uint32 + TitleLength uint32 + BodyLength uint32 + Title string + Body string + PostID uint32 + LikeState bool } // Opcode returns the ID associated with this packet type. @@ -24,9 +32,31 @@ func (m *MsgMhfUpdateGuildMessageBoard) Opcode() network.PacketID { func (m *MsgMhfUpdateGuildMessageBoard) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.MessageOp = bf.ReadUint32() - if m.MessageOp != 5 { - m.Request = bf.DataFromCurrent() - bf.Seek(int64(len(bf.Data())-2), 0) + switch m.MessageOp { + case 0: + m.PostType = bf.ReadUint32() + m.StampID = bf.ReadUint32() + m.TitleLength = bf.ReadUint32() + m.BodyLength = bf.ReadUint32() + m.Title = stringsupport.SJISToUTF8(bf.ReadBytes(uint(m.TitleLength))) + m.Body = stringsupport.SJISToUTF8(bf.ReadBytes(uint(m.BodyLength))) + case 1: + m.PostID = bf.ReadUint32() + case 2: + m.PostID = bf.ReadUint32() + bf.ReadBytes(8) + m.TitleLength = bf.ReadUint32() + m.BodyLength = bf.ReadUint32() + m.Title = stringsupport.SJISToUTF8(bf.ReadBytes(uint(m.TitleLength))) + m.Body = stringsupport.SJISToUTF8(bf.ReadBytes(uint(m.BodyLength))) + case 3: + m.PostID = bf.ReadUint32() + bf.ReadBytes(8) + m.StampID = bf.ReadUint32() + case 4: + m.PostID = bf.ReadUint32() + bf.ReadBytes(8) + m.LikeState = bf.ReadBool() } return nil } diff --git a/server/channelserver/handlers_guild.go b/server/channelserver/handlers_guild.go index a804932d0..7eca11a16 100644 --- a/server/channelserver/handlers_guild.go +++ b/server/channelserver/handlers_guild.go @@ -1867,7 +1867,6 @@ func handleMsgMhfEnumerateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfUpdateGuildMessageBoard) - bf := byteframe.NewByteFrameFromBytes(pkt.Request) guild, err := GetGuildInfoByCharacterId(s, s.charID) applicant := false if guild != nil { @@ -1879,45 +1878,26 @@ func handleMsgMhfUpdateGuildMessageBoard(s *Session, p mhfpacket.MHFPacket) { } switch pkt.MessageOp { case 0: // Create message - postType := bf.ReadUint32() // 0 = message, 1 = news - stampID := bf.ReadUint32() - titleLength := bf.ReadUint32() - bodyLength := bf.ReadUint32() - title := stringsupport.SJISToUTF8(bf.ReadBytes(uint(titleLength))) - body := stringsupport.SJISToUTF8(bf.ReadBytes(uint(bodyLength))) - s.server.db.Exec("INSERT INTO guild_posts (guild_id, author_id, stamp_id, post_type, title, body) VALUES ($1, $2, $3, $4, $5, $6)", guild.ID, s.charID, stampID, postType, title, body) + s.server.db.Exec("INSERT INTO guild_posts (guild_id, author_id, stamp_id, post_type, title, body) VALUES ($1, $2, $3, $4, $5, $6)", guild.ID, s.charID, pkt.StampID, pkt.PostType, pkt.Title, pkt.Body) // TODO: if there are too many messages, purge excess case 1: // Delete message - postID := bf.ReadUint32() - s.server.db.Exec("DELETE FROM guild_posts WHERE id = $1", postID) + s.server.db.Exec("DELETE FROM guild_posts WHERE id = $1", pkt.PostID) case 2: // Update message - postID := bf.ReadUint32() - bf.ReadBytes(8) - titleLength := bf.ReadUint32() - bodyLength := bf.ReadUint32() - title := stringsupport.SJISToUTF8(bf.ReadBytes(uint(titleLength))) - body := stringsupport.SJISToUTF8(bf.ReadBytes(uint(bodyLength))) - s.server.db.Exec("UPDATE guild_posts SET title = $1, body = $2 WHERE id = $3", title, body, postID) + s.server.db.Exec("UPDATE guild_posts SET title = $1, body = $2 WHERE id = $3", pkt.Title, pkt.Body, pkt.PostID) case 3: // Update stamp - postID := bf.ReadUint32() - bf.ReadBytes(8) - stampID := bf.ReadUint32() - s.server.db.Exec("UPDATE guild_posts SET stamp_id = $1 WHERE id = $2", stampID, postID) + s.server.db.Exec("UPDATE guild_posts SET stamp_id = $1 WHERE id = $2", pkt.StampID, pkt.PostID) case 4: // Like message - postID := bf.ReadUint32() - bf.ReadBytes(8) - likeState := bf.ReadBool() var likedBy string - err := s.server.db.QueryRow("SELECT liked_by FROM guild_posts WHERE id = $1", postID).Scan(&likedBy) + err := s.server.db.QueryRow("SELECT liked_by FROM guild_posts WHERE id = $1", pkt.PostID).Scan(&likedBy) if err != nil { s.logger.Error("Failed to get guild message like data from db", zap.Error(err)) } else { - if likeState { + if pkt.LikeState { likedBy = stringsupport.CSVAdd(likedBy, int(s.charID)) - s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE id = $2", likedBy, postID) + s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE id = $2", likedBy, pkt.PostID) } else { likedBy = stringsupport.CSVRemove(likedBy, int(s.charID)) - s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE id = $2", likedBy, postID) + s.server.db.Exec("UPDATE guild_posts SET liked_by = $1 WHERE id = $2", likedBy, pkt.PostID) } } case 5: // Check for new messages