Browse Source

Merge branch 'master' into feature/statistics_ui

tags/3.0
icylogic 9 years ago
parent
commit
4684af053e
25 changed files with 880 additions and 298 deletions
  1. +5
    -4
      shadowsocks-csharp/Controller/Service/TCPRelay.cs
  2. +6
    -6
      shadowsocks-csharp/Controller/Service/UDPRelay.cs
  3. +147
    -72
      shadowsocks-csharp/Controller/Service/UpdateChecker.cs
  4. +13
    -1
      shadowsocks-csharp/Controller/ShadowsocksController.cs
  5. +12
    -5
      shadowsocks-csharp/Data/cn.txt
  6. BIN
      shadowsocks-csharp/Data/libsscrypto.dll.gz
  7. +5
    -1
      shadowsocks-csharp/Encryption/EncryptorBase.cs
  8. +3
    -3
      shadowsocks-csharp/Encryption/EncryptorFactory.cs
  9. +127
    -3
      shadowsocks-csharp/Encryption/IVEncryptor.cs
  10. +2
    -2
      shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs
  11. +9
    -3
      shadowsocks-csharp/Encryption/Sodium.cs
  12. +2
    -2
      shadowsocks-csharp/Encryption/SodiumEncryptor.cs
  13. +2
    -2
      shadowsocks-csharp/Encryption/TableEncryptor.cs
  14. +3
    -0
      shadowsocks-csharp/Model/Configuration.cs
  15. +80
    -0
      shadowsocks-csharp/Model/LogViewerConfig.cs
  16. +5
    -0
      shadowsocks-csharp/Model/Server.cs
  17. +38
    -40
      shadowsocks-csharp/Properties/Resources.Designer.cs
  18. +70
    -55
      shadowsocks-csharp/View/ConfigForm.Designer.cs
  19. +17
    -1
      shadowsocks-csharp/View/ConfigForm.cs
  20. +112
    -51
      shadowsocks-csharp/View/LogForm.Designer.cs
  21. +154
    -19
      shadowsocks-csharp/View/LogForm.cs
  22. +1
    -4
      shadowsocks-csharp/View/LogForm.resx
  23. +52
    -10
      shadowsocks-csharp/View/MenuViewController.cs
  24. +1
    -0
      shadowsocks-csharp/shadowsocks-csharp.csproj
  25. +14
    -14
      test/UnitTest.cs

+ 5
- 4
shadowsocks-csharp/Controller/Service/TCPRelay.cs View File

@@ -93,17 +93,18 @@ namespace Shadowsocks.Controller
private int _firstPacketLength;
// Size of receive buffer.
public const int RecvSize = 8192;
public const int BufferSize = RecvSize + 32;
public const int RecvReserveSize = IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES; // reserve for one-time auth
public const int BufferSize = RecvSize + RecvReserveSize + 32;
private int totalRead = 0;
private int totalWrite = 0;
// remote receive buffer
private byte[] remoteRecvBuffer = new byte[RecvSize];
private byte[] remoteRecvBuffer = new byte[BufferSize];
// remote send buffer
private byte[] remoteSendBuffer = new byte[BufferSize];
// connection receive buffer
private byte[] connetionRecvBuffer = new byte[RecvSize];
private byte[] connetionRecvBuffer = new byte[BufferSize];
// connection send buffer
private byte[] connetionSendBuffer = new byte[BufferSize];
// Received data string.
@@ -124,7 +125,7 @@ namespace Shadowsocks.Controller
{
throw new ArgumentException("No server configured");
}
this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password);
this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.one_time_auth, false);
this.server = server;
}


+ 6
- 6
shadowsocks-csharp/Controller/Service/UDPRelay.cs View File

@@ -74,13 +74,13 @@ namespace Shadowsocks.Controller
}
public void Send(byte[] data, int length)
{
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password);
byte[] dataIn = new byte[length - 3];
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth, true);
byte[] dataIn = new byte[length - 3 + IVEncryptor.ONETIMEAUTH_BYTES];
Array.Copy(data, 3, dataIn, 0, length - 3);
byte[] dataOut = new byte[length - 3 + 16];
byte[] dataOut = new byte[length - 3 + 16 + IVEncryptor.ONETIMEAUTH_BYTES];
int outlen;
encryptor.Encrypt(dataIn, dataIn.Length, dataOut, out outlen);
_remote.SendTo(dataOut, _remoteEndPoint);
encryptor.Encrypt(dataIn, length - 3, dataOut, out outlen);
_remote.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint);
}
public void Receive()
{
@@ -97,7 +97,7 @@ namespace Shadowsocks.Controller
byte[] dataOut = new byte[bytesRead];
int outlen;
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password);
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth, true);
encryptor.Decrypt(_buffer, bytesRead, dataOut, out outlen);
byte[] sendBuf = new byte[outlen + 3];


+ 147
- 72
shadowsocks-csharp/Controller/Service/UpdateChecker.cs View File

@@ -1,137 +1,212 @@
using Shadowsocks.Model;
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using SimpleJson;
using Shadowsocks.Model;
using Shadowsocks.Util;
namespace Shadowsocks.Controller
{
public class UpdateChecker
{
private const string UpdateURL = "https://api.github.com/repos/shadowsocks/shadowsocks-windows/releases";
private const string UserAgent = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36";
private Configuration config;
public bool NewVersionFound;
public string LatestVersionNumber;
public string LatestVersionName;
public string LatestVersionURL;
public event EventHandler NewVersionFound;
public string LatestVersionLocalName;
public event EventHandler CheckUpdateCompleted;
public const string Version = "2.5.8";
public void CheckUpdate(Configuration config)
{
// TODO test failures
WebClient http = new WebClient();
http.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36");
http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort);
http.DownloadStringCompleted += http_DownloadStringCompleted;
http.DownloadStringAsync(new Uri(UpdateURL));
this.config = config;
try
{
WebClient http = CreateWebClient();
http.DownloadStringCompleted += http_DownloadStringCompleted;
http.DownloadStringAsync(new Uri(UpdateURL));
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
}
}
public static int CompareVersion(string l, string r)
private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
var ls = l.Split('.');
var rs = r.Split('.');
for (int i = 0; i < Math.Max(ls.Length, rs.Length); i++)
try
{
int lp = (i < ls.Length) ? int.Parse(ls[i]) : 0;
int rp = (i < rs.Length) ? int.Parse(rs[i]) : 0;
if (lp != rp)
string response = e.Result;
JsonArray result = (JsonArray)SimpleJson.SimpleJson.DeserializeObject(e.Result);
List<Asset> asserts = new List<Asset>();
foreach (JsonObject release in result)
{
if ((bool)release["prerelease"])
{
continue;
}
foreach (JsonObject asset in (JsonArray)release["assets"])
{
Asset ass = new Asset();
ass.Parse(asset);
if (ass.IsNewVersion(Version))
{
asserts.Add(ass);
}
}
}
if (asserts.Count != 0)
{
return lp - rp;
SortByVersions(asserts);
Asset asset = asserts[asserts.Count - 1];
NewVersionFound = true;
LatestVersionURL = asset.browser_download_url;
LatestVersionNumber = asset.version;
LatestVersionName = asset.name;
startDownload();
}
else if (CheckUpdateCompleted != null)
{
CheckUpdateCompleted(this, new EventArgs());
}
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
}
return 0;
}
public class VersionComparer : IComparer<string>
private void startDownload()
{
// Calls CaseInsensitiveComparer.Compare with the parameters reversed.
public int Compare(string x, string y)
try
{
return CompareVersion(ParseVersionFromURL(x), ParseVersionFromURL(y));
string temppath = Utils.GetTempPath();
LatestVersionLocalName = Path.Combine(temppath, LatestVersionName);
WebClient http = CreateWebClient();
http.DownloadFileCompleted += Http_DownloadFileCompleted;
http.DownloadFileAsync(new Uri(LatestVersionURL), LatestVersionLocalName);
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
}
}
private static string ParseVersionFromURL(string url)
private void Http_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase);
if (match.Success)
try
{
if (match.Groups.Count == 2)
if(e.Error != null)
{
Logging.LogUsefulException(e.Error);
return;
}
if (CheckUpdateCompleted != null)
{
return match.Groups[1].Value;
CheckUpdateCompleted(this, new EventArgs());
}
}
return null;
catch (Exception ex)
{
Logging.LogUsefulException(ex);
}
}
private void SortVersions(List<string> versions)
private WebClient CreateWebClient()
{
versions.Sort(new VersionComparer());
WebClient http = new WebClient();
http.Headers.Add("User-Agent", UserAgent);
http.Proxy = new WebProxy(IPAddress.Loopback.ToString(), config.localPort);
return http;
}
private bool IsNewVersion(string url)
private void SortByVersions(List<Asset> asserts)
{
if (url.IndexOf("prerelease") >= 0)
{
return false;
}
string version = ParseVersionFromURL(url);
if (version == null)
{
return false;
}
string currentVersion = Version;
return CompareVersion(version, currentVersion) > 0;
asserts.Sort(new VersionComparer());
}
private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
public class Asset
{
try
public bool prerelease;
public string name;
public string version;
public string browser_download_url;
public bool IsNewVersion(string currentVersion)
{
string response = e.Result;
if (prerelease)
{
return false;
}
if (version == null)
{
return false;
}
return CompareVersion(version, currentVersion) > 0;
}
JsonArray result = (JsonArray)SimpleJson.SimpleJson.DeserializeObject(e.Result);
public void Parse(JsonObject asset)
{
name = (string)asset["name"];
browser_download_url = (string)asset["browser_download_url"];
version = ParseVersionFromURL(browser_download_url);
prerelease = browser_download_url.IndexOf("prerelease") >= 0;
}
List<string> versions = new List<string>();
foreach (JsonObject release in result)
private static string ParseVersionFromURL(string url)
{
Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase);
if (match.Success)
{
if ((bool)release["prerelease"])
if (match.Groups.Count == 2)
{
continue;
}
foreach (JsonObject asset in (JsonArray)release["assets"])
{
string url = (string)asset["browser_download_url"];
if (IsNewVersion(url))
{
versions.Add(url);
}
return match.Groups[1].Value;
}
}
return null;
}
if (versions.Count == 0)
{
return;
}
// sort versions
SortVersions(versions);
LatestVersionURL = versions[versions.Count - 1];
LatestVersionNumber = ParseVersionFromURL(LatestVersionURL);
if (NewVersionFound != null)
public static int CompareVersion(string l, string r)
{
var ls = l.Split('.');
var rs = r.Split('.');
for (int i = 0; i < Math.Max(ls.Length, rs.Length); i++)
{
NewVersionFound(this, new EventArgs());
int lp = (i < ls.Length) ? int.Parse(ls[i]) : 0;
int rp = (i < rs.Length) ? int.Parse(rs[i]) : 0;
if (lp != rp)
{
return lp - rp;
}
}
return 0;
}
catch (Exception ex)
}
class VersionComparer : IComparer<Asset>
{
// Calls CaseInsensitiveComparer.Compare with the parameters reversed.
public int Compare(Asset x, Asset y)
{
Logging.Debug(ex.ToString());
return;
return Asset.CompareVersion(x.version, y.version);
}
}
}
}

