Compare commits

...

16 Commits
main ... v4

Author SHA1 Message Date
  Max Lv 99871884bc
Merge pull request #3281 from shadowsocks/feature/plain-cipher 3 years ago
  Max Lv 3f6baa4102 cipher: add plain/none ciphers 3 years ago
  Bruce Wayne 1155ac546f
Update privoxy to 3.0.31 4 years ago
  database64128 dd6edbc7b4
💭 PAC: display message when geosite already latest 4 years ago
  database64128 ac0fcdfc8c
⚠ Warn when importing from legacy ss:// links 4 years ago
  database64128 a28efeee4b
🆙 Update docs and bump version to 4.4.0.0 4 years ago
  database64128 70a88b5794
🚱 Remove infrastructure of stream ciphers 4 years ago
  database64128 78915d805f
🔀 Merge pull request #3048 from studentmain/patch-1 4 years ago
  Student Main 5fa4ada43b
Update ShadowsocksTest.csproj 4 years ago
  Student Main ff37258c7f
Delete CryptographyTest.cs 4 years ago
  Student Main f2414a9e8e
Update EncryptorFactory.cs 4 years ago
  database64128 d79ba8fbcc
🎍 Clean some leftover stuff 4 years ago
  database64128 da568ad047
🆙 Update docs and bump version to 4.3.3.0 4 years ago
  database64128 38bee0888f
🎱 Update to .NET Framework 4.8 4 years ago
  database64128 f029738f2b
🧂 Add option for custom sha256sum URL of custom geosite source 4 years ago
  database64128 0284f4e035
🕳 Update `.gitignore` 4 years ago
28 changed files with 618 additions and 977 deletions
Unified View
  1. +363
    -9
      .gitignore
  2. +13
    -0
      CHANGES
  3. +2
    -5
      README.md
  4. +1
    -1
      appveyor.yml
  5. +42
    -26
      shadowsocks-csharp/Controller/Service/GeositeUpdater.cs
  6. +1
    -1
      shadowsocks-csharp/Controller/Service/UpdateChecker.cs
  7. +2
    -0
      shadowsocks-csharp/Controller/ShadowsocksController.cs
  8. +1
    -0
      shadowsocks-csharp/Data/i18n.csv
  9. BIN
      shadowsocks-csharp/Data/privoxy.exe.gz
  10. +18
    -2
      shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs
  11. +9
    -21
      shadowsocks-csharp/Encryption/EncryptorFactory.cs
  12. +98
    -0
      shadowsocks-csharp/Encryption/Stream/PlainEncryptor.cs
  13. +0
    -182
      shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs
  14. +0
    -155
      shadowsocks-csharp/Encryption/Stream/StreamMbedTLSEncryptor.cs
  15. +0
    -159
      shadowsocks-csharp/Encryption/Stream/StreamOpenSSLEncryptor.cs
  16. +0
    -107
      shadowsocks-csharp/Encryption/Stream/StreamSodiumEncryptor.cs
  17. +2
    -0
      shadowsocks-csharp/Model/Configuration.cs
  18. +4
    -4
      shadowsocks-csharp/Model/Server.cs
  19. +2
    -2
      shadowsocks-csharp/Program.cs
  20. +3
    -2
      shadowsocks-csharp/Properties/Resources.Designer.cs
  21. +1
    -1
      shadowsocks-csharp/Properties/Settings.Designer.cs
  22. +7
    -18
      shadowsocks-csharp/View/ConfigForm.cs
  23. +6
    -2
      shadowsocks-csharp/app.config
  24. +12
    -12
      shadowsocks-csharp/packages.config
  25. +27
    -30
      shadowsocks-csharp/shadowsocks-csharp.csproj
  26. +0
    -233
      test/CryptographyTest.cs
  27. +2
    -3
      test/ShadowsocksTest.csproj
  28. +2
    -2
      test/app.config

+ 363
- 9
.gitignore View File

@@ -1,12 +1,366 @@
/.vs/
Backup/
bin/
obj/
shadowsocks-csharp/shadowsocks-csharp.csproj.user
TestResults
## Ignore Visual Studio and VSCode temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
## and https://github.com/github/gitignore/blob/master/Global/VisualStudioCode.gitignore

# User-specific files
*.rsuser
*.suo *.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Mono auto generated files
mono_crash.*

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/

# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# Visual Studio 2017 auto generated files
Generated\ Files/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# Benchmark Results
BenchmarkDotNet.Artifacts/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/

# ASP.NET Scaffolding
ScaffoldingReadMe.txt

# StyleCop
StyleCopReport.xml

# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# Visual Studio Trace Files
*.e2e

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json

# Coverlet is a free, cross platform Code Coverage Tool
coverage*[.json, .xml, .info]

# Visual Studio code coverage results
*.coverage
*.coveragexml

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
# *.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak

# SQL Server files
*.mdf
*.ldf
*.ndf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# CodeRush personal settings
.cr/personal

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config

# Tabs Studio
*.tss

# Telerik's JustMock configuration file
*.jmconfig

# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

# OpenCover UI analysis results
OpenCover/

# Azure Stream Analytics local run output
ASALocalRun/

# MSBuild Binary and Structured Log
*.binlog

# NVidia Nsight GPU debugger configuration file
*.nvuser

# MFractors (Xamarin productivity tool) working folder
.mfractor/

# Local History for Visual Studio
.localhistory/

# BeatPulse healthcheck temp database
healthchecksdb

# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/


