Exemplo n.º 1
0
        public static byte[] CreateMutualContactStatusMessage(int userId)
        {
            UserObj user;

            if (_users.Any(x => x.ID == userId))
            {
                user = _users.Find(x => x.ID == userId);
            }
            else
            {
                user = DatabaseCommunication.ReadUser(userId);
            }

            byte[] dataBytes;

            dataBytes = ByteHelper.ConcatinateArray(BitConverter.GetBytes(user.ID), new byte[] { (byte)((user.Online ? 128 : 0) + 64 + 32 + user.Name.Length) }, Encoding.Unicode.GetBytes(user.Name));

            if (user.Online)
            {
                byte[] socketBytes = ByteHelper.ConcatinateArray(BitConverter.GetBytes(user.Socket.Port), user.Socket.Address.GetAddressBytes());
                dataBytes = ByteHelper.ConcatinateArray(dataBytes, socketBytes);
            }

            return(dataBytes);
        }
Exemplo n.º 2
0
        public static void TellMutualContactsAboutUserStatusChange(int userId)
        {
            List <int> contacts = DatabaseCommunication.GetOnlineContacts(userId);

            if (contacts.Count != 0) // if the user has no online contacts, there is no need to do the rest.
            {
                byte[] contactStatusMessageBytes = CreateMutualContactStatusMessage(userId);
                foreach (int contactId in contacts)
                {
                    MessageToUser(contactId, ChatTwo_Protocol.MessageType.ContactStatus, contactStatusMessageBytes);
                }
            }
        }
Exemplo n.º 3
0
        private void StatusUpdate_Click(object sender, EventArgs e)
        {
            bool worked = DatabaseCommunication.UpdateUser((int)numericUpDown1.Value, new System.Net.IPEndPoint(new System.Net.IPAddress(new byte[] { 10, 0, 0, 1 }), 9020));

            if (worked)
            {
                WriteLog("user[" + (int)numericUpDown1.Value + "] Changed to online.", Color.Blue.ToArgb());
            }
            else
            {
                WriteLog("user[" + (int)numericUpDown1.Value + "] Does not exist.", Color.Red.ToArgb());
            }
        }
Exemplo n.º 4
0
        private void ReadUser_Click(object sender, EventArgs e)
        {
            UserObj user = DatabaseCommunication.ReadUser((int)numericUpDown1.Value);

            if (user != null)
            {
                WriteLog(user.ToString(), Color.Purple.ToArgb());
            }
            else
            {
                WriteLog("user[" + (int)numericUpDown1.Value + "] Does not exist.", Color.Red.ToArgb());
            }
        }
Exemplo n.º 5
0
        private void CreateUser_Click(object sender, EventArgs e)
        {
            string hashedPassword = ByteHelper.GetHashString(Encoding.Unicode.GetBytes(textBox2.Text));
            bool   worked         = DatabaseCommunication.CreateUser(textBox1.Text, hashedPassword);

            if (worked)
            {
                WriteLog("user[\"" + textBox1.Text + "\"] Was created successfully.", Color.Blue.ToArgb());
            }
            else
            {
                WriteLog("user[\"" + textBox1.Text + "\"] Was not created.", Color.Red.ToArgb());
            }
        }
Exemplo n.º 6
0
        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult reply = MessageBox.Show(this, "Are you sure you want to close the server?", "Close?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (reply == DialogResult.No)
            {
                e.Cancel = true;
            }
            else
            {
                // Add closing of sockets and stuff here!
                _server.Stop();
                DatabaseCommunication.Disconnect();
            }
        }
Exemplo n.º 7
0
        private void btnSqlUpdate_Click(object sender, EventArgs e)
        {
            bool worked = DatabaseCommunication.UpdateDatabase(tbxSqlUser.Text, tbxSqlPassword.Text, tbxSqlAddress.Text, (int)nudSqlPort.Value);

            if (worked)
            {
                tbxSql_ConnectionStringValuesChanged(null, null);
                toolStripStatusLabel1.Text = "SQL database Updated";
                btnSqlTest_Click(null, null);
            }
            else
            {
                WriteLog("Could not update the database.", Color.Red.ToArgb());
            }
        }
