From 4a070abefdff9eb103b102fa2c9a92bbc5945141 Mon Sep 17 00:00:00 2001 From: BreakWa11 Date: Wed, 12 Oct 2016 14:57:04 +0800 Subject: [PATCH] 3.9.5 fix rc4 fill with randBytes add auth_aes128_md5 & auth_aes128_sha1 --- shadowsocks-csharp/Controller/Local.cs | 64 +++++++++++-------- shadowsocks-csharp/Controller/ProxySocket.cs | 17 ++--- .../Controller/UpdateChecker.cs | 2 +- shadowsocks-csharp/Encryption/IVEncryptor.cs | 3 +- .../Encryption/MbedTLSEncryptor.cs | 2 +- shadowsocks-csharp/Obfs/Auth.cs | 36 ++++++++++- shadowsocks-csharp/Obfs/IObfs.cs | 4 +- .../View/ConfigForm.Designer.cs | 3 +- 8 files changed, 87 insertions(+), 44 deletions(-) diff --git a/shadowsocks-csharp/Controller/Local.cs b/shadowsocks-csharp/Controller/Local.cs index 596ae40..f2e2bc6 100644 --- a/shadowsocks-csharp/Controller/Local.cs +++ b/shadowsocks-csharp/Controller/Local.cs @@ -166,7 +166,7 @@ class Handler protected bool is_obfs_sendback = false; protected bool connectionTCPIdle, connectionUDPIdle, remoteTCPIdle, remoteUDPIdle; - protected int remoteRecvCount = 0; + //protected int remoteRecvCount = 0; protected int connectionRecvCount = 0; protected SpeedTester speedTester = new SpeedTester(); @@ -174,6 +174,7 @@ class Handler protected Random random = new Random(); protected System.Timers.Timer timer; protected object timerLock = new object(); + protected DateTime lastTimerSetTime; enum ConnectState { @@ -206,31 +207,42 @@ private void ResetTimeout(Double time) return; cfg.try_keep_alive = 0; - lock (timerLock) + + if (time <= 0) { - if (time <= 0) + if (timer != null) { - if (timer != null) + lock (timerLock) { - timer.Enabled = false; - timer.Elapsed -= timer_Elapsed; - timer.Dispose(); - timer = null; + if (timer != null) + { + timer.Enabled = false; + timer.Elapsed -= timer_Elapsed; + timer.Dispose(); + timer = null; + } } } - else + } + else + { + if (lastTimerSetTime != null && (DateTime.Now - lastTimerSetTime).TotalMilliseconds > 500) { - if (timer == null) + lock (timerLock) { - timer = new System.Timers.Timer(time * 1000.0); - timer.Elapsed += timer_Elapsed; - } - else - { - timer.Interval = time * 1000.0; - timer.Stop(); + if (timer == null) + { + timer = new System.Timers.Timer(time * 1000.0); + timer.Elapsed += timer_Elapsed; + } + else + { + timer.Interval = time * 1000.0; + timer.Stop(); + } + timer.Start(); + lastTimerSetTime = DateTime.Now; } - timer.Start(); } } } @@ -521,7 +533,7 @@ private void BeginConnect(IPAddress ipAddress, int serverPort) remote.GetSocket().SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); try { - remote.SetEncryptor(EncryptorFactory.GetEncryptor(server.method, server.password)); + remote.CreateEncryptor(server.method, server.password); } catch { @@ -539,7 +551,7 @@ private void BeginConnect(IPAddress ipAddress, int serverPort) SocketType.Dgram, ProtocolType.Udp); remoteUDP.GetSocket().Bind(new IPEndPoint(ipAddress.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any, 0)); - remoteUDP.SetEncryptor(EncryptorFactory.GetEncryptor(server.method, server.password)); + remoteUDP.CreateEncryptor(server.method, server.password); remoteUDP.SetProtocol(ObfsFactory.GetObfs(server.protocol)); remoteUDP.SetObfs(ObfsFactory.GetObfs(server.obfs)); if (server.server_udp_port == 0 || cfg.socks5RemotePort != 0) @@ -668,9 +680,11 @@ public void Close() } closed = true; } + Thread.Sleep(100); for (int i = 0; i < 10; ++i) { - if (remoteRecvCount <= 0 && connectionRecvCount <= 0) + if (//remoteRecvCount <= 0 && + connectionRecvCount <= 0) break; Thread.Sleep(10 * (i + 1) * (i + 1)); } @@ -1291,7 +1305,7 @@ private void UDPoverTCPConnectionSend(byte[] send_buffer, int bytesToSend) private void PipeRemoteReceiveCallback(IAsyncResult ar) { - Interlocked.Increment(ref remoteRecvCount); + //Interlocked.Increment(ref remoteRecvCount); bool final_close = false; try { @@ -1363,7 +1377,7 @@ private void PipeRemoteReceiveCallback(IAsyncResult ar) } finally { - Interlocked.Decrement(ref remoteRecvCount); + //Interlocked.Decrement(ref remoteRecvCount); if (final_close) { Close(); @@ -1375,7 +1389,7 @@ private void PipeRemoteReceiveCallback(IAsyncResult ar) private void PipeRemoteUDPReceiveCallback(IAsyncResult ar) { bool final_close = false; - Interlocked.Decrement(ref remoteRecvCount); + //Interlocked.Decrement(ref remoteRecvCount); try { if (closed) @@ -1426,7 +1440,7 @@ private void PipeRemoteUDPReceiveCallback(IAsyncResult ar) } finally { - Interlocked.Decrement(ref remoteRecvCount); + //Interlocked.Decrement(ref remoteRecvCount); if (final_close) { Close(); diff --git a/shadowsocks-csharp/Controller/ProxySocket.cs b/shadowsocks-csharp/Controller/ProxySocket.cs index d1e7cfa..1a681ae 100644 --- a/shadowsocks-csharp/Controller/ProxySocket.cs +++ b/shadowsocks-csharp/Controller/ProxySocket.cs @@ -25,6 +25,7 @@ class ProxySocket protected IEncryptor _encryptor; protected object _encryptionLock = new object(); + protected string _password; //protected object _decryptionLock = new object(); public IObfs _protocol; public IObfs _obfs; @@ -82,13 +83,6 @@ public bool isProtocolSendback { get { - //Dictionary protocols = new Dictionary(); - //protocols["auth_aes128_sha1"] = 1; - //if (protocols.ContainsKey(_protocol.Name())) - //{ - // return true; - //} - //return false; return _protocol.isAlwaysSendback(); } } @@ -151,9 +145,10 @@ public void EndConnect(IAsyncResult ar) _socket.EndConnect(ar); } - public void SetEncryptor(IEncryptor encryptor) + public void CreateEncryptor(string method, string password) { - _encryptor = encryptor; + _encryptor = EncryptorFactory.GetEncryptor(method, password); + _password = password; } public void SetProtocol(IObfs protocol) @@ -184,9 +179,9 @@ public void SetObfsPlugin(Server server, int head_len) if (_proxy_server != null) server_addr = _proxy_server; _protocol.SetServerInfo(new ServerInfo(server_addr, server.server_port, "", server.getProtocolData(), - _encryptor.getIV(), _encryptor.getKey(), head_len, mss)); + _encryptor.getIV(), _password, _encryptor.getKey(), head_len, mss)); _obfs.SetServerInfo(new ServerInfo(server_addr, server.server_port, server.obfsparam??"", server.getObfsData(), - _encryptor.getIV(), _encryptor.getKey(), head_len, mss)); + _encryptor.getIV(), _password, _encryptor.getKey(), head_len, mss)); } public IAsyncResult BeginReceive(byte[] buffer, int size, SocketFlags flags, AsyncCallback callback, object state) diff --git a/shadowsocks-csharp/Controller/UpdateChecker.cs b/shadowsocks-csharp/Controller/UpdateChecker.cs index 844731b..5cd1d61 100755 --- a/shadowsocks-csharp/Controller/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/UpdateChecker.cs @@ -21,7 +21,7 @@ public class UpdateChecker public const string Name = "ShadowsocksR"; public const string Copyright = "Copyright © BreakWall 2016. Fork from Shadowsocks by clowwindy"; - public const string Version = "3.9.4"; + public const string Version = "3.9.5"; public const string FullVersion = Version + ""; private static bool UseProxy = true; diff --git a/shadowsocks-csharp/Encryption/IVEncryptor.cs b/shadowsocks-csharp/Encryption/IVEncryptor.cs index d2d90bb..3d0b649 100755 --- a/shadowsocks-csharp/Encryption/IVEncryptor.cs +++ b/shadowsocks-csharp/Encryption/IVEncryptor.cs @@ -167,7 +167,7 @@ public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outl public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { - if (_decryptIVReceived < ivLen) + if (_decryptIVReceived <= ivLen) { int start_pos = ivLen; if (_decryptIVReceived + length < ivLen) @@ -199,6 +199,7 @@ public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outl if (outlength > 0) { + _decryptIVReceived += outlength; lock (tempbuf) { // C# could be multi-threaded diff --git a/shadowsocks-csharp/Encryption/MbedTLSEncryptor.cs b/shadowsocks-csharp/Encryption/MbedTLSEncryptor.cs index 6d2b177..bb06183 100644 --- a/shadowsocks-csharp/Encryption/MbedTLSEncryptor.cs +++ b/shadowsocks-csharp/Encryption/MbedTLSEncryptor.cs @@ -34,7 +34,7 @@ public MbedTLSEncryptor(string method, string password) { "camellia-128-cfb", new EncryptorInfo(16, 16, true, CIPHER_CAMELLIA, "CAMELLIA-128-CFB128") }, { "camellia-192-cfb", new EncryptorInfo(24, 16, true, CIPHER_CAMELLIA, "CAMELLIA-192-CFB128") }, { "camellia-256-cfb", new EncryptorInfo(32, 16, true, CIPHER_CAMELLIA, "CAMELLIA-256-CFB128") }, - { "rc4", new EncryptorInfo(16, 16, false, CIPHER_RC4, "ARC4-128") }, + { "rc4", new EncryptorInfo(16, 0, true, CIPHER_RC4, "ARC4-128") }, { "rc4-md5", new EncryptorInfo(16, 16, true, CIPHER_RC4, "ARC4-128") }, { "rc4-md5-6", new EncryptorInfo(16, 6, true, CIPHER_RC4, "ARC4-128") }, }; diff --git a/shadowsocks-csharp/Obfs/Auth.cs b/shadowsocks-csharp/Obfs/Auth.cs index a4cfe52..dbe9906 100644 --- a/shadowsocks-csharp/Obfs/Auth.cs +++ b/shadowsocks-csharp/Obfs/Auth.cs @@ -232,6 +232,11 @@ public void PackData(byte[] data, int datalength, byte[] outdata, out int outlen Array.Copy(data, 0, outdata, rand_len + 2, datalength); outdata[0] = (byte)(outlength >> 8); outdata[1] = (byte)(outlength); + { + byte[] rnd_data = new byte[rand_len]; + random.NextBytes(rnd_data); + rnd_data.CopyTo(outdata, 2); + } if (rand_len < 128) { outdata[2] = (byte)(rand_len); @@ -252,6 +257,11 @@ public void PackAuthData(byte[] data, int datalength, byte[] outdata, out int ou int data_offset = rand_len + 4 + 2; outlength = data_offset + datalength + 12 + 10; AuthData authData = (AuthData)this.Server.data; + { + byte[] rnd_data = new byte[rand_len]; + random.NextBytes(rnd_data); + rnd_data.CopyTo(outdata, data_offset - rand_len); + } lock (authData) { if (authData.connectionID > 0xFF000000) @@ -447,6 +457,11 @@ public void PackData(byte[] data, int datalength, byte[] outdata, out int outlen outdata[1] = (byte)(outlength); ulong crc32 = Util.CRC32.CalcCRC32(outdata, 2); BitConverter.GetBytes((ushort)crc32).CopyTo(outdata, 2); + { + byte[] rnd_data = new byte[rand_len]; + random.NextBytes(rnd_data); + rnd_data.CopyTo(outdata, 4); + } if (rand_len < 128) { outdata[4] = (byte)(rand_len); @@ -467,6 +482,11 @@ public void PackAuthData(byte[] data, int datalength, byte[] outdata, out int ou int data_offset = rand_len + 4 + 2; outlength = data_offset + datalength + 12 + 10; AuthData authData = (AuthData)this.Server.data; + { + byte[] rnd_data = new byte[rand_len]; + random.NextBytes(rnd_data); + rnd_data.CopyTo(outdata, data_offset - rand_len); + } lock (authData) { if (authData.connectionID > 0xFF000000) @@ -677,6 +697,11 @@ public void PackData(byte[] data, int datalength, byte[] outdata, out int outlen outdata[1] = (byte)(outlength >> 8); ulong crc32 = Util.CRC32.CalcCRC32(outdata, 2); BitConverter.GetBytes((ushort)crc32).CopyTo(outdata, 2); + { + byte[] rnd_data = new byte[rand_len]; + random.NextBytes(rnd_data); + rnd_data.CopyTo(outdata, 4); + } if (rand_len < 128) { outdata[4] = (byte)(rand_len); @@ -958,6 +983,11 @@ public void PackData(byte[] data, int datalength, byte[] outdata, out int outlen byte[] key = new byte[user_key.Length + 4]; user_key.CopyTo(key, 0); BitConverter.GetBytes(pack_id).CopyTo(key, key.Length - 4); + { + byte[] rnd_data = new byte[rand_len]; + random.NextBytes(rnd_data); + rnd_data.CopyTo(outdata, 4); + } { HMAC sha1 = CreateHMAC(key); @@ -1045,12 +1075,12 @@ public void PackAuthData(byte[] data, int datalength, byte[] outdata, out int ou Array.Copy(sha1data, 0, encrypt, 20, 4); } { - byte[] rnd = new byte[3]; + byte[] rnd = new byte[1]; random.NextBytes(rnd); rnd.CopyTo(outdata, 0); HMAC sha1 = CreateHMAC(key); - byte[] sha1data = sha1.ComputeHash(rnd, 0, 3); - Array.Copy(sha1data, 0, outdata, 3, 4); + byte[] sha1data = sha1.ComputeHash(rnd, 0, rnd.Length); + Array.Copy(sha1data, 0, outdata, rnd.Length, 7 - rnd.Length); } encrypt.CopyTo(outdata, 7); Array.Copy(data, 0, outdata, data_offset, datalength); diff --git a/shadowsocks-csharp/Obfs/IObfs.cs b/shadowsocks-csharp/Obfs/IObfs.cs index 1828fb5..be706c0 100644 --- a/shadowsocks-csharp/Obfs/IObfs.cs +++ b/shadowsocks-csharp/Obfs/IObfs.cs @@ -19,9 +19,10 @@ public class ServerInfo public int tcp_mss; public byte[] iv; public byte[] key; + public string key_str; public int head_len; - public ServerInfo(string host, int port, string param, object data, byte[] iv, byte[] key, int head_len, int tcp_mss) + public ServerInfo(string host, int port, string param, object data, byte[] iv, string key_str, byte[] key, int head_len, int tcp_mss) { this.host = host; this.port = port; @@ -29,6 +30,7 @@ public ServerInfo(string host, int port, string param, object data, byte[] iv, b this.data = data; this.iv = iv; this.key = key; + this.key_str = key_str; this.head_len = head_len; this.tcp_mss = tcp_mss; } diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 886216b..3dd88ef 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -476,7 +476,8 @@ private void InitializeComponent() "verify_sha1", "auth_sha1_v2", "auth_sha1_v4", - "auth_aes128"}); + "auth_aes128_md5", + "auth_aes128_sha1"}); this.TCPProtocolComboBox.Location = new System.Drawing.Point(108, 124); this.TCPProtocolComboBox.Name = "TCPProtocolComboBox"; this.TCPProtocolComboBox.Size = new System.Drawing.Size(233, 25);