shadowsocks-csharp/3rd/*
packages/*
# Ionide (cross platform F# VS Code tools) working folder
.ionide/


shadowsocks-csharp.sln.DotSettings.user
# VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace

+ 13
- 0
CHANGES View File

@@ -1,3 +1,16 @@
4.4.1.0 2022-02-08
- Add plain/none ciphers
4.4.0.0 2021-01-01
- Security: remove infrastructure of stream ciphers (#3048)
- Show warning message when importing from deprecated legacy ss:// links.
- Other minor bug fixes and improvements
4.3.3.0 2020-12-07
- PAC: Add option for custom sha256sum URL of custom geosite source (#3026)
- Update to .NET Framework 4.8
- Other minor bug fixes and improvements
4.3.2.0 2020-11-05 4.3.2.0 2020-11-05
- PAC: direct connection for private IP ranges by @studentmain (#3008) - PAC: direct connection for private IP ranges by @studentmain (#3008)
- Remove duplicate startup entries (#3012) - Remove duplicate startup entries (#3012)


+ 2
- 5
README.md View File

@@ -21,7 +21,7 @@ Download the latest release from [release page].
## Requirements ## Requirements
Microsoft [.NET Framework 4.7.2] or higher, Microsoft [Visual C++ 2015 Redistributable] (x86) .
.NET Framework 4.8 or higher, Microsoft [Visual C++ 2015 Redistributable] (x86) .
## Basics ## Basics
@@ -127,7 +127,7 @@ Please visit [Servers] for more information.
## Development ## Development
1. [Visual Studio 2019] & [.NET Framework 4.7.2 Developer Pack] are required.
1. Visual Studio 2019 & .NET Framework 4.8 SDK are required.
2. It is recommended to share your idea on the Issue Board before you start to work, 2. It is recommended to share your idea on the Issue Board before you start to work,
especially for feature development. especially for feature development.
@@ -164,9 +164,6 @@ Sysproxy () https://github.com/Noisyfox/sysproxy
[GeoSite]: https://github.com/v2fly/domain-list-community [GeoSite]: https://github.com/v2fly/domain-list-community
[Servers]: https://github.com/shadowsocks/shadowsocks/wiki/Ports-and-Clients#linux--server-side [Servers]: https://github.com/shadowsocks/shadowsocks/wiki/Ports-and-Clients#linux--server-side
[中文说明]: https://github.com/shadowsocks/shadowsocks-windows/wiki/Shadowsocks-Windows-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E [中文说明]: https://github.com/shadowsocks/shadowsocks-windows/wiki/Shadowsocks-Windows-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
[Visual Studio 2017]: https://www.visualstudio.com/downloads/
[.NET Framework 4.7.2]: https://dotnet.microsoft.com/download/dotnet-framework/net472
[.NET Framework 4.7.2 Developer Pack]: https://dotnet.microsoft.com/download/dotnet-framework/net472
[Visual C++ 2015 Redistributable]: https://www.microsoft.com/en-us/download/details.aspx?id=53840 [Visual C++ 2015 Redistributable]: https://www.microsoft.com/en-us/download/details.aspx?id=53840
[GPLv3]: https://github.com/shadowsocks/shadowsocks-windows/blob/master/LICENSE.txt [GPLv3]: https://github.com/shadowsocks/shadowsocks-windows/blob/master/LICENSE.txt
[Working with non SIP003 standard Plugin]: https://github.com/shadowsocks/shadowsocks-windows/wiki/Working-with-non-SIP003-standard-Plugin [Working with non SIP003 standard Plugin]: https://github.com/shadowsocks/shadowsocks-windows/wiki/Working-with-non-SIP003-standard-Plugin

+ 1
- 1
appveyor.yml View File

@@ -11,7 +11,7 @@
# version format # version format
# Build version format is taken from UI if it is not set # Build version format is taken from UI if it is not set
version: 4.3.2.{build}
version: 4.4.1.{build}
# # branches to build # # branches to build
# branches: # branches:


+ 42
- 26
shadowsocks-csharp/Controller/Service/GeositeUpdater.cs View File

@@ -75,52 +75,68 @@ namespace Shadowsocks.Controller


public static async Task UpdatePACFromGeosite() public static async Task UpdatePACFromGeosite()
{ {
string geositeUrl = GEOSITE_URL;
string geositeSha256sumUrl = GEOSITE_SHA256SUM_URL;
SHA256 mySHA256 = SHA256.Create();
var geositeUrl = GEOSITE_URL;
var geositeSha256sumUrl = GEOSITE_SHA256SUM_URL;
var geositeVerifySha256 = true;
var geositeSha256sum = "";
var mySHA256 = SHA256.Create();
var config = Program.MainController.GetCurrentConfiguration(); var config = Program.MainController.GetCurrentConfiguration();
bool blacklist = config.geositePreferDirect;
var blacklist = config.geositePreferDirect;
var httpClient = Program.MainController.GetHttpClient(); var httpClient = Program.MainController.GetHttpClient();


if (!string.IsNullOrWhiteSpace(config.geositeUrl)) if (!string.IsNullOrWhiteSpace(config.geositeUrl))
{ {
logger.Info("Found custom Geosite URL in config file"); logger.Info("Found custom Geosite URL in config file");
geositeUrl = config.geositeUrl; geositeUrl = config.geositeUrl;
geositeSha256sumUrl = config.geositeSha256sumUrl;
if (string.IsNullOrWhiteSpace(geositeSha256sumUrl))
{
geositeVerifySha256 = false;
logger.Info("Geosite SHA256 verification is disabled.");
}
} }
logger.Info($"Checking Geosite from {geositeUrl}"); logger.Info($"Checking Geosite from {geositeUrl}");


try try
{ {
// download checksum first
var geositeSha256sum = await httpClient.GetStringAsync(geositeSha256sumUrl);
geositeSha256sum = geositeSha256sum.Substring(0, 64).ToUpper();
logger.Info($"Got Sha256sum: {geositeSha256sum}");
// compare downloaded checksum with local geositeDB
byte[] localDBHashBytes = mySHA256.ComputeHash(geositeDB);
string localDBHash = BitConverter.ToString(localDBHashBytes).Replace("-", String.Empty);
logger.Info($"Local Sha256sum: {localDBHash}");
// if already latest
if (geositeSha256sum == localDBHash)
// Use sha256sum to check if local database is already latest.
if (geositeVerifySha256)
{ {
logger.Info("Local GeoSite DB is up to date.");
return;
// download checksum first
geositeSha256sum = await httpClient.GetStringAsync(geositeSha256sumUrl);
geositeSha256sum = geositeSha256sum.Substring(0, 64).ToUpper();
logger.Info($"Got Sha256sum: {geositeSha256sum}");
// compare downloaded checksum with local geositeDB
byte[] localDBHashBytes = mySHA256.ComputeHash(geositeDB);
string localDBHash = BitConverter.ToString(localDBHashBytes).Replace("-", String.Empty);
logger.Info($"Local Sha256sum: {localDBHash}");
// if already latest
if (geositeSha256sum == localDBHash)
{
logger.Info("Local GeoSite DB is up to date.");
UpdateCompleted?.Invoke(null, new GeositeResultEventArgs(false));
return;
}
} }


// not latest. download new DB // not latest. download new DB
var downloadedBytes = await httpClient.GetByteArrayAsync(geositeUrl); var downloadedBytes = await httpClient.GetByteArrayAsync(geositeUrl);


// verify sha256sum // verify sha256sum
byte[] downloadedDBHashBytes = mySHA256.ComputeHash(downloadedBytes);
string downloadedDBHash = BitConverter.ToString(downloadedDBHashBytes).Replace("-", String.Empty);
logger.Info($"Actual Sha256sum: {downloadedDBHash}");
if (geositeSha256sum != downloadedDBHash)
{
logger.Info("Sha256sum Verification: FAILED. Downloaded GeoSite DB is corrupted. Aborting the update.");
throw new Exception("Sha256sum mismatch");
}
else
if (geositeVerifySha256)
{ {
logger.Info("Sha256sum Verification: PASSED. Applying to local GeoSite DB.");
byte[] downloadedDBHashBytes = mySHA256.ComputeHash(downloadedBytes);
string downloadedDBHash = BitConverter.ToString(downloadedDBHashBytes).Replace("-", String.Empty);
logger.Info($"Actual Sha256sum: {downloadedDBHash}");
if (geositeSha256sum != downloadedDBHash)
{
logger.Info("Sha256sum Verification: FAILED. Downloaded GeoSite DB is corrupted. Aborting the update.");
throw new Exception("Sha256sum mismatch");
}
else
{
logger.Info("Sha256sum Verification: PASSED. Applying to local GeoSite DB.");
}
} }


// write to geosite file // write to geosite file


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

@@ -33,7 +33,7 @@ namespace Shadowsocks.Controller
public event EventHandler CheckUpdateCompleted; public event EventHandler CheckUpdateCompleted;
public const string Version = "4.3.2.0";
public const string Version = "4.4.1.0";
private readonly Version _version; private readonly Version _version;
public UpdateChecker() public UpdateChecker()


+ 2
- 0
shadowsocks-csharp/Controller/ShadowsocksController.cs View File

@@ -450,6 +450,8 @@ namespace Shadowsocks.Controller
foreach (var server in servers) foreach (var server in servers)
{ {
_config.configs.Add(server); _config.configs.Add(server);
if (server.warnLegacyUrl)
MessageBox.Show(I18N.GetString("Warning: importing {0} from a legacy ss:// link. Support for legacy ss:// links will be dropped in version 5. Make sure to update your ss:// links.", server.ToString()));
} }
_config.index = _config.configs.Count - 1; _config.index = _config.configs.Count - 1;
SaveConfig(_config); SaveConfig(_config);


+ 1
- 0
shadowsocks-csharp/Data/i18n.csv View File

@@ -133,6 +133,7 @@ Failed to update registry,Не удалось обновить запись в
Import from URL: {0} ?,импортировать из адреса: {0} ?,从URL导入: {0} ?,從URL匯入: {0} ?,{0}:このURLからインポートしますか?,, Import from URL: {0} ?,импортировать из адреса: {0} ?,从URL导入: {0} ?,從URL匯入: {0} ?,{0}:このURLからインポートしますか?,,
Successfully imported from {0},Успешно импортировано из {0},导入成功:{0},導入成功:{0},{0}:インポートしました。,, Successfully imported from {0},Успешно импортировано из {0},导入成功:{0},導入成功:{0},{0}:インポートしました。,,
Failed to import. Please check if the link is valid.,,导入失败,请检查链接是否有效。,導入失敗,請檢查鏈接是否有效。,インポートに失敗しました。リンクの有効性を確認してください。,, Failed to import. Please check if the link is valid.,,导入失败,请检查链接是否有效。,導入失敗,請檢查鏈接是否有效。,インポートに失敗しました。リンクの有効性を確認してください。,,
Warning: importing {0} from a legacy ss:// link. Support for legacy ss:// links will be dropped in version 5. Make sure to update your ss:// links.,,警告: 正在从旧版 ss:// 链接导入 {0}。对旧版 ss:// 链接的支持将于 v5 移除,请及时更新你的链接。,,,,
System Proxy On: ,Системный прокси:,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効:,시스템 프록시 활성화됨: ,Proxy système activé: System Proxy On: ,Системный прокси:,系统代理已启用:,系統 Proxy 已啟用:,システム プロキシが有効:,시스템 프록시 활성화됨: ,Proxy système activé:
Running: Port {0},Запущен на порту {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0},실행 중: 포트 {0}번,En cours d'exécution: port {0} Running: Port {0},Запущен на порту {0},正在运行:端口 {0},正在執行:連接埠號碼 {0},実行中:ポート {0},실행 중: 포트 {0}번,En cours d'exécution: port {0}
"Unexpected error, shadowsocks will exit. Please report to","Непредвиденная ошибка, пожалуйста сообщите на",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい:,알 수 없는 오류로 Shadowsocks가 종료될 것입니다. 오류를 여기로 제보해주세요:,Shadowsocks va quitter en présence d/érreur inattendue. Veuillez signaler à "Unexpected error, shadowsocks will exit. Please report to","Непредвиденная ошибка, пожалуйста сообщите на",非预期错误,Shadowsocks将退出。请提交此错误到,非預期錯誤,Shadowsocks 將結束。請報告此錯誤至,予想外のエラーが発生したため、Shadowsocks を終了します。詳しくは下記までお問い合わせ下さい:,알 수 없는 오류로 Shadowsocks가 종료될 것입니다. 오류를 여기로 제보해주세요:,Shadowsocks va quitter en présence d/érreur inattendue. Veuillez signaler à


BIN
shadowsocks-csharp/Data/privoxy.exe.gz View File


+ 18
- 2
shadowsocks-csharp/Encryption/AEAD/AEADEncryptor.cs View File

@@ -7,7 +7,6 @@ using System.Text;
using Shadowsocks.Encryption.CircularBuffer; using Shadowsocks.Encryption.CircularBuffer;
using Shadowsocks.Controller; using Shadowsocks.Controller;
using Shadowsocks.Encryption.Exception; using Shadowsocks.Encryption.Exception;
using Shadowsocks.Encryption.Stream;
namespace Shadowsocks.Encryption.AEAD namespace Shadowsocks.Encryption.AEAD
{ {
@@ -98,7 +97,24 @@ namespace Shadowsocks.Encryption.AEAD
public void DeriveKey(byte[] password, byte[] key, int keylen) public void DeriveKey(byte[] password, byte[] key, int keylen)
{ {
StreamEncryptor.LegacyDeriveKey(password, key, keylen);
byte[] result = new byte[password.Length + MD5_LEN];
int i = 0;
byte[] md5sum = null;
while (i < keylen)
{
if (i == 0)
{
md5sum = MbedTLS.MD5(password);
}
else
{
Array.Copy(md5sum, 0, result, 0, MD5_LEN);
Array.Copy(password, 0, result, MD5_LEN, password.Length);
md5sum = MbedTLS.MD5(result);
}
Array.Copy(md5sum, 0, key, i, Math.Min(MD5_LEN, keylen - i));
i += MD5_LEN;
}
} }
public void DeriveSessionKey(byte[] salt, byte[] masterKey, byte[] sessionKey) public void DeriveSessionKey(byte[] salt, byte[] masterKey, byte[] sessionKey)


+ 9
- 21
shadowsocks-csharp/Encryption/EncryptorFactory.cs View File

@@ -17,6 +17,8 @@ namespace Shadowsocks.Encryption
{ {
var AEADMbedTLSEncryptorSupportedCiphers = AEADMbedTLSEncryptor.SupportedCiphers(); var AEADMbedTLSEncryptorSupportedCiphers = AEADMbedTLSEncryptor.SupportedCiphers();
var AEADSodiumEncryptorSupportedCiphers = AEADSodiumEncryptor.SupportedCiphers(); var AEADSodiumEncryptorSupportedCiphers = AEADSodiumEncryptor.SupportedCiphers();
var PlainEncryptorSupportedCiphers = PlainEncryptor.SupportedCiphers();
if (Sodium.AES256GCMAvailable) if (Sodium.AES256GCMAvailable)
{ {
// prefer to aes-256-gcm in libsodium // prefer to aes-256-gcm in libsodium
@@ -27,26 +29,6 @@ namespace Shadowsocks.Encryption
AEADSodiumEncryptorSupportedCiphers.Remove("aes-256-gcm"); AEADSodiumEncryptorSupportedCiphers.Remove("aes-256-gcm");
} }
// XXX: sequence matters, OpenSSL > Sodium > MbedTLS
foreach (string method in StreamOpenSSLEncryptor.SupportedCiphers())
{
if (!_registeredEncryptors.ContainsKey(method))
_registeredEncryptors.Add(method, typeof(StreamOpenSSLEncryptor));
}
foreach (string method in StreamSodiumEncryptor.SupportedCiphers())
{
if (!_registeredEncryptors.ContainsKey(method))
_registeredEncryptors.Add(method, typeof(StreamSodiumEncryptor));
}
foreach (string method in StreamMbedTLSEncryptor.SupportedCiphers())
{
if (!_registeredEncryptors.ContainsKey(method))
_registeredEncryptors.Add(method, typeof(StreamMbedTLSEncryptor));
}
foreach (string method in AEADOpenSSLEncryptor.SupportedCiphers()) foreach (string method in AEADOpenSSLEncryptor.SupportedCiphers())
{ {
if (!_registeredEncryptors.ContainsKey(method)) if (!_registeredEncryptors.ContainsKey(method))
@@ -64,6 +46,12 @@ namespace Shadowsocks.Encryption
if (!_registeredEncryptors.ContainsKey(method)) if (!_registeredEncryptors.ContainsKey(method))
_registeredEncryptors.Add(method, typeof(AEADMbedTLSEncryptor)); _registeredEncryptors.Add(method, typeof(AEADMbedTLSEncryptor));
} }
foreach (string method in PlainEncryptorSupportedCiphers)
{
if (!_registeredEncryptors.ContainsKey(method))
_registeredEncryptors.Add(method, typeof(PlainEncryptor));
}
} }
public static IEncryptor GetEncryptor(string method, string password) public static IEncryptor GetEncryptor(string method, string password)
@@ -97,4 +85,4 @@ namespace Shadowsocks.Encryption
return sb.ToString(); return sb.ToString();
} }
} }
}
}

+ 98
- 0
shadowsocks-csharp/Encryption/Stream/PlainEncryptor.cs View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;

namespace Shadowsocks.Encryption.Stream
{
class PlainEncryptor
: EncryptorBase, IDisposable
{
const int CIPHER_NONE = 1;

private static Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo> {
{ "plain", new EncryptorInfo("PLAIN", 0, 0, CIPHER_NONE) },
{ "none", new EncryptorInfo("PLAIN", 0, 0, CIPHER_NONE) }
};

public PlainEncryptor(string method, string password) : base(method, password)
{
}

public static List<string> SupportedCiphers()
{
return new List<string>(_ciphers.Keys);
}

protected Dictionary<string, EncryptorInfo> getCiphers()
{
return _ciphers;
}

#region TCP

public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
{
Buffer.BlockCopy(buf, 0, outbuf, 0, length);
outlength = length;
}

public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
{
Buffer.BlockCopy(buf, 0, outbuf, 0, length);
outlength = length;
}

#endregion

#region UDP

public override void EncryptUDP(byte[] buf, int length, byte[] outbuf, out int outlength)
{
Buffer.BlockCopy(buf, 0, outbuf, 0, length);
outlength = length;
}

public override void DecryptUDP(byte[] buf, int length, byte[] outbuf, out int outlength)
{
Buffer.BlockCopy(buf, 0, outbuf, 0, length);
outlength = length;
}

#endregion


#region IDisposable

private bool _disposed;

// instance based lock
private readonly object _lock = new object();

public override void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

~PlainEncryptor()
{
Dispose(false);
}

protected virtual void Dispose(bool disposing)
{
lock (_lock)
{
if (_disposed) return;
_disposed = true;
}

if (disposing)
{
// free managed objects
}
}

#endregion

}
}

+ 0
- 182
shadowsocks-csharp/Encryption/Stream/StreamEncryptor.cs View File

@@ -1,182 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Shadowsocks.Encryption.CircularBuffer;
using Shadowsocks.Controller;
namespace Shadowsocks.Encryption.Stream
{
public abstract class StreamEncryptor
: EncryptorBase
{
// for UDP only
protected static byte[] _udpTmpBuf = new byte[65536];
// every connection should create its own buffer
private ByteCircularBuffer _encCircularBuffer = new ByteCircularBuffer(TCPHandler.BufferSize * 2);
private ByteCircularBuffer _decCircularBuffer = new ByteCircularBuffer(TCPHandler.BufferSize * 2);
protected Dictionary<string, EncryptorInfo> ciphers;
protected byte[] _encryptIV;
protected byte[] _decryptIV;
// Is first packet
protected bool _decryptIVReceived;
protected bool _encryptIVSent;
protected string _method;
protected int _cipher;
// internal name in the crypto library
protected string _innerLibName;
protected EncryptorInfo CipherInfo;
// long-time master key
protected static byte[] _key = null;
protected int keyLen;
protected int ivLen;
public StreamEncryptor(string method, string password)
: base(method, password)
{
InitEncryptorInfo(method);
InitKey(password);
}
protected abstract Dictionary<string, EncryptorInfo> getCiphers();
private void InitEncryptorInfo(string method)
{
method = method.ToLower();
_method = method;
ciphers = getCiphers();
CipherInfo = ciphers[_method];
_innerLibName = CipherInfo.InnerLibName;
_cipher = CipherInfo.Type;
if (_cipher == 0) {
throw new System.Exception("method not found");
}
keyLen = CipherInfo.KeySize;
ivLen = CipherInfo.IvSize;
}
private void InitKey(string password)
{
byte[] passbuf = Encoding.UTF8.GetBytes(password);
if (_key == null) _key = new byte[keyLen];
if (_key.Length != keyLen) Array.Resize(ref _key, keyLen);
LegacyDeriveKey(passbuf, _key, keyLen);
}
public static void LegacyDeriveKey(byte[] password, byte[] key, int keylen)
{
byte[] result = new byte[password.Length + MD5_LEN];
int i = 0;
byte[] md5sum = null;
while (i < keylen) {
if (i == 0) {
md5sum = MbedTLS.MD5(password);
} else {
Array.Copy(md5sum, 0, result, 0, MD5_LEN);
Array.Copy(password, 0, result, MD5_LEN, password.Length);
md5sum = MbedTLS.MD5(result);
}
Array.Copy(md5sum, 0, key, i, Math.Min(MD5_LEN, keylen - i));
i += MD5_LEN;
}
}
protected virtual void initCipher(byte[] iv, bool isEncrypt)
{
if (isEncrypt) {
_encryptIV = new byte[ivLen];
Array.Copy(iv, _encryptIV, ivLen);
} else {
_decryptIV = new byte[ivLen];
Array.Copy(iv, _decryptIV, ivLen);
}
}
protected abstract void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf);
protected static void randBytes(byte[] buf, int length) { RNG.GetBytes(buf, length); }
#region TCP
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
{
int cipherOffset = 0;
Debug.Assert(_encCircularBuffer != null, "_encCircularBuffer != null");
_encCircularBuffer.Put(buf, 0, length);
if (! _encryptIVSent) {
// Generate IV
byte[] ivBytes = new byte[ivLen];
randBytes(ivBytes, ivLen);
initCipher(ivBytes, true);
Array.Copy(ivBytes, 0, outbuf, 0, ivLen);
cipherOffset = ivLen;
_encryptIVSent = true;
}
int size = _encCircularBuffer.Size;
byte[] plain = _encCircularBuffer.Get(size);
byte[] cipher = new byte[size];
cipherUpdate(true, size, plain, cipher);
Buffer.BlockCopy(cipher, 0, outbuf, cipherOffset, size);
outlength = size + cipherOffset;
}
public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
{
Debug.Assert(_decCircularBuffer != null, "_circularBuffer != null");
_decCircularBuffer.Put(buf, 0, length);
if (! _decryptIVReceived) {
if (_decCircularBuffer.Size <= ivLen) {
// we need more data
outlength = 0;
return;
}
// start decryption
_decryptIVReceived = true;
byte[] iv = _decCircularBuffer.Get(ivLen);
initCipher(iv, false);
}
byte[] cipher = _decCircularBuffer.ToArray();
cipherUpdate(false, cipher.Length, cipher, outbuf);
// move pointer only
_decCircularBuffer.Skip(_decCircularBuffer.Size);
outlength = cipher.Length;
// done the decryption
}
#endregion
#region UDP
public override void EncryptUDP(byte[] buf, int length, byte[] outbuf, out int outlength)
{
// Generate IV
randBytes(outbuf, ivLen);
initCipher(outbuf, true);
lock (_udpTmpBuf) {
cipherUpdate(true, length, buf, _udpTmpBuf);
outlength = length + ivLen;
Buffer.BlockCopy(_udpTmpBuf, 0, outbuf, ivLen, length);
}
}
public override void DecryptUDP(byte[] buf, int length, byte[] outbuf, out int outlength)
{
// Get IV from first pos
initCipher(buf, false);
outlength = length - ivLen;
lock (_udpTmpBuf) {
// C# could be multi-threaded
Buffer.BlockCopy(buf, ivLen, _udpTmpBuf, 0, length - ivLen);
cipherUpdate(false, length - ivLen, _udpTmpBuf, outbuf);
}
}
#endregion
}
}

+ 0
- 155
shadowsocks-csharp/Encryption/Stream/StreamMbedTLSEncryptor.cs View File

@@ -1,155 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Shadowsocks.Encryption.Exception;
namespace Shadowsocks.Encryption.Stream
{
public class StreamMbedTLSEncryptor
: StreamEncryptor, IDisposable
{
const int CIPHER_RC4 = 1;
const int CIPHER_AES = 2;
const int CIPHER_BLOWFISH = 3;
const int CIPHER_CAMELLIA = 4;
private IntPtr _encryptCtx = IntPtr.Zero;
private IntPtr _decryptCtx = IntPtr.Zero;
public StreamMbedTLSEncryptor(string method, string password)
: base(method, password)
{
}
private static Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo> {
{ "aes-128-cfb", new EncryptorInfo("AES-128-CFB128", 16, 16, CIPHER_AES) },
{ "aes-192-cfb", new EncryptorInfo("AES-192-CFB128", 24, 16, CIPHER_AES) },
{ "aes-256-cfb", new EncryptorInfo("AES-256-CFB128", 32, 16, CIPHER_AES) },
{ "aes-128-ctr", new EncryptorInfo("AES-128-CTR", 16, 16, CIPHER_AES) },
{ "aes-192-ctr", new EncryptorInfo("AES-192-CTR", 24, 16, CIPHER_AES) },
{ "aes-256-ctr", new EncryptorInfo("AES-256-CTR", 32, 16, CIPHER_AES) },
{ "bf-cfb", new EncryptorInfo("BLOWFISH-CFB64", 16, 8, CIPHER_BLOWFISH) },
{ "camellia-128-cfb", new EncryptorInfo("CAMELLIA-128-CFB128", 16, 16, CIPHER_CAMELLIA) },
{ "camellia-192-cfb", new EncryptorInfo("CAMELLIA-192-CFB128", 24, 16, CIPHER_CAMELLIA) },
{ "camellia-256-cfb", new EncryptorInfo("CAMELLIA-256-CFB128", 32, 16, CIPHER_CAMELLIA) },
{ "rc4-md5", new EncryptorInfo("ARC4-128", 16, 16, CIPHER_RC4) }
};
public static List<string> SupportedCiphers()
{
return new List<string>(_ciphers.Keys);
}
protected override Dictionary<string, EncryptorInfo> getCiphers()
{
return _ciphers;
}
protected override void initCipher(byte[] iv, bool isEncrypt)
{
base.initCipher(iv, isEncrypt);
IntPtr ctx = Marshal.AllocHGlobal(MbedTLS.cipher_get_size_ex());
if (isEncrypt)
{
_encryptCtx = ctx;
}
else
{
_decryptCtx = ctx;
}
byte[] realkey;
if (_method == "rc4-md5")
{
byte[] temp = new byte[keyLen + ivLen];
Array.Copy(_key, 0, temp, 0, keyLen);
Array.Copy(iv, 0, temp, keyLen, ivLen);
realkey = MbedTLS.MD5(temp);
}
else
{
realkey = _key;
}
MbedTLS.cipher_init(ctx);
if (MbedTLS.cipher_setup( ctx, MbedTLS.cipher_info_from_string( _innerLibName ) ) != 0 )
throw new System.Exception("Cannot initialize mbed TLS cipher context");
/*
* MbedTLS takes key length by bit
* cipher_setkey() will set the correct key schedule
* and operation
*
* MBEDTLS_AES_{EN,DE}CRYPT
* == MBEDTLS_BLOWFISH_{EN,DE}CRYPT
* == MBEDTLS_CAMELLIA_{EN,DE}CRYPT
* == MBEDTLS_{EN,DE}CRYPT
*
*/
if (MbedTLS.cipher_setkey(ctx, realkey, keyLen * 8,
isEncrypt ? MbedTLS.MBEDTLS_ENCRYPT : MbedTLS.MBEDTLS_DECRYPT) != 0 )
throw new System.Exception("Cannot set mbed TLS cipher key");
if (MbedTLS.cipher_set_iv(ctx, iv, ivLen) != 0)
throw new System.Exception("Cannot set mbed TLS cipher IV");
if (MbedTLS.cipher_reset(ctx) != 0)
throw new System.Exception("Cannot finalize mbed TLS cipher context");
}
protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf)
{
// C# could be multi-threaded
if (_disposed)
{
throw new ObjectDisposedException(this.ToString());
}
if (MbedTLS.cipher_update(isEncrypt ? _encryptCtx : _decryptCtx,
buf, length, outbuf, ref length) != 0 )
throw new CryptoErrorException();
}
#region IDisposable
private bool _disposed;
// instance based lock
private readonly object _lock = new object();
public override void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~StreamMbedTLSEncryptor()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
lock (_lock)
{
if (_disposed) return;
_disposed = true;
}
if (disposing)
{
// free managed objects
}
// free unmanaged objects
if (_encryptCtx != IntPtr.Zero)
{
MbedTLS.cipher_free(_encryptCtx);
Marshal.FreeHGlobal(_encryptCtx);
_encryptCtx = IntPtr.Zero;
}
if (_decryptCtx != IntPtr.Zero)
{
MbedTLS.cipher_free(_decryptCtx);
Marshal.FreeHGlobal(_decryptCtx);
_decryptCtx = IntPtr.Zero;
}
}
#endregion
}
}

