Пример #1
0
        public int WannaSendTo(string ip, string path)
        {
            try
            {
                determined.Invoke(true);
                Log.clientLog("Connecting to " + ip);
                Socket     socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint iPEnd  = new IPEndPoint(IPAddress.Parse(ip), CONTROL_PORT);
                socket.Connect(iPEnd);
                socket.SendBufferSize    = 262144;
                socket.ReceiveBufferSize = 262144;
                Send("handshake" + VERSION, socket);
                string     reply          = Receive(socket);
                var        j1             = JObject.Parse(reply);
                IPEndPoint remoteEndPoint = socket.RemoteEndPoint as IPEndPoint;
                if (j1.Value <string>("reply").Equals("deny"))
                {
                    Log.clientLog("Denied: " + j1.Value <string>("reason"), Log.WARN);
                    reason = j1.Value <string>("reason").ToString();
                    determined.Invoke(false);
                    history.RegisterHistory(NetworkHistory.COMMU_TYPE.OUTGOING_SHARE, remoteEndPoint.Address.ToString(),
                                            "{\"file\":\"" + path + "\",\"status\":\"" + reason + "\"}");
                    return(DENIED);
                }
                else if (!j1.Value <string>("reply").Equals("approve"))
                {
                    Log.clientLog("Invalid message: " + reply, Log.ERR);
                    reason = "invalid: " + reply;
                    determined.Invoke(false);
                    history.RegisterHistory(NetworkHistory.COMMU_TYPE.OUTGOING_SHARE, remoteEndPoint.Address.ToString(),
                                            "{\"file\":\"" + path + "\",\"status\":\"invalid_msg\"}");
                    return(ERROR);
                }
                Log.clientLog("RSA public key was received");
                string           pubKey = Receive(socket);
                Secure.RSASystem rsa    = new Secure.RSASystem(pubKey);
                Secure           secure = new Secure
                {
                    Key = "32"
                };
                Send(rsa.Encrypt(secure.Key), socket);
                Log.clientLog("Replied AES key");
                //get IV
                Send(rsa.Encrypt(Setting.Actual_IV), socket);
                secure.SetIV(Setting.Actual_IV);
                Log.clientLog("IV was sent");
                //Get Allow
                JObject pack = new JObject();
                if (!File.Exists(path))
                {
                    Log.clientLog("File not exists(or it is directory): " + path, Log.ERR);
                    pack.Add("reply", "FileErr");
                    Send(pack.ToString(), socket, secure);
                    reason = "FileNotFound";
                    determined.Invoke(false);
                    history.RegisterHistory(NetworkHistory.COMMU_TYPE.OUTGOING_SHARE, remoteEndPoint.Address.ToString(),
                                            "{\"file\":\"" + path + "\",\"status\":\"file_error\"}");
                    return(ERROR);
                }
                FileInfo file = new FileInfo(path);
                pack.Add("reply", "OK");
                pack.Add("name", file.Name);
                pack.Add("size", file.Length);
                Log.clientLog("File data: " + file.Name + " " + file.Length + " Bytes");
                Send(pack.ToString(), socket, secure);
                string received = Receive(socket, secure);
                if (received.Equals("deny"))
                {
                    Log.clientLog("User denied", Log.WARN);
                    reason = "Peer denied";
                    determined.Invoke(false);
                    history.RegisterHistory(NetworkHistory.COMMU_TYPE.OUTGOING_SHARE, remoteEndPoint.Address.ToString(),
                                            "{\"file\":\"" + path + "\",\"status\":\"user_deny\"}");
                    return(DENIED);
                }
                else if (!received.Equals("approve"))
                {
                    Log.clientLog("User invalid reply", Log.ERR);
                    reason = "invalid: " + received;
                    determined.Invoke(false);
                    history.RegisterHistory(NetworkHistory.COMMU_TYPE.OUTGOING_SHARE, remoteEndPoint.Address.ToString(),
                                            "{\"file\":\"" + path + "\",\"status\":\"invalid_msg\"}");
                    return(ERROR);
                }
                Log.clientLog("Received Allow Sign!");
                //Get hash and send: MD5;
                Log.clientLog("Computing hash");
                byte[] hashValue;
                string stringHashValue;
                MD5    hash = MD5.Create();
                using (FileStream stream = File.OpenRead(file.FullName))
                {
                    hashValue       = hash.ComputeHash(stream);
                    stringHashValue = Bytes.getRawString(hashValue);
                }
                Log.clientLog("Sending hash: " + stringHashValue);
                Send(stringHashValue, socket, secure);
                //Send start;
                Log.clientLog("Local file stream connected");
                FileStream fileStream = file.OpenRead();
                //const int sendingBufferSize = 320;  //320B
                const int sendingBufferSize = 131072; //128KB
                                                      //const int sendingBufferSize = 1048576; //1MB
                                                      //const int sendingBufferSize = 524288; //0.5MB
                Log.clientLog("Sending pieces");
                initializer.Invoke((int)((file.Length + (sendingBufferSize - (file.Length % sendingBufferSize))) / sendingBufferSize));
                Log.log((file.Length + (sendingBufferSize - (file.Length % sendingBufferSize))) / sendingBufferSize + " Pieces");
                int packets = 0;
                while (true)
                {
                    byte[] sendingBuffer          = new byte[sendingBufferSize];
                    byte[] encryptedSendingBuffer = new byte[sendingBufferSize + 16];
                    int    read = fileStream.Read(sendingBuffer, 0, sendingBufferSize);

//Log.clientLog("Read " + read + " bytes");
//Log.clientLog("Encryption started");

                    byte[] fitByteBuffer = new byte[read];
                    Array.Copy(sendingBuffer, fitByteBuffer, read);
                    encryptedSendingBuffer = secure.AES256Encrypt(fitByteBuffer);
                    string thisData = Convert.ToBase64String(encryptedSendingBuffer);
//Log.clientLog("Encryption done");
                    JObject packet     = new JObject();
                    string  packetHash = Bytes.getRawString(hash.ComputeHash(fitByteBuffer));
                    packet.Add("segment", thisData);
                    packet.Add("hash", packetHash);
                    packet.Add("isEnd", read < sendingBufferSize);
                    thisData = null;
                    encryptedSendingBuffer = null;
                    string replied;
                    int    attemp = 0;
                    do
                    {
                        attemp++;
//Log.clientLog("Sending data piece: " + (String)packet.GetValue("hash"));
                        Send(packet.ToString(), socket);
//Log.clientLog("Waiting for response");
                        replied = Receive(socket, secure);
//Log.clientLog("File segment reply: \"" + replied + "\", Attemp: "+attemp);
                    } while (!replied.Equals("ok")); // Retry if hash is not correct
                    adder.Invoke();
                    packets++;
                    if (read < sendingBufferSize)
                    {
                        break;
                    }
                }
                Log.clientLog("Waiting for hash test result");
                string hashReply = Receive(socket, secure);
                if (hashReply.Equals("hash"))
                {
                    Log.clientLog("Hash Error: originHash=\"" + stringHashValue + '\"');
                    history.RegisterHistory(NetworkHistory.COMMU_TYPE.OUTGOING_SHARE, remoteEndPoint.Address.ToString(),
                                            "{\"file\":\"" + path + "\",\"status\":\"hash_mismatch\"}");
                }
                else if (!hashReply.Equals("goodbye"))
                {
                    Log.clientLog("Invalid hash reply: " + hashReply);
                    history.RegisterHistory(NetworkHistory.COMMU_TYPE.OUTGOING_SHARE, remoteEndPoint.Address.ToString(),
                                            "{\"file\":\"" + path + "\",\"status\":\"invalid_msg\"}");
                    return(ERROR);
                }
                socket.Close();
                fileStream.Close();
                Log.clientLog("Done: sent " + packets + " file pieces");
                history.RegisterHistory(NetworkHistory.COMMU_TYPE.OUTGOING_SHARE, remoteEndPoint.Address.ToString(),
                                        "{\"file\":\"" + path + "\",\"status\":\"sucess\"}");
                return(SUCESS);
            } catch (Exception e)
            {
                Log.clientLog(e.Message + " client error", Log.ERR);
                return(ERROR);
            }
        }