Exemplo n.º 8
0
        public static void SendAllContacts(int userId)
        {
            Dictionary <int, byte> contacts = DatabaseCommunication.GetAllContacts(userId);

            foreach (KeyValuePair <int, byte> contact in contacts)
            {
                byte[] contactStatusMessageBytes;
                if (contact.Value == 0x03) // 0b00000011
                {
                    contactStatusMessageBytes = CreateMutualContactStatusMessage(contact.Key);
                }
                else
                {
                    contactStatusMessageBytes = CreateNonMutualContactStatusMessage(contact.Key, ByteHelper.CheckBitCodeIndex(contact.Value, 0), ByteHelper.CheckBitCodeIndex(contact.Value, 1));
                }
                MessageToUser(userId, ChatTwo_Protocol.MessageType.ContactStatus, contactStatusMessageBytes);
            }
        }
Exemplo n.º 9
0
        public static byte[] CreateNonMutualContactStatusMessage(int userId, bool relationshipTo, bool relationshipFrom)
        {
            UserObj user;

            if (_users.Any(x => x.ID == userId))
            {
                user = _users.Find(x => x.ID == userId);
            }
            else
            {
                user = DatabaseCommunication.ReadUser(userId);
            }

            byte[] dataBytes;

            dataBytes = ByteHelper.ConcatinateArray(BitConverter.GetBytes(user.ID), new byte[] { (byte)((relationshipTo ? 64 : 0) + (relationshipFrom ? 32 : 0) + user.Name.Length) }, Encoding.Unicode.GetBytes(user.Name));

            return(dataBytes);
        }
Exemplo n.º 10
0
 private void btnSqlConnect_Click(object sender, EventArgs e)
 {
     tbxSqlUser.ReadOnly     = !tbxSqlUser.ReadOnly;
     tbxSqlPassword.ReadOnly = !tbxSqlPassword.ReadOnly;
     tbxSqlAddress.ReadOnly  = !tbxSqlAddress.ReadOnly;
     nudSqlPort.Enabled      = !nudSqlPort.Enabled;
     btnSqlTest.Enabled      = !btnSqlTest.Enabled;
     if (DatabaseCommunication.Active)
     {
         DatabaseCommunication.Disconnect();
         btnSqlConnect.Text = "Start Database Connection";
         tabSqlTest.Parent  = null;
     }
     else
     {
         DatabaseCommunication.Connect(tbxSqlUser.Text, tbxSqlPassword.Text, tbxSqlAddress.Text, (int)nudSqlPort.Value);
         btnSqlConnect.Text = "Stop Database Connection";
         tabSqlTest.Parent  = tabControl1;
     }
     UpdateServerStatus();
 }
Exemplo n.º 11
0
 public static void UserConnect(UserObj user)
 {
     DatabaseCommunication.UpdateUser(user.ID, user.Socket);
     TellMutualContactsAboutUserStatusChange(user.ID);
     SendAllContacts(user.ID);
 }
