OSDN Git Service

Server API to only allow networking by VPN apps
[android-x86/system-netd.git] / tests / binder_test.cpp
1 /*
2  * Copyright 2016 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  * binder_test.cpp - unit tests for netd binder RPCs.
17  */
18
19 #include <cerrno>
20 #include <cinttypes>
21 #include <cstdint>
22 #include <cstdio>
23 #include <cstdlib>
24 #include <vector>
25
26 #include <android-base/stringprintf.h>
27 #include <android-base/strings.h>
28 #include <cutils/multiuser.h>
29 #include <gtest/gtest.h>
30 #include <logwrap/logwrap.h>
31
32 #include "NetdConstants.h"
33 #include "android/net/INetd.h"
34 #include "android/net/UidRange.h"
35 #include "binder/IServiceManager.h"
36
37 using namespace android;
38 using namespace android::base;
39 using namespace android::binder;
40 using android::net::INetd;
41 using android::net::UidRange;
42
43 static const char* IP_RULE_V4 = "-4";
44 static const char* IP_RULE_V6 = "-6";
45
46 class BinderTest : public ::testing::Test {
47
48 public:
49     BinderTest() {
50         sp<IServiceManager> sm = defaultServiceManager();
51         sp<IBinder> binder = sm->getService(String16("netd"));
52         if (binder != nullptr) {
53             mNetd = interface_cast<INetd>(binder);
54         }
55     }
56
57     void SetUp() {
58         ASSERT_NE(nullptr, mNetd.get());
59     }
60
61 protected:
62     sp<INetd> mNetd;
63 };
64
65
66 class TimedOperation : public Stopwatch {
67 public:
68     TimedOperation(std::string name): mName(name) {}
69     virtual ~TimedOperation() {
70         fprintf(stderr, "    %s: %6.1f ms\n", mName.c_str(), timeTaken());
71     }
72
73 private:
74     std::string mName;
75 };
76
77 TEST_F(BinderTest, TestIsAlive) {
78     TimedOperation t("isAlive RPC");
79     bool isAlive = false;
80     mNetd->isAlive(&isAlive);
81     ASSERT_TRUE(isAlive);
82 }
83
84 static int randomUid() {
85     return 100000 * arc4random_uniform(7) + 10000 + arc4random_uniform(5000);
86 }
87
88 static std::vector<std::string> runCommand(const std::string& command) {
89     std::vector<std::string> lines;
90     FILE *f;
91
92     if ((f = popen(command.c_str(), "r")) == nullptr) {
93         perror("popen");
94         return lines;
95     }
96
97     char *line = nullptr;
98     size_t bufsize = 0;
99     ssize_t linelen = 0;
100     while ((linelen = getline(&line, &bufsize, f)) >= 0) {
101         lines.push_back(std::string(line, linelen));
102         free(line);
103         line = nullptr;
104     }
105
106     pclose(f);
107     return lines;
108 }
109
110 static std::vector<std::string> listIpRules(const char *ipVersion) {
111     std::string command = StringPrintf("%s %s rule list", IP_PATH, ipVersion);
112     return runCommand(command);
113 }
114
115 static std::vector<std::string> listIptablesRule(const char *binary, const char *chainName) {
116     std::string command = StringPrintf("%s -n -L %s", binary, chainName);
117     return runCommand(command);
118 }
119
120 static int iptablesRuleLineLength(const char *binary, const char *chainName) {
121     return listIptablesRule(binary, chainName).size();
122 }
123
124 TEST_F(BinderTest, TestFirewallReplaceUidChain) {
125     std::string chainName = StringPrintf("netd_binder_test_%u", arc4random_uniform(10000));
126     const int kNumUids = 500;
127     std::vector<int32_t> noUids(0);
128     std::vector<int32_t> uids(kNumUids);
129     for (int i = 0; i < kNumUids; i++) {
130         uids[i] = randomUid();
131     }
132
133     bool ret;
134     {
135         TimedOperation op(StringPrintf("Programming %d-UID whitelist chain", kNumUids));
136         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), true, uids, &ret);
137     }
138     EXPECT_EQ(true, ret);
139     EXPECT_EQ((int) uids.size() + 4, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
140     EXPECT_EQ((int) uids.size() + 4, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
141     {
142         TimedOperation op("Clearing whitelist chain");
143         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
144     }
145     EXPECT_EQ(true, ret);
146     EXPECT_EQ(2, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
147     EXPECT_EQ(2, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
148
149     {
150         TimedOperation op(StringPrintf("Programming %d-UID blacklist chain", kNumUids));
151         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, uids, &ret);
152     }
153     EXPECT_EQ(true, ret);
154     EXPECT_EQ((int) uids.size() + 3, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
155     EXPECT_EQ((int) uids.size() + 3, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
156
157     {
158         TimedOperation op("Clearing blacklist chain");
159         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
160     }
161     EXPECT_EQ(true, ret);
162     EXPECT_EQ(2, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
163     EXPECT_EQ(2, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
164
165     // Check that the call fails if iptables returns an error.
166     std::string veryLongStringName = "netd_binder_test_UnacceptablyLongIptablesChainName";
167     mNetd->firewallReplaceUidChain(String16(veryLongStringName.c_str()), true, noUids, &ret);
168     EXPECT_EQ(false, ret);
169 }
170
171 static int bandwidthDataSaverEnabled(const char *binary) {
172     std::vector<std::string> lines = listIptablesRule(binary, "bw_data_saver");
173
174     // Output looks like this:
175     //
176     // Chain bw_data_saver (1 references)
177     // target     prot opt source               destination
178     // RETURN     all  --  0.0.0.0/0            0.0.0.0/0
179     EXPECT_EQ(3U, lines.size());
180     if (lines.size() != 3) return -1;
181
182     EXPECT_TRUE(android::base::StartsWith(lines[2], "RETURN ") ||
183                 android::base::StartsWith(lines[2], "REJECT "));
184
185     return android::base::StartsWith(lines[2], "REJECT");
186 }
187
188 bool enableDataSaver(sp<INetd>& netd, bool enable) {
189     TimedOperation op(enable ? " Enabling data saver" : "Disabling data saver");
190     bool ret;
191     netd->bandwidthEnableDataSaver(enable, &ret);
192     return ret;
193 }
194
195 int getDataSaverState() {
196     const int enabled4 = bandwidthDataSaverEnabled(IPTABLES_PATH);
197     const int enabled6 = bandwidthDataSaverEnabled(IP6TABLES_PATH);
198     EXPECT_EQ(enabled4, enabled6);
199     EXPECT_NE(-1, enabled4);
200     EXPECT_NE(-1, enabled6);
201     if (enabled4 != enabled6 || (enabled6 != 0 && enabled6 != 1)) {
202         return -1;
203     }
204     return enabled6;
205 }
206
207 TEST_F(BinderTest, TestBandwidthEnableDataSaver) {
208     const int wasEnabled = getDataSaverState();
209     ASSERT_NE(-1, wasEnabled);
210
211     if (wasEnabled) {
212         ASSERT_TRUE(enableDataSaver(mNetd, false));
213         EXPECT_EQ(0, getDataSaverState());
214     }
215
216     ASSERT_TRUE(enableDataSaver(mNetd, false));
217     EXPECT_EQ(0, getDataSaverState());
218
219     ASSERT_TRUE(enableDataSaver(mNetd, true));
220     EXPECT_EQ(1, getDataSaverState());
221
222     ASSERT_TRUE(enableDataSaver(mNetd, true));
223     EXPECT_EQ(1, getDataSaverState());
224
225     if (!wasEnabled) {
226         ASSERT_TRUE(enableDataSaver(mNetd, false));
227         EXPECT_EQ(0, getDataSaverState());
228     }
229 }
230
231 static bool ipRuleExistsForRange(const uint32_t priority, const UidRange& range,
232         const std::string& action, const char* ipVersion) {
233     // Output looks like this:
234     //   "11500:\tfrom all fwmark 0x0/0x20000 iif lo uidrange 1000-2000 prohibit"
235     std::vector<std::string> rules = listIpRules(ipVersion);
236
237     std::string prefix = StringPrintf("%" PRIu32 ":", priority);
238     std::string suffix = StringPrintf(" iif lo uidrange %d-%d %s\n",
239             range.getStart(), range.getStop(), action.c_str());
240     for (std::string line : rules) {
241         if (android::base::StartsWith(line, prefix.c_str())
242                 && android::base::EndsWith(line, suffix.c_str())) {
243             return true;
244         }
245     }
246     return false;
247 }
248
249 static bool ipRuleExistsForRange(const uint32_t priority, const UidRange& range,
250         const std::string& action) {
251     bool existsIp4 = ipRuleExistsForRange(priority, range, action, IP_RULE_V4);
252     bool existsIp6 = ipRuleExistsForRange(priority, range, action, IP_RULE_V6);
253     EXPECT_EQ(existsIp4, existsIp6);
254     return existsIp4;
255 }
256
257 TEST_F(BinderTest, TestNetworkRejectNonSecureVpn) {
258     constexpr uint32_t RULE_PRIORITY = 11500;
259
260     constexpr int baseUid = MULTIUSER_APP_PER_USER_RANGE * 5;
261     std::vector<UidRange> uidRanges = {
262         {baseUid + 150, baseUid + 224},
263         {baseUid + 226, baseUid + 300}
264     };
265
266     const std::vector<std::string> initialRulesV4 = listIpRules(IP_RULE_V4);
267     const std::vector<std::string> initialRulesV6 = listIpRules(IP_RULE_V6);
268
269     // Create two valid rules.
270     ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(true, uidRanges).isOk());
271     EXPECT_EQ(initialRulesV4.size() + 2, listIpRules(IP_RULE_V4).size());
272     EXPECT_EQ(initialRulesV6.size() + 2, listIpRules(IP_RULE_V6).size());
273     for (auto const& range : uidRanges) {
274         EXPECT_TRUE(ipRuleExistsForRange(RULE_PRIORITY, range, "prohibit"));
275     }
276
277     // Remove the rules.
278     ASSERT_TRUE(mNetd->networkRejectNonSecureVpn(false, uidRanges).isOk());
279     EXPECT_EQ(initialRulesV4.size(), listIpRules(IP_RULE_V4).size());
280     EXPECT_EQ(initialRulesV6.size(), listIpRules(IP_RULE_V6).size());
281     for (auto const& range : uidRanges) {
282         EXPECT_FALSE(ipRuleExistsForRange(RULE_PRIORITY, range, "prohibit"));
283     }
284
285     // Fail to remove the rules a second time after they are already deleted.
286     binder::Status status = mNetd->networkRejectNonSecureVpn(false, uidRanges);
287     ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
288     EXPECT_EQ(ENOENT, status.serviceSpecificErrorCode());
289
290     // All rules should be the same as before.
291     EXPECT_EQ(initialRulesV4, listIpRules(IP_RULE_V4));
292     EXPECT_EQ(initialRulesV6, listIpRules(IP_RULE_V6));
293 }