Compare commits

..
48 Commits
Author SHA1 Message Date
noisyfox 03c087db6d Update CHANGES and bump version 2016-12-16 12:39:47 +11:00
noisyfox 5741133d5c Fix compile error.
And farewell.
2016-12-16 12:25:14 +11:00
noisyfox 28954600a2 Revert "Rename Shadowsocks.Proxy -> Shadowsocks.ForwardProxy"
This reverts commit be3cc3f3a6.
2016-12-16 12:19:52 +11:00
noisyfox 6ddd3d486b Revert "Allow LineReader to start with a first package"
This reverts commit a61b10bb67.
2016-12-16 12:19:42 +11:00
noisyfox dd269ac89d Revert "Remove privoxy"
This reverts commit 0d4d01af3b.
2016-12-16 12:19:33 +11:00
noisyfox 09d89b424d Revert "First working built-in http proxy"
This reverts commit 5ba0dffa5d.
2016-12-16 12:19:26 +11:00
noisyfox 5e973adb77 Revert "Refine header parse"
This reverts commit f9e39fdd1d.
2016-12-16 12:19:18 +11:00
noisyfox f149851e3b Revert "Better host parse"
This reverts commit d1e8f38767.
2016-12-16 12:19:09 +11:00
noisyfox 511a658fd3 Revert "Reuse buffer from first pakcage"
This reverts commit f2b8e91f81.
2016-12-16 12:18:59 +11:00
noisyfox efe6d5ba81 Revert "http -> shadowsocks protocol directly"
This reverts commit b04c59d8e6.
2016-12-16 12:18:51 +11:00
noisyfox 1f47812eca Revert "Typo and refine code"
This reverts commit 9cdb71875a.
2016-12-16 12:18:41 +11:00
noisyfox 7a39c2c71f Revert "Logging exception"
This reverts commit 566a0fcfa5.
2016-12-16 12:18:25 +11:00
noisyfox dc48546fed Revert 2016-12-16 12:17:20 +11:00
noisyfox eef990f529 Check close before create reomte
Check null ref (#940)
2016-12-15 17:23:12 +11:00
noisyfox f66638d14c Don't check and throw exception in a display function. We should check this at input side. 2016-12-15 16:51:23 +11:00
noisyfox 0c055caffd Add the missing semicolon in global proxy bypass list 2016-12-14 22:20:11 +11:00
noisyfox efc486c733 Update CHANGES and bump version 2016-12-13 21:08:32 +11:00
noisyfox b7b92a4af9 Very rarely used regex, do not compile 2016-12-13 20:47:39 +11:00
noisyfox a447feece2 Adjust qrcode display 2016-12-13 20:43:51 +11:00
noisyfox 2a0dd88525 Add import URL from clipboard 2016-12-13 02:52:58 +11:00
noisyfox 5650b1d847 Use compiled regex 2016-12-13 02:42:08 +11:00
noisyfox b972cb250b Don't zoom QRCode 2016-12-13 02:31:01 +11:00
noisyfox f363b94fd6 Show ss URL in QRCode form 2016-12-13 02:22:37 +11:00
noisyfox a08993519f Handle request line correctlly
This coudl fix #937
2016-12-12 23:53:15 +11:00
noisyfox 8a68a3515b Check server url before saving it
Don't clear the textbox, focus it instead. We want the user to see the wrong input instead of a blank textbox.
2016-12-10 01:50:28 +11:00
noisyfox 76fbd808e3 Add menu item to copy local pac url 2016-12-10 01:26:40 +11:00
noisyfox 557c797a9a Refine code 2016-12-10 00:59:57 +11:00
noisyfox ac45b44c09 Update CHANGES and bump version 2016-12-09 17:59:05 +11:00
noisyfox c0299090c4 Merge branch 'proxy_dev' 2016-12-09 02:48:22 +11:00
noisyfox de4a2f862b Update global proxy bypass list 2016-12-09 02:47:12 +11:00
noisyfox 430137495c Always use {} 2016-12-09 02:36:33 +11:00
noisyfox 566a0fcfa5 Logging exception 2016-12-09 02:17:46 +11:00
noisyfox 2c15520230 Remove unnecessary volatile 2016-12-09 02:17:46 +11:00
noisyfox 9cdb71875a Typo and refine code 2016-12-09 02:17:46 +11:00
noisyfox b04c59d8e6 http -> shadowsocks protocol directly
No more http->socks5 transform.
2016-12-09 02:17:46 +11:00
noisyfox f2b8e91f81 Reuse buffer from first pakcage
Remove some debug output
2016-12-09 02:17:46 +11:00
noisyfox d1e8f38767 Better host parse 2016-12-09 02:17:46 +11:00
noisyfox f9e39fdd1d Refine header parse 2016-12-09 02:17:46 +11:00
noisyfox 5ba0dffa5d First working built-in http proxy 2016-12-09 02:17:46 +11:00
noisyfox 0d4d01af3b Remove privoxy 2016-12-09 02:17:46 +11:00
noisyfox a61b10bb67 Allow LineReader to start with a first package 2016-12-09 02:17:46 +11:00
noisyfox be3cc3f3a6 Rename Shadowsocks.Proxy -> Shadowsocks.ForwardProxy 2016-12-09 02:17:46 +11:00
noisyfox 5c5f753721 Use external agents to set system proxy.
This fix the proxy issue on win10 insider preview.
2016-12-09 02:15:29 +11:00
noisyfox 264b91d6b0 Fix a problem that forward proxy settings are saved twice
Fix #926
2016-12-09 02:05:42 +11:00
noisyfox 4b067346bf Refine random string generate. 2016-12-09 01:39:07 +11:00
noisyfox 9e51b4a41b Add translation 2016-12-08 19:01:07 +11:00
noisyfox 983c1adb28 Check secret in PACServer 2016-12-08 18:54:57 +11:00
noisyfox 22d8cdeff7 Add secret in local pac url. 2016-12-08 18:13:22 +11:00
30 changed files with 356 additions and 715 deletions
+19
View File
@@ -1,3 +1,22 @@
3.4.2 2016-12-16
- Fix null ref in TCPRelay. (#940)
- Bring Privoxy back. (#948)
- Bug fixes and improvements.
3.4.1 (pre-release) 2016-12-13
- Fix crash if user input an invaild server address. (#933)
- Fix ERR_TOO_MANY_REDIRECTS with http proxy. (#937)
- Show SS URL in QRCode form.
- Add import URL from clipboard.
- Bug fixes and improvements.
3.4.0 (pre-release) 2016-12-9
- Replace Privoxy with built-in http proxy.
- Try fix system proxy settings on windows 10 insider preview.
- Secure local pac.
- Update bypass list.
- Bug fixes and improvements.
3.3.6 2016-12-6
- Refine system proxy mode switching logic,
merge 'Switch to PAC' and 'Switch to Global' into
@@ -5,19 +5,23 @@ using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Shadowsocks.Encryption;
using Shadowsocks.Model;
using Shadowsocks.Properties;
using Shadowsocks.Util;
namespace Shadowsocks.Controller
{
class PACServer : Listener.Service
public class PACServer : Listener.Service
{
public const string PAC_FILE = "pac.txt";
public const string USER_RULE_FILE = "user-rule.txt";
public const string USER_ABP_FILE = "abp.txt";
private string PacSecret { get; set; } = "";
public string PacUrl { get; private set; } = "";
FileSystemWatcher PACFileWatcher;
FileSystemWatcher UserRuleFileWatcher;
private Configuration _config;
@@ -34,6 +38,25 @@ namespace Shadowsocks.Controller
public void UpdateConfiguration(Configuration config)
{
this._config = config;
if (config.secureLocalPac)
{
var rd = new byte[32];
RNG.GetBytes(rd);
PacSecret = $"&secret={Convert.ToBase64String(rd)}";
}
else
{
PacSecret = "";
}
PacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}{PacSecret}";
}
private static string GetTimestamp(DateTime value)
{
return value.ToString("yyyyMMddHHmmssfff");
}
public override bool Handle(byte[] firstPacket, int length, Socket socket, object state)
@@ -47,6 +70,7 @@ namespace Shadowsocks.Controller
string request = Encoding.UTF8.GetString(firstPacket, 0, length);
string[] lines = request.Split('\r', '\n');
bool hostMatch = false, pathMatch = false, useSocks = false;
bool secretMatch = PacSecret.IsNullOrEmpty();
foreach (string line in lines)
{
string[] kv = line.Split(new char[] { ':' }, 2);
@@ -74,11 +98,25 @@ namespace Shadowsocks.Controller
{
pathMatch = true;
}
if (!secretMatch)
{
if(line.IndexOf(PacSecret, StringComparison.Ordinal) >= 0)
{
secretMatch = true;
}
}
}
}
if (hostMatch && pathMatch)
{
SendResponse(firstPacket, length, socket, useSocks);
if (!secretMatch)
{
socket.Close(); // Close immediately
}
else
{
SendResponse(firstPacket, length, socket, useSocks);
}
return true;
}
return false;
@@ -230,16 +230,21 @@ namespace Shadowsocks.Controller
{
Logging.LogUsefulException(e);
}
try
if (_currentRemoteSession != null)
{
var remote = _currentRemoteSession.Remote;
remote.Shutdown(SocketShutdown.Both);
remote.Close();
}
catch (Exception e)
{
Logging.LogUsefulException(e);
try
{
var remote = _currentRemoteSession.Remote;
remote.Shutdown(SocketShutdown.Both);
remote.Close();
}
catch (Exception e)
{
Logging.LogUsefulException(e);
}
}
lock (_encryptionLock)
{
lock (_decryptionLock)
@@ -540,7 +545,16 @@ namespace Shadowsocks.Controller
}
var session = new AsyncSession(remote);
_currentRemoteSession = session;
lock (_closeConnLock)
{
if (_closed)
{
remote.Close();
return;
}
_currentRemoteSession = session;
}
ProxyTimer proxyTimer = new ProxyTimer(_proxyTimeout);
proxyTimer.AutoReset = false;
@@ -24,7 +24,7 @@ namespace Shadowsocks.Controller
public string LatestVersionLocalName;
public event EventHandler CheckUpdateCompleted;
public const string Version = "3.3.6";
public const string Version = "3.4.2";
private class CheckUpdateTimer : System.Timers.Timer
{
@@ -176,10 +176,10 @@ namespace Shadowsocks.Controller
private void SortByVersions(List<Asset> asserts)
{
asserts.Sort(new VersionComparer());
asserts.Sort();
}
public class Asset
public class Asset : IComparable<Asset>
{
public bool prerelease;
public string name;
@@ -243,14 +243,10 @@ namespace Shadowsocks.Controller
}
return 0;
}
}
class VersionComparer : IComparer<Asset>
{
// Calls CaseInsensitiveComparer.Compare with the parameters reversed.
public int Compare(Asset x, Asset y)
public int CompareTo(Asset other)
{
return Asset.CompareVersion(x.version, y.version);
return CompareVersion(version, other.version);
}
}
}
@@ -6,6 +6,7 @@ using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Web;
using System.Windows.Forms;
using Newtonsoft.Json;
using Shadowsocks.Controller.Strategy;
@@ -220,12 +221,13 @@ namespace Shadowsocks.Controller
SaveConfig(_config);
}
public void EnableProxy(int type, string proxy, int port)
public void EnableProxy(int type, string proxy, int port, int timeout)
{
_config.proxy.useProxy = true;
_config.proxy.proxyType = type;
_config.proxy.proxyServer = proxy;
_config.proxy.proxyPort = port;
_config.proxy.proxyTimeout = timeout;
SaveConfig(_config);
}
@@ -269,7 +271,7 @@ namespace Shadowsocks.Controller
}
if (_config.enabled)
{
SystemProxy.Update(_config, true);
SystemProxy.Update(_config, true, null);
}
Encryption.RNG.Close();
}
@@ -347,6 +349,16 @@ namespace Shadowsocks.Controller
}
}
public void ToggleSecureLocalPac(bool enabled)
{
_config.secureLocalPac = enabled;
SaveConfig(_config);
if (ConfigChanged != null)
{
ConfigChanged(this, new EventArgs());
}
}
public void ToggleCheckingUpdate(bool enabled)
{
_config.autoCheckUpdate = enabled;
@@ -378,16 +390,6 @@ namespace Shadowsocks.Controller
}
}
public void SaveProxyConfig(ProxyConfig newConfig)
{
_config.proxy = newConfig;
Configuration.Save(_config);
if (ConfigChanged != null)
{
ConfigChanged(this, new EventArgs());
}
}
public void SaveHotkeyConfig(HotkeyConfig newConfig)
{
_config.hotkey = newConfig;
@@ -515,7 +517,7 @@ namespace Shadowsocks.Controller
{
if (_config.enabled)
{
SystemProxy.Update(_config, false);
SystemProxy.Update(_config, false, _pacServer);
_systemProxyIsDirty = true;
}
else
@@ -523,7 +525,7 @@ namespace Shadowsocks.Controller
// only switch it off if we have switched it on
if (_systemProxyIsDirty)
{
SystemProxy.Update(_config, false);
SystemProxy.Update(_config, false, _pacServer);
_systemProxyIsDirty = false;
}
}
@@ -590,6 +592,11 @@ namespace Shadowsocks.Controller
File.WriteAllText(PACServer.PAC_FILE, abpContent, Encoding.UTF8);
}
public void CopyPacUrl()
{
Clipboard.SetDataObject(_pacServer.PacUrl);
}
#region Memory Management
private void StartReleasingMemory()
@@ -11,7 +11,7 @@ namespace Shadowsocks.Controller
return value.ToString("yyyyMMddHHmmssfff");
}
public static void Update(Configuration config, bool forceDisable)
public static void Update(Configuration config, bool forceDisable, PACServer pacSrv)
{
bool global = config.global;
bool enabled = config.enabled;
@@ -27,21 +27,25 @@ namespace Shadowsocks.Controller
{
if (global)
{
WinINet.SetIEProxy(true, true, "127.0.0.1:" + config.localPort.ToString(), "");
Sysproxy.SetIEProxy(true, true, "127.0.0.1:" + config.localPort.ToString(), "");
}
else
{
string pacUrl;
if (config.useOnlinePac && !config.pacUrl.IsNullOrEmpty())
{
pacUrl = config.pacUrl;
}
else
pacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}";
WinINet.SetIEProxy(true, false, "", pacUrl);
{
pacUrl = pacSrv.PacUrl;
}
Sysproxy.SetIEProxy(true, false, "", pacUrl);
}
}
else
{
WinINet.SetIEProxy(false, false, "", "");
Sysproxy.SetIEProxy(false, false, "", "");
}
}
catch (ProxyException ex)
+6 -2
View File
@@ -19,8 +19,11 @@ Online PAC=使用在线 PAC
Edit Local PAC File...=编辑本地 PAC 文件...
Update Local PAC from GFWList=从 GFWList 更新本地 PAC
Edit User Rule for GFWList...=编辑 GFWList 的用户规则...
Show QRCode...=显示二维码...
Secure Local PAC=保护本地 PAC
Copy Local PAC URL=复制本地 PAC 网址
Share Server Config...=分享服务器配置...
Scan QRCode from Screen...=扫描屏幕上的二维码...
Import URL from Clipboard...=从剪贴板导入URL...
Availability Statistics=统计可用性
Show Logs...=显示日志...
Verbose Logging=详细记录日志
@@ -81,7 +84,7 @@ Outbound=出站
# QRCode Form
QRCode=二维码
QRCode and URL=二维码与 URL
# PAC Url Form
@@ -103,6 +106,7 @@ Reg All=注册全部热键
Shadowsocks Error: {0}=Shadowsocks 错误: {0}
Port already in use=端口已被占用
Invalid server address=非法服务器地址
Illegal port number format=非法端口格式
Illegal timeout format=非法超时格式
Please add at least one server=请添加至少一个服务器
Binary file not shown.
Binary file not shown.
+6 -2
View File
@@ -19,8 +19,11 @@ Online PAC=使用在線 PAC
Edit Local PAC File...=編輯本地 PAC 文件...
Update Local PAC from GFWList=從 GFWList 更新本地 PAC
Edit User Rule for GFWList...=編輯 GFWList 的用戶規則...
Show QRCode...=顯示 QR 碼...
Secure Local PAC=保護本地 PAC
Copy Local PAC URL=複製本地 PAC 網址
Share Server Config...=分享伺服器配置...
Scan QRCode from Screen...=掃描螢幕上的 QR 碼...
Import URL from Clipboard...=從剪貼板導入URL...
Availability Statistics=統計可用性
Show Logs...=顯示日誌...
Verbose Logging=詳細記錄日誌
@@ -81,7 +84,7 @@ Outbound=出站
# QRCode Form
QRCode=QR 碼
QRCode and URL=QR 碼与 URL
# PAC Url Form
@@ -103,6 +106,7 @@ Reg All=註冊全部捷徑鍵
Shadowsocks Error: {0}=Shadowsocks 錯誤: {0}
Port already in use=連接埠號碼已被占用
Invalid server address=非法伺服器位址
Illegal port number format=非法連接埠號碼格式
Illegal timeout format=非法超時格式
Please add at least one server=請新增至少一個伺服器
+5
View File
@@ -26,6 +26,11 @@ namespace Shadowsocks.Encryption
Init();
}
public static void GetBytes(byte[] buf)
{
_rng.GetBytes(buf);
}
public static void GetBytes(byte[] buf, int len)
{
try
@@ -22,6 +22,7 @@ namespace Shadowsocks.Model
public int localPort;
public string pacUrl;
public bool useOnlinePac;
public bool secureLocalPac = true;
public bool availabilityStatistics;
public bool autoCheckUpdate;
public bool checkPreRelease;
+3 -6
View File
@@ -10,10 +10,9 @@ namespace Shadowsocks.Model
public class Server
{
public static readonly Regex
UrlFinder = new Regex("^(?i)ss://([A-Za-z0-9+-/=_]+)(#(.+))?$",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
UrlFinder = new Regex("^(?i)ss://([A-Za-z0-9+-/=_]+)(#(.+))?$", RegexOptions.IgnoreCase),
DetailsParser = new Regex("^((?<method>.+?)(?<auth>-auth)??:(?<password>.*)@(?<hostname>.+?)" +
":(?<port>\\d+?))$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
":(?<port>\\d+?))$", RegexOptions.IgnoreCase);
private const int DefaultServerTimeoutSec = 5;
public const int MaxServerTimeoutSec = 20;
@@ -46,9 +45,7 @@ namespace Shadowsocks.Model
string serverStr;
// CheckHostName() won't do a real DNS lookup
var hostType = Uri.CheckHostName( server );
if ( hostType == UriHostNameType.Unknown ) {
throw new FormatException("Invalid Server Address.");
}
switch ( hostType ) {
case UriHostNameType.IPv6:
serverStr = $"[{server}]:{server_port}";
+20
View File
@@ -215,6 +215,26 @@ namespace Shadowsocks.Properties {
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] sysproxy_exe {
get {
object obj = ResourceManager.GetObject("sysproxy_exe", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] sysproxy64_exe {
get {
object obj = ResourceManager.GetObject("sysproxy64_exe", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// 查找类似 ! Put user rules line by line in this file.
///! See https://adblockplus.org/en/filter-cheatsheet
@@ -157,6 +157,12 @@
<data name="ssw128" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ssw128.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="sysproxy64_exe" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Data\sysproxy64.exe.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="sysproxy_exe" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Data\sysproxy.exe.gz;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="user_rule" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\data\user-rule.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
+1 -1
View File
@@ -165,7 +165,7 @@ namespace Shadowsocks.Proxy
st.innerState.ex = ex;
}
private static readonly Regex HttpRespondHeaderRegex = new Regex(@"^(HTTP/1\.\d) (\d{3}) (.+)$");
private static readonly Regex HttpRespondHeaderRegex = new Regex(@"^(HTTP/1\.\d) (\d{3}) (.+)$", RegexOptions.Compiled);
private int _respondLineCount = 0;
private bool _established = false;
@@ -21,7 +21,7 @@ namespace Shadowsocks.Util.Sockets
// Only used during connection and close, so it won't cost too much.
private SpinLock _socketSyncLock = new SpinLock();
private volatile bool _disposed;
private bool _disposed;
private bool Connected => _activeSocket != null;
private Socket _activeSocket;
@@ -1,42 +0,0 @@
/****************************** Module Header ******************************\
Module Name: INTERNET_OPTION.cs
Project: CSWebBrowserWithProxy
Copyright (c) Microsoft Corporation.
This enum contains 4 WinINet constants used in method InternetQueryOption and
InternetSetOption functions.
Visit http://msdn.microsoft.com/en-us/library/aa385328(VS.85).aspx to get the
whole constants list.
This source is subject to the Microsoft Public License.
See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
All other rights reserved.
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
namespace Shadowsocks.Util.SystemProxy
{
public enum INTERNET_OPTION
{
// Sets or retrieves an INTERNET_PER_CONN_OPTION_LIST structure that specifies
// a list of options for a particular connection.
INTERNET_OPTION_PER_CONNECTION_OPTION = 75,
// Notify the system that the registry settings have been changed so that
// it verifies the settings on the next call to InternetConnect.
INTERNET_OPTION_SETTINGS_CHANGED = 39,
// Causes the proxy data to be reread from the registry for a handle.
INTERNET_OPTION_REFRESH = 37,
// Alerts the current WinInet instance that proxy settings have changed
// and that they must update with the new settings.
// To alert all available WinInet instances, set the Buffer parameter of
// InternetSetOption to NULL and BufferLength to 0 when passing this option.
INTERNET_OPTION_PROXY_SETTINGS_CHANGED = 95
}
}
@@ -1,115 +0,0 @@
/****************************** Module Header ******************************\
Module Name: INTERNET_PER_CONN_OPTION.cs
Project: CSWebBrowserWithProxy
Copyright (c) Microsoft Corporation.
This file defines the struct INTERNET_PER_CONN_OPTION and constants used by it.
The struct INTERNET_PER_CONN_OPTION contains the value of an option that to be
set to internet settings.
Visit http://msdn.microsoft.com/en-us/library/aa385145(VS.85).aspx to get the
detailed description.
This source is subject to the Microsoft Public License.
See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
All other rights reserved.
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Runtime.InteropServices;
namespace Shadowsocks.Util.SystemProxy
{
/// <summary>
/// Constants used in INTERNET_PER_CONN_OPTION_OptionUnion struct.
/// </summary>
public enum INTERNET_PER_CONN_OptionEnum
{
INTERNET_PER_CONN_FLAGS = 1,
INTERNET_PER_CONN_PROXY_SERVER = 2,
INTERNET_PER_CONN_PROXY_BYPASS = 3,
INTERNET_PER_CONN_AUTOCONFIG_URL = 4,
INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5,
INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL = 6,
INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS = 7,
INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME = 8,
INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL = 9,
INTERNET_PER_CONN_FLAGS_UI = 10
}
/// <summary>
/// Constants used in INTERNET_PER_CONN_OPTON struct.
/// </summary>
[Flags]
public enum INTERNET_OPTION_PER_CONN_FLAGS
{
PROXY_TYPE_DIRECT = 0x00000001, // direct to net
PROXY_TYPE_PROXY = 0x00000002, // via named proxy
PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL
PROXY_TYPE_AUTO_DETECT = 0x00000008 // use autoproxy detection
}
/// <summary>
/// Constants used in INTERNET_PER_CONN_OPTON struct.
/// Windows 7 and later:
/// Clients that support Internet Explorer 8 should query the connection type using INTERNET_PER_CONN_FLAGS_UI.
/// If this query fails, then the system is running a previous version of Internet Explorer and the client should
/// query again with INTERNET_PER_CONN_FLAGS.
/// Restore the connection type using INTERNET_PER_CONN_FLAGS regardless of the version of Internet Explorer.
/// XXX: If fails, notify user to upgrade Internet Explorer
/// </summary>
[Flags]
public enum INTERNET_OPTION_PER_CONN_FLAGS_UI
{
PROXY_TYPE_DIRECT = 0x00000001, // direct to net
PROXY_TYPE_PROXY = 0x00000002, // via named proxy
PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, // autoproxy URL
PROXY_TYPE_AUTO_DETECT = 0x00000008 // use autoproxy detection
}
/// <summary>
/// Used in INTERNET_PER_CONN_OPTION.
/// When create a instance of OptionUnion, only one filed will be used.
/// The StructLayout and FieldOffset attributes could help to decrease the struct size.
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct INTERNET_PER_CONN_OPTION_OptionUnion : IDisposable
{
// A value in INTERNET_OPTION_PER_CONN_FLAGS.
[FieldOffset(0)]
public int dwValue;
[FieldOffset(0)]
public System.IntPtr pszValue;
[FieldOffset(0)]
public System.Runtime.InteropServices.ComTypes.FILETIME ftValue;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
if (pszValue != IntPtr.Zero)
{
Marshal.FreeHGlobal(pszValue);
pszValue = IntPtr.Zero;
}
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct INTERNET_PER_CONN_OPTION
{
// A value in INTERNET_PER_CONN_OptionEnum.
public int dwOption;
public INTERNET_PER_CONN_OPTION_OptionUnion Value;
}
}
@@ -1,63 +0,0 @@
/****************************** Module Header ******************************\
Module Name: INTERNET_PER_CONN_OPTION_LIST.cs
Project: CSWebBrowserWithProxy
Copyright (c) Microsoft Corporation.
The struct INTERNET_PER_CONN_OPTION contains a list of options that to be
set to internet connection.
Visit http://msdn.microsoft.com/en-us/library/aa385146(VS.85).aspx to get the
detailed description.
This source is subject to the Microsoft Public License.
See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
All other rights reserved.
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Runtime.InteropServices;
namespace Shadowsocks.Util.SystemProxy
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct INTERNET_PER_CONN_OPTION_LIST : IDisposable
{
public int Size;
// The connection to be set. NULL means LAN.
public System.IntPtr Connection;
public int OptionCount;
public int OptionError;
// List of INTERNET_PER_CONN_OPTIONs.
public System.IntPtr pOptions;
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
private void Dispose( bool disposing )
{
if ( disposing )
{
if ( Connection != IntPtr.Zero )
{
Marshal.FreeHGlobal( Connection );
Connection = IntPtr.Zero;
}
if ( pOptions != IntPtr.Zero )
{
Marshal.FreeHGlobal( pOptions );
pOptions = IntPtr.Zero;
}
}
}
}
}
@@ -1,36 +0,0 @@
/****************************** Module Header ******************************\
Module Name: NativeMethods.cs
Project: CSWebBrowserWithProxy
Copyright (c) Microsoft Corporation.
This class is a simple .NET wrapper of wininet.dll. It contains 4 extern
methods in wininet.dll. They are InternetOpen, InternetCloseHandle,
InternetSetOption and InternetQueryOption.
This source is subject to the Microsoft Public License.
See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
All other rights reserved.
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Runtime.InteropServices;
namespace Shadowsocks.Util.SystemProxy
{
internal static class NativeMethods
{
/// <summary>
/// Sets an Internet option.
/// </summary>
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool InternetSetOption(
IntPtr hInternet,
INTERNET_OPTION dwOption,
IntPtr lpBuffer,
int lpdwBufferLength);
}
}
-148
View File
@@ -1,148 +0,0 @@
using System.Runtime.InteropServices;
namespace Shadowsocks.Util.SystemProxy
{
internal static class RemoteAccessService
{
private enum RasFieldSizeConstants
{
#region original header
//#if (WINVER >= 0x400)
//#define RAS_MaxEntryName 256
//#define RAS_MaxDeviceName 128
//#define RAS_MaxCallbackNumber RAS_MaxPhoneNumber
//#else
//#define RAS_MaxEntryName 20
//#define RAS_MaxDeviceName 32
//#define RAS_MaxCallbackNumber 48
//#endif
#endregion
RAS_MaxEntryName = 256,
RAS_MaxPath = 260
}
private const int ERROR_SUCCESS = 0;
private const int RASBASE = 600;
private const int ERROR_BUFFER_TOO_SMALL = RASBASE + 3;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct RasEntryName
{
#region original header
//#define RASENTRYNAMEW struct tagRASENTRYNAMEW
//RASENTRYNAMEW
//{
// DWORD dwSize;
// WCHAR szEntryName[RAS_MaxEntryName + 1];
//
//#if (WINVER >= 0x500)
// //
// // If this flag is REN_AllUsers then its a
// // system phonebook.
// //
// DWORD dwFlags;
// WCHAR szPhonebookPath[MAX_PATH + 1];
//#endif
//};
//
//#define RASENTRYNAMEA struct tagRASENTRYNAMEA
//RASENTRYNAMEA
//{
// DWORD dwSize;
// CHAR szEntryName[RAS_MaxEntryName + 1];
//
//#if (WINVER >= 0x500)
// DWORD dwFlags;
// CHAR szPhonebookPath[MAX_PATH + 1];
//#endif
//};
#endregion
public int dwSize;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=(int)RasFieldSizeConstants.RAS_MaxEntryName + 1)]
public string szEntryName;
public int dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=(int)RasFieldSizeConstants.RAS_MaxPath + 1)]
public string szPhonebookPath;
}
[DllImport("rasapi32.dll", CharSet = CharSet.Auto)]
private static extern uint RasEnumEntries(
// reserved, must be NULL
string reserved,
// pointer to full path and file name of phone-book file
string lpszPhonebook,
// buffer to receive phone-book entries
[In, Out] RasEntryName[] lprasentryname,
// size in bytes of buffer
ref int lpcb,
// number of entries written to buffer
out int lpcEntries
);
/// <summary>
/// Get all entries from RAS
/// </summary>
/// <param name="allConns"></param>
/// <returns>
/// 0: success with entries
/// 1: success but no entries found
/// 2: failed
/// </returns>
public static uint GetAllConns(ref string[] allConns)
{
int lpNames = 0;
int entryNameSize = 0;
int lpSize = 0;
uint retval = ERROR_SUCCESS;
RasEntryName[] names = null;
entryNameSize = Marshal.SizeOf(typeof(RasEntryName));
// Windows Vista or later: To determine the required buffer size, call RasEnumEntries
// with lprasentryname set to NULL. The variable pointed to by lpcb should be set to zero.
// The function will return the required buffer size in lpcb and an error code of ERROR_BUFFER_TOO_SMALL.
retval = RasEnumEntries(null, null, null, ref lpSize, out lpNames);
if (retval == ERROR_BUFFER_TOO_SMALL)
{
names = new RasEntryName[lpNames];
for (int i = 0; i < names.Length; i++)
{
names[i].dwSize = entryNameSize;
}
retval = RasEnumEntries(null, null, names, ref lpSize, out lpNames);
}
if (retval == ERROR_SUCCESS)
{
if (lpNames == 0)
{
// no entries found.
return 1;
}
allConns = new string[names.Length];
for (int i = 0; i < names.Length; i++)
{
allConns[i] = names[i].szEntryName;
}
return 0;
}
else
{
return 2;
}
}
}
}
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Shadowsocks.Controller;
using Shadowsocks.Properties;
namespace Shadowsocks.Util.SystemProxy
{
public static class Sysproxy
{
enum RET_ERRORS : int
{
RET_NO_ERROR = 0,
INVALID_FORMAT = 1,
NO_PERMISSION = 2,
SYSCALL_FAILED = 3,
NO_MEMORY = 4,
INVAILD_OPTION_COUNT = 5,
};
static Sysproxy()
{
try
{
FileManager.UncompressFile(Utils.GetTempPath("sysproxy.exe"),
Environment.Is64BitOperatingSystem ? Resources.sysproxy64_exe : Resources.sysproxy_exe);
}
catch (IOException e)
{
Logging.LogUsefulException(e);
}
}
public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL)
{
string arguments;
if (enable)
{
if (global)
{
arguments = $"global {proxyServer} <local>;localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;172.32.*;192.168.*";
}
else
{
arguments = $"pac {pacURL}";
}
}
else
{
arguments = "off";
}
using (var process = new Process())
{
// Configure the process using the StartInfo properties.
process.StartInfo.FileName = Utils.GetTempPath("sysproxy.exe");
process.StartInfo.Arguments = arguments;
process.StartInfo.WorkingDirectory = Utils.GetTempPath();
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
var error = process.StandardError.ReadToEnd();
process.WaitForExit();
var exitCode = process.ExitCode;
if (exitCode != (int) RET_ERRORS.RET_NO_ERROR)
{
throw new ProxyException(error);
}
}
}
}
}
@@ -1,183 +0,0 @@
/****************************** Module Header ******************************\
Module Name: WinINet.cs
Project: CSWebBrowserWithProxy
Copyright (c) Microsoft Corporation.
This class is used to set the proxy. or restore to the system proxy for the
current application
This source is subject to the Microsoft Public License.
See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
All other rights reserved.
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using Shadowsocks.Controller;
namespace Shadowsocks.Util.SystemProxy
{
public static class WinINet
{
/// <summary>
/// Set IE settings.
/// </summary>
private static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL, string connName)
{
List<INTERNET_PER_CONN_OPTION> _optionlist = new List<INTERNET_PER_CONN_OPTION>();
if (enable)
{
if (global)
{
// global proxy
_optionlist.Add(new INTERNET_PER_CONN_OPTION
{
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS_UI,
Value = { dwValue = (int)(INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_PROXY
| INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_DIRECT) }
});
_optionlist.Add(new INTERNET_PER_CONN_OPTION
{
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_SERVER,
Value = { pszValue = Marshal.StringToHGlobalAuto(proxyServer) }
});
_optionlist.Add(new INTERNET_PER_CONN_OPTION
{
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_PROXY_BYPASS,
Value = { pszValue = Marshal.StringToHGlobalAuto("<local>") }
});
}
else
{
// pac
_optionlist.Add(new INTERNET_PER_CONN_OPTION
{
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS_UI,
Value = { dwValue = (int)INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_AUTO_PROXY_URL }
});
_optionlist.Add(new INTERNET_PER_CONN_OPTION
{
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_AUTOCONFIG_URL,
Value = { pszValue = Marshal.StringToHGlobalAuto(pacURL) }
});
}
}
else
{
// direct
_optionlist.Add(new INTERNET_PER_CONN_OPTION
{
dwOption = (int)INTERNET_PER_CONN_OptionEnum.INTERNET_PER_CONN_FLAGS_UI,
Value = { dwValue = (int)(INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_AUTO_DETECT
| INTERNET_OPTION_PER_CONN_FLAGS_UI.PROXY_TYPE_DIRECT) }
});
}
// Get total length of INTERNET_PER_CONN_OPTIONs
var len = _optionlist.Sum(each => Marshal.SizeOf(each));
// Allocate a block of memory of the options.
IntPtr buffer = Marshal.AllocCoTaskMem(len);
IntPtr current = buffer;
// Marshal data from a managed object to an unmanaged block of memory.
foreach (INTERNET_PER_CONN_OPTION eachOption in _optionlist)
{
Marshal.StructureToPtr(eachOption, current, false);
current = (IntPtr)((int)current + Marshal.SizeOf(eachOption));
}
// Initialize a INTERNET_PER_CONN_OPTION_LIST instance.
INTERNET_PER_CONN_OPTION_LIST optionList = new INTERNET_PER_CONN_OPTION_LIST();
// Point to the allocated memory.
optionList.pOptions = buffer;
// Return the unmanaged size of an object in bytes.
optionList.Size = Marshal.SizeOf(optionList);
optionList.Connection = connName.IsNullOrEmpty()
? IntPtr.Zero // NULL means LAN
: Marshal.StringToHGlobalAuto(connName); // TODO: not working if contains Chinese
optionList.OptionCount = _optionlist.Count;
optionList.OptionError = 0;
int optionListSize = Marshal.SizeOf(optionList);
// Allocate memory for the INTERNET_PER_CONN_OPTION_LIST instance.
IntPtr intptrStruct = Marshal.AllocCoTaskMem(optionListSize);
// Marshal data from a managed object to an unmanaged block of memory.
Marshal.StructureToPtr(optionList, intptrStruct, true);
// Set internet settings.
bool bReturn = NativeMethods.InternetSetOption(
IntPtr.Zero,
INTERNET_OPTION.INTERNET_OPTION_PER_CONNECTION_OPTION,
intptrStruct, optionListSize);
// Free the allocated memory.
Marshal.FreeCoTaskMem(buffer);
Marshal.FreeCoTaskMem(intptrStruct);
// Throw an exception if this operation failed.
if (!bReturn)
{
throw new ProxyException("InternetSetOption failed.", new Win32Exception());
}
// Notify the system that the registry settings have been changed and cause
// the proxy data to be reread from the registry for a handle.
bReturn = NativeMethods.InternetSetOption(
IntPtr.Zero,
INTERNET_OPTION.INTERNET_OPTION_PROXY_SETTINGS_CHANGED,
IntPtr.Zero, 0);
if (!bReturn)
{
Logging.Error("InternetSetOption:INTERNET_OPTION_PROXY_SETTINGS_CHANGED");
}
bReturn = NativeMethods.InternetSetOption(
IntPtr.Zero,
INTERNET_OPTION.INTERNET_OPTION_REFRESH,
IntPtr.Zero, 0);
if (!bReturn)
{
Logging.Error("InternetSetOption:INTERNET_OPTION_REFRESH");
}
}
public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL)
{
string[] allConnections = null;
var ret = RemoteAccessService.GetAllConns(ref allConnections);
if (ret == 2)
throw new ProxyException("Cannot get all connections");
if (ret == 1)
{
// no entries, only set LAN
SetIEProxy(enable, global, proxyServer, pacURL, null);
}
else if (ret == 0)
{
// found entries, set LAN and each connection
SetIEProxy(enable, global, proxyServer, pacURL, null);
foreach (string connName in allConnections)
{
SetIEProxy(enable, global, proxyServer, pacURL, connName);
}
}
}
}
}
+9 -11
View File
@@ -80,28 +80,26 @@ namespace Shadowsocks.View
return true;
}
Server server = new Server();
server.server = IPTextBox.Text.Trim();
try
if (Uri.CheckHostName(server.server = IPTextBox.Text.Trim()) == UriHostNameType.Unknown)
{
server.server_port = int.Parse(ServerPortTextBox.Text);
MessageBox.Show(I18N.GetString("Invalid server address"));
IPTextBox.Focus();
return false;
}
catch (FormatException)
if (!int.TryParse(ServerPortTextBox.Text, out server.server_port))
{
MessageBox.Show(I18N.GetString("Illegal port number format"));
ServerPortTextBox.Clear();
ServerPortTextBox.Focus();
return false;
}
server.password = PasswordTextBox.Text;
server.method = EncryptionSelect.Text;
server.remarks = RemarksTextBox.Text;
try
{
server.timeout = int.Parse(TimeoutTextBox.Text);
}
catch (FormatException)
if (!int.TryParse(TimeoutTextBox.Text, out server.timeout))
{
MessageBox.Show(I18N.GetString("Illegal timeout format"));
TimeoutTextBox.Clear();
TimeoutTextBox.Focus();
return false;
}
server.auth = OneTimeAuth.Checked;
+29 -2
View File
@@ -47,6 +47,7 @@ namespace Shadowsocks.View
private MenuItem updateFromGFWListItem;
private MenuItem editGFWUserRuleItem;
private MenuItem editOnlinePACItem;
private MenuItem secureLocalPacUrlToggleItem;
private MenuItem autoCheckUpdatesToggleItem;
private MenuItem checkPreReleaseToggleItem;
private MenuItem proxyItem;
@@ -260,8 +261,10 @@ namespace Shadowsocks.View
this.SeperatorItem = new MenuItem("-"),
this.ConfigItem = CreateMenuItem("Edit Servers...", new EventHandler(this.Config_Click)),
CreateMenuItem("Statistics Config...", StatisticsConfigItem_Click),
CreateMenuItem("Show QRCode...", new EventHandler(this.QRCodeItem_Click)),
CreateMenuItem("Scan QRCode from Screen...", new EventHandler(this.ScanQRCodeItem_Click))
new MenuItem("-"),
CreateMenuItem("Share Server Config...", new EventHandler(this.QRCodeItem_Click)),
CreateMenuItem("Scan QRCode from Screen...", new EventHandler(this.ScanQRCodeItem_Click)),
CreateMenuItem("Import URL from Clipboard...", new EventHandler(this.ImportURLItem_Click))
}),
CreateMenuGroup("PAC ", new MenuItem[] {
this.localPACItem = CreateMenuItem("Local PAC", new EventHandler(this.LocalPACItem_Click)),
@@ -270,6 +273,8 @@ namespace Shadowsocks.View
this.editLocalPACItem = CreateMenuItem("Edit Local PAC File...", new EventHandler(this.EditPACFileItem_Click)),
this.updateFromGFWListItem = CreateMenuItem("Update Local PAC from GFWList", new EventHandler(this.UpdatePACFromGFWListItem_Click)),
this.editGFWUserRuleItem = CreateMenuItem("Edit User Rule for GFWList...", new EventHandler(this.EditUserRuleFileForGFWListItem_Click)),
this.secureLocalPacUrlToggleItem = CreateMenuItem("Secure Local PAC", new EventHandler(this.SecureLocalPacUrlToggleItem_Click)),
CreateMenuItem("Copy Local PAC URL", new EventHandler(this.CopyLocalPacUrlItem_Click)),
this.editOnlinePACItem = CreateMenuItem("Edit Online PAC URL...", new EventHandler(this.UpdateOnlinePACURLItem_Click)),
}),
this.proxyItem = CreateMenuItem("Forward Proxy...", new EventHandler(this.proxyItem_Click)),
@@ -397,6 +402,7 @@ namespace Shadowsocks.View
AutoStartupItem.Checked = AutoStartup.Check();
onlinePACItem.Checked = onlinePACItem.Enabled && config.useOnlinePac;
localPACItem.Checked = !onlinePACItem.Checked;
secureLocalPacUrlToggleItem.Checked = config.secureLocalPac;
UpdatePACItemsEnabledStatus();
UpdateUpdateMenu();
}
@@ -735,6 +741,15 @@ namespace Shadowsocks.View
MessageBox.Show(I18N.GetString("No QRCode found. Try to zoom in or move it to the center of the screen."));
}
private void ImportURLItem_Click(object sender, EventArgs e)
{
var success = controller.AddServerBySSURL(Clipboard.GetText(TextDataFormat.Text));
if (success)
{
ShowConfigForm();
}
}
void splash_FormClosed(object sender, FormClosedEventArgs e)
{
ShowConfigForm();
@@ -796,6 +811,17 @@ namespace Shadowsocks.View
}
}
private void SecureLocalPacUrlToggleItem_Click(object sender, EventArgs e)
{
Configuration configuration = controller.GetConfigurationCopy();
controller.ToggleSecureLocalPac(!configuration.secureLocalPac);
}
private void CopyLocalPacUrlItem_Click(object sender, EventArgs e)
{
controller.CopyPacUrl();
}
private void UpdatePACItemsEnabledStatus()
{
if (this.localPACItem.Checked)
@@ -814,6 +840,7 @@ namespace Shadowsocks.View
}
}
private void UpdateUpdateMenu()
{
Configuration configuration = controller.GetConfigurationCopy();
+7 -27
View File
@@ -58,35 +58,25 @@ namespace Shadowsocks.View
private void OKButton_Click(object sender, EventArgs e)
{
var type = ProxyTypeComboBox.SelectedIndex;
var proxy = ProxyServerTextBox.Text;
var port = 0;
var timeout = 3;
if (UseProxyCheckBox.Checked)
{
try
{
port = int.Parse(ProxyPortTextBox.Text);
}
catch (FormatException)
int port;
int timeout;
if (!int.TryParse(ProxyPortTextBox.Text, out port))
{
MessageBox.Show(I18N.GetString("Illegal port number format"));
ProxyPortTextBox.Clear();
return;
}
try
{
timeout = int.Parse(ProxyTimeoutTextBox.Text);
}
catch (FormatException)
if (!int.TryParse(ProxyTimeoutTextBox.Text, out timeout))
{
MessageBox.Show(I18N.GetString("Illegal timeout format"));
ProxyTimeoutTextBox.Clear();
return;
}
var type = ProxyTypeComboBox.SelectedIndex;
var proxy = ProxyServerTextBox.Text;
try
{
Configuration.CheckServer(proxy);
@@ -99,20 +89,13 @@ namespace Shadowsocks.View
return;
}
controller.EnableProxy(type, proxy, port);
controller.EnableProxy(type, proxy, port, timeout);
}
else
{
controller.DisableProxy();
}
_modifiedConfiguration.useProxy = UseProxyCheckBox.Checked;
_modifiedConfiguration.proxyType = type;
_modifiedConfiguration.proxyServer = proxy;
_modifiedConfiguration.proxyPort = port;
_modifiedConfiguration.proxyTimeout = timeout;
controller.SaveProxyConfig(_modifiedConfiguration);
this.Close();
}
@@ -142,9 +125,6 @@ namespace Shadowsocks.View
}
else
{
ProxyServerTextBox.Clear();
ProxyPortTextBox.Clear();
ProxyTimeoutTextBox.Clear();
ProxyServerTextBox.Enabled = false;
ProxyPortTextBox.Enabled = false;
ProxyTimeoutTextBox.Enabled = false;
+16 -3
View File
@@ -30,6 +30,7 @@
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.listBox1 = new System.Windows.Forms.ListBox();
this.textBoxURL = new System.Windows.Forms.TextBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
@@ -39,7 +40,7 @@
this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(210, 210);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
this.pictureBox1.TabIndex = 1;
this.pictureBox1.TabStop = false;
//
@@ -56,6 +57,15 @@
this.listBox1.ValueMember = "Key";
this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
//
// textBoxURL
//
this.textBoxURL.Location = new System.Drawing.Point(10, 227);
this.textBoxURL.Name = "textBoxURL";
this.textBoxURL.ReadOnly = true;
this.textBoxURL.Size = new System.Drawing.Size(441, 21);
this.textBoxURL.TabIndex = 3;
this.textBoxURL.Click += new System.EventHandler(this.textBoxURL_Click);
//
// QRCodeForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
@@ -63,7 +73,8 @@
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(457, 228);
this.ClientSize = new System.Drawing.Size(457, 257);
this.Controls.Add(this.textBoxURL);
this.Controls.Add(this.listBox1);
this.Controls.Add(this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
@@ -72,10 +83,11 @@
this.Name = "QRCodeForm";
this.Padding = new System.Windows.Forms.Padding(10);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "QRCode";
this.Text = "QRCode and URL";
this.Load += new System.EventHandler(this.QRCodeForm_Load);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
@@ -83,5 +95,6 @@
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.TextBox textBoxURL;
}
}
+17 -2
View File
@@ -24,7 +24,7 @@ namespace Shadowsocks.View
this.code = code;
InitializeComponent();
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
this.Text = I18N.GetString("QRCode");
this.Text = I18N.GetString("QRCode and URL");
}
private void GenQR(string ssconfig)
@@ -33,6 +33,14 @@ namespace Shadowsocks.View
QRCode code = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M);
ByteMatrix m = code.Matrix;
int blockSize = Math.Max(pictureBox1.Height/m.Height, 1);
var qrWidth = m.Width*blockSize;
var qrHeight = m.Height*blockSize;
var dWidth = pictureBox1.Width - qrWidth;
var dHeight = pictureBox1.Height - qrHeight;
var maxD = Math.Max(dWidth, dHeight);
pictureBox1.SizeMode = maxD >= 7*blockSize ? PictureBoxSizeMode.Zoom : PictureBoxSizeMode.CenterImage;
Bitmap drawArea = new Bitmap((m.Width*blockSize), (m.Height*blockSize));
using (Graphics g = Graphics.FromImage(drawArea))
{
@@ -69,7 +77,14 @@ namespace Shadowsocks.View
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
GenQR((sender as ListBox)?.SelectedValue.ToString());
var url = (sender as ListBox)?.SelectedValue.ToString();
GenQR(url);
textBoxURL.Text = url;
}
private void textBoxURL_Click(object sender, EventArgs e)
{
textBoxURL.SelectAll();
}
}
}
+28 -31
View File
@@ -195,13 +195,8 @@
<Compile Include="Util\Sockets\LineReader.cs" />
<Compile Include="Util\Sockets\SocketUtil.cs" />
<Compile Include="Util\Sockets\WrappedSocket.cs" />
<Compile Include="Util\SystemProxy\INTERNET_OPTION.cs" />
<Compile Include="Util\SystemProxy\INTERNET_PER_CONN_OPTION.cs" />
<Compile Include="Util\SystemProxy\INTERNET_PER_CONN_OPTION_LIST.cs" />
<Compile Include="Util\SystemProxy\NativeMethods.cs" />
<Compile Include="Util\SystemProxy\ProxyException.cs" />
<Compile Include="Util\SystemProxy\RAS.cs" />
<Compile Include="Util\SystemProxy\WinINet.cs" />
<Compile Include="Util\SystemProxy\Sysproxy.cs" />
<Compile Include="Util\Util.cs" />
<Compile Include="Util\ViewUtils.cs" />
<Compile Include="View\ConfigForm.cs">
@@ -294,6 +289,8 @@
<None Include="Data\proxy.pac.txt.gz" />
</ItemGroup>
<ItemGroup>
<None Include="Data\sysproxy.exe.gz" />
<None Include="Data\sysproxy64.exe.gz" />
<None Include="packages.config" />
<None Include="Properties\DataSources\Shadowsocks.Model.StatisticsStrategyConfiguration.datasource" />
<None Include="Properties\Settings.settings">
@@ -359,25 +356,25 @@
<Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System" />
<Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.IO" />
<Using xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Namespace="System.Xml.Linq" />
<Code xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Type="Fragment" Language="cs"><![CDATA[
var config = XElement.Load(Config.ItemSpec).Elements("Costura").FirstOrDefault();
if (config == null) return true;
var excludedAssemblies = new List<string>();
var attribute = config.Attribute("ExcludeAssemblies");
if (attribute != null)
foreach (var item in attribute.Value.Split('|').Select(x => x.Trim()).Where(x => x != string.Empty))
excludedAssemblies.Add(item);
var element = config.Element("ExcludeAssemblies");
if (element != null)
foreach (var item in element.Value.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x != string.Empty))
excludedAssemblies.Add(item);
var filesToCleanup = Files.Select(f => f.ItemSpec).Where(f => !excludedAssemblies.Contains(Path.GetFileNameWithoutExtension(f), StringComparer.InvariantCultureIgnoreCase));
foreach (var item in filesToCleanup)
File.Delete(item);
<Code xmlns="http://schemas.microsoft.com/developer/msbuild/2003" Type="Fragment" Language="cs"><![CDATA[
var config = XElement.Load(Config.ItemSpec).Elements("Costura").FirstOrDefault();
if (config == null) return true;
var excludedAssemblies = new List<string>();
var attribute = config.Attribute("ExcludeAssemblies");
if (attribute != null)
foreach (var item in attribute.Value.Split('|').Select(x => x.Trim()).Where(x => x != string.Empty))
excludedAssemblies.Add(item);
var element = config.Element("ExcludeAssemblies");
if (element != null)
foreach (var item in element.Value.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).Where(x => x != string.Empty))
excludedAssemblies.Add(item);
var filesToCleanup = Files.Select(f => f.ItemSpec).Where(f => !excludedAssemblies.Contains(Path.GetFileNameWithoutExtension(f), StringComparer.InvariantCultureIgnoreCase));
foreach (var item in filesToCleanup)
File.Delete(item);
]]></Code>
</Task>
</UsingTask>
@@ -391,11 +388,11 @@ foreach (var item in filesToCleanup)
</PropertyGroup>
<Error Condition="!Exists('3rd\Fody.1.29.4\build\dotnet\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '3rd\Fody.1.29.4\build\dotnet\Fody.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>