private Task DispatchPacket(EncryptionResponse packet) { var requestGrain = GrainFactory.GetGrain <ILoginFlow>(this.GetPrimaryKey()); requestGrain.DispatchPacket(packet).Ignore(); return(Task.CompletedTask); }
private Task DispatchLoginPackets(UncompressedPacket packet) { var br = new SpanReader(packet.Data); Task task; switch (packet.PacketId) { // Login Start case 0x00: task = DispatchPacket(LoginStart.Deserialize(ref br)); break; // Encryption Response case 0x01: task = DispatchPacket(EncryptionResponse.Deserialize(ref br)); break; default: throw new InvalidDataException($"Unrecognizable packet id: 0x{packet.PacketId:X2}."); } if (!br.IsCosumed) { throw new InvalidDataException($"Packet data is not fully consumed."); } return(task); }
public async Task DispatchPacket(EncryptionResponse packet) { var settingsGrain = GrainFactory.GetGrain <IServerSettings>(0); var settings = await settingsGrain.GetSettings(); // TODO auth and compression var packetRouter = GrainFactory.GetGrain <IPacketRouter>(this.GetPrimaryKey()); var userName = await packetRouter.GetUserName(); // mojang request url var mojangURL = String.Format("https://sessionserver.mojang.com/session/minecraft/hasJoined?username={0}&serverId={1}&ip={2}", userName, "", settings.ServerIp); // success var user = await GrainFactory.GetGrain <INonAuthenticatedUser>(userName).GetUser(); var world = await user.GetWorld(); var gameSession = GrainFactory.GetGrain <IGameSession>(world.GetPrimaryKeyString()); var uuid = user.GetPrimaryKey(); await SendLoginSuccess(userName, uuid); await user.SetClientPacketSink(GrainFactory.GetGrain <IClientboundPacketSink>(this.GetPrimaryKey())); await user.SetPacketRouter(packetRouter); var game = GrainFactory.GetGrain <IGameSession>(world.GetPrimaryKeyString()); await game.JoinGame(user); }
/// <summary> /// Server side encryption /// </summary> public CryptoMC(Stream baseStream, EncryptionResponse resp) { this.BaseStream = baseStream; Pkcs1Encoding padding = new Pkcs1Encoding(new RsaEngine()); padding.Init(false, keyParameters); SharedKey = padding.ProcessBlock(resp.SharedKey, 0, resp.SharedKey.Length); InitCiphers(); }
public void SendEncryptionResponse(ClientConnectionInfo connection, EncryptionResponseCode responseCode, byte[] key, byte[] iv) { var handShakeResponse = new EncryptionResponse { ResponseCode = responseCode, AESKey = key, IV = iv }; if (responseCode == EncryptionResponseCode.OK) { RSAEncryptedSend(connection, handShakeResponse.Create(), ChannelID.Handshaking, true); } else { DefaultSend(connection, handShakeResponse.Create(), ChannelID.Handshaking, true); } }
private void OnEncryptionCompleted(string result, EncryptionResponse response) { switch (response) { case EncryptionResponse.Success: FormsContainer.MainForm.HideTip(); ResultTextBox.Text = result; break; case EncryptionResponse.PasswordIsEmpty: FormsContainer.MainForm.ShowTip("Password is empty"); break; case EncryptionResponse.SourceIsEmpty: FormsContainer.MainForm.ShowTip("Source is empty"); break; case EncryptionResponse.SaltIsEmpty: FormsContainer.MainForm.ShowTip("Salt is empty"); break; case EncryptionResponse.SaltIsIncorrect: FormsContainer.MainForm.ShowTip("Salt is incorrect"); break; case EncryptionResponse.SaltIsLessThan8Bytes: FormsContainer.MainForm.ShowTip("Salt less than 8 bytes"); break; case EncryptionResponse.SaltIsMoreThan32Bytes: FormsContainer.MainForm.ShowTip("Salt more than 32 bytes"); break; case EncryptionResponse.DecryptionFail: FormsContainer.MainForm.ShowTip("Incorrect password or source text"); break; } }
/// <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 }
public virtual void OnEncryptionResponse(EncryptionResponse packet) { }
private void InvokeEncryptionResponse(EncryptionResponse packet) { packetListener.OnEncryptionResponse(packet); }