From 11b67208f46dee55ff33b0a52bd043547ae59699 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sat, 28 Jan 2017 12:42:46 -0700 Subject: [PATCH] created password length constraint --- .../PasswordLengthConstraintTests.cs | 64 +++++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + .../Resources/Language/Language.Designer.cs | 9 +++ mRemoteV1/Resources/Language/Language.resx | 5 +- .../PasswordCreation/IPasswordConstraint.cs | 12 ++++ .../PasswordLengthConstraint.cs | 38 +++++++++++ mRemoteV1/mRemoteV1.csproj | 2 + 7 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 mRemoteNGTests/Security/PasswordCreation/PasswordLengthConstraintTests.cs create mode 100644 mRemoteV1/Security/PasswordCreation/IPasswordConstraint.cs create mode 100644 mRemoteV1/Security/PasswordCreation/PasswordLengthConstraint.cs diff --git a/mRemoteNGTests/Security/PasswordCreation/PasswordLengthConstraintTests.cs b/mRemoteNGTests/Security/PasswordCreation/PasswordLengthConstraintTests.cs new file mode 100644 index 000000000..55800ce0d --- /dev/null +++ b/mRemoteNGTests/Security/PasswordCreation/PasswordLengthConstraintTests.cs @@ -0,0 +1,64 @@ +using System; +using mRemoteNG.Security; +using mRemoteNG.Security.PasswordCreation; +using NUnit.Framework; + + +namespace mRemoteNGTests.Security.PasswordCreation +{ + public class PasswordLengthConstraintTests + { + private PasswordLengthConstraint _lengthConstraint; + + + [Test] + public void PasswordLessThanMinimumLengthFailsValidation() + { + var password = "123456789".ConvertToSecureString(); + _lengthConstraint = new PasswordLengthConstraint(10); + Assert.That(_lengthConstraint.Validate(password), Is.False); + } + + [Test] + public void PasswordThatEqualsMinimumLengthPassesValidation() + { + var password = "12345".ConvertToSecureString(); + _lengthConstraint = new PasswordLengthConstraint(5); + Assert.That(_lengthConstraint.Validate(password), Is.True); + } + + [Test] + public void PasswordGreaterThanMaxLengthFailsValidation() + { + var password = "123456".ConvertToSecureString(); + _lengthConstraint = new PasswordLengthConstraint(1, 5); + Assert.That(_lengthConstraint.Validate(password), Is.False); + } + + [Test] + public void PasswordThatEqualsMaxLengthPassesValidation() + { + var password = "12345".ConvertToSecureString(); + _lengthConstraint = new PasswordLengthConstraint(1, 5); + Assert.That(_lengthConstraint.Validate(password), Is.True); + } + + [Test] + public void MinimumLengthMustBeAPositiveValue() + { + Assert.Throws(() => new PasswordLengthConstraint(-1)); + } + + [Test] + public void MaximumLengthMustBeAPositiveValue() + { + Assert.Throws(() => new PasswordLengthConstraint(1, -1)); + } + + [Test] + public void MaximumLengthMustBeGreaterThanMinimumLength() + { + Assert.Throws(() => new PasswordLengthConstraint(4, 1)); + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 8c5bc2b02..dfd426f4c 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -140,6 +140,7 @@ + diff --git a/mRemoteV1/Resources/Language/Language.Designer.cs b/mRemoteV1/Resources/Language/Language.Designer.cs index 10834abdf..a8e5851bb 100644 --- a/mRemoteV1/Resources/Language/Language.Designer.cs +++ b/mRemoteV1/Resources/Language/Language.Designer.cs @@ -3820,6 +3820,15 @@ namespace mRemoteNG { } } + /// + /// Looks up a localized string similar to Password length must be between {0} and {1}. + /// + internal static string strPasswordLengthConstraintHint { + get { + return ResourceManager.GetString("strPasswordLengthConstraintHint", resourceCulture); + } + } + /// /// Looks up a localized string similar to Password protect. /// diff --git a/mRemoteV1/Resources/Language/Language.resx b/mRemoteV1/Resources/Language/Language.resx index 49ef8c42e..8ec584a29 100644 --- a/mRemoteV1/Resources/Language/Language.resx +++ b/mRemoteV1/Resources/Language/Language.resx @@ -2463,4 +2463,7 @@ mRemoteNG will now quit and begin with the installation. Alert on Idle Disconnect - + + Password length must be between {0} and {1} + + \ No newline at end of file diff --git a/mRemoteV1/Security/PasswordCreation/IPasswordConstraint.cs b/mRemoteV1/Security/PasswordCreation/IPasswordConstraint.cs new file mode 100644 index 000000000..6e1b19d4f --- /dev/null +++ b/mRemoteV1/Security/PasswordCreation/IPasswordConstraint.cs @@ -0,0 +1,12 @@ +using System.Security; + + +namespace mRemoteNG.Security.PasswordCreation +{ + public interface IPasswordConstraint + { + string ConstraintHint { get; } + + bool Validate(SecureString password); + } +} \ No newline at end of file diff --git a/mRemoteV1/Security/PasswordCreation/PasswordLengthConstraint.cs b/mRemoteV1/Security/PasswordCreation/PasswordLengthConstraint.cs new file mode 100644 index 000000000..0c6758143 --- /dev/null +++ b/mRemoteV1/Security/PasswordCreation/PasswordLengthConstraint.cs @@ -0,0 +1,38 @@ +using System; +using System.Security; + + +namespace mRemoteNG.Security.PasswordCreation +{ + public class PasswordLengthConstraint : IPasswordConstraint + { + private readonly int _minLength; + private readonly int _maxLength; + + public string ConstraintHint { get; } + + public PasswordLengthConstraint(int minimumLength, int maxLength = int.MaxValue) + { + if (minimumLength < 0) + throw new ArgumentException($"{nameof(minimumLength)} must be a positive value."); + if (maxLength <= 0) + throw new ArgumentException($"{nameof(maxLength)} must be a positive, non-zero value."); + if (maxLength < minimumLength) + throw new ArgumentException($"{nameof(maxLength)} must be greater than or equal to {nameof(minimumLength)}."); + + _minLength = minimumLength; + _maxLength = maxLength; + ConstraintHint = string.Format(Language.strPasswordLengthConstraintHint, _minLength, _maxLength); + } + + public bool Validate(SecureString password) + { + if (password.Length < _minLength) + return false; + if (password.Length > _maxLength) + return false; + + return true; + } + } +} \ No newline at end of file diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index aecb83070..dae99cf1c 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -223,8 +223,10 @@ + +