+ 13
- 1
shadowsocks-csharp/Controller/ShadowsocksController.cs View File

@@ -126,7 +126,7 @@ namespace Shadowsocks.Controller
{
_config.configs = servers;
_config.localPort = localPort;
SaveConfig(_config);
Configuration.Save(_config);
}
public void SaveStrategyConfigurations(StatisticsStrategyConfiguration configuration)
@@ -288,6 +288,18 @@ namespace Shadowsocks.Controller
}
}
public void ToggleCheckingUpdate(bool enabled)
{
_config.autoCheckUpdate = enabled;
Configuration.Save(_config);
}
public void SaveLogViewerConfig(LogViewerConfig newConfig)
{
_config.logViewer = newConfig;
Configuration.Save(_config);
}
protected void Reload()
{
// some logic in configuration updated the config when saving, we need to read it again


+ 12
- 5
shadowsocks-csharp/Data/cn.txt View File

@@ -21,6 +21,9 @@ Show QRCode...=显示二维码...
Scan QRCode from Screen...=扫描屏幕上的二维码...
Availability Statistics=统计可用性
Show Logs...=显示日志...
Updates...=更新...
Check for Updates...=检查更新
Check for Updates at Startup=启动时检查更新
About...=关于...
Quit=退出
Edit Servers=编辑服务器
@@ -39,6 +42,7 @@ Password=密码
Encryption=加密
Proxy Port=代理端口
Remarks=备注
Onetime Authentication (Experimental)=一次性认证(实验性)
OK=确定
Cancel=取消
New server=未配置的服务器
@@ -50,10 +54,12 @@ Move D&own=下移(&O)
&File=文件(&F)
&Open Location=在资源管理器中打开(&O)
E&xit=退出(&X)
&Clean logs=清空(&C)
&Font=字体(&F)
&Wrap text=自动换行(&W)
&Top most=置顶(&T)
&View=视图(&V)
&Clean Logs=清空日志(&C)
Change &Font=设置字体(&F)
&Wrap Text=自动换行(&W)
&Top Most=置顶(&T)
&Show Toolbar=显示工具栏(&S)
Log Viewer=日志查看器

# QRCode Form
@@ -77,7 +83,8 @@ Password can not be blank=密码不能为空
Port out of range=端口超出范围
Port can't be 8123=端口不能为 8123
Shadowsocks {0} Update Found=Shadowsocks {0} 更新
Click here to download=点击这里下载
No update is available=没有可用的更新
Click here to update=点击这里升级
Shadowsocks is here=Shadowsocks 在这里
You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks
System Proxy Enabled=系统代理已启用


BIN
shadowsocks-csharp/Data/libsscrypto.dll.gz View File


+ 5
- 1
shadowsocks-csharp/Encryption/EncryptorBase.cs View File

@@ -8,14 +8,18 @@ namespace Shadowsocks.Encryption
{
public const int MAX_INPUT_SIZE = 32768;
protected EncryptorBase(string method, string password)
protected EncryptorBase(string method, string password, bool onetimeauth, bool isudp)
{
Method = method;
Password = password;
OnetimeAuth = onetimeauth;
IsUDP = isudp;
}
protected string Method;
protected string Password;
protected bool OnetimeAuth;
protected bool IsUDP;
protected byte[] GetPasswordHash()
{


+ 3
- 3
shadowsocks-csharp/Encryption/EncryptorFactory.cs View File

@@ -8,7 +8,7 @@ namespace Shadowsocks.Encryption
{
private static Dictionary<string, Type> _registeredEncryptors;
private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string) };
private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string), typeof(bool), typeof(bool) };
static EncryptorFactory()
{
@@ -27,7 +27,7 @@ namespace Shadowsocks.Encryption
}
}
public static IEncryptor GetEncryptor(string method, string password)
public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth, bool isudp)
{
if (string.IsNullOrEmpty(method))
{
@@ -36,7 +36,7 @@ namespace Shadowsocks.Encryption
method = method.ToLowerInvariant();
Type t = _registeredEncryptors[method];
ConstructorInfo c = t.GetConstructor(_constructorTypes);
IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password });
IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password, onetimeauth, isudp });
return result;
}
}


+ 127
- 3
shadowsocks-csharp/Encryption/IVEncryptor.cs View File

