Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbfc5d332d | ||
|
|
5d75e19c26 | ||
|
|
816651ebdc |
@@ -1,3 +1,7 @@
|
|||||||
|
4.0.4 2017-06-01
|
||||||
|
- Save user wininet settings as user-wininet.json
|
||||||
|
- Improve performance of aes-256-gcm
|
||||||
|
|
||||||
4.0.2 2017-05-19
|
4.0.2 2017-05-19
|
||||||
- Fix legacy key derivation
|
- Fix legacy key derivation
|
||||||
- Bug fixes and improvements
|
- Bug fixes and improvements
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Shadowsocks.Controller
|
|||||||
public string LatestVersionLocalName;
|
public string LatestVersionLocalName;
|
||||||
public event EventHandler CheckUpdateCompleted;
|
public event EventHandler CheckUpdateCompleted;
|
||||||
|
|
||||||
public const string Version = "4.0.2";
|
public const string Version = "4.0.4";
|
||||||
|
|
||||||
private class CheckUpdateTimer : System.Timers.Timer
|
private class CheckUpdateTimer : System.Timers.Timer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ namespace Shadowsocks.Controller
|
|||||||
|
|
||||||
private bool stopped = false;
|
private bool stopped = false;
|
||||||
|
|
||||||
private bool _systemProxyIsDirty = false;
|
|
||||||
|
|
||||||
public class PathEventArgs : EventArgs
|
public class PathEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public string Path;
|
public string Path;
|
||||||
@@ -510,20 +508,7 @@ namespace Shadowsocks.Controller
|
|||||||
|
|
||||||
private void UpdateSystemProxy()
|
private void UpdateSystemProxy()
|
||||||
{
|
{
|
||||||
if (_config.enabled)
|
SystemProxy.Update(_config, false, _pacServer);
|
||||||
{
|
|
||||||
SystemProxy.Update(_config, false, _pacServer);
|
|
||||||
_systemProxyIsDirty = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// only switch it off if we have switched it on
|
|
||||||
if (_systemProxyIsDirty)
|
|
||||||
{
|
|
||||||
SystemProxy.Update(_config, false, _pacServer);
|
|
||||||
_systemProxyIsDirty = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pacServer_PACFileChanged(object sender, EventArgs e)
|
private void pacServer_PACFileChanged(object sender, EventArgs e)
|
||||||
|
|||||||
Binary file not shown.
@@ -10,6 +10,7 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
: AEADEncryptor, IDisposable
|
: AEADEncryptor, IDisposable
|
||||||
{
|
{
|
||||||
private const int CIPHER_CHACHA20IETFPOLY1305 = 1;
|
private const int CIPHER_CHACHA20IETFPOLY1305 = 1;
|
||||||
|
private const int CIPHER_AES256GCM = 2;
|
||||||
|
|
||||||
private byte[] _sodiumEncSubkey;
|
private byte[] _sodiumEncSubkey;
|
||||||
private byte[] _sodiumDecSubkey;
|
private byte[] _sodiumDecSubkey;
|
||||||
@@ -24,6 +25,7 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
private static Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo>
|
private static Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo>
|
||||||
{
|
{
|
||||||
{"chacha20-ietf-poly1305", new EncryptorInfo(32, 32, 12, 16, CIPHER_CHACHA20IETFPOLY1305)},
|
{"chacha20-ietf-poly1305", new EncryptorInfo(32, 32, 12, 16, CIPHER_CHACHA20IETFPOLY1305)},
|
||||||
|
{"aes-256-gcm", new EncryptorInfo(32, 32, 12, 16, CIPHER_AES256GCM)},
|
||||||
};
|
};
|
||||||
|
|
||||||
public static List<string> SupportedCiphers()
|
public static List<string> SupportedCiphers()
|
||||||
@@ -63,6 +65,13 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
null, _encNonce,
|
null, _encNonce,
|
||||||
_sodiumEncSubkey);
|
_sodiumEncSubkey);
|
||||||
break;
|
break;
|
||||||
|
case CIPHER_AES256GCM:
|
||||||
|
ret = Sodium.crypto_aead_aes256gcm_encrypt(ciphertext, ref encClen,
|
||||||
|
plaintext, (ulong)plen,
|
||||||
|
null, 0,
|
||||||
|
null, _encNonce,
|
||||||
|
_sodiumEncSubkey);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new System.Exception("not implemented");
|
throw new System.Exception("not implemented");
|
||||||
}
|
}
|
||||||
@@ -91,6 +100,13 @@ namespace Shadowsocks.Encryption.AEAD
|
|||||||
null, 0,
|
null, 0,
|
||||||
_decNonce, _sodiumDecSubkey);
|
_decNonce, _sodiumDecSubkey);
|
||||||
break;
|
break;
|
||||||
|
case CIPHER_AES256GCM:
|
||||||
|
ret = Sodium.crypto_aead_aes256gcm_decrypt(plaintext, ref decPlen,
|
||||||
|
null,
|
||||||
|
ciphertext, (ulong)clen,
|
||||||
|
null, 0,
|
||||||
|
_decNonce, _sodiumDecSubkey);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new System.Exception("not implemented");
|
throw new System.Exception("not implemented");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,18 @@ namespace Shadowsocks.Encryption
|
|||||||
|
|
||||||
static EncryptorFactory()
|
static EncryptorFactory()
|
||||||
{
|
{
|
||||||
|
var AEADMbedTLSEncryptorSupportedCiphers = AEADMbedTLSEncryptor.SupportedCiphers();
|
||||||
|
var AEADSodiumEncryptorSupportedCiphers = AEADSodiumEncryptor.SupportedCiphers();
|
||||||
|
if (Sodium.AES256GCMAvailable)
|
||||||
|
{
|
||||||
|
// prefer to aes-256-gcm in libsodium
|
||||||
|
AEADMbedTLSEncryptorSupportedCiphers.Remove("aes-256-gcm");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AEADSodiumEncryptorSupportedCiphers.Remove("aes-256-gcm");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (string method in StreamMbedTLSEncryptor.SupportedCiphers())
|
foreach (string method in StreamMbedTLSEncryptor.SupportedCiphers())
|
||||||
{
|
{
|
||||||
_registeredEncryptors.Add(method, typeof(StreamMbedTLSEncryptor));
|
_registeredEncryptors.Add(method, typeof(StreamMbedTLSEncryptor));
|
||||||
@@ -22,11 +34,11 @@ namespace Shadowsocks.Encryption
|
|||||||
{
|
{
|
||||||
_registeredEncryptors.Add(method, typeof(StreamSodiumEncryptor));
|
_registeredEncryptors.Add(method, typeof(StreamSodiumEncryptor));
|
||||||
}
|
}
|
||||||
foreach (string method in AEADMbedTLSEncryptor.SupportedCiphers())
|
foreach (string method in AEADMbedTLSEncryptorSupportedCiphers)
|
||||||
{
|
{
|
||||||
_registeredEncryptors.Add(method, typeof(AEADMbedTLSEncryptor));
|
_registeredEncryptors.Add(method, typeof(AEADMbedTLSEncryptor));
|
||||||
}
|
}
|
||||||
foreach (string method in AEADSodiumEncryptor.SupportedCiphers())
|
foreach (string method in AEADSodiumEncryptorSupportedCiphers)
|
||||||
{
|
{
|
||||||
_registeredEncryptors.Add(method, typeof(AEADSodiumEncryptor));
|
_registeredEncryptors.Add(method, typeof(AEADSodiumEncryptor));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ namespace Shadowsocks.Encryption
|
|||||||
private static bool _initialized = false;
|
private static bool _initialized = false;
|
||||||
private static readonly object _initLock = new object();
|
private static readonly object _initLock = new object();
|
||||||
|
|
||||||
|
public static bool AES256GCMAvailable { get; private set; } = false;
|
||||||
|
|
||||||
static Sodium()
|
static Sodium()
|
||||||
{
|
{
|
||||||
string dllPath = Utils.GetTempPath(DLLNAME);
|
string dllPath = Utils.GetTempPath(DLLNAME);
|
||||||
@@ -42,6 +44,9 @@ namespace Shadowsocks.Encryption
|
|||||||
{
|
{
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AES256GCMAvailable = crypto_aead_aes256gcm_is_available() == 1;
|
||||||
|
Logging.Debug($"sodium: AES256GCMAvailable is {AES256GCMAvailable}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,6 +57,9 @@ namespace Shadowsocks.Encryption
|
|||||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern int sodium_init();
|
private static extern int sodium_init();
|
||||||
|
|
||||||
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
private static extern int crypto_aead_aes256gcm_is_available();
|
||||||
|
|
||||||
#region AEAD
|
#region AEAD
|
||||||
|
|
||||||
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
@@ -65,6 +73,14 @@ namespace Shadowsocks.Encryption
|
|||||||
public static extern int crypto_aead_chacha20poly1305_ietf_decrypt(byte[] m, ref ulong mlen_p,
|
public static extern int crypto_aead_chacha20poly1305_ietf_decrypt(byte[] m, ref ulong mlen_p,
|
||||||
byte[] nsec, byte[] c, ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k);
|
byte[] nsec, byte[] c, ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k);
|
||||||
|
|
||||||
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int crypto_aead_aes256gcm_encrypt(byte[] c, ref ulong clen_p, byte[] m, ulong mlen,
|
||||||
|
byte[] ad, ulong adlen, byte[] nsec, byte[] npub, byte[] k);
|
||||||
|
|
||||||
|
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static extern int crypto_aead_aes256gcm_decrypt(byte[] m, ref ulong mlen_p, byte[] nsec, byte[] c,
|
||||||
|
ulong clen, byte[] ad, ulong adlen, byte[] npub, byte[] k);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Stream
|
#region Stream
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Shadowsocks.Model
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Data come from WinINET
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class SysproxyConfig
|
||||||
|
{
|
||||||
|
public bool UserSettingsRecorded;
|
||||||
|
public string Flags;
|
||||||
|
public string ProxyServer;
|
||||||
|
public string BypassList;
|
||||||
|
public string PacUrl;
|
||||||
|
|
||||||
|
public SysproxyConfig()
|
||||||
|
{
|
||||||
|
UserSettingsRecorded = false;
|
||||||
|
Flags = "1";
|
||||||
|
ProxyServer = "";
|
||||||
|
BypassList = "";
|
||||||
|
PacUrl = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
|
||||||
using Shadowsocks.Controller;
|
using Shadowsocks.Controller;
|
||||||
using Shadowsocks.Properties;
|
using Shadowsocks.Properties;
|
||||||
|
using Shadowsocks.Model;
|
||||||
|
using System.Text;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Shadowsocks.Util.SystemProxy
|
namespace Shadowsocks.Util.SystemProxy
|
||||||
{
|
{
|
||||||
public static class Sysproxy
|
public static class Sysproxy
|
||||||
{
|
{
|
||||||
private static bool _userSettingsRecorded = false;
|
private const string _userWininetConfigFile = "user-wininet.json";
|
||||||
|
|
||||||
|
private static string _queryStr;
|
||||||
|
|
||||||
// In general, this won't change
|
// In general, this won't change
|
||||||
// format:
|
// format:
|
||||||
@@ -17,7 +21,7 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
// <proxy-server><CR-LF>
|
// <proxy-server><CR-LF>
|
||||||
// <bypass-list><CR-LF>
|
// <bypass-list><CR-LF>
|
||||||
// <pac-url>
|
// <pac-url>
|
||||||
private static string[] _userSettings = new string[4];
|
private static SysproxyConfig _userSettings = null;
|
||||||
|
|
||||||
enum RET_ERRORS : int
|
enum RET_ERRORS : int
|
||||||
{
|
{
|
||||||
@@ -31,8 +35,7 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
|
|
||||||
static Sysproxy()
|
static Sysproxy()
|
||||||
{
|
{
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
FileManager.UncompressFile(Utils.GetTempPath("sysproxy.exe"),
|
FileManager.UncompressFile(Utils.GetTempPath("sysproxy.exe"),
|
||||||
Environment.Is64BitOperatingSystem ? Resources.sysproxy64_exe : Resources.sysproxy_exe);
|
Environment.Is64BitOperatingSystem ? Resources.sysproxy64_exe : Resources.sysproxy_exe);
|
||||||
}
|
}
|
||||||
@@ -44,13 +47,12 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
|
|
||||||
public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL)
|
public static void SetIEProxy(bool enable, bool global, string proxyServer, string pacURL)
|
||||||
{
|
{
|
||||||
string str;
|
Read();
|
||||||
if (_userSettingsRecorded == false)
|
if (!_userSettings.UserSettingsRecorded)
|
||||||
{
|
{
|
||||||
// record user settings
|
// record user settings
|
||||||
ExecSysproxy("query", out str);
|
ExecSysproxy("query");
|
||||||
ParseQueryStr(str);
|
ParseQueryStr(_queryStr);
|
||||||
_userSettingsRecorded = true;
|
|
||||||
}
|
}
|
||||||
string arguments;
|
string arguments;
|
||||||
|
|
||||||
@@ -63,20 +65,21 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// restore user settings
|
// restore user settings
|
||||||
var flags = _userSettings[0];
|
var flags = _userSettings.Flags;
|
||||||
var proxy_server = _userSettings[1] ?? "-";
|
var proxy_server = _userSettings.ProxyServer ?? "-";
|
||||||
var bypass_list = _userSettings[2] ?? "-";
|
var bypass_list = _userSettings.BypassList ?? "-";
|
||||||
var pac_url = _userSettings[3] ?? "-";
|
var pac_url = _userSettings.PacUrl ?? "-";
|
||||||
arguments = $"set {flags} {proxy_server} {bypass_list} {pac_url}";
|
arguments = $"set {flags} {proxy_server} {bypass_list} {pac_url}";
|
||||||
|
|
||||||
// have to get new settings
|
// have to get new settings
|
||||||
_userSettingsRecorded = false;
|
_userSettings.UserSettingsRecorded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecSysproxy(arguments, out str);
|
Save();
|
||||||
|
ExecSysproxy(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ExecSysproxy(string arguments, out string queryStr)
|
private static void ExecSysproxy(string arguments)
|
||||||
{
|
{
|
||||||
using (var process = new Process())
|
using (var process = new Process())
|
||||||
{
|
{
|
||||||
@@ -107,24 +110,53 @@ namespace Shadowsocks.Util.SystemProxy
|
|||||||
throw new ProxyException(stderr);
|
throw new ProxyException(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments == "query" && stdout.IsNullOrWhiteSpace())
|
if (arguments == "query") {
|
||||||
{
|
if (stdout.IsNullOrWhiteSpace() || stdout.IsNullOrEmpty()) {
|
||||||
// we cannot get user settings
|
// we cannot get user settings
|
||||||
throw new ProxyException("failed to query wininet settings");
|
throw new ProxyException("failed to query wininet settings");
|
||||||
|
}
|
||||||
|
_queryStr = stdout;
|
||||||
}
|
}
|
||||||
queryStr = stdout;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Save()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
using (StreamWriter sw = new StreamWriter(File.Open(_userWininetConfigFile, FileMode.Create))) {
|
||||||
|
string jsonString = JsonConvert.SerializeObject(_userSettings, Formatting.Indented);
|
||||||
|
sw.Write(jsonString);
|
||||||
|
sw.Flush();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logging.LogUsefulException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Read()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
string configContent = File.ReadAllText(_userWininetConfigFile);
|
||||||
|
_userSettings = JsonConvert.DeserializeObject<SysproxyConfig>(configContent);
|
||||||
|
} catch (FileNotFoundException) {
|
||||||
|
_userSettings = new SysproxyConfig();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseQueryStr(string str)
|
private static void ParseQueryStr(string str)
|
||||||
{
|
{
|
||||||
_userSettings = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
string[] userSettingsArr = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
for (var i = 0; i < 4; i++)
|
_userSettings.Flags = userSettingsArr[0];
|
||||||
{
|
|
||||||
// handle output from WinINET
|
// handle output from WinINET
|
||||||
if (_userSettings[i] == "(null)")
|
if (userSettingsArr[1] == "(null)") _userSettings.ProxyServer = null;
|
||||||
_userSettings[i] = null;
|
else _userSettings.ProxyServer = userSettingsArr[1];
|
||||||
}
|
if (userSettingsArr[2] == "(null)") _userSettings.BypassList = null;
|
||||||
|
else _userSettings.BypassList = userSettingsArr[2];
|
||||||
|
if (userSettingsArr[3] == "(null)") _userSettings.PacUrl = null;
|
||||||
|
else _userSettings.PacUrl = userSettingsArr[3];
|
||||||
|
|
||||||
|
_userSettings.UserSettingsRecorded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,7 @@
|
|||||||
<Compile Include="Encryption\Stream\StreamSodiumEncryptor.cs" />
|
<Compile Include="Encryption\Stream\StreamSodiumEncryptor.cs" />
|
||||||
<Compile Include="Model\HotKeyConfig.cs" />
|
<Compile Include="Model\HotKeyConfig.cs" />
|
||||||
<Compile Include="Model\ProxyConfig.cs" />
|
<Compile Include="Model\ProxyConfig.cs" />
|
||||||
|
<Compile Include="Model\SysproxyConfig.cs" />
|
||||||
<Compile Include="Properties\Settings.Designer.cs">
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
|||||||
Reference in New Issue
Block a user