Beispiel #1
0
        //every client runs on its own thread.
        //File send and receives also runs on its own thread. this is to keep GUI responsive.
        private void recvMessage(object s)
        {
            ConnectedClient client       = (ConnectedClient)s;
            bool            bRecvMessage = true;

            while (bRecvMessage)
            {
                try
                {
                    nBuffer buffer = new nBuffer();
                    int     ReadBytes;
                    if ((ReadBytes = buffer.ReceiveCryptoBuffer(client.socket, client.CC.Salt)) > 0)
                    {
                        #region RecvClientSettings
                        if (buffer.GetID() == MsgType.ClientSettings)
                        {
                            Console.WriteLine(client.socket.RemoteEndPoint.ToString() + ": Received Client settings");
                            ClientSettings CSettings;

                            CSettings    = buffer.GetObject <ClientSettings>();
                            CSettings.Ip = client.CC.Ip;

                            bool InGroupList = false;

                            for (int i = 0; i < ConnectedClients.Count(); i++)
                            {
                                if (ConnectedClients[i].CC.Ip == client.CC.Ip)
                                {
                                    Console.WriteLine(ConnectedClients[i].Name + " Renamed to: " + CSettings.Name);
                                    ConnectedClients[i].Name = CSettings.Name;
                                }
                            }
                            client.Groups = CSettings.Groups;
                            string[] tmpGroups = CSettings.Groups.Split(';');
                            foreach (string group in tmpGroups)
                            {
                                if (group != "")
                                {
                                    InGroupList = false;
                                    for (int i = 0; i < ChatGroupsContainer.Instance.Count; i++)
                                    {
                                        if (group == ChatGroupsContainer.Instance.at(i).GroupName)
                                        {
                                            InGroupList = true; // group is already in chatrgrouplist,
                                        }
                                    }
                                    if (!InGroupList)
                                    {
                                        ChatGroup cGroup = new ChatGroup();
                                        cGroup.GroupName = group;
                                        ChatGroupsContainer.Instance.Add(cGroup);
                                        AddGroupToDataGridview(cGroup);
                                        Console.WriteLine("Group " + group + " Added to List");
                                    }
                                    // check if user is in group, else add it, and check if name updated;
                                    for (int i = 0; i < ChatGroupsContainer.Instance.Count; i++)
                                    {
                                        bool UserInList = false;
                                        if (ChatGroupsContainer.Instance.at(i).GroupName == group)
                                        {
                                            for (int j = 0; j < ChatGroupsContainer.Instance.at(i).Members.Count; j++)
                                            {
                                                if (ChatGroupsContainer.Instance.at(i).Members[j].Ip == CSettings.Ip) // Member is in list
                                                {
                                                    UserInList = true;
                                                    ChatGroupsContainer.Instance.at(i).Members[j].Name = CSettings.Name; // update name.
                                                }
                                            }
                                            if (!UserInList)
                                            {
                                                ChatGroupsContainer.Instance.at(i).Members.Add(CSettings);
                                                Console.WriteLine(CSettings.Name + " Added to: " + ChatGroupsContainer.Instance.at(i).GroupName);
                                            }
                                        }
                                    }
                                }
                            }

                            // check all groups if it has the user, if it does, check if the user has specified the group, else delete it from that group
                            for (int j = 0; j < ChatGroupsContainer.Instance.Count; j++)
                            {
                                bool UserInGroup        = false;
                                bool UserSpecifiedGroup = false;
                                int  IndexOfUser        = -1;
                                for (int i = 0; i < ChatGroupsContainer.Instance.WholeList[j].Members.Count; i++)
                                {
                                    if (ChatGroupsContainer.Instance.at(j).Members[i].Ip == CSettings.Ip) // client is in the group
                                    {
                                        UserInGroup = true;
                                        foreach (string Cgroups in tmpGroups) // check if groupname is also specified by teh client;
                                        {
                                            if (Cgroups == ChatGroupsContainer.Instance.at(j).GroupName)
                                            {
                                                UserSpecifiedGroup = true;
                                            }
                                        }
                                        if (!UserSpecifiedGroup)
                                        {
                                            IndexOfUser = i;
                                        }
                                    }
                                }
                                if (UserInGroup && !UserSpecifiedGroup) // user is in chatgroup but not specified in tmpgroups.
                                {
                                    ChatGroupsContainer.Instance.at(j).Members.RemoveAt(IndexOfUser);
                                }
                            }
                            UpdateClientList();
                        }
                        #endregion

                        #region RecvTextMessage

                        if (buffer.GetID() == MsgType.TextMessage)
                        {
                            Console.WriteLine(client.socket.RemoteEndPoint.ToString() + ": Received TextMessage");
                            TextMessage TM = buffer.GetObject <TextMessage>();
                            PassMessage(TM);
                            if (LogChatMessages.Checked)
                            {
                                MessageLogger.LOG(TM, ChatGroupsContainer.Instance.WholeList);
                            }
                        }
                        #endregion

                        #region FileRecv/Send
                        if (buffer.GetID() == MsgType.SendFile) // Server Receives file
                        {
                            PrepareFileSend PFS = buffer.GetObject <PrepareFileSend>();
                            Console.WriteLine(client.socket.RemoteEndPoint.ToString() + ": Send File -> " + PFS.FileName + PFS.Ext);
                            buffer.innerbuffer.Clear();
                            buffer.ReceiveCryptoFileBuffer(client.socket, client.CC.Salt);
                            ServerFile SF = buffer.GetObject <ServerFile>(0);
                            // Encrypt current password into file;
                            byte[] Passwordbytes = Crypt.Base64Encode(BinaryFilesPassword);
                            byte[] binaryfile    = new byte[Passwordbytes.Length + SF.BinaryFile.Length];
                            Buffer.BlockCopy(Passwordbytes, 0, binaryfile, 0, Passwordbytes.Length);
                            Buffer.BlockCopy(SF.BinaryFile, 0, binaryfile, Passwordbytes.Length, SF.BinaryFile.Length); // copy binary file;

                            binaryfile = Crypt.Encrypt(binaryfile, BinaryFilesKey, BinaryFilesPassword);                // encrypt file and store it.

                            string     Path = Utils.AssemblyDirectory + "\\" + PFS.FileName + PFS.Ext + ".scbd";
                            FileStream fs   = null;
                            if (File.Exists(Path))
                            {
                                fs = new FileStream(Path, FileMode.Truncate, FileAccess.ReadWrite); // overwrite file
                            }
                            else
                            {
                                fs = new FileStream(Path, FileMode.OpenOrCreate, FileAccess.ReadWrite); // create new;
                            }
                            if (fs.CanWrite)
                            {
                                fs.Write(binaryfile, 0, binaryfile.Length);
                            }
                            fs.Close();
                            fs.Dispose();
                            SF.length  = binaryfile.Length;
                            SF.Ext     = PFS.Ext;
                            binaryfile = null;

                            // now we need to notify clients that there is a file for them.
                            TextMessage TM = new TextMessage();
                            TM.To      = PFS.to;
                            TM.From    = PFS.from;
                            TM.ID      = ChatBufferMessageType.Link;
                            TM.Message = PFS.FileName + PFS.Ext;
                            PassMessage(TM);

                            buffer.innerbuffer.Clear();
                            buffer.AddID(MsgType.FileSendComplete);
                            FileSendComplete FSC = new FileSendComplete();
                            FSC.complete = true;
                            buffer.AddObject(FSC);
                            buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                        }

                        #endregion

                        #region File Request Awsering
                        if (buffer.GetID() == MsgType.RequestFile) // Client requests file from server
                        {
                            bool        NoFile = true;
                            RequestFile RF     = buffer.GetObject <RequestFile>();
                            Console.WriteLine(client.socket.RemoteEndPoint.ToString() + ": Request File -> " + RF.Name);
                            buffer.innerbuffer.Clear();

                            byte[] binaryfile = new byte[] { };
                            string Path       = Utils.AssemblyDirectory + "\\" + RF.Name + ".scbd";
                            if (File.Exists(Path))
                            {
                                binaryfile = Crypt.Decrypt(File.ReadAllBytes(Path), BinaryFilesKey, BinaryFilesPassword);
                                byte[] passwordbytes          = Crypt.Base64Encode(BinaryFilesPassword); // get bytes of password
                                byte[] binarypasswordfromfile = new byte[passwordbytes.Length];          // allocate bytes
                                try
                                {
                                    // copy length of of current password from binrayfile on disk;
                                    Buffer.BlockCopy(binaryfile, 0, binarypasswordfromfile, 0, binarypasswordfromfile.Length);
                                    string DecodedBinaryPassword = Crypt.Base64Decode(binarypasswordfromfile); // decode password
                                    if (DecodedBinaryPassword == BinaryFilesPassword)                          // password from file is the same as current password;
                                    {
                                        Buffer.BlockCopy(binaryfile, passwordbytes.Length, binaryfile, 0, binaryfile.Length - passwordbytes.Length);
                                    }
                                    else // password was longer/smaller or same length but different chars.
                                    {
                                        Console.WriteLine("Encrypted password does not match current password, file could not be send to user : "******"Failed to Decrypt file from disk");
                                    Console.WriteLine(ex.Message + "/n/r " + ex.StackTrace);
                                }
                                NoFile = false;

                                PrepareFileSend PFS = new PrepareFileSend();
                                PFS.filesize = binaryfile.Length;
                                PFS.FileName = RF.Name;
                                PFS.ACK      = 0;
                                buffer.AddID(MsgType.SendFile);
                                buffer.AddObject(PFS);
                                buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                                buffer.innerbuffer.Clear();
                                buffer.CryptoSize = 0;

                                buffer.ReceiveCryptoBuffer(client.socket, client.CC.Salt);
                                if (buffer.GetID() == MsgType.SendOK)
                                {
                                    buffer.innerbuffer.Clear();
                                    ServerFile serverfile = new ServerFile();
                                    string[]   splitname  = RF.Name.Split('.');
                                    serverfile.Name       = splitname[0]; // name
                                    serverfile.Ext        = splitname[1]; // extension
                                    serverfile.BinaryFile = binaryfile;   // decrypt file to send it.
                                    binaryfile            = null;
                                    buffer.AddObject(serverfile);
                                    Console.WriteLine("Server : " + buffer.SendCryptoBuffer(client.socket, client.CC.Salt) + " bytess  of " + RF.Name + " send!");
                                    buffer.innerbuffer.Clear();
                                }
                            }
                            if (NoFile)
                            {
                                PrepareFileSend PFS = new PrepareFileSend();
                                PFS.filesize = -1;
                                PFS.FileName = RF.Name;
                                PFS.ACK      = 0;
                                buffer.AddID(MsgType.Nofile);
                                buffer.AddObject(PFS);
                                buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                                buffer.innerbuffer.Clear();
                                Thread.Sleep(10);
                            }
                        }
                        #endregion
                        #region Reguest Logo
                        if (buffer.GetID() == MsgType.RequestLogo)
                        {
                            if (Logo == null)
                            {
                                buffer.innerbuffer.Clear();
                                buffer.AddID(MsgType.NoLogo);
                                buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                            }
                            else
                            {
                                buffer.innerbuffer.Clear();
                                buffer.AddID(MsgType.Logo);

                                buffer.AddObject(Logo);
                                buffer.SendCryptoBuffer(client.socket, client.CC.Salt);
                            }
                        }
                        #endregion
                    }
                    else
                    {
                        for (int i = 0; i < ConnectedClients.Count(); i++)
                        {
                            if (ConnectedClients[i].socket == client.socket)
                            {
                                if (client.CC.Ip == ConnectedClients[i].CC.Ip && client.CC.sockettype != ConnectionType.Client) // or delete if FileSocket.
                                {
                                    ConnectedClients[i].socket.Shutdown(SocketShutdown.Both);
                                    ConnectedClients[i].socket.Close(1);
                                    ConnectedClients.RemoveAt(i);
                                    Console.WriteLine("Socket of Type {0} Disconnected!", client.CC.sockettype);
                                    bRecvMessage = false;
                                    return;
                                }

                                client.socket.Shutdown(SocketShutdown.Both);
                                client.socket.Close(1);
                                client.socket = null;
                                client.Online = false;
                                bRecvMessage  = false;

                                Console.WriteLine("Client {0} of Type {1} Disconnected!", client.CC.Ip, client.CC.sockettype);
                                UpdateClientList();
                                return;
                            }
                        }
                        //  if (ConnectedClients[index].CC.sockettype != ConnectionType.File) // only update clientlist if socket is not a filesocket.
                        //       UpdateClientList();
                    }
                }
                catch (Exception e)
                {
                    for (int i = 0; i < ConnectedClients.Count(); i++)
                    {
                        if (client.socket == ConnectedClients[i].socket)
                        {
                            Console.WriteLine(ConnectedClients[i].CC.Ip + "   " + e.Message + "\r\n Disconnected");
                            if (i < ConnectedClients.Count())
                            {
                                /*
                                 * ConnectedClients[i].Online = false;
                                 * ConnectedClients[i].socket = null;
                                 * ConnectedClients[i].IsRunning = false;
                                 */
                                client.socket.Shutdown(SocketShutdown.Both);
                                client.socket.Close(1);
                                client.socket = null;
                                client.Online = false;
                                bRecvMessage  = false;
                            }
                        }
                    }
                }
            }
        }