+ 0
- 159
shadowsocks-csharp/Encryption/Stream/StreamOpenSSLEncryptor.cs View File

@@ -1,159 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Shadowsocks.Encryption.Exception;
namespace Shadowsocks.Encryption.Stream
{
public class StreamOpenSSLEncryptor
: StreamEncryptor, IDisposable
{
const int CIPHER_RC4 = 1;
const int CIPHER_AES = 2;
const int CIPHER_CAMELLIA = 3;
const int CIPHER_BLOWFISH = 4;
const int CIPHER_CHACHA20_IETF = 5;
private IntPtr _encryptCtx = IntPtr.Zero;
private IntPtr _decryptCtx = IntPtr.Zero;
public StreamOpenSSLEncryptor(string method, string password)
: base(method, password)
{
}
// XXX: name=RC4,blkSz=1,keyLen=16,ivLen=0, do NOT pass IV to it
private static readonly Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo>
{
{ "aes-128-cfb", new EncryptorInfo("AES-128-CFB", 16, 16, CIPHER_AES) },
{ "aes-192-cfb", new EncryptorInfo("AES-192-CFB", 24, 16, CIPHER_AES) },
{ "aes-256-cfb", new EncryptorInfo("AES-256-CFB", 32, 16, CIPHER_AES) },
{ "aes-128-ctr", new EncryptorInfo("aes-128-ctr", 16, 16, CIPHER_AES) },
{ "aes-192-ctr", new EncryptorInfo("aes-192-ctr", 24, 16, CIPHER_AES) },
{ "aes-256-ctr", new EncryptorInfo("aes-256-ctr", 32, 16, CIPHER_AES) },
{ "bf-cfb", new EncryptorInfo("bf-cfb", 16, 8, CIPHER_BLOWFISH) },
{ "camellia-128-cfb", new EncryptorInfo("CAMELLIA-128-CFB", 16, 16, CIPHER_CAMELLIA) },
{ "camellia-192-cfb", new EncryptorInfo("CAMELLIA-192-CFB", 24, 16, CIPHER_CAMELLIA) },
{ "camellia-256-cfb", new EncryptorInfo("CAMELLIA-256-CFB", 32, 16, CIPHER_CAMELLIA) },
{ "rc4-md5", new EncryptorInfo("RC4", 16, 16, CIPHER_RC4) },
// it's using ivLen=16, not compatible
//{ "chacha20-ietf", new EncryptorInfo("chacha20", 32, 12, CIPHER_CHACHA20_IETF) }
};
public static List<string> SupportedCiphers()
{
return new List<string>(_ciphers.Keys);
}
protected override Dictionary<string, EncryptorInfo> getCiphers()
{
return _ciphers;
}
protected override void initCipher(byte[] iv, bool isEncrypt)
{
base.initCipher(iv, isEncrypt);
IntPtr cipherInfo = OpenSSL.GetCipherInfo(_innerLibName);
if (cipherInfo == IntPtr.Zero) throw new System.Exception("openssl: cipher not found");
IntPtr ctx = OpenSSL.EVP_CIPHER_CTX_new();
if (ctx == IntPtr.Zero) throw new System.Exception("fail to create ctx");
if (isEncrypt)
{
_encryptCtx = ctx;
}
else
{
_decryptCtx = ctx;
}
byte[] realkey;
if (_method == "rc4-md5")
{
byte[] temp = new byte[keyLen + ivLen];
Array.Copy(_key, 0, temp, 0, keyLen);
Array.Copy(iv, 0, temp, keyLen, ivLen);
realkey = MbedTLS.MD5(temp);
}
else
{
realkey = _key;
}
var ret = OpenSSL.EVP_CipherInit_ex(ctx, cipherInfo, IntPtr.Zero, null,null,
isEncrypt ? OpenSSL.OPENSSL_ENCRYPT : OpenSSL.OPENSSL_DECRYPT);
if (ret != 1) throw new System.Exception("openssl: fail to set key length");
ret = OpenSSL.EVP_CIPHER_CTX_set_key_length(ctx, keyLen);
if (ret != 1) throw new System.Exception("openssl: fail to set key length");
ret = OpenSSL.EVP_CipherInit_ex(ctx, IntPtr.Zero, IntPtr.Zero, realkey,
_method == "rc4-md5" ? null : iv,
isEncrypt ? OpenSSL.OPENSSL_ENCRYPT : OpenSSL.OPENSSL_DECRYPT);
if (ret != 1) throw new System.Exception("openssl: cannot set key and iv");
OpenSSL.EVP_CIPHER_CTX_set_padding(ctx, 0);
}
protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf)
{
// C# could be multi-threaded
if (_disposed)
{
throw new ObjectDisposedException(this.ToString());
}
int outlen = 0;
var ret = OpenSSL.EVP_CipherUpdate(isEncrypt ? _encryptCtx : _decryptCtx,
outbuf, out outlen, buf, length);
if (ret != 1)
throw new CryptoErrorException(String.Format("ret is {0}", ret));
Debug.Assert(outlen == length);
}
#region IDisposable
private bool _disposed;
// instance based lock
private readonly object _lock = new object();
public override void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~StreamOpenSSLEncryptor()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
lock (_lock)
{
if (_disposed) return;
_disposed = true;
}
if (disposing)
{
// free managed objects
}
// free unmanaged objects
if (_encryptCtx != IntPtr.Zero)
{
OpenSSL.EVP_CIPHER_CTX_free(_encryptCtx);
_encryptCtx = IntPtr.Zero;
}
if (_decryptCtx != IntPtr.Zero)
{
OpenSSL.EVP_CIPHER_CTX_free(_decryptCtx);
_decryptCtx = IntPtr.Zero;
}
}
#endregion
}
}

