fix: tighten MxGateway Ldap:Port to 1-65535; catch IOException in path validation
Defect 1: ValidateLdap used AddIfNotPositive for Port, accepting any value
> 0 including 70000. Replaced with builder.Port() from the shared
ZB.MOM.WW.Configuration library, which enforces the 1-65535 TCP range and
emits "MxGateway:Ldap:Port must be between 1 and 65535 (was {value})".
Defect 2: AddIfInvalidPath only caught ArgumentException, NotSupportedException,
and PathTooLongException from Path.GetFullPath. On macOS/Linux a path containing
an embedded null throws IOException, which escaped the catch block and caused
Validate() to throw instead of returning a failure. Added catch (IOException).
Tests: added Validate_Fails_WhenLdapPortIsZero, Validate_Fails_WhenLdapPortExceedsMaximum,
and Validate_Succeeds_WhenLdapEnabledWithValidPort to cover the new range boundary.
This commit is contained in:
@@ -80,7 +80,7 @@ public sealed class GatewayOptionsValidator : OptionsValidatorBase<GatewayOption
|
|||||||
options.GroupAttribute,
|
options.GroupAttribute,
|
||||||
"MxGateway:Ldap:GroupAttribute is required when LDAP login is enabled.",
|
"MxGateway:Ldap:GroupAttribute is required when LDAP login is enabled.",
|
||||||
builder);
|
builder);
|
||||||
AddIfNotPositive(options.Port, "MxGateway:Ldap:Port must be greater than zero.", builder);
|
builder.Port(options.Port, "MxGateway:Ldap:Port");
|
||||||
|
|
||||||
if (!options.UseTls && !options.AllowInsecureLdap)
|
if (!options.UseTls && !options.AllowInsecureLdap)
|
||||||
{
|
{
|
||||||
@@ -339,5 +339,9 @@ public sealed class GatewayOptionsValidator : OptionsValidatorBase<GatewayOption
|
|||||||
{
|
{
|
||||||
builder.Add(message);
|
builder.Add(message);
|
||||||
}
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
builder.Add(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,29 @@ public sealed class GatewayOptionsValidatorTests
|
|||||||
// design-default values; those defaults are validated separately in GatewayOptionsTests.
|
// design-default values; those defaults are validated separately in GatewayOptionsTests.
|
||||||
private static GatewayOptions ValidOptions() => new();
|
private static GatewayOptions ValidOptions() => new();
|
||||||
|
|
||||||
|
// Returns enabled LDAP options that pass all checks except Port.
|
||||||
|
// The class defaults already satisfy the blank-field checks; we only
|
||||||
|
// override Enabled (must be true to exercise the port check) and Port.
|
||||||
|
private static LdapOptions LdapOptionsWithPort(int port) => new()
|
||||||
|
{
|
||||||
|
Enabled = true,
|
||||||
|
Port = port,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static GatewayOptions CloneWithLdap(GatewayOptions source, LdapOptions ldap)
|
||||||
|
=> new()
|
||||||
|
{
|
||||||
|
Authentication = source.Authentication,
|
||||||
|
Ldap = ldap,
|
||||||
|
Worker = source.Worker,
|
||||||
|
Sessions = source.Sessions,
|
||||||
|
Events = source.Events,
|
||||||
|
Dashboard = source.Dashboard,
|
||||||
|
Protocol = source.Protocol,
|
||||||
|
Alarms = source.Alarms,
|
||||||
|
Tls = source.Tls,
|
||||||
|
};
|
||||||
|
|
||||||
private static GatewayOptions CloneWithTls(GatewayOptions source, TlsOptions tls)
|
private static GatewayOptions CloneWithTls(GatewayOptions source, TlsOptions tls)
|
||||||
=> new()
|
=> new()
|
||||||
{
|
{
|
||||||
@@ -65,4 +88,34 @@ public sealed class GatewayOptionsValidatorTests
|
|||||||
Assert.True(result.Failed);
|
Assert.True(result.Failed);
|
||||||
Assert.Contains(result.Failures!, f => f.Contains("MxGateway:Tls:SelfSignedCertPath must not be blank."));
|
Assert.Contains(result.Failures!, f => f.Contains("MxGateway:Tls:SelfSignedCertPath must not be blank."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Validate_Fails_WhenLdapPortIsZero()
|
||||||
|
{
|
||||||
|
GatewayOptions options = CloneWithLdap(ValidOptions(), LdapOptionsWithPort(0));
|
||||||
|
ValidateOptionsResult result = new GatewayOptionsValidator().Validate(null, options);
|
||||||
|
Assert.True(result.Failed);
|
||||||
|
Assert.Contains(
|
||||||
|
result.Failures!,
|
||||||
|
f => f.Contains("MxGateway:Ldap:Port must be between 1 and 65535 (was 0)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Validate_Fails_WhenLdapPortExceedsMaximum()
|
||||||
|
{
|
||||||
|
GatewayOptions options = CloneWithLdap(ValidOptions(), LdapOptionsWithPort(70000));
|
||||||
|
ValidateOptionsResult result = new GatewayOptionsValidator().Validate(null, options);
|
||||||
|
Assert.True(result.Failed);
|
||||||
|
Assert.Contains(
|
||||||
|
result.Failures!,
|
||||||
|
f => f.Contains("MxGateway:Ldap:Port must be between 1 and 65535 (was 70000)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Validate_Succeeds_WhenLdapEnabledWithValidPort()
|
||||||
|
{
|
||||||
|
GatewayOptions options = CloneWithLdap(ValidOptions(), LdapOptionsWithPort(389));
|
||||||
|
ValidateOptionsResult result = new GatewayOptionsValidator().Validate(null, options);
|
||||||
|
Assert.True(result.Succeeded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user