1 /* 2 * Copyright (C) 2018, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.connectivity; 18 19 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; 20 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; 21 import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; 22 import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE; 23 import static android.provider.Settings.Global.PRIVATE_DNS_MODE; 24 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER; 25 26 import static org.junit.Assert.assertEquals; 27 import static org.junit.Assert.assertFalse; 28 import static org.junit.Assert.assertNull; 29 import static org.junit.Assert.assertTrue; 30 import static org.mockito.Mockito.when; 31 32 import android.content.ContentResolver; 33 import android.content.Context; 34 import android.net.IpPrefix; 35 import android.net.LinkAddress; 36 import android.net.LinkProperties; 37 import android.net.Network; 38 import android.net.RouteInfo; 39 import android.os.INetworkManagementService; 40 import android.provider.Settings; 41 import android.support.test.filters.SmallTest; 42 import android.support.test.runner.AndroidJUnit4; 43 import android.test.mock.MockContentResolver; 44 45 import com.android.internal.util.test.FakeSettingsProvider; 46 import com.android.server.connectivity.DnsManager.PrivateDnsConfig; 47 import com.android.server.connectivity.MockableSystemProperties; 48 49 import java.net.InetAddress; 50 import java.util.Arrays; 51 52 import org.junit.runner.RunWith; 53 import org.junit.Before; 54 import org.junit.Test; 55 import org.mockito.Mock; 56 import org.mockito.MockitoAnnotations; 57 58 /** 59 * Tests for {@link DnsManager}. 60 * 61 * Build, install and run with: 62 * runtest frameworks-net -c com.android.server.connectivity.DnsManagerTest 63 */ 64 @RunWith(AndroidJUnit4.class) 65 @SmallTest 66 public class DnsManagerTest { 67 static final String TEST_IFACENAME = "test_wlan0"; 68 static final int TEST_NETID = 100; 69 static final int TEST_NETID_ALTERNATE = 101; 70 static final int TEST_NETID_UNTRACKED = 102; 71 final boolean IS_DEFAULT = true; 72 final boolean NOT_DEFAULT = false; 73 74 DnsManager mDnsManager; 75 MockContentResolver mContentResolver; 76 77 @Mock Context mCtx; 78 @Mock INetworkManagementService mNMService; 79 @Mock MockableSystemProperties mSystemProperties; 80 81 @Before setUp()82 public void setUp() throws Exception { 83 MockitoAnnotations.initMocks(this); 84 mContentResolver = new MockContentResolver(); 85 mContentResolver.addProvider(Settings.AUTHORITY, 86 new FakeSettingsProvider()); 87 when(mCtx.getContentResolver()).thenReturn(mContentResolver); 88 mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties); 89 90 // Clear the private DNS settings 91 Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, ""); 92 Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, ""); 93 Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, ""); 94 } 95 96 @Test testTrackedValidationUpdates()97 public void testTrackedValidationUpdates() throws Exception { 98 mDnsManager.updatePrivateDns(new Network(TEST_NETID), 99 mDnsManager.getPrivateDnsConfig()); 100 mDnsManager.updatePrivateDns(new Network(TEST_NETID_ALTERNATE), 101 mDnsManager.getPrivateDnsConfig()); 102 LinkProperties lp = new LinkProperties(); 103 lp.setInterfaceName(TEST_IFACENAME); 104 lp.addDnsServer(InetAddress.getByName("3.3.3.3")); 105 lp.addDnsServer(InetAddress.getByName("4.4.4.4")); 106 107 // Send a validation event that is tracked on the alternate netId 108 mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); 109 mDnsManager.setDnsConfigurationForNetwork(TEST_NETID_ALTERNATE, lp, NOT_DEFAULT); 110 mDnsManager.updatePrivateDnsValidation( 111 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_ALTERNATE, 112 InetAddress.parseNumericAddress("4.4.4.4"), "", true)); 113 LinkProperties fixedLp = new LinkProperties(lp); 114 mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); 115 assertFalse(fixedLp.isPrivateDnsActive()); 116 assertNull(fixedLp.getPrivateDnsServerName()); 117 fixedLp = new LinkProperties(lp); 118 mDnsManager.updatePrivateDnsStatus(TEST_NETID_ALTERNATE, fixedLp); 119 assertTrue(fixedLp.isPrivateDnsActive()); 120 assertNull(fixedLp.getPrivateDnsServerName()); 121 assertEquals(Arrays.asList(InetAddress.getByName("4.4.4.4")), 122 fixedLp.getValidatedPrivateDnsServers()); 123 124 // Set up addresses for strict mode and switch to it. 125 lp.addLinkAddress(new LinkAddress("192.0.2.4/24")); 126 lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"), 127 TEST_IFACENAME)); 128 lp.addLinkAddress(new LinkAddress("2001:db8:1::1/64")); 129 lp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("2001:db8:1::1"), 130 TEST_IFACENAME)); 131 132 Settings.Global.putString(mContentResolver, 133 PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); 134 Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com"); 135 mDnsManager.updatePrivateDns(new Network(TEST_NETID), 136 new DnsManager.PrivateDnsConfig("strictmode.com", new InetAddress[] { 137 InetAddress.parseNumericAddress("6.6.6.6"), 138 InetAddress.parseNumericAddress("2001:db8:66:66::1") 139 })); 140 mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); 141 fixedLp = new LinkProperties(lp); 142 mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); 143 assertTrue(fixedLp.isPrivateDnsActive()); 144 assertEquals("strictmode.com", fixedLp.getPrivateDnsServerName()); 145 // No validation events yet. 146 assertEquals(Arrays.asList(new InetAddress[0]), fixedLp.getValidatedPrivateDnsServers()); 147 // Validate one. 148 mDnsManager.updatePrivateDnsValidation( 149 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, 150 InetAddress.parseNumericAddress("6.6.6.6"), "strictmode.com", true)); 151 fixedLp = new LinkProperties(lp); 152 mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); 153 assertEquals(Arrays.asList(InetAddress.parseNumericAddress("6.6.6.6")), 154 fixedLp.getValidatedPrivateDnsServers()); 155 // Validate the 2nd one. 156 mDnsManager.updatePrivateDnsValidation( 157 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, 158 InetAddress.parseNumericAddress("2001:db8:66:66::1"), "strictmode.com", true)); 159 fixedLp = new LinkProperties(lp); 160 mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp); 161 assertEquals(Arrays.asList( 162 InetAddress.parseNumericAddress("2001:db8:66:66::1"), 163 InetAddress.parseNumericAddress("6.6.6.6")), 164 fixedLp.getValidatedPrivateDnsServers()); 165 } 166 167 @Test testIgnoreUntrackedValidationUpdates()168 public void testIgnoreUntrackedValidationUpdates() throws Exception { 169 // The PrivateDnsConfig map is empty, so no validation events will 170 // be tracked. 171 LinkProperties lp = new LinkProperties(); 172 lp.addDnsServer(InetAddress.getByName("3.3.3.3")); 173 mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); 174 mDnsManager.updatePrivateDnsValidation( 175 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, 176 InetAddress.parseNumericAddress("3.3.3.3"), "", true)); 177 mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); 178 assertFalse(lp.isPrivateDnsActive()); 179 assertNull(lp.getPrivateDnsServerName()); 180 181 // Validation event has untracked netId 182 mDnsManager.updatePrivateDns(new Network(TEST_NETID), 183 mDnsManager.getPrivateDnsConfig()); 184 mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); 185 mDnsManager.updatePrivateDnsValidation( 186 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_UNTRACKED, 187 InetAddress.parseNumericAddress("3.3.3.3"), "", true)); 188 mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); 189 assertFalse(lp.isPrivateDnsActive()); 190 assertNull(lp.getPrivateDnsServerName()); 191 192 // Validation event has untracked ipAddress 193 mDnsManager.updatePrivateDnsValidation( 194 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, 195 InetAddress.parseNumericAddress("4.4.4.4"), "", true)); 196 mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); 197 assertFalse(lp.isPrivateDnsActive()); 198 assertNull(lp.getPrivateDnsServerName()); 199 200 // Validation event has untracked hostname 201 mDnsManager.updatePrivateDnsValidation( 202 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, 203 InetAddress.parseNumericAddress("3.3.3.3"), "hostname", 204 true)); 205 mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); 206 assertFalse(lp.isPrivateDnsActive()); 207 assertNull(lp.getPrivateDnsServerName()); 208 209 // Validation event failed 210 mDnsManager.updatePrivateDnsValidation( 211 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, 212 InetAddress.parseNumericAddress("3.3.3.3"), "", false)); 213 mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); 214 assertFalse(lp.isPrivateDnsActive()); 215 assertNull(lp.getPrivateDnsServerName()); 216 217 // Network removed 218 mDnsManager.removeNetwork(new Network(TEST_NETID)); 219 mDnsManager.updatePrivateDnsValidation( 220 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, 221 InetAddress.parseNumericAddress("3.3.3.3"), "", true)); 222 mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); 223 assertFalse(lp.isPrivateDnsActive()); 224 assertNull(lp.getPrivateDnsServerName()); 225 226 // Turn private DNS mode off 227 Settings.Global.putString(mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF); 228 mDnsManager.updatePrivateDns(new Network(TEST_NETID), 229 mDnsManager.getPrivateDnsConfig()); 230 mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT); 231 mDnsManager.updatePrivateDnsValidation( 232 new DnsManager.PrivateDnsValidationUpdate(TEST_NETID, 233 InetAddress.parseNumericAddress("3.3.3.3"), "", true)); 234 mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp); 235 assertFalse(lp.isPrivateDnsActive()); 236 assertNull(lp.getPrivateDnsServerName()); 237 } 238 239 @Test testOverrideDefaultMode()240 public void testOverrideDefaultMode() throws Exception { 241 // Hard-coded default is opportunistic mode. 242 final PrivateDnsConfig cfgAuto = DnsManager.getPrivateDnsConfig(mContentResolver); 243 assertTrue(cfgAuto.useTls); 244 assertEquals("", cfgAuto.hostname); 245 assertEquals(new InetAddress[0], cfgAuto.ips); 246 247 // Pretend a gservices push sets the default to "off". 248 Settings.Global.putString(mContentResolver, PRIVATE_DNS_DEFAULT_MODE, "off"); 249 final PrivateDnsConfig cfgOff = DnsManager.getPrivateDnsConfig(mContentResolver); 250 assertFalse(cfgOff.useTls); 251 assertEquals("", cfgOff.hostname); 252 assertEquals(new InetAddress[0], cfgOff.ips); 253 254 // Strict mode still works. 255 Settings.Global.putString( 256 mContentResolver, PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); 257 Settings.Global.putString(mContentResolver, PRIVATE_DNS_SPECIFIER, "strictmode.com"); 258 final PrivateDnsConfig cfgStrict = DnsManager.getPrivateDnsConfig(mContentResolver); 259 assertTrue(cfgStrict.useTls); 260 assertEquals("strictmode.com", cfgStrict.hostname); 261 assertEquals(new InetAddress[0], cfgStrict.ips); 262 } 263 } 264