public async void StartAccepting() { // Establish the local endpoint for the socket. var localEndPoint = new IPEndPoint(IPAddress.Any, ((IPEndPoint)this.LocalEndpoint).Port); // Create a TCP/IP socket. var listener = new ImapListener(this.server, localEndPoint); // Bind the socket to the local endpoint and listen for incoming connections. try { listener.Start(100); while (true) { // Start an asynchronous socket to listen for connections. var handler = await listener.AcceptTcpClientAsync(); // Create the state object. ImapConnection imapConnection; if (this.PortType == PortClass.ClearText || this.PortType == PortClass.ExplicitTLS) { var stream = handler.GetStream(); imapConnection = new ImapConnection(_Store, this.server, handler, stream); } else { var stream = handler.GetStream(); var sslStream = new SslStream(stream); try { await sslStream.AuthenticateAsServerAsync(this.server.ServerAuthenticationCertificate); } catch (IOException ioe) { _Logger.Error("I/O Exception attempting to perform TLS handshake", ioe); return; } imapConnection = new ImapConnection(_Store, this.server, handler, sslStream, true); } this.server.AddConnection(imapConnection); imapConnection.Process(); } } catch (Exception ex) { _Logger.Error("Exception when trying to accept connection from listener", ex); } }
public void Start() { this.listeners.Clear(); // Test LDAP connection, if configured if (this.LdapDirectoryConfiguration != null) { Logger.InfoFormat("Testing LDAP connection to {0} with lookup account {1}", this.LdapDirectoryConfiguration.LdapServer, this.LdapDirectoryConfiguration.LookupAccountUsername); if (LdapUtility.UserExists(this.LdapDirectoryConfiguration.LdapServer, this.LdapDirectoryConfiguration.SearchPath, this.LdapDirectoryConfiguration.LookupAccountUsername, this.LdapDirectoryConfiguration.LookupAccountPassword, this.LdapDirectoryConfiguration.LookupAccountUsername)) { Logger.Info("LDAP lookup account successfully found."); } else { Logger.Warn("Unable to find LDAP lookup account. LDAP authentication is being disabled."); this.LdapDirectoryConfiguration = null; } } // Setup SSL if (!string.IsNullOrWhiteSpace(this.SslServerCertificateThumbprint) && this.SslServerCertificateThumbprint != null) { var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.OpenExistingOnly); try { var collection = store.Certificates.Find(X509FindType.FindByThumbprint, this.SslServerCertificateThumbprint, true); if (collection.Cast <X509Certificate2>().Count(c => c.HasPrivateKey) == 0) { Logger.WarnFormat(@"No valid certificate with a public and private key could be found in the LocalMachine\Personal store with thumbprint: {0}. Disabling SSL.", this.SslServerCertificateThumbprint); this.AllowStartTLS = false; this.ImapExplicitTLSPorts = new int[0]; this.ImapImplicitTLSPorts = new int[0]; } else { Logger.InfoFormat("Located valid certificate with subject '{0}' and serial {1}", collection[0].Subject, collection[0].SerialNumber); this.ServerAuthenticationCertificate = collection[0]; } } finally { store.Close(); } } else if (this.SslGenerateSelfSignedServerCertificate || this.ImapExplicitTLSPorts.Any() || this.ImapImplicitTLSPorts.Any()) { var pfx = CertificateUtility.CreateSelfSignCertificatePfx("CN=freenews", DateTime.Now, DateTime.Now.AddYears(100), "password"); this.ServerAuthenticationCertificate = new X509Certificate2(pfx, "password"); } foreach (var clearPort in this.ImapClearPorts) { // Establish the local endpoint for the socket. var localEndPoint = new IPEndPoint(IPAddress.Any, clearPort); // Create a TCP/IP socket. var listener = new ImapListener(this, localEndPoint) { PortType = PortClass.ClearText }; this.listeners.Add(new Tuple <Thread, ImapListener>(new Thread(listener.StartAccepting), listener)); } foreach (var implicitTlsPort in this.ImapImplicitTLSPorts) { // Establish the local endpoint for the socket. var localEndPoint = new IPEndPoint(IPAddress.Any, implicitTlsPort); // Create a TCP/IP socket. var listener = new ImapListener(this, localEndPoint) { PortType = PortClass.ImplicitTLS }; this.listeners.Add(new Tuple <Thread, ImapListener>(new Thread(listener.StartAccepting), listener)); } foreach (var listener in this.listeners) { try { listener.Item1.Start(); Logger.InfoFormat("Listening on port {0} ({1})", ((IPEndPoint)listener.Item2.LocalEndpoint).Port, listener.Item2.PortType); } catch (OutOfMemoryException oom) { Logger.Error("Unable to start listener thread. Not enough memory.", oom); } } }