diff --git a/Wino.Core.Domain/Models/Connectivity/ImapClientPoolOptions.cs b/Wino.Core.Domain/Models/Connectivity/ImapClientPoolOptions.cs new file mode 100644 index 00000000..c53cfffd --- /dev/null +++ b/Wino.Core.Domain/Models/Connectivity/ImapClientPoolOptions.cs @@ -0,0 +1,25 @@ +using System.IO; +using Wino.Core.Domain.Entities; + +namespace Wino.Core.Domain.Models.Connectivity +{ + public class ImapClientPoolOptions + { + public Stream ProtocolLog { get; } + public CustomServerInformation ServerInformation { get; } + public bool IsTestPool { get; } + + protected ImapClientPoolOptions(CustomServerInformation serverInformation, Stream protocolLog, bool isTestPool) + { + ServerInformation = serverInformation; + ProtocolLog = protocolLog; + IsTestPool = isTestPool; + } + + public static ImapClientPoolOptions CreateDefault(CustomServerInformation serverInformation, Stream protocolLog) + => new(serverInformation, protocolLog, false); + + public static ImapClientPoolOptions CreateTestPool(CustomServerInformation serverInformation, Stream protocolLog) + => new(serverInformation, protocolLog, true); + } +} diff --git a/Wino.Core/Integration/ImapClientPool.cs b/Wino.Core/Integration/ImapClientPool.cs index 4d8125ff..bd531566 100644 --- a/Wino.Core/Integration/ImapClientPool.cs +++ b/Wino.Core/Integration/ImapClientPool.cs @@ -17,6 +17,7 @@ using Serilog; using Wino.Core.Domain.Entities; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Exceptions; +using Wino.Core.Domain.Models.Connectivity; namespace Wino.Core.Integration { @@ -46,6 +47,7 @@ namespace Wino.Core.Integration }; public bool ThrowOnSSLHandshakeCallback { get; set; } + public ImapClientPoolOptions ImapClientPoolOptions { get; } private readonly int MinimumPoolSize = 5; @@ -55,15 +57,16 @@ namespace Wino.Core.Integration private readonly Stream _protocolLogStream; private readonly ILogger _logger = Log.ForContext(); - public ImapClientPool(CustomServerInformation customServerInformation, Stream protocolLogStream = null) + public ImapClientPool(ImapClientPoolOptions imapClientPoolOptions) { - _customServerInformation = customServerInformation; - _protocolLogStream = protocolLogStream; + _customServerInformation = imapClientPoolOptions.ServerInformation; + _protocolLogStream = imapClientPoolOptions.ProtocolLog; // Set the maximum pool size to 5 or the custom value if it's greater. - _semaphore = new(Math.Max(MinimumPoolSize, customServerInformation.MaxConcurrentClients)); + _semaphore = new(Math.Max(MinimumPoolSize, _customServerInformation.MaxConcurrentClients)); CryptographyContext.Register(typeof(WindowsSecureMimeContext)); + ImapClientPoolOptions = imapClientPoolOptions; } private async Task EnsureConnectivityAsync(ImapClient client, bool isCreatedNew) @@ -230,6 +233,30 @@ namespace Wino.Core.Integration await client.ConnectAsync(_customServerInformation.IncomingServer, int.Parse(_customServerInformation.IncomingServerPort), GetSocketOptions(_customServerInformation.IncomingServerSocketOption)); + + // Print out useful information for testing. + if (client.IsConnected && ImapClientPoolOptions.IsTestPool) + { + // Print supported authentication methods for the client. + var supportedAuthMethods = client.AuthenticationMechanisms; + + if (supportedAuthMethods == null || supportedAuthMethods.Count == 0) + { + WriteToProtocolLog("There are no supported authentication mechanisms..."); + } + else + { + WriteToProtocolLog($"Supported authentication mechanisms: {string.Join(", ", supportedAuthMethods)}"); + } + } + } + + private void WriteToProtocolLog(string message) + { + if (_protocolLogStream == null) return; + + var messageBytes = Encoding.UTF8.GetBytes($"W: {message}\n"); + _protocolLogStream.Write(messageBytes, 0, messageBytes.Length); } bool MyServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) @@ -261,6 +288,7 @@ namespace Wino.Core.Integration var saslMechanism = GetSASLAuthenticationMethodName(prefferedAuthenticationMethod); client.AuthenticationMechanisms.Add(saslMechanism); + var mechanism = SaslMechanism.Create(saslMechanism, cred); await client.AuthenticateAsync(SaslMechanism.Create(saslMechanism, cred)); } diff --git a/Wino.Core/Services/ImapTestService.cs b/Wino.Core/Services/ImapTestService.cs index eb2dbc89..907df208 100644 --- a/Wino.Core/Services/ImapTestService.cs +++ b/Wino.Core/Services/ImapTestService.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Wino.Core.Domain.Entities; using Wino.Core.Domain.Interfaces; +using Wino.Core.Domain.Models.Connectivity; using Wino.Core.Integration; namespace Wino.Core.Services @@ -38,7 +39,9 @@ namespace Wino.Core.Services { EnsureProtocolLogFileExists(); - var clientPool = new ImapClientPool(serverInformation, _protocolLogStream) + var poolOptions = ImapClientPoolOptions.CreateTestPool(serverInformation, _protocolLogStream); + + var clientPool = new ImapClientPool(poolOptions) { ThrowOnSSLHandshakeCallback = !allowSSLHandShake }; diff --git a/Wino.Core/Synchronizers/ImapSynchronizer.cs b/Wino.Core/Synchronizers/ImapSynchronizer.cs index d8c15851..b9b1fc73 100644 --- a/Wino.Core/Synchronizers/ImapSynchronizer.cs +++ b/Wino.Core/Synchronizers/ImapSynchronizer.cs @@ -15,6 +15,7 @@ using Wino.Core.Domain.Entities; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Exceptions; using Wino.Core.Domain.Interfaces; +using Wino.Core.Domain.Models.Connectivity; using Wino.Core.Domain.Models.MailItem; using Wino.Core.Domain.Models.Synchronization; using Wino.Core.Extensions; @@ -73,7 +74,9 @@ namespace Wino.Core.Synchronizers _imapChangeProcessor = imapChangeProcessor; _applicationConfiguration = applicationConfiguration; - _clientPool = new ImapClientPool(Account.ServerInformation, CreateAccountProtocolLogFileStream()); + var poolOptions = ImapClientPoolOptions.CreateDefault(Account.ServerInformation, CreateAccountProtocolLogFileStream()); + + _clientPool = new ImapClientPool(poolOptions); idleDoneToken = new CancellationTokenSource(); }