Browse Source

Merge pull request #5 from clowwindy/master

Merge with upstream
pull/146/head
Sharuru 10 years ago
parent
commit
203875186e
22 changed files with 522 additions and 513 deletions
  1. +10
    -0
      CHANGES
  2. +39
    -0
      shadowsocks-csharp/Controller/AutoStartup.cs
  3. +79
    -18
      shadowsocks-csharp/Controller/Local.cs
  4. +39
    -6
      shadowsocks-csharp/Controller/PACServer.cs
  5. +22
    -0
      shadowsocks-csharp/Controller/SystemProxy.cs
  6. +3
    -0
      shadowsocks-csharp/Data/polipo_config.txt
  7. +1
    -1
      shadowsocks-csharp/Encrypt/EncryptorFactory.cs
  8. +0
    -45
      shadowsocks-csharp/Encrypt/OpenSSL.cs
  9. +0
    -170
      shadowsocks-csharp/Encrypt/OpenSSLEncryptor.cs
  10. +34
    -13
      shadowsocks-csharp/Encrypt/PolarSSL.cs
  11. +124
    -139
      shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs
  12. +1
    -4
      shadowsocks-csharp/Model/Configuration.cs
  13. +1
    -16
      shadowsocks-csharp/Program.cs
  14. +1
    -1
      shadowsocks-csharp/Properties/AssemblyInfo.cs
  15. +0
    -10
      shadowsocks-csharp/Properties/Resources.Designer.cs
  16. +0
    -3
      shadowsocks-csharp/Properties/Resources.resx
  17. +76
    -81
      shadowsocks-csharp/View/ConfigForm.Designer.cs
  18. +9
    -0
      shadowsocks-csharp/View/ConfigForm.cs
  19. +4
    -4
      shadowsocks-csharp/View/ConfigForm.resx
  20. +1
    -2
      shadowsocks-csharp/shadowsocks-csharp.csproj
  21. +75
    -0
      test/UnitTest.cs
  22. +3
    -0
      test/test.csproj

+ 10
- 0
CHANGES View File

@@ -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



+ 39
- 0
shadowsocks-csharp/Controller/AutoStartup.cs View File

@@ -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;
}
}
}
}

+ 79
- 18
shadowsocks-csharp/Controller/Local.cs View File

@@ -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();
}
}


+ 39
- 6
shadowsocks-csharp/Controller/PACServer.cs View File

@@ -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;
}
}
}

+ 22
- 0
shadowsocks-csharp/Controller/SystemProxy.cs View File

@@ -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");


+ 3
- 0
shadowsocks-csharp/Data/polipo_config.txt View File

@@ -4,3 +4,6 @@ socksParentProxy = "127.0.0.1:__SOCKS_PORT__"
socksProxyType = socks5
diskCacheRoot = ""
localDocumentRoot = ""

allowedPorts = 1-65535
tunnelAllowedPorts = 1-65535

+ 1
- 1
shadowsocks-csharp/Encrypt/EncryptorFactory.cs View File

@@ -10,7 +10,7 @@ namespace Shadowsocks.Encrypt
return new TableEncryptor(method, password);
}
return new OpenSSLEncryptor(method, password);
return new PolarSSLEncryptor(method, password);
}
}
}

+ 0
- 45
shadowsocks-csharp/Encrypt/OpenSSL.cs View File

@@ -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);
}
}

+ 0
- 170
shadowsocks-csharp/Encrypt/OpenSSLEncryptor.cs View File

@@ -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<string, int[]> ciphers = new Dictionary<string, int[]> {
{"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<string, byte[]> CachedKeys = new Dictionary<string, byte[]>();
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
}
}

+ 34
- 13
shadowsocks-csharp/Encrypt/PolarSSL.cs View File

@@ -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);
}
}

+ 124
- 139
shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs View File

@@ -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;
}
}
}


+ 1
- 4
shadowsocks-csharp/Model/Configuration.cs View File

@@ -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<Server> configs;
public int index;
public bool enabled;


+ 1
- 16
shadowsocks-csharp/Program.cs View File

@@ -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);
/// <summary>
/// 应用程序的主入口点。
@@ -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


+ 1
- 1
shadowsocks-csharp/Properties/AssemblyInfo.cs View File

@@ -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")]

+ 0
- 10
shadowsocks-csharp/Properties/Resources.Designer.cs View File

@@ -63,16 +63,6 @@ namespace Shadowsocks.Properties {
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] libeay32_dll {
get {
object obj = ResourceManager.GetObject("libeay32_dll", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] polarssl_dll {
get {
object obj = ResourceManager.GetObject("polarssl_dll", resourceCulture);


+ 0
- 3
shadowsocks-csharp/Properties/Resources.resx View File

@@ -118,9 +118,6 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="libeay32_dll" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Data\libeay32.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="polarssl_dll" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Data\polarssl.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>


+ 76
- 81
shadowsocks-csharp/View/ConfigForm.Designer.cs View File

@@ -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;
}
}

+ 9
- 0
shadowsocks-csharp/View/ConfigForm.cs View File

@@ -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");
}
}
}
}

+ 4
- 4
shadowsocks-csharp/View/ConfigForm.resx View File

@@ -112,15 +112,15 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="notifyIcon1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="notifyIcon1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="contextMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="contextMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>146, 19</value>
</metadata>
</root>

+ 1
- 2
shadowsocks-csharp/shadowsocks-csharp.csproj View File

@@ -71,13 +71,12 @@
<ItemGroup>
<Compile Include="3rd\QRCodeCS.cs" />
<Compile Include="3rd\SimpleJson.cs" />
<Compile Include="Controller\AutoStartup.cs" />
<Compile Include="Controller\FileManager.cs" />
<Compile Include="Controller\Logging.cs" />
<Compile Include="Controller\UpdateChecker.cs" />
<Compile Include="Encrypt\EncryptorBase.cs" />
<Compile Include="Encrypt\EncryptorFactory.cs" />
<Compile Include="Encrypt\OpenSSL.cs" />
<Compile Include="Encrypt\OpenSSLEncryptor.cs" />
<Compile Include="Encrypt\PolarSSL.cs" />
<Compile Include="Encrypt\PolarSSLEncryptor.cs" />
<Compile Include="Encrypt\TableEncryptor.cs" />


+ 75
- 0
test/UnitTest.cs View File

@@ -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<Thread> threads = new List<Thread>();
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;
}
}
}
}

+ 3
- 0
test/test.csproj View File

@@ -26,6 +26,9 @@
<OutputPath>bin\x86\Release\</OutputPath>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>


Loading…
Cancel
Save