@@ -2,12 +2,24 @@
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Net;
namespace Shadowsocks.Encryption
{
public abstract class IVEncryptor
: EncryptorBase
{
public const int MAX_KEY_LENGTH = 64;
public const int MAX_IV_LENGTH = 16;
public const int ONETIMEAUTH_FLAG = 0x10;
public const int ADDRTYPE_MASK = 0xF;
public const int ONETIMEAUTH_BYTES = 10;
public const int CLEN_BYTES = 2;
public const int AUTH_BYTES = ONETIMEAUTH_BYTES + CLEN_BYTES;
protected static byte[] tempbuf = new byte[MAX_INPUT_SIZE];
protected Dictionary<string, int[]> ciphers;
@@ -25,9 +37,11 @@ namespace Shadowsocks.Encryption
protected byte[] _key;
protected int keyLen;
protected int ivLen;
protected uint counter = 0;
protected byte[] _keyBuffer = null;
public IVEncryptor(string method, string password)
: base(method, password)
public IVEncryptor(string method, string password, bool onetimeauth, bool isudp)
: base(method, password, onetimeauth, isudp)
{
InitKey(method, password);
}
@@ -112,14 +126,122 @@ namespace Shadowsocks.Encryption
protected abstract void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf);
protected int getHeadLen(byte[] buf, int length)
{
int len = 0;
int atyp = length > 0 ? (buf[0] & ADDRTYPE_MASK) : 0;
if (atyp == 1)
{
len = 7; // atyp (1 bytes) + ipv4 (4 bytes) + port (2 bytes)
}
else if (atyp == 3 && length > 1)
{
int nameLen = buf[1];
len = 4 + nameLen; // atyp (1 bytes) + name length (1 bytes) + name (n bytes) + port (2 bytes)
}
else if (atyp == 4)
{
len = 19; // atyp (1 bytes) + ipv6 (16 bytes) + port (2 bytes)
}
if (len == 0 || len > length)
throw new Exception($"invalid header with addr type {atyp}");
return len;
}
protected byte[] genOnetimeAuthHash(byte[] msg, int msg_len)
{
byte[] auth = new byte[ONETIMEAUTH_BYTES];
byte[] hash = new byte[20];
byte[] auth_key = new byte[MAX_IV_LENGTH + MAX_KEY_LENGTH];
Buffer.BlockCopy(_encryptIV, 0, auth_key, 0, ivLen);
Buffer.BlockCopy(_key, 0, auth_key, ivLen, keyLen);
Sodium.ss_sha1_hmac_ex(auth_key, (uint)(ivLen + keyLen),
msg, 0, (uint)msg_len, hash);
Buffer.BlockCopy(hash, 0, auth, 0, ONETIMEAUTH_BYTES);
return auth;
}
protected void updateKeyBuffer()
{
if (_keyBuffer == null)
{
_keyBuffer = new byte[MAX_IV_LENGTH + 4];
Buffer.BlockCopy(_encryptIV, 0, _keyBuffer, 0, ivLen);
}
byte[] counter_bytes = BitConverter.GetBytes((uint)IPAddress.HostToNetworkOrder((int)counter));
Buffer.BlockCopy(counter_bytes, 0, _keyBuffer, ivLen, 4);
counter++;
}
protected byte[] genHash(byte[] buf, int offset, int len)
{
byte[] hash = new byte[20];
updateKeyBuffer();
Sodium.ss_sha1_hmac_ex(_keyBuffer, (uint)_keyBuffer.Length,
buf, offset, (uint)len, hash);
return hash;
}
protected void reactBuffer4TCP(byte[] buf, ref int length)
{
if (!_encryptIVSent)
{
int headLen = getHeadLen(buf, length);
int dataLen = length - headLen;
buf[0] |= ONETIMEAUTH_FLAG;
byte[] hash = genOnetimeAuthHash(buf, headLen);
Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen);
Buffer.BlockCopy(hash, 0, buf, headLen, ONETIMEAUTH_BYTES);
hash = genHash(buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen);
Buffer.BlockCopy(hash, 0, buf, headLen + ONETIMEAUTH_BYTES + CLEN_BYTES, ONETIMEAUTH_BYTES);
byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)dataLen));
Buffer.BlockCopy(lenBytes, 0, buf, headLen + ONETIMEAUTH_BYTES, CLEN_BYTES);
length = headLen + ONETIMEAUTH_BYTES + AUTH_BYTES + dataLen;
}
else
{
byte[] hash = genHash(buf, 0, length);
Buffer.BlockCopy(buf, 0, buf, AUTH_BYTES, length);
byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)length));
Buffer.BlockCopy(lenBytes, 0, buf, 0, CLEN_BYTES);
Buffer.BlockCopy(hash, 0, buf, CLEN_BYTES, ONETIMEAUTH_BYTES);
length += AUTH_BYTES;
}
}
protected void reactBuffer4UDP(byte[] buf, ref int length)
{
buf[0] |= ONETIMEAUTH_FLAG;
byte[] hash = genOnetimeAuthHash(buf, length);
Buffer.BlockCopy(hash, 0, buf, length, ONETIMEAUTH_BYTES);
length += ONETIMEAUTH_BYTES;
}
protected void reactBuffer(byte[] buf, ref int length)
{
if (OnetimeAuth && ivLen > 0)
{
if (!IsUDP)
{
reactBuffer4TCP(buf, ref length);
}
else
{
reactBuffer4UDP(buf, ref length);
}
}
}
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;
reactBuffer(buf, ref length);
_encryptIVSent = true;
lock (tempbuf)
{
cipherUpdate(true, length, buf, tempbuf);
@@ -129,6 +251,7 @@ namespace Shadowsocks.Encryption
}
else
{
reactBuffer(buf, ref length);
outlength = length;
cipherUpdate(true, length, buf, outbuf);
}
@@ -154,5 +277,6 @@ namespace Shadowsocks.Encryption
cipherUpdate(false, length, buf, outbuf);
}
}
}
}

+ 2
- 2
shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs View File

@@ -16,8 +16,8 @@ namespace Shadowsocks.Encryption
private IntPtr _encryptCtx = IntPtr.Zero;
private IntPtr _decryptCtx = IntPtr.Zero;
public PolarSSLEncryptor(string method, string password)
: base(method, password)
public PolarSSLEncryptor(string method, string password, bool onetimeauth, bool isudp)
: base(method, password, onetimeauth, isudp)
{
InitKey(method, password);
}


+ 9
- 3
shadowsocks-csharp/Encryption/Sodium.cs View File

@@ -20,7 +20,6 @@ namespace Shadowsocks.Encryption
try
{
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
LoadLibrary(dllPath);
}
catch (IOException)
{
@@ -36,9 +35,16 @@ namespace Shadowsocks.Encryption
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);
public extern static int 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);
public extern static int crypto_stream_chacha20_xor_ic(byte[] c, byte[] m, ulong mlen, byte[] n, ulong ic, byte[] k);
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static void ss_sha1_hmac_ex(byte[] key, uint keylen,
byte[] input, int ioff, uint ilen,
byte[] output);
}
}

+ 2
- 2
shadowsocks-csharp/Encryption/SodiumEncryptor.cs View File

@@ -20,8 +20,8 @@ namespace Shadowsocks.Encryption
protected ulong _encryptIC;
protected ulong _decryptIC;
public SodiumEncryptor(string method, string password)
: base(method, password)
public SodiumEncryptor(string method, string password, bool onetimeauth, bool isudp)
: base(method, password, onetimeauth, isudp)
{
InitKey(method, password);
}


+ 2
- 2
shadowsocks-csharp/Encryption/TableEncryptor.cs View File

