VpnTest: test getConnectionOwnerUid API
Test connection->UID resolution for both UDP and TCP connections.
Bug: 9496886
Bug: 109758967
Test: atest HostsideVpnTests
Change-Id: Ic17c64df74f65d788fd3d95a25af3c5b44946881
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
index bc982ce..1ba701d 100755
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -16,6 +16,7 @@
package com.android.cts.net.hostside;
+import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.*;
import android.content.Intent;
@@ -36,6 +37,7 @@
import android.support.test.uiautomator.UiSelector;
import android.system.ErrnoException;
import android.system.Os;
+import android.system.OsConstants;
import android.system.StructPollfd;
import android.test.InstrumentationTestCase;
import android.test.MoreAsserts;
@@ -353,7 +355,7 @@
MoreAsserts.assertEquals(data, read);
}
- private static void checkTcpReflection(String to, String expectedFrom) throws IOException {
+ private void checkTcpReflection(String to, String expectedFrom) throws IOException {
// Exercise TCP over the VPN by "connecting to ourselves". We open a server socket and a
// client socket, and connect the client socket to a remote host, with the port of the
// server socket. The PacketReflector reflects the packets, changing the source addresses
@@ -391,7 +393,8 @@
// Accept the connection on the server side.
listen.setSoTimeout(SOCKET_TIMEOUT_MS);
server = listen.accept();
-
+ checkConnectionOwnerUidTcp(client);
+ checkConnectionOwnerUidTcp(server);
// Check that the source and peer addresses are as expected.
assertEquals(expectedFrom, client.getLocalAddress().getHostAddress());
assertEquals(expectedFrom, server.getLocalAddress().getHostAddress());
@@ -424,7 +427,23 @@
}
}
- private static void checkUdpEcho(String to, String expectedFrom) throws IOException {
+ private void checkConnectionOwnerUidUdp(DatagramSocket s, boolean expectSuccess) {
+ final int expectedUid = expectSuccess ? Process.myUid() : INVALID_UID;
+ InetSocketAddress loc = new InetSocketAddress(s.getLocalAddress(), s.getLocalPort());
+ InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort());
+ int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_UDP, loc, rem);
+ assertEquals(expectedUid, uid);
+ }
+
+ private void checkConnectionOwnerUidTcp(Socket s) {
+ final int expectedUid = Process.myUid();
+ InetSocketAddress loc = new InetSocketAddress(s.getLocalAddress(), s.getLocalPort());
+ InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort());
+ int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_TCP, loc, rem);
+ assertEquals(expectedUid, uid);
+ }
+
+ private void checkUdpEcho(String to, String expectedFrom) throws IOException {
DatagramSocket s;
InetAddress address = InetAddress.getByName(to);
if (address instanceof Inet6Address) { // http://b/18094870
@@ -448,6 +467,7 @@
try {
if (expectedFrom != null) {
s.send(p);
+ checkConnectionOwnerUidUdp(s, true);
s.receive(p);
MoreAsserts.assertEquals(data, p.getData());
} else {
@@ -455,7 +475,9 @@
s.send(p);
s.receive(p);
fail("Received unexpected reply");
- } catch(IOException expected) {}
+ } catch (IOException expected) {
+ checkConnectionOwnerUidUdp(s, false);
+ }
}
} finally {
s.close();
@@ -580,4 +602,23 @@
checkNoTrafficOnVpn();
}
+
+ public void testGetConnectionOwnerUidSecurity() throws Exception {
+
+ if (!supportedHardware()) return;
+
+ DatagramSocket s;
+ InetAddress address = InetAddress.getByName("localhost");
+ s = new DatagramSocket();
+ s.setSoTimeout(SOCKET_TIMEOUT_MS);
+ s.connect(address, 7);
+ InetSocketAddress loc = new InetSocketAddress(s.getLocalAddress(), s.getLocalPort());
+ InetSocketAddress rem = new InetSocketAddress(s.getInetAddress(), s.getPort());
+ try {
+ int uid = mCM.getConnectionOwnerUid(OsConstants.IPPROTO_TCP, loc, rem);
+ fail("Only an active VPN app may call this API.");
+ } catch (SecurityException expected) {
+ return;
+ }
+ }
}
diff --git a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java
index 69b07af..853668c 100644
--- a/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java
+++ b/tests/cts/hostside/src/com/android/cts/net/HostsideVpnTests.java
@@ -44,4 +44,8 @@
public void testAppDisallowed() throws Exception {
runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testAppDisallowed");
}
+
+ public void testGetConnectionOwnerUidSecurity() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testGetConnectionOwnerUidSecurity");
+ }
}