mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 08:23:45 +00:00
fix(multiplayer): fence roster topology at persistence
This commit is contained in:
@@ -149,11 +149,21 @@ func SaveVerifiedAssignmentRoster(ctx context.Context, db *sql.DB, assignment do
|
||||
}
|
||||
digest := domain.ManifestDigest(assignment.Manifest)
|
||||
rows := make([]DurableAssignment, 0, len(roster))
|
||||
seenPlayers := make(map[string]struct{}, len(roster))
|
||||
seenSlots := make(map[int]struct{}, len(roster))
|
||||
for _, signed := range roster {
|
||||
auth := signed.Authorisation
|
||||
if err := validateSignedRosterEntry(assignment, signed, verify); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, exists := seenPlayers[auth.PlayerID]; exists {
|
||||
return fmt.Errorf("invalid signed assignment roster: duplicate player")
|
||||
}
|
||||
if _, exists := seenSlots[auth.Slot]; exists {
|
||||
return fmt.Errorf("invalid signed assignment roster: duplicate slot")
|
||||
}
|
||||
seenPlayers[auth.PlayerID] = struct{}{}
|
||||
seenSlots[auth.Slot] = struct{}{}
|
||||
envelope, err := json.Marshal(signed)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encode signed assignment roster: %w", err)
|
||||
@@ -172,7 +182,7 @@ func SaveVerifiedAssignmentRoster(ctx context.Context, db *sql.DB, assignment do
|
||||
|
||||
func validateSignedRosterEntry(assignment domain.Assignment, signed domain.SignedJoinAuthorisation, verify func([]byte, []byte) bool) error {
|
||||
auth := signed.Authorisation
|
||||
if len(signed.Signature) == 0 || verify == nil || !verify(domain.JoinAuthorisationBytes(auth), signed.Signature) || auth.MatchID != assignment.Allocation.MatchID || auth.ServerID != assignment.Allocation.ServerID || auth.Protocol != strconv.Itoa(assignment.Allocation.Protocol) || auth.PlayerID == "" || auth.Slot < 0 || auth.Slot > 5 || auth.ExpiresAt.IsZero() {
|
||||
if len(signed.Signature) == 0 || verify == nil || !verify(domain.JoinAuthorisationBytes(auth), signed.Signature) || auth.MatchID != assignment.Allocation.MatchID || auth.ServerID != assignment.Allocation.ServerID || auth.Protocol != strconv.Itoa(assignment.Allocation.Protocol) || auth.PlayerID == "" || auth.Slot < 0 || auth.Slot > 5 || auth.Team < 0 || auth.Team > 1 || auth.Slot/3 != auth.Team || auth.ExpiresAt.IsZero() {
|
||||
return fmt.Errorf("invalid signed assignment roster")
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user