blob: 5067979afb4cc5a41260da954fadc2eb733b95fc [file] [log] [blame]
Darin Petkov33af05c2012-02-28 10:10:30 +01001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/openvpn_driver.h"
6
Darin Petkova9b1fed2012-02-29 11:49:05 +01007#include <algorithm>
8
Paul Stewart291a4732012-03-14 19:19:02 -07009#include <base/file_path.h>
10#include <base/file_util.h>
11#include <base/string_util.h>
Darin Petkovfe6a9372012-02-28 16:25:06 +010012#include <chromeos/dbus/service_constants.h>
Darin Petkov33af05c2012-02-28 10:10:30 +010013#include <gtest/gtest.h>
14
Paul Stewartebd38562012-03-23 13:06:40 -070015#include "shill/dbus_adaptor.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010016#include "shill/error.h"
Darin Petkov14c29ec2012-03-02 11:34:19 +010017#include "shill/ipconfig.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070018#include "shill/logging.h"
Darin Petkova9b1fed2012-02-29 11:49:05 +010019#include "shill/mock_adaptors.h"
Paul Stewartca6abd42012-03-01 15:45:29 -080020#include "shill/mock_device_info.h"
Darin Petkovf20994f2012-03-05 16:12:19 +010021#include "shill/mock_glib.h"
22#include "shill/mock_manager.h"
23#include "shill/mock_metrics.h"
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020024#include "shill/mock_nss.h"
Darin Petkov46463022012-03-29 14:57:32 +020025#include "shill/mock_openvpn_management_server.h"
Darin Petkov5a850472012-06-06 15:44:24 +020026#include "shill/mock_process_killer.h"
Darin Petkova5e07ef2012-07-09 14:27:57 +020027#include "shill/mock_service.h"
Darin Petkovf3c71d72012-03-21 12:32:15 +010028#include "shill/mock_store.h"
Darin Petkov36a3ace2012-03-06 17:22:14 +010029#include "shill/mock_vpn.h"
Darin Petkov79d74c92012-03-07 17:20:32 +010030#include "shill/mock_vpn_service.h"
Darin Petkova9b1fed2012-02-29 11:49:05 +010031#include "shill/nice_mock_control.h"
Paul Stewart8e7e4592012-04-29 09:47:48 -070032#include "shill/property_store_inspector.h"
Darin Petkova9b1fed2012-02-29 11:49:05 +010033#include "shill/rpc_task.h"
Darin Petkovf20994f2012-03-05 16:12:19 +010034#include "shill/vpn.h"
Darin Petkov79d74c92012-03-07 17:20:32 +010035#include "shill/vpn_service.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010036
Darin Petkov5a850472012-06-06 15:44:24 +020037using base::WeakPtr;
Darin Petkova9b1fed2012-02-29 11:49:05 +010038using std::map;
Darin Petkovfe6a9372012-02-28 16:25:06 +010039using std::string;
40using std::vector;
Paul Stewartca6abd42012-03-01 15:45:29 -080041using testing::_;
Darin Petkovf3c71d72012-03-21 12:32:15 +010042using testing::AnyNumber;
Paul Stewartca6abd42012-03-01 15:45:29 -080043using testing::DoAll;
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020044using testing::ElementsAreArray;
Darin Petkove8587e32012-07-02 13:56:07 +020045using testing::Field;
Darin Petkovf3c71d72012-03-21 12:32:15 +010046using testing::Ne;
Paul Stewartce4ec192012-03-14 12:53:46 -070047using testing::NiceMock;
Paul Stewartca6abd42012-03-01 15:45:29 -080048using testing::Return;
49using testing::SetArgumentPointee;
Paul Stewartce4ec192012-03-14 12:53:46 -070050using testing::StrictMock;
Darin Petkovfe6a9372012-02-28 16:25:06 +010051
Darin Petkov33af05c2012-02-28 10:10:30 +010052namespace shill {
53
Darin Petkova9b1fed2012-02-29 11:49:05 +010054class OpenVPNDriverTest : public testing::Test,
55 public RPCTaskDelegate {
Darin Petkov33af05c2012-02-28 10:10:30 +010056 public:
Darin Petkovfe6a9372012-02-28 16:25:06 +010057 OpenVPNDriverTest()
Darin Petkov0e9735d2012-04-24 12:33:45 +020058 : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
Darin Petkovf20994f2012-03-05 16:12:19 +010059 manager_(&control_, &dispatcher_, &metrics_, &glib_),
Darin Petkov79d74c92012-03-07 17:20:32 +010060 driver_(new OpenVPNDriver(&control_, &dispatcher_, &metrics_, &manager_,
Paul Stewart451aa7f2012-04-11 19:07:58 -070061 &device_info_, &glib_)),
Darin Petkov79d74c92012-03-07 17:20:32 +010062 service_(new MockVPNService(&control_, &dispatcher_, &metrics_,
63 &manager_, driver_)),
64 device_(new MockVPN(&control_, &dispatcher_, &metrics_, &manager_,
Darin Petkov46463022012-03-29 14:57:32 +020065 kInterfaceName, kInterfaceIndex)),
66 management_server_(new NiceMock<MockOpenVPNManagementServer>()) {
67 driver_->management_server_.reset(management_server_);
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020068 driver_->nss_ = &nss_;
Darin Petkov5a850472012-06-06 15:44:24 +020069 driver_->process_killer_ = &process_killer_;
Darin Petkov46463022012-03-29 14:57:32 +020070 }
Darin Petkovfe6a9372012-02-28 16:25:06 +010071
Darin Petkov33af05c2012-02-28 10:10:30 +010072 virtual ~OpenVPNDriverTest() {}
73
Darin Petkov36a3ace2012-03-06 17:22:14 +010074 virtual void TearDown() {
Darin Petkova5e07ef2012-07-09 14:27:57 +020075 driver_->default_service_callback_tag_ = 0;
Darin Petkov79d74c92012-03-07 17:20:32 +010076 driver_->child_watch_tag_ = 0;
77 driver_->pid_ = 0;
78 driver_->device_ = NULL;
79 driver_->service_ = NULL;
Darin Petkov1a462de2012-05-02 11:10:48 +020080 if (!lsb_release_file_.empty()) {
81 EXPECT_TRUE(file_util::Delete(lsb_release_file_, false));
82 lsb_release_file_.clear();
83 }
Darin Petkov36a3ace2012-03-06 17:22:14 +010084 }
Darin Petkova9b1fed2012-02-29 11:49:05 +010085
Darin Petkov33af05c2012-02-28 10:10:30 +010086 protected:
Darin Petkovfe6a9372012-02-28 16:25:06 +010087 static const char kOption[];
88 static const char kProperty[];
89 static const char kValue[];
90 static const char kOption2[];
91 static const char kProperty2[];
92 static const char kValue2[];
Darin Petkov60596742012-03-05 12:17:17 +010093 static const char kGateway1[];
94 static const char kNetmask1[];
95 static const char kNetwork1[];
96 static const char kGateway2[];
97 static const char kNetmask2[];
98 static const char kNetwork2[];
Darin Petkov79d74c92012-03-07 17:20:32 +010099 static const char kInterfaceName[];
100 static const int kInterfaceIndex;
Darin Petkovfe6a9372012-02-28 16:25:06 +0100101
Darin Petkovb451d6e2012-04-23 11:56:41 +0200102 void SetArg(const string &arg, const string &value) {
103 driver_->args()->SetString(arg, value);
Darin Petkovfe6a9372012-02-28 16:25:06 +0100104 }
105
Darin Petkovf3c71d72012-03-21 12:32:15 +0100106 KeyValueStore *GetArgs() {
Darin Petkovb451d6e2012-04-23 11:56:41 +0200107 return driver_->args();
Darin Petkovf3c71d72012-03-21 12:32:15 +0100108 }
109
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200110 void RemoveStringArg(const string &arg) {
111 driver_->args()->RemoveString(arg);
112 }
113
Paul Stewartca6abd42012-03-01 15:45:29 -0800114 // Used to assert that a flag appears in the options.
115 void ExpectInFlags(const vector<string> &options, const string &flag,
116 const string &value);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200117 void ExpectInFlags(const vector<string> &options, const string &flag);
118 void ExpectNotInFlags(const vector<string> &options, const string &flag);
Paul Stewartca6abd42012-03-01 15:45:29 -0800119
Darin Petkov1a462de2012-05-02 11:10:48 +0200120 void SetupLSBRelease();
121
Darin Petkov36a3ace2012-03-06 17:22:14 +0100122 // Inherited from RPCTaskDelegate.
Darin Petkov209e6292012-04-20 11:33:32 +0200123 virtual void GetLogin(string *user, string *password);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100124 virtual void Notify(const string &reason, const map<string, string> &dict);
Paul Stewartca6abd42012-03-01 15:45:29 -0800125
Darin Petkova9b1fed2012-02-29 11:49:05 +0100126 NiceMockControl control_;
Darin Petkov0e9735d2012-04-24 12:33:45 +0200127 NiceMock<MockDeviceInfo> device_info_;
Darin Petkovf20994f2012-03-05 16:12:19 +0100128 EventDispatcher dispatcher_;
129 MockMetrics metrics_;
130 MockGLib glib_;
131 MockManager manager_;
Darin Petkov46463022012-03-29 14:57:32 +0200132 OpenVPNDriver *driver_; // Owned by |service_|.
Darin Petkov79d74c92012-03-07 17:20:32 +0100133 scoped_refptr<MockVPNService> service_;
134 scoped_refptr<MockVPN> device_;
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200135 MockNSS nss_;
Darin Petkov5a850472012-06-06 15:44:24 +0200136 MockProcessKiller process_killer_;
Darin Petkov46463022012-03-29 14:57:32 +0200137
138 // Owned by |driver_|.
139 NiceMock<MockOpenVPNManagementServer> *management_server_;
Darin Petkov1a462de2012-05-02 11:10:48 +0200140
141 FilePath lsb_release_file_;
Darin Petkov33af05c2012-02-28 10:10:30 +0100142};
143
Darin Petkovfe6a9372012-02-28 16:25:06 +0100144const char OpenVPNDriverTest::kOption[] = "--openvpn-option";
145const char OpenVPNDriverTest::kProperty[] = "OpenVPN.SomeProperty";
146const char OpenVPNDriverTest::kValue[] = "some-property-value";
147const char OpenVPNDriverTest::kOption2[] = "--openvpn-option2";
148const char OpenVPNDriverTest::kProperty2[] = "OpenVPN.SomeProperty2";
149const char OpenVPNDriverTest::kValue2[] = "some-property-value2";
Darin Petkov60596742012-03-05 12:17:17 +0100150const char OpenVPNDriverTest::kGateway1[] = "10.242.2.13";
151const char OpenVPNDriverTest::kNetmask1[] = "255.255.255.255";
152const char OpenVPNDriverTest::kNetwork1[] = "10.242.2.1";
153const char OpenVPNDriverTest::kGateway2[] = "10.242.2.14";
154const char OpenVPNDriverTest::kNetmask2[] = "255.255.0.0";
155const char OpenVPNDriverTest::kNetwork2[] = "192.168.0.0";
Darin Petkov79d74c92012-03-07 17:20:32 +0100156const char OpenVPNDriverTest::kInterfaceName[] = "tun0";
157const int OpenVPNDriverTest::kInterfaceIndex = 123;
Darin Petkovfe6a9372012-02-28 16:25:06 +0100158
Darin Petkov209e6292012-04-20 11:33:32 +0200159void OpenVPNDriverTest::GetLogin(string */*user*/, string */*password*/) {}
160
Darin Petkova9b1fed2012-02-29 11:49:05 +0100161void OpenVPNDriverTest::Notify(const string &/*reason*/,
162 const map<string, string> &/*dict*/) {}
163
Paul Stewartca6abd42012-03-01 15:45:29 -0800164void OpenVPNDriverTest::ExpectInFlags(const vector<string> &options,
165 const string &flag,
166 const string &value) {
167 vector<string>::const_iterator it =
168 std::find(options.begin(), options.end(), flag);
169
170 EXPECT_TRUE(it != options.end());
171 if (it != options.end())
Darin Petkov36a3ace2012-03-06 17:22:14 +0100172 return; // Don't crash below.
Paul Stewartca6abd42012-03-01 15:45:29 -0800173 it++;
174 EXPECT_TRUE(it != options.end());
175 if (it != options.end())
Darin Petkov36a3ace2012-03-06 17:22:14 +0100176 return; // Don't crash below.
Paul Stewartca6abd42012-03-01 15:45:29 -0800177 EXPECT_EQ(value, *it);
178}
179
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200180void OpenVPNDriverTest::ExpectInFlags(const vector<string> &options,
181 const string &flag) {
182 EXPECT_TRUE(std::find(options.begin(), options.end(), flag) !=
183 options.end());
184}
185
186void OpenVPNDriverTest::ExpectNotInFlags(const vector<string> &options,
187 const string &flag) {
188 EXPECT_TRUE(std::find(options.begin(), options.end(), flag) ==
189 options.end());
190}
191
Darin Petkov1a462de2012-05-02 11:10:48 +0200192void OpenVPNDriverTest::SetupLSBRelease() {
193 static const char kLSBReleaseContents[] =
194 "\n"
195 "=\n"
196 "foo=\n"
197 "=bar\n"
198 "zoo==\n"
199 "CHROMEOS_RELEASE_BOARD=x86-alex\n"
200 "CHROMEOS_RELEASE_NAME=Chromium OS\n"
201 "CHROMEOS_RELEASE_VERSION=2202.0\n";
202 EXPECT_TRUE(file_util::CreateTemporaryFile(&lsb_release_file_));
203 EXPECT_EQ(arraysize(kLSBReleaseContents),
204 file_util::WriteFile(lsb_release_file_,
205 kLSBReleaseContents,
206 arraysize(kLSBReleaseContents)));
207 EXPECT_EQ(OpenVPNDriver::kLSBReleaseFile, driver_->lsb_release_file_.value());
208 driver_->lsb_release_file_ = lsb_release_file_;
209}
210
Darin Petkov33af05c2012-02-28 10:10:30 +0100211TEST_F(OpenVPNDriverTest, Connect) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100212 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
213 const string interface = kInterfaceName;
Darin Petkovf20994f2012-03-05 16:12:19 +0100214 EXPECT_CALL(device_info_, CreateTunnelInterface(_))
Darin Petkov79d74c92012-03-07 17:20:32 +0100215 .WillOnce(DoAll(SetArgumentPointee<0>(interface), Return(true)));
216 Error error;
217 driver_->Connect(service_, &error);
218 EXPECT_TRUE(error.IsSuccess());
219 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
Darin Petkov602303f2012-06-06 12:15:59 +0200220 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov79d74c92012-03-07 17:20:32 +0100221}
222
223TEST_F(OpenVPNDriverTest, ConnectTunnelFailure) {
224 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200225 EXPECT_CALL(device_info_, CreateTunnelInterface(_)).WillOnce(Return(false));
Darin Petkov79d74c92012-03-07 17:20:32 +0100226 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
227 Error error;
228 driver_->Connect(service_, &error);
229 EXPECT_EQ(Error::kInternalError, error.type());
230 EXPECT_TRUE(driver_->tunnel_interface_.empty());
Darin Petkov602303f2012-06-06 12:15:59 +0200231 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov33af05c2012-02-28 10:10:30 +0100232}
233
Darin Petkov0e9735d2012-04-24 12:33:45 +0200234namespace {
235MATCHER_P(IsIPAddress, address, "") {
236 IPAddress ip_address(IPAddress::kFamilyIPv4);
237 EXPECT_TRUE(ip_address.SetAddressFromString(address));
238 return ip_address.Equals(arg);
239}
240} // namespace
241
Darin Petkov14c29ec2012-03-02 11:34:19 +0100242TEST_F(OpenVPNDriverTest, Notify) {
Darin Petkov0e9735d2012-04-24 12:33:45 +0200243 map<string, string> config;
Darin Petkov79d74c92012-03-07 17:20:32 +0100244 driver_->device_ = device_;
Darin Petkov602303f2012-06-06 12:15:59 +0200245 driver_->StartConnectTimeout();
Darin Petkove8587e32012-07-02 13:56:07 +0200246 EXPECT_CALL(*device_,
247 UpdateIPConfig(Field(&IPConfig::Properties::address, "")));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200248 driver_->Notify("up", config);
Darin Petkov602303f2012-06-06 12:15:59 +0200249 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkove8587e32012-07-02 13:56:07 +0200250
251 // Tests that existing properties are reused if no new ones provided.
252 IPConfigRefPtr ipconfig(new IPConfig(&control_, device_->link_name()));
253 IPConfig::Properties props;
254 props.address = "1.2.3.4";
255 ipconfig->set_properties(props);
256 device_->set_ipconfig(ipconfig);
257 EXPECT_CALL(*device_,
258 UpdateIPConfig(Field(&IPConfig::Properties::address, "1.2.3.4")));
259 driver_->Notify("up", config);
Darin Petkov79d74c92012-03-07 17:20:32 +0100260}
261
262TEST_F(OpenVPNDriverTest, NotifyFail) {
263 map<string, string> dict;
264 driver_->device_ = device_;
Darin Petkov602303f2012-06-06 12:15:59 +0200265 driver_->StartConnectTimeout();
Darin Petkov79d74c92012-03-07 17:20:32 +0100266 EXPECT_CALL(*device_, OnDisconnected());
267 driver_->Notify("fail", dict);
Darin Petkov602303f2012-06-06 12:15:59 +0200268 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100269}
270
Darin Petkov60596742012-03-05 12:17:17 +0100271TEST_F(OpenVPNDriverTest, GetRouteOptionEntry) {
272 OpenVPNDriver::RouteOptions routes;
273 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "bar", &routes));
274 EXPECT_TRUE(routes.empty());
275 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "foo", &routes));
276 EXPECT_TRUE(routes.empty());
277 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "fooZ", &routes));
278 EXPECT_TRUE(routes.empty());
279 IPConfig::Route *route =
280 OpenVPNDriver::GetRouteOptionEntry("foo", "foo12", &routes);
281 EXPECT_EQ(1, routes.size());
282 EXPECT_EQ(route, &routes[12]);
283 route = OpenVPNDriver::GetRouteOptionEntry("foo", "foo13", &routes);
284 EXPECT_EQ(2, routes.size());
285 EXPECT_EQ(route, &routes[13]);
286}
287
288TEST_F(OpenVPNDriverTest, ParseRouteOption) {
289 OpenVPNDriver::RouteOptions routes;
290 OpenVPNDriver::ParseRouteOption("foo", "bar", &routes);
291 EXPECT_TRUE(routes.empty());
292 OpenVPNDriver::ParseRouteOption("gateway_2", kGateway2, &routes);
293 OpenVPNDriver::ParseRouteOption("netmask_2", kNetmask2, &routes);
294 OpenVPNDriver::ParseRouteOption("network_2", kNetwork2, &routes);
295 EXPECT_EQ(1, routes.size());
296 OpenVPNDriver::ParseRouteOption("gateway_1", kGateway1, &routes);
297 OpenVPNDriver::ParseRouteOption("netmask_1", kNetmask1, &routes);
298 OpenVPNDriver::ParseRouteOption("network_1", kNetwork1, &routes);
299 EXPECT_EQ(2, routes.size());
300 EXPECT_EQ(kGateway1, routes[1].gateway);
301 EXPECT_EQ(kNetmask1, routes[1].netmask);
302 EXPECT_EQ(kNetwork1, routes[1].host);
303 EXPECT_EQ(kGateway2, routes[2].gateway);
304 EXPECT_EQ(kNetmask2, routes[2].netmask);
305 EXPECT_EQ(kNetwork2, routes[2].host);
306}
307
308TEST_F(OpenVPNDriverTest, SetRoutes) {
309 OpenVPNDriver::RouteOptions routes;
310 routes[1].gateway = "1.2.3.4";
311 routes[1].host= "1.2.3.4";
312 routes[2].host = "2.3.4.5";
313 routes[2].netmask = "255.0.0.0";
314 routes[3].netmask = "255.0.0.0";
315 routes[3].gateway = "1.2.3.5";
316 routes[5].host = kNetwork2;
317 routes[5].netmask = kNetmask2;
318 routes[5].gateway = kGateway2;
319 routes[4].host = kNetwork1;
320 routes[4].netmask = kNetmask1;
321 routes[4].gateway = kGateway1;
322 IPConfig::Properties props;
323 OpenVPNDriver::SetRoutes(routes, &props);
324 ASSERT_EQ(2, props.routes.size());
325 EXPECT_EQ(kGateway1, props.routes[0].gateway);
326 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
327 EXPECT_EQ(kNetwork1, props.routes[0].host);
328 EXPECT_EQ(kGateway2, props.routes[1].gateway);
329 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
330 EXPECT_EQ(kNetwork2, props.routes[1].host);
Darin Petkove8587e32012-07-02 13:56:07 +0200331
332 // Tests that the routes are not reset if no new routes are supplied.
333 OpenVPNDriver::SetRoutes(OpenVPNDriver::RouteOptions(), &props);
334 EXPECT_EQ(2, props.routes.size());
Darin Petkov60596742012-03-05 12:17:17 +0100335}
336
Darin Petkov4b944842012-09-21 10:48:48 +0200337TEST_F(OpenVPNDriverTest, SplitPortFromHost) {
338 string name, port;
339 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", NULL, NULL));
340 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", &name, &port));
341 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com", &name, &port));
342 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:", &name, &port));
343 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost(":1234", &name, &port));
344 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:f:1234", &name, &port));
345 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:x", &name, &port));
346 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:-1", &name, &port));
347 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:+1", &name, &port));
348 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:65536", &name, &port));
349 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("v.com:0", &name, &port));
350 EXPECT_EQ("v.com", name);
351 EXPECT_EQ("0", port);
352 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("w.com:65535", &name, &port));
353 EXPECT_EQ("w.com", name);
354 EXPECT_EQ("65535", port);
355 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("x.com:12345", &name, &port));
356 EXPECT_EQ("x.com", name);
357 EXPECT_EQ("12345", port);
358}
359
Darin Petkov14c29ec2012-03-02 11:34:19 +0100360TEST_F(OpenVPNDriverTest, ParseForeignOption) {
Darin Petkove8587e32012-07-02 13:56:07 +0200361 vector<string> domain_search;
362 vector<string> dns_servers;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100363 IPConfig::Properties props;
Darin Petkove8587e32012-07-02 13:56:07 +0200364 OpenVPNDriver::ParseForeignOption("", &domain_search, &dns_servers);
365 OpenVPNDriver::ParseForeignOption(
366 "dhcp-option DOMAIN", &domain_search, &dns_servers);
367 OpenVPNDriver::ParseForeignOption(
368 "dhcp-option DOMAIN zzz.com foo", &domain_search, &dns_servers);
369 OpenVPNDriver::ParseForeignOption(
370 "dhcp-Option DOmAIN xyz.com", &domain_search, &dns_servers);
371 ASSERT_EQ(1, domain_search.size());
372 EXPECT_EQ("xyz.com", domain_search[0]);
373 OpenVPNDriver::ParseForeignOption(
374 "dhcp-option DnS 1.2.3.4", &domain_search, &dns_servers);
375 ASSERT_EQ(1, dns_servers.size());
376 EXPECT_EQ("1.2.3.4", dns_servers[0]);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100377}
378
379TEST_F(OpenVPNDriverTest, ParseForeignOptions) {
Darin Petkove8587e32012-07-02 13:56:07 +0200380 // This also tests that std::map is a sorted container.
Darin Petkov14c29ec2012-03-02 11:34:19 +0100381 map<int, string> options;
382 options[5] = "dhcp-option DOMAIN five.com";
383 options[2] = "dhcp-option DOMAIN two.com";
384 options[8] = "dhcp-option DOMAIN eight.com";
385 options[7] = "dhcp-option DOMAIN seven.com";
386 options[4] = "dhcp-option DOMAIN four.com";
Darin Petkove8587e32012-07-02 13:56:07 +0200387 options[10] = "dhcp-option dns 1.2.3.4";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100388 IPConfig::Properties props;
389 OpenVPNDriver::ParseForeignOptions(options, &props);
390 ASSERT_EQ(5, props.domain_search.size());
391 EXPECT_EQ("two.com", props.domain_search[0]);
392 EXPECT_EQ("four.com", props.domain_search[1]);
393 EXPECT_EQ("five.com", props.domain_search[2]);
394 EXPECT_EQ("seven.com", props.domain_search[3]);
395 EXPECT_EQ("eight.com", props.domain_search[4]);
Darin Petkove8587e32012-07-02 13:56:07 +0200396 ASSERT_EQ(1, props.dns_servers.size());
397 EXPECT_EQ("1.2.3.4", props.dns_servers[0]);
398
399 // Test that the DNS properties are not updated if no new DNS properties are
400 // supplied.
401 OpenVPNDriver::ParseForeignOptions(map<int, string>(), &props);
402 EXPECT_EQ(5, props.domain_search.size());
403 ASSERT_EQ(1, props.dns_servers.size());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100404}
405
406TEST_F(OpenVPNDriverTest, ParseIPConfiguration) {
407 map<string, string> config;
Darin Petkove8587e32012-07-02 13:56:07 +0200408 IPConfig::Properties props;
409
410 OpenVPNDriver::ParseIPConfiguration(config, &props);
411 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
412 EXPECT_EQ(32, props.subnet_prefix);
413
414 props.subnet_prefix = 18;
415 OpenVPNDriver::ParseIPConfiguration(config, &props);
416 EXPECT_EQ(18, props.subnet_prefix);
417
Darin Petkov14c29ec2012-03-02 11:34:19 +0100418 config["ifconfig_loCal"] = "4.5.6.7";
419 config["ifconfiG_broadcast"] = "1.2.255.255";
420 config["ifconFig_netmAsk"] = "255.255.255.0";
421 config["ifconfig_remotE"] = "33.44.55.66";
422 config["route_vpN_gateway"] = "192.168.1.1";
Paul Stewartce4ec192012-03-14 12:53:46 -0700423 config["trusted_ip"] = "99.88.77.66";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100424 config["tun_mtu"] = "1000";
425 config["foreign_option_2"] = "dhcp-option DNS 4.4.4.4";
426 config["foreign_option_1"] = "dhcp-option DNS 1.1.1.1";
427 config["foreign_option_3"] = "dhcp-option DNS 2.2.2.2";
Darin Petkov60596742012-03-05 12:17:17 +0100428 config["route_network_2"] = kNetwork2;
429 config["route_network_1"] = kNetwork1;
430 config["route_netmask_2"] = kNetmask2;
431 config["route_netmask_1"] = kNetmask1;
432 config["route_gateway_2"] = kGateway2;
433 config["route_gateway_1"] = kGateway1;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100434 config["foo"] = "bar";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100435 OpenVPNDriver::ParseIPConfiguration(config, &props);
436 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
437 EXPECT_EQ("4.5.6.7", props.address);
438 EXPECT_EQ("1.2.255.255", props.broadcast_address);
Paul Stewart48100b02012-03-19 07:53:52 -0700439 EXPECT_EQ(24, props.subnet_prefix);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100440 EXPECT_EQ("33.44.55.66", props.peer_address);
441 EXPECT_EQ("192.168.1.1", props.gateway);
Paul Stewartce4ec192012-03-14 12:53:46 -0700442 EXPECT_EQ("99.88.77.66", props.trusted_ip);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100443 EXPECT_EQ(1000, props.mtu);
444 ASSERT_EQ(3, props.dns_servers.size());
445 EXPECT_EQ("1.1.1.1", props.dns_servers[0]);
446 EXPECT_EQ("4.4.4.4", props.dns_servers[1]);
447 EXPECT_EQ("2.2.2.2", props.dns_servers[2]);
Darin Petkov60596742012-03-05 12:17:17 +0100448 ASSERT_EQ(2, props.routes.size());
449 EXPECT_EQ(kGateway1, props.routes[0].gateway);
450 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
451 EXPECT_EQ(kNetwork1, props.routes[0].host);
452 EXPECT_EQ(kGateway2, props.routes[1].gateway);
453 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
454 EXPECT_EQ(kNetwork2, props.routes[1].host);
Ben Chana0163122012-09-25 15:10:52 -0700455 EXPECT_FALSE(props.blackhole_ipv6);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100456}
457
Darin Petkovfe6a9372012-02-28 16:25:06 +0100458TEST_F(OpenVPNDriverTest, InitOptionsNoHost) {
459 Error error;
460 vector<string> options;
Darin Petkov79d74c92012-03-07 17:20:32 +0100461 driver_->InitOptions(&options, &error);
Darin Petkovfe6a9372012-02-28 16:25:06 +0100462 EXPECT_EQ(Error::kInvalidArguments, error.type());
463 EXPECT_TRUE(options.empty());
464}
465
466TEST_F(OpenVPNDriverTest, InitOptions) {
467 static const char kHost[] = "192.168.2.254";
Darin Petkov1fa81942012-04-02 11:38:08 +0200468 static const char kTLSAuthContents[] = "SOME-RANDOM-CONTENTS\n";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200469 static const char kID[] = "TestPKCS11ID";
470 FilePath empty_cert;
471 SetArg(flimflam::kProviderHostProperty, kHost);
472 SetArg(flimflam::kOpenVPNTLSAuthContentsProperty, kTLSAuthContents);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200473 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
Darin Petkov79d74c92012-03-07 17:20:32 +0100474 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov79d74c92012-03-07 17:20:32 +0100475 driver_->tunnel_interface_ = kInterfaceName;
Darin Petkove0d5dd12012-04-04 16:10:48 +0200476 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200477 ServiceRefPtr null_service;
478 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200479
480 Error error;
481 vector<string> options;
482 driver_->InitOptions(&options, &error);
483 EXPECT_TRUE(error.IsSuccess());
484 EXPECT_EQ("--client", options[0]);
485 ExpectInFlags(options, "--remote", kHost);
486 ExpectInFlags(options, "CONNMAN_PATH", RPCTaskMockAdaptor::kRpcId);
487 ExpectInFlags(options, "--dev", kInterfaceName);
488 ExpectInFlags(options, "--group", "openvpn");
489 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
490 ASSERT_FALSE(driver_->tls_auth_file_.empty());
491 ExpectInFlags(options, "--tls-auth", driver_->tls_auth_file_.value());
492 string contents;
493 EXPECT_TRUE(
494 file_util::ReadFileToString(driver_->tls_auth_file_, &contents));
495 EXPECT_EQ(kTLSAuthContents, contents);
496 ExpectInFlags(options, "--pkcs11-id", kID);
Darin Petkovca8a0e62012-09-26 13:16:52 +0200497 ExpectInFlags(options, "--capath", OpenVPNDriver::kDefaultCACertificatesPath);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200498 ExpectInFlags(options, "--syslog");
499 ExpectInFlags(options, "--auth-user-pass");
Darin Petkove0d5dd12012-04-04 16:10:48 +0200500}
501
Darin Petkov4b944842012-09-21 10:48:48 +0200502TEST_F(OpenVPNDriverTest, InitOptionsHostWithPort) {
503 SetArg(flimflam::kProviderHostProperty, "v.com:1234");
504 driver_->rpc_task_.reset(new RPCTask(&control_, this));
505 driver_->tunnel_interface_ = kInterfaceName;
506 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
507 ServiceRefPtr null_service;
508 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
509
510 Error error;
511 vector<string> options;
512 driver_->InitOptions(&options, &error);
513 EXPECT_TRUE(error.IsSuccess());
514 vector<string>::const_iterator it =
515 std::find(options.begin(), options.end(), "--remote");
516 ASSERT_TRUE(it != options.end());
517 ASSERT_TRUE(++it != options.end());
518 EXPECT_EQ("v.com", *it);
519 ASSERT_TRUE(++it != options.end());
520 EXPECT_EQ("1234", *it);
521}
522
Darin Petkovca8a0e62012-09-26 13:16:52 +0200523TEST_F(OpenVPNDriverTest, InitCAOptions) {
Darin Petkove0d5dd12012-04-04 16:10:48 +0200524 static const char kHost[] = "192.168.2.254";
Darin Petkovca8a0e62012-09-26 13:16:52 +0200525 static const char kCaCert[] = "foo";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200526 static const char kCaCertNSS[] = "{1234}";
527 static const char kNSSCertfile[] = "/tmp/nss-cert";
Darin Petkovca8a0e62012-09-26 13:16:52 +0200528
529 Error error;
530 vector<string> options;
531 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
532 EXPECT_TRUE(error.IsSuccess());
533 ExpectInFlags(options, "--capath", OpenVPNDriver::kDefaultCACertificatesPath);
534
535 options.clear();
536 SetArg(flimflam::kOpenVPNCaCertProperty, kCaCert);
537 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
538 ExpectInFlags(options, "--ca", kCaCert);
539 EXPECT_TRUE(error.IsSuccess());
540
541 SetArg(flimflam::kOpenVPNCaCertNSSProperty, kCaCertNSS);
542 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
543 EXPECT_EQ(Error::kInvalidArguments, error.type());
544 EXPECT_EQ("Can't specify both CACert and CACertNSS.", error.message());
545
546 SetArg(flimflam::kOpenVPNCaCertProperty, "");
547 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200548 FilePath empty_cert;
549 FilePath nss_cert(kNSSCertfile);
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200550 EXPECT_CALL(nss_,
551 GetPEMCertfile(kCaCertNSS,
552 ElementsAreArray(kHost, arraysize(kHost) - 1)))
Darin Petkove0d5dd12012-04-04 16:10:48 +0200553 .WillOnce(Return(empty_cert))
554 .WillOnce(Return(nss_cert));
555
Darin Petkovca8a0e62012-09-26 13:16:52 +0200556 error.Reset();
557 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
558 EXPECT_EQ(Error::kInvalidArguments, error.type());
559 EXPECT_EQ("Unable to extract NSS CA certificate: {1234}", error.message());
560
561 error.Reset();
562 options.clear();
563 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200564 ExpectInFlags(options, "--ca", kNSSCertfile);
565 EXPECT_TRUE(error.IsSuccess());
Darin Petkove0d5dd12012-04-04 16:10:48 +0200566}
567
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200568TEST_F(OpenVPNDriverTest, InitClientAuthOptions) {
569 static const char kTestValue[] = "foo";
570 vector<string> options;
571
572 // No key or cert, assume user/password authentication.
573 driver_->InitClientAuthOptions(&options);
574 ExpectInFlags(options, "--auth-user-pass");
575 ExpectNotInFlags(options, "--key");
576 ExpectNotInFlags(options, "--cert");
577
578 // Cert available, no user/password.
579 options.clear();
580 SetArg(OpenVPNDriver::kOpenVPNCertProperty, kTestValue);
581 driver_->InitClientAuthOptions(&options);
582 ExpectNotInFlags(options, "--auth-user-pass");
583 ExpectNotInFlags(options, "--key");
584 ExpectInFlags(options, "--cert", kTestValue);
585
586 // Key available, no user/password.
587 options.clear();
588 SetArg(OpenVPNDriver::kOpenVPNKeyProperty, kTestValue);
589 driver_->InitClientAuthOptions(&options);
590 ExpectNotInFlags(options, "--auth-user-pass");
591 ExpectInFlags(options, "--key", kTestValue);
592
593 // Key available, AuthUserPass set.
594 options.clear();
595 SetArg(flimflam::kOpenVPNAuthUserPassProperty, kTestValue);
596 driver_->InitClientAuthOptions(&options);
597 ExpectInFlags(options, "--auth-user-pass");
598 ExpectInFlags(options, "--key", kTestValue);
599
600 // Key available, User set.
601 options.clear();
602 RemoveStringArg(flimflam::kOpenVPNAuthUserPassProperty);
603 SetArg(flimflam::kOpenVPNUserProperty, "user");
604 driver_->InitClientAuthOptions(&options);
605 ExpectInFlags(options, "--auth-user-pass");
606 ExpectInFlags(options, "--key", kTestValue);
607}
608
Darin Petkove0d5dd12012-04-04 16:10:48 +0200609TEST_F(OpenVPNDriverTest, InitPKCS11Options) {
610 vector<string> options;
611 driver_->InitPKCS11Options(&options);
612 EXPECT_TRUE(options.empty());
613
614 static const char kID[] = "TestPKCS11ID";
615 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
616 driver_->InitPKCS11Options(&options);
617 ExpectInFlags(options, "--pkcs11-id", kID);
618 ExpectInFlags(options, "--pkcs11-providers", "libchaps.so");
619
620 static const char kProvider[] = "libpkcs11.so";
621 SetArg(flimflam::kOpenVPNProviderProperty, kProvider);
622 options.clear();
623 driver_->InitPKCS11Options(&options);
624 ExpectInFlags(options, "--pkcs11-id", kID);
625 ExpectInFlags(options, "--pkcs11-providers", kProvider);
626}
627
628TEST_F(OpenVPNDriverTest, InitManagementChannelOptions) {
629 vector<string> options;
Darin Petkova5e07ef2012-07-09 14:27:57 +0200630 Error error;
631
Darin Petkove0d5dd12012-04-04 16:10:48 +0200632 EXPECT_CALL(*management_server_,
633 Start(&dispatcher_, &driver_->sockets_, &options))
Darin Petkova5e07ef2012-07-09 14:27:57 +0200634 .Times(4)
Darin Petkove0d5dd12012-04-04 16:10:48 +0200635 .WillOnce(Return(false))
Darin Petkova5e07ef2012-07-09 14:27:57 +0200636 .WillRepeatedly(Return(true));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200637
Darin Petkova5e07ef2012-07-09 14:27:57 +0200638 // Management server fails to start.
Darin Petkove0d5dd12012-04-04 16:10:48 +0200639 EXPECT_FALSE(driver_->InitManagementChannelOptions(&options, &error));
640 EXPECT_EQ(Error::kInternalError, error.type());
641 EXPECT_EQ("Unable to setup management channel.", error.message());
642
Darin Petkova5e07ef2012-07-09 14:27:57 +0200643 // Start with a connected default service.
644 scoped_refptr<MockService> mock_service(
645 new MockService(&control_, &dispatcher_, &metrics_, &manager_));
646 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(mock_service));
647 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(true));
648 EXPECT_CALL(*management_server_, ReleaseHold());
Darin Petkove0d5dd12012-04-04 16:10:48 +0200649 error.Reset();
650 EXPECT_TRUE(driver_->InitManagementChannelOptions(&options, &error));
651 EXPECT_TRUE(error.IsSuccess());
Darin Petkova5e07ef2012-07-09 14:27:57 +0200652
653 // Start with a disconnected default service.
654 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(mock_service));
655 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(false));
656 EXPECT_CALL(*management_server_, ReleaseHold()).Times(0);
657 EXPECT_TRUE(driver_->InitManagementChannelOptions(&options, &error));
658 EXPECT_TRUE(error.IsSuccess());
659
660 // Start with no default service.
661 ServiceRefPtr null_service;
662 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
663 EXPECT_CALL(*management_server_, ReleaseHold()).Times(0);
664 EXPECT_TRUE(driver_->InitManagementChannelOptions(&options, &error));
665 EXPECT_TRUE(error.IsSuccess());
Darin Petkovfe6a9372012-02-28 16:25:06 +0100666}
667
Darin Petkov55771b72012-04-25 09:25:19 +0200668TEST_F(OpenVPNDriverTest, InitLoggingOptions) {
669 vector<string> options;
670 bool vpn_logging = SLOG_IS_ON(VPN, 0);
671 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
672 driver_->InitLoggingOptions(&options);
673 ASSERT_EQ(1, options.size());
674 EXPECT_EQ("--syslog", options[0]);
675 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
676 options.clear();
677 driver_->InitLoggingOptions(&options);
678 ExpectInFlags(options, "--verb", "3");
679 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
680 SetArg("OpenVPN.Verb", "2");
681 options.clear();
682 driver_->InitLoggingOptions(&options);
683 ExpectInFlags(options, "--verb", "2");
684 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
685 SetArg("OpenVPN.Verb", "1");
686 options.clear();
687 driver_->InitLoggingOptions(&options);
688 ExpectInFlags(options, "--verb", "1");
689 if (!vpn_logging) {
690 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
691 }
692}
693
Darin Petkovfe6a9372012-02-28 16:25:06 +0100694TEST_F(OpenVPNDriverTest, AppendValueOption) {
695 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200696 EXPECT_FALSE(
697 driver_->AppendValueOption("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100698 EXPECT_TRUE(options.empty());
699
Darin Petkove0d5dd12012-04-04 16:10:48 +0200700 SetArg(kProperty, "");
Darin Petkov46463022012-03-29 14:57:32 +0200701 EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100702 EXPECT_TRUE(options.empty());
703
Darin Petkove0d5dd12012-04-04 16:10:48 +0200704 SetArg(kProperty, kValue);
705 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200706 EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
707 EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100708 EXPECT_EQ(4, options.size());
709 EXPECT_EQ(kOption, options[0]);
710 EXPECT_EQ(kValue, options[1]);
711 EXPECT_EQ(kOption2, options[2]);
712 EXPECT_EQ(kValue2, options[3]);
713}
714
715TEST_F(OpenVPNDriverTest, AppendFlag) {
716 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200717 EXPECT_FALSE(
718 driver_->AppendFlag("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100719 EXPECT_TRUE(options.empty());
720
Darin Petkove0d5dd12012-04-04 16:10:48 +0200721 SetArg(kProperty, "");
722 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200723 EXPECT_TRUE(driver_->AppendFlag(kProperty, kOption, &options));
724 EXPECT_TRUE(driver_->AppendFlag(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100725 EXPECT_EQ(2, options.size());
726 EXPECT_EQ(kOption, options[0]);
727 EXPECT_EQ(kOption2, options[1]);
728}
729
Paul Stewartca6abd42012-03-01 15:45:29 -0800730TEST_F(OpenVPNDriverTest, ClaimInterface) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100731 driver_->tunnel_interface_ = kInterfaceName;
732 EXPECT_FALSE(driver_->ClaimInterface(string(kInterfaceName) + "XXX",
733 kInterfaceIndex));
734 EXPECT_FALSE(driver_->device_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800735
Darin Petkov36a3ace2012-03-06 17:22:14 +0100736 static const char kHost[] = "192.168.2.254";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200737 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov46463022012-03-29 14:57:32 +0200738 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200739 ServiceRefPtr null_service;
740 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
Darin Petkov36a3ace2012-03-06 17:22:14 +0100741 EXPECT_CALL(glib_, SpawnAsyncWithPipesCWD(_, _, _, _, _, _, _, _, _, _))
742 .WillOnce(Return(true));
743 EXPECT_CALL(glib_, ChildWatchAdd(_, _, _)).WillOnce(Return(1));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200744 const int kServiceCallbackTag = 1;
745 EXPECT_EQ(0, driver_->default_service_callback_tag_);
746 EXPECT_CALL(manager_, RegisterDefaultServiceCallback(_))
747 .WillOnce(Return(kServiceCallbackTag));
Darin Petkov79d74c92012-03-07 17:20:32 +0100748 EXPECT_TRUE(driver_->ClaimInterface(kInterfaceName, kInterfaceIndex));
749 ASSERT_TRUE(driver_->device_);
750 EXPECT_EQ(kInterfaceIndex, driver_->device_->interface_index());
Darin Petkova5e07ef2012-07-09 14:27:57 +0200751 EXPECT_EQ(kServiceCallbackTag, driver_->default_service_callback_tag_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800752}
753
Darin Petkov36a3ace2012-03-06 17:22:14 +0100754TEST_F(OpenVPNDriverTest, Cleanup) {
Darin Petkov1fa81942012-04-02 11:38:08 +0200755 driver_->Cleanup(Service::kStateIdle); // Ensure no crash.
756
Darin Petkova5e07ef2012-07-09 14:27:57 +0200757 const unsigned int kChildTag = 123;
Darin Petkov36a3ace2012-03-06 17:22:14 +0100758 const int kPID = 123456;
Darin Petkova5e07ef2012-07-09 14:27:57 +0200759 const int kServiceCallbackTag = 5;
760 driver_->default_service_callback_tag_ = kServiceCallbackTag;
761 driver_->child_watch_tag_ = kChildTag;
Darin Petkov79d74c92012-03-07 17:20:32 +0100762 driver_->pid_ = kPID;
763 driver_->rpc_task_.reset(new RPCTask(&control_, this));
764 driver_->tunnel_interface_ = kInterfaceName;
765 driver_->device_ = device_;
766 driver_->service_ = service_;
Darin Petkov602303f2012-06-06 12:15:59 +0200767 driver_->StartConnectTimeout();
Darin Petkov1fa81942012-04-02 11:38:08 +0200768 FilePath tls_auth_file;
769 EXPECT_TRUE(file_util::CreateTemporaryFile(&tls_auth_file));
770 EXPECT_FALSE(tls_auth_file.empty());
771 EXPECT_TRUE(file_util::PathExists(tls_auth_file));
772 driver_->tls_auth_file_ = tls_auth_file;
Darin Petkov46463022012-03-29 14:57:32 +0200773 // Stop will be called twice -- once by Cleanup and once by the destructor.
774 EXPECT_CALL(*management_server_, Stop()).Times(2);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200775 EXPECT_CALL(glib_, SourceRemove(kChildTag));
776 EXPECT_CALL(manager_, DeregisterDefaultServiceCallback(kServiceCallbackTag));
Darin Petkov5a850472012-06-06 15:44:24 +0200777 EXPECT_CALL(process_killer_, Kill(kPID, _));
778 EXPECT_CALL(device_info_, DeleteInterface(_)).Times(0);
Darin Petkov029d3532012-04-18 14:38:04 +0200779 EXPECT_CALL(*device_, OnDisconnected());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500780 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov79d74c92012-03-07 17:20:32 +0100781 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
Darin Petkov3f9131c2012-03-20 11:37:32 +0100782 driver_->Cleanup(Service::kStateFailure);
Darin Petkov79d74c92012-03-07 17:20:32 +0100783 EXPECT_EQ(0, driver_->child_watch_tag_);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200784 EXPECT_EQ(0, driver_->default_service_callback_tag_);
Darin Petkov79d74c92012-03-07 17:20:32 +0100785 EXPECT_EQ(0, driver_->pid_);
786 EXPECT_FALSE(driver_->rpc_task_.get());
787 EXPECT_TRUE(driver_->tunnel_interface_.empty());
788 EXPECT_FALSE(driver_->device_);
789 EXPECT_FALSE(driver_->service_);
Darin Petkov1fa81942012-04-02 11:38:08 +0200790 EXPECT_FALSE(file_util::PathExists(tls_auth_file));
791 EXPECT_TRUE(driver_->tls_auth_file_.empty());
Darin Petkov602303f2012-06-06 12:15:59 +0200792 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov36a3ace2012-03-06 17:22:14 +0100793}
794
Darin Petkov1a462de2012-05-02 11:10:48 +0200795namespace {
796MATCHER(CheckEnv, "") {
797 if (!arg || !arg[0] || !arg[1] || arg[2]) {
798 return false;
799 }
800 return (string(arg[0]) == "IV_PLAT=Chromium OS" &&
801 string(arg[1]) == "IV_PLAT_REL=2202.0");
802}
803} // namespace
804
Darin Petkov36a3ace2012-03-06 17:22:14 +0100805TEST_F(OpenVPNDriverTest, SpawnOpenVPN) {
Darin Petkov1a462de2012-05-02 11:10:48 +0200806 SetupLSBRelease();
807
Darin Petkov79d74c92012-03-07 17:20:32 +0100808 EXPECT_FALSE(driver_->SpawnOpenVPN());
Darin Petkov36a3ace2012-03-06 17:22:14 +0100809
810 static const char kHost[] = "192.168.2.254";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200811 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov79d74c92012-03-07 17:20:32 +0100812 driver_->tunnel_interface_ = "tun0";
813 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov46463022012-03-29 14:57:32 +0200814 EXPECT_CALL(*management_server_, Start(_, _, _))
815 .Times(2)
816 .WillRepeatedly(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200817 ServiceRefPtr null_service;
818 EXPECT_CALL(manager_, GetDefaultService())
819 .Times(2)
820 .WillRepeatedly(Return(null_service));
Darin Petkov36a3ace2012-03-06 17:22:14 +0100821
822 const int kPID = 234678;
Darin Petkov1a462de2012-05-02 11:10:48 +0200823 EXPECT_CALL(glib_,
824 SpawnAsyncWithPipesCWD(_, CheckEnv(), _, _, _, _, _, _, _, _))
Darin Petkov36a3ace2012-03-06 17:22:14 +0100825 .WillOnce(Return(false))
826 .WillOnce(DoAll(SetArgumentPointee<5>(kPID), Return(true)));
827 const int kTag = 6;
Darin Petkov79d74c92012-03-07 17:20:32 +0100828 EXPECT_CALL(glib_, ChildWatchAdd(kPID, &driver_->OnOpenVPNDied, driver_))
Darin Petkov36a3ace2012-03-06 17:22:14 +0100829 .WillOnce(Return(kTag));
Darin Petkov79d74c92012-03-07 17:20:32 +0100830 EXPECT_FALSE(driver_->SpawnOpenVPN());
831 EXPECT_TRUE(driver_->SpawnOpenVPN());
832 EXPECT_EQ(kPID, driver_->pid_);
833 EXPECT_EQ(kTag, driver_->child_watch_tag_);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100834}
835
836TEST_F(OpenVPNDriverTest, OnOpenVPNDied) {
837 const int kPID = 99999;
Darin Petkov5a850472012-06-06 15:44:24 +0200838 driver_->device_ = device_;
Darin Petkov79d74c92012-03-07 17:20:32 +0100839 driver_->child_watch_tag_ = 333;
840 driver_->pid_ = kPID;
Darin Petkov5a850472012-06-06 15:44:24 +0200841 EXPECT_CALL(*device_, OnDisconnected());
842 EXPECT_CALL(*device_, SetEnabled(false));
843 EXPECT_CALL(process_killer_, Kill(_, _)).Times(0);
844 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
Darin Petkov79d74c92012-03-07 17:20:32 +0100845 OpenVPNDriver::OnOpenVPNDied(kPID, 2, driver_);
846 EXPECT_EQ(0, driver_->child_watch_tag_);
847 EXPECT_EQ(0, driver_->pid_);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100848}
849
Darin Petkov6aa21872012-03-09 16:10:19 +0100850TEST_F(OpenVPNDriverTest, Disconnect) {
851 driver_->device_ = device_;
852 driver_->service_ = service_;
Darin Petkov029d3532012-04-18 14:38:04 +0200853 EXPECT_CALL(*device_, OnDisconnected());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500854 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov6aa21872012-03-09 16:10:19 +0100855 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
856 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
857 driver_->Disconnect();
Darin Petkova0e645e2012-04-25 11:38:59 +0200858 EXPECT_FALSE(driver_->device_);
Darin Petkov6aa21872012-03-09 16:10:19 +0100859 EXPECT_FALSE(driver_->service_);
860}
861
Darin Petkov5eb05422012-05-11 15:45:25 +0200862TEST_F(OpenVPNDriverTest, OnConnectionDisconnected) {
863 driver_->service_ = service_;
864 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
865 driver_->OnConnectionDisconnected();
866 EXPECT_FALSE(driver_->service_);
867}
868
Darin Petkov271fe522012-03-27 13:47:29 +0200869TEST_F(OpenVPNDriverTest, OnReconnecting) {
870 driver_->OnReconnecting(); // Expect no crash.
871 driver_->device_ = device_;
872 driver_->service_ = service_;
873 EXPECT_CALL(*device_, OnDisconnected());
874 EXPECT_CALL(*service_, SetState(Service::kStateAssociating));
875 driver_->OnReconnecting();
Darin Petkov602303f2012-06-06 12:15:59 +0200876 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov271fe522012-03-27 13:47:29 +0200877}
878
Paul Stewart291a4732012-03-14 19:19:02 -0700879TEST_F(OpenVPNDriverTest, VerifyPaths) {
880 // Ensure that the various path constants that the OpenVPN driver uses
Darin Petkova0e645e2012-04-25 11:38:59 +0200881 // actually exists in the build image. Due to build dependencies, they should
882 // already exist by the time we run unit tests.
Paul Stewart291a4732012-03-14 19:19:02 -0700883
Darin Petkova0e645e2012-04-25 11:38:59 +0200884 // The OpenVPNDriver path constants are absolute. FilePath::Append asserts
885 // that its argument is not an absolute path, so we need to strip the leading
886 // separators. There's nothing built into FilePath to do so.
887 static const char *kPaths[] = {
888 OpenVPNDriver::kOpenVPNPath,
889 OpenVPNDriver::kOpenVPNScript,
890 };
891 for (size_t i = 0; i < arraysize(kPaths); i++) {
892 string path(kPaths[i]);
893 TrimString(path, FilePath::kSeparators, &path);
894 EXPECT_TRUE(file_util::PathExists(FilePath(SYSROOT).Append(path)))
895 << kPaths[i];
896 }
Paul Stewart291a4732012-03-14 19:19:02 -0700897}
898
Darin Petkovd4325392012-04-23 15:48:22 +0200899TEST_F(OpenVPNDriverTest, InitPropertyStore) {
900 // Sanity test property store initialization.
901 PropertyStore store;
902 driver_->InitPropertyStore(&store);
903 const string kUser = "joe";
904 Error error;
905 EXPECT_TRUE(
906 store.SetStringProperty(flimflam::kOpenVPNUserProperty, kUser, &error));
907 EXPECT_TRUE(error.IsSuccess());
Darin Petkovb536a742012-04-26 11:31:28 +0200908 EXPECT_EQ(kUser, GetArgs()->LookupString(flimflam::kOpenVPNUserProperty, ""));
909}
910
911TEST_F(OpenVPNDriverTest, GetProvider) {
912 PropertyStore store;
913 driver_->InitPropertyStore(&store);
Paul Stewart8e7e4592012-04-29 09:47:48 -0700914 PropertyStoreInspector inspector(&store);
Darin Petkovb536a742012-04-26 11:31:28 +0200915 {
Darin Petkovb536a742012-04-26 11:31:28 +0200916 KeyValueStore props;
917 EXPECT_TRUE(
Paul Stewart8e7e4592012-04-29 09:47:48 -0700918 inspector.GetKeyValueStoreProperty(
Darin Petkov4682aa82012-05-31 16:24:11 +0200919 flimflam::kProviderProperty, &props));
Darin Petkovb536a742012-04-26 11:31:28 +0200920 EXPECT_TRUE(props.LookupBool(flimflam::kPassphraseRequiredProperty, false));
921 }
922 {
Darin Petkovb536a742012-04-26 11:31:28 +0200923 KeyValueStore props;
924 SetArg(flimflam::kOpenVPNPasswordProperty, "random-password");
925 EXPECT_TRUE(
Paul Stewart8e7e4592012-04-29 09:47:48 -0700926 inspector.GetKeyValueStoreProperty(
Darin Petkov4682aa82012-05-31 16:24:11 +0200927 flimflam::kProviderProperty, &props));
Darin Petkovb536a742012-04-26 11:31:28 +0200928 EXPECT_FALSE(props.LookupBool(flimflam::kPassphraseRequiredProperty, true));
Darin Petkov02236552012-06-11 13:15:19 +0200929 EXPECT_FALSE(props.ContainsString(flimflam::kOpenVPNPasswordProperty));
Darin Petkovb536a742012-04-26 11:31:28 +0200930 }
Darin Petkovd4325392012-04-23 15:48:22 +0200931}
932
Darin Petkov1a462de2012-05-02 11:10:48 +0200933TEST_F(OpenVPNDriverTest, ParseLSBRelease) {
934 SetupLSBRelease();
935 map<string, string> lsb_release;
936 EXPECT_TRUE(driver_->ParseLSBRelease(&lsb_release));
937 EXPECT_TRUE(ContainsKey(lsb_release, "foo") && lsb_release["foo"] == "");
938 EXPECT_EQ("=", lsb_release["zoo"]);
939 EXPECT_EQ("Chromium OS", lsb_release[OpenVPNDriver::kChromeOSReleaseName]);
940 EXPECT_EQ("2202.0", lsb_release[OpenVPNDriver::kChromeOSReleaseVersion]);
941 driver_->lsb_release_file_ = FilePath("/non/existent/file");
942 EXPECT_FALSE(driver_->ParseLSBRelease(NULL));
943}
944
945TEST_F(OpenVPNDriverTest, InitEnvironment) {
946 vector<string> env;
947 SetupLSBRelease();
948 driver_->InitEnvironment(&env);
949 ASSERT_EQ(2, env.size());
950 EXPECT_EQ("IV_PLAT=Chromium OS", env[0]);
951 EXPECT_EQ("IV_PLAT_REL=2202.0", env[1]);
952 env.clear();
953 EXPECT_EQ(0, file_util::WriteFile(lsb_release_file_, "", 0));
954 driver_->InitEnvironment(&env);
955 EXPECT_EQ(0, env.size());
956}
957
Darin Petkov5a850472012-06-06 15:44:24 +0200958TEST_F(OpenVPNDriverTest, DeleteInterface) {
959 scoped_ptr<MockDeviceInfo> device_info(
960 new MockDeviceInfo(&control_, &dispatcher_, &metrics_, &manager_));
961 EXPECT_CALL(*device_info, DeleteInterface(kInterfaceIndex))
962 .WillOnce(Return(true));
963 WeakPtr<DeviceInfo> weak = device_info->AsWeakPtr();
964 EXPECT_TRUE(weak);
965 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
966 device_info.reset();
967 EXPECT_FALSE(weak);
968 // Expect no crash.
969 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
970}
971
Darin Petkova5e07ef2012-07-09 14:27:57 +0200972TEST_F(OpenVPNDriverTest, OnDefaultServiceChanged) {
973 driver_->service_ = service_;
974
975 ServiceRefPtr null_service;
976 EXPECT_CALL(*management_server_, Hold());
977 driver_->OnDefaultServiceChanged(null_service);
978
979 EXPECT_CALL(*management_server_, Hold());
980 driver_->OnDefaultServiceChanged(service_);
981
982 scoped_refptr<MockService> mock_service(
983 new MockService(&control_, &dispatcher_, &metrics_, &manager_));
984
985 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(false));
986 EXPECT_CALL(*management_server_, Hold());
987 driver_->OnDefaultServiceChanged(mock_service);
988
989 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(true));
990 EXPECT_CALL(*management_server_, ReleaseHold());
991 driver_->OnDefaultServiceChanged(mock_service);
992}
993
Darin Petkov33af05c2012-02-28 10:10:30 +0100994} // namespace shill