From 6f70dd1bafa64a30239d35ad4ee9ce4b325efe89 Mon Sep 17 00:00:00 2001 From: mkwcat Date: Wed, 22 Nov 2023 00:45:22 -0500 Subject: [PATCH] GPCM: Fix relogin requirement after adding friends --- gpcm/friend.go | 32 +++++++++++++++++++++++++++++++- gpcm/main.go | 34 ++++++++++++++++++---------------- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/gpcm/friend.go b/gpcm/friend.go index 05ed444..27072f3 100644 --- a/gpcm/friend.go +++ b/gpcm/friend.go @@ -17,6 +17,15 @@ func (g *GameSpySession) isFriendAdded(profileId uint32) bool { return false } +func (g *GameSpySession) isFriendAuthorized(profileId uint32) bool { + for _, storedPid := range g.AuthFriendList { + if storedPid == profileId { + return true + } + } + return false +} + func (g *GameSpySession) addFriend(command common.GameSpyCommand) { strNewProfileId := command.OtherValues["newprofileid"] newProfileId, err := strconv.ParseUint(strNewProfileId, 10, 32) @@ -41,7 +50,8 @@ func (g *GameSpySession) addFriend(command common.GameSpyCommand) { fc := common.CalcFriendCodeString(uint32(newProfileId), "RMCJ") logging.Notice(g.ModuleName, "Add friend:", aurora.Cyan(strNewProfileId), aurora.Cyan(fc)) - if g.isFriendAdded(uint32(newProfileId)) { + if g.isFriendAuthorized(uint32(newProfileId)) { + logging.Warn(g.ModuleName, "Attempt to add a friend who is already authorized") g.replyError(1539) return } @@ -51,6 +61,24 @@ func (g *GameSpySession) addFriend(command common.GameSpyCommand) { // TODO: Add a limit g.FriendList = append(g.FriendList, uint32(newProfileId)) + + // Check if destination has added the sender + newSession, ok := sessions[uint32(newProfileId)] + if !ok || newSession == nil || !newSession.LoggedIn { + logging.Info(g.ModuleName, "Destination is not online") + return + } + + if !newSession.isFriendAdded(g.User.ProfileId) { + // Not an error, just ignore for now + logging.Info(g.ModuleName, "Destination has not added sender") + return + } + + // Friends are now mutual! + // TODO: Add a limit + g.AuthFriendList = append(g.AuthFriendList, uint32(newProfileId)) + sendMessageToProfileId("2", g.User.ProfileId, uint32(newProfileId), "\r\n\r\n|signed|"+common.RandomHexString(32)) } @@ -142,6 +170,8 @@ func (g *GameSpySession) bestieMessage(command common.GameSpyCommand) { if toSession, ok := sessions[uint32(toProfileId)]; ok && toSession.LoggedIn { if !toSession.isFriendAdded(g.User.ProfileId) { logging.Error(g.ModuleName, "Destination", aurora.Cyan(toProfileId), "is not friends with sender") + g.replyError(2305) + return } // TODO SECURITY: Sanitize message (there's a stack overflow exploit in DWC here) diff --git a/gpcm/main.go b/gpcm/main.go index cf2bd41..4d23557 100644 --- a/gpcm/main.go +++ b/gpcm/main.go @@ -16,14 +16,15 @@ import ( ) type GameSpySession struct { - Conn net.Conn - User database.User - ModuleName string - LoggedIn bool - Challenge string - Status string - LocString string - FriendList []uint32 + Conn net.Conn + User database.User + ModuleName string + LoggedIn bool + Challenge string + Status string + LocString string + FriendList []uint32 + AuthFriendList []uint32 } var ( @@ -89,14 +90,15 @@ func (g *GameSpySession) closeSession() { // Handles incoming requests. func handleRequest(conn net.Conn) { session := GameSpySession{ - Conn: conn, - User: database.User{}, - ModuleName: "GPCM", - LoggedIn: false, - Challenge: "", - Status: "", - LocString: "", - FriendList: []uint32{}, + Conn: conn, + User: database.User{}, + ModuleName: "GPCM", + LoggedIn: false, + Challenge: "", + Status: "", + LocString: "", + FriendList: []uint32{}, + AuthFriendList: []uint32{}, } defer session.closeSession()