@@ -6,8 +6,8 @@ namespace Shadowsocks.Encryption
public class TableEncryptor
: EncryptorBase
{
public TableEncryptor(string method, string password)
: base(method, password)
public TableEncryptor(string method, string password, bool onetimeauth, bool isudp)
: base(method, password, onetimeauth, isudp)
{
byte[] hash = GetPasswordHash();
// TODO endian


+ 3
- 0
shadowsocks-csharp/Model/Configuration.cs View File

@@ -24,6 +24,8 @@ namespace Shadowsocks.Model
public string pacUrl;
public bool useOnlinePac;
public bool availabilityStatistics;
public bool autoCheckUpdate;
public LogViewerConfig logViewer;
private static string CONFIG_FILE = "gui-config.json";
@@ -77,6 +79,7 @@ namespace Shadowsocks.Model
index = 0,
isDefault = true,
localPort = 1080,
autoCheckUpdate = true,
configs = new List<Server>()
{
GetDefaultServer()


+ 80
- 0
shadowsocks-csharp/Model/LogViewerConfig.cs View File

@@ -0,0 +1,80 @@
using System;
using System.Drawing;
namespace Shadowsocks.Model
{
[Serializable]
public class LogViewerConfig
{
public string fontName;
public float fontSize;
public string bgColor;
public string textColor;
public bool topMost;
public bool wrapText;
public bool toolbarShown;
public LogViewerConfig()
{
this.fontName = "Consolas";
this.fontSize = 8;
this.bgColor = "black";
this.textColor = "white";
this.topMost = false;
this.wrapText = false;
this.toolbarShown = false;
}
public Font GetFont()
{
try
{
return new Font(fontName, fontSize, FontStyle.Regular);
}
catch (Exception)
{
return new Font("Console", 8F);
}
}
public void SetFont(Font font)
{
fontName = font.Name;
fontSize = font.Size;
}
public Color GetBackgroundColor()
{
try
{
return ColorTranslator.FromHtml(bgColor);
}
catch (Exception)
{
return ColorTranslator.FromHtml("black");
}
}
public void SetBackgroundColor(Color color)
{
bgColor = ColorTranslator.ToHtml(color);
}
public Color GetTextColor()
{
try
{
return ColorTranslator.FromHtml(textColor);
}
catch (Exception)
{
return ColorTranslator.FromHtml("white");
}
}
public void SetTextColor(Color color)
{
textColor = ColorTranslator.ToHtml(color);
}
}
}

+ 5
- 0
shadowsocks-csharp/Model/Server.cs View File

@@ -17,6 +17,7 @@ namespace Shadowsocks.Model
public string password;
public string method;
public string remarks;
public bool one_time_auth;
public override int GetHashCode()
{
@@ -52,6 +53,7 @@ namespace Shadowsocks.Model
this.method = "aes-256-cfb";
this.password = "";
this.remarks = "";
this.one_time_auth = false;
}
public Server(string ssURL) : this()
@@ -88,6 +90,9 @@ namespace Shadowsocks.Model
string[] parts = beforeAt.Split(new[] { ':' });
this.method = parts[0];
this.password = parts[1];
//TODO: read one_time_auth
}
catch (IndexOutOfRangeException)
{


+ 38
- 40
shadowsocks-csharp/Properties/Resources.Designer.cs View File

@@ -10,8 +10,8 @@
namespace Shadowsocks.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@@ -31,7 +31,7 @@ namespace Shadowsocks.Properties {
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
@@ -45,7 +45,7 @@ namespace Shadowsocks.Properties {
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
@@ -59,7 +59,7 @@ namespace Shadowsocks.Properties {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
@@ -69,39 +69,37 @@ namespace Shadowsocks.Properties {
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized string similar to # translation for Simplified Chinese
///
///Shadowsocks=Shadowsocks
///
///# Menu items
///
///Enable System Proxy=启用系统代理
///Mode=系统代理模式
///PAC=PAC 模式
///Global=全局模式
///Servers=服务器
///Edit Servers...=编辑服务器...
///Start on Boot=开机启动
///Allow Clients from LAN=允许来自局域网的连接
///Local PAC=使用本地 PAC
///Online PAC=使用在线 PAC
///Edit Local PAC File...=编辑本地 PAC 文件...
///Update Local PAC from GFWList=从 GFWList 更新本地 PAC
///Edit User Rule for GFWList...=编辑 GFWList 的用户规则...
///Show QRCode...=显示二维码...
///Scan QRCode from Screen...=扫描屏幕上的二维码...
///Show Logs...=显示日志...
///About...=关于...
///Quit=退出 [rest of string was truncated]&quot;;.
/// Looks up a localized string similar to # translation for Simplified Chinese
///
///Shadowsocks=Shadowsocks
///
///# Menu items
///
///Enable System Proxy=启用系统代理
///Mode=系统代理模式
///PAC=PAC 模式
///Global=全局模式
///Servers=服务器
///Edit Servers...=编辑服务器...
///Start on Boot=开机启动
///Allow Clients from LAN=允许来自局域网的连接
///Local PAC=使用本地 PAC
///Online PAC=使用在线 PAC
///Edit Local PAC File...=编辑本地 PAC 文件...
///Update Local PAC from GFWList=从 GFWList 更新本地 PAC
///Edit User Rule for GFWList...=编辑 GFWList 的用户规则...
///Show QRCode...=显示二维码...
///Scan QRCode from Screen...=扫描屏幕上的二维码...
///Availability Statistic [rest of string was truncated]&quot;;.
/// </summary>
internal static string cn {
get {
return ResourceManager.GetString("cn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
@@ -111,7 +109,7 @@ namespace Shadowsocks.Properties {
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
@@ -121,7 +119,7 @@ namespace Shadowsocks.Properties {
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized string similar to listen-address __POLIPO_BIND_IP__:8123
///show-on-task-bar 0
@@ -134,7 +132,7 @@ namespace Shadowsocks.Properties {
return ResourceManager.GetString("privoxy_conf", resourceCulture);
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
@@ -144,7 +142,7 @@ namespace Shadowsocks.Properties {
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
@@ -154,7 +152,7 @@ namespace Shadowsocks.Properties {
return ((byte[])(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@@ -164,7 +162,7 @@ namespace Shadowsocks.Properties {
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@@ -174,7 +172,7 @@ namespace Shadowsocks.Properties {
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@@ -184,7 +182,7 @@ namespace Shadowsocks.Properties {
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@@ -194,7 +192,7 @@ namespace Shadowsocks.Properties {
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized string similar to ! Put user rules line by line in this file.
///! See https://adblockplus.org/en/filter-cheatsheet


+ 70
- 55
shadowsocks-csharp/View/ConfigForm.Designer.cs View File

@@ -3,14 +3,14 @@
partial class ConfigForm
{
/// <summary>
/// 必需的设计器变量。
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
@@ -20,11 +20,11 @@
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
#region Windows Form Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
@@ -39,6 +39,7 @@
this.PasswordTextBox = new System.Windows.Forms.TextBox();
this.EncryptionLabel = new System.Windows.Forms.Label();
this.EncryptionSelect = new System.Windows.Forms.ComboBox();
this.OneTimeAuth = new System.Windows.Forms.CheckBox();
this.panel2 = new System.Windows.Forms.Panel();
this.OKButton = new System.Windows.Forms.Button();
this.MyCancelButton = new System.Windows.Forms.Button();
@@ -81,37 +82,39 @@
this.tableLayoutPanel1.Controls.Add(this.PasswordTextBox, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.EncryptionLabel, 0, 3);
this.tableLayoutPanel1.Controls.Add(this.EncryptionSelect, 1, 3);
this.tableLayoutPanel1.Controls.Add(this.OneTimeAuth, 1, 6);
this.tableLayoutPanel1.Location = new System.Drawing.Point(8, 21);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(3);
this.tableLayoutPanel1.RowCount = 6;
this.tableLayoutPanel1.RowCount = 7;
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(238, 137);
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(249, 162);
this.tableLayoutPanel1.TabIndex = 0;
//
// RemarksTextBox
//
this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.RemarksTextBox.Location = new System.Drawing.Point(72, 111);
this.RemarksTextBox.Location = new System.Drawing.Point(83, 113);
this.RemarksTextBox.MaxLength = 32;
this.RemarksTextBox.Name = "RemarksTextBox";
this.RemarksTextBox.Size = new System.Drawing.Size(160, 20);
this.RemarksTextBox.TabIndex = 10;
this.RemarksTextBox.Size = new System.Drawing.Size(160, 21);
this.RemarksTextBox.TabIndex = 4;
this.RemarksTextBox.WordWrap = false;
//
// RemarksLabel
//
this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.RemarksLabel.AutoSize = true;
this.RemarksLabel.Location = new System.Drawing.Point(17, 114);
this.RemarksLabel.Location = new System.Drawing.Point(30, 117);
this.RemarksLabel.Name = "RemarksLabel";
this.RemarksLabel.Size = new System.Drawing.Size(49, 13);
this.RemarksLabel.Size = new System.Drawing.Size(47, 12);
this.RemarksLabel.TabIndex = 9;
this.RemarksLabel.Text = "Remarks";
//
@@ -119,9 +122,9 @@
//
this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.IPLabel.AutoSize = true;
this.IPLabel.Location = new System.Drawing.Point(15, 9);
this.IPLabel.Location = new System.Drawing.Point(18, 10);
this.IPLabel.Name = "IPLabel";
this.IPLabel.Size = new System.Drawing.Size(51, 13);
this.IPLabel.Size = new System.Drawing.Size(59, 12);
this.IPLabel.TabIndex = 0;
this.IPLabel.Text = "Server IP";
//
@@ -129,9 +132,9 @@
//
this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.ServerPortLabel.AutoSize = true;
this.ServerPortLabel.Location = new System.Drawing.Point(6, 35);
this.ServerPortLabel.Location = new System.Drawing.Point(6, 37);
this.ServerPortLabel.Name = "ServerPortLabel";
this.ServerPortLabel.Size = new System.Drawing.Size(60, 13);
this.ServerPortLabel.Size = new System.Drawing.Size(71, 12);
this.ServerPortLabel.TabIndex = 1;
this.ServerPortLabel.Text = "Server Port";
//
@@ -139,40 +142,40 @@
//
this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.PasswordLabel.AutoSize = true;
this.PasswordLabel.Location = new System.Drawing.Point(13, 61);
this.PasswordLabel.Location = new System.Drawing.Point(24, 64);
this.PasswordLabel.Name = "PasswordLabel";
this.PasswordLabel.Size = new System.Drawing.Size(53, 13);
this.PasswordLabel.Size = new System.Drawing.Size(53, 12);
this.PasswordLabel.TabIndex = 2;
this.PasswordLabel.Text = "Password";
//
// IPTextBox
//
this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.IPTextBox.Location = new System.Drawing.Point(72, 6);
this.IPTextBox.Location = new System.Drawing.Point(83, 6);
this.IPTextBox.MaxLength = 512;
this.IPTextBox.Name = "IPTextBox";
this.IPTextBox.Size = new System.Drawing.Size(160, 20);
this.IPTextBox.Size = new System.Drawing.Size(160, 21);
this.IPTextBox.TabIndex = 0;
this.IPTextBox.WordWrap = false;
//
// ServerPortTextBox
//
this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.ServerPortTextBox.Location = new System.Drawing.Point(72, 32);
this.ServerPortTextBox.Location = new System.Drawing.Point(83, 33);
this.ServerPortTextBox.MaxLength = 10;
this.ServerPortTextBox.Name = "ServerPortTextBox";
this.ServerPortTextBox.Size = new System.Drawing.Size(160, 20);
this.ServerPortTextBox.Size = new System.Drawing.Size(160, 21);
this.ServerPortTextBox.TabIndex = 1;
this.ServerPortTextBox.WordWrap = false;
//
// PasswordTextBox
//
this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.PasswordTextBox.Location = new System.Drawing.Point(72, 58);
this.PasswordTextBox.Location = new System.Drawing.Point(83, 60);
this.PasswordTextBox.MaxLength = 256;
this.PasswordTextBox.Name = "PasswordTextBox";
this.PasswordTextBox.PasswordChar = '*';
this.PasswordTextBox.Size = new System.Drawing.Size(160, 20);
this.PasswordTextBox.Size = new System.Drawing.Size(160, 21);
this.PasswordTextBox.TabIndex = 2;
this.PasswordTextBox.WordWrap = false;
//
@@ -180,20 +183,20 @@
//
this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.EncryptionLabel.AutoSize = true;
this.EncryptionLabel.Location = new System.Drawing.Point(9, 88);
this.EncryptionLabel.Location = new System.Drawing.Point(12, 91);
this.EncryptionLabel.Name = "EncryptionLabel";
this.EncryptionLabel.Size = new System.Drawing.Size(57, 13);
this.EncryptionLabel.Size = new System.Drawing.Size(65, 12);
this.EncryptionLabel.TabIndex = 8;
this.EncryptionLabel.Text = "Encryption";
//
// EncryptionSelect
//
this.EncryptionSelect.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
this.EncryptionSelect.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.EncryptionSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.EncryptionSelect.FormattingEnabled = true;
this.EncryptionSelect.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.EncryptionSelect.ItemHeight = 13;
this.EncryptionSelect.ItemHeight = 12;
this.EncryptionSelect.Items.AddRange(new object[] {
"table",
"rc4-md5",
@@ -203,10 +206,21 @@
"aes-192-cfb",
"aes-128-cfb",
"rc4"});
this.EncryptionSelect.Location = new System.Drawing.Point(72, 84);
this.EncryptionSelect.Location = new System.Drawing.Point(83, 87);
this.EncryptionSelect.Name = "EncryptionSelect";
this.EncryptionSelect.Size = new System.Drawing.Size(160, 21);
this.EncryptionSelect.Size = new System.Drawing.Size(160, 20);
this.EncryptionSelect.TabIndex = 3;
this.EncryptionSelect.SelectedIndexChanged += new System.EventHandler(this.EncryptionSelect_SelectedIndexChanged);
//
// OneTimeAuth
//
this.OneTimeAuth.AutoSize = true;
this.OneTimeAuth.Location = new System.Drawing.Point(83, 140);
this.OneTimeAuth.Name = "OneTimeAuth";
this.OneTimeAuth.Size = new System.Drawing.Size(156, 16);
this.OneTimeAuth.TabIndex = 5;
this.OneTimeAuth.Text = "Onetime Authentication";
this.OneTimeAuth.UseVisualStyleBackColor = true;
//
// panel2
//
@@ -226,7 +240,7 @@
this.OKButton.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0);
this.OKButton.Name = "OKButton";
this.OKButton.Size = new System.Drawing.Size(75, 23);
this.OKButton.TabIndex = 8;
this.OKButton.TabIndex = 12;
this.OKButton.Text = "OK";
this.OKButton.UseVisualStyleBackColor = true;
this.OKButton.Click += new System.EventHandler(this.OKButton_Click);
@@ -239,7 +253,7 @@
this.MyCancelButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0);
this.MyCancelButton.Name = "MyCancelButton";
this.MyCancelButton.Size = new System.Drawing.Size(75, 23);
this.MyCancelButton.TabIndex = 9;
this.MyCancelButton.TabIndex = 13;
this.MyCancelButton.Text = "Cancel";
this.MyCancelButton.UseVisualStyleBackColor = true;
this.MyCancelButton.Click += new System.EventHandler(this.CancelButton_Click);
@@ -251,7 +265,7 @@
this.DeleteButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3);
this.DeleteButton.Name = "DeleteButton";
this.DeleteButton.Size = new System.Drawing.Size(80, 23);
this.DeleteButton.TabIndex = 7;
this.DeleteButton.TabIndex = 9;
this.DeleteButton.Text = "&Delete";
this.DeleteButton.UseVisualStyleBackColor = true;
this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click);
@@ -263,7 +277,7 @@
this.AddButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3);
this.AddButton.Name = "AddButton";
this.AddButton.Size = new System.Drawing.Size(80, 23);
this.AddButton.TabIndex = 6;
this.AddButton.TabIndex = 8;
this.AddButton.Text = "&Add";
this.AddButton.UseVisualStyleBackColor = true;
this.AddButton.Click += new System.EventHandler(this.AddButton_Click);
@@ -276,8 +290,8 @@
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.Size = new System.Drawing.Size(249, 174);
this.ServerGroupBox.TabIndex = 6;
this.ServerGroupBox.Size = new System.Drawing.Size(260, 200);
this.ServerGroupBox.TabIndex = 0;
this.ServerGroupBox.TabStop = false;
this.ServerGroupBox.Text = "Server";
//
@@ -290,7 +304,7 @@
this.ServersListBox.Margin = new System.Windows.Forms.Padding(0);
this.ServersListBox.Name = "ServersListBox";
this.ServersListBox.Size = new System.Drawing.Size(166, 148);
this.ServersListBox.TabIndex = 5;
this.ServersListBox.TabIndex = 7;
this.ServersListBox.SelectedIndexChanged += new System.EventHandler(this.ServersListBox_SelectedIndexChanged);
//
// tableLayoutPanel2
@@ -313,7 +327,7 @@
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, 238);
this.tableLayoutPanel2.Size = new System.Drawing.Size(438, 265);
this.tableLayoutPanel2.TabIndex = 7;
//
// tableLayoutPanel6
@@ -326,7 +340,7 @@
this.tableLayoutPanel6.Controls.Add(this.MoveDownButton, 1, 0);
this.tableLayoutPanel6.Controls.Add(this.MoveUpButton, 0, 0);
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Top;
this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 211);
this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 233);
this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
this.tableLayoutPanel6.RowCount = 1;
@@ -341,7 +355,7 @@
this.MoveDownButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3);
this.MoveDownButton.Name = "MoveDownButton";
this.MoveDownButton.Size = new System.Drawing.Size(80, 23);
this.MoveDownButton.TabIndex = 7;
this.MoveDownButton.TabIndex = 11;
this.MoveDownButton.Text = "Move D&own";
this.MoveDownButton.UseVisualStyleBackColor = true;
this.MoveDownButton.Click += new System.EventHandler(this.MoveDownButton_Click);
@@ -353,7 +367,7 @@
this.MoveUpButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3);
this.MoveUpButton.Name = "MoveUpButton";
this.MoveUpButton.Size = new System.Drawing.Size(80, 23);
this.MoveUpButton.TabIndex = 6;
this.MoveUpButton.TabIndex = 10;
this.MoveUpButton.Text = "Move &Up";
this.MoveUpButton.UseVisualStyleBackColor = true;
this.MoveUpButton.Click += new System.EventHandler(this.MoveUpButton_Click);
@@ -369,36 +383,36 @@
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel5.Controls.Add(this.ProxyPortTextBox, 1, 0);
this.tableLayoutPanel5.Controls.Add(this.ProxyPortLabel, 0, 0);
this.tableLayoutPanel5.Location = new System.Drawing.Point(241, 174);
this.tableLayoutPanel5.Location = new System.Drawing.Point(242, 200);
this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
this.tableLayoutPanel5.Padding = new System.Windows.Forms.Padding(3);
this.tableLayoutPanel5.RowCount = 1;
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26F));
this.tableLayoutPanel5.Size = new System.Drawing.Size(186, 32);
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 27F));
this.tableLayoutPanel5.Size = new System.Drawing.Size(196, 33);
this.tableLayoutPanel5.TabIndex = 9;
//
// ProxyPortTextBox
//
this.ProxyPortTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.ProxyPortTextBox.Location = new System.Drawing.Point(67, 6);
this.ProxyPortTextBox.Location = new System.Drawing.Point(77, 6);
this.ProxyPortTextBox.MaxLength = 10;
this.ProxyPortTextBox.Name = "ProxyPortTextBox";
this.ProxyPortTextBox.Size = new System.Drawing.Size(113, 20);
this.ProxyPortTextBox.TabIndex = 4;
this.ProxyPortTextBox.Size = new System.Drawing.Size(113, 21);
this.ProxyPortTextBox.TabIndex = 6;
this.ProxyPortTextBox.WordWrap = false;
//
// ProxyPortLabel
//
this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.ProxyPortLabel.AutoSize = true;
this.ProxyPortLabel.Location = new System.Drawing.Point(6, 9);
this.ProxyPortLabel.Location = new System.Drawing.Point(6, 10);
this.ProxyPortLabel.Name = "ProxyPortLabel";
this.ProxyPortLabel.Size = new System.Drawing.Size(55, 13);
this.ProxyPortLabel.Size = new System.Drawing.Size(65, 12);
this.ProxyPortLabel.TabIndex = 3;
this.ProxyPortLabel.Text = "Proxy Port";
//
@@ -413,7 +427,7 @@
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, 209);
this.tableLayoutPanel3.Location = new System.Drawing.Point(279, 236);
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 1;
@@ -431,7 +445,7 @@
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, 174);
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;
@@ -505,6 +519,7 @@
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6;
private System.Windows.Forms.Button MoveDownButton;
private System.Windows.Forms.Button MoveUpButton;
private System.Windows.Forms.CheckBox OneTimeAuth;
}
}

+ 17
- 1
shadowsocks-csharp/View/ConfigForm.cs View File

@@ -48,6 +48,7 @@ namespace Shadowsocks.View
EncryptionLabel.Text = I18N.GetString("Encryption");
ProxyPortLabel.Text = I18N.GetString("Proxy Port");
RemarksLabel.Text = I18N.GetString("Remarks");
OneTimeAuth.Text = I18N.GetString("Onetime Authentication (Experimental)");
ServerGroupBox.Text = I18N.GetString("Server");
OKButton.Text = I18N.GetString("OK");
MyCancelButton.Text = I18N.GetString("Cancel");
@@ -82,7 +83,8 @@ namespace Shadowsocks.View
server_port = int.Parse(ServerPortTextBox.Text),
password = PasswordTextBox.Text,
method = EncryptionSelect.Text,
remarks = RemarksTextBox.Text
remarks = RemarksTextBox.Text,
one_time_auth = OneTimeAuth.Checked
};
int localPort = int.Parse(ProxyPortTextBox.Text);
Configuration.CheckServer(server);
@@ -115,6 +117,7 @@ namespace Shadowsocks.View
ProxyPortTextBox.Text = _modifiedConfiguration.localPort.ToString();
EncryptionSelect.Text = server.method ?? "aes-256-cfb";
RemarksTextBox.Text = server.remarks;
OneTimeAuth.Checked = server.one_time_auth;
}
}
@@ -319,5 +322,18 @@ namespace Shadowsocks.View
MoveConfigItem(+1); // +1 means move forward
}
}
private void EncryptionSelect_SelectedIndexChanged(object sender, EventArgs e)
{
if (EncryptionSelect.Text == "rc4" || EncryptionSelect.Text == "table")
{
OneTimeAuth.Enabled = false;
OneTimeAuth.Checked = false;
}
else
{
OneTimeAuth.Enabled = true;
}
}
}
}

