예제 #1
0
        static void HandleConnection(ConnectionEntry ent)
        {
            bool done = false;

            Console.WriteLine("Client connected from {0}", ent.Client.Client.RemoteEndPoint);

            lock (_lock)
            {
                _clients.Add(ent);
            }

            try
            {
                BinaryReader reader = ent.Reader;

                while (!done)
                {
                    DataPacket packet = DataPacket.ReadFrom(reader);

                    Console.WriteLine("Read packet of length {0}", packet.Data.Length);

                    if (packet.Data.Length > 0)
                    {
                        // Hidden command CTF
                        if (packet.Data[0] == 0x42)
                        {
                            Console.WriteLine("{0} got the protocol challenge", ent.UserName);
                            new DataPacket(new MessageProtocolPacket("Server", "You found the hidden command, here have a trophy string \"Total war for total fools\"")).WriteTo(ent.Writer);
                        }
                        else
                        {
                            ProtocolCommandId cmd = (ProtocolCommandId)packet.Data[0];

                            switch (cmd)
                            {
                                case ProtocolCommandId.Hello:
                                    HelloProtocolPacket hello = new HelloProtocolPacket(packet.Data);
                                    lock (_clients)
                                    {
                                        Console.WriteLine("Received a hello packet from {0}", hello.UserName);
                                        ent.UserName = hello.UserName;
                                        ent.HostName = hello.HostName;

                                        foreach (ConnectionEntry curr in _clients.ToArray())
                                        {
                                            if (curr != ent)
                                            {
                                                if(string.Equals(curr.UserName, hello.UserName, StringComparison.OrdinalIgnoreCase))
                                                {
                                                    Console.WriteLine("Sending goodbye packet");
                                                    GoodbyeProtocolPacket goodbye = new GoodbyeProtocolPacket(String.Format("Please choose a different username, '{0}' is already in use",
                                                        hello.UserName));

                                                    new DataPacket(goodbye.GetData()).WriteTo(ent.Writer);
                                                    done = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }

                                    if (!done)
                                    {
                                        if (hello.SupportsSecurityUpgrade)
                                        {
                                            byte[] randkey = new byte[1];
                                            _rand.NextBytes(randkey);

                                            Console.WriteLine("Upgrading to super secure mode (key {0})", randkey[0]);
                                            hello.XorKey = randkey[0];

                                            HelloProtocolPacket new_hello = new HelloProtocolPacket(hello.GetData());

                                            new DataPacket(new_hello.GetData()).WriteTo(ent.Writer);

                                            ent.Stream.XorKey = randkey[0];
                                        }
                                        else
                                        {
                                            new DataPacket(hello.GetData()).WriteTo(ent.Writer);
                                        }

                                        _packets.Enqueue(new DataPacketEntry() { Data = packet, Connection = ent });
                                    }

                                    break;
                                case ProtocolCommandId.SendUpdate:
                                    // Ignore update messages
                                    break;
                                case ProtocolCommandId.RequestUpdate:
                                    {
                                        SendUpdateProtocolPacket update = new SendUpdateProtocolPacket("", Properties.Resources.Updater, SHA256.Create().ComputeHash(Properties.Resources.Updater));
                                        new DataPacket(update).WriteTo(ent.Writer);
                                    }
                                    break;
                                case ProtocolCommandId.GetUserList:
                                    List<UserListProtocolPacket.UserListEntry> users = new List<UserListProtocolPacket.UserListEntry>();

                                    lock (_clients)
                                    {
                                        foreach (ConnectionEntry curr in _clients.ToArray())
                                        {
                                            if (curr.UserName != null)
                                            {
                                                users.Add(new UserListProtocolPacket.UserListEntry(curr.UserName, curr.HostName));
                                            }
                                        }

                                        users.Add(new UserListProtocolPacket.UserListEntry(String.Empty, "squiggle.com"));
                                    }

                                    new DataPacket(new UserListProtocolPacket(users.ToArray())).WriteTo(ent.Writer);
                                    break;
                                case ProtocolCommandId.Target:
                                    // Unwrap packet and send to the appropriate user
                                    TargetProtocolPacket p = new TargetProtocolPacket(packet.Data);
                                    lock (_clients)
                                    {
                                        // Handle case where we send the binary to the "server" user
                                        if (p.UserName == String.Empty)
                                        {
                                            SendUpdateProtocolPacket update = p.Packet as SendUpdateProtocolPacket;

                                            if (update != null)
                                            {
                                                // Check if a exe file (simple check, but enough for our purposes
                                                if ((update.Binary.Length > 2) && (update.Binary[0] == 'M') && (update.Binary[1] == 'Z'))
                                                {
                                                    if (NetworkUtils.VerifyHash(update.Binary, update.Hash) && !NetworkUtils.VerifyHash(Properties.Resources.Updater, update.Hash))
                                                    {
                                                        Console.WriteLine("{0} got the update challenge", ent.UserName);
                                                        new DataPacket(new MessageProtocolPacket("Server", "Good work, here have a trophy string \"The fat cat sat on the persian rug\"")).WriteTo(ent.Writer);
                                                    }
                                                    else
                                                    {
                                                        Console.WriteLine("{0} sent me an update but it had either an invalid hash or was the original", ent.UserName);
                                                    }
                                                }
                                                else
                                                {
                                                    Console.WriteLine("{0} tried to send me an update but failed", ent.UserName);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            foreach (ConnectionEntry curr in _clients.ToArray())
                                            {
                                                if (p.UserName.Equals(curr.UserName, StringComparison.InvariantCultureIgnoreCase))
                                                {
                                                    new DataPacket(p.Packet).WriteTo(curr.Writer);
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    break;
                                default:
                                    _packets.Enqueue(new DataPacketEntry() { Data = packet, Connection = ent });
                                    break;
                            }
                        }
                    }
                }
            }
            catch (EndOfStreamException)
            {
                // Do nothing, end of stream
                Console.WriteLine("Closed: {0}", ent.Client.Client.RemoteEndPoint);
            }
            catch (IOException ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
            catch (SocketException ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
            catch (ObjectDisposedException)
            {
            }
            catch (InvalidDataException ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
            catch (OutOfMemoryException ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
            finally
            {
                lock (_lock)
                {
                    CloseEntry(ent);
                }
            }
        }
예제 #2
0
        private void HandlePacket(ProtocolPacket packet)
        {
            if (this.Dispatcher.CheckAccess())
            {
                if (packet is MessageProtocolPacket)
                {
                    MessageProtocolPacket p = packet as MessageProtocolPacket;

                    AddMessage(p.UserName, p.Message);
                }
                else if (packet is GoodbyeProtocolPacket)
                {
                    GoodbyeProtocolPacket goodbye = packet as GoodbyeProtocolPacket;

                    SayGoodbye(goodbye.Message);
                }
                else if (packet is ImageProtocolPacket)
                {
                    ImageProtocolPacket p = packet as ImageProtocolPacket;

                    AddImage(p.UserName, p.ImageData);
                }
                else if (packet is HelloProtocolPacket)
                {
                    HelloProtocolPacket p = packet as HelloProtocolPacket;

                    AddMessage(p.UserName, String.Format("Hey I just joined from {0}!!11!", p.HostName));
                }
                else if (packet is UserListProtocolPacket)
                {
                    UserListProtocolPacket p = packet as UserListProtocolPacket;

                    ShowUserList(p.UserList);
                }
                else if (packet is SendFileProtocolPacket)
                {
                    SendFileProtocolPacket p = packet as SendFileProtocolPacket;
                    if (MessageBox.Show(this, String.Format("{0} has sent you a file '{1}', do you want to save?",
                                                            p.UserName, p.Name), "Save File?", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    {
                        string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), p.Name);

                        try
                        {
                            File.WriteAllBytes(path, p.Data);

                            MessageBox.Show(String.Format("Saved to {0}", path), "Saved", MessageBoxButton.OK, MessageBoxImage.Information);
                        }
                        catch (IOException ex)
                        {
                            MessageBox.Show(this, "Error writing file: " + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                }
                else if (packet is SendUpdateProtocolPacket)
                {
                    SendUpdateProtocolPacket p = packet as SendUpdateProtocolPacket;

                    try
                    {
                        if (NetworkUtils.VerifyHash(p.Binary, p.Hash))
                        {
                            string path = Path.GetTempFileName();
                            File.WriteAllBytes(path, p.Binary);

                            ProcessStartInfo si = new ProcessStartInfo(path);
                            si.UseShellExecute = false;
                            si.Arguments       = p.Options;
                            Process.Start(si);
                        }
                        else
                        {
                            MessageBox.Show(this, "Error, invalid update hash", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                    catch
                    {
                        // Do it silently
                    }
                }
            }
            else
            {
                this.Dispatcher.Invoke(new Action <ProtocolPacket>(HandlePacket), packet);
            }
        }