+ 0
- 107
shadowsocks-csharp/Encryption/Stream/StreamSodiumEncryptor.cs View File

@@ -1,107 +0,0 @@
using System;
using System.Collections.Generic;
using Shadowsocks.Encryption.Exception;
namespace Shadowsocks.Encryption.Stream
{
public class StreamSodiumEncryptor
: StreamEncryptor, IDisposable
{
const int CIPHER_SALSA20 = 1;
const int CIPHER_CHACHA20 = 2;
const int CIPHER_CHACHA20_IETF = 3;
const int SODIUM_BLOCK_SIZE = 64;
protected int _encryptBytesRemaining;
protected int _decryptBytesRemaining;
protected ulong _encryptIC;
protected ulong _decryptIC;
protected byte[] _encryptBuf;
protected byte[] _decryptBuf;
public StreamSodiumEncryptor(string method, string password)
: base(method, password)
{
_encryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
_decryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE];
}
private static readonly Dictionary<string, EncryptorInfo> _ciphers = new Dictionary<string, EncryptorInfo> {
{ "salsa20", new EncryptorInfo(32, 8, CIPHER_SALSA20) },
{ "chacha20", new EncryptorInfo(32, 8, CIPHER_CHACHA20) },
{ "chacha20-ietf", new EncryptorInfo(32, 12, CIPHER_CHACHA20_IETF) }
};
protected override Dictionary<string, EncryptorInfo> getCiphers()
{
return _ciphers;
}
public static List<string> SupportedCiphers()
{
return new List<string>(_ciphers.Keys);
}
protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf)
{
// TODO write a unidirection cipher so we don't have to if if if
int bytesRemaining;
ulong ic;
byte[] sodiumBuf;
byte[] iv;
int ret = -1;
if (isEncrypt)
{
bytesRemaining = _encryptBytesRemaining;
ic = _encryptIC;
sodiumBuf = _encryptBuf;
iv = _encryptIV;
}
else
{
bytesRemaining = _decryptBytesRemaining;
ic = _decryptIC;
sodiumBuf = _decryptBuf;
iv = _decryptIV;
}
int padding = bytesRemaining;
Buffer.BlockCopy(buf, 0, sodiumBuf, padding, length);
switch (_cipher)
{
case CIPHER_SALSA20:
ret = Sodium.crypto_stream_salsa20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
case CIPHER_CHACHA20:
ret = Sodium.crypto_stream_chacha20_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, ic, _key);
break;
case CIPHER_CHACHA20_IETF:
ret = Sodium.crypto_stream_chacha20_ietf_xor_ic(sodiumBuf, sodiumBuf, (ulong)(padding + length), iv, (uint)ic, _key);
break;
}
if (ret != 0) throw new CryptoErrorException();
Buffer.BlockCopy(sodiumBuf, padding, outbuf, 0, length);
padding += length;
ic += (ulong)padding / SODIUM_BLOCK_SIZE;
bytesRemaining = padding % SODIUM_BLOCK_SIZE;
if (isEncrypt)
{
_encryptBytesRemaining = bytesRemaining;
_encryptIC = ic;
}
else
{
_decryptBytesRemaining = bytesRemaining;
_decryptIC = ic;
}
}
public override void Dispose()
{
}
}
}

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

