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