diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 065f4f1a..79a82314 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -986,7 +986,7 @@ public class XmppConnectionService extends Service { public void onCreate() { ExceptionHelper.init(getApplicationContext()); PRNGFixes.apply(); - Resolver.registerLookupMechanism(this); + Resolver.registerXmppConnectionService(this); this.mRandom = new SecureRandom(); updateMemorizingTrustmanager(); final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); diff --git a/src/main/java/eu/siacs/conversations/utils/Resolver.java b/src/main/java/eu/siacs/conversations/utils/Resolver.java index fb1f0523..8b160fa4 100644 --- a/src/main/java/eu/siacs/conversations/utils/Resolver.java +++ b/src/main/java/eu/siacs/conversations/utils/Resolver.java @@ -24,14 +24,23 @@ import de.measite.minidns.record.Data; import de.measite.minidns.record.InternetAddressRR; import de.measite.minidns.record.SRV; import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; +import eu.siacs.conversations.services.XmppConnectionService; public class Resolver { private static final String DIRECT_TLS_SERVICE = "_xmpps-client"; private static final String STARTTLS_SERICE = "_xmpp-client"; + private static XmppConnectionService SERVICE = null; - public static void registerLookupMechanism(Context context) { + + public static void registerXmppConnectionService(XmppConnectionService service) { + Resolver.SERVICE = service; + registerLookupMechanism(service); + } + + private static void registerLookupMechanism(Context context) { DNSClient.addDnsServerLookupMechanism(new AndroidUsingLinkProperties(context)); } @@ -48,7 +57,7 @@ public class Resolver { Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": "+e.getMessage()); } if (results.size() == 0) { - results.addAll(resolveFallback(DNSName.from(domain))); + results.addAll(resolveFallback(DNSName.from(domain),true)); } Collections.sort(results); Log.d(Config.LOGTAG,Resolver.class.getSimpleName()+": "+results.toString()); @@ -80,7 +89,7 @@ public class Resolver { } List list = new ArrayList<>(); try { - ResolverResult results = resolveWithFallback(DNSName.from(srv.name.toString()),type, !authenticated); + ResolverResult results = resolveWithFallback(DNSName.from(srv.name.toString()),type, authenticated); for (D record : results.getAnswersOrEmptySet()) { Result resolverResult = Result.fromRecord(srv, directTls); resolverResult.authenticated = results.isAuthenticData() && authenticated; @@ -93,18 +102,18 @@ public class Resolver { return list; } - private static List resolveFallback(DNSName dnsName) { + private static List resolveFallback(DNSName dnsName, boolean withCnames) { List results = new ArrayList<>(); try { - for(A a : resolveWithFallback(dnsName,A.class,true).getAnswersOrEmptySet()) { + for(A a : resolveWithFallback(dnsName,A.class,false).getAnswersOrEmptySet()) { results.add(Result.createDefault(dnsName,a.getInetAddress())); } - for(AAAA aaaa : resolveWithFallback(dnsName,AAAA.class,true).getAnswersOrEmptySet()) { + for(AAAA aaaa : resolveWithFallback(dnsName,AAAA.class,false).getAnswersOrEmptySet()) { results.add(Result.createDefault(dnsName,aaaa.getInetAddress())); } if (results.size() == 0) { - for (CNAME cname : resolveWithFallback(dnsName, CNAME.class, true).getAnswersOrEmptySet()) { - results.addAll(resolveFallback(cname.name)); + for (CNAME cname : resolveWithFallback(dnsName, CNAME.class, false).getAnswersOrEmptySet()) { + results.addAll(resolveFallback(cname.name, false)); } } } catch (IOException e) { @@ -117,11 +126,11 @@ public class Resolver { } private static ResolverResult resolveWithFallback(DNSName dnsName, Class type) throws IOException { - return resolveWithFallback(dnsName,type,false); + return resolveWithFallback(dnsName,type,validateHostname()); } - private static ResolverResult resolveWithFallback(DNSName dnsName, Class type, boolean skipDnssec) throws IOException { - if (skipDnssec) { + private static ResolverResult resolveWithFallback(DNSName dnsName, Class type, boolean validateHostname) throws IOException { + if (!validateHostname) { return ResolverApi.INSTANCE.resolve(dnsName, type); } try { @@ -143,6 +152,10 @@ public class Resolver { return ResolverApi.INSTANCE.resolve(dnsName, type); } + private static boolean validateHostname() { + return SERVICE != null && SERVICE.getBooleanPreference("validate_hostname", R.bool.validate_hostname); + } + public static class Result implements Comparable { private InetAddress ip; private DNSName hostname; diff --git a/src/main/res/values/defaults.xml b/src/main/res/values/defaults.xml index f7a84db0..76add0bf 100644 --- a/src/main/res/values/defaults.xml +++ b/src/main/res/values/defaults.xml @@ -40,4 +40,5 @@ false false false + false diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 53a8c036..ff650c6f 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -756,4 +756,6 @@ Show Heads-up Notifications Today Yesterday + Validate hostname with DNSSEC + Server certificates that contain the validated hostname are considered verified diff --git a/src/main/res/xml/preferences.xml b/src/main/res/xml/preferences.xml index af095ca3..6a9adfd4 100644 --- a/src/main/res/xml/preferences.xml +++ b/src/main/res/xml/preferences.xml @@ -194,6 +194,11 @@ android:key="dont_trust_system_cas" android:summary="@string/pref_dont_trust_system_cas_summary" android:title="@string/pref_dont_trust_system_cas_title"/> +