Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added AllowClientSslRenegotiation property on .NET STANDARD 2.1 #191

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Src/SmtpServer/EndpointDefinitionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ public EndpointDefinitionBuilder AllowUnsecureAuthentication(bool value = true)
return this;
}

#if NETSTANDARD2_1_OR_GREATER
/// <summary>
/// Sets a value indicating wheter client ssl renegotiation should be allowed, this is not recommended
/// since it might allow for the following vulnerability https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3555
/// .NET 7.0 has made renagotiation false by default https://learn.microsoft.com/en-us/dotnet/core/compatibility/networking/7.0/allowrenegotiation-default
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public EndpointDefinitionBuilder AllowClientSslRenegotiation(bool value = true)
{
_setters.Add(options => options.AllowClientSslRenegotiation = value);
return this;
}
#endif

/// <summary>
/// Sets the read timeout to apply to stream operations.
/// </summary>
Expand Down Expand Up @@ -154,6 +169,7 @@ internal sealed class EndpointDefinition : IEndpointDefinition
/// </summary>
public bool AuthenticationRequired { get; set; }


/// <summary>
/// Gets a value indicating whether authentication should be allowed on an unsecure session.
/// </summary>
Expand All @@ -173,6 +189,13 @@ internal sealed class EndpointDefinition : IEndpointDefinition
/// The supported SSL protocols.
/// </summary>
public SslProtocols SupportedSslProtocols { get; set; }

#if NETSTANDARD2_1_OR_GREATER
/// <summary>
/// Gets a value indicating if during an SSL connection a client ssl renegotiation is allowed
/// </summary>
public bool AllowClientSslRenegotiation { get; set; }
#endif
}

#endregion
Expand Down
8 changes: 8 additions & 0 deletions Src/SmtpServer/IEndpointDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ public interface IEndpointDefinition
/// </summary>
bool AllowUnsecureAuthentication { get; }


#if NETSTANDARD2_1_OR_GREATER
/// <summary>
/// Gets a value indicating if during an SSL connection a client ssl renegotiation is allowed
/// </summary>
bool AllowClientSslRenegotiation { get; }
#endif

/// <summary>
/// The timeout on each individual buffer read.
/// </summary>
Expand Down
16 changes: 15 additions & 1 deletion Src/SmtpServer/IO/SecurableDuplexPipe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ internal SecurableDuplexPipe(Stream stream, Action disposeAction)
Output = PipeWriter.Create(_stream);
}

#if NETSTANDARD2_1_OR_GREATER
public bool AllowRenegotiation { get; set; } = false;
#endif

/// <summary>
/// Upgrade to a secure pipeline.
/// </summary>
Expand All @@ -40,8 +44,18 @@ public async Task UpgradeAsync(X509Certificate certificate, SslProtocols protoco
{
var stream = new SslStream(_stream, true);

#if NETSTANDARD2_1_OR_GREATER
await stream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions
{
AllowRenegotiation = AllowRenegotiation,
ServerCertificate = certificate,
CertificateRevocationCheckMode = X509RevocationMode.Online,
ClientCertificateRequired = false,
EnabledSslProtocols = protocols,
}, cancellationToken);
#else
await stream.AuthenticateAsServerAsync(certificate, false, protocols, true).ConfigureAwait(false);

#endif
_stream = stream;

Input = PipeReader.Create(_stream);
Expand Down
13 changes: 12 additions & 1 deletion Src/SmtpServer/Net/EndpointListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ internal EndpointListener(IEndpointDefinition endpointDefinition, TcpListener tc
_disposeAction = disposeAction;
}

/// <summary>
/// During ssl connections allows the client to drop the connection and reconnect while renegotiation for a different TLS version
/// .NET 7.0 has set this to false to prevent the following vulnerability https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3555
/// </summary>
public bool AllowSslClientRenegotiation { get; set; } = false;

/// <summary>
/// Returns a securable pipe to the endpoint.
/// </summary>
Expand All @@ -50,7 +56,12 @@ public async Task<ISecurableDuplexPipe> GetPipeAsync(ISessionContext context, Ca
{
tcpClient.Close();
tcpClient.Dispose();
});
})
{
#if NETSTANDARD2_1_OR_GREATER
AllowRenegotiation = AllowSslClientRenegotiation
#endif
};
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Src/SmtpServer/SmtpServer.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<LangVersion>8.0</LangVersion>
<AssemblyName>SmtpServer</AssemblyName>
<RootNamespace>SmtpServer</RootNamespace>
Expand Down