+ 112
- 51
shadowsocks-csharp/View/LogForm.Designer.cs View File

@@ -30,19 +30,25 @@
{
this.components = new System.ComponentModel.Container();
this.LogMessageTextBox = new System.Windows.Forms.TextBox();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components);
this.MainMenu = new System.Windows.Forms.MainMenu(this.components);
this.FileMenuItem = new System.Windows.Forms.MenuItem();
this.OpenLocationMenuItem = new System.Windows.Forms.MenuItem();
this.ExitMenuItem = new System.Windows.Forms.MenuItem();
this.panel1 = new System.Windows.Forms.Panel();
this.ViewMenuItem = new System.Windows.Forms.MenuItem();
this.CleanLogsMenuItem = new System.Windows.Forms.MenuItem();
this.ChangeFontMenuItem = new System.Windows.Forms.MenuItem();
this.WrapTextMenuItem = new System.Windows.Forms.MenuItem();
this.TopMostMenuItem = new System.Windows.Forms.MenuItem();
this.MenuItemSeparater = new System.Windows.Forms.MenuItem();
this.ShowToolbarMenuItem = new System.Windows.Forms.MenuItem();
this.TopMostCheckBox = new System.Windows.Forms.CheckBox();
this.ChangeFontButton = new System.Windows.Forms.Button();
this.CleanLogsButton = new System.Windows.Forms.Button();
this.WrapTextCheckBox = new System.Windows.Forms.CheckBox();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.TopMostCheckBox = new System.Windows.Forms.CheckBox();
this.panel1.SuspendLayout();
this.ToolbarFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
this.tableLayoutPanel1.SuspendLayout();
this.ToolbarFlowLayoutPanel.SuspendLayout();
this.SuspendLayout();
//
// LogMessageTextBox
@@ -51,25 +57,20 @@
this.LogMessageTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.LogMessageTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.LogMessageTextBox.ForeColor = System.Drawing.Color.White;
this.LogMessageTextBox.Location = new System.Drawing.Point(3, 43);
this.LogMessageTextBox.Location = new System.Drawing.Point(3, 38);
this.LogMessageTextBox.MaxLength = 2147483647;
this.LogMessageTextBox.Multiline = true;
this.LogMessageTextBox.Name = "LogMessageTextBox";
this.LogMessageTextBox.ReadOnly = true;
this.LogMessageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.LogMessageTextBox.Size = new System.Drawing.Size(541, 307);
this.LogMessageTextBox.Size = new System.Drawing.Size(584, 377);
this.LogMessageTextBox.TabIndex = 0;
this.LogMessageTextBox.WordWrap = false;
//
// contextMenuStrip1
//
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4);
//
// mainMenu1
// MainMenu
//
this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.FileMenuItem});
this.MainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.FileMenuItem,
this.ViewMenuItem});
//
// FileMenuItem
//
@@ -91,21 +92,70 @@
this.ExitMenuItem.Text = "E&xit";
this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click);
//
// panel1
// ViewMenuItem
//
this.ViewMenuItem.Index = 1;
this.ViewMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.CleanLogsMenuItem,
this.ChangeFontMenuItem,
this.WrapTextMenuItem,
this.TopMostMenuItem,
this.MenuItemSeparater,
this.ShowToolbarMenuItem});
this.ViewMenuItem.Text = "&View";
//
// CleanLogsMenuItem
//
this.CleanLogsMenuItem.Index = 0;
this.CleanLogsMenuItem.Text = "&Clean Logs";
this.CleanLogsMenuItem.Click += new System.EventHandler(this.CleanLogsMenuItem_Click);
//
// ChangeFontMenuItem
//
this.ChangeFontMenuItem.Index = 1;
this.ChangeFontMenuItem.Text = "Change &Font";
this.ChangeFontMenuItem.Click += new System.EventHandler(this.ChangeFontMenuItem_Click);
//
// WrapTextMenuItem
//
this.WrapTextMenuItem.Index = 2;
this.WrapTextMenuItem.Text = "&Wrap Text";
this.WrapTextMenuItem.Click += new System.EventHandler(this.WrapTextMenuItem_Click);
//
// TopMostMenuItem
//
this.TopMostMenuItem.Index = 3;
this.TopMostMenuItem.Text = "&Top Most";
this.TopMostMenuItem.Click += new System.EventHandler(this.TopMostMenuItem_Click);
//
// MenuItemSeparater
//
this.MenuItemSeparater.Index = 4;
this.MenuItemSeparater.Text = "-";
//
// ShowToolbarMenuItem
//
this.panel1.Controls.Add(this.TopMostCheckBox);
this.panel1.Controls.Add(this.ChangeFontButton);
this.panel1.Controls.Add(this.CleanLogsButton);
this.panel1.Controls.Add(this.WrapTextCheckBox);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(3, 3);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(541, 34);
this.panel1.TabIndex = 1;
this.ShowToolbarMenuItem.Index = 5;
this.ShowToolbarMenuItem.Text = "&Show Toolbar";
this.ShowToolbarMenuItem.Click += new System.EventHandler(this.ShowToolbarMenuItem_Click);
//
// TopMostCheckBox
//
this.TopMostCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.TopMostCheckBox.AutoSize = true;
this.TopMostCheckBox.Location = new System.Drawing.Point(249, 3);
this.TopMostCheckBox.Name = "TopMostCheckBox";
this.TopMostCheckBox.Size = new System.Drawing.Size(72, 23);
this.TopMostCheckBox.TabIndex = 3;
this.TopMostCheckBox.Text = "&Top Most";
this.TopMostCheckBox.UseVisualStyleBackColor = true;
this.TopMostCheckBox.CheckedChanged += new System.EventHandler(this.TopMostCheckBox_CheckedChanged);
//
// ChangeFontButton
//
this.ChangeFontButton.Location = new System.Drawing.Point(107, 4);
this.ChangeFontButton.AutoSize = true;
this.ChangeFontButton.Location = new System.Drawing.Point(84, 3);
this.ChangeFontButton.Name = "ChangeFontButton";
this.ChangeFontButton.Size = new System.Drawing.Size(75, 23);
this.ChangeFontButton.TabIndex = 2;
@@ -115,22 +165,25 @@
//
// CleanLogsButton
//
this.CleanLogsButton.Location = new System.Drawing.Point(9, 4);
this.CleanLogsButton.AutoSize = true;
this.CleanLogsButton.Location = new System.Drawing.Point(3, 3);
this.CleanLogsButton.Name = "CleanLogsButton";
this.CleanLogsButton.Size = new System.Drawing.Size(75, 23);
this.CleanLogsButton.TabIndex = 1;
this.CleanLogsButton.Text = "&Clean logs";
this.CleanLogsButton.Text = "&Clean Logs";
this.CleanLogsButton.UseVisualStyleBackColor = true;
this.CleanLogsButton.Click += new System.EventHandler(this.CleanLogsButton_Click);
//
// WrapTextCheckBox
//
this.WrapTextCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.WrapTextCheckBox.AutoSize = true;
this.WrapTextCheckBox.Location = new System.Drawing.Point(209, 9);
this.WrapTextCheckBox.Location = new System.Drawing.Point(165, 3);
this.WrapTextCheckBox.Name = "WrapTextCheckBox";
this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 16);
this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 23);
this.WrapTextCheckBox.TabIndex = 0;
this.WrapTextCheckBox.Text = "&Wrap text";
this.WrapTextCheckBox.Text = "&Wrap Text";
this.WrapTextCheckBox.UseVisualStyleBackColor = true;
this.WrapTextCheckBox.CheckedChanged += new System.EventHandler(this.WrapTextCheckBox_CheckedChanged);
//
@@ -138,45 +191,47 @@
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.panel1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.LogMessageTextBox, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.ToolbarFlowLayoutPanel, 0, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(547, 353);
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(590, 418);
this.tableLayoutPanel1.TabIndex = 2;
//
// TopMostCheckBox
// ToolbarFlowLayoutPanel
//
this.TopMostCheckBox.AutoSize = true;
this.TopMostCheckBox.Location = new System.Drawing.Point(311, 9);
this.TopMostCheckBox.Name = "TopMostCheckBox";
this.TopMostCheckBox.Size = new System.Drawing.Size(72, 16);
this.TopMostCheckBox.TabIndex = 3;
this.TopMostCheckBox.Text = "&Top most";
this.TopMostCheckBox.UseVisualStyleBackColor = true;
this.TopMostCheckBox.CheckedChanged += new System.EventHandler(this.TopMostCheckBox_CheckedChanged);
this.ToolbarFlowLayoutPanel.AutoSize = true;
this.ToolbarFlowLayoutPanel.Controls.Add(this.CleanLogsButton);
this.ToolbarFlowLayoutPanel.Controls.Add(this.ChangeFontButton);
this.ToolbarFlowLayoutPanel.Controls.Add(this.WrapTextCheckBox);
this.ToolbarFlowLayoutPanel.Controls.Add(this.TopMostCheckBox);
this.ToolbarFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.ToolbarFlowLayoutPanel.Location = new System.Drawing.Point(3, 3);
this.ToolbarFlowLayoutPanel.Name = "ToolbarFlowLayoutPanel";
this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(584, 29);
this.ToolbarFlowLayoutPanel.TabIndex = 2;
//
// LogForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(547, 353);
this.ClientSize = new System.Drawing.Size(590, 418);
this.Controls.Add(this.tableLayoutPanel1);
this.Menu = this.mainMenu1;
this.Menu = this.MainMenu;
this.Name = "LogForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Log Viewer";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.LogForm_FormClosing);
this.Load += new System.EventHandler(this.LogForm_Load);
this.Shown += new System.EventHandler(this.LogForm_Shown);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.ToolbarFlowLayoutPanel.ResumeLayout(false);
this.ToolbarFlowLayoutPanel.PerformLayout();
this.ResumeLayout(false);
}
@@ -184,16 +239,22 @@
#endregion
private System.Windows.Forms.TextBox LogMessageTextBox;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.MainMenu mainMenu1;
private System.Windows.Forms.MainMenu MainMenu;
private System.Windows.Forms.MenuItem FileMenuItem;
private System.Windows.Forms.MenuItem OpenLocationMenuItem;
private System.Windows.Forms.MenuItem ExitMenuItem;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.CheckBox WrapTextCheckBox;
private System.Windows.Forms.Button CleanLogsButton;
private System.Windows.Forms.Button ChangeFontButton;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.CheckBox TopMostCheckBox;
private System.Windows.Forms.MenuItem ViewMenuItem;
private System.Windows.Forms.MenuItem CleanLogsMenuItem;
private System.Windows.Forms.MenuItem ChangeFontMenuItem;
private System.Windows.Forms.MenuItem WrapTextMenuItem;
private System.Windows.Forms.MenuItem TopMostMenuItem;
private System.Windows.Forms.FlowLayoutPanel ToolbarFlowLayoutPanel;
private System.Windows.Forms.MenuItem MenuItemSeparater;
private System.Windows.Forms.MenuItem ShowToolbarMenuItem;
}
}

