Skip to content

Commit

Permalink
sslproxy improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
CypherPotato committed Sep 5, 2024
1 parent b0c88bd commit 17e4c44
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 8 deletions.
1 change: 0 additions & 1 deletion extensions/Sisk.SslProxy/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ static class Constants
public const int CH_HSEP = 0x3A; // ':'

public const string RESPONSE_PROTOCOL = "HTTP/1.1 ";
public const string XDigestHeaderName = "X-Sisk-Proxy-Digest";
public const string XClientIpHeaderName = "X-Sisk-Proxy-Client-Ip";

public const string Server = "siskproxy/0.1";
Expand Down
11 changes: 10 additions & 1 deletion extensions/Sisk.SslProxy/HttpRequestReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@
// File name: HttpRequestReader.cs
// Repository: https://github.com/sisk-http/core

using Sisk.Core.Http;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Net.Sockets;
using Sisk.Core.Http;

namespace Sisk.Ssl;

static class HttpRequestReader
{
public static bool TryReadHttp1Request(Stream inboundStream,
string? replaceHostName,
TcpClient client,
[NotNullWhen(true)] out string? method,
[NotNullWhen(true)] out string? path,
[NotNullWhen(true)] out string? proto,
Expand Down Expand Up @@ -67,6 +70,12 @@ public static bool TryReadHttp1Request(Stream inboundStream,
{
hValue = replaceHostName;
}
else if (string.Compare(hName, HttpKnownHeaderNames.XForwardedFor, true) == 0)
{
string? remoteAddr = (client.Client.RemoteEndPoint as IPEndPoint)?.Address.ToString();
if (remoteAddr is not null)
hValue = hValue + ", " + remoteAddr;
}

headerList.Add((hName, hValue));
}
Expand Down
12 changes: 9 additions & 3 deletions extensions/Sisk.SslProxy/SslProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using Sisk.Core.Http;

namespace Sisk.Ssl;

Expand All @@ -26,9 +27,10 @@ public sealed class SslProxy : IDisposable
private bool disposedValue;

/// <summary>
/// Gets a unique, static digest string used to verify trusted proxies.
/// Gets or sets the Proxy-Authorization header value for creating an trusted gateway between
/// the application and the proxy.
/// </summary>
public static string ProxyDigest { get; } = Guid.NewGuid().ToString();
public string? ProxyAuthorization { get; set; }

/// <summary>
/// Gets or sets whether keep-alive connections should be used.
Expand Down Expand Up @@ -145,6 +147,7 @@ void ReceiveClientAsync(IAsyncResult ar)
{
if (!HttpRequestReader.TryReadHttp1Request(sslStream,
GatewayHostname,
client,
out var method,
out var path,
out var proto,
Expand All @@ -154,7 +157,10 @@ void ReceiveClientAsync(IAsyncResult ar)
return;
}

headers.Add((Constants.XDigestHeaderName, ProxyDigest.ToString()));
if (ProxyAuthorization is not null)
{
headers.Add((HttpKnownHeaderNames.ProxyAuthorization, ProxyAuthorization.ToString()));
}
headers.Add((Constants.XClientIpHeaderName, ((IPEndPoint)client.Client.LocalEndPoint!).Address.ToString()));

if (!HttpRequestWriter.TryWriteHttpV1Request(clientStream, method, path, headers, reqContentLength))
Expand Down
8 changes: 6 additions & 2 deletions extensions/Sisk.SslProxy/SslProxyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
// File name: SslProxyExtensions.cs
// Repository: https://github.com/sisk-http/core

using Sisk.Core.Http.Hosting;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using Sisk.Core.Http.Hosting;

namespace Sisk.Ssl;

Expand All @@ -27,13 +27,16 @@ public static class SslProxyExtensions
/// <param name="certificate">Optional. The SSL/HTTPS certificate to use for encrypting communications.</param>
/// <param name="allowedProtocols">Optional. The SSL/HTTPS protocols allowed for the connection. Defaults to <see cref="SslProtocols.Tls12"/> and <see cref="SslProtocols.Tls13"/>.</param>
/// <param name="clientCertificateRequired">Optional. Specifies whether a client certificate is required for authentication. Defaults to <c>false</c>.</param>
/// <param name="proxyAuthorization">Optional. Specifies the Proxy-Authorization header value for creating an trusted gateway between
/// the application and the proxy.</param>
/// <returns>The configured <see cref="HttpServerHostContextBuilder"/> instance.</returns>
public static HttpServerHostContextBuilder UseSsl(
this HttpServerHostContextBuilder builder,
short sslListeningPort,
X509Certificate? certificate = null,
SslProtocols allowedProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
bool clientCertificateRequired = false)
bool clientCertificateRequired = false,
object? proxyAuthorization = null)
{
var primaryHost = builder.ServerConfiguration.ListeningHosts[0];
var primaryPort = primaryHost.Ports[0];
Expand All @@ -47,6 +50,7 @@ public static HttpServerHostContextBuilder UseSsl(

var secureProxy = new SslProxy(sslListeningPort, certificate, endpoint);
secureProxy.GatewayHostname = primaryPort.Hostname;
secureProxy.ProxyAuthorization = proxyAuthorization?.ToString();

var serverHandler = new SslProxyServerHandler(secureProxy);
builder.UseHandler(serverHandler);
Expand Down
134 changes: 133 additions & 1 deletion src/.editorconfig
Original file line number Diff line number Diff line change
@@ -1,2 +1,134 @@
[*.cs]
file_header_template = The Sisk Framework source code\nCopyright (c) 2023 PROJECT PRINCIPIUM\n\nThe code below is licensed under the MIT license as\nof the date of its publication, available at\n\nFile name: {fileName}\nRepository: https://github.com/sisk-http/core
file_header_template = The Sisk Framework source code\nCopyright (c) 2023 PROJECT PRINCIPIUM\n\nThe code below is licensed under the MIT license as\nof the date of its publication, available at\n\nFile name: {fileName}\nRepository: https://github.com/sisk-http/core
[*.cs]
#### Estilos de nomenclatura ####

# Regras de nomenclatura

dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i

dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case

# Especificações de símbolo

dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =

dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =

dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =

# Estilos de nomenclatura

dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
csharp_space_around_binary_operators = before_and_after
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_using_directive_placement = outside_namespace:silent
csharp_style_prefer_switch_expression = true:suggestion
csharp_style_prefer_pattern_matching = true:silent
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_prefer_not_pattern = true:suggestion
csharp_style_prefer_extended_property_pattern = true:suggestion
csharp_prefer_static_local_function = true:suggestion
csharp_style_prefer_readonly_struct = true:suggestion
csharp_style_prefer_readonly_struct_member = true:suggestion
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent
csharp_prefer_simple_using_statement = true:suggestion

[*.vb]
#### Estilos de nomenclatura ####

# Regras de nomenclatura

dotnet_naming_rule.interface_should_be_começa_com_i.severity = suggestion
dotnet_naming_rule.interface_should_be_começa_com_i.symbols = interface
dotnet_naming_rule.interface_should_be_começa_com_i.style = começa_com_i

dotnet_naming_rule.tipos_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.tipos_should_be_pascal_case.symbols = tipos
dotnet_naming_rule.tipos_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.membros_sem_campo_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.membros_sem_campo_should_be_pascal_case.symbols = membros_sem_campo
dotnet_naming_rule.membros_sem_campo_should_be_pascal_case.style = pascal_case

# Especificações de símbolo

dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
dotnet_naming_symbols.interface.required_modifiers =

dotnet_naming_symbols.tipos.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.tipos.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
dotnet_naming_symbols.tipos.required_modifiers =

dotnet_naming_symbols.membros_sem_campo.applicable_kinds = property, event, method
dotnet_naming_symbols.membros_sem_campo.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
dotnet_naming_symbols.membros_sem_campo.required_modifiers =

# Estilos de nomenclatura

dotnet_naming_style.começa_com_i.required_prefix = I
dotnet_naming_style.começa_com_i.required_suffix =
dotnet_naming_style.começa_com_i.word_separator =
dotnet_naming_style.começa_com_i.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case

[*.{cs,vb}]
end_of_line = crlf
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_qualification_for_field = true:silent
dotnet_style_qualification_for_property = true:silent
dotnet_style_qualification_for_method = true:silent
dotnet_style_qualification_for_event = true:silent
dotnet_style_readonly_field = true:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent

0 comments on commit 17e4c44

Please sign in to comment.