· 6 years ago · May 08, 2019, 06:42 PM
1package net.minecraft.server.network;
2
3import com.google.common.base.Charsets;
4import com.mojang.authlib.GameProfile;
5import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
6import io.netty.util.concurrent.GenericFutureListener;
7import java.math.BigInteger;
8import java.security.PrivateKey;
9import java.util.Arrays;
10import java.util.Random;
11import java.util.UUID;
12import java.util.concurrent.atomic.AtomicInteger;
13import javax.crypto.SecretKey;
14import net.minecraft.network.EnumConnectionState;
15import net.minecraft.network.NetworkManager;
16import net.minecraft.network.login.INetHandlerLoginServer;
17import net.minecraft.network.login.client.C00PacketLoginStart;
18import net.minecraft.network.login.client.C01PacketEncryptionResponse;
19import net.minecraft.network.login.server.S00PacketDisconnect;
20import net.minecraft.network.login.server.S01PacketEncryptionRequest;
21import net.minecraft.network.login.server.S02PacketLoginSuccess;
22import net.minecraft.server.MinecraftServer;
23import net.minecraft.util.ChatComponentText;
24import net.minecraft.util.CryptManager;
25import net.minecraft.util.IChatComponent;
26import org.apache.commons.lang3.Validate;
27import org.apache.logging.log4j.LogManager;
28import org.apache.logging.log4j.Logger;
29
30public class NetHandlerLoginServer implements INetHandlerLoginServer
31{
32 private static final AtomicInteger field_147331_b = new AtomicInteger(0);
33 private static final Logger logger = LogManager.getLogger();
34 private static final Random field_147329_d = new Random();
35 private final byte[] field_147330_e = new byte[4];
36 private final MinecraftServer field_147327_f;
37 public final NetworkManager field_147333_a;
38 private NetHandlerLoginServer.LoginState field_147328_g;
39 private int field_147336_h;
40 private GameProfile field_147337_i;
41 private String field_147334_j;
42 private SecretKey field_147335_k;
43 private static final String __OBFID = "CL_00001458";
44
45 public NetHandlerLoginServer(MinecraftServer p_i45298_1_, NetworkManager p_i45298_2_)
46 {
47 this.field_147328_g = NetHandlerLoginServer.LoginState.HELLO;
48 this.field_147334_j = "";
49 this.field_147327_f = p_i45298_1_;
50 this.field_147333_a = p_i45298_2_;
51 field_147329_d.nextBytes(this.field_147330_e);
52 }
53
54 /**
55 * For scheduled network tasks. Used in NetHandlerPlayServer to send keep-alive packets and in NetHandlerLoginServer
56 * for a login-timeout
57 */
58 public void onNetworkTick()
59 {
60 if (this.field_147328_g == NetHandlerLoginServer.LoginState.READY_TO_ACCEPT)
61 {
62 this.func_147326_c();
63 }
64
65 if (this.field_147336_h++ == 600)
66 {
67 this.func_147322_a("Took too long to log in");
68 }
69 }
70
71 public void func_147322_a(String p_147322_1_)
72 {
73 try
74 {
75 logger.info("Disconnecting " + this.func_147317_d() + ": " + p_147322_1_);
76 ChatComponentText var2 = new ChatComponentText(p_147322_1_);
77 this.field_147333_a.scheduleOutboundPacket(new S00PacketDisconnect(var2), new GenericFutureListener[0]);
78 this.field_147333_a.closeChannel(var2);
79 }
80 catch (Exception var3)
81 {
82 logger.error("Error whilst disconnecting player", var3);
83 }
84 }
85
86 public void func_147326_c()
87 {
88 if (!this.field_147337_i.isComplete())
89 {
90 this.field_147337_i = this.func_152506_a(this.field_147337_i);
91 }
92
93 String var1 = this.field_147327_f.getConfigurationManager().func_148542_a(this.field_147333_a.getRemoteAddress(), this.field_147337_i);
94
95 if (var1 != null)
96 {
97 this.func_147322_a(var1);
98 }
99 else
100 {
101 this.field_147328_g = NetHandlerLoginServer.LoginState.ACCEPTED;
102 this.field_147333_a.scheduleOutboundPacket(new S02PacketLoginSuccess(this.field_147337_i), new GenericFutureListener[0]);
103 this.field_147327_f.getConfigurationManager().initializeConnectionToPlayer(this.field_147333_a, this.field_147327_f.getConfigurationManager().func_148545_a(this.field_147337_i));
104 }
105 }
106
107 /**
108 * Invoked when disconnecting, the parameter is a ChatComponent describing the reason for termination
109 */
110 public void onDisconnect(IChatComponent p_147231_1_)
111 {
112 logger.info(this.func_147317_d() + " lost connection: " + p_147231_1_.getUnformattedText());
113 }
114
115 public String func_147317_d()
116 {
117 return this.field_147337_i != null ? this.field_147337_i.toString() + " (" + this.field_147333_a.getRemoteAddress().toString() + ")" : String.valueOf(this.field_147333_a.getRemoteAddress());
118 }
119
120 /**
121 * Allows validation of the connection state transition. Parameters: from, to (connection state). Typically throws
122 * IllegalStateException or UnsupportedOperationException if validation fails
123 */
124 public void onConnectionStateTransition(EnumConnectionState p_147232_1_, EnumConnectionState p_147232_2_)
125 {
126 Validate.validState(this.field_147328_g == NetHandlerLoginServer.LoginState.ACCEPTED || this.field_147328_g == NetHandlerLoginServer.LoginState.HELLO, "Unexpected change in protocol", new Object[0]);
127 Validate.validState(p_147232_2_ == EnumConnectionState.PLAY || p_147232_2_ == EnumConnectionState.LOGIN, "Unexpected protocol " + p_147232_2_, new Object[0]);
128 }
129
130 public void processLoginStart(C00PacketLoginStart p_147316_1_)
131 {
132 Validate.validState(this.field_147328_g == NetHandlerLoginServer.LoginState.HELLO, "Unexpected hello packet", new Object[0]);
133 this.field_147337_i = p_147316_1_.func_149304_c();
134
135 if (this.field_147327_f.isServerInOnlineMode() && !this.field_147333_a.isLocalChannel())
136 {
137 this.field_147328_g = NetHandlerLoginServer.LoginState.KEY;
138 this.field_147333_a.scheduleOutboundPacket(new S01PacketEncryptionRequest(this.field_147334_j, this.field_147327_f.getKeyPair().getPublic(), this.field_147330_e), new GenericFutureListener[0]);
139 }
140 else
141 {
142 this.field_147328_g = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT;
143 }
144 }
145
146 public void processEncryptionResponse(C01PacketEncryptionResponse p_147315_1_)
147 {
148 Validate.validState(this.field_147328_g == NetHandlerLoginServer.LoginState.KEY, "Unexpected key packet", new Object[0]);
149 PrivateKey var2 = this.field_147327_f.getKeyPair().getPrivate();
150
151 if (!Arrays.equals(this.field_147330_e, p_147315_1_.func_149299_b(var2)))
152 {
153 throw new IllegalStateException("Invalid nonce!");
154 }
155 else
156 {
157 this.field_147335_k = p_147315_1_.func_149300_a(var2);
158 this.field_147328_g = NetHandlerLoginServer.LoginState.AUTHENTICATING;
159 this.field_147333_a.enableEncryption(this.field_147335_k);
160 (new Thread("User Authenticator #" + field_147331_b.incrementAndGet())
161 {
162 private static final String __OBFID = "CL_00001459";
163 public void run()
164 {
165 GameProfile var1 = NetHandlerLoginServer.this.field_147337_i;
166
167 try
168 {
169 String var2 = (new BigInteger(CryptManager.getServerIdHash(NetHandlerLoginServer.this.field_147334_j, NetHandlerLoginServer.this.field_147327_f.getKeyPair().getPublic(), NetHandlerLoginServer.this.field_147335_k))).toString(16);
170 NetHandlerLoginServer.this.field_147337_i = NetHandlerLoginServer.this.field_147327_f.func_147130_as().hasJoinedServer(new GameProfile((UUID)null, var1.getName()), var2);
171
172 if (NetHandlerLoginServer.this.field_147337_i != null)
173 {
174 NetHandlerLoginServer.logger.info("UUID of player " + NetHandlerLoginServer.this.field_147337_i.getName() + " is " + NetHandlerLoginServer.this.field_147337_i.getId());
175 NetHandlerLoginServer.this.field_147328_g = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT;
176 }
177 else if (NetHandlerLoginServer.this.field_147327_f.isSinglePlayer())
178 {
179 NetHandlerLoginServer.logger.warn("Failed to verify username but will let them in anyway!");
180 NetHandlerLoginServer.this.field_147337_i = NetHandlerLoginServer.this.func_152506_a(var1);
181 NetHandlerLoginServer.this.field_147328_g = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT;
182 }
183 else
184 {
185 NetHandlerLoginServer.this.func_147322_a("Failed to verify username!");
186 NetHandlerLoginServer.logger.error("Username \'" + NetHandlerLoginServer.this.field_147337_i.getName() + "\' tried to join with an invalid session");
187 }
188 }
189 catch (AuthenticationUnavailableException var3)
190 {
191 if (NetHandlerLoginServer.this.field_147327_f.isSinglePlayer())
192 {
193 NetHandlerLoginServer.logger.warn("Authentication servers are down but will let them in anyway!");
194 NetHandlerLoginServer.this.field_147337_i = NetHandlerLoginServer.this.func_152506_a(var1);
195 NetHandlerLoginServer.this.field_147328_g = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT;
196 }
197 else
198 {
199 NetHandlerLoginServer.this.func_147322_a("Authentication servers are down. Please try again later, sorry!");
200 NetHandlerLoginServer.logger.error("Couldn\'t verify username because servers are unavailable");
201 }
202 }
203 }
204 }).start();
205 }
206 }
207
208 protected GameProfile func_152506_a(GameProfile p_152506_1_)
209 {
210 UUID var2 = UUID.nameUUIDFromBytes(("OfflinePlayer:" + p_152506_1_.getName()).getBytes(Charsets.UTF_8));
211 return new GameProfile(var2, p_152506_1_.getName());
212 }
213
214 static enum LoginState
215 {
216 HELLO("HELLO", 0),
217 KEY("KEY", 1),
218 AUTHENTICATING("AUTHENTICATING", 2),
219 READY_TO_ACCEPT("READY_TO_ACCEPT", 3),
220 ACCEPTED("ACCEPTED", 4);
221
222 private static final NetHandlerLoginServer.LoginState[] $VALUES = new NetHandlerLoginServer.LoginState[]{HELLO, KEY, AUTHENTICATING, READY_TO_ACCEPT, ACCEPTED};
223 private static final String __OBFID = "CL_00001463";
224
225 private LoginState(String p_i45297_1_, int p_i45297_2_) {}
226 }
227}