+ 154
- 19
shadowsocks-csharp/View/LogForm.cs View File

@@ -1,6 +1,4 @@
using Shadowsocks.Controller;
using Shadowsocks.Properties;
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
@@ -10,6 +8,10 @@ using System.Linq;
using System.Text;
using System.Windows.Forms;
using Shadowsocks.Controller;
using Shadowsocks.Properties;
using Shadowsocks.Model;
namespace Shadowsocks.View
{
public partial class LogForm : Form
@@ -18,13 +20,25 @@ namespace Shadowsocks.View
string filename;
Timer timer;
const int BACK_OFFSET = 65536;
ShadowsocksController controller;
public LogForm(string filename)
public LogForm(ShadowsocksController controller, string filename)
{
this.controller = controller;
this.filename = filename;
InitializeComponent();
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
LogViewerConfig config = controller.GetConfigurationCopy().logViewer;
if (config == null)
config = new LogViewerConfig();
topMostTrigger = config.topMost;
wrapTextTrigger = config.wrapText;
toolbarTrigger = config.toolbarShown;
LogMessageTextBox.BackColor = config.GetBackgroundColor();
LogMessageTextBox.ForeColor = config.GetTextColor();
LogMessageTextBox.Font = config.GetFont();
UpdateTexts();
}
@@ -33,10 +47,16 @@ namespace Shadowsocks.View
FileMenuItem.Text = I18N.GetString("&File");
OpenLocationMenuItem.Text = I18N.GetString("&Open Location");
ExitMenuItem.Text = I18N.GetString("E&xit");
CleanLogsButton.Text = I18N.GetString("&Clean logs");
ChangeFontButton.Text = I18N.GetString("&Font");
WrapTextCheckBox.Text = I18N.GetString("&Wrap text");
TopMostCheckBox.Text = I18N.GetString("&Top most");
CleanLogsButton.Text = I18N.GetString("&Clean Logs");
ChangeFontButton.Text = I18N.GetString("Change &Font");
WrapTextCheckBox.Text = I18N.GetString("&Wrap Text");
TopMostCheckBox.Text = I18N.GetString("&Top Most");
ViewMenuItem.Text = I18N.GetString("&View");
CleanLogsMenuItem.Text = I18N.GetString("&Clean Logs");
ChangeFontMenuItem.Text = I18N.GetString("Change &Font");
WrapTextMenuItem.Text = I18N.GetString("&Wrap Text");
TopMostMenuItem.Text = I18N.GetString("&Top Most");
ShowToolbarMenuItem.Text = I18N.GetString("&Show Toolbar");
this.Text = I18N.GetString("Log Viewer");
}
@@ -58,7 +78,7 @@ namespace Shadowsocks.View
string line = "";
while ((line = reader.ReadLine()) != null)
LogMessageTextBox.AppendText(line + "\r\n");
LogMessageTextBox.AppendText(line + Environment.NewLine);
LogMessageTextBox.ScrollToCaret();
@@ -78,7 +98,7 @@ namespace Shadowsocks.View
while ((line = reader.ReadLine()) != null)
{
changed = true;
LogMessageTextBox.AppendText(line + "\r\n");
LogMessageTextBox.AppendText(line + Environment.NewLine);
}
if (changed)
@@ -97,11 +117,31 @@ namespace Shadowsocks.View
timer.Interval = 300;
timer.Tick += Timer_Tick;
timer.Start();
topMostTriggerLock = true;
this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger;
topMostTriggerLock = false;
wrapTextTriggerLock = true;
LogMessageTextBox.WordWrap = WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger;
wrapTextTriggerLock = false;
ToolbarFlowLayoutPanel.Visible = ShowToolbarMenuItem.Checked = toolbarTrigger;
}
private void LogForm_FormClosing(object sender, FormClosingEventArgs e)
{
timer.Stop();
LogViewerConfig config = controller.GetConfigurationCopy().logViewer;
if (config == null)
config = new LogViewerConfig();
config.topMost = topMostTrigger;
config.wrapText = wrapTextTrigger;
config.toolbarShown = toolbarTrigger;
config.SetFont(LogMessageTextBox.Font);
config.SetBackgroundColor(LogMessageTextBox.BackColor);
config.SetTextColor(LogMessageTextBox.ForeColor);
controller.SaveLogViewerConfig(config);
}
private void OpenLocationMenuItem_Click(object sender, EventArgs e)
@@ -121,30 +161,125 @@ namespace Shadowsocks.View
LogMessageTextBox.ScrollToCaret();
}
private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e)
#region Clean up the content in LogMessageTextBox.
private void DoCleanLogs()
{
LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked;
LogMessageTextBox.ScrollToCaret();
LogMessageTextBox.Clear();
}
private void CleanLogsMenuItem_Click(object sender, EventArgs e)
{
DoCleanLogs();
}
private void CleanLogsButton_Click(object sender, EventArgs e)
{
LogMessageTextBox.Clear();
DoCleanLogs();
}
#endregion
#region Change the font settings applied in LogMessageTextBox.
private void DoChangeFont()
{
try
{
FontDialog fd = new FontDialog();
fd.Font = LogMessageTextBox.Font;
if (fd.ShowDialog() == DialogResult.OK)
{
LogMessageTextBox.Font = new Font(fd.Font.FontFamily, fd.Font.Size, fd.Font.Style);
}
}
catch (Exception ex)
{
Logging.LogUsefulException(ex);
MessageBox.Show(ex.Message);
}
}
private void ChangeFontMenuItem_Click(object sender, EventArgs e)
{
DoChangeFont();
}
private void ChangeFontButton_Click(object sender, EventArgs e)
{
FontDialog fd = new FontDialog();
fd.Font = LogMessageTextBox.Font;
if (fd.ShowDialog() == DialogResult.OK)
DoChangeFont();
}
#endregion
#region Trigger the log messages wrapable, or not.
bool wrapTextTrigger = false;
bool wrapTextTriggerLock = false;
private void TriggerWrapText()
{
wrapTextTriggerLock = true;
wrapTextTrigger = !wrapTextTrigger;
LogMessageTextBox.WordWrap = wrapTextTrigger;
LogMessageTextBox.ScrollToCaret();
WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger;
wrapTextTriggerLock = false;
}
private void WrapTextMenuItem_Click(object sender, EventArgs e)
{
if (!wrapTextTriggerLock)
{
LogMessageTextBox.Font = fd.Font;
TriggerWrapText();
}
}
private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (!wrapTextTriggerLock)
{
TriggerWrapText();
}
}
#endregion
#region Trigger this window top most, or not.
bool topMostTrigger = false;
bool topMostTriggerLock = false;
private void TriggerTopMost()
{
topMostTriggerLock = true;
topMostTrigger = !topMostTrigger;
this.TopMost = topMostTrigger;
TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger;
topMostTriggerLock = false;
}
private void TopMostCheckBox_CheckedChanged(object sender, EventArgs e)
{
this.TopMost = TopMostCheckBox.Checked;
if (!topMostTriggerLock)
{
TriggerTopMost();
}
}
private void TopMostMenuItem_Click(object sender, EventArgs e)
{
if (!topMostTriggerLock)
{
TriggerTopMost();
}
}
#endregion
private bool toolbarTrigger = false;
private void ShowToolbarMenuItem_Click(object sender, EventArgs e)
{
toolbarTrigger = !toolbarTrigger;
ToolbarFlowLayoutPanel.Visible = toolbarTrigger;
ShowToolbarMenuItem.Checked = toolbarTrigger;
}
}
}

