| @@ -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 | |||||
| @@ -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) | ||||
| @@ -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 | ||||
| @@ -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: | ||||
| @@ -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 | ||||
| @@ -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() | ||||
| @@ -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); | ||||
| @@ -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 à | ||||
| @@ -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) | ||||
| @@ -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(); | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| } | |||||
| } | |||||
| @@ -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 | |||||
| } | |||||
| } | |||||
| @@ -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() | |||||
| { | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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", | ||||
| @@ -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; | ||||
| } | } | ||||
| @@ -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; | ||||
| } | } | ||||
| @@ -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 < __RULES__.length; i++) { | ///for (var i = 0; i < __RULES__.length; i++) { | ||||
| /// var s = __RULES__[i]; | /// var s = __RULES__[i]; | ||||
| /// if (s.substring(0, 2) == "||") s += "^"; | |||||
| /// if (s.match(re)) s += "^"; | |||||
| /// rules.push(s); | /// rules.push(s); | ||||
| ///} | ///} | ||||
| /// | /// | ||||
| ///for (var i = 0; i < [rest of string was truncated]";. | |||||
| /// [rest of string was truncated]";. | |||||
| /// </summary> | /// </summary> | ||||
| public static string abp_js { | public static string abp_js { | ||||
| get { | get { | ||||
| @@ -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()))); | ||||
| @@ -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,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> | ||||
| @@ -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" /> | ||||
| @@ -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. | ||||
| @@ -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; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -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> | |||||
| @@ -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> | |||||