Пример #2
0
        public void MainServer()
        {
            try
            {
                server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint iPEnd = new IPEndPoint(IPAddress.Any, CONTROL_PORT);
                server.Bind(iPEnd);
                server.Listen(10);
                Log.serverLog("Server Listening");
                while (true)
                {
                    Socket socket = server.Accept();
                    void serve(Socket sock)
                    {
                        sock.SendBufferSize    = 262144;
                        sock.ReceiveBufferSize = 262144;
                        string currentIP = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString();

                        Log.serverLog("New connection: " + currentIP);
                        //HAND SHAKE
                        string msg;

                        msg = Receive(sock);
                        IPEndPoint remoteEndPoint = sock.RemoteEndPoint as IPEndPoint;

                        if (msg.Substring(0, 9).Equals("handshake")) // Share request
                        {
                            if (!Setting.Sharing)
                            {
                                Send("{\"reply\":\"deny\",\"reason\":\"notSharing\"}", sock);
                                Log.serverLog("Denied request: You're currently not sharing", Log.WARN);
                                history.RegisterHistory(NetworkHistory.COMMU_TYPE.INCOMMING_SHARE, remoteEndPoint.Address.ToString(),
                                                        "{\"file\":\"\",\"status\":\"deny\"}");
                                MessageBox.Show("notSharing", "Pass", MessageBoxButton.OK);
                                return;
                            }
                            if (!msg.Substring(9, msg.Length - 9).Equals(VERSION))
                            {
                                Send("{\"reply\":\"deny\",\"reason\":\"VersionMismatch\"}", sock);
                                Log.serverLog("Denied request: FROM" + msg.Substring(9, msg.Length - 9) + " You're: " + VERSION, Log.WARN);
                                history.RegisterHistory(NetworkHistory.COMMU_TYPE.INCOMMING_SHARE, remoteEndPoint.Address.ToString(),
                                                        "{\"file\":\"\",\"status\":\"vers\"}");
                                MessageBox.Show("versMismatch", "Pass", MessageBoxButton.OK);
                                return;
                            }
                            else
                            {
                                Send("{\"reply\":\"approve\"}", sock);
                                Log.serverLog("Approved: " + ((IPEndPoint)sock.RemoteEndPoint).Address.ToString(), Log.WARN);
                            }
                            Log.serverLog("Preparing");
                            //Security
                            string           AES;
                            Secure.RSASystem rsa = new Secure.RSASystem();
                            Send(rsa.PubKey, sock);
                            Log.serverLog("Sent RSA public key");
                            //get AES key
                            AES = rsa.RSADecrypt(Receive(sock));
                            Secure secure = new Secure(AES);
                            Log.serverLog("AES key was replied");
                            //Set IV
                            string ivx = rsa.RSADecrypt(Receive(sock));
                            secure.SetIV(ivx);
                            Log.serverLog("IV value was received");
                            //File Go.
                            JObject json = JObject.Parse(Receive(sock, secure));
                            Log.serverLog("File Info Received");
                            if (!json.Value <string>("reply").Equals("OK"))
                            {
                                Log.serverLog("Not OK!", Log.ERR);
                                history.RegisterHistory(NetworkHistory.COMMU_TYPE.INCOMMING_SHARE, remoteEndPoint.Address.ToString(),
                                                        "{\"file\":\"\",\"status\":\"file_error\"}");
                                MessageBox.Show(Rm.GetString(json.Value <string>("reply")), "Pass", MessageBoxButton.OK);
                                return;
                            }
                            Log.serverLog("File info displayed");
                            long   bytes = long.Parse(json.Value <string>("size"));
                            string unit  = " Byte";
                            double bas;
                            //Byte to suitable unit
                            if (bytes > 1024)
                            {
                                if (bytes > 1024000)
                                {
                                    if (bytes > 1024000000)
                                    {
                                        unit = "GB";
                                        bas  = bytes / 1000000000.0;
                                    }
                                    else
                                    {
                                        unit = "MB";
                                        bas  = bytes / 1000000.0;
                                    }
                                }
                                else
                                {
                                    unit = "KB";
                                    bas  = bytes / 1000.0;
                                }
                            }
                            else
                            {
                                bas = bytes;
                            }
                            bas = Math.Round(bas * 100) / 100;
                            frameControl.Invoke(true);
                            string       file_name = json.Value <string>("name");
                            DialogResult result    = MessageBoxClass.Show(((IPEndPoint)sock.RemoteEndPoint).Address.ToString() +
                                                                          Rm.GetString("appv1") + file_name + Rm.GetString("appv2") +
                                                                          " (" + bas + unit + ')', "Pass", Rm.GetString("allow"), Rm.GetString("deny"));
                            if (result == DialogResult.Yes)
                            {
                                Send("approve", sock, secure);
                            }
                            else
                            {
                                Send("deny", sock, secure);
                                frameControl.Invoke(false);
                                history.RegisterHistory(NetworkHistory.COMMU_TYPE.INCOMMING_SHARE, remoteEndPoint.Address.ToString(),
                                                        "{\"file\":\"" + file_name + "\",\"status\":\"user_deny\"}");
                                return;
                            }
                            string hashValue = Receive(sock, secure);
                            Log.serverLog("Received hash");
                            string targetPath = Setting.DefaultSave + '\\' + json.Value <string>("name");
                            Log.serverLog("Write to " + targetPath);
                            //file download start;
                            Log.serverLog("Downloading started");
                            MD5        md5     = MD5.Create();
                            int        packets = 0;
                            FileStream stream  = File.OpenWrite(targetPath);
                            Log.serverLog("Writing stream connected");
                            while (true)
                            {
                                //Log.serverLog("Waiting for data piece");
                                string  dataSegment  = Receive(sock);
                                JObject data         = JObject.Parse(dataSegment);
                                string  segment      = (string)data.GetValue("segment");
                                string  hash         = (string)data.GetValue("hash");
                                bool    isEnd        = (bool)data.GetValue("isEnd");
                                byte[]  finalSegment = secure.AES256Decrypt(Convert.FromBase64String(segment));

                                //Log.serverLog("Got data piece: " + hash);

                                string hashed = Bytes.getRawString(md5.ComputeHash(finalSegment));
                                if (hash.Equals(hashed))
                                {
                                    Send("ok", sock, secure);
                                    //Log.serverLog("Wrote " + finalSegment.Length + " bytes");
                                    stream.Write(finalSegment, 0, finalSegment.Length);
                                    packets++;
                                    if (isEnd)
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    Send("retry", sock, secure);
                                    Log.serverLog("HASH MISMATCH! requested resend(Hash=" + hashed + ')', Log.ERR);
                                }
                            }
                            stream.Close();
                            //Hash check
                            byte[] hashValueCheck;
                            string stringHashValue;
                            Log.serverLog("Hash check in progress");
                            using (FileStream hashStream = File.OpenRead(targetPath))
                            {
                                hashValueCheck  = md5.ComputeHash(hashStream);
                                stringHashValue = Bytes.getRawString(hashValueCheck);
                            }
                            if (!hashValue.Equals(stringHashValue))
                            {
                                Log.serverLog("FILE HASH MISMATCH! \"" + stringHashValue + "\" vs. n\"" + hashValue + '\"');
                                history.RegisterHistory(NetworkHistory.COMMU_TYPE.INCOMMING_SHARE, remoteEndPoint.Address.ToString(),
                                                        "{\"file\":\"" + file_name + "\",\"status\":\"hash_mismatch\"}");
                                Send("hash", sock, secure);
                            }
                            else
                            {
                                Log.serverLog("FILE HASH MATCH! " + stringHashValue);
                                history.RegisterHistory(NetworkHistory.COMMU_TYPE.INCOMMING_SHARE, remoteEndPoint.Address.ToString(),
                                                        "{\"file\":\"" + file_name + "\",\"status\":\"sucess\"}");
                                Send("goodbye", sock, secure);
                            }
                            Log.serverLog("Done: received " + packets + " file pieces");
                        }
                        else
                        {
                            Log.serverLog("Invalid Message: \"" + msg + "\"");
                            history.RegisterHistory(NetworkHistory.COMMU_TYPE.INCOMMING_SHARE, remoteEndPoint.Address.ToString(),
                                                    "{\"file\":\"\",\"status\":\"invalid_msg\"}");
                        }
                        sock.Close();
                    }
                    Task.Run(() => serve(socket));
                }
            }
            catch (Exception e)
            {
                Log.serverLog("Server Stopped: " + e.Message);
                return;
            }
        }