+ 1
- 4
shadowsocks-csharp/View/LogForm.resx View File

@@ -117,10 +117,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="MainMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="mainMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>172, 17</value>
</metadata>
</root>

+ 52
- 10
shadowsocks-csharp/View/MenuViewController.cs View File

@@ -26,6 +26,7 @@ namespace Shadowsocks.View
private ContextMenu contextMenu1;
private bool _isFirstRun;
private bool _isStartupChecking;
private MenuItem enableItem;
private MenuItem modeItem;
private MenuItem AutoStartupItem;
@@ -41,6 +42,7 @@ namespace Shadowsocks.View
private MenuItem updateFromGFWListItem;
private MenuItem editGFWUserRuleItem;
private MenuItem editOnlinePACItem;
private MenuItem autoCheckUpdatesToggleItem;
private ConfigForm configForm;
private string _urlToOpen;
@@ -67,13 +69,19 @@ namespace Shadowsocks.View
_notifyIcon.MouseDoubleClick += notifyIcon1_DoubleClick;
this.updateChecker = new UpdateChecker();
updateChecker.NewVersionFound += updateChecker_NewVersionFound;
updateChecker.CheckUpdateCompleted += updateChecker_CheckUpdateCompleted;
LoadCurrentConfiguration();
updateChecker.CheckUpdate(controller.GetConfigurationCopy());
Configuration config = controller.GetConfigurationCopy();
if (controller.GetConfigurationCopy().isDefault)
if (config.autoCheckUpdate)
{
_isStartupChecking = true;
updateChecker.CheckUpdate(config);
}
if (config.isDefault)
{
_isFirstRun = true;
ShowConfigForm();
@@ -181,6 +189,11 @@ namespace Shadowsocks.View
this.ShareOverLANItem = CreateMenuItem("Allow Clients from LAN", new EventHandler(this.ShareOverLANItem_Click)),
new MenuItem("-"),
CreateMenuItem("Show Logs...", new EventHandler(this.ShowLogItem_Click)),
CreateMenuGroup("Updates...", new MenuItem[] {
CreateMenuItem("Check for Updates...", new EventHandler(this.checkUpdatesItem_Click)),
new MenuItem("-"),
this.autoCheckUpdatesToggleItem = CreateMenuItem("Check for Updates at Startup", new EventHandler(this.autoCheckUpdatesToggleItem_Click)),
}),
CreateMenuItem("About...", new EventHandler(this.AboutItem_Click)),
new MenuItem("-"),
CreateMenuItem("Quit", new EventHandler(this.Quit_Click))
@@ -238,17 +251,27 @@ namespace Shadowsocks.View
ShowBalloonTip(I18N.GetString("Shadowsocks"), result, ToolTipIcon.Info, 1000);
}
void updateChecker_NewVersionFound(object sender, EventArgs e)
void updateChecker_CheckUpdateCompleted(object sender, EventArgs e)
{
ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to download"), ToolTipIcon.Info, 5000);
_notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked;
_isFirstRun = false;
if (updateChecker.NewVersionFound)
{
ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000);
_notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked;
_isFirstRun = false;
}
else if (!_isStartupChecking)
{
ShowBalloonTip(I18N.GetString("Shadowsocks"), I18N.GetString("No update is available"), ToolTipIcon.Info, 5000);
_isFirstRun = false;
}
_isStartupChecking = false;
}
void notifyIcon1_BalloonTipClicked(object sender, EventArgs e)
{
System.Diagnostics.Process.Start(updateChecker.LatestVersionURL);
_notifyIcon.BalloonTipClicked -= notifyIcon1_BalloonTipClicked;
string argument = "/select, \"" + updateChecker.LatestVersionLocalName + "\"";
System.Diagnostics.Process.Start("explorer.exe", argument);
}
@@ -265,6 +288,7 @@ namespace Shadowsocks.View
onlinePACItem.Checked = onlinePACItem.Enabled && config.useOnlinePac;
localPACItem.Checked = !onlinePACItem.Checked;
UpdatePACItemsEnabledStatus();
UpdateUpdateMenu();
}
private void UpdateServersMenu()
@@ -342,7 +366,7 @@ namespace Shadowsocks.View
if (_isFirstRun)
{
_notifyIcon.BalloonTipTitle = I18N.GetString("Shadowsocks is here");
_notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu");
_notifyIcon.BalloonTipText = I18N.GetString("You can turn on/off Shadowsocks in the context menu");
_notifyIcon.BalloonTipIcon = ToolTipIcon.Info;
_notifyIcon.ShowBalloonTip(0);
_isFirstRun = false;
@@ -414,7 +438,7 @@ namespace Shadowsocks.View
{
string argument = Logging.LogFile;
new LogForm(argument).Show();
new LogForm(controller, argument).Show();
}
private void StatisticsConfigItem_Click(object sender, EventArgs e)
@@ -591,5 +615,23 @@ namespace Shadowsocks.View
this.editOnlinePACItem.Enabled = true;
}
}
private void UpdateUpdateMenu()
{
Configuration configuration = controller.GetConfigurationCopy();
autoCheckUpdatesToggleItem.Checked = configuration.autoCheckUpdate;
}
private void autoCheckUpdatesToggleItem_Click(object sender, EventArgs e)
{
Configuration configuration = controller.GetConfigurationCopy();
controller.ToggleCheckingUpdate(!configuration.autoCheckUpdate);
UpdateUpdateMenu();
}
private void checkUpdatesItem_Click(object sender, EventArgs e)
{
updateChecker.CheckUpdate(controller.GetConfigurationCopy());
}
}
}

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

