1*8542734aSAndroid Build Coastguard Worker /*
2*8542734aSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*8542734aSAndroid Build Coastguard Worker *
4*8542734aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8542734aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8542734aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8542734aSAndroid Build Coastguard Worker *
8*8542734aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8542734aSAndroid Build Coastguard Worker *
10*8542734aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8542734aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8542734aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8542734aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8542734aSAndroid Build Coastguard Worker * limitations under the License.
15*8542734aSAndroid Build Coastguard Worker */
16*8542734aSAndroid Build Coastguard Worker
17*8542734aSAndroid Build Coastguard Worker #include <ifaddrs.h>
18*8542734aSAndroid Build Coastguard Worker #include <net/if.h>
19*8542734aSAndroid Build Coastguard Worker #include <sys/types.h>
20*8542734aSAndroid Build Coastguard Worker
21*8542734aSAndroid Build Coastguard Worker #include <gmock/gmock.h>
22*8542734aSAndroid Build Coastguard Worker #include <gtest/gtest.h>
23*8542734aSAndroid Build Coastguard Worker
24*8542734aSAndroid Build Coastguard Worker #include <netdutils/MockSyscalls.h>
25*8542734aSAndroid Build Coastguard Worker #include <netdutils/NetNativeTestBase.h>
26*8542734aSAndroid Build Coastguard Worker #include <netdutils/Utils.h>
27*8542734aSAndroid Build Coastguard Worker
28*8542734aSAndroid Build Coastguard Worker #include "InterfaceController.h"
29*8542734aSAndroid Build Coastguard Worker
30*8542734aSAndroid Build Coastguard Worker using testing::ByMove;
31*8542734aSAndroid Build Coastguard Worker using testing::Invoke;
32*8542734aSAndroid Build Coastguard Worker using testing::Return;
33*8542734aSAndroid Build Coastguard Worker using testing::StrictMock;
34*8542734aSAndroid Build Coastguard Worker using testing::_;
35*8542734aSAndroid Build Coastguard Worker
36*8542734aSAndroid Build Coastguard Worker namespace android {
37*8542734aSAndroid Build Coastguard Worker namespace net {
38*8542734aSAndroid Build Coastguard Worker namespace {
39*8542734aSAndroid Build Coastguard Worker
40*8542734aSAndroid Build Coastguard Worker using netdutils::Fd;
41*8542734aSAndroid Build Coastguard Worker using netdutils::getIfaceList;
42*8542734aSAndroid Build Coastguard Worker using netdutils::getIfaceNames;
43*8542734aSAndroid Build Coastguard Worker using netdutils::makeSlice;
44*8542734aSAndroid Build Coastguard Worker using netdutils::ScopedMockSyscalls;
45*8542734aSAndroid Build Coastguard Worker using netdutils::Slice;
46*8542734aSAndroid Build Coastguard Worker using netdutils::Status;
47*8542734aSAndroid Build Coastguard Worker using netdutils::statusFromErrno;
48*8542734aSAndroid Build Coastguard Worker using netdutils::StatusOr;
49*8542734aSAndroid Build Coastguard Worker using netdutils::UniqueFd;
50*8542734aSAndroid Build Coastguard Worker using netdutils::status::ok;
51*8542734aSAndroid Build Coastguard Worker
52*8542734aSAndroid Build Coastguard Worker constexpr Fd kDevRandomFd(777);
53*8542734aSAndroid Build Coastguard Worker constexpr Fd kStableSecretFd(9999);
54*8542734aSAndroid Build Coastguard Worker const char kDevRandomPath[] = "/dev/random";
55*8542734aSAndroid Build Coastguard Worker const char kTestIface[] = "wlan5";
56*8542734aSAndroid Build Coastguard Worker const char kStableSecretProperty[] = "persist.netd.stable_secret";
57*8542734aSAndroid Build Coastguard Worker const char kStableSecretPath[] = "/proc/sys/net/ipv6/conf/wlan5/stable_secret";
58*8542734aSAndroid Build Coastguard Worker const char kTestIPv6Address[] = "\x20\x01\x0d\xb8\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10";
59*8542734aSAndroid Build Coastguard Worker const char kTestIPv6AddressString[] = "2001:db8:506:708:90a:b0c:d0e:f10";
60*8542734aSAndroid Build Coastguard Worker
61*8542734aSAndroid Build Coastguard Worker // getProperty() and setProperty() are forwarded to this mock
62*8542734aSAndroid Build Coastguard Worker class MockProperties {
63*8542734aSAndroid Build Coastguard Worker public:
64*8542734aSAndroid Build Coastguard Worker MOCK_CONST_METHOD2(get, std::string(const std::string& key, const std::string& dflt));
65*8542734aSAndroid Build Coastguard Worker MOCK_CONST_METHOD2(set, Status(const std::string& key, const std::string& val));
66*8542734aSAndroid Build Coastguard Worker };
67*8542734aSAndroid Build Coastguard Worker
68*8542734aSAndroid Build Coastguard Worker } // namespace
69*8542734aSAndroid Build Coastguard Worker
70*8542734aSAndroid Build Coastguard Worker class StablePrivacyTest : public NetNativeTestBase {
71*8542734aSAndroid Build Coastguard Worker protected:
expectOpenFile(const std::string & path,const Fd fd,int err)72*8542734aSAndroid Build Coastguard Worker void expectOpenFile(const std::string& path, const Fd fd, int err) {
73*8542734aSAndroid Build Coastguard Worker if (err == 0) {
74*8542734aSAndroid Build Coastguard Worker EXPECT_CALL(mSyscalls, open(path, _, _)).WillOnce(Return(ByMove(UniqueFd(fd))));
75*8542734aSAndroid Build Coastguard Worker EXPECT_CALL(mSyscalls, close(fd)).WillOnce(Return(ok));
76*8542734aSAndroid Build Coastguard Worker } else {
77*8542734aSAndroid Build Coastguard Worker EXPECT_CALL(mSyscalls, open(path, _, _))
78*8542734aSAndroid Build Coastguard Worker .WillOnce(Return(ByMove(statusFromErrno(err, "open() failed"))));
79*8542734aSAndroid Build Coastguard Worker }
80*8542734aSAndroid Build Coastguard Worker }
81*8542734aSAndroid Build Coastguard Worker
expectReadFromDevRandom(const std::string & data)82*8542734aSAndroid Build Coastguard Worker void expectReadFromDevRandom(const std::string& data) {
83*8542734aSAndroid Build Coastguard Worker expectOpenFile(kDevRandomPath, kDevRandomFd, 0);
84*8542734aSAndroid Build Coastguard Worker EXPECT_CALL(mSyscalls, read(kDevRandomFd, _)).WillOnce(Invoke([data](Fd, const Slice buf) {
85*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(data.size(), buf.size());
86*8542734aSAndroid Build Coastguard Worker return take(buf, copy(buf, makeSlice(data)));
87*8542734aSAndroid Build Coastguard Worker }));
88*8542734aSAndroid Build Coastguard Worker }
89*8542734aSAndroid Build Coastguard Worker
expectGetPropertyDefault(const std::string & key)90*8542734aSAndroid Build Coastguard Worker void expectGetPropertyDefault(const std::string& key) {
91*8542734aSAndroid Build Coastguard Worker EXPECT_CALL(mProperties, get(key, _))
92*8542734aSAndroid Build Coastguard Worker .WillOnce(Invoke([](const std::string&, const std::string& dflt) { return dflt; }));
93*8542734aSAndroid Build Coastguard Worker }
94*8542734aSAndroid Build Coastguard Worker
expectGetProperty(const std::string & key,const std::string & val)95*8542734aSAndroid Build Coastguard Worker void expectGetProperty(const std::string& key, const std::string& val) {
96*8542734aSAndroid Build Coastguard Worker EXPECT_CALL(mProperties, get(key, _))
97*8542734aSAndroid Build Coastguard Worker .WillOnce(Invoke([val](const std::string&, const std::string&) { return val; }));
98*8542734aSAndroid Build Coastguard Worker }
99*8542734aSAndroid Build Coastguard Worker
expectSetProperty(const std::string & key,const std::string & val,Status status)100*8542734aSAndroid Build Coastguard Worker void expectSetProperty(const std::string& key, const std::string& val, Status status) {
101*8542734aSAndroid Build Coastguard Worker EXPECT_CALL(mProperties, set(key, val)).WillOnce(Return(std::move(status)));
102*8542734aSAndroid Build Coastguard Worker }
103*8542734aSAndroid Build Coastguard Worker
expectWriteToFile(const Fd fd,const std::string & val,int err)104*8542734aSAndroid Build Coastguard Worker void expectWriteToFile(const Fd fd, const std::string& val, int err) {
105*8542734aSAndroid Build Coastguard Worker EXPECT_CALL(mSyscalls, write(fd, _))
106*8542734aSAndroid Build Coastguard Worker .WillOnce(Invoke([val, err](Fd, const Slice buf) -> StatusOr<size_t> {
107*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(val, toString(buf));
108*8542734aSAndroid Build Coastguard Worker if (err) {
109*8542734aSAndroid Build Coastguard Worker return statusFromErrno(err, "write() failed");
110*8542734aSAndroid Build Coastguard Worker }
111*8542734aSAndroid Build Coastguard Worker return val.size();
112*8542734aSAndroid Build Coastguard Worker }));
113*8542734aSAndroid Build Coastguard Worker }
114*8542734aSAndroid Build Coastguard Worker
enableStablePrivacyAddresses(const std::string & iface)115*8542734aSAndroid Build Coastguard Worker Status enableStablePrivacyAddresses(const std::string& iface) {
116*8542734aSAndroid Build Coastguard Worker return InterfaceController::enableStablePrivacyAddresses(iface, mGet, mSet);
117*8542734aSAndroid Build Coastguard Worker }
118*8542734aSAndroid Build Coastguard Worker
119*8542734aSAndroid Build Coastguard Worker StrictMock<ScopedMockSyscalls> mSyscalls;
120*8542734aSAndroid Build Coastguard Worker StrictMock<MockProperties> mProperties;
121*8542734aSAndroid Build Coastguard Worker
122*8542734aSAndroid Build Coastguard Worker const std::function<std::string(const std::string&, const std::string&)> mGet =
__anon901cf00f0602(const std::string& key, const std::string& dflt) 123*8542734aSAndroid Build Coastguard Worker [this](const std::string& key, const std::string& dflt) {
124*8542734aSAndroid Build Coastguard Worker return mProperties.get(key, dflt);
125*8542734aSAndroid Build Coastguard Worker };
126*8542734aSAndroid Build Coastguard Worker const std::function<Status(const std::string&, const std::string&)> mSet =
__anon901cf00f0702(const std::string& key, const std::string& val) 127*8542734aSAndroid Build Coastguard Worker [this](const std::string& key, const std::string& val) {
128*8542734aSAndroid Build Coastguard Worker return mProperties.set(key, val);
129*8542734aSAndroid Build Coastguard Worker };
130*8542734aSAndroid Build Coastguard Worker };
131*8542734aSAndroid Build Coastguard Worker
TEST_F(StablePrivacyTest,PropertyOpenEnoent)132*8542734aSAndroid Build Coastguard Worker TEST_F(StablePrivacyTest, PropertyOpenEnoent) {
133*8542734aSAndroid Build Coastguard Worker expectOpenFile(kStableSecretPath, kStableSecretFd, ENOENT);
134*8542734aSAndroid Build Coastguard Worker EXPECT_NE(ok, enableStablePrivacyAddresses(kTestIface));
135*8542734aSAndroid Build Coastguard Worker }
136*8542734aSAndroid Build Coastguard Worker
TEST_F(StablePrivacyTest,PropertyOpenEaccess)137*8542734aSAndroid Build Coastguard Worker TEST_F(StablePrivacyTest, PropertyOpenEaccess) {
138*8542734aSAndroid Build Coastguard Worker expectOpenFile(kStableSecretPath, kStableSecretFd, EACCES);
139*8542734aSAndroid Build Coastguard Worker EXPECT_NE(ok, enableStablePrivacyAddresses(kTestIface));
140*8542734aSAndroid Build Coastguard Worker }
141*8542734aSAndroid Build Coastguard Worker
TEST_F(StablePrivacyTest,FirstBootWriteOkSetPropertyOk)142*8542734aSAndroid Build Coastguard Worker TEST_F(StablePrivacyTest, FirstBootWriteOkSetPropertyOk) {
143*8542734aSAndroid Build Coastguard Worker expectOpenFile(kStableSecretPath, kStableSecretFd, 0);
144*8542734aSAndroid Build Coastguard Worker expectGetPropertyDefault(kStableSecretProperty);
145*8542734aSAndroid Build Coastguard Worker expectReadFromDevRandom(kTestIPv6Address);
146*8542734aSAndroid Build Coastguard Worker expectWriteToFile(kStableSecretFd, kTestIPv6AddressString, 0);
147*8542734aSAndroid Build Coastguard Worker expectSetProperty(kStableSecretProperty, kTestIPv6AddressString, ok);
148*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(ok, enableStablePrivacyAddresses(kTestIface));
149*8542734aSAndroid Build Coastguard Worker }
150*8542734aSAndroid Build Coastguard Worker
TEST_F(StablePrivacyTest,FirstBootWriteOkSetPropertyFail)151*8542734aSAndroid Build Coastguard Worker TEST_F(StablePrivacyTest, FirstBootWriteOkSetPropertyFail) {
152*8542734aSAndroid Build Coastguard Worker const auto kError = statusFromErrno(EINVAL, "");
153*8542734aSAndroid Build Coastguard Worker expectOpenFile(kStableSecretPath, kStableSecretFd, 0);
154*8542734aSAndroid Build Coastguard Worker expectGetPropertyDefault(kStableSecretProperty);
155*8542734aSAndroid Build Coastguard Worker expectReadFromDevRandom(kTestIPv6Address);
156*8542734aSAndroid Build Coastguard Worker expectWriteToFile(kStableSecretFd, kTestIPv6AddressString, 0);
157*8542734aSAndroid Build Coastguard Worker expectSetProperty(kStableSecretProperty, kTestIPv6AddressString, kError);
158*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(kError, enableStablePrivacyAddresses(kTestIface));
159*8542734aSAndroid Build Coastguard Worker }
160*8542734aSAndroid Build Coastguard Worker
TEST_F(StablePrivacyTest,FirstBootWriteFail)161*8542734aSAndroid Build Coastguard Worker TEST_F(StablePrivacyTest, FirstBootWriteFail) {
162*8542734aSAndroid Build Coastguard Worker expectOpenFile(kStableSecretPath, kStableSecretFd, 0);
163*8542734aSAndroid Build Coastguard Worker expectGetPropertyDefault(kStableSecretProperty);
164*8542734aSAndroid Build Coastguard Worker expectReadFromDevRandom(kTestIPv6Address);
165*8542734aSAndroid Build Coastguard Worker expectWriteToFile(kStableSecretFd, kTestIPv6AddressString, ENOSPC);
166*8542734aSAndroid Build Coastguard Worker EXPECT_NE(ok, enableStablePrivacyAddresses(kTestIface));
167*8542734aSAndroid Build Coastguard Worker }
168*8542734aSAndroid Build Coastguard Worker
TEST_F(StablePrivacyTest,ExistingPropertyWriteOk)169*8542734aSAndroid Build Coastguard Worker TEST_F(StablePrivacyTest, ExistingPropertyWriteOk) {
170*8542734aSAndroid Build Coastguard Worker expectOpenFile(kStableSecretPath, kStableSecretFd, 0);
171*8542734aSAndroid Build Coastguard Worker expectGetProperty(kStableSecretProperty, kTestIPv6AddressString);
172*8542734aSAndroid Build Coastguard Worker expectWriteToFile(kStableSecretFd, kTestIPv6AddressString, 0);
173*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(ok, enableStablePrivacyAddresses(kTestIface));
174*8542734aSAndroid Build Coastguard Worker }
175*8542734aSAndroid Build Coastguard Worker
TEST_F(StablePrivacyTest,ExistingPropertyWriteFail)176*8542734aSAndroid Build Coastguard Worker TEST_F(StablePrivacyTest, ExistingPropertyWriteFail) {
177*8542734aSAndroid Build Coastguard Worker expectOpenFile(kStableSecretPath, kStableSecretFd, 0);
178*8542734aSAndroid Build Coastguard Worker expectGetProperty(kStableSecretProperty, kTestIPv6AddressString);
179*8542734aSAndroid Build Coastguard Worker expectWriteToFile(kStableSecretFd, kTestIPv6AddressString, EACCES);
180*8542734aSAndroid Build Coastguard Worker EXPECT_NE(ok, enableStablePrivacyAddresses(kTestIface));
181*8542734aSAndroid Build Coastguard Worker }
182*8542734aSAndroid Build Coastguard Worker
183*8542734aSAndroid Build Coastguard Worker class GetIfaceListTest : public NetNativeTestBase {};
184*8542734aSAndroid Build Coastguard Worker
TEST_F(GetIfaceListTest,IfaceNames)185*8542734aSAndroid Build Coastguard Worker TEST_F(GetIfaceListTest, IfaceNames) {
186*8542734aSAndroid Build Coastguard Worker StatusOr<std::vector<std::string>> ifaceNames = getIfaceNames();
187*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(ok, ifaceNames.status());
188*8542734aSAndroid Build Coastguard Worker struct ifaddrs *ifaddr, *ifa;
189*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(0, getifaddrs(&ifaddr));
190*8542734aSAndroid Build Coastguard Worker for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
191*8542734aSAndroid Build Coastguard Worker const auto val = std::find(
192*8542734aSAndroid Build Coastguard Worker ifaceNames.value().begin(), ifaceNames.value().end(), ifa->ifa_name);
193*8542734aSAndroid Build Coastguard Worker EXPECT_NE(ifaceNames.value().end(), val);
194*8542734aSAndroid Build Coastguard Worker }
195*8542734aSAndroid Build Coastguard Worker freeifaddrs(ifaddr);
196*8542734aSAndroid Build Coastguard Worker }
197*8542734aSAndroid Build Coastguard Worker
TEST_F(GetIfaceListTest,IfaceExist)198*8542734aSAndroid Build Coastguard Worker TEST_F(GetIfaceListTest, IfaceExist) {
199*8542734aSAndroid Build Coastguard Worker StatusOr<std::map<std::string, uint32_t>> ifaceMap = getIfaceList();
200*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(ok, ifaceMap.status());
201*8542734aSAndroid Build Coastguard Worker struct ifaddrs *ifaddr, *ifa;
202*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(0, getifaddrs(&ifaddr));
203*8542734aSAndroid Build Coastguard Worker for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
204*8542734aSAndroid Build Coastguard Worker char* ifa_name = ifa->ifa_name;
205*8542734aSAndroid Build Coastguard Worker EXPECT_NE(ifa_name, nullptr);
206*8542734aSAndroid Build Coastguard Worker uint32_t ifaceIndex = if_nametoindex(ifa_name);
207*8542734aSAndroid Build Coastguard Worker const auto ifacePair = ifaceMap.value().find(ifa->ifa_name);
208*8542734aSAndroid Build Coastguard Worker EXPECT_NE(ifaceMap.value().end(), ifacePair);
209*8542734aSAndroid Build Coastguard Worker EXPECT_EQ(ifaceIndex, ifacePair->second);
210*8542734aSAndroid Build Coastguard Worker }
211*8542734aSAndroid Build Coastguard Worker freeifaddrs(ifaddr);
212*8542734aSAndroid Build Coastguard Worker }
213*8542734aSAndroid Build Coastguard Worker
214*8542734aSAndroid Build Coastguard Worker } // namespace net
215*8542734aSAndroid Build Coastguard Worker } // namespace android
216