From dad8a64fad6d74f7d5512f2bf5873287e46e7ba5 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 1 May 2020 22:42:39 -0700 Subject: [PATCH] Adds Argon2 for password protection (#123) --- .circleci/checksum.txt | 13 + .circleci/config.yml | 44 +- .circleci/genchecksum.sh | 1 + .gitignore | 3 + ModernUO.sln | 66 +-- NuGet.Config | 6 + Projects/Argon2/Argon2.cs | 128 ++++++ Projects/Argon2/Argon2.csproj | 42 ++ Projects/Argon2/Argon2.nuspec | 15 + Projects/Argon2/Argon2Context.cs | 34 ++ Projects/Argon2/Argon2Error.cs | 77 ++++ Projects/Argon2/Argon2Exception.cs | 20 + Projects/Argon2/Argon2PasswordHasher.cs | 388 ++++++++++++++++++ Projects/Argon2/Argon2Type.cs | 18 + Projects/Argon2/HashMetadata.cs | 60 +++ Projects/Argon2/Utility.cs | 13 + .../runtimes/linux-x64/native/libargon2.so | Bin 0 -> 210096 bytes .../runtimes/osx-x64/native/libargon2.dylib | Bin 0 -> 46400 bytes .../Argon2/runtimes/win-x64/native/argon2.dll | Bin 0 -> 125952 bytes .../Security/Argon2PasswordProtectionTest.cs | 30 ++ .../PBKDF2PasswordProtectionTest.cs | 4 +- Projects/Scripts.Tests/Scripts.Tests.csproj | 3 +- Projects/Scripts/Accounting/Account.cs | 29 +- .../Scripts/Accounting/AccountSecurity.cs | 26 -- .../Accounting/Security/AccountSecurity.cs | 45 ++ .../Security/Argon2PasswordProtection.cs | 14 + .../Security/MD5PasswordProtection.cs | 25 ++ .../PBKDF2PasswordProtection.cs | 4 +- .../Security/SHA1PasswordProtection.cs | 25 ++ Projects/Scripts/Scripts.csproj | 28 +- Projects/Server.Tests/Server.Tests.csproj | 1 + Projects/Server/Buffers/BufferReader.cs | 1 - .../Linux-SelfContained.pubxml | 10 - .../Properties/PublishProfiles/Linux.pubxml | 9 - .../PublishProfiles/OSX-SelfContained.pubxml | 10 - .../Properties/PublishProfiles/OSX.pubxml | 9 - .../Windows-SelfContained.pubxml | 10 - .../Properties/PublishProfiles/Windows.pubxml | 9 - Projects/Server/Server.csproj | 31 +- THIRD-PARTY-NOTICES | 26 ++ Tools/clean.sh | 6 + Tools/publish-linux-debug.cmd | 3 +- Tools/publish-linux-debug.sh | 3 +- Tools/publish-linux.cmd | 3 +- Tools/publish-linux.sh | 3 +- Tools/publish-osx-debug.cmd | 3 +- Tools/publish-osx-debug.sh | 3 +- Tools/publish-osx.cmd | 3 +- Tools/publish-osx.sh | 3 +- Tools/publish-windows-debug.cmd | 3 +- Tools/publish-windows-debug.sh | 3 +- Tools/publish-windows.cmd | 3 +- Tools/publish-windows.sh | 3 +- packages/do_not_delete | 0 54 files changed, 1152 insertions(+), 167 deletions(-) create mode 100644 .circleci/checksum.txt create mode 100755 .circleci/genchecksum.sh create mode 100644 NuGet.Config create mode 100644 Projects/Argon2/Argon2.cs create mode 100644 Projects/Argon2/Argon2.csproj create mode 100644 Projects/Argon2/Argon2.nuspec create mode 100644 Projects/Argon2/Argon2Context.cs create mode 100644 Projects/Argon2/Argon2Error.cs create mode 100644 Projects/Argon2/Argon2Exception.cs create mode 100644 Projects/Argon2/Argon2PasswordHasher.cs create mode 100644 Projects/Argon2/Argon2Type.cs create mode 100644 Projects/Argon2/HashMetadata.cs create mode 100644 Projects/Argon2/Utility.cs create mode 100755 Projects/Argon2/runtimes/linux-x64/native/libargon2.so create mode 100755 Projects/Argon2/runtimes/osx-x64/native/libargon2.dylib create mode 100644 Projects/Argon2/runtimes/win-x64/native/argon2.dll create mode 100644 Projects/Scripts.Tests/Accounting/Security/Argon2PasswordProtectionTest.cs rename Projects/Scripts.Tests/Accounting/{ => Security}/PBKDF2PasswordProtectionTest.cs (87%) delete mode 100644 Projects/Scripts/Accounting/AccountSecurity.cs create mode 100644 Projects/Scripts/Accounting/Security/AccountSecurity.cs create mode 100644 Projects/Scripts/Accounting/Security/Argon2PasswordProtection.cs create mode 100644 Projects/Scripts/Accounting/Security/MD5PasswordProtection.cs rename Projects/Scripts/Accounting/{ => Security}/PBKDF2PasswordProtection.cs (91%) create mode 100644 Projects/Scripts/Accounting/Security/SHA1PasswordProtection.cs delete mode 100644 Projects/Server/Properties/PublishProfiles/Linux-SelfContained.pubxml delete mode 100644 Projects/Server/Properties/PublishProfiles/Linux.pubxml delete mode 100644 Projects/Server/Properties/PublishProfiles/OSX-SelfContained.pubxml delete mode 100644 Projects/Server/Properties/PublishProfiles/OSX.pubxml delete mode 100644 Projects/Server/Properties/PublishProfiles/Windows-SelfContained.pubxml delete mode 100644 Projects/Server/Properties/PublishProfiles/Windows.pubxml create mode 100644 packages/do_not_delete diff --git a/.circleci/checksum.txt b/.circleci/checksum.txt new file mode 100644 index 000000000..5d4b569c0 --- /dev/null +++ b/.circleci/checksum.txt @@ -0,0 +1,13 @@ +95482048463cdc99c77a69951654de7b28fd6880 ../Projects/Argon2/Argon2.csproj +ebafae4e8160057cbf408cb13114479ca26e1b58 ../Projects/Scripts.Tests/Scripts.Tests.csproj +6c6a48220658bdfa7b2e1e173077fd139ed4af2c ../Projects/Scripts/Scripts.csproj +6213c10f697b45729bab15f7870c42dcf49b026b ../Projects/Server.Tests/Server.Tests.csproj +4b3626e04f76dff1ab445e207658a3b386fce4e5 ../Projects/Server/Server.csproj +a663d309b6b86c7632ea5cd175468dd5180808c1 ../Projects/Argon2/Argon2.cs +1e89625abe364f895346d0c5753f3ca6653cf7df ../Projects/Argon2/Argon2Context.cs +abbb34d85f55ca1d78a400b4d46afbd6965f642b ../Projects/Argon2/Argon2Error.cs +00ef35a6809d4959bdda1de01f45e39ff388270f ../Projects/Argon2/Argon2Exception.cs +53164d1621e24adefc6917379d36d7273551f457 ../Projects/Argon2/Argon2PasswordHasher.cs +a137d2fe0478d065d478366168f80ab9eaaa9c3a ../Projects/Argon2/Argon2Type.cs +c09f7a2f9690d56ca838aafb28640c09950c5a8c ../Projects/Argon2/HashMetadata.cs +b5da07548eb41ec9bd35bc2def006f23698b357e ../Projects/Argon2/Utility.cs diff --git a/.circleci/config.yml b/.circleci/config.yml index 53c4fa85c..7c8138fb3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -19,17 +19,20 @@ jobs: - checkout - restore_cache: keys: - - dotnet-packages-linux-{{ checksum "Projects/Server/Server.csproj" }}-{{ checksum "Projects/Scripts/Scripts.csproj" }} + - dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} + - run: + name: Build Argon2 + command: dotnet build -c Release -r linux-x64 Projects/Argon2/Argon2.csproj - run: name: Install ModernUO dependencies command: dotnet restore - save_cache: paths: - - ~/.nuget/packages - key: dotnet-packages-linux-{{ checksum "Projects/Server/Server.csproj" }}-{{ checksum "Projects/Scripts/Scripts.csproj" }} + - /mnt/ramdisk/packages + key: dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - run: name: Building ModernUO for Linux (Debug) - command: dotnet build -c Release /p:PublishProfile=Linux + command: dotnet build -c Debug -r linux-x64 build_windows: description: Build application executor: win/default @@ -37,17 +40,20 @@ jobs: - checkout - restore_cache: keys: - - dotnet-packages-windows-{{ checksum "Projects/Server/Server.csproj" }}-{{ checksum "Projects/Scripts/Scripts.csproj" }} + - dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} + - run: + name: Build Argon2 + command: dotnet build -c Debug -r win-x64 Projects/Argon2/Argon2.csproj - run: name: Install ModernUO dependencies command: dotnet restore - save_cache: paths: - - ~/.nuget/packages - key: dotnet-packages-windows-{{ checksum "Projects/Server/Server.csproj" }}-{{ checksum "Projects/Scripts/Scripts.csproj" }} + - /mnt/ramdisk/packages + key: dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - run: name: Building ModernUO for Windows (Debug) - command: dotnet build -c Release /p:PublishProfile=Windows + command: dotnet build -c Debug -r win-x64 code_styling: description: Code analysis executor: linux-build @@ -56,17 +62,20 @@ jobs: - checkout - restore_cache: keys: - - dotnet-packages-linux-{{ checksum "Projects/Server/Server.csproj" }}-{{ checksum "Projects/Scripts/Scripts.csproj" }} + - dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} + - run: + name: Build Argon2 + command: dotnet build -c Debug -r linux-x64 Projects/Argon2/Argon2.csproj - run: name: Install ModernUO dependencies command: dotnet restore - save_cache: paths: - - ~/.nuget/packages - key: dotnet-packages-linux-{{ checksum "Projects/Server/Server.csproj" }}-{{ checksum "Projects/Scripts/Scripts.csproj" }} + - /mnt/ramdisk/packages + key: dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} - run: name: Building with Analyzers - command: dotnet build -c Analyze /p:PublishProfile=Linux + command: dotnet build -c Analyze -r linux-x64 tests: description: Unit Tests executor: linux-build @@ -75,17 +84,20 @@ jobs: - checkout - restore_cache: keys: - - dotnet-packages-linux-{{ checksum "Projects/Server/Server.csproj" }}-{{ checksum "Projects/Scripts/Scripts.csproj" }} + - dotnet-packages-v1-{{ arch }}-{{ checksum ".circleci/checksum.txt" }} + - run: + name: Build Argon2 + command: dotnet build -c Debug -r linux-x64 Projects/Argon2/Argon2.csproj - run: name: Install ModernUO dependencies command: dotnet restore - save_cache: paths: - - ~/.nuget/packages - key: dotnet-packages-linux-{{ checksum "Projects/Server/Server.csproj" }}-{{ checksum "Projects/Scripts/Scripts.csproj" }} + - /mnt/ramdisk/packages + key: dotnet-packages-linux-{{ checksum ".circleci/checksum.txt" }} - run: name: Running unit tests - command: dotnet test + command: dotnet test -r linux-x64 workflows: build-and-test: jobs: diff --git a/.circleci/genchecksum.sh b/.circleci/genchecksum.sh new file mode 100755 index 000000000..1d30da007 --- /dev/null +++ b/.circleci/genchecksum.sh @@ -0,0 +1 @@ +sha1sum ../Projects/*/*.csproj ../Projects/Argon2/*.cs > "checksum.txt" diff --git a/.gitignore b/.gitignore index b814ef215..76af4a723 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,6 @@ /.vs .DS_Store + +/packages/* +!/packages/do_not_delete diff --git a/ModernUO.sln b/ModernUO.sln index a2edfb108..e1d9f033b 100644 --- a/ModernUO.sln +++ b/ModernUO.sln @@ -2,45 +2,53 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29102.190 MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Argon2", "Projects\Argon2\Argon2.csproj", "{97150E9D-5561-4D3C-9B78-E795544507D0}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Projects\Server\Server.csproj", "{5E93BB35-3661-4822-9A8A-859726BAD87F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scripts", "Projects\Scripts\Scripts.csproj", "{83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server.Tests", "Projects\Server.Tests\Server.Tests.csproj", "{D7A5D3AF-D607-46EF-BAAD-0D424190311F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server.Tests", "Projects\Server.Tests\Server.Tests.csproj", "{D7A5D3AF-D607-46EF-BAAD-0D424190311F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scripts.Tests", "Projects\Scripts.Tests\Scripts.Tests.csproj", "{3C4797F9-603E-44EF-8E8C-9275CC9EA74B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scripts.Tests", "Projects\Scripts.Tests\Scripts.Tests.csproj", "{3C4797F9-603E-44EF-8E8C-9275CC9EA74B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Analyze|Any CPU = Analyze|Any CPU - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU + Analyze|x64 = Analyze|x64 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Analyze|Any CPU.ActiveCfg = Analyze|Any CPU - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Analyze|Any CPU.Build.0 = Analyze|Any CPU - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5E93BB35-3661-4822-9A8A-859726BAD87F}.Release|Any CPU.Build.0 = Release|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Analyze|Any CPU.ActiveCfg = Analyze|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Analyze|Any CPU.Build.0 = Analyze|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Release|Any CPU.Build.0 = Release|Any CPU - {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Analyze|Any CPU.ActiveCfg = Debug|Any CPU - {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Analyze|Any CPU.Build.0 = Debug|Any CPU - {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Release|Any CPU.Build.0 = Release|Any CPU - {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Analyze|Any CPU.ActiveCfg = Debug|Any CPU - {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Analyze|Any CPU.Build.0 = Debug|Any CPU - {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Release|Any CPU.Build.0 = Release|Any CPU + {5E93BB35-3661-4822-9A8A-859726BAD87F}.Analyze|x64.ActiveCfg = Release|x64 + {5E93BB35-3661-4822-9A8A-859726BAD87F}.Analyze|x64.Build.0 = Release|x64 + {5E93BB35-3661-4822-9A8A-859726BAD87F}.Debug|x64.ActiveCfg = Debug|x64 + {5E93BB35-3661-4822-9A8A-859726BAD87F}.Debug|x64.Build.0 = Debug|x64 + {5E93BB35-3661-4822-9A8A-859726BAD87F}.Release|x64.ActiveCfg = Release|x64 + {5E93BB35-3661-4822-9A8A-859726BAD87F}.Release|x64.Build.0 = Release|x64 + {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Analyze|x64.ActiveCfg = Release|x64 + {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Analyze|x64.Build.0 = Release|x64 + {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Debug|x64.ActiveCfg = Debug|x64 + {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Debug|x64.Build.0 = Debug|x64 + {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Release|x64.ActiveCfg = Release|x64 + {83CF2484-BCCB-4B7C-9C5F-7AB43AEA5E8F}.Release|x64.Build.0 = Release|x64 + {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Analyze|x64.ActiveCfg = Debug|x64 + {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Analyze|x64.Build.0 = Debug|x64 + {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Debug|x64.ActiveCfg = Debug|x64 + {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Debug|x64.Build.0 = Debug|x64 + {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Release|x64.ActiveCfg = Release|x64 + {D7A5D3AF-D607-46EF-BAAD-0D424190311F}.Release|x64.Build.0 = Release|x64 + {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Analyze|x64.ActiveCfg = Debug|x64 + {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Analyze|x64.Build.0 = Debug|x64 + {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Debug|x64.ActiveCfg = Debug|x64 + {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Debug|x64.Build.0 = Debug|x64 + {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Release|x64.ActiveCfg = Release|x64 + {3C4797F9-603E-44EF-8E8C-9275CC9EA74B}.Release|x64.Build.0 = Release|x64 + {97150E9D-5561-4D3C-9B78-E795544507D0}.Analyze|x64.ActiveCfg = Release|x64 + {97150E9D-5561-4D3C-9B78-E795544507D0}.Analyze|x64.Build.0 = Release|x64 + {97150E9D-5561-4D3C-9B78-E795544507D0}.Debug|x64.ActiveCfg = Debug|x64 + {97150E9D-5561-4D3C-9B78-E795544507D0}.Debug|x64.Build.0 = Debug|x64 + {97150E9D-5561-4D3C-9B78-E795544507D0}.Release|x64.ActiveCfg = Release|x64 + {97150E9D-5561-4D3C-9B78-E795544507D0}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 000000000..43de52fb5 --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Projects/Argon2/Argon2.cs b/Projects/Argon2/Argon2.cs new file mode 100644 index 000000000..9be9b86be --- /dev/null +++ b/Projects/Argon2/Argon2.cs @@ -0,0 +1,128 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace Server.Accounting.Security +{ + internal interface IArgon2 + { + public Argon2Error Hash(uint t_cost, uint m_cost, uint parallelism, + byte[] pwd, + byte[] salt, + byte[] hash, + byte[] encoded, + int type, int version); + + Argon2Error Verify(byte[] encoded, byte[] pwd, int pwdlen, int type); + + // TODO: Change str to use ReadOnlySpan then convert to pointer later + Argon2Error Decode(Argon2Context ctx, string str, int type); + } + + internal static class Argon2 + { + internal static readonly IArgon2 Library; + + static Argon2() + { + if (RuntimeUtility.Unix) + Library = new UnixArgon2(); + else + Library = new WindowsArgon2(); + } + } + + internal class WindowsArgon2 : IArgon2 + { + public Argon2Error Hash(uint t_cost, uint m_cost, uint parallelism, + byte[] pwd, + byte[] salt, + byte[] hash, + byte[] encoded, + int type, int version) => + NativeMethods.crypto_argon2_hash(t_cost, m_cost, parallelism, + pwd, pwd.Length, + salt, salt.Length, + hash, hash.Length, + encoded, encoded.Length, + type, version + ); + + public Argon2Error Verify(byte[] encoded, byte[] pwd, int pwdlen, int type) => + NativeMethods.crypto_argon2_verify(encoded, pwd, pwdlen, type); + + public Argon2Error Decode(Argon2Context ctx, string str, int type) + { + byte[] bytes = new byte[str.Length]; + Encoding.ASCII.GetBytes(str, bytes); + + // TODO: Use pointers instead + return NativeMethods.crypto_decode_string(ctx, bytes, type); + } + + internal static class NativeMethods + { + [DllImport("argon2.dll", EntryPoint = "crypto_argon2_hash", CallingConvention = CallingConvention.Cdecl)] + internal static extern Argon2Error crypto_argon2_hash(uint t_cost, uint m_cost, uint parallelism, + byte[] pwd, int pwdlen, + byte[] salt, int saltlen, + byte[] hash, int hashlen, + byte[] encoded, int encodedlen, + int type, int version + ); + + [DllImport("argon2.dll", EntryPoint = "crypto_argon2_verify", CallingConvention = CallingConvention.Cdecl)] + internal static extern Argon2Error crypto_argon2_verify(byte[] encoded, byte[] pwd, int pwdlen, int type); + + [DllImport("argon2.dll", EntryPoint = "crypto_decode_string", CallingConvention = CallingConvention.Cdecl)] + internal static extern Argon2Error crypto_decode_string(Argon2Context ctx, byte[] str, int type); + } + } + + internal class UnixArgon2 : IArgon2 + { + public Argon2Error Hash(uint t_cost, uint m_cost, uint parallelism, + byte[] pwd, + byte[] salt, + byte[] hash, + byte[] encoded, + int type, int version) => + NativeMethods.crypto_argon2_hash(t_cost, m_cost, parallelism, + pwd, pwd.Length, + salt, salt.Length, + hash, hash.Length, + encoded, encoded.Length, + type, version + ); + + public Argon2Error Verify(byte[] encoded, byte[] pwd, int pwdlen, int type) => + NativeMethods.crypto_argon2_verify(encoded, pwd, pwdlen, type); + + public Argon2Error Decode(Argon2Context ctx, string str, int type) + { + byte[] bytes = new byte[str.Length]; + Encoding.ASCII.GetBytes(str, bytes); + + // TODO: Use pointers instead + return NativeMethods.crypto_decode_string(ctx, bytes, type); + } + + internal static class NativeMethods + { + [DllImport("libargon2", EntryPoint = "argon2_hash")] + internal static extern Argon2Error crypto_argon2_hash(uint t_cost, uint m_cost, uint parallelism, + byte[] pwd, int pwdlen, + byte[] salt, int saltlen, + byte[] hash, int hashlen, + byte[] encoded, int encodedlen, + int type, int version + ); + + [DllImport("libargon2", EntryPoint = "argon2_verify")] + internal static extern Argon2Error crypto_argon2_verify(byte[] encoded, byte[] pwd, int pwdlen, int type); + + [DllImport("libargon2", EntryPoint = "decode_string")] + internal static extern Argon2Error crypto_decode_string(Argon2Context ctx, byte[] str, int type); + } + } +} diff --git a/Projects/Argon2/Argon2.csproj b/Projects/Argon2/Argon2.csproj new file mode 100644 index 000000000..b76f1e543 --- /dev/null +++ b/Projects/Argon2/Argon2.csproj @@ -0,0 +1,42 @@ + + + win-x64;linux-x64;osx-x64 + 1.0.0 + Server + Argon2.Bindings + x64 + 8.0 + netcoreapp3.1 + true + true + true + false + Debug;Release;Analyze + WINDOWS + 1.0.0 + x64 + + + + true + runtimes/win-x64/native + PreserveNewest + + + true + runtimes/osx-x64/native + PreserveNewest + + + true + runtimes/linux-x64/native + PreserveNewest + + + + + + + diff --git a/Projects/Argon2/Argon2.nuspec b/Projects/Argon2/Argon2.nuspec new file mode 100644 index 000000000..d4f061905 --- /dev/null +++ b/Projects/Argon2/Argon2.nuspec @@ -0,0 +1,15 @@ + + + + Argon2.Bindings + 1.0.0 + Kamron Batman + Kamron Batman + MIT + https://github.com/modernUO/ModernUO + false + Argon2 C# Bindings for ModernUO + Initial release + Copyright 2020 + + diff --git a/Projects/Argon2/Argon2Context.cs b/Projects/Argon2/Argon2Context.cs new file mode 100644 index 000000000..302e1cca2 --- /dev/null +++ b/Projects/Argon2/Argon2Context.cs @@ -0,0 +1,34 @@ +using System; +using System.Runtime.InteropServices; + +namespace Server.Accounting.Security +{ + [StructLayout(LayoutKind.Sequential)] + internal class Argon2Context + { + public IntPtr Out; + public uint OutLen; + + public IntPtr Pwd; + public uint PwdLen; + + public IntPtr Salt; + public uint SaltLen; + + public IntPtr Secret; + public uint SecretLen; + + public IntPtr AssocData; + public uint AssocDataLen; + + public uint TimeCost; + public uint MemoryCost; + public uint Lanes; + public uint Threads; + + public IntPtr AllocateCallback; + public IntPtr FreeCallback; + + public uint Flags; + } +} diff --git a/Projects/Argon2/Argon2Error.cs b/Projects/Argon2/Argon2Error.cs new file mode 100644 index 000000000..4509170ff --- /dev/null +++ b/Projects/Argon2/Argon2Error.cs @@ -0,0 +1,77 @@ +namespace Server.Accounting.Security +{ + /// + /// An enumeration of the possible error codes which are returned from Daniel Dinu and + /// Dmitry Khovratovich's Argon2 library. + /// + /// Some of these error conditions cannot be reached while using the C# PasswordHasher wrapper + /// + public enum Argon2Error + { + /// + /// The operation was successful + /// + OK = 0, + + /// + /// The output hash length is less than 4 bytes + /// + OUTPUT_TOO_SHORT = -2, + + /// + /// The salt is less than 8 bytes + /// + SALT_TOO_SHORT = -6, + + /// + /// The time cost is less than 1 + /// + TIME_TOO_SMALL = -12, + + /// + /// The memory cost is less than 8 (KiB) + /// + MEMORY_TOO_LITTLE = -14, + /// + /// The memory cost is greater than 2^21 (KiB) (2 GiB) + /// + MEMORY_TOO_MUCH = -15, + + /// + /// The parallelism is less than 1 + /// + LANES_TOO_FEW = -16, + /// + /// The parallelism is greater than 16,777,215 + /// + LANES_TOO_MANY = -17, + + /// + /// Memory allocation failed + /// + MEMORY_ALLOCATION_ERROR = -22, + + /// + /// The parallelism is less than 1 + /// + THREADS_TOO_FEW = -28, + /// + /// The parallelism is greater than 16,777,215 + /// + THREADS_TOO_MANY = -29, + + /// + /// This will not be returned from the C# PasswordHasher wrapper + /// + DECODING_FAIL = -32, + /// + /// Unable to create the number of threads requested + /// + THREAD_FAIL = -33, + + /// + /// This will not be returned from the C# PasswordHasher wrapper + /// + VERIFY_MISMATCH = -35 + } +} diff --git a/Projects/Argon2/Argon2Exception.cs b/Projects/Argon2/Argon2Exception.cs new file mode 100644 index 000000000..f511ead78 --- /dev/null +++ b/Projects/Argon2/Argon2Exception.cs @@ -0,0 +1,20 @@ +using System; + +namespace Server.Accounting.Security +{ + /// + /// An exception class to wrap the errors returned by Daniel Dinu and Dmitry Khovratovich's Argon2 library. + /// + /// Except through very unusual conditions, the only exceptions which could be thrown from PasswordHasher + /// are Argon2Exception, ArgumentNullException, DllNotFoundException (if libargon2.dll is not found) + /// + public class Argon2Exception : Exception + { + /// + /// Construct an Argon2Exception with the specified Argon2 error code + /// Which method the Argon2Exception originated from + /// The error returned from the Argon2 library + /// + public Argon2Exception(string action, Argon2Error error) : base(string.Format("Error during Argon2 {0}: ({1}) {2}", action, (int)error, error)) {} + } +} diff --git a/Projects/Argon2/Argon2PasswordHasher.cs b/Projects/Argon2/Argon2PasswordHasher.cs new file mode 100644 index 000000000..75f1f2d42 --- /dev/null +++ b/Projects/Argon2/Argon2PasswordHasher.cs @@ -0,0 +1,388 @@ +using System; +using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; +// using System.Text.RegularExpressions; + +namespace Server.Accounting.Security +{ + /// + /// PasswordHasher is a class for creating Argon2 hashes and verifying them. This is a wrapper around + /// Daniel Dinu and Dmitry Khovratovich's Argon2 library. + /// + public class Argon2PasswordHasher + { + private static readonly RNGCryptoServiceProvider Rng = new RNGCryptoServiceProvider(); + + // private static readonly Regex HashRegex = new Regex(@"^\$argon2([di])\$v=(\d+)$m=(\d+),t=(\d+),p=(\d+)\$([A-Za-z0-9+/=]+)\$([A-Za-z0-9+/=]*)$", RegexOptions.Compiled); + + + /// + /// How many iterations of the Argon2 hash to perform + /// + public uint TimeCost { get; set; } + + /// + /// How much memory to use while hashing in kibibytes (KiB) + /// + public uint MemoryCost { get; set; } + + /// + /// How many threads to use while hashing + /// + public uint Parallelism { get; set; } + + /// + /// The type of Argon2 hashing algorithm to use + /// Argon2d - The memory access is dependent upon the hash value (vulnerable to side-channel attacks) + /// Argon2i - The memory access is independent upon the hash value (safe from side-channel atacks) + /// + public Argon2Type ArgonType { get; set; } + + /// + /// Length of the generated raw hash in bytes + /// + public uint HashLength { get; set; } + + /// + /// How strings should be decoded when passed to the Hash method. + /// The default is Encoding.UTF8. + /// + public Encoding StringEncoding { get; set; } + + + /// + /// Initialize the Argon2 PasswordHasher with default performance and algorithm settings based upon the environment the hashing will be used in. + /// You should perform your own profiling to determine what the parameters should be for your specific usage; however, this attempts to provide + /// some reasonable defaults. + /// + public Argon2PasswordHasher() + { + TimeCost = 3; + MemoryCost = 8192; + Parallelism = 1; + ArgonType = Argon2Type.Argon2i; + HashLength = 32; + StringEncoding = Encoding.UTF8; + } + + + /// + /// Initialize the Argon2 PasswordHasher with the performance and algorithm settings to use while hashing + /// How many iterations of the Argon2 hash to perform (default: 3, must be at least 1) + /// How much memory to use while hashing in kibibytes (KiB) (default: 8192 KiB [8 MiB], must be at least 8 KiB) + /// How many threads to use while hashing (default: 1, must be at least 1) + /// The type of Argon2 hashing algorithm to use (Independent [default] or Dependent) + /// The length of the resulting hash in bytes (default: 32) + /// + public Argon2PasswordHasher(uint timeCost = 3, uint memoryCost = 8192, uint parallelism = 1, Argon2Type argonType = Argon2Type.Argon2i, uint hashLength = 32) + { + TimeCost = timeCost; + MemoryCost = memoryCost; + Parallelism = parallelism; + ArgonType = argonType; + HashLength = hashLength; + StringEncoding = Encoding.UTF8; + } + + + /// + /// Hash the password using Argon2 with a cryptographically-secure, random, 16-byte salt. + /// This is the only overload of the Hash method that the typical user will need to use for password storage. The other overloads are provided for interoperability purposes. + /// Do not compare two Argon2 hashes directly. Instead, use the Verify or VerifyAndUpdate methods. + /// A string representing the password to be hashed. The password is first decoded into bytes using StringEncoding (default: Encoding.UTF8) + /// A formatted string representing the hashed password, encoded with the parameters used to perform the hash + /// + public string Hash(string password) + { + CheckNull("Hash", "password", password); + + return Hash(StringEncoding.GetBytes(password)); + } + + /// + /// Hash the raw password bytes using Argon2 with a cryptographically-secure, random, 16-byte salt. + /// Do not compare two Argon2 hashes directly. Instead, use the Verify or VerifyAndUpdate methods. + /// The raw bytes of the password to be hashed + /// A formatted string representing the hashed password, encoded with the parameters used to perform the hash + /// + public string Hash(byte[] password) + { + CheckNull("Hash", "password", password); + + return Hash(password, GenerateSalt()); + } + + /// + /// Hash the password using Argon2 with the specified salt. + /// Unless you need to specify your own salt for interoperability purposes, prefer the Hash(string password) overload instead. + /// Do not compare two Argon2 hashes directly. Instead, use the Verify or VerifyAndUpdate methods. + /// A string representing the password to be hashed. The password is first decoded into bytes using StringEncoding (default: Encoding.UTF8) + /// A string representing the salt to be used for the hash. The salt must be at least 8 bytes. The salt is first decoded into bytes using StringEncoding (default: Encoding.UTF8) + /// A formatted string representing the hashed password, encoded with the parameters used to perform the hash + /// + public string Hash(string password, string salt) + { + CheckNull("Hash", "password", password, "salt", salt); + + return Hash(StringEncoding.GetBytes(password), StringEncoding.GetBytes(salt)); + } + + /// + /// Hash the raw password bytes using Argon2 with the specified salt bytes. + /// Unless you need to specify your own salt for interoperability purposes, prefer the Hash(byte[] password) overload instead. + /// Do not compare two Argon2 hashes directly. Instead, use the Verify or VerifyAndUpdate methods. + /// The raw bytes of the password to be hashed + /// The raw salt bytes to be used for the hash. The salt must be at least 8 bytes. + /// A formatted string representing the hashed password, encoded with the parameters used to perform the hash + /// + public string Hash(byte[] password, byte[] salt) + { + CheckNull("Hash", "password", password, "salt", salt); + + byte[] hash = new byte[HashLength]; + byte[] encoded = new byte[39 + ((HashLength + salt.Length) * 4 + 3) / 3]; + var result = Argon2.Library.Hash( + TimeCost, + MemoryCost, + Parallelism, + password, + salt, + hash, + encoded, + (int)ArgonType, + 0x13 + ); + + if (result != Argon2Error.OK) + throw new Argon2Exception("hashing", result); + + var firstNonNull = encoded.Length - 2; + while (encoded[firstNonNull] == 0) + firstNonNull--; + + return Encoding.ASCII.GetString(encoded, 0, firstNonNull + 1); + } + + + /// + /// Hash the password using Argon2 with the specified salt. The HashRaw methods may be used for password-based key derivation. + /// Unless you're using HashRaw for key deriviation or for interoperability purposes, the Hash methods should be used in favor of the HashRaw methods. + /// A string representing the password to be hashed. The password is first decoded into bytes using StringEncoding (default: Encoding.UTF8) + /// A string representing the salt to be used for the hash. The salt must be at least 8 bytes. The salt is first decoded into bytes using StringEncoding (default: Encoding.UTF8) + /// A byte array containing only the resulting hash + /// + public byte[] HashRaw(string password, string salt) + { + CheckNull("HashRaw", "password", password, "salt", salt); + + return HashRaw(StringEncoding.GetBytes(password), StringEncoding.GetBytes(salt)); + } + + /// + /// Hash the password using Argon2 with the specified salt. The HashRaw methods may be used for password-based key derivation. + /// Unless you're using HashRaw for key deriviation or for interoperability purposes, the Hash methods should be used in favor of the HashRaw methods. + /// The raw bytes of the password to be hashed + /// The raw salt bytes to be used for the hash. The salt must be at least 8 bytes. + /// A byte array containing only the resulting hash + /// + public byte[] HashRaw(byte[] password, byte[] salt) + { + byte[] hash = new byte[(int)HashLength]; + + var result = Argon2.Library.Hash( + TimeCost, + MemoryCost, + Parallelism, + password, + salt, + hash, + null, + (int)ArgonType, + 0x13 + ); + + if (result != Argon2Error.OK) + throw new Argon2Exception("raw hashing", result); + + return hash; + } + + + /// + /// Hashes the password and verifies that the password results in the specified hash. + /// The ArgonType must of this PasswordHasher object must match what was used to generate expectedHash. + /// The other parameters (timeCost, etc.) do not need to match and the parameters embedded in the expectedHash will be used. + /// Hashing the password should result in this hash + /// The password to hash and compare its result to expectedHash. The password is first decoded into bytes using StringEncoding (default: Encoding.UTF8) + /// Whether the password results in the expectedHash when hashed + /// + public bool Verify(string expectedHash, string password) + { + CheckNull("Verify", "expectedHash", expectedHash, "password", password); + + return Verify(expectedHash, StringEncoding.GetBytes(password)); + } + + /// + /// Hashes the raw password bytes and verifies that the password results in the specified hash. + /// The ArgonType must of this PasswordHasher object must match what was used to generate expectedHash. + /// The other parameters (timeCost, etc.) do not need to match and the parameters embedded in the expectedHash will be used. + /// Hashing the password should result in this hash + /// The raw password bytes to hash and compare its result to expectedHash + /// Whether the password results in the expectedHash when hashed + /// + public bool Verify(string expectedHash, byte[] password) + { + CheckNull("Verify", "expectedHash", expectedHash, "password", password); + + var result = Argon2.Library.Verify(StringEncoding.GetBytes(expectedHash), password, password.Length, (int)ArgonType); + + if (result == Argon2Error.OK || result == Argon2Error.VERIFY_MISMATCH || result == Argon2Error.DECODING_FAIL) + return result == Argon2Error.OK; + + throw new Argon2Exception("verifying", result); + } + + + + /// + /// Hashes the password and verifies that the password results in the specified hash. (See Verify method) + /// If the password verification is successful, this method checks to see if the memory cost, time cost, and parallelism + /// match the parameters the PasswordHasher object was constructed with. If they do not much, then the password is rehashed + /// using the new parameters and the result is outputted via the newFormattedHash parameter. + /// Hashing the password should result in this hash + /// The password to hash and compare its result to expectedHash. The password is first decoded into bytes using StringEncoding (default: Encoding.UTF8) + /// Whether the cost parameters of expectedHash differ from the PasswordHasher object and if the password was rehashed using th new parameters. This is always false if the password was incorrect. + /// If isUpdated is true, then newFormattedHash is the password hashed with the new cost parameters. If isUpdated is false, then newFormattedHash is expectedHash. + /// Whether the password results in the expectedHash when hashed + /// + public bool VerifyAndUpdate(string expectedHash, string password, out bool isUpdated, out string newFormattedHash) + { + CheckNull("VerifyAndUpdate", "expectedHash", expectedHash, "password", password); + + return VerifyAndUpdate(expectedHash, StringEncoding.GetBytes(password), out isUpdated, out newFormattedHash); + } + + /// + /// Hashes the password and verifies that the password results in the specified hash. (See Verify method) + /// If the password verification is successful, this method checks to see if the memory cost, time cost, and parallelism + /// match the parameters the PasswordHasher object was constructed with. If they do not much, then the password is rehashed + /// using the new parameters and the result is outputted via the newFormattedHash parameter. + /// Hashing the password should result in this hash + /// The raw password bytes to hash and compare its result to expectedHash + /// Whether the cost parameters of expectedHash differ from the PasswordHasher object and if the password was rehashed using th new parameters. This is always false if the password was incorrect. + /// If isUpdated is true, then newFormattedHash is the password hashed with the new cost parameters. If isUpdated is false, then newFormattedHash is expectedHash. + /// Whether the password results in the expectedHash when hashed + /// + public bool VerifyAndUpdate(string expectedHash, byte[] password, out bool isUpdated, out string newFormattedHash) + { + CheckNull("VerifyAndUpdate", "expectedHash", expectedHash, "password", password); + + if (Verify(expectedHash, password)) + { + var hashMetadata = ExtractMetadata(expectedHash); + + if (hashMetadata.MemoryCost != MemoryCost || hashMetadata.TimeCost != TimeCost || hashMetadata.Parallelism != Parallelism) + { + isUpdated = true; + byte[] salt = hashMetadata.Salt; + newFormattedHash = Hash(password, salt); + } + else + { + isUpdated = false; + newFormattedHash = expectedHash; + } + + return true; + } + + isUpdated = false; + newFormattedHash = expectedHash; + return false; + } + + + /// + /// Generate salt using a Cryptographically-Secure Pseudo-Random Number Generator + /// The number of bytes of salt to generate (default: 16) + /// A array of randomly-generated bytes + /// + public static byte[] GenerateSalt(uint byteLength = 16) + { + var salt = new byte[byteLength]; + Rng.GetBytes(salt); + return salt; + } + + + /// + /// Extracts the memory cost, time cost, etc. used to generate the Argon2 hash. + /// An encoded Argon2 hash created by the Hash method + /// The hash metadata or null if the formattedHash was not a valid encoded Argon2 hash + /// + public static HashMetadata ExtractMetadata(string formattedHash) + { + CheckNull("ExtractMetadata", "formattedHash", formattedHash); + + var context = new Argon2Context + { + Out = Marshal.AllocHGlobal(formattedHash.Length), // ensure the space to hold the hash is long enough + OutLen = (uint)formattedHash.Length, + Pwd = Marshal.AllocHGlobal(1), + PwdLen = 1, + Salt = Marshal.AllocHGlobal(formattedHash.Length), // ensure the space to hold the salt is long enough + SaltLen = (uint)formattedHash.Length, + Secret = Marshal.AllocHGlobal(1), + SecretLen = 1, + AssocData = Marshal.AllocHGlobal(1), + AssocDataLen = 1, + TimeCost = 0, + MemoryCost = 0, + Lanes = 0, + Threads = 0 + }; + + try + { + var type = formattedHash.StartsWith("$argon2i") ? Argon2Type.Argon2i : Argon2Type.Argon2d; + var result = Argon2.Library.Decode(context, $"{formattedHash}\0", (int)type); + + if (result != Argon2Error.OK) + return null; + + var salt = new byte[context.SaltLen]; + var hash = new byte[context.OutLen]; + Marshal.Copy(context.Salt, salt, 0, salt.Length); + Marshal.Copy(context.Out, hash, 0, hash.Length); + + return new HashMetadata + { + ArgonType = type, + MemoryCost = context.MemoryCost, + TimeCost = context.TimeCost, + Parallelism = context.Threads, + Salt = salt, + Hash = hash + }; + } + finally + { + Marshal.FreeHGlobal(context.Out); + Marshal.FreeHGlobal(context.Pwd); + Marshal.FreeHGlobal(context.Salt); + Marshal.FreeHGlobal(context.Secret); + Marshal.FreeHGlobal(context.AssocData); + } + } + + + private static void CheckNull(string methodName, params object[] arguments) + { + for (var i = 0; i < arguments.Length; i += 2) + if (arguments[i + 1] == null) + throw new ArgumentNullException(arguments[i].ToString(), string.Format("Argument {0} to method PasswordHasher.{1} is null", arguments[i], methodName)); + } + } +} diff --git a/Projects/Argon2/Argon2Type.cs b/Projects/Argon2/Argon2Type.cs new file mode 100644 index 000000000..dd24c27a5 --- /dev/null +++ b/Projects/Argon2/Argon2Type.cs @@ -0,0 +1,18 @@ +namespace Server.Accounting.Security +{ + /// + /// The type of Argon2 hashing algorithm to use. + /// + public enum Argon2Type + { + /// + /// The memory access is dependent upon the hash value (vulnerable to side-channel attacks) + /// + Argon2d = 0, + + /// + /// The memory access is independent upon the hash value (safe from side-channel atacks) + /// + Argon2i = 1 + } +} diff --git a/Projects/Argon2/HashMetadata.cs b/Projects/Argon2/HashMetadata.cs new file mode 100644 index 000000000..ba1758515 --- /dev/null +++ b/Projects/Argon2/HashMetadata.cs @@ -0,0 +1,60 @@ +using System; + +namespace Server.Accounting.Security +{ + /// + /// HashMetadata represents the information stored in the encoded Argon2 format + /// + public class HashMetadata + { + /// + /// The type of Argon2 hashing algorithm to use + /// Argon2d - The memory access is dependent upon the hash value (vulnerable to side-channel attacks) + /// Argon2i - The memory access is independent upon the hash value (safe from side-channel atacks) + /// + public Argon2Type ArgonType { get; set; } + + /// + /// How much memory to use while hashing in kibibytes (KiB) + /// + public uint MemoryCost { get; set; } + + /// + /// How many iterations of the Argon2 hash to perform + /// + public uint TimeCost { get; set; } + + /// + /// How many threads to use while hashing + /// + public uint Parallelism { get; set; } + + /// + /// The raw bytes of the salt + /// + public byte[] Salt { get; set; } + + /// + /// The raw bytes of the hash + /// + public byte[] Hash { get; set; } + + + /// + /// A base-64 encoded string of the salt, minus the padding (=) characters + /// + public string GetBase64Salt() => Convert.ToBase64String(Salt).Replace("=", ""); + + /// + /// A base-64 encoded string of the hash, minus the padding (=) characters + /// + public string GetBase64Hash() => Convert.ToBase64String(Hash).Replace("=", ""); + + + /// + /// Converts HashMetadata back into the original Argon2 formatted string. + /// + public override string ToString() => + $"$argon2{(ArgonType == Argon2Type.Argon2i ? "i" : "d")}$v=19$m={MemoryCost},t={TimeCost},p={Parallelism}${GetBase64Salt()}${GetBase64Hash()}"; + } +} diff --git a/Projects/Argon2/Utility.cs b/Projects/Argon2/Utility.cs new file mode 100644 index 000000000..e000e30ed --- /dev/null +++ b/Projects/Argon2/Utility.cs @@ -0,0 +1,13 @@ +using System.Runtime.InteropServices; + +namespace Server +{ + internal static class RuntimeUtility + { + public static bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + public static bool IsDarwin = RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + public static bool IsFreeBSD = RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD); + public static bool IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || IsFreeBSD; + public static bool Unix = IsDarwin || IsFreeBSD || IsLinux; + } +} diff --git a/Projects/Argon2/runtimes/linux-x64/native/libargon2.so b/Projects/Argon2/runtimes/linux-x64/native/libargon2.so new file mode 100755 index 0000000000000000000000000000000000000000..5303d8d75ae871724d54d200f12a33569549c602 GIT binary patch literal 210096 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 G4S3g3+{OShi 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%0ARPA$@>BS6elZXJ_dNxK`s7LF z!!h!WRN|R0|Mvs&e*i0UkN769E)xUgz~&F{n|?Wt51=C|#54bXa9_~QE!WrSg?Q3G z(d6TsJpG&c!%B){z!;wXEAipUs0^Zvi?sRr*`IrYW5&_n#h z|7BskLi{;TCRNduLi&$auN&<0`<_;osc7w z)v=^R`5tibth+=Bf_1UdilP_v`sE{f&Lyt$N>>%iCDPj~=>0*^AQ)=tzs{4dq}p9o zwrsH|kx1{sMLgsCqLLDp1P9PYqSIMYv8=jZfr<3$@8y^tL66{6No8x3{ylh#i zvuxR-3PwNSc~By*k9nXN0Vm2NvRFWN62Z^uv|8p^oCPyy%;wf2?Sq?>BJD$%mqK<& zKcY=VoX*7+{k6O>JxPw}5x%_Wc^V{u@O-@ulrIzbbeV;55FAgB=l0(R*0Vo7W}Q+n zkH`~nd_5`0=`1gHR8=ub6F3xjczgv97#uGb+N_c#^AI|nrN!>z{sjIU z`r#EG9v>l+2#%*Gl4AkYQ^n8ebl7LyVYAx#(^QmoqDZa?1#G^G!=%Reb~Y056#TLi z(#=(s#qK2&%F7lOS1qnscEj~~*O#sYgktRa5o*j>fPN-YG7*wI@|q7=4@O0gD@r#i zLiR&E{aoV*>KSrGDAuoCkQZFRCu2hHSs#7M^ zR9BH!=r?<1wcEAy`rG0)b2Z8momr^oe1zi!O!XeRhBPpwf&W~lL_WF_qpyIW?lI(V`aBwqTD<3ymap~|%<|na$3JR2q2;$4ZrkRc=%;wz zu2UxsFL(Q9->uCJs7N`v$bl4ZN7r}nr*LDtNA#;`Tk_B zaIflLwMo@Jjr_-T#Iol51V>){0Rt{l{WZwkAGzx?@Cc~hkoo79dlob-x?YNIxWcL^ zO#XS6J1ui9b7re+jy?+J4lSStBgQS?KzKvl6L5p7&z8xOPO~HrlI+@c)mLa#wPu#l z$1)ZpW6L>2RqyE(!$b1{7HT^RwU9-NYBg=z+*Vb4FY+Y@bt+U;`|n_;Y7IV{*;hD4 z)t;G8n7+A2Z9@@a4(+8S2rSxmtM)=AOZeLgR-!OdEA&8BB&^b8LstSiO}5{0u$}^| zw(5CbVVhR?M_(ay_ZO{jW4L!-Al#c}+tg%hrXrf{Rn`9{@w94RMs9@IcJ0%;fcq+~ z!J(Z}eKp3&j?tuzQ<2G#xPu<(mLn+M;X%xyeeLkAGCF)UIjV0}wptf;5681`XlEj$ zP`a@0qKrW!SwzmCkdwDh+pDe#kpg~hx!bb9a*xGHM#-Kh8Kc8DH#6LuY0Ji=%TYC} z$%v|3O_>gDl&Q&T%Dn`b2y^g+pgOBbk5GwxiN{EmGSI$>Ubr_0Cg8If!`<^*K+0jt zCaU0(m2w`z$RA>K$iDt7@{kz)^4t@nBaK$l`_A&PdR-c$Bk{kheyDHnmuJV>|F(XJ zVC3N#9g@eA(Ee1dmD-f$4c-7lz_4q5mN(jA4X`sq?f*uKMSD-x-nVNf9a>i;FprET zs0KTXhPw60h55H>Hjh?E4auT~9NHI=_S-a4QQI~ z>m1tOsPSpfP{R|=#G!rZThOL`6nQeAS#NgRZxYpT@A60nQT4Hg73sT^ zH=q*;ty=r}ChPG1joAC%Btau>C%gB`7v=RoowW+b2#f<&Uy-wv*sBG^3EB^J9i-ODTDG3fp;^p41;$oMH<0- zuj*|ytKOz0L)}?;!p=(uQH)x*&;3g-M>ZEVyI<9mw!(rmxb;nFF&KJE{fKYUyPC zz-%TK>6d7mCJ)Sn;vjcJ_|49@5e7mBSLFwF;nSVL@af9t88UL1M;>fc^S8N28(tfe zWw~L@rH0qO$vCG*x2gH9HJ#BNmN!0uwVZ0C@x7t80ItE7cc^13Lg7EDKi9stYv;5* zkukkwcZNDUOv>h)p)ag!G1UG9fZcbI#d}&>Tq;tm+S})uoJH%lc-y(rU4$|Yw7)@( zPWm^}pXo-rm*1$Tzt3uH9HDZ0ff-cT!$} z24e7(4TH2X)ZI|0z&<-_a9gyF`iITbNiXQwiNP0x^I8^kga8<>Fth%CGYkv)uf+0C zF6byd(VxGSp{#QeHIj3p-7Zu;#Qs^2RiZHdryqd<9Xv7PeyI_y-mZS+!{7 z=PcS}#VW}x7Hxcs))pdO0BZ7rR)?NHHVDawvvX97kg=#d0Y&g01!x%m~?@n|0(7bz)l!a1RR4R)~Wl^cjM~Dc*-_-N)$p8;n^&KpC$0K1b&vl&wPYtGeqCW!zax=e71;%^B!jT zpwIF_pXGx-&(9M0Spq*x;AaVZ$S>&E3;F>;zg^I0`6NHVBtL~DKg);wJp2vIKMVOe z{4CFh{P3+zejYw)=HatNEQI_NlKd2s{1lS>EFbdo@HZ?U^jZE{$j{OtKM#LX&%-AJ zJbbpDh0s5RBtL~DKZPVe%ZL0t6!?&z!vY`jC!;*+pNCJHdH8G*3n4#+BtL~DKZPVe z%ZL0t6!?&z!vY`jGZ^;6!zTkge72p1ke@=5pF)zKLXw~5Lw+6#e8|sXhR-G=i~84t z@0`unIaRD-me{pcEHbIu4%P5-k6PE_zFgJ1)eN@k>oy{uw@W?sl_Nh;Gez}HFQR3e z%dpNFZMFN-I{)zu%dSPi z_(Kw9v@iA7PPXtgoYrTtC^Qpo!|t2Dgh22$AdUMLS`Cf1_s2VGz?RXcbz0^;eW?~k zY=JwqgEnIu`swG0mS;Pl(O~;9)ju&=UDK#wanRv^ zDR3$pWuA~0_<{vAaDB5GI5ywvF?MWe7#Abtg7r`wF)GUFTB~Y^%Dv>sGQvMw}Yh))rBM|A;)kNWUX&_R7Ty*e`w{Y5<7;Njsj^$0m1PmE7}j87oOr(N*j zbWk6LkNWVC(P8!Bbp7o-+@N6nlhp^Is1F>Fs1J*=`mh+Q4|h*>0Zv!Y!Si8sP#;dO z&dfu95f3+bc=${`LQ$U>pZXXda(-k4cs_y;r-S-1eAI`Bj1H?0r|WO$;RXek%<6+s z)CYDd>ce8JJ}k!SgBY_nPFK)DeHb0ohtsPw^Uz9K6h_K&3m06m?D111V|(9Sbp+#z07}C#t@+sf?7iHno*xU?UoG6E%mh_D*8ieYaSA_v^7o zMFlof9xdbl?=gzvo%Vg~WxmSCXF&sXixkrM zHa0#-$CI<=3p_y9XWWN=!s?qohL!|t?*ZUlZPcM(YBkjT6o>a1S1Q{h%g=6c-lYSgbm&TJ>*gSlV)861Z@AQg1~P{qhM*E$muMBrw9J3troCM>L`t!katY8gM>nBU5*=7(AXvzn0{!7X(@3l{T! z)ghcbX^sZThE%Pvd8#_X@K7)M)x3S3<1iQKoM1yIb7|f_?B_8mP2Xcr&7S{pP1lzF zXhC3ROB9xf3A{RCq%-TERzo5hRyD|xtKoj}{j(Q5S`=oH1*>g#!Ay*|Jr zPwU%R1gr&(Zb2gxyUL6;3$tqV)JHQKMjlzOH}lBT`XUyA9301A$-@on1dWZ7hDXw< zmox&BM!TTVDrj^I8ktZ#lY@mM2h$bmV&oCX!6T4EsBsp@@mKP2!#Y7@qom=HH0mXd zfTYnbXtW9%-GW9Y?10I^LXrc08P^AoKn@;(94rETa2$Un59h7}fdw0ZgeM}g>m_zT zVz(n=iH5CH?;B(AMgcU{y$gH5b5bl#DJBZ7+DnwA`j{bEwH!8j-HZ_>IR%H-L&M-d zXOSf)`(|fb3@`6iF$fHPMl*Gcmsho_`KJsIljmd!n7YGy?MU-(ptRtDVX6+x1%WAf zEpj}j`qpnJ`&6|#&CLYt6#&M(>$kTHU@rj?0kji9woEt?0(u32C5iRhX}N%MuvD>r zyPg4~npJO5udX@mffzMwJ4WGYi1iBSZm4}g1w-v4)+FFESd*Y|uomzq8urCn0FKcN z(gy0#StPcBUr^e>Hed#!{~zrCINFPM+N?WJLHDTmnJP8#Vd&V<5I3PS97N=lSs&m$Hmm=V$a`+UP5AoS$)s zW!!y!#yiNcYHud8ewCHaKEM3GAVc+4XVMC74!k7POLdBPk$$qEQiqX}?^l_=>g>pK zIAPdSkd5j=W%HMPbbLd1N~ZouG!ixZ^f1Zo(B(Fg{S4?-yx2syW` zmCuJ^`Gl>z--o$1t(_#(Ldr7VY!kYubtKw6cstlXb!={&3t!dBCZdr{4F9MIEyK7^ z(ohPee#}ZurgYkIQzAz&c7tF~+$8JO?#}6)NNf35qbjOK+-m;G@)n&RrTX`mtGURk z^OtU8RZ&Ytm!0!>E zWfOLu8#`mIfH4|)Bp||i5qfwyy$G4p&2%&3mX01U^>fVrMM7rkW)47xG&K+R8Q3?R z32A0v*KlSgLhKo04aYYFJBBlj2(e!{GY27d3uopc#9radDLC<^J#q*vAvJl6`2B%9 zXIr*HJA7G(O$e~Y;J+Q?@m_OP&em>V;n78k@Vq@+B7hXPUTrFv&v2RwXaE%LyjRrM zE9&bFpd2dUtrww(hXqAQEHKl}h+8t%cMsf_j343g0;AdRTBAA=t42CCFPQ+%OY&p= z1dEySh#Fg;BI`Va!@Ec8kxwW7eIsipA?C|awY4TP$XNZ{H^MemY)aq_0CUwp#OhXy zHz6)qH<-;tMi1_{meIq60#qS~>US|&8q~U7hT1QQzh7m<4c>M@f4@>j1}8A342Ob7 z?&k43j9M`GncnapEzrj~Rd-rl6XXgSj)WbWj}#O>JI-nSVmq#+-(zeQgq+c;r zS$q$-Bj)g5n`vLuw+2zeL;s4q(d#z9vj-mr`7TdA zb!&FGuev)Y+}GJc4BJ7vHpY-s-dP?XhKxI77-n(^h5=o;udRV-e)xop?adD#?)o_V zN%i}g;ltHm=hDe|h_wqmTadc*R@ASB4$zZOhp6rmlI$p{qMO7xe!K5(eeZ3!odxUX zKam>XlErHP*{^cF^edpR4JYK=aKgM#**619*asyXe1*VW`J@Ua#^LIn*{J_lIgsO> z+k7MRp!9UCj(_1Scb4y?8pkPnK;8F|vID5~hp2Ce7zAdZeyy3L(_HA3rR{?*N zBwlVJ`uoW{{Dd#Ppx=X2Ml+;dkfifHLA>qSA-G;RD8jlASh2zPf&CbXdr*WH1a}i) z20;CCGXQuB-^kxwj|6mjQynI?CKFv#JB{pUYy)a+exL)z_yxoB<_Eo?Nw3baS9j=e zgD*9oQ3WSktK|(eOAHfs)npXb9W&I?$N=x;7;3*DG(KXu)$quNEID9UAE4I}HU#bH zYYmSyAl2AxsN2GFTiibsBUFq49ojaB))JY}OD7jsR&-F8EqYEH`7T>M-8|%%=sg?? z%_20iFf;WDcuh*D!9BE^`mX|J9+yTEoAoVk_ALH9<6bo{sA_&HXQ4rbEhIm7y+vw90v#EXu3DfDRGwQIY@+aJ$RLDhTCyu3j5 z7qHQq;h{n_Gl)nFYh1(^KS9U*=3Z1+!5e^0bt+L#g7D!Gy6WTs|b!ykcI)JruAIFm5^W-}%-l+{$%h6FQJkjshL71e}I7)kvR zY~f-H<|esnu3@T z!AdWW%i0LxA{|)QuxL%4Y20vPBeduCVK|4z`e+2zlZqgb(k$NachwHsaRy|xYMo?q zoCBr_X!P}v^1s+-_rn{-YoSZPqy@uk4e?F38OFnO{#rv^i{;8-3LwLInY|pc;&RbM zg=x^3YByRmbQ0fo3E|ft36<=I@S->yAAc0-`XOGa-P&KLSi9iXo>fQffP}9U;Vcp6 zibt9xD$~u(D>LpJps2Gwp);KQEFy6!71)eyqI8brXC^qxdi({!c4fj#x zAbcsWF%{*m;Mot!x>A?GHO6_XUi7czhT^@|hd;oVIOwAO6+>_=O<+|`!vVXKZhao! z-}x8?SXVmmjcw-ND8Cu`az6?ucK;erFaA6M&K}@Rwy4!tp||=L=V%|`9iK=5V$y!= zO=!jr%@uI?OLU&8CWpaxa7#PcM%|B)W7irT+EN%sQ=|ywaVmx_L!tKDB6E>Ys5@L2 zC^T3P8|uDB^(;-(@6Ke8dD79bXi%U4;$K95Ot@R0;@9QGb`SYv|D?D3OLaw3h@jt< zOcZUP_#DdE9!oJ<{A#P`bcW%Pbx7c++R!)}9av<4WEIgdY~7=Jx3#J|c#Vl~VOc^w z^?{my#_))fa&CHv=Nn27Ig0<*0^Qbg`@77Rf z0$|bR&4Q5Q`i1-=;v7RlmYcYgM-6q~przX$vneqtk02pIN?Pu_u#{AoOIZUU!|_4} z&l7Sj6_!G-1^^))5b{xDOy6CR*Rf?<=r80lZa37;Lpj@HI*Z@jdNcH>0?gZG)tYc9 zC%?z=$P}V!*m?@@e?p17RR5@df{vIH&lw(}ZDv)s2TFVZ%LLJYeu}@h7H?lcN*%B(bLzy;%_0h1F&ez=ioQr;<;I8GSqEHlHET_hv%ik-fe(JJa*q| zBfeD78ktR;$U4|M4_?|=ali(LW(;+|Wt3*-c&31c1^{x<1~9gMfqpAtlSy983Apct z-SVAb_C9pYT^4P+-rh7F%O1=~r%(vkOd*U`rI2?sE3&2+A*GU1XcTBTfH$BUu)Kx6 zWQ*q(#jw61crex5(B7H4g}&^-wv4mm+O_R5t0`F+!}8DU-cYhIhC=NytQO-F81C}s z3z@_6f4_h!w47%OYrsBc3T^-}g}XccfU$4<@ROf^V*UW*cdZqtQ?TG*!}+AE#rl*( z+iTHwIHsl3Z%eZ%fop^tD zNzbm(fuf#WI6Ae<>VN8445%!~*z!wR#Q!)QNeUe>_80ufmhryT|9C4adqn?wK9zkN zg#ABD2_4Ak*%vynr00F2sJ*l1>$Y1JCE5U*r{4D-yhVF^O;0POY(x1|ySxW(&G^Vl z|95HcpW25~YrfhFy3t^;1Fy{%^|TmXYsuJ&jdAcW)Q&{e9RB$_OYrkFtL`hC|EK7a z&*%-_K6Dl~!`3Tpez)l@n|8_)?Bdn5jyuTesr2lT_3W|v-!SotcIjWIidx4VfHW5W z(JJTr20G3_IB{Oeuyy!%dE%R;BF=x}N`J+mg%AE`pE&CO9iF)RW{f72>1m_dteRJ% zlkU8fTRW-_HKZ(04{ggmvBN!_UdZLsIDGgct+R(pQT`X5pT^eb`S(%yDk$x?+qE{# zZTSRlg%Li94lC4}>XD_rhd#D;Gqq39`y$fv33a#o47GQoON583`x$kv_$Z9wA!j=D zZfQz4;Uv-ynrfaJjjVBvhKFs)L62*XVoWs)N9RE7)5sRe^`66*Rjx*Mp{|Qi@1KUW z#y*?RYPuUQ@_4=nVPKISNb)+ySP*MJ4YRP;6x(8DIx;GERk)Nv+Z ztKWokS$hl*|A=TtahUKM8!hV65yHGEzUPpgx)|dWEPB+MitsQ)3s=pb^fRQetT{5v zOj%U;c9~+7DN|&MB2#`WQ`#XM!x|$~0y5_nf|ZnAYUbKI+H>uJ)DpvtIwr8U9hLwWe_& zV2m?7e0o`c>KF*GIydb}w3AS9rA+Btonpe*GV0Fp2ZTzDFoh1(*aD&8s(p<>_=|}> zo#5!I-TH9fxwR&GG~o^VT2SB|Rtu}%*Hi33`0&0%;SKu_g)FPib%t1RNCS(LNKFru@d33lv+Te|*E`Oxs8VG<1RrSU+b51WlC2}g@ zZNJt3D3hT>@1JEE`?h~0li^Fff5r5%r$PrRd*1VJVls5;{l6m-#(onzp!R&NHLW?t zBxu68;M51+FUDtlFp>!nKz&ZNdfO*tG-vc?bXy)xh5#yju(8m8Z8~0W^7i7zC0nzl zF&WF8y;01Qx(u}yWN71daOb}e033o%Vcx&cce9Bcf}R;090Eqa9b+B-5q^lH_($2T z+Rkx1y{DN&I1Ptj_qOQl-e6K8wC=r>2uH)r5ztBFyr_ja7Cf)))cM(XUgQp#RZ+@6 z@RSso9U!yJCo^LyH^>x4rkG?(JEUP{E|n<(nWC2|^)ltmWrDLurX1xdv~)wPKa-#t z;QZ7*1d>BAVwj3%T`Rr8TImheOK0aTEhyl>ESMrbYOHudoRSKX8*JV~2m9-g_pk>La)TJe1yn9^ivQ zt+Rtxv!n;G`p2x+KCq74Kf^y}9DKkwsuuGBPh846kw%=`g+GO-5U{P+3-f4?vIl6(Q@-PaWk`-MLU_w8>w&mGXHB+ea7;Z@mV z9Zi-nKh*@7`-5%p2bc(64}VaoeZu@fJ(?rp!XNA)fABbKix~F9AMEM(2bSq$_l6cO z>DlXF!`dPo#^bClLWxB^+h_*B+M=8RjL+yv^afUP1{p!iqlMHOxIegp`-7U8KVUKp z^hukUKS1M$PdYgf;qT&9III zv`|KgY(wD|Xl{T}-id5lINOZxp2p5cXuYxn!dsUe7$l@{pD@Bc?mhafVFum?qya)R z1_*(q_yr^W{`V%>mEw&KtGb%SHgA9T-FIW>5u*X^jChd+Z^ebY@ek{N5)urJQm z2WUvM1cy25Xh+}T!C07`Jy87*n9LYGpA6z4^F))+VMxl`UuuHZNb~-;WKa<^KoDutgWUc8+COj5sos{{SMSSFUku@_))+(-fpWsX)&x1 z*>n`ESvgTxQ{(VIZ!%-~iXDKXQTtWHP%n%(%_Br24V*J6F={ncs+cdD9e#AwDKuQh z>8vApEfE8%i(+iukl-l13)R8$1|o{}F^Jze93R_*o|qgKy!(kg2vly0;pHG4&X*S7 z%uxVM^nxbUCHpr22%}Zkp*7QIBI$h{w<#CyH=uJsgpi}^ z8dc0w&3X*~={RcS;S8{zT52*Gyi*{C=K-)c)LspnpzbQ$s*5m2op@!)N>%2#kph&( z)Y3L}@hF_1m8Ea@Uu(o<)q8Mt%{^RIm@<&w=sZIYc(O#*kG=+aqou=7kjPX<>%LrT zz+hVIfr>sR%ES}J*+vy5HX#vfE54^gR8U0}+cbH*ET@)_f%tj_a;LzS90qH*_hyrV zbxX{kOHCv4TJRQ;VSSKImp;cL?YR~#(lkOt&}%l__YQV=SBHfmXiK-lsvY466u0HI zSa6Cz(@=XB-XgDssA6HT<4fkez8at?2Ri8~cr(w0qdyOra^ja;NPnbLe2R}NDnd^U z&+2x+du-HduzfAw^mX`B(#2Ocd9`e{Eg0})R}fz#-AmjtcKArt3Gc|n>SV=2*SPpf zq3OOeuu}9=uU&_=T72IDRoYCp=FW)KNj_j$Y{ZEyJY(zBl2O%H;C(O)UdF1%NvEl3 zY7P??jImH*)xPeyhK;LJ*Ri9}?2HaI^%}##F?B;EnWnSne_vD_9x~Fi^rilTprX~9 z@DX?TLA-bOv)KDn*f&YRF^hRAI6*OvZu3%-D3*c@Ynl^{$$#NsJNws|y7 z0lk_xJFEL;z?qB$dKVxy&YA*JU}0t~a0d%^Pr)7OMJye6q_cZUk?M_jRL=Bw7|-`r zq|Pv~9(?2?gnT^(siV?yyBkvXRg{8cU&UY2Jy3l3@bRAT_O_G!XhYi`?AW_Oxv%o% zE8*?O&xXToQ5-k;9KSEZpU^3UiZ{~h3D0&s9I{Nq$$@a&u~2YsTO>TUt2VtIS)l_i zWpBu`sxt5j21aYs1C(Z&c6?{Za$Vc5kY!R^Gu_?}|E&uXMVrzab{$7D^1{d3-VX(r zveOMGLk9|#ufm1L+jtg)2n83k9bi(tRQ>*~ka%Ax=<56kqU`2ncDHqrC`Uq;xm|(K z!f8tILVUw7Rex|RRW1~?b)KP7#lC#HADTh;lkAK`G(S{;^A0oU9(bZ(NE`x*3CR^T zsE|wz{jv!)3E7x-E-2jj`siCdDxK@NtfeVucqL8vf+?8DZXJc+qgU3#`y~!>cN{5k4TIHtqP^ zWUiR8E^TWKS(bv^-@5R%%%w^@M8I=^xt?fy2R}NLvppQG?8py4ScxjXbbJR=fmql^ zZ46Q-KB7;KLmsF-+(s?!BuaMmfFD^1v{6G<{j`p6n>$)?N&VVLue44 z2SX(;!^is2!3BnW`cT7MLp$y^!x24%vQgLYD~z2sza6<98C&N>v|`&utsSHCwvYQ^+WT;599gO z;_02}dKcAc!8x+Zoj5Uc96qG&5LlC7hnU5NrNvGE;Eg^PlbZ{C}1mT|M z_S3ie4Q?TQt6@=i)Hr))*hK}_Gdl_$tTF5$a4j2xYuWu_c7K%JA7l5m?EY(ZU&rqM#O~|a{kQD?J9htP z+%XpN|KKS^EVH9mjfEWRmQZ2`Z8|L>)*T;H>>7&gqS#c5HB)RB#kNw6P&!_v*!>iH zkzx-~te#@)DE3>5{hnfLDfSnNJw&l>6k9>DJrr9;u_F{KrC2Y;?n2DM{`Nzu!v6+D zslwqh0hdWw7APxKX5OL9tZ`S?xQ&$+Wy{>IDq~r-amHMSLnZ@sS5z3QmsC`_6Vl2n z@aI@&6<1d;uc#^|y#9iTsjTSi;&S)EV(}@gh^4x^qNJ?Y?J70W-`^Nm`U07pwyUJd zl}LR+8Y?!ZY^lpwQc>Msa%pjSxpH1|IW*`}3SCPps#XqCevk}~F$bzzJylkZaV@gR-^|i)@q<^W%a@VrO?j=<9Wfg8?uELZwC`vUc^t|G{)`KJPyhM~l z#SV&FTzVcWp$2HMqNLbeRz}g^=i!fo*mBm%XOI>JW)gbF)&4sMeSWy+%bVxTbTPUq?aWi0oLs}Q= zT3K0M25L)+tCuKqm)*ClV!2Q}bX4lX@+Iv-(cTd4+0b6fRpmAC5bV;oyzw<13Y_|H zZ`aoS`{FI*d)J?<`g+;TUrqjj^Cu@}zOeJ5&tF>oj~D&)it<~=uU(S*FZaD^`R30b zdaqbH_Q6Xo-`@W73*kw+GQ3c^|BOBfi5`lEHPjK&C?xiGuP~cYFnd)nfmYyy+25kU zG*uai-$nRgkk3NOBRpA_(y0t~9T;uGp^JE6-9#a}*t=o;2qrvPhSI5=q(QWa7s*ES z2$$p~nTRLB6sLSjC%#0B=n@{$B0Qoiqm5n9?>OQgh%{{ z7nPUkghQ9Clhh}blXZ@#Npce|@g^QJkIG9K5M{W;m*^1=@gy0D50#~m=u>@(9?_Cz zi8ftCTRtPAMKnlWic7vkn`jX(UGlk5Sy>07EoGBBmGV$J$w4%!9OV;jqDi#nb0isw zp1i0m(UAHgJfcCgP-ciQnF=6tI5F2}3`>NQ zM8Ysp;NnY0jlT4<%&hNypQOvaoOC+|KdNu8ph+R=0+(**{8ZgoB}rGTOV(u#Pth5n zKouGETjio6JWjeAp^U|!&mxM7QUnr4oucaoq52d>my0**19%X|;Yw2L#VBxzqT7h2 z$=u77q>Yy;$(b0n6=ee%Tk`ckRCKdU2(MCf_17!O^-zu{7b4vVIun&t^G!;MXA1J5 zyzX0oQ=p`nZ&!2yjP1-nRdk-YWM4Wi2w25mx82L3ks|!2jKiHG+$X{o5pELU3nKK3 z@Lmz#A;POgm@2|!OE}%XiSQv2&KBVq5snmLbTKdgxd^w5@HG)WE5fxRTp_}{MR=Jt90S!Zb0j%@pDHL}(J>^&*@i!rMgX5aFF7EE3_p zB6N#TYGcqv2$?w)4ryRW149}Z(!h`ghBPpwfgueHX<$eLLmC*;z>o%pH1I#7fvmBa zMc4dDDWWqUbY+>HPG_|nhu@qfOYUc?9JGqLX|SpMp4@maHft$V?DpLy*cL zst=%9fGYVxIwy{0;y5Rz&W}rVttew9i{jGm#Q{_*w*+a`?kXHoB&d=@%Sx730>nWJ zr;@6SC{{M;Q2ND`66M2`6%|#^g%ImL#hbcF@uyb1N^ttlxxB2>MIzz|r}ARz{l(>F zI8y3zmMz0+*J|ZV>O$rBX{B_A&qeHTZchoP^OJfKekXld%~F!%gY?@Smg&xta#wK` z2;czf-qMvR4=0s6mBu6`)vfH;mAF?ZXLaoS z-kKyFTP$0&QrVd7QoJcj(#lHL4MLn#I(DMasr++#vQmFB&Ifre!7YGyeUhBY<3#bB zBqf>XIF%PApMsXUH$K52kk%&)kw0WeU2#Z%NG48y#^>lZeviccK8gE%os%Sb1F5Y)BL3I#gwsgq z7V+bVdvbXCImFlHpkO`SHqtFXx7O=$YsUv*ljx8sv|n9aj6=HhDg1OLJ*O8^K=LLO ztDk~mFtImNN?j|Q#pRVtit$P;)W+<@31g^nDQzib#pOzE8c64(cm-MvH=}bYgFfgN zQo%nT)Vt}{Y9>isv1eV6qc|_4M5_gv8*if$x1j_KrRyF8yssA;dwdBp| ztdYN!o}vVPLxsB8-LsA%uzUOODc+91o(4j%vN*eY)`;U^IFog8Q9#$4Jj+b~)}^mY z&1BcQRQi{@QJ0z7p61aN8FTB0*XuS8Z%qn}45WCHi~$|~C2vexmljCsPTH7}o0+*z zA4v0zHk$)_xRJ>?pm!034!}_8QUy$ZGnuZt1Z;G0c(H)%@8NJY!KsMf$KlliHVgRI z1cQ$=zDM(5$^x&^#VaWLhZ z@GHWPE`n#^Rzv_Uf(hRv@c&WZOPKNrKY$-y1QULM09*tUz8Q6(i~jx{@s}{=6Mid2 za8W?`@i5_Mio=ie$Mgta!c?B{aior21QUKdO!!3te~rMGu*5fW^ceqmnDFZb{u2UU z!V*88-(dW^1^%A|zJw)yJU_yZhlzi#IB2>>;7eHI|7ZL?0)Lmlm$1Z-=QkMtfWSX2 z@Fgtq*U`aBTm%z-JWTS>!rP*B9T)f#j^T@z8^e!-3BMg@FzKQ%0@3rAu*A>g*)jg{ zFyVI#{L2Ksgug4k!rt{(lxqaOgug3(rof*f@Fo0R@r?rCCh#TvUGZ}T{yz$Q34d37 zv%oJB_!5@*^Z^dK2xiYe4krD#;tL6Mxdpz2zbk$b#u0QqD)1%zUGcl|i6Xk55%?08 z__;hgCVxCk@*C;!F|NM~dZ|&smw&U9q?fOyH)TXkR9}g4%Sw>#TNdjNO65qqKWBQAS z3BT3I3*0X2FJOsZ#Is}g@i5`%j^zbr3w#Mnd}9KBJj~=5`1eZr1uXI7?PUfM<6*-0 zi1H5#d=h^-EaWLTr1pWqrFJXzlF@b+PO!$@8 zae{vm_!5@*vnYa#0+K%-X8f;b*~;sZzknrv0CrE8#E*vw-!qBlZx{FymiXp4e?$D^ zVaER^j=xXx7qG-rwFbXejH5vjW_fBuLZt@sTlFkjVn+5<6**=p$ECN#p& zOz=9(?3W$F^O!)N{maUiszJ#ef@vo!^E(!=g9wz+E0+y{@ zC-5aqK6}F{kjGIYXV=w5!MKd{nRp3il;(NsW zieS=TJWTlPkGLamp1_x|#5Z&DG5d^%nf!P00!}HvfF=Iq1pIjT+w{K}^y2lu6fo(( zD`EaxB>4SV@RzXUZ%)vEJWTS-`S)glFJX!QaYFwS568<--HZV=JRV+QyauKiKtzsb z@Cq1%<@}gl=%;)+Uc~whgXQ>>>Q4D`KKu&-%l7q%fTg|vi^Lc0>16>MVYhTO;79c2 z{A`zi<$UX~faUz7N5FDEOMfqk@a6oJJ{-_1T5zZF2G=i|NL5>0DBVPUnjuyQOtP!mlNP^3GmwqaBBj*Hvw)> zfFlWTZvvbKzY{Ods04US0(?~hJQ2u~@SBX^P59Ag{C|SqRQztnZyJ8o#%{&WjGqO+ z+wd#EFCRZEe*YaBM#cFpTNGFUXP;<@Emk}6S%ZpYH?W0y85i3Hv}_zp8nDtXQ`zFP z1O{&NB&4zx;Dj``I2=oh+wPEQVs~L67%yq*K!ELk$h{7MRmxV#owOSfOBqPF)XCv^ zT4e))!3dX~N4QK7l8hugfYtz!%Y<|ZGRx#Rp^-FD>R1A&zL2l-W6yvu`^$)vFYU)b zw(>s!a?;ZNz!bjdA4_Aq0x?Kz8eCut%vsXEdEy+nr{?6flv`?$3>zT>b~<>{z|9bz zCU-ypiER|N87Vj3uoKt6y91z1Y@Uei9hQO}9==&3A=)x=ifujTAUlPGJYb{H*}uJr zt=xnSSS0YRS48-3DBE8JR2{e7N?>dYm~FHUNa35pa@Upbx5}MXK~opo>zc!6sMC(0u9|yJ5dwnR^yW>6YeWsT2--ZVX+&Z%$e|yuF8t) zGIvE)nX7t2<&u)?u-(1PRdpTrTNA3QN+yV}8eLzaOt`SbYa&e2@NPQm;i$n zbh57l!IJsLtyHS0F!ehn6;-ak=Xny|brbU^PtILPPxE|N5bvMj+VgqcBAs=hrbcH5 zF68S5a~k~)YJg8-&W@8qYrzQxG^g|Y%OD<+DloX`VugiYHIy0-C;ksfqmThevA)p z{+=3g%@n-xoiSr5H)aU#7i>2&YB2LsQf*WNZjj+^Gfq4<&i82 rJ@fzv&s$@xyOtvi(PLIry8j*-fOcKU6np}#nApeL@PHl#Q;Gi%{naB_ literal 0 HcmV?d00001 diff --git a/Projects/Argon2/runtimes/win-x64/native/argon2.dll b/Projects/Argon2/runtimes/win-x64/native/argon2.dll new file mode 100644 index 0000000000000000000000000000000000000000..6a46dd60dbdafe306796fc36a1a7202e3ffc2ec8 GIT binary patch literal 125952 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 WNVn2m(p}ySW&5%{V0%FK!2bcjm!8-F literal 0 HcmV?d00001 diff --git a/Projects/Scripts.Tests/Accounting/Security/Argon2PasswordProtectionTest.cs b/Projects/Scripts.Tests/Accounting/Security/Argon2PasswordProtectionTest.cs new file mode 100644 index 000000000..082ddb0cb --- /dev/null +++ b/Projects/Scripts.Tests/Accounting/Security/Argon2PasswordProtectionTest.cs @@ -0,0 +1,30 @@ +using Server.Accounting.Security; +using Xunit; + +namespace Server.Tests.Accounting.Security +{ + public class Argon2PasswordProtectionTest + { + private const string plainPassword = "hello-good-sir"; + + [Fact] + public void TestValidates() + { + var passwordProtection = new Argon2PasswordProtection(); + + string encryptedPassword = passwordProtection.EncryptPassword(plainPassword); + + Assert.True(passwordProtection.ValidatePassword(encryptedPassword, plainPassword)); + } + + [Fact] + public void TestPasswordDoesNotValidate() + { + var passwordProtection = new Argon2PasswordProtection(); + + string encryptedPassword = passwordProtection.EncryptPassword(plainPassword); + + Assert.False(passwordProtection.ValidatePassword(encryptedPassword, "Not the same password")); + } + } +} diff --git a/Projects/Scripts.Tests/Accounting/PBKDF2PasswordProtectionTest.cs b/Projects/Scripts.Tests/Accounting/Security/PBKDF2PasswordProtectionTest.cs similarity index 87% rename from Projects/Scripts.Tests/Accounting/PBKDF2PasswordProtectionTest.cs rename to Projects/Scripts.Tests/Accounting/Security/PBKDF2PasswordProtectionTest.cs index 1b1ec46bf..58eba9ca0 100644 --- a/Projects/Scripts.Tests/Accounting/PBKDF2PasswordProtectionTest.cs +++ b/Projects/Scripts.Tests/Accounting/Security/PBKDF2PasswordProtectionTest.cs @@ -1,7 +1,7 @@ +using Server.Accounting.Security; using Xunit; -using Server.Accounting; -namespace Server.Tests.Accounting +namespace Server.Tests.Accounting.Security { public class PBKDF2PasswordProtectionTest { diff --git a/Projects/Scripts.Tests/Scripts.Tests.csproj b/Projects/Scripts.Tests/Scripts.Tests.csproj index d67207c07..69728f1bd 100644 --- a/Projects/Scripts.Tests/Scripts.Tests.csproj +++ b/Projects/Scripts.Tests/Scripts.Tests.csproj @@ -1,7 +1,8 @@ netcoreapp3.1 - false + x64 + WINDOWS diff --git a/Projects/Scripts/Accounting/Account.cs b/Projects/Scripts/Accounting/Account.cs index 1252c8855..6fedb2ccb 100644 --- a/Projects/Scripts/Accounting/Account.cs +++ b/Projects/Scripts/Accounting/Account.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Net; using System.Xml; +using Server.Accounting.Security; using Server.Misc; using Server.Mobiles; using Server.Multis; @@ -297,13 +298,9 @@ namespace Server.Accounting public bool GetBanTags(out DateTime banTime, out TimeSpan banDuration) { - string tagTime = GetTag("BanTime"); string tagDuration = GetTag("BanDuration"); - if (tagTime != null) - banTime = Utility.GetXMLDateTime(tagTime, DateTime.MinValue); - else - banTime = DateTime.MinValue; + banTime = Utility.GetXMLDateTime(GetTag("BanTime"), DateTime.MinValue); if (tagDuration == "Infinite") banDuration = TimeSpan.MaxValue; @@ -323,7 +320,9 @@ namespace Server.Accounting public bool CheckPassword(string plainPassword) { - bool ok = AccountSecurity.GetPasswordProtection(m_PasswordAlgorithm).ValidatePassword(Password, plainPassword); + string phrase = m_PasswordAlgorithm == PasswordProtectionAlgorithm.SHA1 ? $"{Username}{plainPassword}" : plainPassword; + + bool ok = AccountSecurity.GetPasswordProtection(m_PasswordAlgorithm).ValidatePassword(Password, phrase); if (!ok) return false; @@ -459,6 +458,24 @@ namespace Server.Accounting // TODO: Offload passwords to its own module so it can be easily written/upgraded Password = Utility.GetText(node["password"], null); Enum.TryParse(Utility.GetText(node["passwordAlgorithm"], null), true, out m_PasswordAlgorithm); + + if (m_PasswordAlgorithm == PasswordProtectionAlgorithm.None) + { + string md5Password = Utility.GetText(node["cryptPassword"], null); + string sha1Password = Utility.GetText(node["newCryptPassword"], null); + + if (sha1Password != null) + { + Password = sha1Password; + m_PasswordAlgorithm = PasswordProtectionAlgorithm.SHA1; + } + else if (md5Password != null) + { + Password = md5Password; + m_PasswordAlgorithm = PasswordProtectionAlgorithm.MD5; + } + } + Enum.TryParse(Utility.GetText(node["accessLevel"], "Player"), true, out m_AccessLevel); Flags = Utility.GetXMLInt32(Utility.GetText(node["flags"], "0"), 0); Created = Utility.GetXMLDateTime(Utility.GetText(node["created"], null), DateTime.UtcNow); diff --git a/Projects/Scripts/Accounting/AccountSecurity.cs b/Projects/Scripts/Accounting/AccountSecurity.cs deleted file mode 100644 index 0e14425ea..000000000 --- a/Projects/Scripts/Accounting/AccountSecurity.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Server.Accounting -{ - public enum PasswordProtectionAlgorithm - { - PBKDF2 - } - - public static class AccountSecurity - { - // TODO: Put it in a configuration - public const PasswordProtectionAlgorithm AlgorithmName = PasswordProtectionAlgorithm.PBKDF2; - - public static readonly IPasswordProtection CurrentPasswordProtection = GetPasswordProtection(AlgorithmName); - - public static IPasswordProtection GetPasswordProtection(PasswordProtectionAlgorithm algorithm) - { - var passwordProtection = algorithm switch - { - PasswordProtectionAlgorithm.PBKDF2 => PBKDF2PasswordProtection.Instance, - _ => null - }; - - return passwordProtection; - } - } -} diff --git a/Projects/Scripts/Accounting/Security/AccountSecurity.cs b/Projects/Scripts/Accounting/Security/AccountSecurity.cs new file mode 100644 index 000000000..57f5dc37b --- /dev/null +++ b/Projects/Scripts/Accounting/Security/AccountSecurity.cs @@ -0,0 +1,45 @@ +using System; + +namespace Server.Accounting.Security +{ + public enum PasswordProtectionAlgorithm + { + // Obsolete algorithms. These are not secure! + // They are included for password upgrades only. + None, + MD5, + SHA1, + + // Support algorithms + PBKDF2, + Argon2 // Recommended algorithm for real security. + } + + public static class AccountSecurity + { + // TODO: Put it in a configuration + public const PasswordProtectionAlgorithm AlgorithmName = PasswordProtectionAlgorithm.Argon2; + + public static readonly IPasswordProtection CurrentPasswordProtection = GetPasswordProtection(AlgorithmName); + + public static void Configure() + { + if (AlgorithmName < PasswordProtectionAlgorithm.PBKDF2) + throw new Exception($"Security: {AlgorithmName} is obselete and not secure. Do not use it."); + } + + public static IPasswordProtection GetPasswordProtection(PasswordProtectionAlgorithm algorithm) + { + var passwordProtection = algorithm switch + { + PasswordProtectionAlgorithm.MD5 => MD5PasswordProtection.Instance, + PasswordProtectionAlgorithm.SHA1 => SHA1PasswordProtection.Instance, + PasswordProtectionAlgorithm.PBKDF2 => PBKDF2PasswordProtection.Instance, + PasswordProtectionAlgorithm.Argon2 => Argon2PasswordProtection.Instance, + _ => null + }; + + return passwordProtection; + } + } +} diff --git a/Projects/Scripts/Accounting/Security/Argon2PasswordProtection.cs b/Projects/Scripts/Accounting/Security/Argon2PasswordProtection.cs new file mode 100644 index 000000000..3d7cc0611 --- /dev/null +++ b/Projects/Scripts/Accounting/Security/Argon2PasswordProtection.cs @@ -0,0 +1,14 @@ +namespace Server.Accounting.Security +{ + public class Argon2PasswordProtection : IPasswordProtection + { + public static IPasswordProtection Instance = new Argon2PasswordProtection(); + private Argon2PasswordHasher m_PasswordHasher = new Argon2PasswordHasher(); + + public string EncryptPassword(string plainPassword) => + m_PasswordHasher.Hash(plainPassword); + + public bool ValidatePassword(string encryptedPassword, string plainPassword) => + m_PasswordHasher.Verify(encryptedPassword, plainPassword); + } +} diff --git a/Projects/Scripts/Accounting/Security/MD5PasswordProtection.cs b/Projects/Scripts/Accounting/Security/MD5PasswordProtection.cs new file mode 100644 index 000000000..23fc59a75 --- /dev/null +++ b/Projects/Scripts/Accounting/Security/MD5PasswordProtection.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; + +namespace Server.Accounting.Security +{ + public class MD5PasswordProtection : IPasswordProtection + { + public static IPasswordProtection Instance = new MD5PasswordProtection(); + private MD5CryptoServiceProvider m_MD5HashProvider = new MD5CryptoServiceProvider(); + + public string EncryptPassword(string plainPassword) + { + ReadOnlySpan password = plainPassword.AsSpan(0, Math.Min(256, plainPassword.Length)); + byte[] bytes = new byte[Encoding.ASCII.GetByteCount(password)]; + Encoding.ASCII.GetBytes(password, bytes); + + return BitConverter.ToString(m_MD5HashProvider.ComputeHash(bytes)); + } + + public bool ValidatePassword(string encryptedPassword, string plainPassword) => + EncryptPassword(plainPassword) == encryptedPassword; + } +} diff --git a/Projects/Scripts/Accounting/PBKDF2PasswordProtection.cs b/Projects/Scripts/Accounting/Security/PBKDF2PasswordProtection.cs similarity index 91% rename from Projects/Scripts/Accounting/PBKDF2PasswordProtection.cs rename to Projects/Scripts/Accounting/Security/PBKDF2PasswordProtection.cs index da0944e15..672efc6d5 100644 --- a/Projects/Scripts/Accounting/PBKDF2PasswordProtection.cs +++ b/Projects/Scripts/Accounting/Security/PBKDF2PasswordProtection.cs @@ -3,11 +3,11 @@ using System.Buffers.Binary; using System.Security.Cryptography; using Server.Misc; -namespace Server.Accounting +namespace Server.Accounting.Security { public class PBKDF2PasswordProtection : IPasswordProtection { - public static PBKDF2PasswordProtection Instance = new PBKDF2PasswordProtection(); + public static IPasswordProtection Instance = new PBKDF2PasswordProtection(); private const ushort m_MinIterations = 1024; private const ushort m_MaxIterations = 1536; diff --git a/Projects/Scripts/Accounting/Security/SHA1PasswordProtection.cs b/Projects/Scripts/Accounting/Security/SHA1PasswordProtection.cs new file mode 100644 index 000000000..2f45c5e85 --- /dev/null +++ b/Projects/Scripts/Accounting/Security/SHA1PasswordProtection.cs @@ -0,0 +1,25 @@ +using System; +using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; + +namespace Server.Accounting.Security +{ + public class SHA1PasswordProtection : IPasswordProtection + { + public static IPasswordProtection Instance = new SHA1PasswordProtection(); + private SHA1CryptoServiceProvider m_SHA1HashProvider = new SHA1CryptoServiceProvider(); + + public string EncryptPassword(string plainPassword) + { + ReadOnlySpan password = plainPassword.AsSpan(0, Math.Min(256, plainPassword.Length)); + byte[] bytes = new byte[Encoding.ASCII.GetByteCount(password)]; + Encoding.ASCII.GetBytes(password, bytes); + + return BitConverter.ToString(m_SHA1HashProvider.ComputeHash(bytes)); + } + + public bool ValidatePassword(string encryptedPassword, string plainPassword) => + EncryptPassword(plainPassword) == encryptedPassword; + } +} diff --git a/Projects/Scripts/Scripts.csproj b/Projects/Scripts/Scripts.csproj index 114419f4f..a30ebe1c3 100644 --- a/Projects/Scripts/Scripts.csproj +++ b/Projects/Scripts/Scripts.csproj @@ -19,6 +19,8 @@ $(SolutionDir)\Distribution\Assemblies true Debug;Release;Analyze + WINDOWS + x64 @@ -38,14 +40,14 @@ - - TRACE;DEBUG + + TRACE;DEBUG;$(DefineConstants) false - + true - + true true true @@ -64,6 +66,7 @@ + @@ -74,4 +77,21 @@ + + + 1.1.118 + all + + + stylecop.json + + + 2.9.8 + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + Rules.rulest + + diff --git a/Projects/Server.Tests/Server.Tests.csproj b/Projects/Server.Tests/Server.Tests.csproj index 09142eb9b..562d89327 100644 --- a/Projects/Server.Tests/Server.Tests.csproj +++ b/Projects/Server.Tests/Server.Tests.csproj @@ -2,6 +2,7 @@ netcoreapp3.1 false + AnyCPU;x64 diff --git a/Projects/Server/Buffers/BufferReader.cs b/Projects/Server/Buffers/BufferReader.cs index f35d4629d..b534ef704 100644 --- a/Projects/Server/Buffers/BufferReader.cs +++ b/Projects/Server/Buffers/BufferReader.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. // See LICENSE file in the project root for full license information. -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Threading; diff --git a/Projects/Server/Properties/PublishProfiles/Linux-SelfContained.pubxml b/Projects/Server/Properties/PublishProfiles/Linux-SelfContained.pubxml deleted file mode 100644 index c43c47567..000000000 --- a/Projects/Server/Properties/PublishProfiles/Linux-SelfContained.pubxml +++ /dev/null @@ -1,10 +0,0 @@ - - - - FileSystem - Release - linux-x64 - true - true - - diff --git a/Projects/Server/Properties/PublishProfiles/Linux.pubxml b/Projects/Server/Properties/PublishProfiles/Linux.pubxml deleted file mode 100644 index fb76af4c2..000000000 --- a/Projects/Server/Properties/PublishProfiles/Linux.pubxml +++ /dev/null @@ -1,9 +0,0 @@ - - - - FileSystem - Release - linux-x64 - false - - diff --git a/Projects/Server/Properties/PublishProfiles/OSX-SelfContained.pubxml b/Projects/Server/Properties/PublishProfiles/OSX-SelfContained.pubxml deleted file mode 100644 index 2f9813651..000000000 --- a/Projects/Server/Properties/PublishProfiles/OSX-SelfContained.pubxml +++ /dev/null @@ -1,10 +0,0 @@ - - - - FileSystem - Release - osx-x64 - true - true - - diff --git a/Projects/Server/Properties/PublishProfiles/OSX.pubxml b/Projects/Server/Properties/PublishProfiles/OSX.pubxml deleted file mode 100644 index 7c45904d8..000000000 --- a/Projects/Server/Properties/PublishProfiles/OSX.pubxml +++ /dev/null @@ -1,9 +0,0 @@ - - - - FileSystem - Release - osx-x64 - false - - diff --git a/Projects/Server/Properties/PublishProfiles/Windows-SelfContained.pubxml b/Projects/Server/Properties/PublishProfiles/Windows-SelfContained.pubxml deleted file mode 100644 index a43797ef8..000000000 --- a/Projects/Server/Properties/PublishProfiles/Windows-SelfContained.pubxml +++ /dev/null @@ -1,10 +0,0 @@ - - - - FileSystem - Release - win-x64 - true - true - - diff --git a/Projects/Server/Properties/PublishProfiles/Windows.pubxml b/Projects/Server/Properties/PublishProfiles/Windows.pubxml deleted file mode 100644 index c6a68c538..000000000 --- a/Projects/Server/Properties/PublishProfiles/Windows.pubxml +++ /dev/null @@ -1,9 +0,0 @@ - - - - FileSystem - Release - win-x64 - false - - diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index b07198e22..a629ba630 100644 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -6,7 +6,7 @@ Server.Core ModernUO - 0.3.0 + 0.3.1 Kamron Batman ModernUO ModernUO Server @@ -17,13 +17,14 @@ x64 8.0 $(SolutionDir)\Distribution - $(SolutionDir)\Distribution - $(SolutionDir)\Distribution + true true false Debug;Release;Analyze + x64 @@ -48,14 +49,14 @@ - + TRACE;DEBUG false - + true - + true true true @@ -86,13 +87,21 @@ - - - - + + + 1.1.118 + all + + + stylecop.json + + + 2.9.8 all runtime; build; native; contentfiles; analyzers; buildtransitive - + + Rules.rulest + diff --git a/THIRD-PARTY-NOTICES b/THIRD-PARTY-NOTICES index 0e65567e8..b8636df40 100644 --- a/THIRD-PARTY-NOTICES +++ b/THIRD-PARTY-NOTICES @@ -580,6 +580,8 @@ consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. +License notice for BufferReader/BufferWrite +--------------------------- The MIT License (MIT) Copyright (c) Harry Pierson @@ -601,3 +603,27 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +License notice for csharp-argon-2 +--------------------------- +The MIT License (MIT) + +Copyright (c) 2016 Kevin Spinar (Alipha) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Tools/clean.sh b/Tools/clean.sh index d289d4a1b..f8054d000 100755 --- a/Tools/clean.sh +++ b/Tools/clean.sh @@ -1,4 +1,5 @@ rm -rf Projects/*/obj +rm -rf Projects/*/bin rm -f Distribution/Assemblies/BouncyCastle.Crypto.dll rm -f Distribution/Assemblies/MailKit.dll @@ -12,10 +13,15 @@ rm -f Distribution/Assemblies/Microsoft.Extensions.Logging.Abstractions.dll rm -f Distribution/Assemblies/Microsoft.Extensions.Primitives.dll rm -f Distribution/Assemblies/MimeKit.dll rm -f Distribution/Assemblies/System.IO.Pipelines.dll +rm -f Distribution/Assemblies/Argon2.Bindings.dll +rm -f Distribution/Assemblies/libargon2.so +rm -f Distribution/Assemblies/libargon2.dylib +rm -f Distribution/Assemblies/argon2.dll rm -f Distribution/libdrng.dll rm -f Distribution/libuv.dll rm -f Distribution/libuv.so +rm -f Distribution/libuv.dylib rm -f Distribution/Microsoft.AspNetCore.Connections.Abstractions.dll rm -f Distribution/Microsoft.AspNetCore.Http.Features.dll rm -f Distribution/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.dll diff --git a/Tools/publish-linux-debug.cmd b/Tools/publish-linux-debug.cmd index a33b7d284..7d833938c 100755 --- a/Tools/publish-linux-debug.cmd +++ b/Tools/publish-linux-debug.cmd @@ -1 +1,2 @@ -dotnet publish -c Debug /p:PublishProfile=Linux +dotnet build -c Debug -r linux-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Debug -r linux-x64 --self-contained=false diff --git a/Tools/publish-linux-debug.sh b/Tools/publish-linux-debug.sh index 69c0e045f..e121aceb1 100755 --- a/Tools/publish-linux-debug.sh +++ b/Tools/publish-linux-debug.sh @@ -1 +1,2 @@ -dotnet publish -c Debug /p:PublishProfile=Linux +dotnet build -c Debug -r linux-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Debug -r linux-x64 --self-contained=false diff --git a/Tools/publish-linux.cmd b/Tools/publish-linux.cmd index 66e59e289..611f1193a 100755 --- a/Tools/publish-linux.cmd +++ b/Tools/publish-linux.cmd @@ -1 +1,2 @@ -dotnet publish -c Release /p:PublishProfile=Linux +dotnet build -c Release -r linux-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Release -r linux-x64 --self-contained=false diff --git a/Tools/publish-linux.sh b/Tools/publish-linux.sh index 281501fea..f87640036 100755 --- a/Tools/publish-linux.sh +++ b/Tools/publish-linux.sh @@ -1 +1,2 @@ -dotnet publish -c Release /p:PublishProfile=Linux +dotnet build -c Release -r linux-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Release -r linux-x64 --self-contained=false diff --git a/Tools/publish-osx-debug.cmd b/Tools/publish-osx-debug.cmd index a8b55ff26..4566baa3e 100755 --- a/Tools/publish-osx-debug.cmd +++ b/Tools/publish-osx-debug.cmd @@ -1 +1,2 @@ -dotnet publish -c Debug /p:PublishProfile=OSX +dotnet build -c Debug -r osx-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Debug -r osx-x64 --self-contained=false diff --git a/Tools/publish-osx-debug.sh b/Tools/publish-osx-debug.sh index 7bf73bc47..e66f2db29 100755 --- a/Tools/publish-osx-debug.sh +++ b/Tools/publish-osx-debug.sh @@ -1 +1,2 @@ -dotnet publish -c Debug /p:PublishProfile=OSX +dotnet build -c Debug -r osx-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Debug -r osx-x64 --self-contained=false diff --git a/Tools/publish-osx.cmd b/Tools/publish-osx.cmd index 6952d1c4a..9565404f6 100755 --- a/Tools/publish-osx.cmd +++ b/Tools/publish-osx.cmd @@ -1 +1,2 @@ -dotnet publish -c Release /p:PublishProfile=OSX +dotnet build -c Release -r osx-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Release -r osx-x64 --self-contained=false diff --git a/Tools/publish-osx.sh b/Tools/publish-osx.sh index 73036b71d..249fe207a 100755 --- a/Tools/publish-osx.sh +++ b/Tools/publish-osx.sh @@ -1 +1,2 @@ -dotnet publish -c Release /p:PublishProfile=OSX +dotnet build -c Release -r osx-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Release -r osx-x64 --self-contained=false diff --git a/Tools/publish-windows-debug.cmd b/Tools/publish-windows-debug.cmd index d52f8b2e7..1398c2e10 100755 --- a/Tools/publish-windows-debug.cmd +++ b/Tools/publish-windows-debug.cmd @@ -1 +1,2 @@ -dotnet publish -c Debug /p:PublishProfile=Windows +dotnet build -c Debug -r win-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Debug -r win-x64 --self-contained=false diff --git a/Tools/publish-windows-debug.sh b/Tools/publish-windows-debug.sh index 1a0b31cc8..3b6a9f8b7 100755 --- a/Tools/publish-windows-debug.sh +++ b/Tools/publish-windows-debug.sh @@ -1 +1,2 @@ -dotnet publish -c Debug /p:PublishProfile=Windows +dotnet build -c Debug -r win-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Debug -r win-x64 --self-contained=false diff --git a/Tools/publish-windows.cmd b/Tools/publish-windows.cmd index fe2ac4372..6bb720871 100755 --- a/Tools/publish-windows.cmd +++ b/Tools/publish-windows.cmd @@ -1 +1,2 @@ -dotnet publish -c Release /p:PublishProfile=Windows +dotnet build -c Release -r win-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Release -r win-x64 --self-contained=false diff --git a/Tools/publish-windows.sh b/Tools/publish-windows.sh index 5b51c26c6..1e359fac6 100755 --- a/Tools/publish-windows.sh +++ b/Tools/publish-windows.sh @@ -1 +1,2 @@ -dotnet publish -c Release /p:PublishProfile=Windows +dotnet build -c Release -r win-x64 Projects/Argon2/Argon2.csproj +dotnet publish -c Release -r win-x64 --self-contained=false diff --git a/packages/do_not_delete b/packages/do_not_delete new file mode 100644 index 000000000..e69de29bb