diff --git a/CHANGES b/CHANGES index 781044c9..2f8955b3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +2.0.9 2014-11-13 +- Fix startup path +- Fix allowed port range for polipo + +2.0.8 2014-11-12 +- Fix data corruption +- Set proxy for PPPoE +- Auto Startup Option +- Support high DPI screens + 2.0.7 2014-11-11 - Use OpenSSL for now diff --git a/shadowsocks-csharp/Controller/AutoStartup.cs b/shadowsocks-csharp/Controller/AutoStartup.cs new file mode 100644 index 00000000..cc7e0b2b --- /dev/null +++ b/shadowsocks-csharp/Controller/AutoStartup.cs @@ -0,0 +1,39 @@ +using System; +using System.Windows.Forms; +using Microsoft.Win32; + +namespace Shadowsocks.Controller { + class AutoStartup { + public static bool Set(bool enabled) { + try { + string path = Application.ExecutablePath; + RegistryKey runKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true); + if (enabled) { + runKey.SetValue("Shadowsocks", path); + } else { + runKey.DeleteValue("Shadowsocks"); + } + runKey.Close(); + return true; + } catch (Exception) { + return false; + } + } + + public static bool Check() { + try { + string path = Application.ExecutablePath; + RegistryKey runKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run"); + string[] runList = runKey.GetValueNames(); + runKey.Close(); + foreach (string item in runList) { + if (item.Equals("Shadowsocks")) + return true; + } + return false; + } catch (Exception) { + return false; + } + } + } +} diff --git a/shadowsocks-csharp/Controller/Local.cs b/shadowsocks-csharp/Controller/Local.cs index 8bdbd15f..97f21474 100755 --- a/shadowsocks-csharp/Controller/Local.cs +++ b/shadowsocks-csharp/Controller/Local.cs @@ -115,6 +115,9 @@ namespace Shadowsocks.Controller private bool connectionShutdown = false; private bool remoteShutdown = false; private bool closed = false; + + private object encryptionLock = new object(); + private object decryptionLock = new object(); public void Start() { @@ -141,7 +144,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } @@ -173,7 +176,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); } } if (remote != null) @@ -185,14 +188,24 @@ namespace Shadowsocks.Controller } catch (SocketException e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); + } + } + lock (encryptionLock) + { + lock (decryptionLock) + { + ((IDisposable)encryptor).Dispose(); } } - ((IDisposable)encryptor).Dispose(); } private void ConnectCallback(IAsyncResult ar) { + if (closed) + { + return; + } try { // Complete the connection. @@ -205,13 +218,17 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } private void HandshakeReceive() { + if (closed) + { + return; + } try { connection.BeginReceive(connetionRecvBuffer, 0, 256, 0, @@ -219,13 +236,17 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } private void HandshakeReceiveCallback(IAsyncResult ar) { + if (closed) + { + return; + } try { int bytesRead = connection.EndReceive(ar); @@ -248,13 +269,17 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } private void HandshakeSendCallback(IAsyncResult ar) { + if (closed) + { + return; + } try { connection.EndSend(ar); @@ -271,13 +296,17 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } private void handshakeReceive2Callback(IAsyncResult ar) { + if (closed) + { + return; + } try { int bytesRead = connection.EndReceive(ar); @@ -295,7 +324,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } @@ -303,6 +332,10 @@ namespace Shadowsocks.Controller private void StartPipe(IAsyncResult ar) { + if (closed) + { + return; + } try { connection.EndReceive(ar); @@ -313,14 +346,17 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } private void PipeRemoteReceiveCallback(IAsyncResult ar) { - + if (closed) + { + return; + } try { int bytesRead = remote.EndReceive(ar); @@ -328,7 +364,14 @@ namespace Shadowsocks.Controller if (bytesRead > 0) { int bytesToSend; - encryptor.Decrypt(remoteRecvBuffer, bytesRead, remoteSendBuffer, out bytesToSend); + lock (decryptionLock) + { + if (closed) + { + return; + } + encryptor.Decrypt(remoteRecvBuffer, bytesRead, remoteSendBuffer, out bytesToSend); + } connection.BeginSend(remoteSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeConnectionSendCallback), null); } else @@ -341,14 +384,17 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } private void PipeConnectionReceiveCallback(IAsyncResult ar) { - + if (closed) + { + return; + } try { int bytesRead = connection.EndReceive(ar); @@ -356,7 +402,14 @@ namespace Shadowsocks.Controller if (bytesRead > 0) { int bytesToSend; - encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend); + lock (encryptionLock) + { + if (closed) + { + return; + } + encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend); + } remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeRemoteSendCallback), null); } else @@ -368,13 +421,17 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } private void PipeRemoteSendCallback(IAsyncResult ar) { + if (closed) + { + return; + } try { remote.EndSend(ar); @@ -383,13 +440,17 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } private void PipeConnectionSendCallback(IAsyncResult ar) { + if (closed) + { + return; + } try { connection.EndSend(ar); @@ -398,7 +459,7 @@ namespace Shadowsocks.Controller } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); this.Close(); } } diff --git a/shadowsocks-csharp/Controller/PACServer.cs b/shadowsocks-csharp/Controller/PACServer.cs index 422089dc..7b39252d 100755 --- a/shadowsocks-csharp/Controller/PACServer.cs +++ b/shadowsocks-csharp/Controller/PACServer.cs @@ -15,6 +15,7 @@ namespace Shadowsocks.Controller { private static int PORT = 8090; private static string PAC_FILE = "pac.txt"; + private static Configuration config; Socket _listener; FileSystemWatcher watcher; @@ -25,6 +26,7 @@ namespace Shadowsocks.Controller { try { + config = configuration; // Create a TCP/IP socket. _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); @@ -84,12 +86,21 @@ namespace Shadowsocks.Controller new AsyncCallback(AcceptCallback), listener); - conn.BeginReceive(new byte[1024], 0, 1024, 0, - new AsyncCallback(ReceiveCallback), conn); + byte[] buf = new byte[2048]; + object[] state = new object[] { + conn, + buf + }; + + conn.BeginReceive(buf, 0, 1024, 0, + new AsyncCallback(ReceiveCallback), state); + } + catch (ObjectDisposedException) + { } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); } } @@ -120,7 +131,10 @@ namespace Shadowsocks.Controller private void ReceiveCallback(IAsyncResult ar) { - Socket conn = (Socket)ar.AsyncState; + object[] state = (object[])ar.AsyncState; + + Socket conn = (Socket)state[0]; + byte[] requestBuf = (byte[])state[1]; try { int bytesRead = conn.EndReceive(ar); @@ -129,7 +143,7 @@ namespace Shadowsocks.Controller IPEndPoint localEndPoint = (IPEndPoint)conn.LocalEndPoint; - string proxy = "PROXY " + localEndPoint.Address + ":8123;"; + string proxy = GetPACAddress(requestBuf, localEndPoint); pac = pac.Replace("__PROXY__", proxy); @@ -152,7 +166,7 @@ Connection: Close } catch (Exception e) { - Console.WriteLine(e.Message); + Console.WriteLine(e); conn.Close(); } } @@ -186,5 +200,24 @@ Connection: Close PACFileChanged(this, new EventArgs()); } } + + private string GetPACAddress(byte[] requestBuf, IPEndPoint localEndPoint) + { + string proxy = "PROXY " + localEndPoint.Address + ":8123;"; + //try + //{ + // string requestString = Encoding.UTF8.GetString(requestBuf); + // if (requestString.IndexOf("AppleWebKit") >= 0) + // { + // string address = "" + localEndPoint.Address + ":" + config.GetCurrentServer().local_port; + // proxy = "SOCKS5 " + address + "; SOCKS " + address + ";"; + // } + //} + //catch (Exception e) + //{ + // Console.WriteLine(e); + //} + return proxy; + } } } diff --git a/shadowsocks-csharp/Controller/SystemProxy.cs b/shadowsocks-csharp/Controller/SystemProxy.cs index 884c7260..a578752a 100755 --- a/shadowsocks-csharp/Controller/SystemProxy.cs +++ b/shadowsocks-csharp/Controller/SystemProxy.cs @@ -35,6 +35,8 @@ namespace Shadowsocks.Controller registry.SetValue("ProxyServer", ""); registry.SetValue("AutoConfigURL", "http://127.0.0.1:8090/pac?t=" + GetTimestamp(DateTime.Now)); SystemProxy.NotifyIE(); + //Must Notify IE first, or the connections do not chanage + CopyProxySettingFromLan(); } catch (Exception) { @@ -54,6 +56,7 @@ namespace Shadowsocks.Controller registry.SetValue("ProxyServer", ""); registry.SetValue("AutoConfigURL", ""); SystemProxy.NotifyIE(); + CopyProxySettingFromLan(); } catch (Exception) { @@ -62,6 +65,25 @@ namespace Shadowsocks.Controller } } + private static void CopyProxySettingFromLan() + { + RegistryKey registry = + Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections", + true); + var defulatValue = registry.GetValue("DefaultConnectionSettings"); + var connections = registry.GetValueNames(); + foreach (String each in connections){ + if (!(each.Equals("DefaultConnectionSettings") + || each.Equals("LAN Connection") + || each.Equals("SavedLegacySettings"))) + { + //set all the connections's proxy as the lan + registry.SetValue(each, defulatValue); + } + } + NotifyIE(); + } + private static String GetTimestamp(DateTime value) { return value.ToString("yyyyMMddHHmmssffff"); diff --git a/shadowsocks-csharp/Data/polipo_config.txt b/shadowsocks-csharp/Data/polipo_config.txt index fc500543..5a18557f 100755 --- a/shadowsocks-csharp/Data/polipo_config.txt +++ b/shadowsocks-csharp/Data/polipo_config.txt @@ -4,3 +4,6 @@ socksParentProxy = "127.0.0.1:__SOCKS_PORT__" socksProxyType = socks5 diskCacheRoot = "" localDocumentRoot = "" + +allowedPorts = 1-65535 +tunnelAllowedPorts = 1-65535 \ No newline at end of file diff --git a/shadowsocks-csharp/Encrypt/EncryptorFactory.cs b/shadowsocks-csharp/Encrypt/EncryptorFactory.cs index dbb45d33..59111a69 100644 --- a/shadowsocks-csharp/Encrypt/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encrypt/EncryptorFactory.cs @@ -10,7 +10,7 @@ namespace Shadowsocks.Encrypt return new TableEncryptor(method, password); } - return new OpenSSLEncryptor(method, password); + return new PolarSSLEncryptor(method, password); } } } diff --git a/shadowsocks-csharp/Encrypt/OpenSSL.cs b/shadowsocks-csharp/Encrypt/OpenSSL.cs deleted file mode 100755 index 8d7c31e4..00000000 --- a/shadowsocks-csharp/Encrypt/OpenSSL.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; - -namespace Shadowsocks.Encrypt -{ - public class OpenSSL - { - const string DLLNAME = "libeay32"; - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void OpenSSL_add_all_ciphers(); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static IntPtr EVP_md5(); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int EVP_BytesToKey(IntPtr type, IntPtr md, IntPtr salt, byte[] data, int datal, int count, byte[] key, byte[] iv); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int RAND_bytes(byte[] buf, int num); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static IntPtr EVP_get_cipherbyname(byte[] name); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static IntPtr EVP_CIPHER_CTX_new(); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int EVP_CipherInit_ex(IntPtr ctx, IntPtr type, IntPtr impl, byte[] key, byte[] iv, int enc); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int EVP_CIPHER_CTX_cleanup(IntPtr a); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int EVP_CIPHER_CTX_free(IntPtr a); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int EVP_CipherUpdate(IntPtr ctx, byte[] outb, out int outl, byte[] inb, int inl); - - [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static IntPtr MD5(byte[] d, long n, byte[] md); - } -} diff --git a/shadowsocks-csharp/Encrypt/OpenSSLEncryptor.cs b/shadowsocks-csharp/Encrypt/OpenSSLEncryptor.cs deleted file mode 100755 index 7abdb375..00000000 --- a/shadowsocks-csharp/Encrypt/OpenSSLEncryptor.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; - -namespace Shadowsocks.Encrypt -{ - public class OpenSSLEncryptor - : EncryptorBase, IDisposable - { - static Dictionary ciphers = new Dictionary { - {"aes-128-cfb", new int[]{16, 16}}, - {"aes-192-cfb", new int[]{24, 16}}, - {"aes-256-cfb", new int[]{32, 16}}, - {"bf-cfb", new int[]{16, 8}}, - {"rc4", new int[]{16, 0}}, - {"rc4-md5", new int[]{16, 16}}, - }; - - static OpenSSLEncryptor() - { - OpenSSL.OpenSSL_add_all_ciphers(); - } - - public OpenSSLEncryptor(string method, string password) - : base(method, password) - { - InitKey(method, password); - } - - - static byte[] tempbuf = new byte[32768]; - - public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) - { - if (_encryptCtx == IntPtr.Zero) - { - OpenSSL.RAND_bytes(outbuf, ivLen); - InitCipher(ref _encryptCtx, outbuf, true); - outlength = length + ivLen; - OpenSSL.EVP_CipherUpdate(_encryptCtx, tempbuf, out outlength, buf, length); - outlength = length + ivLen; - Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, outlength); - } - else - { - outlength = length; - OpenSSL.EVP_CipherUpdate(_encryptCtx, outbuf, out outlength, buf, length); - } - } - - public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) - { - if (_decryptCtx == IntPtr.Zero) - { - InitCipher(ref _decryptCtx, buf, false); - outlength = length - ivLen; - Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen); - OpenSSL.EVP_CipherUpdate(_decryptCtx, outbuf, out outlength, tempbuf, length - ivLen); - } - else - { - outlength = length; - OpenSSL.EVP_CipherUpdate(_decryptCtx, outbuf, out outlength, buf, length); - } - } - - private static readonly Dictionary CachedKeys = new Dictionary(); - private byte[] _key; - private IntPtr _encryptCtx; - private IntPtr _decryptCtx; - private IntPtr _cipher; - private string _method; - private int keyLen; - private int ivLen; - - private void InitKey(string method, string password) - { - method = method.ToLower(); - _method = method; - string k = method + ":" + password; - if (method == "rc4-md5") - { - method = "rc4"; - } - _cipher = OpenSSL.EVP_get_cipherbyname(System.Text.Encoding.UTF8.GetBytes(method)); - if (_cipher == null) - { - throw new Exception("method not found"); - } - keyLen = ciphers[_method][0]; - ivLen = ciphers[_method][1]; - if (CachedKeys.ContainsKey(k)) - { - _key = CachedKeys[k]; - } - else - { - byte[] passbuf = Encoding.UTF8.GetBytes(password); - _key = new byte[32]; - byte[] iv = new byte[16]; - OpenSSL.EVP_BytesToKey(_cipher, OpenSSL.EVP_md5(), IntPtr.Zero, passbuf, passbuf.Length, 1, _key, iv); - CachedKeys[k] = _key; - } - } - - private void InitCipher(ref IntPtr ctx, byte[] iv, bool isCipher) - { - ctx = OpenSSL.EVP_CIPHER_CTX_new(); - int enc = isCipher ? 1 : 0; - byte[] realkey; - IntPtr r = IntPtr.Zero; - if (_method == "rc4-md5") - { - byte[] temp = new byte[keyLen + ivLen]; - realkey = new byte[keyLen]; - Array.Copy(_key, 0, temp, 0, keyLen); - Array.Copy(iv, 0, temp, keyLen, ivLen); - r = OpenSSL.MD5(temp, keyLen + ivLen, null); - Marshal.Copy(r, realkey, 0, keyLen); - } - else - { - realkey = _key; - } - OpenSSL.EVP_CipherInit_ex(ctx, _cipher, IntPtr.Zero, realkey, iv, enc); - } - - #region IDisposable - private bool _disposed; - - public override void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - ~OpenSSLEncryptor() - { - Dispose(false); - } - - protected virtual void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - - } - - if (_encryptCtx.ToInt64() != 0) - { - OpenSSL.EVP_CIPHER_CTX_cleanup(_encryptCtx); - OpenSSL.EVP_CIPHER_CTX_free(_encryptCtx); - _encryptCtx = IntPtr.Zero; - } - if (_decryptCtx.ToInt64() != 0) - { - OpenSSL.EVP_CIPHER_CTX_cleanup(_decryptCtx); - OpenSSL.EVP_CIPHER_CTX_free(_decryptCtx); - _decryptCtx = IntPtr.Zero; - } - - _disposed = true; - } - } - #endregion - } -} diff --git a/shadowsocks-csharp/Encrypt/PolarSSL.cs b/shadowsocks-csharp/Encrypt/PolarSSL.cs index 0eab93c7..193e4ab0 100755 --- a/shadowsocks-csharp/Encrypt/PolarSSL.cs +++ b/shadowsocks-csharp/Encrypt/PolarSSL.cs @@ -1,5 +1,8 @@ -using System; +using Shadowsocks.Controller; +using Shadowsocks.Properties; +using System; using System.Collections.Generic; +using System.IO; using System.Runtime.InteropServices; using System.Text; @@ -13,32 +16,50 @@ namespace Shadowsocks.Encrypt public const int AES_ENCRYPT = 1; public const int AES_DECRYPT = 0; + static PolarSSL() + { + string tempPath = Path.GetTempPath(); + string dllPath = tempPath + "/polarssl.dll"; + try + { + FileManager.UncompressFile(dllPath, Resources.polarssl_dll); + } + catch (IOException e) + { + Console.WriteLine(e.ToString()); + } + LoadLibrary(dllPath); + } + + [DllImport("Kernel32.dll")] + private static extern IntPtr LoadLibrary(string path); + [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void aes_init(byte[] ctx); + public extern static void aes_init(IntPtr ctx); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void aes_free(byte[] ctx); + public extern static void aes_free(IntPtr ctx); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int aes_setkey_enc(byte[] ctx, byte[] key, int keysize); + public extern static int aes_setkey_enc(IntPtr ctx, byte[] key, int keysize); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int aes_crypt_cfb128(byte[] ctx, int mode, int length, ref int iv_off, byte[] iv, byte[] input, byte[] output); + public extern static int aes_crypt_cfb128(IntPtr ctx, int mode, int length, ref int iv_off, byte[] iv, byte[] input, byte[] output); public const int ARC4_CTX_SIZE = 264; [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void arc4_init(byte[] ctx); + public extern static void arc4_init(IntPtr ctx); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void arc4_free(byte[] ctx); + public extern static void arc4_free(IntPtr ctx); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void arc4_setup(byte[] ctx, byte[] key, int keysize); + public extern static void arc4_setup(IntPtr ctx, byte[] key, int keysize); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int arc4_crypt(byte[] ctx, int length, byte[] input, byte[] output); + public extern static int arc4_crypt(IntPtr ctx, int length, byte[] input, byte[] output); public const int BLOWFISH_CTX_SIZE = 4168; @@ -46,16 +67,16 @@ namespace Shadowsocks.Encrypt public const int BLOWFISH_DECRYPT = 0; [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void blowfish_init(byte[] ctx); + public extern static void blowfish_init(IntPtr ctx); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static void blowfish_free(byte[] ctx); + public extern static void blowfish_free(IntPtr ctx); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int blowfish_setkey(byte[] ctx, byte[] key, int keysize); + public extern static int blowfish_setkey(IntPtr ctx, byte[] key, int keysize); [DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] - public extern static int blowfish_crypt_cfb64(byte[] ctx, int mode, int length, ref int iv_off, byte[] iv, byte[] input, byte[] output); + public extern static int blowfish_crypt_cfb64(IntPtr ctx, int mode, int length, ref int iv_off, byte[] iv, byte[] input, byte[] output); } } diff --git a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs index 68293a8a..7b369130 100755 --- a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs @@ -27,12 +27,12 @@ namespace Shadowsocks.Encrypt private int _cipher; private int[] _cipherInfo; private byte[] _key; - private byte[] _encryptCtx; - private byte[] _decryptCtx; + private IntPtr _encryptCtx = IntPtr.Zero; + private IntPtr _decryptCtx = IntPtr.Zero; private byte[] _encryptIV; private byte[] _decryptIV; - private int _encryptIVOffset; - private int _decryptIVOffset; + private int _encryptIVOffset = 0; + private int _decryptIVOffset = 0; private string _method; private int keyLen; private int ivLen; @@ -100,63 +100,61 @@ namespace Shadowsocks.Encrypt } } - private void InitCipher(ref byte[] ctx, byte[] iv, bool isCipher) + private void InitCipher(ref IntPtr ctx, byte[] iv, bool isCipher) { - ctx = new byte[_cipherInfo[3]]; - lock (ctx) + ctx = Marshal.AllocHGlobal(_cipherInfo[3]); + byte[] realkey; + if (_method == "rc4-md5") { - byte[] realkey; - if (_method == "rc4-md5") + byte[] temp = new byte[keyLen + ivLen]; + realkey = new byte[keyLen]; + Array.Copy(_key, 0, temp, 0, keyLen); + Array.Copy(iv, 0, temp, keyLen, ivLen); + realkey = MD5.Create().ComputeHash(temp); + } + else + { + realkey = _key; + } + if (_cipher == CIPHER_AES) + { + PolarSSL.aes_init(ctx); + // PolarSSL takes key length by bit + // since we'll use CFB mode, here we both do enc, not dec + PolarSSL.aes_setkey_enc(ctx, realkey, keyLen * 8); + if (isCipher) { - byte[] temp = new byte[keyLen + ivLen]; - realkey = new byte[keyLen]; - Array.Copy(_key, 0, temp, 0, keyLen); - Array.Copy(iv, 0, temp, keyLen, ivLen); - realkey = MD5.Create().ComputeHash(temp); + _encryptIV = new byte[ivLen]; + Array.Copy(iv, _encryptIV, ivLen); } else { - realkey = _key; - } - if (_cipher == CIPHER_AES) - { - PolarSSL.aes_init(ctx); - // PolarSSL takes key length by bit - // since we'll use CFB mode, here we both do enc, not dec - PolarSSL.aes_setkey_enc(ctx, realkey, keyLen * 8); - if (isCipher) - { - _encryptIV = new byte[ivLen]; - Array.Copy(iv, _encryptIV, ivLen); - } - else - { - _decryptIV = new byte[ivLen]; - Array.Copy(iv, _decryptIV, ivLen); - } + _decryptIV = new byte[ivLen]; + Array.Copy(iv, _decryptIV, ivLen); } - else if (_cipher == CIPHER_BF) + } + else if (_cipher == CIPHER_BF) + { + PolarSSL.blowfish_init(ctx); + // PolarSSL takes key length by bit + PolarSSL.blowfish_setkey(ctx, realkey, keyLen * 8); + if (isCipher) { - PolarSSL.blowfish_init(ctx); - // PolarSSL takes key length by bit - PolarSSL.blowfish_setkey(ctx, realkey, keyLen * 8); - if (isCipher) - { - _encryptIV = new byte[ivLen]; - Array.Copy(iv, _encryptIV, ivLen); - } - else - { - _decryptIV = new byte[ivLen]; - Array.Copy(iv, _decryptIV, ivLen); - } + _encryptIV = new byte[ivLen]; + Array.Copy(iv, _encryptIV, ivLen); } - else if (_cipher == CIPHER_RC4) + else { - PolarSSL.arc4_init(ctx); - PolarSSL.arc4_setup(ctx, realkey, keyLen); + _decryptIV = new byte[ivLen]; + Array.Copy(iv, _decryptIV, ivLen); } } + else if (_cipher == CIPHER_RC4) + { + PolarSSL.arc4_init(ctx); + // PolarSSL RC4 takes key length by byte + PolarSSL.arc4_setup(ctx, realkey, keyLen); + } } @@ -165,7 +163,7 @@ namespace Shadowsocks.Encrypt public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { - if (_encryptCtx == null) + if (_encryptCtx == IntPtr.Zero) { randBytes(outbuf, ivLen); InitCipher(ref _encryptCtx, outbuf, true); @@ -173,34 +171,6 @@ namespace Shadowsocks.Encrypt lock (tempbuf) { // C# could be multi-threaded - lock (_encryptCtx) - { - if (_disposed) - { - throw new ObjectDisposedException(this.ToString()); - } - switch (_cipher) - { - case CIPHER_AES: - PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, tempbuf); - break; - case CIPHER_BF: - PolarSSL.blowfish_crypt_cfb64(_encryptCtx, PolarSSL.BLOWFISH_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, tempbuf); - break; - case CIPHER_RC4: - PolarSSL.arc4_crypt(_encryptCtx, length, buf, tempbuf); - break; - } - outlength = length + ivLen; - Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, outlength); - } - } - } - else - { - outlength = length; - lock (_encryptCtx) - { if (_disposed) { throw new ObjectDisposedException(this.ToString()); @@ -208,22 +178,45 @@ namespace Shadowsocks.Encrypt switch (_cipher) { case CIPHER_AES: - PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, outbuf); + PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, tempbuf); break; case CIPHER_BF: - PolarSSL.blowfish_crypt_cfb64(_encryptCtx, PolarSSL.BLOWFISH_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, outbuf); + PolarSSL.blowfish_crypt_cfb64(_encryptCtx, PolarSSL.BLOWFISH_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, tempbuf); break; case CIPHER_RC4: - PolarSSL.arc4_crypt(_encryptCtx, length, buf, outbuf); + PolarSSL.arc4_crypt(_encryptCtx, length, buf, tempbuf); break; } + outlength = length + ivLen; + Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length); + + } + } + else + { + outlength = length; + if (_disposed) + { + throw new ObjectDisposedException(this.ToString()); + } + switch (_cipher) + { + case CIPHER_AES: + PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, outbuf); + break; + case CIPHER_BF: + PolarSSL.blowfish_crypt_cfb64(_encryptCtx, PolarSSL.BLOWFISH_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, outbuf); + break; + case CIPHER_RC4: + PolarSSL.arc4_crypt(_encryptCtx, length, buf, outbuf); + break; } } } public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { - if (_decryptCtx == null) + if (_decryptCtx == IntPtr.Zero) { InitCipher(ref _decryptCtx, buf, false); outlength = length - ivLen; @@ -231,32 +224,6 @@ namespace Shadowsocks.Encrypt { // C# could be multi-threaded Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen); - lock (_decryptCtx) - { - if (_disposed) - { - throw new ObjectDisposedException(this.ToString()); - } - switch (_cipher) - { - case CIPHER_AES: - PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length - ivLen, ref _decryptIVOffset, _decryptIV, tempbuf, outbuf); - break; - case CIPHER_BF: - PolarSSL.blowfish_crypt_cfb64(_decryptCtx, PolarSSL.BLOWFISH_DECRYPT, length - ivLen, ref _decryptIVOffset, _decryptIV, tempbuf, outbuf); - break; - case CIPHER_RC4: - PolarSSL.arc4_crypt(_decryptCtx, length - ivLen, tempbuf, outbuf); - break; - } - } - } - } - else - { - outlength = length; - lock (_decryptCtx) - { if (_disposed) { throw new ObjectDisposedException(this.ToString()); @@ -264,17 +231,37 @@ namespace Shadowsocks.Encrypt switch (_cipher) { case CIPHER_AES: - PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length, ref _decryptIVOffset, _decryptIV, buf, outbuf); + PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length - ivLen, ref _decryptIVOffset, _decryptIV, tempbuf, outbuf); break; case CIPHER_BF: - PolarSSL.blowfish_crypt_cfb64(_decryptCtx, PolarSSL.BLOWFISH_DECRYPT, length, ref _decryptIVOffset, _decryptIV, buf, outbuf); + PolarSSL.blowfish_crypt_cfb64(_decryptCtx, PolarSSL.BLOWFISH_DECRYPT, length - ivLen, ref _decryptIVOffset, _decryptIV, tempbuf, outbuf); break; case CIPHER_RC4: - PolarSSL.arc4_crypt(_decryptCtx, length, buf, outbuf); + PolarSSL.arc4_crypt(_decryptCtx, length - ivLen, tempbuf, outbuf); break; } } } + else + { + outlength = length; + if (_disposed) + { + throw new ObjectDisposedException(this.ToString()); + } + switch (_cipher) + { + case CIPHER_AES: + PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length, ref _decryptIVOffset, _decryptIV, buf, outbuf); + break; + case CIPHER_BF: + PolarSSL.blowfish_crypt_cfb64(_decryptCtx, PolarSSL.BLOWFISH_DECRYPT, length, ref _decryptIVOffset, _decryptIV, buf, outbuf); + break; + case CIPHER_RC4: + PolarSSL.arc4_crypt(_decryptCtx, length, buf, outbuf); + break; + } + } } #region IDisposable @@ -304,41 +291,39 @@ namespace Shadowsocks.Encrypt if (disposing) { - if (_encryptCtx != null) + if (_encryptCtx != IntPtr.Zero) { - lock (_encryptCtx) + switch (_cipher) { - switch (_cipher) - { - case CIPHER_AES: - PolarSSL.aes_free(_encryptCtx); - break; - case CIPHER_BF: - PolarSSL.blowfish_free(_encryptCtx); - break; - case CIPHER_RC4: - PolarSSL.arc4_free(_encryptCtx); - break; - } + case CIPHER_AES: + PolarSSL.aes_free(_encryptCtx); + break; + case CIPHER_BF: + PolarSSL.blowfish_free(_encryptCtx); + break; + case CIPHER_RC4: + PolarSSL.arc4_free(_encryptCtx); + break; } + Marshal.FreeHGlobal(_encryptCtx); + _encryptCtx = IntPtr.Zero; } - if (_decryptCtx != null) + if (_decryptCtx != IntPtr.Zero) { - lock (_decryptCtx) + switch (_cipher) { - switch (_cipher) - { - case CIPHER_AES: - PolarSSL.aes_free(_decryptCtx); - break; - case CIPHER_BF: - PolarSSL.blowfish_free(_decryptCtx); - break; - case CIPHER_RC4: - PolarSSL.arc4_free(_decryptCtx); - break; - } + case CIPHER_AES: + PolarSSL.aes_free(_decryptCtx); + break; + case CIPHER_BF: + PolarSSL.blowfish_free(_decryptCtx); + break; + case CIPHER_RC4: + PolarSSL.arc4_free(_decryptCtx); + break; } + Marshal.FreeHGlobal(_decryptCtx); + _decryptCtx = IntPtr.Zero; } } } diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 65b0a3b6..db02b840 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -2,16 +2,13 @@ using System.Collections.Generic; using System.IO; using System.Text; +using System.Windows.Forms; namespace Shadowsocks.Model { [Serializable] public class Configuration { - public Configuration() - { - } - public List configs; public int index; public bool enabled; diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index d730419a..7b0d6df0 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -5,8 +5,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; @@ -14,8 +12,6 @@ namespace Shadowsocks { static class Program { - [DllImport("Kernel32.dll")] - private static extern IntPtr LoadLibrary(string path); /// /// 应用程序的主入口点。 @@ -35,18 +31,7 @@ namespace Shadowsocks MessageBox.Show("Shadowsocks is already running.\n\nFind Shadowsocks icon in your notify tray."); return; } - string tempPath = Path.GetTempPath(); - string dllPath = tempPath + "/libeay32.dll"; - try - { - FileManager.UncompressFile(dllPath, Resources.libeay32_dll); - } - catch (IOException e) - { - Console.WriteLine(e.ToString()); - } - LoadLibrary(dllPath); - + Directory.SetCurrentDirectory(Application.StartupPath); #if !DEBUG Logging.OpenLogFile(); #endif diff --git a/shadowsocks-csharp/Properties/AssemblyInfo.cs b/shadowsocks-csharp/Properties/AssemblyInfo.cs index a5fe27d4..90a614c5 100755 --- a/shadowsocks-csharp/Properties/AssemblyInfo.cs +++ b/shadowsocks-csharp/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.7")] +[assembly: AssemblyVersion("2.0.9")] // [assembly: AssemblyFileVersion("2.0.0")] diff --git a/shadowsocks-csharp/Properties/Resources.Designer.cs b/shadowsocks-csharp/Properties/Resources.Designer.cs index 65b2d0a2..4f9edeba 100755 --- a/shadowsocks-csharp/Properties/Resources.Designer.cs +++ b/shadowsocks-csharp/Properties/Resources.Designer.cs @@ -63,16 +63,6 @@ namespace Shadowsocks.Properties { /// /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] libeay32_dll { - get { - object obj = ResourceManager.GetObject("libeay32_dll", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Byte[]. - /// internal static byte[] polarssl_dll { get { object obj = ResourceManager.GetObject("polarssl_dll", resourceCulture); diff --git a/shadowsocks-csharp/Properties/Resources.resx b/shadowsocks-csharp/Properties/Resources.resx index f196cbea..a644b5f9 100755 --- a/shadowsocks-csharp/Properties/Resources.resx +++ b/shadowsocks-csharp/Properties/Resources.resx @@ -118,9 +118,6 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - ..\Data\libeay32.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ..\Data\polarssl.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 6b246c66..1d5f7236 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -49,6 +49,7 @@ this.panel1 = new System.Windows.Forms.Panel(); this.contextMenu1 = new System.Windows.Forms.ContextMenu(); this.enableItem = new System.Windows.Forms.MenuItem(); + this.AutoStartupItem = new System.Windows.Forms.MenuItem(); this.ShareOverLANItem = new System.Windows.Forms.MenuItem(); this.ServersItem = new System.Windows.Forms.MenuItem(); this.SeperatorItem = new System.Windows.Forms.MenuItem(); @@ -65,6 +66,7 @@ this.AddButton = new System.Windows.Forms.Button(); this.ServerGroupBox = new System.Windows.Forms.GroupBox(); this.ServersListBox = new System.Windows.Forms.ListBox(); + this.menuItem1 = new System.Windows.Forms.MenuItem(); this.tableLayoutPanel1.SuspendLayout(); this.panel1.SuspendLayout(); this.panel3.SuspendLayout(); @@ -90,10 +92,10 @@ this.tableLayoutPanel1.Controls.Add(this.PasswordTextBox, 1, 2); this.tableLayoutPanel1.Controls.Add(this.label5, 0, 3); this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 3); - this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 31); - this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(7, 7, 7, 7); + this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(7, 7, 7, 7); + this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(5, 5, 5, 5); this.tableLayoutPanel1.RowCount = 6; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); @@ -101,16 +103,15 @@ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(360, 232); + this.tableLayoutPanel1.Size = new System.Drawing.Size(242, 167); this.tableLayoutPanel1.TabIndex = 0; // // RemarksTextBox // this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.RemarksTextBox.Location = new System.Drawing.Point(110, 194); - this.RemarksTextBox.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.RemarksTextBox.Location = new System.Drawing.Point(74, 139); this.RemarksTextBox.Name = "RemarksTextBox"; - this.RemarksTextBox.Size = new System.Drawing.Size(238, 26); + this.RemarksTextBox.Size = new System.Drawing.Size(160, 20); this.RemarksTextBox.TabIndex = 10; this.RemarksTextBox.WordWrap = false; // @@ -118,10 +119,9 @@ // this.label6.Anchor = System.Windows.Forms.AnchorStyles.Right; this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(27, 197); - this.label6.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); + this.label6.Location = new System.Drawing.Point(19, 142); this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(73, 20); + this.label6.Size = new System.Drawing.Size(49, 13); this.label6.TabIndex = 9; this.label6.Text = "Remarks"; // @@ -129,10 +129,9 @@ // this.label1.Anchor = System.Windows.Forms.AnchorStyles.Right; this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(26, 15); - this.label1.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); + this.label1.Location = new System.Drawing.Point(17, 11); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(74, 20); + this.label1.Size = new System.Drawing.Size(51, 13); this.label1.TabIndex = 0; this.label1.Text = "Server IP"; // @@ -140,20 +139,18 @@ // this.label2.Anchor = System.Windows.Forms.AnchorStyles.Right; this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(12, 51); - this.label2.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); + this.label2.Location = new System.Drawing.Point(8, 37); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(88, 20); + this.label2.Size = new System.Drawing.Size(60, 13); this.label2.TabIndex = 1; this.label2.Text = "Server Port"; // // ProxyPortTextBox // this.ProxyPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyPortTextBox.Location = new System.Drawing.Point(110, 158); - this.ProxyPortTextBox.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.ProxyPortTextBox.Location = new System.Drawing.Point(74, 113); this.ProxyPortTextBox.Name = "ProxyPortTextBox"; - this.ProxyPortTextBox.Size = new System.Drawing.Size(238, 26); + this.ProxyPortTextBox.Size = new System.Drawing.Size(160, 20); this.ProxyPortTextBox.TabIndex = 4; this.ProxyPortTextBox.WordWrap = false; // @@ -161,10 +158,9 @@ // this.label4.Anchor = System.Windows.Forms.AnchorStyles.Right; this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(20, 161); - this.label4.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); + this.label4.Location = new System.Drawing.Point(13, 116); this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(80, 20); + this.label4.Size = new System.Drawing.Size(55, 13); this.label4.TabIndex = 3; this.label4.Text = "Proxy Port"; // @@ -172,41 +168,37 @@ // this.label3.Anchor = System.Windows.Forms.AnchorStyles.Right; this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(22, 87); - this.label3.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); + this.label3.Location = new System.Drawing.Point(15, 63); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(78, 20); + this.label3.Size = new System.Drawing.Size(53, 13); this.label3.TabIndex = 2; this.label3.Text = "Password"; // // IPTextBox // this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.IPTextBox.Location = new System.Drawing.Point(110, 12); - this.IPTextBox.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.IPTextBox.Location = new System.Drawing.Point(74, 8); this.IPTextBox.Name = "IPTextBox"; - this.IPTextBox.Size = new System.Drawing.Size(238, 26); + this.IPTextBox.Size = new System.Drawing.Size(160, 20); this.IPTextBox.TabIndex = 0; this.IPTextBox.WordWrap = false; // // ServerPortTextBox // this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ServerPortTextBox.Location = new System.Drawing.Point(110, 48); - this.ServerPortTextBox.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.ServerPortTextBox.Location = new System.Drawing.Point(74, 34); this.ServerPortTextBox.Name = "ServerPortTextBox"; - this.ServerPortTextBox.Size = new System.Drawing.Size(238, 26); + this.ServerPortTextBox.Size = new System.Drawing.Size(160, 20); this.ServerPortTextBox.TabIndex = 1; this.ServerPortTextBox.WordWrap = false; // // PasswordTextBox // this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PasswordTextBox.Location = new System.Drawing.Point(110, 84); - this.PasswordTextBox.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.PasswordTextBox.Location = new System.Drawing.Point(74, 60); this.PasswordTextBox.Name = "PasswordTextBox"; this.PasswordTextBox.PasswordChar = '*'; - this.PasswordTextBox.Size = new System.Drawing.Size(238, 26); + this.PasswordTextBox.Size = new System.Drawing.Size(160, 20); this.PasswordTextBox.TabIndex = 2; this.PasswordTextBox.WordWrap = false; // @@ -214,10 +206,9 @@ // this.label5.Anchor = System.Windows.Forms.AnchorStyles.Right; this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(16, 124); - this.label5.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); + this.label5.Location = new System.Drawing.Point(11, 90); this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(84, 20); + this.label5.Size = new System.Drawing.Size(57, 13); this.label5.TabIndex = 8; this.label5.Text = "Encryption"; // @@ -228,7 +219,7 @@ this.EncryptionSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.EncryptionSelect.FormattingEnabled = true; this.EncryptionSelect.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.EncryptionSelect.ItemHeight = 20; + this.EncryptionSelect.ItemHeight = 13; this.EncryptionSelect.Items.AddRange(new object[] { "table", "rc4-md5", @@ -237,10 +228,9 @@ "aes-128-cfb", "bf-cfb", "rc4"}); - this.EncryptionSelect.Location = new System.Drawing.Point(110, 120); - this.EncryptionSelect.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.EncryptionSelect.Location = new System.Drawing.Point(74, 86); this.EncryptionSelect.Name = "EncryptionSelect"; - this.EncryptionSelect.Size = new System.Drawing.Size(238, 28); + this.EncryptionSelect.Size = new System.Drawing.Size(160, 21); this.EncryptionSelect.TabIndex = 3; // // notifyIcon1 @@ -253,8 +243,7 @@ this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top; this.panel2.AutoSize = true; this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.panel2.Location = new System.Drawing.Point(246, 263); - this.panel2.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.panel2.Location = new System.Drawing.Point(164, 175); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(0, 0); this.panel2.TabIndex = 1; @@ -262,10 +251,9 @@ // OKButton // this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.OKButton.Location = new System.Drawing.Point(6, 6); - this.OKButton.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.OKButton.Location = new System.Drawing.Point(4, 4); this.OKButton.Name = "OKButton"; - this.OKButton.Size = new System.Drawing.Size(113, 35); + this.OKButton.Size = new System.Drawing.Size(75, 23); this.OKButton.TabIndex = 8; this.OKButton.Text = "OK"; this.OKButton.UseVisualStyleBackColor = true; @@ -274,10 +262,9 @@ // MyCancelButton // this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.MyCancelButton.Location = new System.Drawing.Point(130, 6); - this.MyCancelButton.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.MyCancelButton.Location = new System.Drawing.Point(87, 4); this.MyCancelButton.Name = "MyCancelButton"; - this.MyCancelButton.Size = new System.Drawing.Size(113, 35); + this.MyCancelButton.Size = new System.Drawing.Size(75, 23); this.MyCancelButton.TabIndex = 9; this.MyCancelButton.Text = "Cancel"; this.MyCancelButton.UseVisualStyleBackColor = true; @@ -289,20 +276,22 @@ this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.panel1.Controls.Add(this.MyCancelButton); this.panel1.Controls.Add(this.OKButton); - this.panel1.Location = new System.Drawing.Point(469, 371); + this.panel1.Location = new System.Drawing.Point(313, 247); this.panel1.Margin = new System.Windows.Forms.Padding(0); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(248, 46); + this.panel1.Size = new System.Drawing.Size(165, 30); this.panel1.TabIndex = 1; // // contextMenu1 // this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.enableItem, - this.ShareOverLANItem, this.ServersItem, - this.menuItem4, + this.menuItem1, + this.AutoStartupItem, + this.ShareOverLANItem, this.editPACFileItem, + this.menuItem4, this.QRCodeItem, this.ShowLogItem, this.aboutItem, @@ -315,15 +304,21 @@ this.enableItem.Text = "&Enable"; this.enableItem.Click += new System.EventHandler(this.EnableItem_Click); // + // AutoStartupItem + // + this.AutoStartupItem.Index = 3; + this.AutoStartupItem.Text = "Start on Boot"; + this.AutoStartupItem.Click += new System.EventHandler(this.AutoStartupItem_Click); + // // ShareOverLANItem // - this.ShareOverLANItem.Index = 1; + this.ShareOverLANItem.Index = 4; this.ShareOverLANItem.Text = "Share over LAN"; this.ShareOverLANItem.Click += new System.EventHandler(this.ShareOverLANItem_Click); // // ServersItem // - this.ServersItem.Index = 2; + this.ServersItem.Index = 1; this.ServersItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.SeperatorItem, this.ConfigItem}); @@ -342,41 +337,41 @@ // // menuItem4 // - this.menuItem4.Index = 3; + this.menuItem4.Index = 6; this.menuItem4.Text = "-"; // // editPACFileItem // - this.editPACFileItem.Index = 4; + this.editPACFileItem.Index = 5; this.editPACFileItem.Text = "Edit &PAC File..."; this.editPACFileItem.Click += new System.EventHandler(this.EditPACFileItem_Click); // // QRCodeItem // - this.QRCodeItem.Index = 5; + this.QRCodeItem.Index = 7; this.QRCodeItem.Text = "Show &QRCode..."; this.QRCodeItem.Click += new System.EventHandler(this.QRCodeItem_Click); // // ShowLogItem // - this.ShowLogItem.Index = 6; + this.ShowLogItem.Index = 8; this.ShowLogItem.Text = "Show Logs..."; this.ShowLogItem.Click += new System.EventHandler(this.ShowLogItem_Click); // // aboutItem // - this.aboutItem.Index = 7; + this.aboutItem.Index = 9; this.aboutItem.Text = "About..."; this.aboutItem.Click += new System.EventHandler(this.AboutItem_Click); // // menuItem3 // - this.menuItem3.Index = 8; + this.menuItem3.Index = 10; this.menuItem3.Text = "-"; // // quitItem // - this.quitItem.Index = 9; + this.quitItem.Index = 11; this.quitItem.Text = "&Quit"; this.quitItem.Click += new System.EventHandler(this.Quit_Click); // @@ -385,18 +380,17 @@ this.panel3.AutoSize = true; this.panel3.Controls.Add(this.DeleteButton); this.panel3.Controls.Add(this.AddButton); - this.panel3.Location = new System.Drawing.Point(18, 330); + this.panel3.Location = new System.Drawing.Point(12, 220); this.panel3.Margin = new System.Windows.Forms.Padding(0); this.panel3.Name = "panel3"; - this.panel3.Size = new System.Drawing.Size(288, 46); + this.panel3.Size = new System.Drawing.Size(192, 31); this.panel3.TabIndex = 5; // // DeleteButton // - this.DeleteButton.Location = new System.Drawing.Point(150, 6); - this.DeleteButton.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.DeleteButton.Location = new System.Drawing.Point(100, 4); this.DeleteButton.Name = "DeleteButton"; - this.DeleteButton.Size = new System.Drawing.Size(133, 35); + this.DeleteButton.Size = new System.Drawing.Size(89, 23); this.DeleteButton.TabIndex = 7; this.DeleteButton.Text = "&Delete"; this.DeleteButton.UseVisualStyleBackColor = true; @@ -404,10 +398,9 @@ // // AddButton // - this.AddButton.Location = new System.Drawing.Point(6, 6); - this.AddButton.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.AddButton.Location = new System.Drawing.Point(4, 4); this.AddButton.Name = "AddButton"; - this.AddButton.Size = new System.Drawing.Size(133, 35); + this.AddButton.Size = new System.Drawing.Size(89, 23); this.AddButton.TabIndex = 6; this.AddButton.Text = "&Add"; this.AddButton.UseVisualStyleBackColor = true; @@ -416,11 +409,9 @@ // ServerGroupBox // this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1); - this.ServerGroupBox.Location = new System.Drawing.Point(334, 18); - this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.ServerGroupBox.Location = new System.Drawing.Point(223, 12); this.ServerGroupBox.Name = "ServerGroupBox"; - this.ServerGroupBox.Padding = new System.Windows.Forms.Padding(5, 5, 5, 5); - this.ServerGroupBox.Size = new System.Drawing.Size(383, 307); + this.ServerGroupBox.Size = new System.Drawing.Size(255, 205); this.ServerGroupBox.TabIndex = 6; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; @@ -428,29 +419,31 @@ // ServersListBox // this.ServersListBox.FormattingEnabled = true; - this.ServersListBox.ItemHeight = 20; - this.ServersListBox.Location = new System.Drawing.Point(18, 18); - this.ServersListBox.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.ServersListBox.Location = new System.Drawing.Point(12, 12); this.ServersListBox.Name = "ServersListBox"; - this.ServersListBox.Size = new System.Drawing.Size(286, 264); + this.ServersListBox.Size = new System.Drawing.Size(192, 173); this.ServersListBox.TabIndex = 5; this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); // + // menuItem1 + // + this.menuItem1.Index = 2; + this.menuItem1.Text = "-"; + // // ConfigForm // this.AcceptButton = this.OKButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(144F, 144F); + this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; this.AutoSize = true; this.CancelButton = this.MyCancelButton; - this.ClientSize = new System.Drawing.Size(733, 430); + this.ClientSize = new System.Drawing.Size(489, 287); this.Controls.Add(this.ServersListBox); this.Controls.Add(this.ServerGroupBox); this.Controls.Add(this.panel1); this.Controls.Add(this.panel3); this.Controls.Add(this.panel2); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ConfigForm"; @@ -508,6 +501,8 @@ private System.Windows.Forms.MenuItem QRCodeItem; private System.Windows.Forms.MenuItem ShowLogItem; private System.Windows.Forms.MenuItem ShareOverLANItem; + private System.Windows.Forms.MenuItem AutoStartupItem; + private System.Windows.Forms.MenuItem menuItem1; } } diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index f992222a..c1bfff63 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -5,6 +5,7 @@ using System.Drawing; using System.Text; using System.Windows.Forms; using System.Diagnostics; +using Microsoft.Win32; using Shadowsocks.Controller; using Shadowsocks.Model; using Shadowsocks.Properties; @@ -184,6 +185,7 @@ namespace Shadowsocks.View UpdateServersMenu(); enableItem.Checked = _modifiedConfiguration.enabled; ShareOverLANItem.Checked = _modifiedConfiguration.shareOverLan; + AutoStartupItem.Checked = AutoStartup.Check(); } private void UpdateServersMenu() @@ -377,5 +379,12 @@ namespace Shadowsocks.View qrCodeForm.Icon = this.Icon; qrCodeForm.Show(); } + + private void AutoStartupItem_Click(object sender, EventArgs e) { + AutoStartupItem.Checked = !AutoStartupItem.Checked; + if (!AutoStartup.Set(AutoStartupItem.Checked)) { + MessageBox.Show("Failed to edit registry"); + } + } } } diff --git a/shadowsocks-csharp/View/ConfigForm.resx b/shadowsocks-csharp/View/ConfigForm.resx index dc4a77ba..3dc5188a 100755 --- a/shadowsocks-csharp/View/ConfigForm.resx +++ b/shadowsocks-csharp/View/ConfigForm.resx @@ -112,15 +112,15 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + 17, 17 - + 146, 19 \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 7629f4fc..41515225 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -71,13 +71,12 @@ + - - diff --git a/test/UnitTest.cs b/test/UnitTest.cs index c23f4c75..166620f5 100755 --- a/test/UnitTest.cs +++ b/test/UnitTest.cs @@ -1,6 +1,9 @@ using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Shadowsocks.Controller; +using Shadowsocks.Encrypt; +using System.Threading; +using System.Collections.Generic; namespace test { @@ -18,5 +21,77 @@ namespace test Assert.IsTrue(UpdateChecker.CompareVersion("2.3.1", "2.4") < 0); Assert.IsTrue(UpdateChecker.CompareVersion("1.3.2", "1.3.1") > 0); } + + [TestMethod] + public void TestEncryption() + { + // run it once before the multi-threading test to initialize global tables + RunSingleEncryptionThread(); + List threads = new List(); + for (int i = 0; i < 10; i++) + { + Thread t = new Thread(new ThreadStart(RunSingleEncryptionThread)); + threads.Add(t); + t.Start(); + } + foreach (Thread t in threads) + { + t.Join(); + } + Assert.IsFalse(encryptionFailed); + } + + private static bool encryptionFailed = false; + private static object locker = new object(); + + private void RunSingleEncryptionThread() + { + try + { + for (int i = 0; i < 1000; i++) + { + var random = new Random(); + IEncryptor encryptor; + IEncryptor decryptor; + encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); + decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); + byte[] plain = new byte[16384]; + byte[] cipher = new byte[plain.Length + 16]; + byte[] plain2 = new byte[plain.Length + 16]; + int outLen = 0; + int outLen2 = 0; + random.NextBytes(plain); + //lock (locker) + //{ + encryptor.Encrypt(plain, plain.Length, cipher, out outLen); + decryptor.Decrypt(cipher, outLen, plain2, out outLen2); + Assert.AreEqual(plain.Length, outLen2); + for (int j = 0; j < plain.Length; j++) + { + Assert.AreEqual(plain[j], plain2[j]); + } + encryptor.Encrypt(plain, 1000, cipher, out outLen); + decryptor.Decrypt(cipher, outLen, plain2, out outLen2); + Assert.AreEqual(1000, outLen2); + for (int j = 0; j < outLen2; j++) + { + Assert.AreEqual(plain[j], plain2[j]); + } + encryptor.Encrypt(plain, 12333, cipher, out outLen); + decryptor.Decrypt(cipher, outLen, plain2, out outLen2); + Assert.AreEqual(12333, outLen2); + for (int j = 0; j < outLen2; j++) + { + Assert.AreEqual(plain[j], plain2[j]); + } + //} + } + } + catch + { + encryptionFailed = true; + throw; + } + } } } diff --git a/test/test.csproj b/test/test.csproj index 235846d0..d7420145 100755 --- a/test/test.csproj +++ b/test/test.csproj @@ -26,6 +26,9 @@ bin\x86\Release\ x86 + + +