@@ -272,6 +272,7 @@ namespace Shadowsocks.Controller | |||
{ | |||
SystemProxy.Update(_config, true); | |||
} | |||
Encryption.RNG.Close(); | |||
} | |||
public void TouchPACFile() | |||
@@ -413,6 +414,7 @@ namespace Shadowsocks.Controller | |||
protected void Reload() | |||
{ | |||
Encryption.RNG.Reload(); | |||
// some logic in configuration updated the config when saving, we need to read it again | |||
_config = Configuration.Load(); | |||
StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); | |||
@@ -1,8 +1,6 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Concurrent; | |||
using System.Linq; | |||
using System.Security.Cryptography; | |||
using System.Text; | |||
using System.Net; | |||
@@ -237,10 +235,7 @@ namespace Shadowsocks.Encryption | |||
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) | |||
@@ -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) | |||
{ | |||
Logging.Error(e.ExceptionObject?.ToString()); | |||
string errMsg = e.ExceptionObject.ToString(); | |||
Logging.Error(errMsg); | |||
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); | |||
Application.Exit(); | |||
} | |||
@@ -102,12 +103,15 @@ namespace Shadowsocks | |||
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) | |||
@@ -168,7 +172,10 @@ namespace Shadowsocks | |||
private static void Application_ApplicationExit(object sender, EventArgs e) | |||
{ | |||
// detach static event handlers | |||
Application.ApplicationExit -= Application_ApplicationExit; | |||
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; | |||
Application.ThreadException -= Application_ThreadException; | |||
HotKeys.Destroy(); | |||
if (_controller != null) | |||
{ | |||
@@ -183,6 +183,7 @@ | |||
<Compile Include="Util\Hotkeys.cs" /> | |||
<Compile Include="Util\ProcessManagement\Job.cs" /> | |||
<Compile Include="Util\ProcessManagement\ThreadUtil.cs" /> | |||
<Compile Include="Encryption\RNG.cs" /> | |||
<Compile Include="Util\Sockets\LineReader.cs" /> | |||
<Compile Include="Util\Sockets\SocketUtil.cs" /> | |||
<Compile Include="Util\Sockets\WrappedSocket.cs" /> | |||
@@ -68,6 +68,7 @@ namespace test | |||
private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor) | |||
{ | |||
RNG.Reload(); | |||
byte[] plain = new byte[16384]; | |||
byte[] cipher = new byte[plain.Length + 16 + IVEncryptor.ONETIMEAUTH_BYTES + IVEncryptor.AUTH_BYTES]; | |||
byte[] plain2 = new byte[plain.Length + 16]; | |||
@@ -117,6 +118,7 @@ namespace test | |||
{ | |||
t.Join(); | |||
} | |||
RNG.Close(); | |||
Assert.IsFalse(encryptionFailed); | |||
} | |||
@@ -156,6 +158,7 @@ namespace test | |||
{ | |||
t.Join(); | |||
} | |||
RNG.Close(); | |||
Assert.IsFalse(encryptionFailed); | |||
} | |||
@@ -196,6 +199,7 @@ namespace test | |||
{ | |||
t.Join(); | |||
} | |||
RNG.Close(); | |||
Assert.IsFalse(encryptionFailed); | |||
} | |||