@@ -272,6 +272,7 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
SystemProxy.Update(_config, true); | SystemProxy.Update(_config, true); | ||||
} | } | ||||
Encryption.RNG.Close(); | |||||
} | } | ||||
public void TouchPACFile() | public void TouchPACFile() | ||||
@@ -413,6 +414,7 @@ namespace Shadowsocks.Controller | |||||
protected void Reload() | protected void Reload() | ||||
{ | { | ||||
Encryption.RNG.Reload(); | |||||
// some logic in configuration updated the config when saving, we need to read it again | // some logic in configuration updated the config when saving, we need to read it again | ||||
_config = Configuration.Load(); | _config = Configuration.Load(); | ||||
StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); | StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); | ||||
@@ -1,8 +1,6 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
using System.Linq; | |||||
using System.Security.Cryptography; | |||||
using System.Text; | using System.Text; | ||||
using System.Net; | using System.Net; | ||||
@@ -237,10 +235,7 @@ namespace Shadowsocks.Encryption | |||||
protected static void randBytes(byte[] buf, int length) | protected static void randBytes(byte[] buf, int length) | ||||
{ | { | ||||
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) | |||||
{ | |||||
rng.GetBytes(buf, 0, length); | |||||
} | |||||
RNG.GetBytes(buf, length); | |||||
} | } | ||||
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) | public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) | ||||
@@ -0,0 +1,44 @@ | |||||
using System; | |||||
using System.Security.Cryptography; | |||||
namespace Shadowsocks.Encryption | |||||
{ | |||||
public static class RNG | |||||
{ | |||||
private static RNGCryptoServiceProvider _rng = null; | |||||
public static void Init() | |||||
{ | |||||
if (_rng == null) | |||||
_rng = new RNGCryptoServiceProvider(); | |||||
} | |||||
public static void Close() | |||||
{ | |||||
if (_rng == null) return; | |||||
_rng.Dispose(); | |||||
_rng = null; | |||||
} | |||||
public static void Reload() | |||||
{ | |||||
Close(); | |||||
Init(); | |||||
} | |||||
public static void GetBytes(byte[] buf, int len) | |||||
{ | |||||
try | |||||
{ | |||||
_rng.GetBytes(buf, 0, len); | |||||
} | |||||
catch (Exception) | |||||
{ | |||||
// the backup way | |||||
byte[] tmp = new byte[len]; | |||||
_rng.GetBytes(tmp); | |||||
Buffer.BlockCopy(tmp, 0, buf, 0, len); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -92,9 +92,10 @@ namespace Shadowsocks | |||||
{ | { | ||||
if (Interlocked.Increment(ref exited) == 1) | if (Interlocked.Increment(ref exited) == 1) | ||||
{ | { | ||||
Logging.Error(e.ExceptionObject?.ToString()); | |||||
string errMsg = e.ExceptionObject.ToString(); | |||||
Logging.Error(errMsg); | |||||
MessageBox.Show( | MessageBox.Show( | ||||
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{e.ExceptionObject?.ToString()}", | |||||
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errMsg}", | |||||
"Shadowsocks non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); | "Shadowsocks non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); | ||||
Application.Exit(); | Application.Exit(); | ||||
} | } | ||||
@@ -102,12 +103,15 @@ namespace Shadowsocks | |||||
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) | private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) | ||||
{ | { | ||||
string errorMsg = $"Exception Type: {e.Exception.GetType().Name}{Environment.NewLine}Stack Trace:{Environment.NewLine}{e.Exception.StackTrace}"; | |||||
Logging.Error(errorMsg); | |||||
MessageBox.Show( | |||||
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errorMsg}", | |||||
"Shadowsocks UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); | |||||
Application.Exit(); | |||||
if (Interlocked.Increment(ref exited) == 1) | |||||
{ | |||||
string errorMsg = $"Exception Detail: {Environment.NewLine}{e.Exception}"; | |||||
Logging.Error(errorMsg); | |||||
MessageBox.Show( | |||||
$"{I18N.GetString("Unexpected error, shadowsocks will exit. Please report to")} https://github.com/shadowsocks/shadowsocks-windows/issues {Environment.NewLine}{errorMsg}", | |||||
"Shadowsocks UI Error", MessageBoxButtons.OK, MessageBoxIcon.Error); | |||||
Application.Exit(); | |||||
} | |||||
} | } | ||||
private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) | private static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e) | ||||
@@ -168,7 +172,10 @@ namespace Shadowsocks | |||||
private static void Application_ApplicationExit(object sender, EventArgs e) | private static void Application_ApplicationExit(object sender, EventArgs e) | ||||
{ | { | ||||
// detach static event handlers | |||||
Application.ApplicationExit -= Application_ApplicationExit; | |||||
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; | SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; | ||||
Application.ThreadException -= Application_ThreadException; | |||||
HotKeys.Destroy(); | HotKeys.Destroy(); | ||||
if (_controller != null) | if (_controller != null) | ||||
{ | { | ||||
@@ -183,6 +183,7 @@ | |||||
<Compile Include="Util\Hotkeys.cs" /> | <Compile Include="Util\Hotkeys.cs" /> | ||||
<Compile Include="Util\ProcessManagement\Job.cs" /> | <Compile Include="Util\ProcessManagement\Job.cs" /> | ||||
<Compile Include="Util\ProcessManagement\ThreadUtil.cs" /> | <Compile Include="Util\ProcessManagement\ThreadUtil.cs" /> | ||||
<Compile Include="Encryption\RNG.cs" /> | |||||
<Compile Include="Util\Sockets\LineReader.cs" /> | <Compile Include="Util\Sockets\LineReader.cs" /> | ||||
<Compile Include="Util\Sockets\SocketUtil.cs" /> | <Compile Include="Util\Sockets\SocketUtil.cs" /> | ||||
<Compile Include="Util\Sockets\WrappedSocket.cs" /> | <Compile Include="Util\Sockets\WrappedSocket.cs" /> | ||||
@@ -68,6 +68,7 @@ namespace test | |||||
private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) | private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) | ||||
{ | { | ||||
RNG.Reload(); | |||||
byte[] plain = new byte[16384]; | byte[] plain = new byte[16384]; | ||||
byte[] cipher = new byte[plain.Length + 16 + IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES]; | byte[] cipher = new byte[plain.Length + 16 + IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES]; | ||||
byte[] plain2 = new byte[plain.Length + 16]; | byte[] plain2 = new byte[plain.Length + 16]; | ||||
@@ -117,6 +118,7 @@ namespace test | |||||
{ | { | ||||
t.Join(); | t.Join(); | ||||
} | } | ||||
RNG.Close(); | |||||
Assert.IsFalse(encryptionFailed); | Assert.IsFalse(encryptionFailed); | ||||
} | } | ||||
@@ -156,6 +158,7 @@ namespace test | |||||
{ | { | ||||
t.Join(); | t.Join(); | ||||
} | } | ||||
RNG.Close(); | |||||
Assert.IsFalse(encryptionFailed); | Assert.IsFalse(encryptionFailed); | ||||
} | } | ||||
@@ -196,6 +199,7 @@ namespace test | |||||
{ | { | ||||
t.Join(); | t.Join(); | ||||
} | } | ||||
RNG.Close(); | |||||
Assert.IsFalse(encryptionFailed); | Assert.IsFalse(encryptionFailed); | ||||
} | } | ||||