From 81f34d4afa076002ceaae0a88c27f21125256552 Mon Sep 17 00:00:00 2001 From: cosullivan Date: Thu, 28 May 2020 23:29:25 +0800 Subject: [PATCH] minor cleanup --- Src/SmtpServer.Tests/SmtpParserTests.cs | 102 ++++++++---------- Src/SmtpServer/ISessionContext.cs | 1 - ...roxyProtocolCommand.cs => ProxyCommand.cs} | 19 ++-- Src/SmtpServer/Protocol/SmtpCommandVisitor.cs | 7 +- Src/SmtpServer/Protocol/SmtpParser.cs | 4 +- Src/SmtpServer/Protocol/SmtpStateMachine.cs | 6 +- Src/SmtpServer/SmtpServer.csproj | 8 +- .../Tracing/TracingSmtpCommandVisitor.cs | 2 +- 8 files changed, 64 insertions(+), 85 deletions(-) rename Src/SmtpServer/Protocol/{ProxyProtocolCommand.cs => ProxyCommand.cs} (76%) diff --git a/Src/SmtpServer.Tests/SmtpParserTests.cs b/Src/SmtpServer.Tests/SmtpParserTests.cs index bbcbed7..2d0a3ac 100644 --- a/Src/SmtpServer.Tests/SmtpParserTests.cs +++ b/Src/SmtpServer.Tests/SmtpParserTests.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.Net; using System.Text; -using SmtpServer.Mail; using SmtpServer.Protocol; using SmtpServer.Text; using Xunit; @@ -41,7 +39,7 @@ public void CanMakeNoop() var parser = CreateParser("NOOP"); // act - var result = parser.TryMakeNoop(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeNoop(out var command, out var errorResponse); // assert Assert.True(result); @@ -55,7 +53,7 @@ public void CanMakeHelo() var parser = CreateParser("HELO abc-1-def.mail.com"); // act - var result = parser.TryMakeHelo(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeHelo(out var command, out var errorResponse); // assert Assert.True(result); @@ -73,7 +71,7 @@ public void CanNotMakeHelo(string input) var parser = CreateParser(input); // act - var result = parser.TryMakeHelo(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeHelo(out var command, out var errorResponse); // assert Assert.False(result); @@ -92,7 +90,7 @@ public void CanMakeEhlo(string input) var parser = CreateParser(input); // act - var result = parser.TryMakeEhlo(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeEhlo(out var command, out var errorResponse); var ipOrDomainPart = input.Substring(5); @@ -121,7 +119,7 @@ public void CanMakeAuthPlain() var parser = CreateParser("AUTH PLAIN Y2Fpbi5vc3VsbGl2YW5AZ21haWwuY29t"); // act - var result = parser.TryMakeAuth(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeAuth(out var command, out var errorResponse); // assert Assert.True(result); @@ -137,7 +135,7 @@ public void CanMakeAuthLogin() var parser = CreateParser("AUTH LOGIN Y2Fpbi5vc3VsbGl2YW5AZ21haWwuY29t"); // act - var result = parser.TryMakeAuth(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeAuth(out var command, out var errorResponse); // assert Assert.True(result); @@ -163,7 +161,7 @@ public void CanMakeMail(string email, string user, string host, string extension var parser = CreateParser(mailTo); // act - var result = parser.TryMakeMail(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeMail(out var command, out var errorResponse); // assert Assert.True(result); @@ -185,7 +183,7 @@ public void CanMakeMailWithNoAddress() var parser = CreateParser("MAIL FROM:<>"); // act - var result = parser.TryMakeMail(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeMail(out var command, out var errorResponse); // assert Assert.True(result); @@ -202,7 +200,7 @@ public void CanMakeMailWithBlankAddress() var parser = CreateParser("MAIL FROM:< >"); // act - var result = parser.TryMakeMail(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeMail(out var command, out var errorResponse); // assert Assert.True(result); @@ -220,7 +218,7 @@ public void CanNotMakeMail(string input) var parser = CreateParser(input); // act - var result = parser.TryMakeMail(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeMail(out var command, out var errorResponse); // assert Assert.False(result); @@ -237,7 +235,7 @@ public void CanMakeRcpt(string email, string user, string host) var parser = CreateParser($"RCPT TO:<{email}>"); // act - var result = parser.TryMakeRcpt(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeRcpt(out var command, out var errorResponse); // assert Assert.True(result); @@ -253,15 +251,15 @@ public void CanMakeProxyIpV4() var parser = CreateParser("PROXY TCP4 192.168.1.1 192.168.1.2 1234 16789"); // act - var result = parser.TryMakeProxy(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeProxy(out var command, out var errorResponse); // assert Assert.True(result); - Assert.True(command is ProxyProtocolCommand); - Assert.Equal("192.168.1.1", ((ProxyProtocolCommand)command).SourceEndpoint.Address.ToString()); - Assert.Equal("192.168.1.2", ((ProxyProtocolCommand)command).DestinationEndpoint.Address.ToString()); - Assert.Equal(1234, ((ProxyProtocolCommand)command).SourceEndpoint.Port); - Assert.Equal(16789, ((ProxyProtocolCommand)command).DestinationEndpoint.Port); + Assert.True(command is ProxyCommand); + Assert.Equal("192.168.1.1", ((ProxyCommand)command).SourceEndpoint.Address.ToString()); + Assert.Equal("192.168.1.2", ((ProxyCommand)command).DestinationEndpoint.Address.ToString()); + Assert.Equal(1234, ((ProxyCommand)command).SourceEndpoint.Port); + Assert.Equal(16789, ((ProxyCommand)command).DestinationEndpoint.Port); } [Fact] @@ -271,15 +269,15 @@ public void CanMakeProxyIpV6() var parser = CreateParser("PROXY TCP6 2001:1234:abcd::0001 3456:2e76:66d8:f84:abcd:abef:ffff:1234 1234 16789"); // act - var result = parser.TryMakeProxy(out SmtpCommand command, out SmtpResponse errorResponse); + var result = parser.TryMakeProxy(out var command, out var errorResponse); // assert Assert.True(result); - Assert.True(command is ProxyProtocolCommand); - Assert.Equal(IPAddress.Parse("2001:1234:abcd::0001").ToString(), ((ProxyProtocolCommand)command).SourceEndpoint.Address.ToString()); - Assert.Equal(IPAddress.Parse("3456:2e76:66d8:f84:abcd:abef:ffff:1234").ToString(), ((ProxyProtocolCommand)command).DestinationEndpoint.Address.ToString()); - Assert.Equal(1234, ((ProxyProtocolCommand)command).SourceEndpoint.Port); - Assert.Equal(16789, ((ProxyProtocolCommand)command).DestinationEndpoint.Port); + Assert.True(command is ProxyCommand); + Assert.Equal(IPAddress.Parse("2001:1234:abcd::0001").ToString(), ((ProxyCommand)command).SourceEndpoint.Address.ToString()); + Assert.Equal(IPAddress.Parse("3456:2e76:66d8:f84:abcd:abef:ffff:1234").ToString(), ((ProxyCommand)command).DestinationEndpoint.Address.ToString()); + Assert.Equal(1234, ((ProxyCommand)command).SourceEndpoint.Port); + Assert.Equal(16789, ((ProxyCommand)command).DestinationEndpoint.Port); } [Fact] @@ -287,10 +285,9 @@ public void CanMakeAtom() { // arrange var parser = CreateParser("hello"); - string atom; // act - var made = parser.TryMakeAtom(out atom); + var made = parser.TryMakeAtom(out var atom); // assert Assert.True(made); @@ -302,10 +299,9 @@ public void CanMakeDotString() { // arrange var parser = CreateParser("abc.def.hij"); - string dotString; // act - var made = parser.TryMakeDotString(out dotString); + var made = parser.TryMakeDotString(out var dotString); // assert Assert.True(made); @@ -317,10 +313,9 @@ public void CanMakeLocalPart() { // arrange var parser = CreateParser("abc"); - string localPart; // act - var made = parser.TryMakeLocalPart(out localPart); + var made = parser.TryMakeLocalPart(out var localPart); // assert Assert.True(made); @@ -331,12 +326,10 @@ public void CanMakeLocalPart() public void CanMakeTextOrNumber() { // arrange - string textOrNumber1; - string textOrNumber2; // act - var made1 = CreateParser("abc").TryMakeTextOrNumber(out textOrNumber1); - var made2 = CreateParser("123").TryMakeTextOrNumber(out textOrNumber2); + var made1 = CreateParser("abc").TryMakeTextOrNumber(out var textOrNumber1); + var made2 = CreateParser("123").TryMakeTextOrNumber(out var textOrNumber2); // assert Assert.True(made1); @@ -350,10 +343,9 @@ public void CanMakeTextOrNumberOrHyphenString() { // arrange var parser = CreateParser("a1-b2"); - string textOrNumberOrHyphen1; // act - var made1 = parser.TryMakeTextOrNumberOrHyphenString(out textOrNumberOrHyphen1); + var made1 = parser.TryMakeTextOrNumberOrHyphenString(out var textOrNumberOrHyphen1); // assert Assert.True(made1); @@ -365,10 +357,9 @@ public void CanMakeSubdomain() { // arrange var parser = CreateParser("a-1-b-2"); - string subdomain; // act - var made = parser.TryMakeSubdomain(out subdomain); + var made = parser.TryMakeSubdomain(out var subdomain); // assert Assert.True(made); @@ -380,10 +371,9 @@ public void CanMakeDomain() { // arrange var parser = CreateParser("123.abc.com"); - string domain; // act - var made = parser.TryMakeDomain(out domain); + var made = parser.TryMakeDomain(out var domain); // assert Assert.True(made); @@ -404,10 +394,9 @@ public void CanMakeMailbox(string email, string user, string host) { // arrange var parser = CreateParser(email); - IMailbox mailbox; // act - var made = parser.TryMakeMailbox(out mailbox); + var made = parser.TryMakeMailbox(out var mailbox); // assert Assert.True(made); @@ -420,10 +409,9 @@ public void CanMakePlusAddressMailBox() { // arrange var parser = CreateParser("cain.osullivan+plus@gmail.com"); - IMailbox mailbox; // act - var made = parser.TryMakeMailbox(out mailbox); + var made = parser.TryMakeMailbox(out var mailbox); // assert Assert.True(made); @@ -436,10 +424,9 @@ public void CanMakeAtDomain() { // arrange var parser = CreateParser("@gmail.com"); - string atDomain; // act - var made = parser.TryMakeAtDomain(out atDomain); + var made = parser.TryMakeAtDomain(out var atDomain); // assert Assert.True(made); @@ -451,10 +438,9 @@ public void CanMakeAtDomainList() { // arrange var parser = CreateParser("@gmail.com,@hotmail.com"); - string atDomainList; // act - var made = parser.TryMakeAtDomainList(out atDomainList); + var made = parser.TryMakeAtDomainList(out var atDomainList); // assert Assert.True(made); @@ -466,10 +452,9 @@ public void CanMakePath() { // path var parser = CreateParser("<@gmail.com,@hotmail.com:cain.osullivan@gmail.com>"); - IMailbox mailbox; // act - var made = parser.TryMakePath(out mailbox); + var made = parser.TryMakePath(out var mailbox); // assert Assert.True(made); @@ -482,10 +467,9 @@ public void CanMakeReversePath() { // path var parser = CreateParser("<@gmail.com,@hotmail.com:cain.osullivan@gmail.com>"); - IMailbox mailbox; // act - var made = parser.TryMakePath(out mailbox); + var made = parser.TryMakePath(out var mailbox); // assert Assert.True(made); @@ -498,10 +482,9 @@ public void CanMakeAddressLiteral() { // arrange var parser = CreateParser("[ 127.0.0.1 ]"); - string address; // act - var made = parser.TryMakeAddressLiteral(out address); + var made = parser.TryMakeAddressLiteral(out var address); // assert Assert.True(made); @@ -513,20 +496,19 @@ public void CanMakeMailParameters() { // arrange var parser = CreateParser("SIZE=123 ABC=DEF ABCDE ZZZ=123"); - IReadOnlyDictionary parameters; // act - var made = parser.TryMakeMailParameters(out parameters); + var made = parser.TryMakeMailParameters(out var parameters); // assert Assert.True(made); Assert.Equal(4, parameters.Count); Assert.True(parameters.ContainsKey("SIZE")); - Assert.Equal(parameters["SIZE"], "123"); + Assert.Equal("123", parameters["SIZE"]); Assert.True(parameters.ContainsKey("ABC")); - Assert.Equal(parameters["ABC"], "DEF"); + Assert.Equal("DEF", parameters["ABC"]); Assert.True(parameters.ContainsKey("ZZZ")); - Assert.Equal(parameters["ZZZ"], "123"); + Assert.Equal("123", parameters["ZZZ"]); Assert.True(parameters.ContainsKey("ABCDE")); } diff --git a/Src/SmtpServer/ISessionContext.cs b/Src/SmtpServer/ISessionContext.cs index 0aa5738..9e483e9 100644 --- a/Src/SmtpServer/ISessionContext.cs +++ b/Src/SmtpServer/ISessionContext.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Net; using SmtpServer.IO; namespace SmtpServer diff --git a/Src/SmtpServer/Protocol/ProxyProtocolCommand.cs b/Src/SmtpServer/Protocol/ProxyCommand.cs similarity index 76% rename from Src/SmtpServer/Protocol/ProxyProtocolCommand.cs rename to Src/SmtpServer/Protocol/ProxyCommand.cs index 7b86658..1594c54 100644 --- a/Src/SmtpServer/Protocol/ProxyProtocolCommand.cs +++ b/Src/SmtpServer/Protocol/ProxyCommand.cs @@ -1,5 +1,4 @@ -using System; -using System.Net; +using System.Net; using System.Threading; using System.Threading.Tasks; @@ -10,22 +9,20 @@ namespace SmtpServer.Protocol /// Documented at http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt /// This should always (and only ever) be the first command seen on a new connection from HAProxy /// - public sealed class ProxyProtocolCommand : SmtpCommand + public sealed class ProxyCommand : SmtpCommand { - public const string ProxySourceEndpointKey = "ProxyProtocol:ProxySourceEndpoint"; - public const string ProxyDestinationEndpointKey = "ProxyProtocol:ProxyDestinationEndpoint"; + public const string ProxySourceEndpointKey = "Proxy:ProxySourceEndpoint"; + public const string ProxyDestinationEndpointKey = "Proxy:ProxyDestinationEndpoint"; public const string Command = "PROXY"; - public IPEndPoint SourceEndpoint { get; } - public IPEndPoint DestinationEndpoint { get; } - - public ProxyProtocolCommand(ISmtpServerOptions options, IPEndPoint sourceEndpoint, IPEndPoint destinationEndpoint) : base(options) + public ProxyCommand(ISmtpServerOptions options, IPEndPoint sourceEndpoint, IPEndPoint destinationEndpoint) : base(options) { SourceEndpoint = sourceEndpoint; DestinationEndpoint = destinationEndpoint; } + /// internal override Task ExecuteAsync(SmtpSessionContext context, CancellationToken cancellationToken) { context.Properties.Add(ProxySourceEndpointKey, SourceEndpoint); @@ -34,5 +31,9 @@ internal override Task ExecuteAsync(SmtpSessionContext context, Cancellati // Do not transition smtp protocol state for these commands. return Task.FromResult(false); } + + public IPEndPoint SourceEndpoint { get; } + + public IPEndPoint DestinationEndpoint { get; } } } \ No newline at end of file diff --git a/Src/SmtpServer/Protocol/SmtpCommandVisitor.cs b/Src/SmtpServer/Protocol/SmtpCommandVisitor.cs index 845e8cc..8fc0173 100644 --- a/Src/SmtpServer/Protocol/SmtpCommandVisitor.cs +++ b/Src/SmtpServer/Protocol/SmtpCommandVisitor.cs @@ -46,9 +46,9 @@ public void Visit(SmtpCommand command) return; } - if (command is ProxyProtocolCommand) + if (command is ProxyCommand) { - Visit((ProxyProtocolCommand)command); + Visit((ProxyCommand)command); return; } @@ -119,8 +119,7 @@ protected virtual void Visit(NoopCommand command) { } /// Visit an PROXY command. /// /// The command that is being visited. - protected virtual void Visit(ProxyProtocolCommand command) { } - + protected virtual void Visit(ProxyCommand command) { } /// /// Visit an QUIT command. diff --git a/Src/SmtpServer/Protocol/SmtpParser.cs b/Src/SmtpServer/Protocol/SmtpParser.cs index da70d6b..682308a 100644 --- a/Src/SmtpServer/Protocol/SmtpParser.cs +++ b/Src/SmtpServer/Protocol/SmtpParser.cs @@ -298,7 +298,7 @@ public bool TryMakeProxy(out SmtpCommand command, out SmtpResponse errorResponse if (inetProto == "UNKNOWN") { // IF INET PROTO IS UNKNOWN REST OF THIS LINE SHOULD BE IGNORED. - command = new ProxyProtocolCommand(_options, null, null); + command = new ProxyCommand(_options, null, null); return true; } @@ -344,7 +344,7 @@ public bool TryMakeProxy(out SmtpCommand command, out SmtpResponse errorResponse return false; } - command = new ProxyProtocolCommand(_options, new IPEndPoint(sourceIp, sourcePort), + command = new ProxyCommand(_options, new IPEndPoint(sourceIp, sourcePort), new IPEndPoint(destinationIp, destinationPort)); return true; } diff --git a/Src/SmtpServer/Protocol/SmtpStateMachine.cs b/Src/SmtpServer/Protocol/SmtpStateMachine.cs index 9cbc5f2..3239872 100644 --- a/Src/SmtpServer/Protocol/SmtpStateMachine.cs +++ b/Src/SmtpServer/Protocol/SmtpStateMachine.cs @@ -27,7 +27,7 @@ internal SmtpStateMachine(SmtpSessionContext context) { NoopCommand.Command, TryMakeNoop }, { RsetCommand.Command, TryMakeRset }, { QuitCommand.Command, TryMakeQuit }, - { ProxyProtocolCommand.Command, TryMakeProxy }, + { ProxyCommand.Command, TryMakeProxy }, { HeloCommand.Command, TryMakeHelo, c => c.NetworkClient.Stream.IsSecure ? SmtpState.WaitingForMailSecure : SmtpState.WaitingForMail }, { EhloCommand.Command, TryMakeEhlo, c => c.NetworkClient.Stream.IsSecure ? SmtpState.WaitingForMailSecure : SmtpState.WaitingForMail }, }, @@ -85,7 +85,6 @@ internal SmtpStateMachine(SmtpSessionContext context) _stateTable.Initialize(SmtpState.Initialized); } - /// /// Called when the session has been authenticated. @@ -259,7 +258,7 @@ bool TryMakeRcpt(TokenEnumerator tokenEnumerator, out SmtpCommand command, out S /// The command that was found. /// The error response that was returned if a command could not be matched. /// true if a PROXY command was found, false if not. - private bool TryMakeProxy(TokenEnumerator tokenEnumerator, out SmtpCommand command, out SmtpResponse errorResponse) + bool TryMakeProxy(TokenEnumerator tokenEnumerator, out SmtpCommand command, out SmtpResponse errorResponse) { return new SmtpParser(_context.ServerOptions, tokenEnumerator).TryMakeProxy(out command, out errorResponse); } @@ -487,5 +486,4 @@ public StateTransition(TryMakeDelegate @delegate, Func7.2 SmtpServer SmtpServer - 7.0.0 + 7.1.0 .NET SmtpServer Cain O'Sullivan @@ -15,9 +15,9 @@ smtp smtpserver smtp server True - 7.0.0.0 - 7.0.0.0 - Modified the INetworkClient to abstract the INetworkStream for better composition. + 7.1.0.0 + 7.1.0.0 + Added support for the PROXY command. true LICENSE diff --git a/Src/SmtpServer/Tracing/TracingSmtpCommandVisitor.cs b/Src/SmtpServer/Tracing/TracingSmtpCommandVisitor.cs index b1e0811..da3d863 100644 --- a/Src/SmtpServer/Tracing/TracingSmtpCommandVisitor.cs +++ b/Src/SmtpServer/Tracing/TracingSmtpCommandVisitor.cs @@ -84,7 +84,7 @@ protected override void Visit(NoopCommand command) /// Visit an PROXY command. /// /// The command that is being visited. - protected override void Visit(ProxyProtocolCommand command) + protected override void Visit(ProxyCommand command) { _output.WriteLine($"PROXY {command.SourceEndpoint} --> {command.DestinationEndpoint}"); }