示例#1
0
        /// <summary>
        /// Parses the handshake from the received data
        /// </summary>
        private int ParseHandshake()
        {
            int offset = 0;

            ushort length = BitConverter.ToUInt16(DataBuffer, 0);

            offset = (HandshakeHeaderLength + length);

            byte[] handshakeData = new ArraySegment <byte>(DataBuffer, HandshakeHeaderLength, length).ToArray();

            PacketReader reader         = new PacketReader(ref handshakeData, IncomingPacketType.NoHeader);
            ushort       version        = reader.ReadUInt16();
            ushort       subversion     = Convert.ToUInt16(reader.ReadMapleString());
            uint         localVector    = reader.ReadUInt32();
            uint         remoteVector   = reader.ReadUInt32();
            byte         locale         = reader.ReadInt8();
            byte         isLoginContext = 255;

            if (reader.AbsoluteLength >= 15) //Decode CRC 'n shit
            {
                isLoginContext = reader.ReadInt8();
            }

            LocalCipher.Initialize(localVector, version);
            RemoteCipher.Initialize(remoteVector, version);

            HandshakeReceived?.Invoke(version, subversion, locale, isLoginContext);

            Handshaken = true;

            return(offset);
        }
示例#2
0
文件: Session.cs 项目: dorisoy/Zerio
        private void OnMessageFramed(ReadOnlySpan <byte> message)
        {
            if (_isWaitingForHandshake)
            {
                PeerId = Encoding.ASCII.GetString(message);
                HandshakeReceived?.Invoke(Encoding.ASCII.GetString(message));
                _isWaitingForHandshake = false;
                return;
            }

            MessageReceived?.Invoke(PeerId, message);
        }
示例#3
0
        public async Task Listen(Stream client, ResolveToServerEndpoints resolveDelegate)
        {
            // Try and read Minecraft packet structure
            int packetLength = await client.ReadVarInt();

            // Read packet body
            byte[] buffer = new byte[packetLength];
            await client.ReadAsync(buffer, 0, packetLength);

            var packetStream = new MemoryStream(buffer);

            int packetId = await packetStream.ReadVarInt();

            if (packetId != 0)
            {
                // Not handshake packet
                throw new ProtocolException("Illegal packet ID for handshake");
            }

            // Read handshake packet
            var handshake = await MinecraftHandshake.Read(packetStream);

            HandshakeReceived?.Invoke(this, handshake);

            // Resolve to a server endpoint based on handshake
            ProxyRule.ProxyEndpoint[] endpoints = resolveDelegate(handshake);
            if (endpoints == null || endpoints.Length == 0)
            {
                await WriteDisconnectPacket(client, $"Proxy server has no server for this hostname.", "red");

                throw new NoServersMatchException(handshake);
            }

            // Try to connect to an endpoint
            NetworkStream tunnel = null;

            ProxyRule.ProxyEndpoint connectedEndpoint = null;
            foreach (var endpointObj in endpoints)
            {
                try
                {
                    // This will just grab the endpoint, or do a DNS lookup if needed
                    IPEndPoint endpoint = await endpointObj.GetEndpoint();

                    var tunnelClient = new TcpClient();
                    await tunnelClient.ConnectAsync(endpoint.Address, endpoint.Port);

                    tunnel = tunnelClient.GetStream();

                    connectedEndpoint = endpointObj;
                    Connected?.Invoke(this, endpointObj);
                    break;
                }
                catch (Exception e)
                {
                    EndpointFailed?.Invoke(this, endpointObj);
                }
            }

            if (tunnel == null || connectedEndpoint == null)
            {
                await WriteDisconnectPacket(client, $"Proxy server cannot connect to origin server.", "red");

                throw new Exception("No server endpoints are accessible.");
            }

            // Modify handshake before we resend it to appear as if we connected directly to the target server
            bool fmlMagicStringPresent = handshake.ServerAddress.EndsWith("\0FML\0");

            if (connectedEndpoint.DnsHostname == null)
            {
                handshake.ServerAddress = connectedEndpoint.Endpoint.Address.ToString();
            }
            else
            {
                handshake.ServerAddress = connectedEndpoint.DnsHostname;
            }

            // Reappend FML magic string
            if (fmlMagicStringPresent)
            {
                handshake.ServerAddress += "\0FML\0";
            }

            handshake.Port = (ushort)connectedEndpoint.Port;

            try
            {
                // Resend handshake packet
                var resendHandshakeStream = new MemoryStream();
                await resendHandshakeStream.WriteVarInt(0); // Packet ID 0 (handshake)

                await handshake.Write(resendHandshakeStream);

                byte[] resendHandshakeBytes = resendHandshakeStream.ToArray();

                await tunnel.WriteVarInt(resendHandshakeBytes.Length);                         // Packet length

                await tunnel.WriteAsync(resendHandshakeBytes, 0, resendHandshakeBytes.Length); // Packet body

                // Proxy traffic backwards and forwards
                await Task.WhenAny(client.CopyToAsync(tunnel), tunnel.CopyToAsync(client));

                // Close connection
                tunnel?.Close();
                client?.Close();
            }
            catch {}
        }
示例#4
0
 private void HandleHandshake(string connectionId) => HandshakeReceived?.Invoke(this, connectionId);