Exemplo n.º 12
0
        public static void MessageReceivedHandler(object sender, PacketReceivedEventArgs args)
        {
            if (!DatabaseCommunication.Active)
#if DEBUG
            { throw new NotImplementedException("Database connection was not active and a reply for this have not been implemented yet."); }
            // Need to add a simple debug message here, but this works as a great breakpoint until then.
            // Also need to make some kind of error message I can send back to the client.
#else
            { return; }
#endif

            if (args.Data[0] == 0x92)
            {
                string sharedSecret;
                // Position of the Type byte is 30 (SignatureByteLength + MacByteLength + TimezByteLength + UserIdByteLength).
                ChatTwo_Protocol.MessageType type = (ChatTwo_Protocol.MessageType)args.Data[ChatTwo_Protocol.SignatureByteLength + ByteHelper.HashByteLength + 4 + 4];
                // Position of the UserID bytes is 26 (SignatureByteLength + MacByteLength + TimezByteLength) with a length of 4.
                int userId = ByteHelper.ToInt32(args.Data, ChatTwo_Protocol.SignatureByteLength + ByteHelper.HashByteLength + 4);
                if (type == ChatTwo_Protocol.MessageType.CreateUser)
                {
                    sharedSecret = ChatTwo_Protocol.DefaultSharedSecret;
                }
                else if (type == ChatTwo_Protocol.MessageType.Login)
                {
#if DEBUG
                    byte[] test = ByteHelper.SubArray(args.Data, ChatTwo_Protocol.SignatureByteLength + ByteHelper.HashByteLength + 4);
#endif
                    // Don't take the Timez as part of the sharedSecret. This is mostly because of a problem I have in the client where I make the sharedSecrt before I add the Timez.
                    sharedSecret = ByteHelper.GetHashString(ByteHelper.SubArray(args.Data, ChatTwo_Protocol.SignatureByteLength + ByteHelper.HashByteLength + 4));
                }
                else
                {
                    if (!_users.Any(x => x.ID == userId))
                    {
                        return; // This is mostly to prevent clients with a connection to a previces server instants from crashing the server. Need to fix this.
                    }
                    sharedSecret = _users.Find(x => x.ID == userId).Secret;
                }


                if (ChatTwo_Protocol.ValidateMac(args.Data, sharedSecret))
                {
                    Message message = ChatTwo_Protocol.MessageReceivedHandler(args);

                    switch (message.Type)
                    {
                    case ChatTwo_Protocol.MessageType.CreateUser:
                    {
                        string passwordHash = Convert.ToBase64String(message.Data, 0, ByteHelper.HashByteLength);
                        string username     = Encoding.Unicode.GetString(ByteHelper.SubArray(message.Data, ByteHelper.HashByteLength));
                        if (username.Length < 1 || username.Length > 30)
                        {
                            // Username is too short or too long.
                            MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.CreateUserReply, new byte[] { 0x02 });
                            return;
                        }
                        bool worked = DatabaseCommunication.CreateUser(username, passwordHash);
                        if (!worked)
                        {
                            // Some error prevented the user from being created. Best guess is that a user with that name already exist.
                            MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.CreateUserReply, new byte[] { 0x01 });
                            return;
                        }
                        // Uesr creation was successful!
                        MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.CreateUserReply, new byte[] { 0x00 });
                        break;
                    }

                    case ChatTwo_Protocol.MessageType.Login:
                    {
                        string  passwordHash = Convert.ToBase64String(message.Data, 0, ByteHelper.HashByteLength);
                        string  username     = Encoding.Unicode.GetString(ByteHelper.SubArray(message.Data, ByteHelper.HashByteLength));
                        UserObj user         = DatabaseCommunication.LoginUser(username, passwordHash);
                        if (user == null)
                        {
                            // Have to send back a LoginReply message here with a "wrong username/password" error.
                            _tempUsers.Add(message.Ip, sharedSecret);
                            MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.LoginReply, new byte[] { 0x01 });
                            return;
                        }
                        if (_users.Any(x => x.ID == user.ID))
                        {
                            // Have to send back a LoginReply message here with a "User is already online" error.
                            _tempUsers.Add(message.Ip, sharedSecret);
                            MessageToIp(message.Ip, ChatTwo_Protocol.MessageType.LoginReply, new byte[] { 0x02 });
                            return;
                        }
                        user.Secret = sharedSecret;
                        user.Socket = message.Ip;
                        user.Online = true;
                        _users.Add(user);
                        MessageToUser(user.ID, ChatTwo_Protocol.MessageType.LoginReply, ByteHelper.ConcatinateArray(new byte[] { 0x00 }, BitConverter.GetBytes(user.ID)), user.Name);
                        UserConnect(user);
                        break;
                    }

                    case ChatTwo_Protocol.MessageType.Status:
                    {
                        UserObj user = _users.Find(x => x.ID == message.From);
                        if (user != null)         // If the user is not found, don't do anything. (Can this happen?)
                        {
                            if (!IPEndPoint.Equals(user.Socket, message.Ip))
                            {
                                user.Socket = message.Ip;
                                // Message all contacts of the user with the new IP change.
                                TellMutualContactsAboutUserStatusChange(user.ID);
                            }
                            DatabaseCommunication.UpdateUser(user.ID, user.Socket);
                        }
                        break;
                    }

                    case ChatTwo_Protocol.MessageType.ContactRequest:
                    {
                        string  username = Encoding.Unicode.GetString(message.Data);
                        UserObj user     = DatabaseCommunication.LookupUser(username);
                        if (user == null)
                        {
                            // Have to send back a ContactRequestReply message here with a "No user with that name" error.
                            MessageToUser(message.From, ChatTwo_Protocol.MessageType.ContactRequestReply, new byte[] { 0x01 });
                            return;
                        }
                        if (user.ID == message.From)
                        {
                            // Have to send back a ContactRequestReply message here with a "You can't add your self" error.
                            MessageToUser(message.From, ChatTwo_Protocol.MessageType.ContactRequestReply, new byte[] { 0x02 });
                            return;
                        }
                        bool added = DatabaseCommunication.AddContact(message.From, user.ID);
                        if (!added)
                        {
                            // Have to send back a ContactRequestReply message here with a "User is already a contact" error.
                            MessageToUser(message.From, ChatTwo_Protocol.MessageType.ContactRequestReply, new byte[] { 0x03 });
                            return;
                        }
                        MessageToUser(message.From, ChatTwo_Protocol.MessageType.ContactRequestReply, new byte[] { 0x00 });
                        //if (_users.Any(x => x.ID == user.ID))
                        //    TellContactsAboutUserStatusChange(message.From, true); // Need to figure this out.
                        break;
                    }
                    }
                }
