diff --git a/app/src/main/java/eu/faircode/email/ConnectionHelper.java b/app/src/main/java/eu/faircode/email/ConnectionHelper.java index a829c40d33..8b42b0aed2 100644 --- a/app/src/main/java/eu/faircode/email/ConnectionHelper.java +++ b/app/src/main/java/eu/faircode/email/ConnectionHelper.java @@ -37,12 +37,21 @@ import com.sun.mail.iap.ConnectionException; import com.sun.mail.util.FolderClosedIOException; import java.io.IOException; +import java.net.InetSocketAddress; +import java.security.cert.Certificate; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + public class ConnectionHelper { static final List PREF_NETWORK = Collections.unmodifiableList(Arrays.asList( "metered", "roaming", "rlah", "require_validated", "vpn_only" // update network state @@ -472,4 +481,29 @@ public class ConnectionHelper { return Settings.Global.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0; } + + static List getCommonNames(Context context, String domain, int port, int timeout) throws IOException { + List result = new ArrayList<>(); + InetSocketAddress address = new InetSocketAddress(domain, port); + SocketFactory factory = SSLSocketFactory.getDefault(); + try (SSLSocket sslSocket = (SSLSocket) factory.createSocket()) { + EntityLog.log(context, "Connecting to " + address); + sslSocket.connect(address, timeout); + EntityLog.log(context, "Connected " + address); + + sslSocket.setSoTimeout(timeout); + sslSocket.startHandshake(); + + Certificate[] certs = sslSocket.getSession().getPeerCertificates(); + for (Certificate cert : certs) + if (cert instanceof X509Certificate) { + try { + result.addAll(EntityCertificate.getDnsNames((X509Certificate) cert)); + } catch (CertificateParsingException ex) { + Log.w(ex); + } + } + } + return result; + } } diff --git a/app/src/main/java/eu/faircode/email/EmailProvider.java b/app/src/main/java/eu/faircode/email/EmailProvider.java index 92e3740bfd..d8ea3d85e9 100644 --- a/app/src/main/java/eu/faircode/email/EmailProvider.java +++ b/app/src/main/java/eu/faircode/email/EmailProvider.java @@ -281,6 +281,34 @@ public class EmailProvider implements Parcelable { List candidates = new ArrayList<>(_fromDomain(context, domain.toLowerCase(Locale.ROOT), email, discover)); + try { + InetAddress iaddr = InetAddress.getByName(domain.toLowerCase(Locale.ROOT)); + List commonNames = + ConnectionHelper.getCommonNames(context, domain.toLowerCase(Locale.ROOT), 443, SCAN_TIMEOUT); + EntityLog.log(context, "Website common names=" + TextUtils.join(",", commonNames)); + for (String commonName : commonNames) { + String altName = commonName; + if (altName.startsWith("*.")) { + altName = altName.substring(2); + if (commonNames.contains(altName)) + continue; + } + + if (!altName.equalsIgnoreCase(domain)) + try { + InetAddress ialt = InetAddress.getByName(altName); + if (!ialt.equals(iaddr)) { + EntityLog.log(context, "Using website common name=" + altName); + candidates.addAll(_fromDomain(context, altName.toLowerCase(Locale.ROOT), email, discover)); + } + } catch (Throwable ex) { + Log.w(ex); + } + } + } catch (Throwable ex) { + Log.w(ex); + } + try { DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, domain, "mx");