From 395f903edc536adda0c370edc0fc957cf873ecc7 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 29 Oct 2021 17:53:19 +0200 Subject: [PATCH] Use SOA record for quick setup --- .../java/eu/faircode/email/DnsHelper.java | 7 ++ .../java/eu/faircode/email/EmailProvider.java | 84 +++++++++++-------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/DnsHelper.java b/app/src/main/java/eu/faircode/email/DnsHelper.java index f61760ce9e..34992e5a90 100644 --- a/app/src/main/java/eu/faircode/email/DnsHelper.java +++ b/app/src/main/java/eu/faircode/email/DnsHelper.java @@ -33,6 +33,7 @@ import org.xbill.DNS.Lookup; import org.xbill.DNS.MXRecord; import org.xbill.DNS.Message; import org.xbill.DNS.Record; +import org.xbill.DNS.SOARecord; import org.xbill.DNS.SRVRecord; import org.xbill.DNS.SimpleResolver; import org.xbill.DNS.TXTRecord; @@ -109,6 +110,9 @@ public class DnsHelper { case "mx": rtype = Type.MX; break; + case "soa": + rtype = Type.SOA; + break; case "srv": rtype = Type.SRV; break; @@ -213,6 +217,9 @@ public class DnsHelper { if (record instanceof MXRecord) { MXRecord mx = (MXRecord) record; result.add(new DnsRecord(mx.getTarget().toString(true))); + } else if (record instanceof SOARecord) { + SOARecord soa = (SOARecord) record; + result.add(new DnsRecord(soa.getHost().toString(true))); } else if (record instanceof SRVRecord) { SRVRecord srv = (SRVRecord) record; result.add(new DnsRecord(srv.getTarget().toString(true), srv.getPort())); diff --git a/app/src/main/java/eu/faircode/email/EmailProvider.java b/app/src/main/java/eu/faircode/email/EmailProvider.java index d8ea3d85e9..a36389d20d 100644 --- a/app/src/main/java/eu/faircode/email/EmailProvider.java +++ b/app/src/main/java/eu/faircode/email/EmailProvider.java @@ -128,7 +128,7 @@ public class EmailProvider implements Parcelable { List providers = loadProfiles(context); for (EmailProvider provider : providers) - if (provider.domain != null) + if (provider.enabled && provider.domain != null) for (String domain : provider.domain) if (!result.contains(domain)) result.add(domain); @@ -270,7 +270,7 @@ public class EmailProvider implements Parcelable { List providers = loadProfiles(context); for (EmailProvider provider : providers) - if (provider.domain != null) + if (provider.enabled && provider.domain != null) for (String d : provider.domain) if (domain.toLowerCase(Locale.ROOT).matches(d)) { EntityLog.log(context, "Provider from domain=" + domain + " (" + d + ")"); @@ -281,47 +281,64 @@ 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 (false) // Unsafe: the password could be sent to an unrelated email server + 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)); + 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); - } + } + } catch (Throwable ex) { + Log.w(ex); } - } catch (Throwable ex) { - Log.w(ex); - } try { - DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, domain, "mx"); + List records = new ArrayList<>(); + try { + DnsHelper.DnsRecord[] mx = DnsHelper.lookup(context, domain, "mx"); + if (mx.length > 0) + records.add(mx[0]); + } catch (Throwable ex) { + Log.w(ex); + } + + try { + // Primary DNS server + DnsHelper.DnsRecord[] soa = DnsHelper.lookup(context, domain, "soa"); + if (soa.length > 0) + records.add(soa[0]); + } catch (Throwable ex) { + Log.w(ex); + } for (DnsHelper.DnsRecord record : records) if (!TextUtils.isEmpty(record.name)) { String target = record.name.toLowerCase(Locale.ROOT); - EntityLog.log(context, "MX target=" + target); + EntityLog.log(context, "MX/SOA target=" + target); for (EmailProvider provider : providers) { - if (provider.mx != null) + if (provider.enabled && provider.mx != null) for (String mx : provider.mx) if (target.matches(mx)) { - EntityLog.log(context, "From MX domain=" + domain); + EntityLog.log(context, "From MX/SOA domain=" + domain); candidates.add(provider); break; } @@ -329,7 +346,7 @@ public class EmailProvider implements Parcelable { String mxparent = UriHelper.getParentDomain(context, target); String pdomain = UriHelper.getParentDomain(context, provider.imap.host); if (mxparent.equalsIgnoreCase(pdomain)) { - EntityLog.log(context, "From MX host=" + provider.imap.host); + EntityLog.log(context, "From MX/SOA host=" + provider.imap.host); candidates.add(provider); break; } @@ -385,7 +402,8 @@ public class EmailProvider implements Parcelable { // - ISPDB is not always correct // - documentation links for (EmailProvider provider : providers) - if (provider.imap.host.equals(candidate.imap.host) || + if (provider.enabled && + provider.imap.host.equals(candidate.imap.host) || provider.smtp.host.equals(candidate.smtp.host)) { EntityLog.log(context, "Replacing auto config by profile=" + provider.name); if (!BuildConfig.DEBUG) @@ -941,7 +959,7 @@ public class EmailProvider implements Parcelable { public boolean starttls; // Scores: - // 0 from MX record + // 0 from MX/SOA record // 10 from port scan // +2 trusted host // +1 trusted DNS name