#if DEBUG
                else
                {
                    throw new NotImplementedException("Could not validate the MAC of the received message.");
                }
                // Need to add a simple debug message here, but this works as a great breakpoint until then.
#endif
            }
#if DEBUG
            else
            {
                throw new NotImplementedException("Could not validate the signature of the received message. The signature was \"0x" + args.Data[0] + "\" but only \"0x92\" is allowed.");
            }
            // Need to add a simple debug message here, but this works as a great breakpoint until then.
#endif
        }
Exemplo n.º 13
0
        private void btnSqlTest_Click(object sender, EventArgs e)
        {
            tbxSql_ConnectionStringValuesChanged(null, null);
            btnSqlTest.Enabled = false;

            // Basic user feedback.
            toolStripStatusLabel1.Text = "Testing connection and access to the database...";
            statusStrip1.Refresh(); // Has to be done or the statusStrip won't display the new toolStripStatusLabel text.

            // Test the connection and access, giving the user feedback if it fails.
            DatabaseCommunication.ConnectionTestResult dbTest = DatabaseCommunication.TestConnection(tbxSqlUser.Text, tbxSqlPassword.Text, tbxSqlAddress.Text, (int)nudSqlPort.Value);

            // Check the result of the connetion test.
            bool connectTestSuccessful = dbTest == DatabaseCommunication.ConnectionTestResult.Successful;

            if (connectTestSuccessful)
            {
                toolStripStatusLabel1.Text = "Database connection test: successful";
                lblSqlConnection.Text      = "Test: successful";
                toolTip1.SetToolTip(lblSqlConnection, "");
                btnSqlConnect.Enabled = true;
            }
            else
            {
                string errorMessage;
                string errorTip;
                switch (dbTest)
                {
                case DatabaseCommunication.ConnectionTestResult.NoConnection:
                    errorMessage = "Could not connect to the server at \"" + tbxSqlAddress.Text + ":" + (int)nudSqlPort.Value + "\"";
                    errorTip     = "." + Environment.NewLine + Environment.NewLine +
                                   "Please make sure the MySQL server is running and the IP address and port is correct.";
                    break;

                case DatabaseCommunication.ConnectionTestResult.FailLogin:
                    errorMessage = "Login rejected by server";
                    errorTip     = "." + Environment.NewLine + Environment.NewLine +
                                   "Please make sure the username and password is correct.";
                    break;

                case DatabaseCommunication.ConnectionTestResult.NoPermission:
                    errorMessage = "Permission failed for user";
                    errorTip     = "." + Environment.NewLine + Environment.NewLine +
                                   "Talk to the system admin to gain access to the MySQL server.";
                    break;

                case DatabaseCommunication.ConnectionTestResult.MissingDatabase:
                    errorMessage = "Database does not exist";
                    errorTip     = "." + Environment.NewLine + Environment.NewLine +
                                   "You can create/repair the database by clicking the button below.";
                    btnSqlCreate.Enabled = true;
                    break;

                case DatabaseCommunication.ConnectionTestResult.MissingTable:
                    errorMessage = "One or more of the tables do not exist";
                    errorTip     = "." + Environment.NewLine + Environment.NewLine +
                                   "You can create/repair the database by clicking the button below.";
                    btnSqlCreate.Enabled = true;
                    break;

                case DatabaseCommunication.ConnectionTestResult.OutDated:
                    errorMessage         = "SQL database need to be updated";
                    errorTip             = ".";
                    btnSqlUpdate.Enabled = true;
                    break;

                default:
                    errorMessage = "Unknown SQL error";
                    errorTip     = ".";
                    break;
                }
                if (sender != null)
                {
                    MessageBox.Show(errorMessage + errorTip, "SQL Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                toolStripStatusLabel1.Text = "Database connection test: failed. " + errorMessage;
                lblSqlConnection.Text      = "Test: failed";
                lblSqlConnection.Image     = _infoTip;
                toolTip1.SetToolTip(lblSqlConnection, errorMessage + errorTip);
            }

            btnSqlTest.Enabled = true;
        }