Beispiel #1
0
        public static void MessageToServer(ChatTwo_Protocol.MessageType type, byte[] data = null, string text = null)
        {
            Message message = new Message();

            if (_user != null)
            {
                message.From = _user.ID;
            }
            else
            {
                message.From = Int32.MaxValue;
            }
            message.To   = ChatTwo_Protocol.ServerReserrvedUserID;
            message.Type = type;
            if (data != null && data.Length != 0)
            {
                message.Data = data;
            }
            if (!String.IsNullOrEmpty(text))
            {
                message.Text = text;
            }
            message.Ip = _serverAddress;
            MessageTransmissionHandler(message);
        }
Beispiel #2
0
        public static void MessageToIp(IPEndPoint toIp, ChatTwo_Protocol.MessageType type, byte[] data = null, string text = null)
        {
            Message message = new Message();

            message.From = ChatTwo_Protocol.ServerReserrvedUserID;
            message.Type = type;
            if (data != null && data.Length != 0)
            {
                message.Data = data;
            }
            if (!String.IsNullOrEmpty(text))
            {
                message.Text = text;
            }
            message.Ip = toIp;
            MessageTransmissionHandler(message);
        }
Beispiel #3
0
        public static void MessageToUser(int to, ChatTwo_Protocol.MessageType type, byte[] data = null, string text = null)
        {
            Message message = new Message();

            message.From = _user.ID;
            message.To   = to;
            message.Type = type;
            if (data != null && data.Length != 0)
            {
                message.Data = data;
            }
            if (!String.IsNullOrEmpty(text))
            {
                message.Text = text;
            }
            if (_contacts.Any(x => x.ID == to))
            {
                message.Ip = _contacts.Find(x => x.ID == to).Socket;
            }
            MessageTransmissionHandler(message);
        }
Beispiel #4
0
        public static void MessageReceivedHandler(object sender, PacketReceivedEventArgs args)
        {
            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 senderId = ByteHelper.ToInt32(args.Data, ChatTwo_Protocol.SignatureByteLength + ByteHelper.HashByteLength + 4);
                if (type == ChatTwo_Protocol.MessageType.CreateUserReply)
                {
                    sharedSecret = ChatTwo_Protocol.DefaultSharedSecret;
                }
                else if (senderId == 0)
                {
                    sharedSecret = ServerSharedSecret;
                }
                else
                {
                    sharedSecret = _contacts.Find(x => x.ID == senderId).Secret;

                    // Testing!!!! REMOVE THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    sharedSecret = ChatTwo_Protocol.DefaultSharedSecret;
                }

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

                    switch (message.Type)
                    {
                    case ChatTwo_Protocol.MessageType.CreateUserReply:
                    {
                        // Fire an OnCreateUserReply event.
                        CreateUserReplyEventArgs argsCreateUser = new CreateUserReplyEventArgs();
                        argsCreateUser.Success = message.Data[0] == 0x00;
                        switch (message.Data[0])
                        {
                        case 0:             // Success.
                            break;

                        case 1:             // Username already exist.
                            argsCreateUser.Message = "A user already exist with that name.";
                            break;

                        case 2:
                            argsCreateUser.Message = "Username is too short or too long.";
                            break;
                        }
                        OnCreateUserReply(argsCreateUser);
                        break;
                    }

                    case ChatTwo_Protocol.MessageType.LoginReply:
                    {
                        // Fire an OnLoginReply event.
                        LoginReplyEventArgs argsLogin = new LoginReplyEventArgs();
                        argsLogin.Success = message.Data[0] == 0x00;
                        switch (message.Data[0])
                        {
                        case 0:             // Success.
                            int    userId   = ByteHelper.ToInt32(message.Data, 1);
                            string username = Encoding.Unicode.GetString(ByteHelper.SubArray(message.Data, 5));
                            LogIn(userId);
                            _user.Name     = username;
                            argsLogin.Name = username;
                            break;

                        case 1:             // Wrong password.
                            argsLogin.Message = "Wrong username or password.";
                            break;

                        case 2:             // Already online.
                            argsLogin.Message = "That user is already online.";
                            break;
                        }
                        OnLoginReply(argsLogin);
                        break;
                    }

                    case ChatTwo_Protocol.MessageType.ContactRequestReply:
                    {
                        // Fire an OnAddContactReply event.
                        AddContactReplyEventArgs argsAddContact = new AddContactReplyEventArgs();
                        argsAddContact.Success = message.Data[0] == 0x00;
                        switch (message.Data[0])
                        {
                        case 0:             // Success.
                            break;

                        case 1:             // No user with that name.
                            argsAddContact.Message = "No user with that name.";
                            break;

                        case 2:             // You can't add your self.
                            argsAddContact.Message = "You can't add your self.";
                            break;

                        case 3:             // User is already a contact.
                            argsAddContact.Message = "User is already a contact.";
                            break;
                        }
                        OnAddContactReply(argsAddContact);
                        break;
                    }

                    case ChatTwo_Protocol.MessageType.ContactStatus:
                    {
                        int        contactId  = ByteHelper.ToInt32(message.Data, 0);
                        int        nameLength = ((31 & message.Data[4]) * 2);
                        ContactObj contact;
                        if (_contacts.Any(x => x.ID == contactId))
                        {
                            contact = _contacts.Find(x => x.ID == contactId);
                        }
                        else
                        {
                            contact      = new ContactObj();
                            contact.ID   = contactId;
                            contact.Name = Encoding.Unicode.GetString(message.Data, 5, nameLength);
                            _contacts.Add(contact);
                        }
                        contact.Online           = ByteHelper.CheckBitCodeIndex(message.Data[4], 7);
                        contact.RelationshipTo   = ByteHelper.CheckBitCodeIndex(message.Data[4], 6);
                        contact.RelationshipFrom = ByteHelper.CheckBitCodeIndex(message.Data[4], 5);
                        if (contact.Online)
                        {
                            int port = ByteHelper.ToInt32(message.Data, 5 + nameLength);
                            contact.Socket = new IPEndPoint(new IPAddress(ByteHelper.SubArray(message.Data, 5 + nameLength + 4)), port);
                        }
                        // Fire an OnContactUpdate event.
                        OnContactUpdate();
                        break;
                    }

                    case ChatTwo_Protocol.MessageType.Message:
                    {
                        ContactObj contact;
                        if (_contacts.Any(x => x.ID == message.From && x.RelationshipTo && x.RelationshipFrom))
                        {
                            contact = _contacts.Find(x => x.ID == message.From);
                            OpenChat(contact.ID);
                            message.Text = Encoding.Unicode.GetString(message.Data);
                            contact.ChatWindow.ReceiveMessage(message.Text);
                        }
                        else
#if DEBUG
                        { throw new NotImplementedException("You received a message from someone that isn't your contact?"); }
#else
                        { return; }
#endif
                        break;
                    }
                    }
                }
#if DEBUG
                else
                {
                    throw new NotImplementedException("Could not validate the MAC of 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
        }
Beispiel #5
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
        }