Skip to content

Commit 959ec8d

Browse files
authored
1.26.10 & auth (#2261)
1 parent d0635e6 commit 959ec8d

24 files changed

+759
-354
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ data/*
268268
material_tags.txt
269269
item_types.txt
270270
block_types.txt
271+
discovery-cache.json
272+
openid-cache.json
271273

272274
run/
273275

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ snakeyaml = { group = "org.yaml", name = "snakeyaml", version = "1.33" }
1616
leveldb = { group = "org.iq80.leveldb", name = "leveldb", version = "0.11.1-SNAPSHOT" }
1717
leveldbjni = { group = "net.daporkchop", name = "leveldb-mcpe-jni", version = "0.0.10-SNAPSHOT" }
1818
snappy = { group = "org.xerial.snappy", name = "snappy-java", version = "1.1.10.8" }
19-
jwt = { group = "com.nimbusds", name = "nimbus-jose-jwt", version = "10.3.1" }
19+
jwt = { group = "org.bitbucket.b_c", name = "jose4j", version = "0.9.6" }
2020
jopt-simple = { group = "net.sf.jopt-simple", name = "jopt-simple", version = "5.0.4" }
2121
blockstateupdater = { group = "org.cloudburstmc", name = "block-state-updater", version = "1.21.40-SNAPSHOT" }
2222
lmbda = { group = "org.lanternpowered", name = "lmbda", version = "2.0.0" }

src/main/java/cn/nukkit/Player.java

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde
141141
private boolean loginPacketReceived;
142142
protected boolean networkSettingsRequested;
143143
public int gamemode;
144-
protected long randomClientId;
145-
private String unverifiedUsername = "";
146144

147145
protected final BiMap<Inventory, Integer> windows = HashBiMap.create();
148146
protected final BiMap<Integer, Inventory> windowIndex = windows.inverse();
@@ -430,7 +428,7 @@ public String getClientSecret() {
430428
*/
431429
@Deprecated
432430
public Long getClientId() {
433-
return randomClientId;
431+
return loginChainData.getClientId();
434432
}
435433

436434
@Override
@@ -2945,7 +2943,7 @@ public void handleDataPacket(DataPacket packet) {
29452943
this.networkSettingsRequested = true;
29462944

29472945
if (this.getNetworkSession().getCompression() != CompressionProvider.NONE) {
2948-
this.getServer().getLogger().debug((this.username == null ? this.unverifiedUsername : this.username) +
2946+
this.getServer().getLogger().debug(this.username +
29492947
": got a RequestNetworkSettingsPacket but compression is already set");
29502948
return;
29512949
}
@@ -2978,7 +2976,6 @@ public void handleDataPacket(DataPacket packet) {
29782976
this.loginPacketReceived = true;
29792977

29802978
LoginPacket loginPacket = (LoginPacket) packet;
2981-
this.unverifiedUsername = TextFormat.clean(loginPacket.username);
29822979

29832980
if (!this.networkSettingsRequested) {
29842981
this.close("", "Invalid login sequence: login packet before network settings");
@@ -2997,50 +2994,33 @@ public void handleDataPacket(DataPacket packet) {
29972994
return;
29982995
}
29992996

3000-
if (loginPacket.skin == null) {
3001-
this.close("", "disconnectionScreen.invalidSkin");
3002-
return;
3003-
}
3004-
3005-
if (this.server.getOnlinePlayersCount() >= this.server.getMaxPlayers() && this.kick(PlayerKickEvent.Reason.SERVER_FULL, "disconnectionScreen.serverFull", false)) {
3006-
return;
3007-
}
3008-
30092997
try {
3010-
// TODO: Why do we read this separately?
30112998
this.loginChainData = ClientChainData.read(loginPacket);
30122999
} catch (ClientChainData.TooBigSkinException ex) {
30133000
this.close("", "disconnectionScreen.invalidSkin");
30143001
return;
3002+
} catch (Exception ex) {
3003+
getServer().getLogger().logException(ex);
3004+
this.close("", "disconnectionScreen.noReason");
3005+
return;
30153006
}
30163007

3017-
server.getLogger().debug("Name: " + this.unverifiedUsername + " Protocol: " + loginPacket.getProtocol() + " Version: " + loginChainData.getGameVersion());
3008+
server.getLogger().debug("Name: " + loginChainData.getUsername() + " Version: " + loginChainData.getGameVersion());
30183009

30193010
if (!loginChainData.isXboxAuthed() && server.xboxAuth) {
30203011
this.close("", "disconnectionScreen.notAuthenticated");
30213012
return;
30223013
}
30233014

3024-
// Do not set username before the user is authenticated
3025-
this.username = this.unverifiedUsername;
3026-
this.unverifiedUsername = null;
3027-
this.displayName = this.username;
3028-
this.iusername = this.username.toLowerCase(Locale.ROOT);
3029-
this.setDataProperty(new StringEntityData(DATA_NAMETAG, this.username), false);
3030-
3031-
this.randomClientId = loginPacket.clientId;
3032-
this.uuid = loginPacket.clientUUID;
3033-
this.rawUUID = Binary.writeUUID(this.uuid);
3034-
30353015
boolean valid = true;
3036-
int len = loginPacket.username.length();
3037-
if (len > 16 || len < 3 || loginPacket.username.trim().isEmpty()) {
3016+
int len = loginChainData.getUsername().length();
3017+
if (len > 16 || len < 3 || loginChainData.getUsername().trim().isEmpty()) {
30383018
valid = false;
30393019
}
30403020

30413021
if (valid) {
30423022
for (int i = 0; i < len; i++) {
3043-
char c = loginPacket.username.charAt(i);
3023+
char c = loginChainData.getUsername().charAt(i);
30443024
if ((c >= 'a' && c <= 'z') ||
30453025
(c >= 'A' && c <= 'Z') ||
30463026
(c >= '0' && c <= '9') ||
@@ -3054,13 +3034,27 @@ public void handleDataPacket(DataPacket packet) {
30543034
}
30553035
}
30563036

3057-
if (!valid || Objects.equals(this.iusername, "rcon") || Objects.equals(this.iusername, "console")) {
3037+
String lowerCaseName = loginChainData.getUsername().toLowerCase(Locale.ROOT);
3038+
if (!valid || Objects.equals(lowerCaseName, "rcon") || Objects.equals(lowerCaseName, "console")) {
30583039
this.close("", "disconnectionScreen.invalidName");
30593040
return;
30603041
}
30613042

3062-
Skin skin = loginPacket.skin;
3063-
if (!skin.isValid()) {
3043+
// Do not set username before the user is authenticated
3044+
this.username = loginChainData.getUsername();
3045+
this.displayName = this.username;
3046+
this.iusername = lowerCaseName;
3047+
this.setDataProperty(new StringEntityData(DATA_NAMETAG, this.username), false);
3048+
3049+
this.uuid = loginChainData.getClientUUID();
3050+
this.rawUUID = Binary.writeUUID(this.uuid);
3051+
3052+
if (this.server.getOnlinePlayersCount() >= this.server.getMaxPlayers() && this.kick(PlayerKickEvent.Reason.SERVER_FULL, "disconnectionScreen.serverFull", false)) {
3053+
return;
3054+
}
3055+
3056+
Skin skin = loginChainData.getSkin();
3057+
if (skin == null || !skin.isValid()) {
30643058
this.close("", "disconnectionScreen.invalidSkin");
30653059
return;
30663060
}
@@ -5416,7 +5410,7 @@ public void close(TextContainer message, String reason, boolean notify) {
54165410
this.server.getPluginManager().unsubscribeFromPermission(Server.BROADCAST_CHANNEL_USERS, this);
54175411
this.spawned = false;
54185412
this.server.getLogger().info(this.getServer().getLanguage().translateString("nukkit.player.logOut",
5419-
TextFormat.AQUA + (this.username == null ? this.unverifiedUsername : this.username) + TextFormat.WHITE,
5413+
TextFormat.AQUA + this.username + TextFormat.WHITE,
54205414
this.getAddress(),
54215415
String.valueOf(this.getPort()),
54225416
this.getServer().getLanguage().translateString(reason)));
@@ -5444,7 +5438,7 @@ public void close(TextContainer message, String reason, boolean notify) {
54445438
this.server.removePlayer(this);
54455439

54465440
if (this.loggedIn) {
5447-
this.server.getLogger().warning("Player is still logged in: " + (this.username == null ? this.unverifiedUsername : this.username));
5441+
this.server.getLogger().warning("Player is still logged in: " + this.username);
54485442
this.interfaz.close(this, notify ? reason : "");
54495443
this.server.removeOnlinePlayer(this);
54505444
this.loggedIn = false;

src/main/java/cn/nukkit/Server.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import cn.nukkit.network.Network;
5555
import cn.nukkit.network.RakNetInterface;
5656
import cn.nukkit.network.SourceInterface;
57+
import cn.nukkit.network.encryption.EncryptionUtils;
5758
import cn.nukkit.network.protocol.*;
5859
import cn.nukkit.network.query.QueryHandler;
5960
import cn.nukkit.network.rcon.RCON;
@@ -432,6 +433,10 @@ public Level remove(Object key) {
432433
log.info(this.getLanguage().translateString("language.selected", new String[]{getLanguage().getName(), getLanguage().getLang()}));
433434
log.info(getLanguage().translateString("nukkit.server.start", TextFormat.AQUA + this.getVersion() + TextFormat.RESET));
434435

436+
log.debug("Setting up auth environment...");
437+
//noinspection ResultOfMethodCallIgnored
438+
EncryptionUtils.getMojangPublicKey();
439+
435440
Object poolSize = this.getConfig("settings.async-workers", "auto");
436441
if (!(poolSize instanceof Integer)) {
437442
try {

src/main/java/cn/nukkit/inventory/transaction/data/UseItemData.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ public class UseItemData implements TransactionData {
2323
public Vector3f clickPos;
2424
public int blockRuntimeId;
2525
public int clientInteractPrediction;
26+
public int clientCooldownState;
2627
}

src/main/java/cn/nukkit/network/Network.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public void processBatch(byte[] payload, Collection<DataPacket> packets, Compres
159159
try {
160160
pk.decode();
161161

162-
if (Nukkit.DEBUG > 1 && pk.offset < pk.getRawBuffer().length) {
162+
if (Nukkit.DEBUG > 1 && packetId != ProtocolInfo.LOGIN_PACKET && pk.offset < pk.getRawBuffer().length) {
163163
log.debug(pk.getClass().getSimpleName() + " still has " + (pk.getRawBuffer().length - pk.offset) + " bytes to read!");
164164
}
165165
} catch (Exception e) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package cn.nukkit.network.auth;
2+
3+
public interface AuthPayload {
4+
5+
/**
6+
* Returns the authentication type of the player.
7+
*
8+
* @return the authentication type
9+
*/
10+
AuthType getAuthType();
11+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package cn.nukkit.network.auth;
2+
3+
public enum AuthType {
4+
/**
5+
* Player auth status is unknown. This is the default value for legacy clients.
6+
*/
7+
UNKNOWN,
8+
/**
9+
* Player is authenticated directly to Mojang auth servers.
10+
*/
11+
FULL,
12+
/**
13+
* Split screen player using the host's authentication token.
14+
*/
15+
GUEST,
16+
/**
17+
* This player is not authenticated with Mojang auth servers.
18+
*/
19+
SELF_SIGNED
20+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package cn.nukkit.network.auth;
2+
3+
import lombok.Getter;
4+
5+
import java.util.List;
6+
import java.util.Objects;
7+
8+
public class CertificateChainPayload implements AuthPayload {
9+
10+
@Getter
11+
private final List<String> chain;
12+
private final AuthType type;
13+
14+
public CertificateChainPayload(List<String> chain) {
15+
this(chain, AuthType.UNKNOWN);
16+
}
17+
18+
public CertificateChainPayload(List<String> chain, AuthType type) {
19+
this.chain = chain;
20+
this.type = Objects.requireNonNull(type);
21+
}
22+
23+
@Override
24+
public AuthType getAuthType() {
25+
return type;
26+
}
27+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package cn.nukkit.network.auth;
2+
3+
import lombok.Getter;
4+
5+
import java.util.Objects;
6+
7+
public class TokenPayload implements AuthPayload {
8+
9+
@Getter
10+
private final String token;
11+
private final AuthType type;
12+
13+
public TokenPayload(String token, AuthType type) {
14+
if (type == AuthType.UNKNOWN) {
15+
throw new IllegalArgumentException("TokenPayload cannot be of type UNKNOWN");
16+
}
17+
18+
this.token = token;
19+
this.type = Objects.requireNonNull(type);
20+
}
21+
22+
@Override
23+
public AuthType getAuthType() {
24+
return type;
25+
}
26+
}

0 commit comments

Comments
 (0)