@@ -1,3 +1,22 @@ | |||||
2.1.4 2014-12-20 | |||||
- Fix crash when remarks are too long | |||||
2.1.3 2014-12-20 | |||||
- Add Chinese Language | |||||
- Fix some UI issues on Windows 8 | |||||
- Fix some UI issues on high DPI screens | |||||
- Log bind error more friendly | |||||
- Stability issues | |||||
2.1.2 2014-12-14 | |||||
- Fix sometimes Shadowsocks doesn't respond to requests | |||||
2.1.1 2014-12-14 | |||||
- Add global proxy option | |||||
2.1 2014-12-12 | |||||
- Add salsa20 and chacha20 support | |||||
2.0.11 2014-11-23 | 2.0.11 2014-11-23 | ||||
- Fix a crash | - Fix a crash | ||||
- Only switch the system proxy off if we have switched it on | - Only switch the system proxy off if we have switched it on | ||||
@@ -3,36 +3,34 @@ Shadowsocks for Windows | |||||
[![Build Status]][Appveyor] | [![Build Status]][Appveyor] | ||||
### Features | |||||
#### Features | |||||
1. Native Windows UI | |||||
2. Fast system proxy switching | |||||
3. Compatible with IE | |||||
4. Builtin PAC server with user editable PAC | |||||
5. QRCode generation | |||||
6. Only a single exe file of 200KB size | |||||
1. System proxy configuration | |||||
2. Fast profile switching | |||||
3. PAC mode and global mode | |||||
4. Compatible with IE | |||||
5. Only a single exe file of 200KB size | |||||
### Download | |||||
#### Download | |||||
Download [latest release]. | Download [latest release]. | ||||
For Windows 7 and older, please download Shadowsocks-win-x.x.x.zip. | |||||
For <= Windows 7, download Shadowsocks-win-x.x.x.zip. | |||||
For Windows 8 and newer, please download Shadowsocks-win-dotnet4.0-x.x.x.zip. | |||||
For >= Windows 8, download Shadowsocks-win-dotnet4.0-x.x.x.zip. | |||||
### Usage | |||||
#### Usage | |||||
1. Find Shadowsocks icon in notification tray | 1. Find Shadowsocks icon in notification tray | ||||
2. You can add multiple servers in servers menu | 2. You can add multiple servers in servers menu | ||||
3. After servers are added, click Enable menu item to enable system proxy | |||||
4. After you saved PAC file with any editor, Shadowsocks will notify browsers | |||||
3. Select Enable menu to enable system proxy | |||||
4. Leave Enable menu unchecked, Shadowsocks will still provide an HTTP proxy at 127.0.0.1:8123 | |||||
5. After you saved PAC file with any editor, Shadowsocks will notify browsers | |||||
about the change automatically | about the change automatically | ||||
5. Please disable other proxy addons in your browser, or set them to use | |||||
6. Please disable other proxy addons in your browser, or set them to use | |||||
system proxy | system proxy | ||||
6. You may need to install VC 2008 Runtime and .Net framework if Shadowsocks | |||||
failed to start | |||||
### License | |||||
#### License | |||||
GPLv3 | GPLv3 | ||||
@@ -0,0 +1,42 @@ | |||||
using Shadowsocks.Properties; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Text.RegularExpressions; | |||||
namespace Shadowsocks.Controller | |||||
{ | |||||
public class I18N | |||||
{ | |||||
protected static Dictionary<string, string> Strings; | |||||
static I18N() | |||||
{ | |||||
Strings = new Dictionary<string, string>(); | |||||
if (System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag.ToLowerInvariant().StartsWith("zh")) | |||||
{ | |||||
string[] lines = Regex.Split(Resources.cn, "\r\n|\r|\n"); | |||||
foreach (string line in lines) | |||||
{ | |||||
string[] kv = Regex.Split(line, "="); | |||||
if (kv.Length == 2) | |||||
{ | |||||
Strings[kv[0]] = kv[1]; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
public static string GetString(string key) | |||||
{ | |||||
if (Strings.ContainsKey(key)) | |||||
{ | |||||
return Strings[key]; | |||||
} | |||||
else | |||||
{ | |||||
return key; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -66,16 +66,12 @@ namespace Shadowsocks.Controller | |||||
public void AcceptCallback(IAsyncResult ar) | public void AcceptCallback(IAsyncResult ar) | ||||
{ | { | ||||
Socket listener = (Socket)ar.AsyncState; | |||||
try | try | ||||
{ | { | ||||
Socket listener = (Socket)ar.AsyncState; | |||||
Socket conn = listener.EndAccept(ar); | Socket conn = listener.EndAccept(ar); | ||||
conn.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | conn.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | ||||
listener.BeginAccept( | |||||
new AsyncCallback(AcceptCallback), | |||||
listener); | |||||
Handler handler = new Handler(); | Handler handler = new Handler(); | ||||
handler.connection = conn; | handler.connection = conn; | ||||
handler.encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); | handler.encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); | ||||
@@ -87,6 +83,19 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
//Console.WriteLine(e.Message); | //Console.WriteLine(e.Message); | ||||
} | } | ||||
finally | |||||
{ | |||||
try | |||||
{ | |||||
listener.BeginAccept( | |||||
new AsyncCallback(AcceptCallback), | |||||
listener); | |||||
} | |||||
catch | |||||
{ | |||||
//Console.WriteLine(e.Message); | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -47,6 +47,10 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
// received rst | // received rst | ||||
} | } | ||||
else if (se.SocketErrorCode == SocketError.NotConnected) | |||||
{ | |||||
// close when not connected | |||||
} | |||||
else | else | ||||
{ | { | ||||
Console.WriteLine(e); | Console.WriteLine(e); | ||||
@@ -58,8 +58,11 @@ namespace Shadowsocks.Controller | |||||
public void Stop() | public void Stop() | ||||
{ | { | ||||
_listener.Close(); | |||||
_listener = null; | |||||
if (_listener != null) | |||||
{ | |||||
_listener.Close(); | |||||
_listener = null; | |||||
} | |||||
} | } | ||||
public string TouchPACFile() | public string TouchPACFile() | ||||
@@ -75,24 +78,22 @@ namespace Shadowsocks.Controller | |||||
} | } | ||||
} | } | ||||
// we don't even use it | |||||
static byte[] requestBuf = new byte[2048]; | |||||
public void AcceptCallback(IAsyncResult ar) | public void AcceptCallback(IAsyncResult ar) | ||||
{ | { | ||||
Socket listener = (Socket)ar.AsyncState; | |||||
try | try | ||||
{ | { | ||||
Socket listener = (Socket)ar.AsyncState; | |||||
Socket conn = listener.EndAccept(ar); | Socket conn = listener.EndAccept(ar); | ||||
listener.BeginAccept( | |||||
new AsyncCallback(AcceptCallback), | |||||
listener); | |||||
byte[] buf = new byte[2048]; | |||||
object[] state = new object[] { | object[] state = new object[] { | ||||
conn, | conn, | ||||
buf | |||||
requestBuf | |||||
}; | }; | ||||
conn.BeginReceive(buf, 0, 1024, 0, | |||||
conn.BeginReceive(requestBuf, 0, requestBuf.Length, 0, | |||||
new AsyncCallback(ReceiveCallback), state); | new AsyncCallback(ReceiveCallback), state); | ||||
} | } | ||||
catch (ObjectDisposedException) | catch (ObjectDisposedException) | ||||
@@ -102,6 +103,23 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
Console.WriteLine(e); | Console.WriteLine(e); | ||||
} | } | ||||
finally | |||||
{ | |||||
try | |||||
{ | |||||
listener.BeginAccept( | |||||
new AsyncCallback(AcceptCallback), | |||||
listener); | |||||
} | |||||
catch (ObjectDisposedException) | |||||
{ | |||||
// do nothing | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Logging.LogUsefulException(e); | |||||
} | |||||
} | |||||
} | } | ||||
private string GetPACContent() | private string GetPACContent() | ||||
@@ -113,18 +131,17 @@ namespace Shadowsocks.Controller | |||||
else | else | ||||
{ | { | ||||
byte[] pacGZ = Resources.proxy_pac_txt; | byte[] pacGZ = Resources.proxy_pac_txt; | ||||
byte[] buffer = new byte[1024 * 1024]; // builtin pac gzip size: maximum 1M | |||||
byte[] buffer = new byte[1024]; // builtin pac gzip size: maximum 100K | |||||
MemoryStream sb = new MemoryStream(); | |||||
int n; | int n; | ||||
using (GZipStream input = new GZipStream(new MemoryStream(pacGZ), | using (GZipStream input = new GZipStream(new MemoryStream(pacGZ), | ||||
CompressionMode.Decompress, false)) | CompressionMode.Decompress, false)) | ||||
{ | { | ||||
n = input.Read(buffer, 0, buffer.Length); | |||||
if (n == 0) | |||||
while((n = input.Read(buffer, 0, buffer.Length)) > 0) | |||||
{ | { | ||||
throw new IOException("can not decompress pac"); | |||||
sb.Write(buffer, 0, n); | |||||
} | } | ||||
return System.Text.Encoding.UTF8.GetString(buffer, 0, n); | |||||
return System.Text.Encoding.UTF8.GetString(sb.ToArray()); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -158,6 +175,7 @@ Connection: Close | |||||
", System.Text.Encoding.UTF8.GetBytes(pac).Length) + pac; | ", System.Text.Encoding.UTF8.GetBytes(pac).Length) + pac; | ||||
byte[] response = System.Text.Encoding.UTF8.GetBytes(text); | byte[] response = System.Text.Encoding.UTF8.GetBytes(text); | ||||
conn.BeginSend(response, 0, response.Length, 0, new AsyncCallback(SendCallback), conn); | conn.BeginSend(response, 0, response.Length, 0, new AsyncCallback(SendCallback), conn); | ||||
Util.Util.ReleaseMemory(); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -4,6 +4,7 @@ using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Text; | using System.Text; | ||||
using System.Threading; | using System.Threading; | ||||
using System.Net.Sockets; | |||||
namespace Shadowsocks.Controller | namespace Shadowsocks.Controller | ||||
{ | { | ||||
@@ -31,38 +32,30 @@ namespace Shadowsocks.Controller | |||||
public event EventHandler ConfigChanged; | public event EventHandler ConfigChanged; | ||||
public event EventHandler EnableStatusChanged; | public event EventHandler EnableStatusChanged; | ||||
public event EventHandler EnableGlobalChanged; | |||||
public event EventHandler ShareOverLANStatusChanged; | public event EventHandler ShareOverLANStatusChanged; | ||||
// when user clicked Edit PAC, and PAC file has already created | // when user clicked Edit PAC, and PAC file has already created | ||||
public event EventHandler<PathEventArgs> PACFileReadyToOpen; | public event EventHandler<PathEventArgs> PACFileReadyToOpen; | ||||
public event ErrorEventHandler Errored; | |||||
public ShadowsocksController() | public ShadowsocksController() | ||||
{ | { | ||||
_config = Configuration.Load(); | _config = Configuration.Load(); | ||||
polipoRunner = new PolipoRunner(); | |||||
polipoRunner.Start(_config); | |||||
local = new Local(_config); | |||||
try | |||||
{ | |||||
local.Start(); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Console.WriteLine(e); | |||||
} | |||||
try | |||||
{ | |||||
pacServer = new PACServer(); | |||||
pacServer.PACFileChanged += pacServer_PACFileChanged; | |||||
pacServer.Start(_config); | |||||
} | |||||
catch (Exception e) | |||||
} | |||||
public void Start() | |||||
{ | |||||
Reload(); | |||||
} | |||||
protected void ReportError(Exception e) | |||||
{ | |||||
if (Errored != null) | |||||
{ | { | ||||
Console.WriteLine(e); | |||||
Errored(this, new ErrorEventArgs(e)); | |||||
} | } | ||||
UpdateSystemProxy(); | |||||
StartReleasingMemory(); | |||||
} | } | ||||
public Server GetCurrentServer() | public Server GetCurrentServer() | ||||
@@ -93,6 +86,17 @@ namespace Shadowsocks.Controller | |||||
} | } | ||||
} | } | ||||
public void ToggleGlobal(bool global) | |||||
{ | |||||
_config.global = global; | |||||
UpdateSystemProxy(); | |||||
SaveConfig(_config); | |||||
if (EnableGlobalChanged != null) | |||||
{ | |||||
EnableGlobalChanged(this, new EventArgs()); | |||||
} | |||||
} | |||||
public void ToggleShareOverLAN(bool enabled) | public void ToggleShareOverLAN(bool enabled) | ||||
{ | { | ||||
_config.shareOverLan = enabled; | _config.shareOverLan = enabled; | ||||
@@ -116,8 +120,14 @@ namespace Shadowsocks.Controller | |||||
return; | return; | ||||
} | } | ||||
stopped = true; | stopped = true; | ||||
local.Stop(); | |||||
polipoRunner.Stop(); | |||||
if (local != null) | |||||
{ | |||||
local.Stop(); | |||||
} | |||||
if (polipoRunner != null) | |||||
{ | |||||
polipoRunner.Stop(); | |||||
} | |||||
if (_config.enabled) | if (_config.enabled) | ||||
{ | { | ||||
SystemProxy.Disable(); | SystemProxy.Disable(); | ||||
@@ -141,41 +151,79 @@ namespace Shadowsocks.Controller | |||||
return "ss://" + base64; | return "ss://" + base64; | ||||
} | } | ||||
protected void SaveConfig(Configuration newConfig) | |||||
protected void Reload() | |||||
{ | { | ||||
Configuration.Save(newConfig); | |||||
// some logic in configuration updated the config when saving, we need to read it again | // some logic in configuration updated the config when saving, we need to read it again | ||||
_config = Configuration.Load(); | _config = Configuration.Load(); | ||||
if (polipoRunner == null) | |||||
{ | |||||
polipoRunner = new PolipoRunner(); | |||||
} | |||||
if (pacServer == null) | |||||
{ | |||||
pacServer = new PACServer(); | |||||
pacServer.PACFileChanged += pacServer_PACFileChanged; | |||||
} | |||||
pacServer.Stop(); | pacServer.Stop(); | ||||
local.Stop(); | |||||
if (local != null) | |||||
{ | |||||
local.Stop(); | |||||
} | |||||
// don't put polipoRunner.Start() before pacServer.Stop() | // don't put polipoRunner.Start() before pacServer.Stop() | ||||
// or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 | // or bind will fail when switching bind address from 0.0.0.0 to 127.0.0.1 | ||||
// though UseShellExecute is set to true now | // though UseShellExecute is set to true now | ||||
// http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open | // http://stackoverflow.com/questions/10235093/socket-doesnt-close-after-application-exits-if-a-launched-process-is-open | ||||
polipoRunner.Stop(); | polipoRunner.Stop(); | ||||
polipoRunner.Start(_config); | |||||
try | |||||
{ | |||||
polipoRunner.Start(_config); | |||||
local = new Local(_config); | |||||
local.Start(); | |||||
pacServer.Start(_config); | |||||
local = new Local(_config); | |||||
local.Start(); | |||||
pacServer.Start(_config); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
// translate Microsoft language into human language | |||||
// i.e. An attempt was made to access a socket in a way forbidden by its access permissions => Port already in use | |||||
if (e is SocketException) | |||||
{ | |||||
SocketException se = (SocketException)e; | |||||
if (se.SocketErrorCode == SocketError.AccessDenied) | |||||
{ | |||||
e = new Exception(I18N.GetString("Port already in use"), e); | |||||
} | |||||
} | |||||
Logging.LogUsefulException(e); | |||||
ReportError(e); | |||||
} | |||||
if (ConfigChanged != null) | if (ConfigChanged != null) | ||||
{ | { | ||||
ConfigChanged(this, new EventArgs()); | ConfigChanged(this, new EventArgs()); | ||||
} | } | ||||
UpdateSystemProxy(); | |||||
Util.Util.ReleaseMemory(); | Util.Util.ReleaseMemory(); | ||||
} | } | ||||
protected void SaveConfig(Configuration newConfig) | |||||
{ | |||||
Configuration.Save(newConfig); | |||||
Reload(); | |||||
} | |||||
private void UpdateSystemProxy() | private void UpdateSystemProxy() | ||||
{ | { | ||||
if (_config.enabled) | if (_config.enabled) | ||||
{ | { | ||||
SystemProxy.Enable(); | |||||
SystemProxy.Enable(_config.global); | |||||
_systemProxyIsDirty = true; | _systemProxyIsDirty = true; | ||||
} | } | ||||
else | else | ||||
@@ -24,16 +24,25 @@ namespace Shadowsocks.Controller | |||||
_refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0); | _refreshReturn = InternetSetOption(IntPtr.Zero, INTERNET_OPTION_REFRESH, IntPtr.Zero, 0); | ||||
} | } | ||||
public static void Enable() | |||||
public static void Enable(bool global) | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
RegistryKey registry = | RegistryKey registry = | ||||
Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", | Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", | ||||
true); | true); | ||||
registry.SetValue("ProxyEnable", 0); | |||||
registry.SetValue("ProxyServer", ""); | |||||
registry.SetValue("AutoConfigURL", "http://127.0.0.1:8093/pac?t=" + GetTimestamp(DateTime.Now)); | |||||
if (global) | |||||
{ | |||||
registry.SetValue("ProxyEnable", 1); | |||||
registry.SetValue("ProxyServer", "127.0.0.1:8123"); | |||||
registry.SetValue("AutoConfigURL", ""); | |||||
} | |||||
else | |||||
{ | |||||
registry.SetValue("ProxyEnable", 0); | |||||
registry.SetValue("ProxyServer", ""); | |||||
registry.SetValue("AutoConfigURL", "http://127.0.0.1:8093/pac?t=" + GetTimestamp(DateTime.Now)); | |||||
} | |||||
SystemProxy.NotifyIE(); | SystemProxy.NotifyIE(); | ||||
//Must Notify IE first, or the connections do not chanage | //Must Notify IE first, or the connections do not chanage | ||||
CopyProxySettingFromLan(); | CopyProxySettingFromLan(); | ||||
@@ -17,6 +17,8 @@ namespace Shadowsocks.Controller | |||||
public string LatestVersionURL; | public string LatestVersionURL; | ||||
public event EventHandler NewVersionFound; | public event EventHandler NewVersionFound; | ||||
public const string Version = "2.1.4"; | |||||
public void CheckUpdate() | public void CheckUpdate() | ||||
{ | { | ||||
// TODO test failures | // TODO test failures | ||||
@@ -100,7 +102,7 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
return false; | return false; | ||||
} | } | ||||
string currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); | |||||
string currentVersion = Version; | |||||
return CompareVersion(version, currentVersion) > 0; | return CompareVersion(version, currentVersion) > 0; | ||||
} | } | ||||
@@ -0,0 +1,41 @@ | |||||
Shadowsocks=Shadowsocks | |||||
Enable=启用代理 | |||||
Mode=代理模式 | |||||
PAC=PAC 模式 | |||||
Global=全局模式 | |||||
Servers=服务器选择 | |||||
Edit Servers...=编辑服务器... | |||||
Start on Boot=自动启动 | |||||
Share over LAN=在局域网共享代理 | |||||
Edit PAC File...=编辑 PAC 文件... | |||||
Show QRCode...=显示二维码... | |||||
Show Logs...=显示日志... | |||||
About...=关于... | |||||
Quit=退出 | |||||
Edit Servers=编辑服务器 | |||||
&Add=添加(&A) | |||||
&Delete=删除(&D) | |||||
Server=服务器 | |||||
Server IP=服务器 IP | |||||
Server Port=服务器端口 | |||||
Password=密码 | |||||
Encryption=加密 | |||||
Proxy Port=代理端口 | |||||
Remarks=备注 | |||||
OK=确定 | |||||
Cancel=取消 | |||||
New server=未配置的服务器 | |||||
QRCode=二维码 | |||||
Shadowsocks Error: {0}=Shadowsocks 错误: {0} | |||||
Port already in use=端口已被占用 | |||||
Illegal port number format=非法端口格式 | |||||
Please add at least one server=请添加至少一个服务器 | |||||
Server IP can not be blank=服务器 IP 不能为空 | |||||
Password can not be blank=密码不能为空 | |||||
Port out of range=端口超出范围 | |||||
Shadowsocks {0} Update Found=Shadowsocks {0} 更新 | |||||
Click here to download=点击这里下载 | |||||
Shadowsocks is here=Shadowsocks 在这里 | |||||
You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks | |||||
Enabled=已启用代理 | |||||
Disabled=已禁用代理 |
@@ -6,6 +6,8 @@ namespace Shadowsocks.Encrypt | |||||
public abstract class EncryptorBase | public abstract class EncryptorBase | ||||
: IEncryptor | : IEncryptor | ||||
{ | { | ||||
public const int MAX_INPUT_SIZE = 32768; | |||||
protected EncryptorBase(string method, string password) | protected EncryptorBase(string method, string password) | ||||
{ | { | ||||
Method = method; | Method = method; | ||||
@@ -1,16 +1,43 @@ | |||||
| | ||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Reflection; | |||||
namespace Shadowsocks.Encrypt | namespace Shadowsocks.Encrypt | ||||
{ | { | ||||
public static class EncryptorFactory | public static class EncryptorFactory | ||||
{ | { | ||||
public static IEncryptor GetEncryptor(string method, string password) | |||||
private static Dictionary<string, Type> _registeredEncryptors; | |||||
private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string) }; | |||||
static EncryptorFactory() | |||||
{ | { | ||||
if (string.IsNullOrEmpty(method) || method.ToLowerInvariant() == "table") | |||||
_registeredEncryptors = new Dictionary<string, Type>(); | |||||
foreach (string method in TableEncryptor.SupportedCiphers()) | |||||
{ | |||||
_registeredEncryptors.Add(method, typeof(TableEncryptor)); | |||||
} | |||||
foreach (string method in PolarSSLEncryptor.SupportedCiphers()) | |||||
{ | |||||
_registeredEncryptors.Add(method, typeof(PolarSSLEncryptor)); | |||||
} | |||||
foreach (string method in SodiumEncryptor.SupportedCiphers()) | |||||
{ | { | ||||
return new TableEncryptor(method, password); | |||||
_registeredEncryptors.Add(method, typeof(SodiumEncryptor)); | |||||
} | } | ||||
} | |||||
return new PolarSSLEncryptor(method, password); | |||||
public static IEncryptor GetEncryptor(string method, string password) | |||||
{ | |||||
if (string.IsNullOrEmpty(method)) | |||||
{ | |||||
method = "table"; | |||||
} | |||||
method = method.ToLowerInvariant(); | |||||
Type t = _registeredEncryptors[method]; | |||||
ConstructorInfo c = t.GetConstructor(_constructorTypes); | |||||
IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password }); | |||||
return result; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -0,0 +1,158 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Security.Cryptography; | |||||
using System.Text; | |||||
namespace Shadowsocks.Encrypt | |||||
{ | |||||
public abstract class IVEncryptor | |||||
: EncryptorBase | |||||
{ | |||||
protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE]; | |||||
protected Dictionary<string, int[]> ciphers; | |||||
private static readonly Dictionary<string, byte[]> CachedKeys = new Dictionary<string, byte[]>(); | |||||
protected byte[] _encryptIV; | |||||
protected byte[] _decryptIV; | |||||
protected bool _decryptIVReceived; | |||||
protected bool _encryptIVSent; | |||||
protected int _encryptIVOffset = 0; | |||||
protected int _decryptIVOffset = 0; | |||||
protected string _method; | |||||
protected int _cipher; | |||||
protected int[] _cipherInfo; | |||||
protected byte[] _key; | |||||
protected int keyLen; | |||||
protected int ivLen; | |||||
public IVEncryptor(string method, string password) | |||||
: base(method, password) | |||||
{ | |||||
InitKey(method, password); | |||||
} | |||||
protected abstract Dictionary<string, int[]> getCiphers(); | |||||
protected void InitKey(string method, string password) | |||||
{ | |||||
method = method.ToLower(); | |||||
_method = method; | |||||
string k = method + ":" + password; | |||||
ciphers = getCiphers(); | |||||
_cipherInfo = ciphers[_method]; | |||||
_cipher = _cipherInfo[2]; | |||||
if (_cipher == 0) | |||||
{ | |||||
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]; | |||||
bytesToKey(passbuf, _key); | |||||
CachedKeys[k] = _key; | |||||
} | |||||
} | |||||
protected void bytesToKey(byte[] password, byte[] key) | |||||
{ | |||||
byte[] result = new byte[password.Length + 16]; | |||||
int i = 0; | |||||
byte[] md5sum = null; | |||||
while (i < key.Length) | |||||
{ | |||||
MD5 md5 = MD5.Create(); | |||||
if (i == 0) | |||||
{ | |||||
md5sum = md5.ComputeHash(password); | |||||
} | |||||
else | |||||
{ | |||||
md5sum.CopyTo(result, 0); | |||||
password.CopyTo(result, md5sum.Length); | |||||
md5sum = md5.ComputeHash(result); | |||||
} | |||||
md5sum.CopyTo(key, i); | |||||
i += md5sum.Length; | |||||
} | |||||
} | |||||
protected static void randBytes(byte[] buf, int length) | |||||
{ | |||||
byte[] temp = new byte[length]; | |||||
new Random().NextBytes(temp); | |||||
temp.CopyTo(buf, 0); | |||||
} | |||||
protected virtual void initCipher(byte[] iv, bool isCipher) | |||||
{ | |||||
if (ivLen > 0) | |||||
{ | |||||
if (isCipher) | |||||
{ | |||||
_encryptIV = new byte[ivLen]; | |||||
Array.Copy(iv, _encryptIV, ivLen); | |||||
} | |||||
else | |||||
{ | |||||
_decryptIV = new byte[ivLen]; | |||||
Array.Copy(iv, _decryptIV, ivLen); | |||||
} | |||||
} | |||||
} | |||||
protected abstract void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf); | |||||
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) | |||||
{ | |||||
if (!_encryptIVSent) | |||||
{ | |||||
_encryptIVSent = true; | |||||
randBytes(outbuf, ivLen); | |||||
initCipher(outbuf, true); | |||||
outlength = length + ivLen; | |||||
lock (tempbuf) | |||||
{ | |||||
cipherUpdate(true, length, buf, tempbuf); | |||||
outlength = length + ivLen; | |||||
Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
outlength = length; | |||||
cipherUpdate(true, length, buf, outbuf); | |||||
} | |||||
} | |||||
public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) | |||||
{ | |||||
if (!_decryptIVReceived) | |||||
{ | |||||
_decryptIVReceived = true; | |||||
initCipher(buf, false); | |||||
outlength = length - ivLen; | |||||
lock (tempbuf) | |||||
{ | |||||
// C# could be multi-threaded | |||||
Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen); | |||||
cipherUpdate(false, length - ivLen, tempbuf, outbuf); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
outlength = length; | |||||
cipherUpdate(false, length, buf, outbuf); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -10,7 +10,7 @@ namespace Shadowsocks.Encrypt | |||||
{ | { | ||||
public class PolarSSL | public class PolarSSL | ||||
{ | { | ||||
const string DLLNAME = "polarssl"; | |||||
const string DLLNAME = "libsscrypto"; | |||||
public const int AES_CTX_SIZE = 8 + 4 * 68; | public const int AES_CTX_SIZE = 8 + 4 * 68; | ||||
public const int AES_ENCRYPT = 1; | public const int AES_ENCRYPT = 1; | ||||
@@ -19,12 +19,15 @@ namespace Shadowsocks.Encrypt | |||||
static PolarSSL() | static PolarSSL() | ||||
{ | { | ||||
string tempPath = Path.GetTempPath(); | string tempPath = Path.GetTempPath(); | ||||
string dllPath = tempPath + "/polarssl.dll"; | |||||
string dllPath = tempPath + "/libsscrypto.dll"; | |||||
try | try | ||||
{ | { | ||||
FileManager.UncompressFile(dllPath, Resources.polarssl_dll); | |||||
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll); | |||||
} | } | ||||
catch (IOException e) | |||||
catch (IOException) | |||||
{ | |||||
} | |||||
catch (Exception e) | |||||
{ | { | ||||
Console.WriteLine(e.ToString()); | Console.WriteLine(e.ToString()); | ||||
} | } | ||||
@@ -8,32 +8,13 @@ using System.Threading; | |||||
namespace Shadowsocks.Encrypt | namespace Shadowsocks.Encrypt | ||||
{ | { | ||||
public class PolarSSLEncryptor | public class PolarSSLEncryptor | ||||
: EncryptorBase, IDisposable | |||||
: IVEncryptor, IDisposable | |||||
{ | { | ||||
const int CIPHER_AES = 1; | const int CIPHER_AES = 1; | ||||
const int CIPHER_RC4 = 2; | const int CIPHER_RC4 = 2; | ||||
static Dictionary<string, int[]> ciphers = new Dictionary<string, int[]> { | |||||
{"aes-128-cfb", new int[]{16, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, | |||||
{"aes-192-cfb", new int[]{24, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, | |||||
{"aes-256-cfb", new int[]{32, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, | |||||
{"rc4", new int[]{16, 0, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, | |||||
{"rc4-md5", new int[]{16, 16, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, | |||||
}; | |||||
private static readonly Dictionary<string, byte[]> CachedKeys = new Dictionary<string, byte[]>(); | |||||
private int _cipher; | |||||
private int[] _cipherInfo; | |||||
private byte[] _key; | |||||
private IntPtr _encryptCtx = IntPtr.Zero; | private IntPtr _encryptCtx = IntPtr.Zero; | ||||
private IntPtr _decryptCtx = IntPtr.Zero; | private IntPtr _decryptCtx = IntPtr.Zero; | ||||
private byte[] _encryptIV; | |||||
private byte[] _decryptIV; | |||||
private int _encryptIVOffset = 0; | |||||
private int _decryptIVOffset = 0; | |||||
private string _method; | |||||
private int keyLen; | |||||
private int ivLen; | |||||
public PolarSSLEncryptor(string method, string password) | public PolarSSLEncryptor(string method, string password) | ||||
: base(method, password) | : base(method, password) | ||||
@@ -41,66 +22,38 @@ namespace Shadowsocks.Encrypt | |||||
InitKey(method, password); | InitKey(method, password); | ||||
} | } | ||||
private static void randBytes(byte[] buf, int length) | |||||
private static Dictionary<string, int[]> _ciphers = new Dictionary<string, int[]> { | |||||
{"aes-128-cfb", new int[]{16, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, | |||||
{"aes-192-cfb", new int[]{24, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, | |||||
{"aes-256-cfb", new int[]{32, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, | |||||
{"rc4", new int[]{16, 0, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, | |||||
{"rc4-md5", new int[]{16, 16, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, | |||||
}; | |||||
public static List<string> SupportedCiphers() | |||||
{ | { | ||||
byte[] temp = new byte[length]; | |||||
new Random().NextBytes(temp); | |||||
temp.CopyTo(buf, 0); | |||||
return new List<string>(_ciphers.Keys); | |||||
} | } | ||||
private void bytesToKey(byte[] password, byte[] key) | |||||
protected override Dictionary<string, int[]> getCiphers() | |||||
{ | { | ||||
byte[] result = new byte[password.Length + 16]; | |||||
int i = 0; | |||||
byte[] md5sum = null; | |||||
while (i < key.Length) | |||||
{ | |||||
MD5 md5 = MD5.Create(); | |||||
if (i == 0) | |||||
{ | |||||
md5sum = md5.ComputeHash(password); | |||||
} | |||||
else | |||||
{ | |||||
md5sum.CopyTo(result, 0); | |||||
password.CopyTo(result, md5sum.Length); | |||||
md5sum = md5.ComputeHash(result); | |||||
} | |||||
md5sum.CopyTo(key, i); | |||||
i += md5sum.Length; | |||||
} | |||||
return _ciphers; | |||||
} | } | ||||
private void InitKey(string method, string password) | |||||
protected override void initCipher(byte[] iv, bool isCipher) | |||||
{ | { | ||||
method = method.ToLower(); | |||||
_method = method; | |||||
string k = method + ":" + password; | |||||
_cipherInfo = ciphers[_method]; | |||||
_cipher = _cipherInfo[2]; | |||||
if (_cipher == 0) | |||||
{ | |||||
throw new Exception("method not found"); | |||||
} | |||||
keyLen = ciphers[_method][0]; | |||||
ivLen = ciphers[_method][1]; | |||||
if (CachedKeys.ContainsKey(k)) | |||||
base.initCipher(iv, isCipher); | |||||
IntPtr ctx; | |||||
ctx = Marshal.AllocHGlobal(_cipherInfo[3]); | |||||
if (isCipher) | |||||
{ | { | ||||
_key = CachedKeys[k]; | |||||
_encryptCtx = ctx; | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
byte[] passbuf = Encoding.UTF8.GetBytes(password); | |||||
_key = new byte[32]; | |||||
byte[] iv = new byte[16]; | |||||
bytesToKey(passbuf, _key); | |||||
CachedKeys[k] = _key; | |||||
_decryptCtx = ctx; | |||||
} | } | ||||
} | |||||
private void InitCipher(ref IntPtr ctx, byte[] iv, bool isCipher) | |||||
{ | |||||
ctx = Marshal.AllocHGlobal(_cipherInfo[3]); | |||||
byte[] realkey; | byte[] realkey; | ||||
if (_method == "rc4-md5") | if (_method == "rc4-md5") | ||||
{ | { | ||||
@@ -120,16 +73,6 @@ namespace Shadowsocks.Encrypt | |||||
// PolarSSL takes key length by bit | // PolarSSL takes key length by bit | ||||
// since we'll use CFB mode, here we both do enc, not dec | // since we'll use CFB mode, here we both do enc, not dec | ||||
PolarSSL.aes_setkey_enc(ctx, realkey, keyLen * 8); | 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); | |||||
} | |||||
} | } | ||||
else if (_cipher == CIPHER_RC4) | else if (_cipher == CIPHER_RC4) | ||||
{ | { | ||||
@@ -139,98 +82,44 @@ namespace Shadowsocks.Encrypt | |||||
} | } | ||||
} | } | ||||
static byte[] tempbuf = new byte[32768]; | |||||
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) | |||||
protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf) | |||||
{ | { | ||||
if (_encryptCtx == IntPtr.Zero) | |||||
// C# could be multi-threaded | |||||
if (_disposed) | |||||
{ | { | ||||
randBytes(outbuf, ivLen); | |||||
InitCipher(ref _encryptCtx, outbuf, true); | |||||
outlength = length + ivLen; | |||||
lock (tempbuf) | |||||
{ | |||||
// C# could be multi-threaded | |||||
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_RC4: | |||||
PolarSSL.arc4_crypt(_encryptCtx, length, buf, tempbuf); | |||||
break; | |||||
} | |||||
outlength = length + ivLen; | |||||
Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length); | |||||
} | |||||
throw new ObjectDisposedException(this.ToString()); | |||||
} | |||||
byte[] iv; | |||||
int ivOffset; | |||||
IntPtr ctx; | |||||
if (isCipher) | |||||
{ | |||||
iv = _encryptIV; | |||||
ivOffset = _encryptIVOffset; | |||||
ctx = _encryptCtx; | |||||
} | } | ||||
else | 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_RC4: | |||||
PolarSSL.arc4_crypt(_encryptCtx, length, buf, outbuf); | |||||
break; | |||||
} | |||||
iv = _decryptIV; | |||||
ivOffset = _decryptIVOffset; | |||||
ctx = _decryptCtx; | |||||
} | } | ||||
} | |||||
public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) | |||||
{ | |||||
if (_decryptCtx == IntPtr.Zero) | |||||
switch (_cipher) | |||||
{ | { | ||||
InitCipher(ref _decryptCtx, buf, false); | |||||
outlength = length - ivLen; | |||||
lock (tempbuf) | |||||
{ | |||||
// C# could be multi-threaded | |||||
Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen); | |||||
if (_disposed) | |||||
case CIPHER_AES: | |||||
PolarSSL.aes_crypt_cfb128(ctx, isCipher ? PolarSSL.AES_ENCRYPT : PolarSSL.AES_DECRYPT, length, ref ivOffset, iv, buf, outbuf); | |||||
if (isCipher) | |||||
{ | { | ||||
throw new ObjectDisposedException(this.ToString()); | |||||
_encryptIVOffset = ivOffset; | |||||
} | } | ||||
switch (_cipher) | |||||
else | |||||
{ | { | ||||
case CIPHER_AES: | |||||
PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length - ivLen, ref _decryptIVOffset, _decryptIV, tempbuf, outbuf); | |||||
break; | |||||
case CIPHER_RC4: | |||||
PolarSSL.arc4_crypt(_decryptCtx, length - ivLen, tempbuf, outbuf); | |||||
break; | |||||
_decryptIVOffset = ivOffset; | |||||
} | } | ||||
} | |||||
} | |||||
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_RC4: | |||||
PolarSSL.arc4_crypt(_decryptCtx, length, buf, outbuf); | |||||
break; | |||||
} | |||||
break; | |||||
case CIPHER_RC4: | |||||
PolarSSL.arc4_crypt(ctx, length, buf, outbuf); | |||||
break; | |||||
} | } | ||||
} | } | ||||
@@ -0,0 +1,43 @@ | |||||
using Shadowsocks.Controller; | |||||
using Shadowsocks.Properties; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Runtime.InteropServices; | |||||
using System.Text; | |||||
namespace Shadowsocks.Encrypt | |||||
{ | |||||
public class Sodium | |||||
{ | |||||
const string DLLNAME = "libsscrypto"; | |||||
static Sodium() | |||||
{ | |||||
string tempPath = Path.GetTempPath(); | |||||
string dllPath = tempPath + "/libsscrypto.dll"; | |||||
try | |||||
{ | |||||
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll); | |||||
LoadLibrary(dllPath); | |||||
} | |||||
catch (IOException) | |||||
{ | |||||
} | |||||
catch (Exception 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 crypto_stream_salsa20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); | |||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)] | |||||
public extern static void crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k); | |||||
} | |||||
} |
@@ -0,0 +1,99 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace Shadowsocks.Encrypt | |||||
{ | |||||
public class SodiumEncryptor | |||||
: IVEncryptor, IDisposable | |||||
{ | |||||
const int CIPHER_SALSA20 = 1; | |||||
const int CIPHER_CHACHA20 = 2; | |||||
const int SODIUM_BLOCK_SIZE = 64; | |||||
protected int _encryptBytesRemaining; | |||||
protected int _decryptBytesRemaining; | |||||
protected ulong _encryptIC; | |||||
protected ulong _decryptIC; | |||||
protected byte[] _encryptBuf; | |||||
protected byte[] _decryptBuf; | |||||
public SodiumEncryptor(string method, string password) | |||||
: base(method, password) | |||||
{ | |||||
InitKey(method, password); | |||||
_encryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE]; | |||||
_decryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE]; | |||||
} | |||||
private static Dictionary<string, int[]> _ciphers = new Dictionary<string, int[]> { | |||||
{"salsa20", new int[]{32, 8, CIPHER_SALSA20, PolarSSL.AES_CTX_SIZE}}, | |||||
{"chacha20", new int[]{32, 8, CIPHER_CHACHA20, PolarSSL.AES_CTX_SIZE}}, | |||||
}; | |||||
protected override Dictionary<string, int[]> getCiphers() | |||||
{ | |||||
return _ciphers; | |||||
} | |||||
public static List<string> SupportedCiphers() | |||||
{ | |||||
return new List<string>(_ciphers.Keys); | |||||
} | |||||
protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf) | |||||
{ | |||||
// TODO write a unidirection cipher so we don't have to if if if | |||||
int bytesRemaining; | |||||
ulong ic; | |||||
byte[] sodiumBuf; | |||||
byte[] iv; | |||||
if (isCipher) | |||||
{ | |||||
bytesRemaining = _encryptBytesRemaining; | |||||
ic = _encryptIC; | |||||
sodiumBuf = _encryptBuf; | |||||
iv = _encryptIV; | |||||
} | |||||
else | |||||
{ | |||||
bytesRemaining = _decryptBytesRemaining; | |||||
ic = _decryptIC; | |||||
sodiumBuf = _decryptBuf; | |||||
iv = _decryptIV; | |||||
} | |||||
int padding = bytesRemaining; | |||||
Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length); | |||||
switch (_cipher) | |||||
{ | |||||
case CIPHER_SALSA20: | |||||
Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key); | |||||
break; | |||||
case CIPHER_CHACHA20: | |||||
Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key); | |||||
break; | |||||
} | |||||
Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length); | |||||
padding += length; | |||||
ic += (ulong)padding / SODIUM_BLOCK_SIZE; | |||||
bytesRemaining = padding % SODIUM_BLOCK_SIZE; | |||||
if (isCipher) | |||||
{ | |||||
_encryptBytesRemaining = bytesRemaining; | |||||
_encryptIC = ic; | |||||
} | |||||
else | |||||
{ | |||||
_decryptBytesRemaining = bytesRemaining; | |||||
_decryptIC = ic; | |||||
} | |||||
} | |||||
public override void Dispose() | |||||
{ | |||||
} | |||||
} | |||||
} |
@@ -1,4 +1,5 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
namespace Shadowsocks.Encrypt | namespace Shadowsocks.Encrypt | ||||
{ | { | ||||
@@ -25,6 +26,11 @@ namespace Shadowsocks.Encrypt | |||||
} | } | ||||
} | } | ||||
public static List<string> SupportedCiphers() | |||||
{ | |||||
return new List<string>(new string[]{"table"}); | |||||
} | |||||
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) | public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) | ||||
{ | { | ||||
byte[] result = new byte[length]; | byte[] result = new byte[length]; | ||||
@@ -1,4 +1,5 @@ | |||||
using System; | |||||
using Shadowsocks.Controller; | |||||
using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.IO; | using System.IO; | ||||
using System.Text; | using System.Text; | ||||
@@ -11,6 +12,7 @@ namespace Shadowsocks.Model | |||||
{ | { | ||||
public List<Server> configs; | public List<Server> configs; | ||||
public int index; | public int index; | ||||
public bool global; | |||||
public bool enabled; | public bool enabled; | ||||
public bool shareOverLan; | public bool shareOverLan; | ||||
public bool isDefault; | public bool isDefault; | ||||
@@ -35,7 +37,6 @@ namespace Shadowsocks.Model | |||||
CheckPort(server.server_port); | CheckPort(server.server_port); | ||||
CheckPassword(server.password); | CheckPassword(server.password); | ||||
CheckServer(server.server); | CheckServer(server.server); | ||||
CheckRemark(server.remarks); | |||||
} | } | ||||
public static Configuration Load() | public static Configuration Load() | ||||
@@ -108,7 +109,7 @@ namespace Shadowsocks.Model | |||||
{ | { | ||||
if (!condition) | if (!condition) | ||||
{ | { | ||||
throw new Exception("assertion failure"); | |||||
throw new Exception(I18N.GetString("assertion failure")); | |||||
} | } | ||||
} | } | ||||
@@ -116,7 +117,7 @@ namespace Shadowsocks.Model | |||||
{ | { | ||||
if (port <= 0 || port > 65535) | if (port <= 0 || port > 65535) | ||||
{ | { | ||||
throw new ArgumentException("port out of range"); | |||||
throw new ArgumentException(I18N.GetString("Port out of range")); | |||||
} | } | ||||
} | } | ||||
@@ -124,7 +125,7 @@ namespace Shadowsocks.Model | |||||
{ | { | ||||
if (string.IsNullOrEmpty(password)) | if (string.IsNullOrEmpty(password)) | ||||
{ | { | ||||
throw new ArgumentException("password can not be blank"); | |||||
throw new ArgumentException(I18N.GetString("Password can not be blank")); | |||||
} | } | ||||
} | } | ||||
@@ -132,15 +133,10 @@ namespace Shadowsocks.Model | |||||
{ | { | ||||
if (string.IsNullOrEmpty(server)) | if (string.IsNullOrEmpty(server)) | ||||
{ | { | ||||
throw new ArgumentException("server IP can not be blank"); | |||||
throw new ArgumentException(I18N.GetString("Server IP can not be blank")); | |||||
} | } | ||||
} | } | ||||
private static void CheckRemark(string remark) | |||||
{ | |||||
//remark is optional | |||||
} | |||||
private class JsonSerializerStrategy : SimpleJson.PocoJsonSerializerStrategy | private class JsonSerializerStrategy : SimpleJson.PocoJsonSerializerStrategy | ||||
{ | { | ||||
// convert string to int | // convert string to int | ||||
@@ -4,6 +4,7 @@ using System.Text; | |||||
using System.IO; | using System.IO; | ||||
using System.Diagnostics; | using System.Diagnostics; | ||||
using SimpleJson; | using SimpleJson; | ||||
using Shadowsocks.Controller; | |||||
namespace Shadowsocks.Model | namespace Shadowsocks.Model | ||||
{ | { | ||||
@@ -16,5 +17,21 @@ namespace Shadowsocks.Model | |||||
public string password; | public string password; | ||||
public string method; | public string method; | ||||
public string remarks; | public string remarks; | ||||
public string FriendlyName() | |||||
{ | |||||
if (string.IsNullOrEmpty(server)) | |||||
{ | |||||
return I18N.GetString("New server"); | |||||
} | |||||
if (string.IsNullOrEmpty(remarks)) | |||||
{ | |||||
return server + ":" + server_port; | |||||
} | |||||
else | |||||
{ | |||||
return remarks + " (" + server + ":" + server_port + ")"; | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
@@ -41,7 +41,9 @@ namespace Shadowsocks | |||||
ShadowsocksController controller = new ShadowsocksController(); | ShadowsocksController controller = new ShadowsocksController(); | ||||
MenuViewController viewController = new MenuViewController(controller); | MenuViewController viewController = new MenuViewController(controller); | ||||
Util.Util.ReleaseMemory(); | |||||
controller.Start(); | |||||
Application.Run(); | Application.Run(); | ||||
} | } | ||||
} | } | ||||
@@ -1,4 +1,5 @@ | |||||
using System.Reflection; | |||||
using Shadowsocks.Controller; | |||||
using System.Reflection; | |||||
using System.Runtime.CompilerServices; | using System.Runtime.CompilerServices; | ||||
using System.Runtime.InteropServices; | using System.Runtime.InteropServices; | ||||
@@ -32,5 +33,5 @@ using System.Runtime.InteropServices; | |||||
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, | ||||
// 方法是按如下所示使用“*”: | // 方法是按如下所示使用“*”: | ||||
// [assembly: AssemblyVersion("1.0.*")] | // [assembly: AssemblyVersion("1.0.*")] | ||||
[assembly: AssemblyVersion("2.0.11")] | |||||
[assembly: AssemblyVersion(UpdateChecker.Version)] | |||||
// [assembly: AssemblyFileVersion("2.0.0")] | // [assembly: AssemblyFileVersion("2.0.0")] |
@@ -61,11 +61,50 @@ namespace Shadowsocks.Properties { | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized string similar to Shadowsocks=Shadowsocks | |||||
///Enable=启用代理 | |||||
///Mode=代理模式 | |||||
///PAC=PAC 模式 | |||||
///Global=全局模式 | |||||
///Servers=服务器选择 | |||||
///Edit Servers...=编辑服务器... | |||||
///Start on Boot=自动启动 | |||||
///Share over LAN=在局域网共享代理 | |||||
///Edit PAC File...=编辑 PAC 文件... | |||||
///Show QRCode...=显示二维码... | |||||
///Show Logs...=显示日志... | |||||
///About...=关于... | |||||
///Quit=退出 | |||||
///Edit Servers=编辑服务器 | |||||
///&Add=添加(&A) | |||||
///&Delete=删除(&D) | |||||
///Server=服务器 | |||||
///Server IP=服务器 IP | |||||
///Server Port=服务器端口 | |||||
///Password=密码 | |||||
///Encryption=加密 | |||||
///Proxy Port=代理端口 | |||||
///Remarks=备注 | |||||
///OK=确定 | |||||
///Cancel=取消 | |||||
///New server=未配置的服务器 | |||||
///QRCode=二维码 | |||||
///Shadowsocks Error: {0}=Shadowsocks 错误: {0} | |||||
///Port already in use=端口已被占用 | |||||
///Il [rest of string was truncated]";. | |||||
/// </summary> | |||||
internal static string cn { | |||||
get { | |||||
return ResourceManager.GetString("cn", resourceCulture); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Looks up a localized resource of type System.Byte[]. | /// Looks up a localized resource of type System.Byte[]. | ||||
/// </summary> | /// </summary> | ||||
internal static byte[] polarssl_dll { | |||||
internal static byte[] libsscrypto_dll { | |||||
get { | get { | ||||
object obj = ResourceManager.GetObject("polarssl_dll", resourceCulture); | |||||
object obj = ResourceManager.GetObject("libsscrypto_dll", resourceCulture); | |||||
return ((byte[])(obj)); | return ((byte[])(obj)); | ||||
} | } | ||||
} | } | ||||
@@ -118,8 +118,11 @@ | |||||
<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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | ||||
</resheader> | </resheader> | ||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> | <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> | ||||
<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 name="cn" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||||
<value>..\data\cn.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value> | |||||
</data> | |||||
<data name="libsscrypto_dll" type="System.Resources.ResXFileRef, System.Windows.Forms"> | |||||
<value>..\data\libsscrypto.dll.gz;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</data> | </data> | ||||
<data name="polipo_config" type="System.Resources.ResXFileRef, System.Windows.Forms"> | <data name="polipo_config" type="System.Resources.ResXFileRef, System.Windows.Forms"> | ||||
<value>..\Data\polipo_config.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;gb2312</value> | <value>..\Data\polipo_config.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;gb2312</value> | ||||
@@ -30,30 +30,32 @@ | |||||
{ | { | ||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); | this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); | ||||
this.RemarksTextBox = new System.Windows.Forms.TextBox(); | this.RemarksTextBox = new System.Windows.Forms.TextBox(); | ||||
this.label6 = new System.Windows.Forms.Label(); | |||||
this.label1 = new System.Windows.Forms.Label(); | |||||
this.label2 = new System.Windows.Forms.Label(); | |||||
this.RemarksLabel = new System.Windows.Forms.Label(); | |||||
this.IPLabel = new System.Windows.Forms.Label(); | |||||
this.ServerPortLabel = new System.Windows.Forms.Label(); | |||||
this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); | this.ProxyPortTextBox = new System.Windows.Forms.TextBox(); | ||||
this.label4 = new System.Windows.Forms.Label(); | |||||
this.label3 = new System.Windows.Forms.Label(); | |||||
this.ProxyPortLabel = new System.Windows.Forms.Label(); | |||||
this.PasswordLabel = new System.Windows.Forms.Label(); | |||||
this.IPTextBox = new System.Windows.Forms.TextBox(); | this.IPTextBox = new System.Windows.Forms.TextBox(); | ||||
this.ServerPortTextBox = new System.Windows.Forms.TextBox(); | this.ServerPortTextBox = new System.Windows.Forms.TextBox(); | ||||
this.PasswordTextBox = new System.Windows.Forms.TextBox(); | this.PasswordTextBox = new System.Windows.Forms.TextBox(); | ||||
this.label5 = new System.Windows.Forms.Label(); | |||||
this.EncryptionLabel = new System.Windows.Forms.Label(); | |||||
this.EncryptionSelect = new System.Windows.Forms.ComboBox(); | this.EncryptionSelect = new System.Windows.Forms.ComboBox(); | ||||
this.panel2 = new System.Windows.Forms.Panel(); | this.panel2 = new System.Windows.Forms.Panel(); | ||||
this.OKButton = new System.Windows.Forms.Button(); | this.OKButton = new System.Windows.Forms.Button(); | ||||
this.MyCancelButton = new System.Windows.Forms.Button(); | this.MyCancelButton = new System.Windows.Forms.Button(); | ||||
this.panel1 = new System.Windows.Forms.Panel(); | |||||
this.panel3 = new System.Windows.Forms.Panel(); | |||||
this.DeleteButton = new System.Windows.Forms.Button(); | this.DeleteButton = new System.Windows.Forms.Button(); | ||||
this.AddButton = new System.Windows.Forms.Button(); | this.AddButton = new System.Windows.Forms.Button(); | ||||
this.ServerGroupBox = new System.Windows.Forms.GroupBox(); | this.ServerGroupBox = new System.Windows.Forms.GroupBox(); | ||||
this.ServersListBox = new System.Windows.Forms.ListBox(); | this.ServersListBox = new System.Windows.Forms.ListBox(); | ||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); | |||||
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); | |||||
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); | |||||
this.tableLayoutPanel1.SuspendLayout(); | this.tableLayoutPanel1.SuspendLayout(); | ||||
this.panel1.SuspendLayout(); | |||||
this.panel3.SuspendLayout(); | |||||
this.ServerGroupBox.SuspendLayout(); | this.ServerGroupBox.SuspendLayout(); | ||||
this.tableLayoutPanel2.SuspendLayout(); | |||||
this.tableLayoutPanel3.SuspendLayout(); | |||||
this.tableLayoutPanel4.SuspendLayout(); | |||||
this.SuspendLayout(); | this.SuspendLayout(); | ||||
// | // | ||||
// tableLayoutPanel1 | // tableLayoutPanel1 | ||||
@@ -64,21 +66,21 @@ | |||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | ||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | ||||
this.tableLayoutPanel1.Controls.Add(this.RemarksTextBox, 1, 5); | this.tableLayoutPanel1.Controls.Add(this.RemarksTextBox, 1, 5); | ||||
this.tableLayoutPanel1.Controls.Add(this.label6, 0, 5); | |||||
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0); | |||||
this.tableLayoutPanel1.Controls.Add(this.label2, 0, 1); | |||||
this.tableLayoutPanel1.Controls.Add(this.RemarksLabel, 0, 5); | |||||
this.tableLayoutPanel1.Controls.Add(this.IPLabel, 0, 0); | |||||
this.tableLayoutPanel1.Controls.Add(this.ServerPortLabel, 0, 1); | |||||
this.tableLayoutPanel1.Controls.Add(this.ProxyPortTextBox, 1, 4); | this.tableLayoutPanel1.Controls.Add(this.ProxyPortTextBox, 1, 4); | ||||
this.tableLayoutPanel1.Controls.Add(this.label4, 0, 4); | |||||
this.tableLayoutPanel1.Controls.Add(this.label3, 0, 2); | |||||
this.tableLayoutPanel1.Controls.Add(this.ProxyPortLabel, 0, 4); | |||||
this.tableLayoutPanel1.Controls.Add(this.PasswordLabel, 0, 2); | |||||
this.tableLayoutPanel1.Controls.Add(this.IPTextBox, 1, 0); | this.tableLayoutPanel1.Controls.Add(this.IPTextBox, 1, 0); | ||||
this.tableLayoutPanel1.Controls.Add(this.ServerPortTextBox, 1, 1); | this.tableLayoutPanel1.Controls.Add(this.ServerPortTextBox, 1, 1); | ||||
this.tableLayoutPanel1.Controls.Add(this.PasswordTextBox, 1, 2); | this.tableLayoutPanel1.Controls.Add(this.PasswordTextBox, 1, 2); | ||||
this.tableLayoutPanel1.Controls.Add(this.label5, 0, 3); | |||||
this.tableLayoutPanel1.Controls.Add(this.EncryptionLabel, 0, 3); | |||||
this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 3); | this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 3); | ||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); | this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21); | ||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(5); | |||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); | |||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1"; | this.tableLayoutPanel1.Name = "tableLayoutPanel1"; | ||||
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(5); | |||||
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3); | |||||
this.tableLayoutPanel1.RowCount = 6; | this.tableLayoutPanel1.RowCount = 6; | ||||
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.RowStyles.Add(new System.Windows.Forms.RowStyle()); | ||||
@@ -86,81 +88,84 @@ | |||||
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.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(242, 167); | |||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(238, 163); | |||||
this.tableLayoutPanel1.TabIndex = 0; | this.tableLayoutPanel1.TabIndex = 0; | ||||
// | // | ||||
// RemarksTextBox | // RemarksTextBox | ||||
// | // | ||||
this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | ||||
this.RemarksTextBox.Location = new System.Drawing.Point(74, 139); | |||||
this.RemarksTextBox.Location = new System.Drawing.Point(72, 137); | |||||
this.RemarksTextBox.MaxLength = 32; | |||||
this.RemarksTextBox.Name = "RemarksTextBox"; | this.RemarksTextBox.Name = "RemarksTextBox"; | ||||
this.RemarksTextBox.Size = new System.Drawing.Size(160, 20); | this.RemarksTextBox.Size = new System.Drawing.Size(160, 20); | ||||
this.RemarksTextBox.TabIndex = 10; | this.RemarksTextBox.TabIndex = 10; | ||||
this.RemarksTextBox.WordWrap = false; | this.RemarksTextBox.WordWrap = false; | ||||
// | // | ||||
// label6 | |||||
// RemarksLabel | |||||
// | // | ||||
this.label6.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.label6.AutoSize = true; | |||||
this.label6.Location = new System.Drawing.Point(19, 142); | |||||
this.label6.Name = "label6"; | |||||
this.label6.Size = new System.Drawing.Size(49, 13); | |||||
this.label6.TabIndex = 9; | |||||
this.label6.Text = "Remarks"; | |||||
this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.RemarksLabel.AutoSize = true; | |||||
this.RemarksLabel.Location = new System.Drawing.Point(17, 140); | |||||
this.RemarksLabel.Name = "RemarksLabel"; | |||||
this.RemarksLabel.Size = new System.Drawing.Size(49, 13); | |||||
this.RemarksLabel.TabIndex = 9; | |||||
this.RemarksLabel.Text = "Remarks"; | |||||
// | // | ||||
// label1 | |||||
// IPLabel | |||||
// | // | ||||
this.label1.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.label1.AutoSize = true; | |||||
this.label1.Location = new System.Drawing.Point(17, 11); | |||||
this.label1.Name = "label1"; | |||||
this.label1.Size = new System.Drawing.Size(51, 13); | |||||
this.label1.TabIndex = 0; | |||||
this.label1.Text = "Server IP"; | |||||
this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.IPLabel.AutoSize = true; | |||||
this.IPLabel.Location = new System.Drawing.Point(15, 9); | |||||
this.IPLabel.Name = "IPLabel"; | |||||
this.IPLabel.Size = new System.Drawing.Size(51, 13); | |||||
this.IPLabel.TabIndex = 0; | |||||
this.IPLabel.Text = "Server IP"; | |||||
// | // | ||||
// label2 | |||||
// ServerPortLabel | |||||
// | // | ||||
this.label2.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.label2.AutoSize = true; | |||||
this.label2.Location = new System.Drawing.Point(8, 37); | |||||
this.label2.Name = "label2"; | |||||
this.label2.Size = new System.Drawing.Size(60, 13); | |||||
this.label2.TabIndex = 1; | |||||
this.label2.Text = "Server Port"; | |||||
this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.ServerPortLabel.AutoSize = true; | |||||
this.ServerPortLabel.Location = new System.Drawing.Point(6, 35); | |||||
this.ServerPortLabel.Name = "ServerPortLabel"; | |||||
this.ServerPortLabel.Size = new System.Drawing.Size(60, 13); | |||||
this.ServerPortLabel.TabIndex = 1; | |||||
this.ServerPortLabel.Text = "Server Port"; | |||||
// | // | ||||
// ProxyPortTextBox | // ProxyPortTextBox | ||||
// | // | ||||
this.ProxyPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | this.ProxyPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | ||||
this.ProxyPortTextBox.Location = new System.Drawing.Point(74, 113); | |||||
this.ProxyPortTextBox.Location = new System.Drawing.Point(72, 111); | |||||
this.ProxyPortTextBox.MaxLength = 10; | |||||
this.ProxyPortTextBox.Name = "ProxyPortTextBox"; | this.ProxyPortTextBox.Name = "ProxyPortTextBox"; | ||||
this.ProxyPortTextBox.Size = new System.Drawing.Size(160, 20); | this.ProxyPortTextBox.Size = new System.Drawing.Size(160, 20); | ||||
this.ProxyPortTextBox.TabIndex = 4; | this.ProxyPortTextBox.TabIndex = 4; | ||||
this.ProxyPortTextBox.WordWrap = false; | this.ProxyPortTextBox.WordWrap = false; | ||||
// | // | ||||
// label4 | |||||
// ProxyPortLabel | |||||
// | // | ||||
this.label4.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.label4.AutoSize = true; | |||||
this.label4.Location = new System.Drawing.Point(13, 116); | |||||
this.label4.Name = "label4"; | |||||
this.label4.Size = new System.Drawing.Size(55, 13); | |||||
this.label4.TabIndex = 3; | |||||
this.label4.Text = "Proxy Port"; | |||||
this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.ProxyPortLabel.AutoSize = true; | |||||
this.ProxyPortLabel.Location = new System.Drawing.Point(11, 114); | |||||
this.ProxyPortLabel.Name = "ProxyPortLabel"; | |||||
this.ProxyPortLabel.Size = new System.Drawing.Size(55, 13); | |||||
this.ProxyPortLabel.TabIndex = 3; | |||||
this.ProxyPortLabel.Text = "Proxy Port"; | |||||
// | // | ||||
// label3 | |||||
// PasswordLabel | |||||
// | // | ||||
this.label3.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.label3.AutoSize = true; | |||||
this.label3.Location = new System.Drawing.Point(15, 63); | |||||
this.label3.Name = "label3"; | |||||
this.label3.Size = new System.Drawing.Size(53, 13); | |||||
this.label3.TabIndex = 2; | |||||
this.label3.Text = "Password"; | |||||
this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.PasswordLabel.AutoSize = true; | |||||
this.PasswordLabel.Location = new System.Drawing.Point(13, 61); | |||||
this.PasswordLabel.Name = "PasswordLabel"; | |||||
this.PasswordLabel.Size = new System.Drawing.Size(53, 13); | |||||
this.PasswordLabel.TabIndex = 2; | |||||
this.PasswordLabel.Text = "Password"; | |||||
// | // | ||||
// IPTextBox | // IPTextBox | ||||
// | // | ||||
this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | ||||
this.IPTextBox.Location = new System.Drawing.Point(74, 8); | |||||
this.IPTextBox.Location = new System.Drawing.Point(72, 6); | |||||
this.IPTextBox.MaxLength = 512; | |||||
this.IPTextBox.Name = "IPTextBox"; | this.IPTextBox.Name = "IPTextBox"; | ||||
this.IPTextBox.Size = new System.Drawing.Size(160, 20); | this.IPTextBox.Size = new System.Drawing.Size(160, 20); | ||||
this.IPTextBox.TabIndex = 0; | this.IPTextBox.TabIndex = 0; | ||||
@@ -169,7 +174,8 @@ | |||||
// ServerPortTextBox | // ServerPortTextBox | ||||
// | // | ||||
this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | ||||
this.ServerPortTextBox.Location = new System.Drawing.Point(74, 34); | |||||
this.ServerPortTextBox.Location = new System.Drawing.Point(72, 32); | |||||
this.ServerPortTextBox.MaxLength = 10; | |||||
this.ServerPortTextBox.Name = "ServerPortTextBox"; | this.ServerPortTextBox.Name = "ServerPortTextBox"; | ||||
this.ServerPortTextBox.Size = new System.Drawing.Size(160, 20); | this.ServerPortTextBox.Size = new System.Drawing.Size(160, 20); | ||||
this.ServerPortTextBox.TabIndex = 1; | this.ServerPortTextBox.TabIndex = 1; | ||||
@@ -178,22 +184,23 @@ | |||||
// PasswordTextBox | // PasswordTextBox | ||||
// | // | ||||
this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); | ||||
this.PasswordTextBox.Location = new System.Drawing.Point(74, 60); | |||||
this.PasswordTextBox.Location = new System.Drawing.Point(72, 58); | |||||
this.PasswordTextBox.MaxLength = 256; | |||||
this.PasswordTextBox.Name = "PasswordTextBox"; | this.PasswordTextBox.Name = "PasswordTextBox"; | ||||
this.PasswordTextBox.PasswordChar = '*'; | this.PasswordTextBox.PasswordChar = '*'; | ||||
this.PasswordTextBox.Size = new System.Drawing.Size(160, 20); | this.PasswordTextBox.Size = new System.Drawing.Size(160, 20); | ||||
this.PasswordTextBox.TabIndex = 2; | this.PasswordTextBox.TabIndex = 2; | ||||
this.PasswordTextBox.WordWrap = false; | this.PasswordTextBox.WordWrap = false; | ||||
// | // | ||||
// label5 | |||||
// EncryptionLabel | |||||
// | // | ||||
this.label5.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.label5.AutoSize = true; | |||||
this.label5.Location = new System.Drawing.Point(11, 90); | |||||
this.label5.Name = "label5"; | |||||
this.label5.Size = new System.Drawing.Size(57, 13); | |||||
this.label5.TabIndex = 8; | |||||
this.label5.Text = "Encryption"; | |||||
this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; | |||||
this.EncryptionLabel.AutoSize = true; | |||||
this.EncryptionLabel.Location = new System.Drawing.Point(9, 88); | |||||
this.EncryptionLabel.Name = "EncryptionLabel"; | |||||
this.EncryptionLabel.Size = new System.Drawing.Size(57, 13); | |||||
this.EncryptionLabel.TabIndex = 8; | |||||
this.EncryptionLabel.Text = "Encryption"; | |||||
// | // | ||||
// EncryptionSelect | // EncryptionSelect | ||||
// | // | ||||
@@ -206,11 +213,13 @@ | |||||
this.EncryptionSelect.Items.AddRange(new object[] { | this.EncryptionSelect.Items.AddRange(new object[] { | ||||
"table", | "table", | ||||
"rc4-md5", | "rc4-md5", | ||||
"salsa20", | |||||
"chacha20", | |||||
"aes-256-cfb", | "aes-256-cfb", | ||||
"aes-192-cfb", | "aes-192-cfb", | ||||
"aes-128-cfb", | "aes-128-cfb", | ||||
"rc4"}); | "rc4"}); | ||||
this.EncryptionSelect.Location = new System.Drawing.Point(74, 86); | |||||
this.EncryptionSelect.Location = new System.Drawing.Point(72, 84); | |||||
this.EncryptionSelect.Name = "EncryptionSelect"; | this.EncryptionSelect.Name = "EncryptionSelect"; | ||||
this.EncryptionSelect.Size = new System.Drawing.Size(160, 21); | this.EncryptionSelect.Size = new System.Drawing.Size(160, 21); | ||||
this.EncryptionSelect.TabIndex = 3; | this.EncryptionSelect.TabIndex = 3; | ||||
@@ -220,7 +229,7 @@ | |||||
this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top; | this.panel2.Anchor = System.Windows.Forms.AnchorStyles.Top; | ||||
this.panel2.AutoSize = true; | this.panel2.AutoSize = true; | ||||
this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | this.panel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | ||||
this.panel2.Location = new System.Drawing.Point(164, 175); | |||||
this.panel2.Location = new System.Drawing.Point(207, 187); | |||||
this.panel2.Name = "panel2"; | this.panel2.Name = "panel2"; | ||||
this.panel2.Size = new System.Drawing.Size(0, 0); | this.panel2.Size = new System.Drawing.Size(0, 0); | ||||
this.panel2.TabIndex = 1; | this.panel2.TabIndex = 1; | ||||
@@ -228,7 +237,9 @@ | |||||
// OKButton | // OKButton | ||||
// | // | ||||
this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; | this.OKButton.DialogResult = System.Windows.Forms.DialogResult.OK; | ||||
this.OKButton.Location = new System.Drawing.Point(4, 4); | |||||
this.OKButton.Dock = System.Windows.Forms.DockStyle.Right; | |||||
this.OKButton.Location = new System.Drawing.Point(3, 3); | |||||
this.OKButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0); | |||||
this.OKButton.Name = "OKButton"; | this.OKButton.Name = "OKButton"; | ||||
this.OKButton.Size = new System.Drawing.Size(75, 23); | this.OKButton.Size = new System.Drawing.Size(75, 23); | ||||
this.OKButton.TabIndex = 8; | this.OKButton.TabIndex = 8; | ||||
@@ -239,7 +250,9 @@ | |||||
// MyCancelButton | // MyCancelButton | ||||
// | // | ||||
this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; | this.MyCancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; | ||||
this.MyCancelButton.Location = new System.Drawing.Point(87, 4); | |||||
this.MyCancelButton.Dock = System.Windows.Forms.DockStyle.Right; | |||||
this.MyCancelButton.Location = new System.Drawing.Point(84, 3); | |||||
this.MyCancelButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0); | |||||
this.MyCancelButton.Name = "MyCancelButton"; | this.MyCancelButton.Name = "MyCancelButton"; | ||||
this.MyCancelButton.Size = new System.Drawing.Size(75, 23); | this.MyCancelButton.Size = new System.Drawing.Size(75, 23); | ||||
this.MyCancelButton.TabIndex = 9; | this.MyCancelButton.TabIndex = 9; | ||||
@@ -247,34 +260,13 @@ | |||||
this.MyCancelButton.UseVisualStyleBackColor = true; | this.MyCancelButton.UseVisualStyleBackColor = true; | ||||
this.MyCancelButton.Click += new System.EventHandler(this.CancelButton_Click); | this.MyCancelButton.Click += new System.EventHandler(this.CancelButton_Click); | ||||
// | // | ||||
// panel1 | |||||
// | |||||
this.panel1.AutoSize = true; | |||||
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(313, 247); | |||||
this.panel1.Margin = new System.Windows.Forms.Padding(0); | |||||
this.panel1.Name = "panel1"; | |||||
this.panel1.Size = new System.Drawing.Size(165, 30); | |||||
this.panel1.TabIndex = 1; | |||||
// | |||||
// panel3 | |||||
// | |||||
this.panel3.AutoSize = true; | |||||
this.panel3.Controls.Add(this.DeleteButton); | |||||
this.panel3.Controls.Add(this.AddButton); | |||||
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(192, 31); | |||||
this.panel3.TabIndex = 5; | |||||
// | |||||
// DeleteButton | // DeleteButton | ||||
// | // | ||||
this.DeleteButton.Location = new System.Drawing.Point(100, 4); | |||||
this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Right; | |||||
this.DeleteButton.Location = new System.Drawing.Point(86, 6); | |||||
this.DeleteButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3); | |||||
this.DeleteButton.Name = "DeleteButton"; | this.DeleteButton.Name = "DeleteButton"; | ||||
this.DeleteButton.Size = new System.Drawing.Size(89, 23); | |||||
this.DeleteButton.Size = new System.Drawing.Size(80, 23); | |||||
this.DeleteButton.TabIndex = 7; | this.DeleteButton.TabIndex = 7; | ||||
this.DeleteButton.Text = "&Delete"; | this.DeleteButton.Text = "&Delete"; | ||||
this.DeleteButton.UseVisualStyleBackColor = true; | this.DeleteButton.UseVisualStyleBackColor = true; | ||||
@@ -282,9 +274,11 @@ | |||||
// | // | ||||
// AddButton | // AddButton | ||||
// | // | ||||
this.AddButton.Location = new System.Drawing.Point(4, 4); | |||||
this.AddButton.Dock = System.Windows.Forms.DockStyle.Left; | |||||
this.AddButton.Location = new System.Drawing.Point(0, 6); | |||||
this.AddButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); | |||||
this.AddButton.Name = "AddButton"; | this.AddButton.Name = "AddButton"; | ||||
this.AddButton.Size = new System.Drawing.Size(89, 23); | |||||
this.AddButton.Size = new System.Drawing.Size(80, 23); | |||||
this.AddButton.TabIndex = 6; | this.AddButton.TabIndex = 6; | ||||
this.AddButton.Text = "&Add"; | this.AddButton.Text = "&Add"; | ||||
this.AddButton.UseVisualStyleBackColor = true; | this.AddButton.UseVisualStyleBackColor = true; | ||||
@@ -292,10 +286,13 @@ | |||||
// | // | ||||
// ServerGroupBox | // ServerGroupBox | ||||
// | // | ||||
this.ServerGroupBox.AutoSize = true; | |||||
this.ServerGroupBox.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||||
this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1); | this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1); | ||||
this.ServerGroupBox.Location = new System.Drawing.Point(223, 12); | |||||
this.ServerGroupBox.Location = new System.Drawing.Point(178, 0); | |||||
this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(12, 0, 0, 0); | |||||
this.ServerGroupBox.Name = "ServerGroupBox"; | this.ServerGroupBox.Name = "ServerGroupBox"; | ||||
this.ServerGroupBox.Size = new System.Drawing.Size(255, 205); | |||||
this.ServerGroupBox.Size = new System.Drawing.Size(249, 200); | |||||
this.ServerGroupBox.TabIndex = 6; | this.ServerGroupBox.TabIndex = 6; | ||||
this.ServerGroupBox.TabStop = false; | this.ServerGroupBox.TabStop = false; | ||||
this.ServerGroupBox.Text = "Server"; | this.ServerGroupBox.Text = "Server"; | ||||
@@ -303,29 +300,88 @@ | |||||
// ServersListBox | // ServersListBox | ||||
// | // | ||||
this.ServersListBox.FormattingEnabled = true; | this.ServersListBox.FormattingEnabled = true; | ||||
this.ServersListBox.Location = new System.Drawing.Point(12, 12); | |||||
this.ServersListBox.IntegralHeight = false; | |||||
this.ServersListBox.Location = new System.Drawing.Point(0, 0); | |||||
this.ServersListBox.Margin = new System.Windows.Forms.Padding(0); | |||||
this.ServersListBox.Name = "ServersListBox"; | this.ServersListBox.Name = "ServersListBox"; | ||||
this.ServersListBox.Size = new System.Drawing.Size(192, 173); | |||||
this.ServersListBox.Size = new System.Drawing.Size(166, 148); | |||||
this.ServersListBox.TabIndex = 5; | this.ServersListBox.TabIndex = 5; | ||||
this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); | this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged); | ||||
// | // | ||||
// tableLayoutPanel2 | |||||
// | |||||
this.tableLayoutPanel2.AutoSize = true; | |||||
this.tableLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||||
this.tableLayoutPanel2.ColumnCount = 2; | |||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||||
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel3, 1, 2); | |||||
this.tableLayoutPanel2.Controls.Add(this.ServersListBox, 0, 0); | |||||
this.tableLayoutPanel2.Controls.Add(this.ServerGroupBox, 1, 0); | |||||
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 1); | |||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(12, 12); | |||||
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); | |||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2"; | |||||
this.tableLayoutPanel2.RowCount = 3; | |||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(427, 264); | |||||
this.tableLayoutPanel2.TabIndex = 7; | |||||
// | |||||
// tableLayoutPanel3 | |||||
// | |||||
this.tableLayoutPanel3.AutoSize = true; | |||||
this.tableLayoutPanel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||||
this.tableLayoutPanel3.ColumnCount = 2; | |||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); | |||||
this.tableLayoutPanel3.Controls.Add(this.MyCancelButton, 1, 0); | |||||
this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0); | |||||
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right; | |||||
this.tableLayoutPanel3.Location = new System.Drawing.Point(268, 235); | |||||
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); | |||||
this.tableLayoutPanel3.Name = "tableLayoutPanel3"; | |||||
this.tableLayoutPanel3.RowCount = 1; | |||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||||
this.tableLayoutPanel3.Size = new System.Drawing.Size(159, 26); | |||||
this.tableLayoutPanel3.TabIndex = 8; | |||||
// | |||||
// tableLayoutPanel4 | |||||
// | |||||
this.tableLayoutPanel4.AutoSize = true; | |||||
this.tableLayoutPanel4.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||||
this.tableLayoutPanel4.ColumnCount = 2; | |||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); | |||||
this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0); | |||||
this.tableLayoutPanel4.Controls.Add(this.AddButton, 0, 0); | |||||
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Top; | |||||
this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 200); | |||||
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); | |||||
this.tableLayoutPanel4.Name = "tableLayoutPanel4"; | |||||
this.tableLayoutPanel4.RowCount = 1; | |||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); | |||||
this.tableLayoutPanel4.Size = new System.Drawing.Size(166, 32); | |||||
this.tableLayoutPanel4.TabIndex = 8; | |||||
// | |||||
// ConfigForm | // ConfigForm | ||||
// | // | ||||
this.AcceptButton = this.OKButton; | this.AcceptButton = this.OKButton; | ||||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); | this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); | ||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; | ||||
this.AutoSize = true; | this.AutoSize = true; | ||||
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||||
this.CancelButton = this.MyCancelButton; | this.CancelButton = this.MyCancelButton; | ||||
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.ClientSize = new System.Drawing.Size(574, 367); | |||||
this.Controls.Add(this.tableLayoutPanel2); | |||||
this.Controls.Add(this.panel2); | this.Controls.Add(this.panel2); | ||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; | ||||
this.MaximizeBox = false; | this.MaximizeBox = false; | ||||
this.MinimizeBox = false; | this.MinimizeBox = false; | ||||
this.Name = "ConfigForm"; | this.Name = "ConfigForm"; | ||||
this.Padding = new System.Windows.Forms.Padding(12, 12, 12, 9); | |||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | ||||
this.Text = "Edit Servers"; | this.Text = "Edit Servers"; | ||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConfigForm_FormClosed); | this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ConfigForm_FormClosed); | ||||
@@ -333,10 +389,12 @@ | |||||
this.Shown += new System.EventHandler(this.ConfigForm_Shown); | this.Shown += new System.EventHandler(this.ConfigForm_Shown); | ||||
this.tableLayoutPanel1.ResumeLayout(false); | this.tableLayoutPanel1.ResumeLayout(false); | ||||
this.tableLayoutPanel1.PerformLayout(); | this.tableLayoutPanel1.PerformLayout(); | ||||
this.panel1.ResumeLayout(false); | |||||
this.panel3.ResumeLayout(false); | |||||
this.ServerGroupBox.ResumeLayout(false); | this.ServerGroupBox.ResumeLayout(false); | ||||
this.ServerGroupBox.PerformLayout(); | this.ServerGroupBox.PerformLayout(); | ||||
this.tableLayoutPanel2.ResumeLayout(false); | |||||
this.tableLayoutPanel2.PerformLayout(); | |||||
this.tableLayoutPanel3.ResumeLayout(false); | |||||
this.tableLayoutPanel4.ResumeLayout(false); | |||||
this.ResumeLayout(false); | this.ResumeLayout(false); | ||||
this.PerformLayout(); | this.PerformLayout(); | ||||
@@ -345,27 +403,28 @@ | |||||
#endregion | #endregion | ||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; | ||||
private System.Windows.Forms.Label label1; | |||||
private System.Windows.Forms.Label label2; | |||||
private System.Windows.Forms.Label label3; | |||||
private System.Windows.Forms.Label label4; | |||||
private System.Windows.Forms.Label IPLabel; | |||||
private System.Windows.Forms.Label ServerPortLabel; | |||||
private System.Windows.Forms.Label PasswordLabel; | |||||
private System.Windows.Forms.Label ProxyPortLabel; | |||||
private System.Windows.Forms.TextBox IPTextBox; | private System.Windows.Forms.TextBox IPTextBox; | ||||
private System.Windows.Forms.TextBox ServerPortTextBox; | private System.Windows.Forms.TextBox ServerPortTextBox; | ||||
private System.Windows.Forms.TextBox PasswordTextBox; | private System.Windows.Forms.TextBox PasswordTextBox; | ||||
private System.Windows.Forms.TextBox ProxyPortTextBox; | private System.Windows.Forms.TextBox ProxyPortTextBox; | ||||
private System.Windows.Forms.Label label5; | |||||
private System.Windows.Forms.Label EncryptionLabel; | |||||
private System.Windows.Forms.ComboBox EncryptionSelect; | private System.Windows.Forms.ComboBox EncryptionSelect; | ||||
private System.Windows.Forms.Panel panel2; | private System.Windows.Forms.Panel panel2; | ||||
private System.Windows.Forms.Button OKButton; | private System.Windows.Forms.Button OKButton; | ||||
private System.Windows.Forms.Button MyCancelButton; | private System.Windows.Forms.Button MyCancelButton; | ||||
private System.Windows.Forms.Panel panel1; | |||||
private System.Windows.Forms.Panel panel3; | |||||
private System.Windows.Forms.Button DeleteButton; | private System.Windows.Forms.Button DeleteButton; | ||||
private System.Windows.Forms.Button AddButton; | private System.Windows.Forms.Button AddButton; | ||||
private System.Windows.Forms.GroupBox ServerGroupBox; | private System.Windows.Forms.GroupBox ServerGroupBox; | ||||
private System.Windows.Forms.ListBox ServersListBox; | private System.Windows.Forms.ListBox ServersListBox; | ||||
private System.Windows.Forms.TextBox RemarksTextBox; | private System.Windows.Forms.TextBox RemarksTextBox; | ||||
private System.Windows.Forms.Label label6; | |||||
private System.Windows.Forms.Label RemarksLabel; | |||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; | |||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; | |||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; | |||||
} | } | ||||
} | } | ||||
@@ -22,7 +22,14 @@ namespace Shadowsocks.View | |||||
public ConfigForm(ShadowsocksController controller) | public ConfigForm(ShadowsocksController controller) | ||||
{ | { | ||||
this.Font = System.Drawing.SystemFonts.MessageBoxFont; | |||||
InitializeComponent(); | InitializeComponent(); | ||||
// a dirty hack | |||||
this.ServersListBox.Dock = System.Windows.Forms.DockStyle.Fill; | |||||
this.PerformLayout(); | |||||
UpdateTexts(); | |||||
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | ||||
this.controller = controller; | this.controller = controller; | ||||
@@ -31,6 +38,22 @@ namespace Shadowsocks.View | |||||
LoadCurrentConfiguration(); | LoadCurrentConfiguration(); | ||||
} | } | ||||
private void UpdateTexts() | |||||
{ | |||||
AddButton.Text = I18N.GetString("&Add"); | |||||
DeleteButton.Text = I18N.GetString("&Delete"); | |||||
IPLabel.Text = I18N.GetString("Server IP"); | |||||
ServerPortLabel.Text = I18N.GetString("Server Port"); | |||||
PasswordLabel.Text = I18N.GetString("Password"); | |||||
EncryptionLabel.Text = I18N.GetString("Encryption"); | |||||
ProxyPortLabel.Text = I18N.GetString("Proxy Port"); | |||||
RemarksLabel.Text = I18N.GetString("Remarks"); | |||||
ServerGroupBox.Text = I18N.GetString("Server"); | |||||
OKButton.Text = I18N.GetString("OK"); | |||||
MyCancelButton.Text = I18N.GetString("Cancel"); | |||||
this.Text = I18N.GetString("Edit Servers"); | |||||
} | |||||
private void controller_ConfigChanged(object sender, EventArgs e) | private void controller_ConfigChanged(object sender, EventArgs e) | ||||
{ | { | ||||
LoadCurrentConfiguration(); | LoadCurrentConfiguration(); | ||||
@@ -67,7 +90,7 @@ namespace Shadowsocks.View | |||||
} | } | ||||
catch (FormatException) | catch (FormatException) | ||||
{ | { | ||||
MessageBox.Show("illegal port number format"); | |||||
MessageBox.Show(I18N.GetString("Illegal port number format")); | |||||
} | } | ||||
catch (Exception ex) | catch (Exception ex) | ||||
{ | { | ||||
@@ -102,7 +125,7 @@ namespace Shadowsocks.View | |||||
ServersListBox.Items.Clear(); | ServersListBox.Items.Clear(); | ||||
foreach (Server server in _modifiedConfiguration.configs) | foreach (Server server in _modifiedConfiguration.configs) | ||||
{ | { | ||||
ServersListBox.Items.Add(string.IsNullOrEmpty(server.server) ? "New server" : string.IsNullOrEmpty(server.remarks)? server.server + ":" + server.server_port : server.server + ":" + server.server_port + " (" + server.remarks + ")"); | |||||
ServersListBox.Items.Add(server.FriendlyName()); | |||||
} | } | ||||
} | } | ||||
@@ -176,7 +199,7 @@ namespace Shadowsocks.View | |||||
} | } | ||||
if (_modifiedConfiguration.configs.Count == 0) | if (_modifiedConfiguration.configs.Count == 0) | ||||
{ | { | ||||
MessageBox.Show("Please add at least one server"); | |||||
MessageBox.Show(I18N.GetString("Please add at least one server")); | |||||
return; | return; | ||||
} | } | ||||
controller.SaveServers(_modifiedConfiguration.configs); | controller.SaveServers(_modifiedConfiguration.configs); | ||||
@@ -14,12 +14,12 @@ namespace Shadowsocks.View | |||||
{ | { | ||||
// yes this is just a menu view controller | // yes this is just a menu view controller | ||||
// when config form is closed, it moves away from RAM | // when config form is closed, it moves away from RAM | ||||
// and it should just does anything related to the config form | |||||
// and it should just do anything related to the config form | |||||
private ShadowsocksController controller; | private ShadowsocksController controller; | ||||
private UpdateChecker updateChecker; | private UpdateChecker updateChecker; | ||||
private NotifyIcon notifyIcon1; | |||||
private NotifyIcon _notifyIcon; | |||||
private ContextMenu contextMenu1; | private ContextMenu contextMenu1; | ||||
private bool _isFirstRun; | private bool _isFirstRun; | ||||
@@ -37,18 +37,29 @@ namespace Shadowsocks.View | |||||
private MenuItem menuItem3; | private MenuItem menuItem3; | ||||
private MenuItem quitItem; | private MenuItem quitItem; | ||||
private MenuItem menuItem1; | private MenuItem menuItem1; | ||||
private MenuItem modeItem; | |||||
private MenuItem globalModeItem; | |||||
private MenuItem PACModeItem; | |||||
private ConfigForm configForm; | private ConfigForm configForm; | ||||
public MenuViewController(ShadowsocksController controller) | public MenuViewController(ShadowsocksController controller) | ||||
{ | { | ||||
this.controller = controller; | |||||
LoadMenu(); | LoadMenu(); | ||||
LoadTrayIcon(); | |||||
this.controller = controller; | |||||
controller.EnableStatusChanged += controller_EnableStatusChanged; | controller.EnableStatusChanged += controller_EnableStatusChanged; | ||||
controller.ConfigChanged += controller_ConfigChanged; | controller.ConfigChanged += controller_ConfigChanged; | ||||
controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; | controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; | ||||
controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | ||||
controller.EnableGlobalChanged += controller_EnableGlobalChanged; | |||||
controller.Errored += controller_Errored; | |||||
_notifyIcon = new NotifyIcon(); | |||||
UpdateTrayIcon(); | |||||
_notifyIcon.Visible = true; | |||||
_notifyIcon.ContextMenu = contextMenu1; | |||||
_notifyIcon.DoubleClick += notifyIcon1_DoubleClick; | |||||
this.updateChecker = new UpdateChecker(); | this.updateChecker = new UpdateChecker(); | ||||
updateChecker.NewVersionFound += updateChecker_NewVersionFound; | updateChecker.NewVersionFound += updateChecker_NewVersionFound; | ||||
@@ -64,7 +75,12 @@ namespace Shadowsocks.View | |||||
} | } | ||||
} | } | ||||
private void LoadTrayIcon() | |||||
void controller_Errored(object sender, System.IO.ErrorEventArgs e) | |||||
{ | |||||
MessageBox.Show(e.GetException().ToString(), String.Format(I18N.GetString("Shadowsocks Error: {0}"), e.GetException().Message)); | |||||
} | |||||
private void UpdateTrayIcon() | |||||
{ | { | ||||
int dpi; | int dpi; | ||||
Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); | Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); | ||||
@@ -85,19 +101,33 @@ namespace Shadowsocks.View | |||||
{ | { | ||||
icon = Resources.ss24; | icon = Resources.ss24; | ||||
} | } | ||||
notifyIcon1 = new NotifyIcon(); | |||||
notifyIcon1.Text = "Shadowsocks"; | |||||
notifyIcon1.Icon = Icon.FromHandle(icon.GetHicon()); | |||||
notifyIcon1.Visible = true; | |||||
bool enabled = controller.GetConfiguration().enabled; | |||||
if (!enabled) | |||||
{ | |||||
Bitmap iconCopy = new Bitmap(icon); | |||||
for (int x = 0; x < iconCopy.Width; x++) | |||||
{ | |||||
for (int y = 0; y < iconCopy.Height; y++) | |||||
{ | |||||
Color color = icon.GetPixel(x, y); | |||||
iconCopy.SetPixel(x, y , Color.FromArgb((byte)(color.A / 1.25), color.R, color.G, color.B)); | |||||
} | |||||
} | |||||
icon = iconCopy; | |||||
} | |||||
_notifyIcon.Icon = Icon.FromHandle(icon.GetHicon()); | |||||
notifyIcon1.ContextMenu = contextMenu1; | |||||
notifyIcon1.DoubleClick +=notifyIcon1_DoubleClick; | |||||
string text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("Enabled") : I18N.GetString("Disabled")) + "\n" + controller.GetCurrentServer().FriendlyName(); | |||||
_notifyIcon.Text = text.Substring(0, Math.Min(63, text.Length)); | |||||
} | } | ||||
private void LoadMenu() | private void LoadMenu() | ||||
{ | { | ||||
this.contextMenu1 = new System.Windows.Forms.ContextMenu(); | this.contextMenu1 = new System.Windows.Forms.ContextMenu(); | ||||
this.enableItem = new System.Windows.Forms.MenuItem(); | this.enableItem = new System.Windows.Forms.MenuItem(); | ||||
this.modeItem = new System.Windows.Forms.MenuItem(); | |||||
this.PACModeItem = new System.Windows.Forms.MenuItem(); | |||||
this.globalModeItem = new System.Windows.Forms.MenuItem(); | |||||
this.AutoStartupItem = new System.Windows.Forms.MenuItem(); | this.AutoStartupItem = new System.Windows.Forms.MenuItem(); | ||||
this.ShareOverLANItem = new System.Windows.Forms.MenuItem(); | this.ShareOverLANItem = new System.Windows.Forms.MenuItem(); | ||||
this.ServersItem = new System.Windows.Forms.MenuItem(); | this.ServersItem = new System.Windows.Forms.MenuItem(); | ||||
@@ -117,6 +147,7 @@ namespace Shadowsocks.View | |||||
// | // | ||||
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | ||||
this.enableItem, | this.enableItem, | ||||
this.modeItem, | |||||
this.ServersItem, | this.ServersItem, | ||||
this.menuItem1, | this.menuItem1, | ||||
this.AutoStartupItem, | this.AutoStartupItem, | ||||
@@ -132,28 +163,36 @@ namespace Shadowsocks.View | |||||
// enableItem | // enableItem | ||||
// | // | ||||
this.enableItem.Index = 0; | this.enableItem.Index = 0; | ||||
this.enableItem.Text = "&Enable"; | |||||
this.enableItem.Text = I18N.GetString("Enable"); | |||||
this.enableItem.Click += new System.EventHandler(this.EnableItem_Click); | 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 = 4; | |||||
this.ShareOverLANItem.Text = "Share over LAN"; | |||||
this.ShareOverLANItem.Click += new System.EventHandler(this.ShareOverLANItem_Click); | |||||
// | |||||
// modeMenu | |||||
// | |||||
this.modeItem.Index = 1; | |||||
this.modeItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |||||
this.PACModeItem, | |||||
this.globalModeItem}); | |||||
this.modeItem.Text = I18N.GetString("Mode"); | |||||
// | |||||
// PACModeItem | |||||
// | |||||
this.PACModeItem.Index = 0; | |||||
this.PACModeItem.Text = I18N.GetString("PAC"); | |||||
this.PACModeItem.Click += new System.EventHandler(this.PACModeItem_Click); | |||||
// | |||||
// globalModeItem | |||||
// | |||||
this.globalModeItem.Index = 1; | |||||
this.globalModeItem.Text = I18N.GetString("Global"); | |||||
this.globalModeItem.Click += new System.EventHandler(this.GlobalModeItem_Click); | |||||
// | // | ||||
// ServersItem | // ServersItem | ||||
// | // | ||||
this.ServersItem.Index = 1; | |||||
this.ServersItem.Index = 2; | |||||
this.ServersItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | this.ServersItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | ||||
this.SeperatorItem, | this.SeperatorItem, | ||||
this.ConfigItem}); | this.ConfigItem}); | ||||
this.ServersItem.Text = "&Servers"; | |||||
this.ServersItem.Text = I18N.GetString("Servers"); | |||||
// | // | ||||
// SeperatorItem | // SeperatorItem | ||||
// | // | ||||
@@ -163,58 +202,71 @@ namespace Shadowsocks.View | |||||
// ConfigItem | // ConfigItem | ||||
// | // | ||||
this.ConfigItem.Index = 1; | this.ConfigItem.Index = 1; | ||||
this.ConfigItem.Text = "Edit Servers..."; | |||||
this.ConfigItem.Text = I18N.GetString("Edit Servers..."); | |||||
this.ConfigItem.Click += new System.EventHandler(this.Config_Click); | this.ConfigItem.Click += new System.EventHandler(this.Config_Click); | ||||
// | // | ||||
// menuItem4 | |||||
// menuItem1 | |||||
// | // | ||||
this.menuItem4.Index = 6; | |||||
this.menuItem4.Text = "-"; | |||||
this.menuItem1.Index = 3; | |||||
this.menuItem1.Text = "-"; | |||||
// | |||||
// AutoStartupItem | |||||
// | |||||
this.AutoStartupItem.Index = 4; | |||||
this.AutoStartupItem.Text = I18N.GetString("Start on Boot"); | |||||
this.AutoStartupItem.Click += new System.EventHandler(this.AutoStartupItem_Click); | |||||
// | |||||
// ShareOverLANItem | |||||
// | |||||
this.ShareOverLANItem.Index = 5; | |||||
this.ShareOverLANItem.Text = I18N.GetString("Share over LAN"); | |||||
this.ShareOverLANItem.Click += new System.EventHandler(this.ShareOverLANItem_Click); | |||||
// | // | ||||
// editPACFileItem | // editPACFileItem | ||||
// | // | ||||
this.editPACFileItem.Index = 5; | |||||
this.editPACFileItem.Text = "Edit &PAC File..."; | |||||
this.editPACFileItem.Index = 6; | |||||
this.editPACFileItem.Text = I18N.GetString("Edit PAC File..."); | |||||
this.editPACFileItem.Click += new System.EventHandler(this.EditPACFileItem_Click); | this.editPACFileItem.Click += new System.EventHandler(this.EditPACFileItem_Click); | ||||
// | // | ||||
// menuItem4 | |||||
// | |||||
this.menuItem4.Index = 7; | |||||
this.menuItem4.Text = "-"; | |||||
// | |||||
// QRCodeItem | // QRCodeItem | ||||
// | // | ||||
this.QRCodeItem.Index = 7; | |||||
this.QRCodeItem.Text = "Show &QRCode..."; | |||||
this.QRCodeItem.Index = 8; | |||||
this.QRCodeItem.Text = I18N.GetString("Show QRCode..."); | |||||
this.QRCodeItem.Click += new System.EventHandler(this.QRCodeItem_Click); | this.QRCodeItem.Click += new System.EventHandler(this.QRCodeItem_Click); | ||||
// | // | ||||
// ShowLogItem | // ShowLogItem | ||||
// | // | ||||
this.ShowLogItem.Index = 8; | |||||
this.ShowLogItem.Text = "Show Logs..."; | |||||
this.ShowLogItem.Index = 9; | |||||
this.ShowLogItem.Text = I18N.GetString("Show Logs..."); | |||||
this.ShowLogItem.Click += new System.EventHandler(this.ShowLogItem_Click); | this.ShowLogItem.Click += new System.EventHandler(this.ShowLogItem_Click); | ||||
// | // | ||||
// aboutItem | // aboutItem | ||||
// | // | ||||
this.aboutItem.Index = 9; | |||||
this.aboutItem.Text = "About..."; | |||||
this.aboutItem.Index = 10; | |||||
this.aboutItem.Text = I18N.GetString("About..."); | |||||
this.aboutItem.Click += new System.EventHandler(this.AboutItem_Click); | this.aboutItem.Click += new System.EventHandler(this.AboutItem_Click); | ||||
// | // | ||||
// menuItem3 | // menuItem3 | ||||
// | // | ||||
this.menuItem3.Index = 10; | |||||
this.menuItem3.Index = 11; | |||||
this.menuItem3.Text = "-"; | this.menuItem3.Text = "-"; | ||||
// | // | ||||
// quitItem | // quitItem | ||||
// | // | ||||
this.quitItem.Index = 11; | |||||
this.quitItem.Text = "&Quit"; | |||||
this.quitItem.Index = 12; | |||||
this.quitItem.Text = I18N.GetString("Quit"); | |||||
this.quitItem.Click += new System.EventHandler(this.Quit_Click); | this.quitItem.Click += new System.EventHandler(this.Quit_Click); | ||||
// | |||||
// menuItem1 | |||||
// | |||||
this.menuItem1.Index = 2; | |||||
this.menuItem1.Text = "-"; | |||||
} | } | ||||
private void controller_ConfigChanged(object sender, EventArgs e) | private void controller_ConfigChanged(object sender, EventArgs e) | ||||
{ | { | ||||
LoadCurrentConfiguration(); | LoadCurrentConfiguration(); | ||||
UpdateTrayIcon(); | |||||
} | } | ||||
private void controller_EnableStatusChanged(object sender, EventArgs e) | private void controller_EnableStatusChanged(object sender, EventArgs e) | ||||
@@ -227,6 +279,12 @@ namespace Shadowsocks.View | |||||
ShareOverLANItem.Checked = controller.GetConfiguration().shareOverLan; | ShareOverLANItem.Checked = controller.GetConfiguration().shareOverLan; | ||||
} | } | ||||
void controller_EnableGlobalChanged(object sender, EventArgs e) | |||||
{ | |||||
globalModeItem.Checked = controller.GetConfiguration().global; | |||||
PACModeItem.Checked = !globalModeItem.Checked; | |||||
} | |||||
void controller_PACFileReadyToOpen(object sender, ShadowsocksController.PathEventArgs e) | void controller_PACFileReadyToOpen(object sender, ShadowsocksController.PathEventArgs e) | ||||
{ | { | ||||
string argument = @"/select, " + e.Path; | string argument = @"/select, " + e.Path; | ||||
@@ -236,11 +294,11 @@ namespace Shadowsocks.View | |||||
void updateChecker_NewVersionFound(object sender, EventArgs e) | void updateChecker_NewVersionFound(object sender, EventArgs e) | ||||
{ | { | ||||
notifyIcon1.BalloonTipTitle = "Shadowsocks " + updateChecker.LatestVersionNumber + " Update Found"; | |||||
notifyIcon1.BalloonTipText = "Click here to download"; | |||||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||||
notifyIcon1.BalloonTipClicked += notifyIcon1_BalloonTipClicked; | |||||
notifyIcon1.ShowBalloonTip(5000); | |||||
_notifyIcon.BalloonTipTitle = String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber); | |||||
_notifyIcon.BalloonTipText = I18N.GetString("Click here to download"); | |||||
_notifyIcon.BalloonTipIcon = ToolTipIcon.Info; | |||||
_notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked; | |||||
_notifyIcon.ShowBalloonTip(5000); | |||||
_isFirstRun = false; | _isFirstRun = false; | ||||
} | } | ||||
@@ -255,6 +313,8 @@ namespace Shadowsocks.View | |||||
Configuration config = controller.GetConfiguration(); | Configuration config = controller.GetConfiguration(); | ||||
UpdateServersMenu(); | UpdateServersMenu(); | ||||
enableItem.Checked = config.enabled; | enableItem.Checked = config.enabled; | ||||
globalModeItem.Checked = config.global; | |||||
PACModeItem.Checked = !config.global; | |||||
ShareOverLANItem.Checked = config.shareOverLan; | ShareOverLANItem.Checked = config.shareOverLan; | ||||
AutoStartupItem.Checked = AutoStartup.Check(); | AutoStartupItem.Checked = AutoStartup.Check(); | ||||
} | } | ||||
@@ -269,7 +329,7 @@ namespace Shadowsocks.View | |||||
for (int i = 0; i < configuration.configs.Count; i++) | for (int i = 0; i < configuration.configs.Count; i++) | ||||
{ | { | ||||
Server server = configuration.configs[i]; | Server server = configuration.configs[i]; | ||||
MenuItem item = new MenuItem(string.IsNullOrEmpty(server.remarks) ? server.server + ":" + server.server_port : server.server + ":" + server.server_port + " (" + server.remarks + ")"); | |||||
MenuItem item = new MenuItem(server.FriendlyName()); | |||||
item.Tag = i; | item.Tag = i; | ||||
item.Click += AServerItem_Click; | item.Click += AServerItem_Click; | ||||
items.Add(item); | items.Add(item); | ||||
@@ -312,7 +372,7 @@ namespace Shadowsocks.View | |||||
private void Quit_Click(object sender, EventArgs e) | private void Quit_Click(object sender, EventArgs e) | ||||
{ | { | ||||
controller.Stop(); | controller.Stop(); | ||||
notifyIcon1.Visible = false; | |||||
_notifyIcon.Visible = false; | |||||
Application.Exit(); | Application.Exit(); | ||||
} | } | ||||
@@ -320,10 +380,10 @@ namespace Shadowsocks.View | |||||
{ | { | ||||
if (_isFirstRun) | if (_isFirstRun) | ||||
{ | { | ||||
notifyIcon1.BalloonTipTitle = "Shadowsocks is here"; | |||||
notifyIcon1.BalloonTipText = "You can turn on/off Shadowsocks in the context menu"; | |||||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||||
notifyIcon1.ShowBalloonTip(0); | |||||
_notifyIcon.BalloonTipTitle = I18N.GetString("Shadowsocks is here"); | |||||
_notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu"); | |||||
_notifyIcon.BalloonTipIcon = ToolTipIcon.Info; | |||||
_notifyIcon.ShowBalloonTip(0); | |||||
_isFirstRun = false; | _isFirstRun = false; | ||||
} | } | ||||
} | } | ||||
@@ -338,11 +398,19 @@ namespace Shadowsocks.View | |||||
ShowConfigForm(); | ShowConfigForm(); | ||||
} | } | ||||
private void EnableItem_Click(object sender, EventArgs e) | private void EnableItem_Click(object sender, EventArgs e) | ||||
{ | { | ||||
enableItem.Checked = !enableItem.Checked; | |||||
controller.ToggleEnable(enableItem.Checked); | |||||
controller.ToggleEnable(!enableItem.Checked); | |||||
} | |||||
private void GlobalModeItem_Click(object sender, EventArgs e) | |||||
{ | |||||
controller.ToggleGlobal(true); | |||||
} | |||||
private void PACModeItem_Click(object sender, EventArgs e) | |||||
{ | |||||
controller.ToggleGlobal(false); | |||||
} | } | ||||
private void ShareOverLANItem_Click(object sender, EventArgs e) | private void ShareOverLANItem_Click(object sender, EventArgs e) | ||||
@@ -29,49 +29,37 @@ | |||||
private void InitializeComponent() | private void InitializeComponent() | ||||
{ | { | ||||
this.pictureBox1 = new System.Windows.Forms.PictureBox(); | this.pictureBox1 = new System.Windows.Forms.PictureBox(); | ||||
this.panel1 = new System.Windows.Forms.Panel(); | |||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); | ||||
this.panel1.SuspendLayout(); | |||||
this.SuspendLayout(); | this.SuspendLayout(); | ||||
// | // | ||||
// pictureBox1 | // pictureBox1 | ||||
// | // | ||||
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; | |||||
this.pictureBox1.Location = new System.Drawing.Point(10, 10); | |||||
this.pictureBox1.Location = new System.Drawing.Point(9, 9); | |||||
this.pictureBox1.Margin = new System.Windows.Forms.Padding(0); | this.pictureBox1.Margin = new System.Windows.Forms.Padding(0); | ||||
this.pictureBox1.Name = "pictureBox1"; | this.pictureBox1.Name = "pictureBox1"; | ||||
this.pictureBox1.Size = new System.Drawing.Size(204, 202); | |||||
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; | |||||
this.pictureBox1.Size = new System.Drawing.Size(210, 210); | |||||
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; | |||||
this.pictureBox1.TabIndex = 1; | this.pictureBox1.TabIndex = 1; | ||||
this.pictureBox1.TabStop = false; | this.pictureBox1.TabStop = false; | ||||
// | // | ||||
// panel1 | |||||
// | |||||
this.panel1.Controls.Add(this.pictureBox1); | |||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; | |||||
this.panel1.Location = new System.Drawing.Point(0, 0); | |||||
this.panel1.Margin = new System.Windows.Forms.Padding(0); | |||||
this.panel1.Name = "panel1"; | |||||
this.panel1.Padding = new System.Windows.Forms.Padding(10); | |||||
this.panel1.Size = new System.Drawing.Size(224, 222); | |||||
this.panel1.TabIndex = 2; | |||||
// | |||||
// QRCodeForm | // QRCodeForm | ||||
// | // | ||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); | |||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |||||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); | |||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; | |||||
this.AutoSize = true; | |||||
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; | |||||
this.BackColor = System.Drawing.Color.White; | this.BackColor = System.Drawing.Color.White; | ||||
this.ClientSize = new System.Drawing.Size(224, 222); | |||||
this.Controls.Add(this.panel1); | |||||
this.ClientSize = new System.Drawing.Size(338, 274); | |||||
this.Controls.Add(this.pictureBox1); | |||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; | ||||
this.MaximizeBox = false; | this.MaximizeBox = false; | ||||
this.MinimizeBox = false; | this.MinimizeBox = false; | ||||
this.Name = "QRCodeForm"; | this.Name = "QRCodeForm"; | ||||
this.Padding = new System.Windows.Forms.Padding(9); | |||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; | ||||
this.Text = "QRCode"; | this.Text = "QRCode"; | ||||
this.Load += new System.EventHandler(this.QRCodeForm_Load); | this.Load += new System.EventHandler(this.QRCodeForm_Load); | ||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); | ||||
this.panel1.ResumeLayout(false); | |||||
this.ResumeLayout(false); | this.ResumeLayout(false); | ||||
} | } | ||||
@@ -79,6 +67,5 @@ | |||||
#endregion | #endregion | ||||
private System.Windows.Forms.PictureBox pictureBox1; | private System.Windows.Forms.PictureBox pictureBox1; | ||||
private System.Windows.Forms.Panel panel1; | |||||
} | } | ||||
} | } |
@@ -1,4 +1,5 @@ | |||||
using QRCode4CS; | using QRCode4CS; | ||||
using Shadowsocks.Controller; | |||||
using Shadowsocks.Properties; | using Shadowsocks.Properties; | ||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
@@ -21,6 +22,7 @@ namespace Shadowsocks.View | |||||
this.code = code; | this.code = code; | ||||
InitializeComponent(); | InitializeComponent(); | ||||
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | ||||
this.Text = I18N.GetString("QRCode"); | |||||
} | } | ||||
private void GenQR(string ssconfig) | private void GenQR(string ssconfig) | ||||
@@ -73,12 +73,16 @@ | |||||
<Compile Include="3rd\SimpleJson.cs" /> | <Compile Include="3rd\SimpleJson.cs" /> | ||||
<Compile Include="Controller\AutoStartup.cs" /> | <Compile Include="Controller\AutoStartup.cs" /> | ||||
<Compile Include="Controller\FileManager.cs" /> | <Compile Include="Controller\FileManager.cs" /> | ||||
<Compile Include="Controller\I18N.cs" /> | |||||
<Compile Include="Controller\Logging.cs" /> | <Compile Include="Controller\Logging.cs" /> | ||||
<Compile Include="Controller\UpdateChecker.cs" /> | <Compile Include="Controller\UpdateChecker.cs" /> | ||||
<Compile Include="Encrypt\EncryptorBase.cs" /> | <Compile Include="Encrypt\EncryptorBase.cs" /> | ||||
<Compile Include="Encrypt\EncryptorFactory.cs" /> | <Compile Include="Encrypt\EncryptorFactory.cs" /> | ||||
<Compile Include="Encrypt\IVEncryptor.cs" /> | |||||
<Compile Include="Encrypt\PolarSSL.cs" /> | <Compile Include="Encrypt\PolarSSL.cs" /> | ||||
<Compile Include="Encrypt\PolarSSLEncryptor.cs" /> | <Compile Include="Encrypt\PolarSSLEncryptor.cs" /> | ||||
<Compile Include="Encrypt\Sodium.cs" /> | |||||
<Compile Include="Encrypt\SodiumEncryptor.cs" /> | |||||
<Compile Include="Encrypt\TableEncryptor.cs" /> | <Compile Include="Encrypt\TableEncryptor.cs" /> | ||||
<Compile Include="Encrypt\IEncryptor.cs" /> | <Compile Include="Encrypt\IEncryptor.cs" /> | ||||
<Compile Include="Controller\PACServer.cs" /> | <Compile Include="Controller\PACServer.cs" /> | ||||
@@ -125,7 +129,7 @@ | |||||
<None Include="app.manifest"> | <None Include="app.manifest"> | ||||
<SubType>Designer</SubType> | <SubType>Designer</SubType> | ||||
</None> | </None> | ||||
<None Include="Data\polarssl.dll.gz" /> | |||||
<None Include="Data\libsscrypto.dll.gz" /> | |||||
<None Include="Data\polipo.exe.gz" /> | <None Include="Data\polipo.exe.gz" /> | ||||
<None Include="Properties\Settings.settings"> | <None Include="Properties\Settings.settings"> | ||||
<Generator>SettingsSingleFileGenerator</Generator> | <Generator>SettingsSingleFileGenerator</Generator> | ||||
@@ -143,6 +147,7 @@ | |||||
<None Include="Resources\ss16.png" /> | <None Include="Resources\ss16.png" /> | ||||
<None Include="Resources\ss24.png" /> | <None Include="Resources\ss24.png" /> | ||||
<None Include="Resources\ssw128.png" /> | <None Include="Resources\ssw128.png" /> | ||||
<Content Include="Data\cn.txt" /> | |||||
<Content Include="shadowsocks.ico" /> | <Content Include="shadowsocks.ico" /> | ||||
<None Include="Data\polipo_config.txt" /> | <None Include="Data\polipo_config.txt" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -22,15 +22,50 @@ namespace test | |||||
Assert.IsTrue(UpdateChecker.CompareVersion("1.3.2", "1.3.1") > 0); | Assert.IsTrue(UpdateChecker.CompareVersion("1.3.2", "1.3.1") > 0); | ||||
} | } | ||||
private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) | |||||
{ | |||||
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; | |||||
var random = new Random(); | |||||
random.NextBytes(plain); | |||||
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]); | |||||
} | |||||
} | |||||
private static bool encryptionFailed = false; | |||||
private static object locker = new object(); | |||||
[TestMethod] | [TestMethod] | ||||
public void TestEncryption() | |||||
public void TestPolarSSLEncryption() | |||||
{ | { | ||||
// run it once before the multi-threading test to initialize global tables | // run it once before the multi-threading test to initialize global tables | ||||
RunSingleEncryptionThread(); | |||||
RunSinglePolarSSLEncryptionThread(); | |||||
List<Thread> threads = new List<Thread>(); | List<Thread> threads = new List<Thread>(); | ||||
for (int i = 0; i < 10; i++) | for (int i = 0; i < 10; i++) | ||||
{ | { | ||||
Thread t = new Thread(new ThreadStart(RunSingleEncryptionThread)); | |||||
Thread t = new Thread(new ThreadStart(RunSinglePolarSSLEncryptionThread)); | |||||
threads.Add(t); | threads.Add(t); | ||||
t.Start(); | t.Start(); | ||||
} | } | ||||
@@ -41,51 +76,98 @@ namespace test | |||||
Assert.IsFalse(encryptionFailed); | Assert.IsFalse(encryptionFailed); | ||||
} | } | ||||
private static bool encryptionFailed = false; | |||||
private static object locker = new object(); | |||||
private void RunSinglePolarSSLEncryptionThread() | |||||
{ | |||||
try | |||||
{ | |||||
for (int i = 0; i < 100; i++) | |||||
{ | |||||
IEncryptor encryptor; | |||||
IEncryptor decryptor; | |||||
encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); | |||||
decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!"); | |||||
RunEncryptionRound(encryptor, decryptor); | |||||
} | |||||
} | |||||
catch | |||||
{ | |||||
encryptionFailed = true; | |||||
throw; | |||||
} | |||||
} | |||||
[TestMethod] | |||||
public void TestRC4Encryption() | |||||
{ | |||||
// run it once before the multi-threading test to initialize global tables | |||||
RunSingleRC4EncryptionThread(); | |||||
List<Thread> threads = new List<Thread>(); | |||||
for (int i = 0; i < 10; i++) | |||||
{ | |||||
Thread t = new Thread(new ThreadStart(RunSingleRC4EncryptionThread)); | |||||
threads.Add(t); | |||||
t.Start(); | |||||
} | |||||
foreach (Thread t in threads) | |||||
{ | |||||
t.Join(); | |||||
} | |||||
Assert.IsFalse(encryptionFailed); | |||||
} | |||||
private void RunSingleRC4EncryptionThread() | |||||
{ | |||||
try | |||||
{ | |||||
for (int i = 0; i < 100; i++) | |||||
{ | |||||
var random = new Random(); | |||||
IEncryptor encryptor; | |||||
IEncryptor decryptor; | |||||
encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!"); | |||||
decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!"); | |||||
RunEncryptionRound(encryptor, decryptor); | |||||
} | |||||
} | |||||
catch | |||||
{ | |||||
encryptionFailed = true; | |||||
throw; | |||||
} | |||||
} | |||||
[TestMethod] | |||||
public void TestSodiumEncryption() | |||||
{ | |||||
// run it once before the multi-threading test to initialize global tables | |||||
RunSingleSodiumEncryptionThread(); | |||||
List<Thread> threads = new List<Thread>(); | |||||
for (int i = 0; i < 10; i++) | |||||
{ | |||||
Thread t = new Thread(new ThreadStart(RunSingleSodiumEncryptionThread)); | |||||
threads.Add(t); | |||||
t.Start(); | |||||
} | |||||
foreach (Thread t in threads) | |||||
{ | |||||
t.Join(); | |||||
} | |||||
Assert.IsFalse(encryptionFailed); | |||||
} | |||||
private void RunSingleEncryptionThread() | |||||
private void RunSingleSodiumEncryptionThread() | |||||
{ | { | ||||
try | try | ||||
{ | { | ||||
for (int i = 0; i < 100; 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]); | |||||
} | |||||
//} | |||||
} | |||||
for (int i = 0; i < 100; i++) | |||||
{ | |||||
var random = new Random(); | |||||
IEncryptor encryptor; | |||||
IEncryptor decryptor; | |||||
encryptor = new SodiumEncryptor("salsa20", "barfoo!"); | |||||
decryptor = new SodiumEncryptor("salsa20", "barfoo!"); | |||||
RunEncryptionRound(encryptor, decryptor); | |||||
} | |||||
} | } | ||||
catch | catch | ||||
{ | { | ||||