-
-
Notifications
You must be signed in to change notification settings - Fork 834
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Swallow SMTP RSET exceptions. These obscure other Send/SendAsync exce…
…ptions. Partial fix for issue #1748
- Loading branch information
Showing
4 changed files
with
248 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3865,6 +3865,234 @@ public async Task TestMailFromMailboxUnavailableAsync () | |
} | ||
} | ||
|
||
static List<SmtpReplayCommand> CreateMailFromAuthRequiredRsetDisconnectCommands () | ||
{ | ||
return new List<SmtpReplayCommand> { | ||
new SmtpReplayCommand ("", "comcast-greeting.txt"), | ||
new SmtpReplayCommand ($"EHLO {SmtpClient.DefaultLocalDomain}\r\n", "comcast-ehlo.txt"), | ||
new SmtpReplayCommand ("AUTH PLAIN AHVzZXJuYW1lAHBhc3N3b3Jk\r\n", "comcast-auth-plain.txt"), | ||
new SmtpReplayCommand ("MAIL FROM:<[email protected]>\r\n", "auth-required.txt", SmtpReplayState.UnexpectedDisconnect), | ||
new SmtpReplayCommand ("RSET\r\n", string.Empty) | ||
}; | ||
} | ||
|
||
[Test] | ||
public void TestMailFromAuthRequiredRsetDisconnect () | ||
{ | ||
var commands = CreateMailFromAuthRequiredRsetDisconnectCommands (); | ||
|
||
using (var client = new SmtpClient ()) { | ||
try { | ||
client.Connect (new SmtpReplayStream (commands, false), "localhost", 25, SecureSocketOptions.None); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Connect: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.True, "Client failed to connect."); | ||
|
||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.Authentication), Is.True, "Failed to detect AUTH extension"); | ||
Assert.That (client.AuthenticationMechanisms, Does.Contain ("LOGIN"), "Failed to detect the LOGIN auth mechanism"); | ||
Assert.That (client.AuthenticationMechanisms, Does.Contain ("PLAIN"), "Failed to detect the PLAIN auth mechanism"); | ||
|
||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.EightBitMime), Is.True, "Failed to detect 8BITMIME extension"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.EnhancedStatusCodes), Is.True, "Failed to detect ENHANCEDSTATUSCODES extension"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.Size), Is.True, "Failed to detect SIZE extension"); | ||
Assert.That (client.MaxSize, Is.EqualTo (36700160), "Failed to parse SIZE correctly"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.StartTLS), Is.True, "Failed to detect STARTTLS extension"); | ||
|
||
try { | ||
client.Authenticate ("username", "password"); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Authenticate: {ex}"); | ||
} | ||
|
||
try { | ||
using (var message = CreateSimpleMessage ()) | ||
client.Send (message); | ||
Assert.Fail ("Expected an ServiceNotAuthenticatedException"); | ||
} catch (ServiceNotAuthenticatedException) { | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect this exception in Send: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.False, "Expected the client to be disconnected"); | ||
|
||
try { | ||
client.Disconnect (true); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Disconnect: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.False, "Failed to disconnect"); | ||
} | ||
} | ||
|
||
[Test] | ||
public async Task TestMailFromAuthRequiredRsetDisconnectAsync () | ||
{ | ||
var commands = CreateMailFromAuthRequiredRsetDisconnectCommands (); | ||
|
||
using (var client = new SmtpClient ()) { | ||
try { | ||
await client.ConnectAsync (new SmtpReplayStream (commands, true), "localhost", 25, SecureSocketOptions.None); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Connect: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.True, "Client failed to connect."); | ||
|
||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.Authentication), Is.True, "Failed to detect AUTH extension"); | ||
Assert.That (client.AuthenticationMechanisms, Does.Contain ("LOGIN"), "Failed to detect the LOGIN auth mechanism"); | ||
Assert.That (client.AuthenticationMechanisms, Does.Contain ("PLAIN"), "Failed to detect the PLAIN auth mechanism"); | ||
|
||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.EightBitMime), Is.True, "Failed to detect 8BITMIME extension"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.EnhancedStatusCodes), Is.True, "Failed to detect ENHANCEDSTATUSCODES extension"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.Size), Is.True, "Failed to detect SIZE extension"); | ||
Assert.That (client.MaxSize, Is.EqualTo (36700160), "Failed to parse SIZE correctly"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.StartTLS), Is.True, "Failed to detect STARTTLS extension"); | ||
|
||
try { | ||
await client.AuthenticateAsync ("username", "password"); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Authenticate: {ex}"); | ||
} | ||
|
||
try { | ||
using (var message = CreateSimpleMessage ()) | ||
await client.SendAsync (message); | ||
Assert.Fail ("Expected an ServiceNotAuthenticatedException"); | ||
} catch (ServiceNotAuthenticatedException) { | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect this exception in Send: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.False, "Expected the client to be disconnected"); | ||
|
||
try { | ||
await client.DisconnectAsync (true); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Disconnect: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.False, "Failed to disconnect"); | ||
} | ||
} | ||
|
||
static List<SmtpReplayCommand> CreateMailFromUnavailableRsetDisconnectCommands () | ||
{ | ||
return new List<SmtpReplayCommand> { | ||
new SmtpReplayCommand ("", "comcast-greeting.txt"), | ||
new SmtpReplayCommand ($"EHLO {SmtpClient.DefaultLocalDomain}\r\n", "comcast-ehlo.txt"), | ||
new SmtpReplayCommand ("AUTH PLAIN AHVzZXJuYW1lAHBhc3N3b3Jk\r\n", "comcast-auth-plain.txt"), | ||
new SmtpReplayCommand ("MAIL FROM:<[email protected]>\r\n", "mailbox-unavailable.txt", SmtpReplayState.UnexpectedDisconnect), | ||
new SmtpReplayCommand ("RSET\r\n", string.Empty) | ||
}; | ||
} | ||
|
||
[Test] | ||
public void TestMailFromUnavailableRsetDisconnect () | ||
{ | ||
var commands = CreateMailFromUnavailableRsetDisconnectCommands (); | ||
|
||
using (var client = new SmtpClient ()) { | ||
try { | ||
client.Connect (new SmtpReplayStream (commands, false), "localhost", 25, SecureSocketOptions.None); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Connect: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.True, "Client failed to connect."); | ||
|
||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.Authentication), Is.True, "Failed to detect AUTH extension"); | ||
Assert.That (client.AuthenticationMechanisms, Does.Contain ("LOGIN"), "Failed to detect the LOGIN auth mechanism"); | ||
Assert.That (client.AuthenticationMechanisms, Does.Contain ("PLAIN"), "Failed to detect the PLAIN auth mechanism"); | ||
|
||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.EightBitMime), Is.True, "Failed to detect 8BITMIME extension"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.EnhancedStatusCodes), Is.True, "Failed to detect ENHANCEDSTATUSCODES extension"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.Size), Is.True, "Failed to detect SIZE extension"); | ||
Assert.That (client.MaxSize, Is.EqualTo (36700160), "Failed to parse SIZE correctly"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.StartTLS), Is.True, "Failed to detect STARTTLS extension"); | ||
|
||
try { | ||
client.Authenticate ("username", "password"); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Authenticate: {ex}"); | ||
} | ||
|
||
try { | ||
using (var message = CreateSimpleMessage ()) | ||
client.Send (message); | ||
Assert.Fail ("Expected an SmtpCommandException"); | ||
} catch (SmtpCommandException sex) { | ||
Assert.That (sex.ErrorCode, Is.EqualTo (SmtpErrorCode.SenderNotAccepted), "Unexpected SmtpErrorCode"); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect this exception in Send: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.False, "Expected the client to be disconnected"); | ||
|
||
try { | ||
client.Disconnect (true); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Disconnect: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.False, "Failed to disconnect"); | ||
} | ||
} | ||
|
||
[Test] | ||
public async Task TestMailFromUnavailableRsetDisconnectAsync () | ||
{ | ||
var commands = CreateMailFromUnavailableRsetDisconnectCommands (); | ||
|
||
using (var client = new SmtpClient ()) { | ||
try { | ||
await client.ConnectAsync (new SmtpReplayStream (commands, true), "localhost", 25, SecureSocketOptions.None); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Connect: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.True, "Client failed to connect."); | ||
|
||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.Authentication), Is.True, "Failed to detect AUTH extension"); | ||
Assert.That (client.AuthenticationMechanisms, Does.Contain ("LOGIN"), "Failed to detect the LOGIN auth mechanism"); | ||
Assert.That (client.AuthenticationMechanisms, Does.Contain ("PLAIN"), "Failed to detect the PLAIN auth mechanism"); | ||
|
||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.EightBitMime), Is.True, "Failed to detect 8BITMIME extension"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.EnhancedStatusCodes), Is.True, "Failed to detect ENHANCEDSTATUSCODES extension"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.Size), Is.True, "Failed to detect SIZE extension"); | ||
Assert.That (client.MaxSize, Is.EqualTo (36700160), "Failed to parse SIZE correctly"); | ||
Assert.That (client.Capabilities.HasFlag (SmtpCapabilities.StartTLS), Is.True, "Failed to detect STARTTLS extension"); | ||
|
||
try { | ||
await client.AuthenticateAsync ("username", "password"); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Authenticate: {ex}"); | ||
} | ||
|
||
try { | ||
using (var message = CreateSimpleMessage ()) | ||
await client.SendAsync (message); | ||
Assert.Fail ("Expected an SmtpCommandException"); | ||
} catch (SmtpCommandException sex) { | ||
Assert.That (sex.ErrorCode, Is.EqualTo (SmtpErrorCode.SenderNotAccepted), "Unexpected SmtpErrorCode"); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect this exception in Send: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.False, "Expected the client to be disconnected"); | ||
|
||
try { | ||
await client.DisconnectAsync (true); | ||
} catch (Exception ex) { | ||
Assert.Fail ($"Did not expect an exception in Disconnect: {ex}"); | ||
} | ||
|
||
Assert.That (client.IsConnected, Is.False, "Failed to disconnect"); | ||
} | ||
} | ||
|
||
static List<SmtpReplayCommand> CreateRcptToMailboxUnavailableCommands () | ||
{ | ||
return new List<SmtpReplayCommand> { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters