diff --git a/packages/core/src/handlers/login.ts b/packages/core/src/handlers/login.ts index 721b17f66..1e843dfec 100644 --- a/packages/core/src/handlers/login.ts +++ b/packages/core/src/handlers/login.ts @@ -18,6 +18,7 @@ import { NetworkHandler } from "../network"; import { ClientSystemInfo, Player } from "../entity"; import { PlayerProperties } from "../types"; import { PlayerJoinSignal } from "../events"; +import { AuthenticationType } from "@serenityjs/protocol/src/types/authentication-type"; class LoginHandler extends NetworkHandler { public static readonly packet = Packet.Login; @@ -28,7 +29,23 @@ class LoginHandler extends NetworkHandler { // Decode the tokens given by the client. // This contains the client data, identity data, and public key. // Along with the players XUID, display name, and uuid. - const { clientData, identityData } = LoginHandler.decode(packet.tokens); + const { clientData, identityData, authenticationType } = LoginHandler.decode(packet.tokens); + + // Check if the authentication type is valid. + // The LoginPacket passes one of three authentication types: + // 0 - Standard, the player is using their own token to connect. + // 1 - The connection is coming from a guest split screen session using the host's token. + // 2 - The connection is not authenticated. + // By default, we do not want to allow guest or unauthenticated connections to the server. + + if (authenticationType !== AuthenticationType.Full && !this.serenity.properties.allowUnsignedConnections) { + // Disconnect the player. + return this.network.disconnectConnection( + connection, + "Failed to authenticate. Make sure you are connected to Xbox Live before joining the server.", + DisconnectReason.NotAuthenticated + ); + } // Get the clients xuid and username. const xuid = identityData.XUID; @@ -165,7 +182,7 @@ class LoginHandler extends NetworkHandler { const clientData: ClientData = this.decoder(tokens.client); // Parse the identity data from the tokens - const identity: { Certificate: string } = JSON.parse(tokens.identity); + const identity: { AuthenticationType: number, Certificate: string } = JSON.parse(tokens.identity); // Get the identity chain from the identity data const chains: Array = JSON.parse(identity.Certificate).chain; @@ -187,7 +204,8 @@ class LoginHandler extends NetworkHandler { return { clientData, identityData, - publicKey + publicKey, + authenticationType: identity.AuthenticationType }; } } diff --git a/packages/core/src/serenity.ts b/packages/core/src/serenity.ts index 6a71ab0b0..5f84fa58d 100644 --- a/packages/core/src/serenity.ts +++ b/packages/core/src/serenity.ts @@ -49,6 +49,7 @@ const DefaultSerenityProperties: SerenityProperties = { movementValidation: true, movementHorizontalThreshold: 0.4, movementVerticalThreshold: 0.6, + allowUnsignedConnections: false, shutdownMessage: "Server is shutting down.", ticksPerSecond: 20, debugLogging: false diff --git a/packages/core/src/types/serenity-properties.ts b/packages/core/src/types/serenity-properties.ts index eadb76b19..c18980a67 100644 --- a/packages/core/src/types/serenity-properties.ts +++ b/packages/core/src/types/serenity-properties.ts @@ -11,6 +11,7 @@ interface SerenityProperties { movementValidation: boolean; movementHorizontalThreshold: number; movementVerticalThreshold: number; + allowUnsignedConnections: boolean; shutdownMessage: string; ticksPerSecond: number; debugLogging: boolean; diff --git a/packages/protocol/src/types/authentication-type.ts b/packages/protocol/src/types/authentication-type.ts new file mode 100644 index 000000000..849e2b6c3 --- /dev/null +++ b/packages/protocol/src/types/authentication-type.ts @@ -0,0 +1,7 @@ +enum AuthenticationType { + Full = 0, // The player's own token + Guest = 1, // Split screen sessions, the player is using the host's token + SelfSigned = 2 // Not authenticated +} + +export { AuthenticationType } \ No newline at end of file diff --git a/packages/protocol/src/types/login-data.ts b/packages/protocol/src/types/login-data.ts index 362951a10..396e3f29a 100644 --- a/packages/protocol/src/types/login-data.ts +++ b/packages/protocol/src/types/login-data.ts @@ -1,3 +1,5 @@ +import { AuthenticationType } from "./authentication-type"; + interface ClientData { AnimatedImageData: Array; ArmSize: string; @@ -78,6 +80,7 @@ interface LoginTokenData { clientData: ClientData; identityData: IdentityData; publicKey: string; + authenticationType: AuthenticationType } export type { LoginTokenData, IdentityData, ClientData };