made DNSEC hostname validation opt-in
This commit is contained in:
		
							parent
							
								
									da00a58902
								
							
						
					
					
						commit
						abf84e065d
					
				| @ -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); | ||||
|  | ||||
| @ -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<Result> list = new ArrayList<>(); | ||||
|         try { | ||||
|             ResolverResult<D> results = resolveWithFallback(DNSName.from(srv.name.toString()),type, !authenticated); | ||||
|             ResolverResult<D> 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<Result> resolveFallback(DNSName dnsName) { | ||||
|     private static List<Result> resolveFallback(DNSName dnsName, boolean withCnames) { | ||||
|         List<Result> 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 <D extends Data> ResolverResult<D> resolveWithFallback(DNSName dnsName, Class<D> type) throws IOException { | ||||
|         return resolveWithFallback(dnsName,type,false); | ||||
|         return resolveWithFallback(dnsName,type,validateHostname()); | ||||
|     } | ||||
| 
 | ||||
|     private static <D extends Data> ResolverResult<D> resolveWithFallback(DNSName dnsName, Class<D> type, boolean skipDnssec) throws IOException { | ||||
|         if (skipDnssec) { | ||||
|     private static <D extends Data> ResolverResult<D> resolveWithFallback(DNSName dnsName, Class<D> 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<Result> { | ||||
|         private InetAddress ip; | ||||
|         private DNSName hostname; | ||||
|  | ||||
| @ -40,4 +40,5 @@ | ||||
|     <bool name="enable_foreground_service">false</bool> | ||||
|     <bool name="never_send">false</bool> | ||||
|     <bool name="return_to_previous">false</bool> | ||||
|     <bool name="validate_hostname">false</bool> | ||||
| </resources> | ||||
|  | ||||
| @ -756,4 +756,6 @@ | ||||
| 	<string name="pref_headsup_notifications_summary">Show Heads-up Notifications</string> | ||||
| 	<string name="today">Today</string> | ||||
| 	<string name="yesterday">Yesterday</string> | ||||
| 	<string name="pref_validate_hostname">Validate hostname with DNSSEC</string> | ||||
| 	<string name="pref_validate_hostname_summary">Server certificates that contain the validated hostname are considered verified</string> | ||||
| </resources> | ||||
|  | ||||
| @ -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"/> | ||||
|                 <CheckBoxPreference | ||||
|                     android:defaultValue="@bool/validate_hostname" | ||||
|                     android:key="validate_hostname" | ||||
|                     android:summary="@string/pref_validate_hostname_summary" | ||||
|                     android:title="@string/pref_validate_hostname"/> | ||||
|                 <Preference | ||||
|                     android:key="remove_trusted_certificates" | ||||
|                     android:summary="@string/pref_remove_trusted_certificates_summary" | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gultsch
						Daniel Gultsch