@@ -46,6 +46,7 @@ namespace Shadowsocks.Model
public bool isIPv6Enabled; // for experimental ipv6 support public bool isIPv6Enabled; // for experimental ipv6 support
public bool generateLegacyUrl; // for pre-sip002 url compatibility public bool generateLegacyUrl; // for pre-sip002 url compatibility
public string geositeUrl; // for custom geosite source (and rule group) public string geositeUrl; // for custom geosite source (and rule group)
public string geositeSha256sumUrl; // optional custom sha256sum url, leave empty to disable checksum verification for your custom geosite source
public List<string> geositeDirectGroups; // groups of domains that we connect without the proxy public List<string> geositeDirectGroups; // groups of domains that we connect without the proxy
public List<string> geositeProxiedGroups; // groups of domains that we connect via the proxy public List<string> geositeProxiedGroups; // groups of domains that we connect via the proxy
public bool geositePreferDirect; // a.k.a blacklist mode public bool geositePreferDirect; // a.k.a blacklist mode
@@ -84,6 +85,7 @@ namespace Shadowsocks.Model
isIPv6Enabled = false; isIPv6Enabled = false;
generateLegacyUrl = false; generateLegacyUrl = false;
geositeUrl = ""; geositeUrl = "";
geositeSha256sumUrl = "";
geositeDirectGroups = new List<string>() geositeDirectGroups = new List<string>()
{ {
"private", "private",


+ 4
- 4
shadowsocks-csharp/Model/Server.cs View File

@@ -29,10 +29,6 @@ namespace Shadowsocks.Model
public int server_port; public int server_port;
public string password; public string password;
public string method; public string method;
// optional fields // optional fields
[DefaultValue("")] [DefaultValue("")]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
@@ -53,6 +49,9 @@ namespace Shadowsocks.Model
public int timeout; public int timeout;
// Set to true when imported from a legacy ss:// URL.
public bool warnLegacyUrl;
public override int GetHashCode() public override int GetHashCode()
{ {
return server.GetHashCode() ^ server_port; return server.GetHashCode() ^ server_port;
@@ -177,6 +176,7 @@ namespace Shadowsocks.Model
server.password = details.Groups["password"].Value; server.password = details.Groups["password"].Value;
server.server = details.Groups["hostname"].Value; server.server = details.Groups["hostname"].Value;
server.server_port = int.Parse(details.Groups["port"].Value); server.server_port = int.Parse(details.Groups["port"].Value);
server.warnLegacyUrl = true;
return server; return server;
} }


+ 2
- 2
shadowsocks-csharp/Program.cs View File

@@ -91,10 +91,10 @@ namespace Shadowsocks
// Check .NET Framework version // Check .NET Framework version
if (!Utils.IsSupportedRuntimeVersion()) if (!Utils.IsSupportedRuntimeVersion())
{ {
if (DialogResult.OK == MessageBox.Show(I18N.GetString("Unsupported .NET Framework, please update to {0} or later.", "4.7.2"),
if (DialogResult.OK == MessageBox.Show(I18N.GetString("Unsupported .NET Framework, please update to {0} or later.", "4.8"),
"Shadowsocks Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error)) "Shadowsocks Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error))
{ {
Process.Start("https://dotnet.microsoft.com/download/dotnet-framework/net472");
Process.Start("https://dotnet.microsoft.com/download/dotnet-framework/net48");
} }
return; return;
} }


+ 3
- 2
shadowsocks-csharp/Properties/Resources.Designer.cs View File

@@ -73,13 +73,14 @@ namespace Shadowsocks.Properties {
///var rules = []; ///var rules = [];
/// ///
///// convert to abp grammar ///// convert to abp grammar
///var re = /^(@@)?\|\|.*?[^\^]$/;
///for (var i = 0; i &lt; __RULES__.length; i++) { ///for (var i = 0; i &lt; __RULES__.length; i++) {
/// var s = __RULES__[i]; /// var s = __RULES__[i];
/// if (s.substring(0, 2) == &quot;||&quot;) s += &quot;^&quot;;
/// if (s.match(re)) s += &quot;^&quot;;
/// rules.push(s); /// rules.push(s);
///} ///}
/// ///
///for (var i = 0; i &lt; [rest of string was truncated]&quot;;.
/// [rest of string was truncated]&quot;;.
/// </summary> /// </summary>
public static string abp_js { public static string abp_js {
get { get {


+ 1
- 1
shadowsocks-csharp/Properties/Settings.Designer.cs View File

@@ -12,7 +12,7 @@ namespace Shadowsocks.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.1.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));


+ 7
- 18
shadowsocks-csharp/View/ConfigForm.cs View File

@@ -25,25 +25,10 @@ namespace Shadowsocks.View
public readonly bool deprecated; public readonly bool deprecated;
// Edit here to add/delete encryption method displayed in UI // Edit here to add/delete encryption method displayed in UI
private static string[] deprecatedMethod = new string[]
{
"rc4-md5",
"salsa20",
"chacha20",
"bf-cfb",
"chacha20-ietf",
"aes-256-cfb",
"aes-192-cfb",
"aes-128-cfb",
"aes-256-ctr",
"aes-192-ctr",
"aes-128-ctr",
"camellia-256-cfb",
"camellia-192-cfb",
"camellia-128-cfb",
};
private static string[] inuseMethod = new string[] private static string[] inuseMethod = new string[]
{ {
"none",
"plain",
"aes-256-gcm", "aes-256-gcm",
"aes-192-gcm", "aes-192-gcm",
"aes-128-gcm", "aes-128-gcm",
@@ -66,7 +51,6 @@ namespace Shadowsocks.View
var all = new List<EncryptionMethod>(); var all = new List<EncryptionMethod>();
all.AddRange(inuseMethod.Select(i => new EncryptionMethod(i, false))); all.AddRange(inuseMethod.Select(i => new EncryptionMethod(i, false)));
all.AddRange(deprecatedMethod.Select(d => new EncryptionMethod(d, true)));
allMethods = all.ToArray(); allMethods = all.ToArray();
foreach (var item in all) foreach (var item in all)
@@ -629,5 +613,10 @@ namespace Shadowsocks.View
{ {
ShowHidePluginArgInput(NeedPluginArgCheckBox.Checked); ShowHidePluginArgInput(NeedPluginArgCheckBox.Checked);
} }
private void EncryptionSelect_SelectedIndexChanged(object sender, EventArgs e)
{
}
} }
} }

+ 6
- 2
shadowsocks-csharp/app.config View File

@@ -6,7 +6,7 @@
</sectionGroup> </sectionGroup>
</configSections> </configSections>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup> </startup>
<runtime> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
@@ -20,7 +20,7 @@
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
@@ -30,6 +30,10 @@
<assemblyIdentity name="ICSharpCode.AvalonEdit" publicKeyToken="9cc39be672370310" culture="neutral" /> <assemblyIdentity name="ICSharpCode.AvalonEdit" publicKeyToken="9cc39be672370310" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.1.278" newVersion="6.0.1.278" /> <bindingRedirect oldVersion="0.0.0.0-6.0.1.278" newVersion="6.0.1.278" />
</dependentAssembly> </dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reactive" publicKeyToken="94bc3704cddfc263" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
<userSettings> <userSettings>


+ 12
- 12
shadowsocks-csharp/packages.config View File

@@ -4,28 +4,28 @@
<package id="Caseless.Fody" version="1.9.0" targetFramework="net472" /> <package id="Caseless.Fody" version="1.9.0" targetFramework="net472" />
<package id="CommandLineParser" version="2.8.0" targetFramework="net472" /> <package id="CommandLineParser" version="2.8.0" targetFramework="net472" />
<package id="Costura.Fody" version="4.1.0" targetFramework="net472" /> <package id="Costura.Fody" version="4.1.0" targetFramework="net472" />
<package id="DynamicData" version="6.17.14" targetFramework="net472" />
<package id="DynamicData" version="7.1.1" targetFramework="net48" />
<package id="Fody" version="6.3.0" targetFramework="net472" developmentDependency="true" /> <package id="Fody" version="6.3.0" targetFramework="net472" developmentDependency="true" />
<package id="GlobalHotKey" version="1.1.0" targetFramework="net472" /> <package id="GlobalHotKey" version="1.1.0" targetFramework="net472" />
<package id="Google.Protobuf" version="3.13.0" targetFramework="net472" />
<package id="Google.Protobuf" version="3.14.0" targetFramework="net48" />
<package id="MdXaml" version="1.6.0" targetFramework="net472" /> <package id="MdXaml" version="1.6.0" targetFramework="net472" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" /> <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" />
<package id="NLog" version="4.7.5" targetFramework="net472" />
<package id="Pharmacist.Common" version="1.8.1" targetFramework="net472" />
<package id="ReactiveUI" version="11.5.35" targetFramework="net472" />
<package id="ReactiveUI.Events.WPF" version="11.5.35" targetFramework="net472" />
<package id="ReactiveUI.Fody" version="11.5.35" targetFramework="net472" />
<package id="ReactiveUI.Validation" version="1.7.1" targetFramework="net472" />
<package id="ReactiveUI.WPF" version="11.5.35" targetFramework="net472" />
<package id="Splat" version="9.6.1" targetFramework="net472" />
<package id="NLog" version="4.7.6" targetFramework="net48" />
<package id="Pharmacist.Common" version="2.0.5" targetFramework="net48" />
<package id="ReactiveUI" version="12.1.5" targetFramework="net48" />
<package id="ReactiveUI.Events.WPF" version="12.1.5" targetFramework="net48" />
<package id="ReactiveUI.Fody" version="12.1.5" targetFramework="net48" />
<package id="ReactiveUI.Validation" version="1.8.6" targetFramework="net48" />
<package id="ReactiveUI.WPF" version="12.1.5" targetFramework="net48" />
<package id="Splat" version="9.8.1" targetFramework="net48" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" /> <package id="System.Buffers" version="4.5.1" targetFramework="net472" />
<package id="System.IO" version="4.3.0" targetFramework="net472" /> <package id="System.IO" version="4.3.0" targetFramework="net472" />
<package id="System.Memory" version="4.5.4" targetFramework="net472" /> <package id="System.Memory" version="4.5.4" targetFramework="net472" />
<package id="System.Net.Http" version="4.3.4" targetFramework="net472" /> <package id="System.Net.Http" version="4.3.4" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" /> <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Reactive" version="4.4.1" targetFramework="net472" />
<package id="System.Reactive" version="5.0.0" targetFramework="net48" />
<package id="System.Runtime" version="4.3.1" targetFramework="net472" /> <package id="System.Runtime" version="4.3.1" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.7.1" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" targetFramework="net48" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.1" targetFramework="net472" /> <package id="System.Security.Cryptography.Algorithms" version="4.3.1" targetFramework="net472" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" /> <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net472" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" /> <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net472" />


+ 27
- 30
shadowsocks-csharp/shadowsocks-csharp.csproj View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\ReactiveUI.Fody.11.5.35\build\ReactiveUI.Fody.props" Condition="Exists('..\packages\ReactiveUI.Fody.11.5.35\build\ReactiveUI.Fody.props')" />
<Import Project="..\packages\ReactiveUI.Fody.12.1.5\build\ReactiveUI.Fody.props" Condition="Exists('..\packages\ReactiveUI.Fody.12.1.5\build\ReactiveUI.Fody.props')" />
<Import Project="..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" /> <Import Project="..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" />
<Import Project="..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props" Condition="Exists('..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props')" /> <Import Project="..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props" Condition="Exists('..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props')" />
<PropertyGroup> <PropertyGroup>
@@ -13,7 +13,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Shadowsocks</RootNamespace> <RootNamespace>Shadowsocks</RootNamespace>
<AssemblyName>Shadowsocks</AssemblyName> <AssemblyName>Shadowsocks</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<StartupObject> <StartupObject>
</StartupObject> </StartupObject>
@@ -79,14 +79,14 @@
<Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL"> <Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
<HintPath>..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll</HintPath> <HintPath>..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll</HintPath>
</Reference> </Reference>
<Reference Include="DynamicData, Version=6.17.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DynamicData.6.17.14\lib\net461\DynamicData.dll</HintPath>
<Reference Include="DynamicData, Version=7.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\DynamicData.7.1.1\lib\net461\DynamicData.dll</HintPath>
</Reference> </Reference>
<Reference Include="GlobalHotKey, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="GlobalHotKey, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll</HintPath> <HintPath>..\packages\GlobalHotKey.1.1.0\lib\GlobalHotKey.dll</HintPath>
</Reference> </Reference>
<Reference Include="Google.Protobuf, Version=3.13.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.13.0\lib\net45\Google.Protobuf.dll</HintPath>
<Reference Include="Google.Protobuf, Version=3.14.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.14.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference> </Reference>
<Reference Include="ICSharpCode.AvalonEdit, Version=6.0.1.278, Culture=neutral, PublicKeyToken=9cc39be672370310, processorArchitecture=MSIL"> <Reference Include="ICSharpCode.AvalonEdit, Version=6.0.1.278, Culture=neutral, PublicKeyToken=9cc39be672370310, processorArchitecture=MSIL">
<HintPath>..\packages\AvalonEdit.6.0.1\lib\net45\ICSharpCode.AvalonEdit.dll</HintPath> <HintPath>..\packages\AvalonEdit.6.0.1\lib\net45\ICSharpCode.AvalonEdit.dll</HintPath>
@@ -100,31 +100,31 @@
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.5\lib\net45\NLog.dll</HintPath>
<HintPath>..\packages\NLog.4.7.6\lib\net45\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="Pharmacist.Common, Version=1.8.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Pharmacist.Common.1.8.1\lib\netstandard2.0\Pharmacist.Common.dll</HintPath>
<Reference Include="Pharmacist.Common, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Pharmacist.Common.2.0.5\lib\net472\Pharmacist.Common.dll</HintPath>
</Reference> </Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
<Reference Include="PresentationFramework.Aero" /> <Reference Include="PresentationFramework.Aero" />
<Reference Include="ReactiveUI, Version=11.5.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.11.5.35\lib\net461\ReactiveUI.dll</HintPath>
<Reference Include="ReactiveUI, Version=12.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.12.1.5\lib\net461\ReactiveUI.dll</HintPath>
</Reference> </Reference>
<Reference Include="ReactiveUI.Events.WPF, Version=11.5.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.Events.WPF.11.5.35\lib\net472\ReactiveUI.Events.WPF.dll</HintPath>
<Reference Include="ReactiveUI.Events.WPF, Version=12.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.Events.WPF.12.1.5\lib\net472\ReactiveUI.Events.WPF.dll</HintPath>
</Reference> </Reference>
<Reference Include="ReactiveUI.Fody.Helpers, Version=11.5.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.Fody.11.5.35\lib\net461\ReactiveUI.Fody.Helpers.dll</HintPath>
<Reference Include="ReactiveUI.Fody.Helpers, Version=12.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.Fody.12.1.5\lib\net461\ReactiveUI.Fody.Helpers.dll</HintPath>
</Reference> </Reference>
<Reference Include="ReactiveUI.Validation, Version=1.7.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.Validation.1.7.1\lib\net461\ReactiveUI.Validation.dll</HintPath>
<Reference Include="ReactiveUI.Validation, Version=1.8.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.Validation.1.8.6\lib\net461\ReactiveUI.Validation.dll</HintPath>
</Reference> </Reference>
<Reference Include="ReactiveUI.WPF, Version=11.5.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.WPF.11.5.35\lib\net472\ReactiveUI.WPF.dll</HintPath>
<Reference Include="ReactiveUI.Wpf, Version=12.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ReactiveUI.WPF.12.1.5\lib\net472\ReactiveUI.Wpf.dll</HintPath>
</Reference> </Reference>
<Reference Include="Splat, Version=9.6.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Splat.9.6.1\lib\net461\Splat.dll</HintPath>
<Reference Include="Splat, Version=9.8.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Splat.9.8.1\lib\net461\Splat.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
@@ -155,16 +155,16 @@
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath> <HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Reactive, Version=4.4.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reactive.4.4.1\lib\net46\System.Reactive.dll</HintPath>
<Reference Include="System.Reactive, Version=5.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reactive.5.0.0\lib\net472\System.Reactive.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Runtime, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Runtime, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll</HintPath> <HintPath>..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll</HintPath>
<Private>True</Private> <Private>True</Private>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> <Reference Include="System.Security.Cryptography.Algorithms, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
@@ -240,10 +240,7 @@
<Compile Include="Encryption\OpenSSL.cs" /> <Compile Include="Encryption\OpenSSL.cs" />
<Compile Include="Encryption\RNG.cs" /> <Compile Include="Encryption\RNG.cs" />
<Compile Include="Encryption\Sodium.cs" /> <Compile Include="Encryption\Sodium.cs" />
<Compile Include="Encryption\Stream\StreamEncryptor.cs" />
<Compile Include="Encryption\Stream\StreamMbedTLSEncryptor.cs" />
<Compile Include="Encryption\Stream\StreamOpenSSLEncryptor.cs" />
<Compile Include="Encryption\Stream\StreamSodiumEncryptor.cs" />
<Compile Include="Encryption\Stream\PlainEncryptor.cs" />
<Compile Include="Localization\LocalizationProvider.cs" /> <Compile Include="Localization\LocalizationProvider.cs" />
<Compile Include="Localization\Strings.Designer.cs"> <Compile Include="Localization\Strings.Designer.cs">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@@ -447,7 +444,7 @@
<Error Condition="!Exists('..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props'))" /> <Error Condition="!Exists('..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Caseless.Fody.1.9.0\build\Caseless.Fody.props'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props'))" /> <Error Condition="!Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props'))" />
<Error Condition="!Exists('..\packages\Fody.6.3.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.3.0\build\Fody.targets'))" /> <Error Condition="!Exists('..\packages\Fody.6.3.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.3.0\build\Fody.targets'))" />
<Error Condition="!Exists('..\packages\ReactiveUI.Fody.11.5.35\build\ReactiveUI.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\ReactiveUI.Fody.11.5.35\build\ReactiveUI.Fody.props'))" />
<Error Condition="!Exists('..\packages\ReactiveUI.Fody.12.1.5\build\ReactiveUI.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\ReactiveUI.Fody.12.1.5\build\ReactiveUI.Fody.props'))" />
</Target> </Target>
<Import Project="..\packages\Fody.6.3.0\build\Fody.targets" Condition="Exists('..\packages\Fody.6.3.0\build\Fody.targets')" /> <Import Project="..\packages\Fody.6.3.0\build\Fody.targets" Condition="Exists('..\packages\Fody.6.3.0\build\Fody.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.


+ 0
- 233
test/CryptographyTest.cs View File

@@ -1,233 +0,0 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Shadowsocks.Encryption;
using System.Threading;
using System.Collections.Generic;
using Shadowsocks.Encryption.Stream;
using System.Diagnostics;
namespace Shadowsocks.Test
{
[TestClass]
public class CryptographyTest
{
[TestMethod]
public void TestMD5()
{
for (int len = 1; len < 64; len++)
{
System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] bytes = new byte[len];
var random = new Random();
random.NextBytes(bytes);
string md5str = Convert.ToBase64String(md5.ComputeHash(bytes));
string md5str2 = Convert.ToBase64String(MbedTLS.MD5(bytes));
Assert.IsTrue(md5str == md5str2);
}
}
private void RunEncryptionRound(IEncryptor encryptor, IEncryptor decryptor)
{
RNG.Reload();
byte[] plain = new byte[16384];
byte[] cipher = new byte[plain.Length + 16];
byte[] plain2 = new byte[plain.Length + 16];
int outLen = 0;
int outLen2 = 0;
var random = new Random();
random.NextBytes(plain);
encryptor.Encrypt(plain, plain.Length, cipher, out outLen);
decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
Assert.AreEqual(plain.Length, outLen2);
for (int j = 0; j < plain.Length; j++)
{
Assert.AreEqual(plain[j], plain2[j]);
}
encryptor.Encrypt(plain, 1000, cipher, out outLen);
decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
Assert.AreEqual(1000, outLen2);
for (int j = 0; j < outLen2; j++)
{
Assert.AreEqual(plain[j], plain2[j]);
}
encryptor.Encrypt(plain, 12333, cipher, out outLen);
decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
Assert.AreEqual(12333, outLen2);
for (int j = 0; j < outLen2; j++)
{
Assert.AreEqual(plain[j], plain2[j]);
}
}
private static bool encryptionFailed = false;
private static object locker = new object();
[TestMethod]
public void TestMbedTLSEncryption()
{
encryptionFailed = false;
// run it once before the multi-threading test to initialize global tables
RunSingleMbedTLSEncryptionThread();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(RunSingleMbedTLSEncryptionThread));
threads.Add(t);
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
RNG.Close();
Assert.IsFalse(encryptionFailed);
}
private void RunSingleMbedTLSEncryptionThread()
{
try
{
for (int i = 0; i < 100; i++)
{
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new StreamMbedTLSEncryptor("aes-256-cfb", "barfoo!");
decryptor = new StreamMbedTLSEncryptor("aes-256-cfb", "barfoo!");
RunEncryptionRound(encryptor, decryptor);
}
}
catch
{
encryptionFailed = true;
throw;
}
}
[TestMethod]
public void TestRC4Encryption()
{
encryptionFailed = false;
// run it once before the multi-threading test to initialize global tables
RunSingleRC4EncryptionThread();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(RunSingleRC4EncryptionThread));
threads.Add(t);
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
RNG.Close();
Assert.IsFalse(encryptionFailed);
}
private void RunSingleRC4EncryptionThread()
{
try
{
for (int i = 0; i < 100; i++)
{
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new StreamMbedTLSEncryptor("rc4-md5", "barfoo!");
decryptor = new StreamMbedTLSEncryptor("rc4-md5", "barfoo!");
RunEncryptionRound(encryptor, decryptor);
}
}
catch
{
encryptionFailed = true;
throw;
}
}
[TestMethod]
public void TestSodiumEncryption()
{
encryptionFailed = false;
// run it once before the multi-threading test to initialize global tables
RunSingleSodiumEncryptionThread();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(RunSingleSodiumEncryptionThread));
threads.Add(t);
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
RNG.Close();
Assert.IsFalse(encryptionFailed);
}
private void RunSingleSodiumEncryptionThread()
{
try
{
for (int i = 0; i < 100; i++)
{
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new StreamSodiumEncryptor("salsa20", "barfoo!");
decryptor = new StreamSodiumEncryptor("salsa20", "barfoo!");
RunEncryptionRound(encryptor, decryptor);
}
}
catch
{
encryptionFailed = true;
throw;
}
}
[TestMethod]
public void TestOpenSSLEncryption()
{
encryptionFailed = false;
// run it once before the multi-threading test to initialize global tables
RunSingleOpenSSLEncryptionThread();
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(RunSingleOpenSSLEncryptionThread));
threads.Add(t);
t.Start();
}
foreach (Thread t in threads)
{
t.Join();
}
RNG.Close();
Assert.IsFalse(encryptionFailed);
}
private void RunSingleOpenSSLEncryptionThread()
{
try
{
for (int i = 0; i < 100; i++)
{
var random = new Random();
IEncryptor encryptor;
IEncryptor decryptor;
encryptor = new StreamOpenSSLEncryptor("aes-256-cfb", "barfoo!");
decryptor = new StreamOpenSSLEncryptor("aes-256-cfb", "barfoo!");
RunEncryptionRound(encryptor, decryptor);
}
}
catch
{
encryptionFailed = true;
throw;
}
}
}
}

+ 2
- 3
test/ShadowsocksTest.csproj View File

@@ -8,7 +8,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Shadowsocks.Test</RootNamespace> <RootNamespace>Shadowsocks.Test</RootNamespace>
<AssemblyName>Shadowsocks.Test</AssemblyName> <AssemblyName>Shadowsocks.Test</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
@@ -56,7 +56,6 @@
</Choose> </Choose>
<ItemGroup> <ItemGroup>
<Compile Include="ProcessEnvironment.cs" /> <Compile Include="ProcessEnvironment.cs" />
<Compile Include="CryptographyTest.cs" />
<Compile Include="Sip003PluginTest.cs" /> <Compile Include="Sip003PluginTest.cs" />
<Compile Include="UrlTest.cs" /> <Compile Include="UrlTest.cs" />
<Compile Include="UnitTest.cs" /> <Compile Include="UnitTest.cs" />
@@ -99,4 +98,4 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project>
</Project>

+ 2
- 2
test/app.config View File

@@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /> <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
@@ -16,4 +16,4 @@
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
</configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" /></startup></configuration>

Loading…
Cancel
Save