@@ -191,6 +191,7 @@
<Compile Include="Encryption\TableEncryptor.cs" />
<Compile Include="Encryption\IEncryptor.cs" />
<Compile Include="Controller\Service\PACServer.cs" />
<Compile Include="Model\LogViewerConfig.cs" />
<Compile Include="Model\Server.cs" />
<Compile Include="Model\Configuration.cs" />
<Compile Include="Model\StatisticsStrategyConfiguration.cs" />


+ 14
- 14
test/UnitTest.cs View File

@@ -13,19 +13,19 @@ namespace test
[TestMethod]
public void TestCompareVersion()
{
Assert.IsTrue(UpdateChecker.CompareVersion("2.3.1.0", "2.3.1") == 0);
Assert.IsTrue(UpdateChecker.CompareVersion("1.2", "1.3") < 0);
Assert.IsTrue(UpdateChecker.CompareVersion("1.3", "1.2") > 0);
Assert.IsTrue(UpdateChecker.CompareVersion("1.3", "1.3") == 0);
Assert.IsTrue(UpdateChecker.CompareVersion("1.2.1", "1.2") > 0);
Assert.IsTrue(UpdateChecker.CompareVersion("2.3.1", "2.4") < 0);
Assert.IsTrue(UpdateChecker.CompareVersion("1.3.2", "1.3.1") > 0);
Assert.IsTrue(UpdateChecker.Asset.CompareVersion("2.3.1.0", "2.3.1") == 0);
Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.2", "1.3") < 0);
Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3", "1.2") > 0);
Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.3", "1.3") == 0);
Assert.IsTrue(UpdateChecker.Asset.CompareVersion("1.2.1", "1.2") > 0);
Assert.IsTrue(UpdateChecker.Asset.CompareVersion("2.3.1", "2.4") < 0);
Assert.IsTrue(UpdateChecker.Asset.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[] cipher = new byte[plain.Length + 16 + IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES];
byte[] plain2 = new byte[plain.Length + 16];
int outLen = 0;
int outLen2 = 0;
@@ -84,8 +84,8 @@ namespace test
{
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!");
decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!");
encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false, false);
decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false, false);
RunEncryptionRound(encryptor, decryptor);
}
}
@@ -124,8 +124,8 @@ namespace test
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!");
decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!");
encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false, false);
decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false, false);
RunEncryptionRound(encryptor, decryptor);
}
}
@@ -164,8 +164,8 @@ namespace test
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new SodiumEncryptor("salsa20", "barfoo!");
decryptor = new SodiumEncryptor("salsa20", "barfoo!");
encryptor = new SodiumEncryptor("salsa20", "barfoo!", false, false);
decryptor = new SodiumEncryptor("salsa20", "barfoo!", false, false);
RunEncryptionRound(encryptor, decryptor);
}
}


Loading…
Cancel
Save