public EncryptionResponse(CryptoMC crypto) { this.SharedKey = crypto.SharedKeyEncrypted; this.Test = crypto.TestEncrypted; }
static MinecraftServer() { RsaBytes = CryptoMC.Init(); PingReplyMessage = "Loading..."; }
/// <summary> /// Return false if disconnect/finished /// </summary> void RunClientHandshake() { clientThread.WatchdogTick = DateTime.Now; //Read Handshake var hs = PacketReader.ReadFirstPackage(clientStream); if (hs == null) { //Old status packet LegacyStatus.SendStatus(clientStream); Phase = Phases.FinalClose; return; } var h = new Handshake(hs); Debug.FromClient(this, h); clientThread.State = "Handshake Received " + h; ClientVersion = h.Version; if (h.State == HandshakeState.Status) { RunStatusPing(h); return; } if (h.State == HandshakeState.None) { Close("Invalid handshake state: " + h.State); return; } if (h.State != HandshakeState.Login) { Close("Invalid handshake state: " + h.State); return; } #if DEBUG if (h.Version >= ProtocolVersion.next) { throw new InvalidDataException("new version: " + h.Version); } #endif if (h.Version > MinecraftServer.BackendVersion) { clientThread.State = "Handshake too high version"; Close("We are still running " + MinecraftServer.BackendVersion.ToText() + " we are so very sorry about that"); return; } if (h.Version < MinecraftServer.FrontendVersion) { clientThread.State = "Handshake too low version"; Close("Upgrade your client to " + MinecraftServer.FrontendVersion.ToText()); return; } //Login var l = new LoginStart(PacketReader.ReadHandshake(clientStream)); clientThread.State = "LoginStart Received " + l.Name; unverifiedUsername = l.Name; #if DEBUGx var names = new string[] { "travelcraft2012", "nuxas", "drjanitor" }; unverifiedUsername = names[logincount++ % names.Length]; #endif if (unverifiedUsername.Length == 0 || unverifiedUsername.Length > 16) { clientThread.State = "Handshake wrong username length"; Close("Bad username"); Console.WriteLine("Wrong username length: " + unverifiedUsername.Length); return; } //Set Compression var compression = new SetCompression(); SendToClientInternal(compression); maxUncompressed = compression.MaxSize; //Send encryption request clientThread.State = "Handshake: Sending encryption request"; //Initiate ID var r = new Random(); ID = new byte[8]; r.NextBytes(ID); SendToClientInternal(new EncryptionRequest(Authentication.McHex(ID), MinecraftServer.RsaBytes)); clientThread.State = "Handshake: Sent encryption request, reading response"; //Read enc response int erSize; var erBuffer = PacketReader.Read(clientStream, out erSize); if (erSize != 0) { erBuffer = Compression.Decompress(erBuffer, erSize); } var er = new EncryptionResponse(erBuffer); clientThread.State = "Handshake: Got enc resp"; CryptoMC cryptoStream = new CryptoMC(clientStream, er); //Verify user clientThread.WatchdogTick = DateTime.Now; clientThread.State = "Handshake: loading proxy data"; Settings = LoadProxyPlayer(unverifiedUsername); if (IPAddress.IsLoopback(RemoteEndPoint.Address)) { MinecraftUsername = unverifiedUsername; Log.WritePlayer(this, "Succesful login from (local) " + RemoteEndPoint); } else { clientThread.State = "Handshake: Verifying login credentials"; string error = Authentication.VerifyUserLogin(unverifiedUsername, cryptoStream.SharedKey, ID); if (error != null) { //Unauthorized Log.WriteAuthFail(unverifiedUsername, RemoteEndPoint, error); Close("Mojang says " + error); return; } else { MinecraftUsername = unverifiedUsername; Log.WritePlayer(this, "Login from " + RemoteEndPoint + " " + Country); } } clientThread.State = "Handshake: Logged in"; //Get UUID try { Settings.UUID = UsernameUUID.GetUUID(MinecraftUsername); //Saved further down Debug.WriteLine("Real UUID for " + MinecraftUsername + " is " + Settings.UUID); } catch (Exception) { Debug.WriteLine("Failed to get UUID for MinecraftName " + MinecraftUsername); } clientThread.WatchdogTick = DateTime.Now; MineProxy.Inbox.Status(this); //start encryption clientStream = cryptoStream; SendToClientInternal(new LoginSuccess(Settings.UUID, MinecraftUsername)); clientThread.User = MinecraftUsername; clientThread.State = "Logged in"; EntityID = freeEID; //Math.Abs(unverifiedUsername.GetHashCode()); freeEID += 5000; //Login reply to client JoinGame lr = new JoinGame(); lr.ClientVersion = 0; lr.Difficulty = 0; lr.Dimension = 0; lr.EntityID = EntityID; lr.MaxPlayers = (byte)MinecraftServer.PlayerListSlots; lr.GameMode = 0; SendToClient(lr); Phase = Phases.Gaming; Queue = new SendQueue(this); PlayerList.LoginPlayer(this); SaveProxyPlayer(); string name = h.Host.ToLowerInvariant().Split('.')[0]; if (name == "con") { SetWorld(World.Construct); } else { SetWorld(World.Main); } //Handshake complete }
/// <summary> /// Return false if disconnect/finished /// </summary> void RunClientHandshake() { clientThread.WatchdogTick = DateTime.Now; //Read Handshake var hs = PacketReader.ReadFirstPackage(clientStream); if (hs == null) { //Old status packet LegacyStatus.SendStatus(clientStream); Phase = Phases.FinalClose; return; } var h = new Handshake(hs); Debug.FromClient(this, h); clientThread.State = "Handshake Received " + h; ClientVersion = h.Version; if (h.State == HandshakeState.Status) { RunStatusPing(h); return; } if (h.State == HandshakeState.None) { Close("Invalid handshake state: " + h.State); return; } if (h.State != HandshakeState.Login) { Close("Invalid handshake state: " + h.State); return; } #if DEBUG if (h.Version >= ProtocolVersion.next) { throw new InvalidDataException("new version: " + h.Version); } #endif if (h.Version > MinecraftServer.BackendVersion) { clientThread.State = "Handshake too high version"; Close("We are still running " + MinecraftServer.BackendVersion.ToText() + " we are so very sorry about that"); return; } if (h.Version < MinecraftServer.FrontendVersion) { clientThread.State = "Handshake too low version"; Close("Upgrade your client to " + MinecraftServer.FrontendVersion.ToText()); return; } clientThread.WatchdogTick = DateTime.Now; //Login var l = new LoginStart(PacketReader.ReadHandshake(clientStream)); Debug.FromClient(this, l); clientThread.State = "LoginStart Received " + l.Name; unverifiedUsername = l.Name; if (unverifiedUsername.Length == 0 || unverifiedUsername.Length > 16) { clientThread.State = "Handshake wrong username length"; Close("Bad username"); Console.WriteLine("Wrong username length: " + unverifiedUsername.Length); return; } //Set Compression var compression = new SetCompression(); SendToClientInternal(compression); maxUncompressed = compression.MaxSize; //Send encryption request clientThread.State = "Handshake: Sending encryption request"; //Initiate ID var r = new Random(); ID = new byte[8]; r.NextBytes(ID); SendToClientInternal(new EncryptionRequest(Authentication.McHex(ID), MinecraftServer.RsaBytes)); clientThread.State = "Handshake: Sent encryption request, reading response"; //Read enc response int erSize; var erBuffer = PacketReader.Read(clientStream, out erSize); if (erSize != 0) { erBuffer = Compression.Decompress(erBuffer, erSize); } var er = new EncryptionResponse(erBuffer); Debug.FromClient(this, er); clientThread.State = "Handshake: Got enc resp"; CryptoMC cryptoStream = new CryptoMC(clientStream, er); //Verify user clientThread.State = "Handshake: loading proxy data"; Settings = LoadProxyPlayer(unverifiedUsername); clientThread.State = "Handshake: Verifying login credentials"; var auth = Authentication.VerifyUserLogin(unverifiedUsername, cryptoStream.SharedKey, ID); #warning From here we now need to take care of the id in the response. if (auth == null) { //Unauthorized Log.WriteAuthFail(unverifiedUsername, RemoteEndPoint, ""); Close("Mojang says no"); return; } else { MinecraftUsername = unverifiedUsername; Log.WritePlayer(this, "Login from " + RemoteEndPoint + " " + Country); } clientThread.State = "Handshake: Logged in"; //Get UUID Settings.UUID = auth.id; clientThread.WatchdogTick = DateTime.Now; MineProxy.Inbox.Status(this); //start encryption clientStream = cryptoStream; SendToClientInternal(new LoginSuccess(Settings.UUID, MinecraftUsername)); clientThread.User = MinecraftUsername; clientThread.State = "Logged in"; EntityID = freeEID; //Math.Abs(unverifiedUsername.GetHashCode()); freeEID += 5000; //Login reply to client //No longer, send the vanilla server Login reply instead. Phase = Phases.Gaming; Queue = new SendQueue(this); PlayerList.LoginPlayer(this); SaveProxyPlayer(); string name = h.Host.ToLowerInvariant().Split('.')[0]; if (World.VanillaWorlds.ContainsKey(name)) { SetWorld(World.VanillaWorlds[name]); } else { SetWorld(World.Main); } //Handshake complete }