1 //
2 // Copyright (C) 2012 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 #include "update_engine/connection_manager.h"
18 
19 #include <set>
20 #include <string>
21 
22 #include <base/logging.h>
23 #include <brillo/any.h>
24 #include <brillo/make_unique_ptr.h>
25 #include <brillo/message_loops/fake_message_loop.h>
26 #include <brillo/variant_dictionary.h>
27 #include <gmock/gmock.h>
28 #include <gtest/gtest.h>
29 #include <shill/dbus-constants.h>
30 #include <shill/dbus-proxies.h>
31 #include <shill/dbus-proxy-mocks.h>
32 
33 #include "update_engine/common/test_utils.h"
34 #include "update_engine/fake_shill_proxy.h"
35 #include "update_engine/fake_system_state.h"
36 
37 using org::chromium::flimflam::ManagerProxyMock;
38 using org::chromium::flimflam::ServiceProxyMock;
39 using std::set;
40 using std::string;
41 using testing::Return;
42 using testing::SetArgPointee;
43 using testing::_;
44 
45 namespace chromeos_update_engine {
46 
47 class ConnectionManagerTest : public ::testing::Test {
48  public:
SetUp()49   void SetUp() override {
50     loop_.SetAsCurrent();
51     fake_system_state_.set_connection_manager(&cmut_);
52   }
53 
TearDown()54   void TearDown() override { EXPECT_FALSE(loop_.PendingTasks()); }
55 
56  protected:
57   // Sets the default_service object path in the response from the
58   // ManagerProxyMock instance.
59   void SetManagerReply(const char* default_service, bool reply_succeeds);
60 
61   // Sets the |service_type|, |physical_technology| and |service_tethering|
62   // properties in the mocked service |service_path|. If any of the three
63   // const char* is a nullptr, the corresponding property will not be included
64   // in the response.
65   void SetServiceReply(const string& service_path,
66                        const char* service_type,
67                        const char* physical_technology,
68                        const char* service_tethering);
69 
70   void TestWithServiceType(
71       const char* service_type,
72       const char* physical_technology,
73       NetworkConnectionType expected_type);
74   void TestWithServiceTethering(
75       const char* service_tethering,
76       NetworkTethering expected_tethering);
77 
78   brillo::FakeMessageLoop loop_{nullptr};
79   FakeSystemState fake_system_state_;
80   FakeShillProxy fake_shill_proxy_;
81 
82   // ConnectionManager under test.
83   ConnectionManager cmut_{&fake_shill_proxy_, &fake_system_state_};
84 };
85 
SetManagerReply(const char * default_service,bool reply_succeeds)86 void ConnectionManagerTest::SetManagerReply(const char* default_service,
87                                             bool reply_succeeds) {
88   ManagerProxyMock* manager_proxy_mock = fake_shill_proxy_.GetManagerProxy();
89   if (!reply_succeeds) {
90     EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
91         .WillOnce(Return(false));
92     return;
93   }
94 
95   // Create a dictionary of properties and optionally include the default
96   // service.
97   brillo::VariantDictionary reply_dict;
98   reply_dict["SomeOtherProperty"] = 0xC0FFEE;
99 
100   if (default_service) {
101     reply_dict[shill::kDefaultServiceProperty] =
102         dbus::ObjectPath(default_service);
103   }
104   EXPECT_CALL(*manager_proxy_mock, GetProperties(_, _, _))
105       .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));
106 }
107 
SetServiceReply(const string & service_path,const char * service_type,const char * physical_technology,const char * service_tethering)108 void ConnectionManagerTest::SetServiceReply(const string& service_path,
109                                             const char* service_type,
110                                             const char* physical_technology,
111                                             const char* service_tethering) {
112   brillo::VariantDictionary reply_dict;
113   reply_dict["SomeOtherProperty"] = 0xC0FFEE;
114 
115   if (service_type)
116     reply_dict[shill::kTypeProperty] = string(service_type);
117 
118   if (physical_technology) {
119     reply_dict[shill::kPhysicalTechnologyProperty] =
120         string(physical_technology);
121   }
122 
123   if (service_tethering)
124     reply_dict[shill::kTetheringProperty] = string(service_tethering);
125 
126   std::unique_ptr<ServiceProxyMock> service_proxy_mock(new ServiceProxyMock());
127 
128   // Plumb return value into mock object.
129   EXPECT_CALL(*service_proxy_mock.get(), GetProperties(_, _, _))
130       .WillOnce(DoAll(SetArgPointee<0>(reply_dict), Return(true)));
131 
132   fake_shill_proxy_.SetServiceForPath(dbus::ObjectPath(service_path),
133                                       std::move(service_proxy_mock));
134 }
135 
TestWithServiceType(const char * service_type,const char * physical_technology,NetworkConnectionType expected_type)136 void ConnectionManagerTest::TestWithServiceType(
137     const char* service_type,
138     const char* physical_technology,
139     NetworkConnectionType expected_type) {
140   SetManagerReply("/service/guest/network", true);
141   SetServiceReply("/service/guest/network",
142                   service_type,
143                   physical_technology,
144                   shill::kTetheringNotDetectedState);
145 
146   NetworkConnectionType type;
147   NetworkTethering tethering;
148   EXPECT_TRUE(cmut_.GetConnectionProperties(&type, &tethering));
149   EXPECT_EQ(expected_type, type);
150   testing::Mock::VerifyAndClearExpectations(
151       fake_shill_proxy_.GetManagerProxy());
152 }
153 
TestWithServiceTethering(const char * service_tethering,NetworkTethering expected_tethering)154 void ConnectionManagerTest::TestWithServiceTethering(
155     const char* service_tethering,
156     NetworkTethering expected_tethering) {
157   SetManagerReply("/service/guest/network", true);
158   SetServiceReply(
159       "/service/guest/network", shill::kTypeWifi, nullptr, service_tethering);
160 
161   NetworkConnectionType type;
162   NetworkTethering tethering;
163   EXPECT_TRUE(cmut_.GetConnectionProperties(&type, &tethering));
164   EXPECT_EQ(expected_tethering, tethering);
165   testing::Mock::VerifyAndClearExpectations(
166       fake_shill_proxy_.GetManagerProxy());
167 }
168 
TEST_F(ConnectionManagerTest,SimpleTest)169 TEST_F(ConnectionManagerTest, SimpleTest) {
170   TestWithServiceType(shill::kTypeEthernet, nullptr,
171                       NetworkConnectionType::kEthernet);
172   TestWithServiceType(shill::kTypeWifi, nullptr,
173                       NetworkConnectionType::kWifi);
174   TestWithServiceType(shill::kTypeWimax, nullptr,
175                       NetworkConnectionType::kWimax);
176   TestWithServiceType(shill::kTypeBluetooth, nullptr,
177                       NetworkConnectionType::kBluetooth);
178   TestWithServiceType(shill::kTypeCellular, nullptr,
179                       NetworkConnectionType::kCellular);
180 }
181 
TEST_F(ConnectionManagerTest,PhysicalTechnologyTest)182 TEST_F(ConnectionManagerTest, PhysicalTechnologyTest) {
183   TestWithServiceType(shill::kTypeVPN, nullptr,
184                       NetworkConnectionType::kUnknown);
185   TestWithServiceType(shill::kTypeVPN, shill::kTypeVPN,
186                       NetworkConnectionType::kUnknown);
187   TestWithServiceType(shill::kTypeVPN, shill::kTypeWifi,
188                       NetworkConnectionType::kWifi);
189   TestWithServiceType(shill::kTypeVPN, shill::kTypeWimax,
190                       NetworkConnectionType::kWimax);
191 }
192 
TEST_F(ConnectionManagerTest,TetheringTest)193 TEST_F(ConnectionManagerTest, TetheringTest) {
194   TestWithServiceTethering(shill::kTetheringConfirmedState,
195                            NetworkTethering::kConfirmed);
196   TestWithServiceTethering(shill::kTetheringNotDetectedState,
197                            NetworkTethering::kNotDetected);
198   TestWithServiceTethering(shill::kTetheringSuspectedState,
199                            NetworkTethering::kSuspected);
200   TestWithServiceTethering("I'm not a valid property value =)",
201                            NetworkTethering::kUnknown);
202 }
203 
TEST_F(ConnectionManagerTest,UnknownTest)204 TEST_F(ConnectionManagerTest, UnknownTest) {
205   TestWithServiceType("foo", nullptr, NetworkConnectionType::kUnknown);
206 }
207 
TEST_F(ConnectionManagerTest,AllowUpdatesOverEthernetTest)208 TEST_F(ConnectionManagerTest, AllowUpdatesOverEthernetTest) {
209   // Updates over Ethernet are allowed even if there's no policy.
210   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
211                                         NetworkTethering::kUnknown));
212 }
213 
TEST_F(ConnectionManagerTest,AllowUpdatesOverWifiTest)214 TEST_F(ConnectionManagerTest, AllowUpdatesOverWifiTest) {
215   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
216                                         NetworkTethering::kUnknown));
217 }
218 
TEST_F(ConnectionManagerTest,AllowUpdatesOverWimaxTest)219 TEST_F(ConnectionManagerTest, AllowUpdatesOverWimaxTest) {
220   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWimax,
221                                         NetworkTethering::kUnknown));
222 }
223 
TEST_F(ConnectionManagerTest,BlockUpdatesOverBluetoothTest)224 TEST_F(ConnectionManagerTest, BlockUpdatesOverBluetoothTest) {
225   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kBluetooth,
226                                          NetworkTethering::kUnknown));
227 }
228 
TEST_F(ConnectionManagerTest,AllowUpdatesOnlyOver3GPerPolicyTest)229 TEST_F(ConnectionManagerTest, AllowUpdatesOnlyOver3GPerPolicyTest) {
230   policy::MockDevicePolicy allow_3g_policy;
231 
232   fake_system_state_.set_device_policy(&allow_3g_policy);
233 
234   // This test tests cellular (3G) being the only connection type being allowed.
235   set<string> allowed_set;
236   allowed_set.insert(
237       cmut_.StringForConnectionType(NetworkConnectionType::kCellular));
238 
239   EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
240       .Times(1)
241       .WillOnce(DoAll(SetArgPointee<0>(allowed_set), Return(true)));
242 
243   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
244                                         NetworkTethering::kUnknown));
245 }
246 
TEST_F(ConnectionManagerTest,AllowUpdatesOver3GAndOtherTypesPerPolicyTest)247 TEST_F(ConnectionManagerTest, AllowUpdatesOver3GAndOtherTypesPerPolicyTest) {
248   policy::MockDevicePolicy allow_3g_policy;
249 
250   fake_system_state_.set_device_policy(&allow_3g_policy);
251 
252   // This test tests multiple connection types being allowed, with
253   // 3G one among them. Only Cellular is currently enforced by the policy
254   // setting, the others are ignored (see Bluetooth for example).
255   set<string> allowed_set;
256   allowed_set.insert(
257       cmut_.StringForConnectionType(NetworkConnectionType::kCellular));
258   allowed_set.insert(
259       cmut_.StringForConnectionType(NetworkConnectionType::kBluetooth));
260 
261   EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
262       .Times(3)
263       .WillRepeatedly(DoAll(SetArgPointee<0>(allowed_set), Return(true)));
264 
265   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
266                                         NetworkTethering::kUnknown));
267   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
268                                         NetworkTethering::kNotDetected));
269   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
270                                         NetworkTethering::kUnknown));
271   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
272                                         NetworkTethering::kUnknown));
273   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWimax,
274                                         NetworkTethering::kUnknown));
275   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kBluetooth,
276                                          NetworkTethering::kUnknown));
277 
278   // Tethered networks are treated in the same way as Cellular networks and
279   // thus allowed.
280   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
281                                         NetworkTethering::kConfirmed));
282   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
283                                         NetworkTethering::kConfirmed));
284 }
285 
TEST_F(ConnectionManagerTest,BlockUpdatesOverCellularByDefaultTest)286 TEST_F(ConnectionManagerTest, BlockUpdatesOverCellularByDefaultTest) {
287   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
288                                          NetworkTethering::kUnknown));
289 }
290 
TEST_F(ConnectionManagerTest,BlockUpdatesOverTetheredNetworkByDefaultTest)291 TEST_F(ConnectionManagerTest, BlockUpdatesOverTetheredNetworkByDefaultTest) {
292   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
293                                          NetworkTethering::kConfirmed));
294   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kEthernet,
295                                          NetworkTethering::kConfirmed));
296   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kWifi,
297                                         NetworkTethering::kSuspected));
298 }
299 
TEST_F(ConnectionManagerTest,BlockUpdatesOver3GPerPolicyTest)300 TEST_F(ConnectionManagerTest, BlockUpdatesOver3GPerPolicyTest) {
301   policy::MockDevicePolicy block_3g_policy;
302 
303   fake_system_state_.set_device_policy(&block_3g_policy);
304 
305   // Test that updates for 3G are blocked while updates are allowed
306   // over several other types.
307   set<string> allowed_set;
308   allowed_set.insert(
309       cmut_.StringForConnectionType(NetworkConnectionType::kEthernet));
310   allowed_set.insert(
311       cmut_.StringForConnectionType(NetworkConnectionType::kWifi));
312   allowed_set.insert(
313       cmut_.StringForConnectionType(NetworkConnectionType::kWimax));
314 
315   EXPECT_CALL(block_3g_policy, GetAllowedConnectionTypesForUpdate(_))
316       .Times(1)
317       .WillOnce(DoAll(SetArgPointee<0>(allowed_set), Return(true)));
318 
319   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
320                                          NetworkTethering::kUnknown));
321 }
322 
TEST_F(ConnectionManagerTest,BlockUpdatesOver3GIfErrorInPolicyFetchTest)323 TEST_F(ConnectionManagerTest, BlockUpdatesOver3GIfErrorInPolicyFetchTest) {
324   policy::MockDevicePolicy allow_3g_policy;
325 
326   fake_system_state_.set_device_policy(&allow_3g_policy);
327 
328   set<string> allowed_set;
329   allowed_set.insert(
330       cmut_.StringForConnectionType(NetworkConnectionType::kCellular));
331 
332   // Return false for GetAllowedConnectionTypesForUpdate and see
333   // that updates are still blocked for 3G despite the value being in
334   // the string set above.
335   EXPECT_CALL(allow_3g_policy, GetAllowedConnectionTypesForUpdate(_))
336       .Times(1)
337       .WillOnce(DoAll(SetArgPointee<0>(allowed_set), Return(false)));
338 
339   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
340                                          NetworkTethering::kUnknown));
341 }
342 
TEST_F(ConnectionManagerTest,UseUserPrefForUpdatesOverCellularIfNoPolicyTest)343 TEST_F(ConnectionManagerTest, UseUserPrefForUpdatesOverCellularIfNoPolicyTest) {
344   policy::MockDevicePolicy no_policy;
345   testing::NiceMock<MockPrefs>* prefs = fake_system_state_.mock_prefs();
346 
347   fake_system_state_.set_device_policy(&no_policy);
348 
349   // No setting enforced by the device policy, user prefs should be used.
350   EXPECT_CALL(no_policy, GetAllowedConnectionTypesForUpdate(_))
351       .Times(3)
352       .WillRepeatedly(Return(false));
353 
354   // No user pref: block.
355   EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
356       .Times(1)
357       .WillOnce(Return(false));
358   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
359                                          NetworkTethering::kUnknown));
360 
361   // Allow per user pref.
362   EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
363       .Times(1)
364       .WillOnce(Return(true));
365   EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
366       .Times(1)
367       .WillOnce(DoAll(SetArgPointee<1>(true), Return(true)));
368   EXPECT_TRUE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
369                                         NetworkTethering::kUnknown));
370 
371   // Block per user pref.
372   EXPECT_CALL(*prefs, Exists(kPrefsUpdateOverCellularPermission))
373       .Times(1)
374       .WillOnce(Return(true));
375   EXPECT_CALL(*prefs, GetBoolean(kPrefsUpdateOverCellularPermission, _))
376       .Times(1)
377       .WillOnce(DoAll(SetArgPointee<1>(false), Return(true)));
378   EXPECT_FALSE(cmut_.IsUpdateAllowedOver(NetworkConnectionType::kCellular,
379                                          NetworkTethering::kUnknown));
380 }
381 
TEST_F(ConnectionManagerTest,StringForConnectionTypeTest)382 TEST_F(ConnectionManagerTest, StringForConnectionTypeTest) {
383   EXPECT_STREQ(shill::kTypeEthernet,
384                cmut_.StringForConnectionType(NetworkConnectionType::kEthernet));
385   EXPECT_STREQ(shill::kTypeWifi,
386                cmut_.StringForConnectionType(NetworkConnectionType::kWifi));
387   EXPECT_STREQ(shill::kTypeWimax,
388                cmut_.StringForConnectionType(NetworkConnectionType::kWimax));
389   EXPECT_STREQ(shill::kTypeBluetooth,
390                cmut_.StringForConnectionType(
391                    NetworkConnectionType::kBluetooth));
392   EXPECT_STREQ(shill::kTypeCellular,
393                cmut_.StringForConnectionType(NetworkConnectionType::kCellular));
394   EXPECT_STREQ("Unknown",
395                cmut_.StringForConnectionType(NetworkConnectionType::kUnknown));
396   EXPECT_STREQ("Unknown",
397                cmut_.StringForConnectionType(
398                    static_cast<NetworkConnectionType>(999999)));
399 }
400 
TEST_F(ConnectionManagerTest,MalformedServiceList)401 TEST_F(ConnectionManagerTest, MalformedServiceList) {
402   SetManagerReply("/service/guest/network", false);
403 
404   NetworkConnectionType type;
405   NetworkTethering tethering;
406   EXPECT_FALSE(cmut_.GetConnectionProperties(&type, &tethering));
407 }
408 
409 }  // namespace chromeos_update_engine
410