Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try all IP addresses when connecting to a POP3 server #6453

Merged
merged 1 commit into from Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -5,9 +5,10 @@
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
import java.security.KeyManagementException;
import java.security.MessageDigest;
Expand Down Expand Up @@ -61,15 +62,7 @@ class Pop3Connection {

void open() throws MessagingException {
try {
SocketAddress socketAddress = new InetSocketAddress(settings.getHost(), settings.getPort());
if (settings.getConnectionSecurity() == ConnectionSecurity.SSL_TLS_REQUIRED) {
socket = trustedSocketFactory.createSocket(null, settings.getHost(),
settings.getPort(), settings.getClientCertificateAlias());
} else {
socket = new Socket();
}

socket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
socket = connect();
in = new BufferedInputStream(socket.getInputStream(), 1024);
out = new BufferedOutputStream(socket.getOutputStream(), 512);

Expand Down Expand Up @@ -102,6 +95,44 @@ void open() throws MessagingException {
}
}

private Socket connect()
throws IOException, MessagingException, NoSuchAlgorithmException, KeyManagementException {
InetAddress[] inetAddresses = InetAddress.getAllByName(settings.getHost());

IOException connectException = null;
for (InetAddress address : inetAddresses) {
try {
return connectToAddress(address);
} catch (IOException e) {
Timber.w(e, "Could not connect to %s", address);
connectException = e;
}
}

throw connectException != null ? connectException : new UnknownHostException();
}

private Socket connectToAddress(InetAddress address)
throws IOException, MessagingException, NoSuchAlgorithmException, KeyManagementException {
if (K9MailLib.isDebug() && K9MailLib.DEBUG_PROTOCOL_POP3) {
Timber.d("Connecting to %s as %s", settings.getHost(), address);
}

InetSocketAddress socketAddress = new InetSocketAddress(address, settings.getPort());

final Socket socket;
if (settings.getConnectionSecurity() == ConnectionSecurity.SSL_TLS_REQUIRED) {
socket = trustedSocketFactory.createSocket(null, settings.getHost(), settings.getPort(),
settings.getClientCertificateAlias());
} else {
socket = new Socket();
}

socket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);

return socket;
}

/*
* If STARTTLS is not available throws a CertificateValidationException which in K-9
* triggers a "Certificate error" notification that takes the user to the incoming
Expand Down
Expand Up @@ -37,7 +37,7 @@ class Pop3StoreTest {
@Test(expected = MessagingException::class)
fun `checkSettings() with TrustedSocketFactory throwing should throw MessagingException`() {
stubbing(trustedSocketFactory) {
on { createSocket(null, "server", 12345, null) } doThrow IOException()
on { createSocket(null, HOST, 12345, null) } doThrow IOException()
}

store.checkSettings()
Expand Down Expand Up @@ -72,7 +72,7 @@ class Pop3StoreTest {
private fun createServerSettings(): ServerSettings {
return ServerSettings(
type = "pop3",
host = "server",
host = HOST,
port = 12345,
connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED,
authenticationType = AuthType.PLAIN,
Expand All @@ -93,13 +93,14 @@ class Pop3StoreTest {
}

stubbing(trustedSocketFactory) {
on { createSocket(null, "server", 12345, null) } doReturn socket
on { createSocket(null, HOST, 12345, null) } doReturn socket
}

return outputStream
}

companion object {
private const val HOST = "127.0.0.1"
private const val INITIAL_RESPONSE = "+OK POP3 server greeting\r\n"

private const val CAPA_RESPONSE = "+OK Listing of supported mechanisms follows\r\n" +
Expand Down