blob: eff0db8e8b1b29b861e06fe8827f144f12bb0f25 [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
Darin Petkov3189a472012-10-05 09:55:33 +0200114 const ServiceRefPtr &GetSelectedService() {
115 return device_->selected_service();
116 }
117
Paul Stewartca6abd42012-03-01 15:45:29 -0800118 // Used to assert that a flag appears in the options.
119 void ExpectInFlags(const vector<string> &options, const string &flag,
120 const string &value);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200121 void ExpectInFlags(const vector<string> &options, const string &flag);
122 void ExpectNotInFlags(const vector<string> &options, const string &flag);
Paul Stewartca6abd42012-03-01 15:45:29 -0800123
Darin Petkov1a462de2012-05-02 11:10:48 +0200124 void SetupLSBRelease();
125
Darin Petkov36a3ace2012-03-06 17:22:14 +0100126 // Inherited from RPCTaskDelegate.
Darin Petkov209e6292012-04-20 11:33:32 +0200127 virtual void GetLogin(string *user, string *password);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100128 virtual void Notify(const string &reason, const map<string, string> &dict);
Paul Stewartca6abd42012-03-01 15:45:29 -0800129
Darin Petkova9b1fed2012-02-29 11:49:05 +0100130 NiceMockControl control_;
Darin Petkov0e9735d2012-04-24 12:33:45 +0200131 NiceMock<MockDeviceInfo> device_info_;
Darin Petkovf20994f2012-03-05 16:12:19 +0100132 EventDispatcher dispatcher_;
133 MockMetrics metrics_;
134 MockGLib glib_;
135 MockManager manager_;
Darin Petkov46463022012-03-29 14:57:32 +0200136 OpenVPNDriver *driver_; // Owned by |service_|.
Darin Petkov79d74c92012-03-07 17:20:32 +0100137 scoped_refptr<MockVPNService> service_;
138 scoped_refptr<MockVPN> device_;
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200139 MockNSS nss_;
Darin Petkov5a850472012-06-06 15:44:24 +0200140 MockProcessKiller process_killer_;
Darin Petkov46463022012-03-29 14:57:32 +0200141
142 // Owned by |driver_|.
143 NiceMock<MockOpenVPNManagementServer> *management_server_;
Darin Petkov1a462de2012-05-02 11:10:48 +0200144
145 FilePath lsb_release_file_;
Darin Petkov33af05c2012-02-28 10:10:30 +0100146};
147
Darin Petkovfe6a9372012-02-28 16:25:06 +0100148const char OpenVPNDriverTest::kOption[] = "--openvpn-option";
149const char OpenVPNDriverTest::kProperty[] = "OpenVPN.SomeProperty";
150const char OpenVPNDriverTest::kValue[] = "some-property-value";
151const char OpenVPNDriverTest::kOption2[] = "--openvpn-option2";
152const char OpenVPNDriverTest::kProperty2[] = "OpenVPN.SomeProperty2";
153const char OpenVPNDriverTest::kValue2[] = "some-property-value2";
Darin Petkov60596742012-03-05 12:17:17 +0100154const char OpenVPNDriverTest::kGateway1[] = "10.242.2.13";
155const char OpenVPNDriverTest::kNetmask1[] = "255.255.255.255";
156const char OpenVPNDriverTest::kNetwork1[] = "10.242.2.1";
157const char OpenVPNDriverTest::kGateway2[] = "10.242.2.14";
158const char OpenVPNDriverTest::kNetmask2[] = "255.255.0.0";
159const char OpenVPNDriverTest::kNetwork2[] = "192.168.0.0";
Darin Petkov79d74c92012-03-07 17:20:32 +0100160const char OpenVPNDriverTest::kInterfaceName[] = "tun0";
161const int OpenVPNDriverTest::kInterfaceIndex = 123;
Darin Petkovfe6a9372012-02-28 16:25:06 +0100162
Darin Petkov209e6292012-04-20 11:33:32 +0200163void OpenVPNDriverTest::GetLogin(string */*user*/, string */*password*/) {}
164
Darin Petkova9b1fed2012-02-29 11:49:05 +0100165void OpenVPNDriverTest::Notify(const string &/*reason*/,
166 const map<string, string> &/*dict*/) {}
167
Paul Stewartca6abd42012-03-01 15:45:29 -0800168void OpenVPNDriverTest::ExpectInFlags(const vector<string> &options,
169 const string &flag,
170 const string &value) {
171 vector<string>::const_iterator it =
172 std::find(options.begin(), options.end(), flag);
173
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 it++;
178 EXPECT_TRUE(it != options.end());
179 if (it != options.end())
Darin Petkov36a3ace2012-03-06 17:22:14 +0100180 return; // Don't crash below.
Paul Stewartca6abd42012-03-01 15:45:29 -0800181 EXPECT_EQ(value, *it);
182}
183
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200184void OpenVPNDriverTest::ExpectInFlags(const vector<string> &options,
185 const string &flag) {
186 EXPECT_TRUE(std::find(options.begin(), options.end(), flag) !=
187 options.end());
188}
189
190void OpenVPNDriverTest::ExpectNotInFlags(const vector<string> &options,
191 const string &flag) {
192 EXPECT_TRUE(std::find(options.begin(), options.end(), flag) ==
193 options.end());
194}
195
Darin Petkov1a462de2012-05-02 11:10:48 +0200196void OpenVPNDriverTest::SetupLSBRelease() {
197 static const char kLSBReleaseContents[] =
198 "\n"
199 "=\n"
200 "foo=\n"
201 "=bar\n"
202 "zoo==\n"
203 "CHROMEOS_RELEASE_BOARD=x86-alex\n"
204 "CHROMEOS_RELEASE_NAME=Chromium OS\n"
205 "CHROMEOS_RELEASE_VERSION=2202.0\n";
206 EXPECT_TRUE(file_util::CreateTemporaryFile(&lsb_release_file_));
207 EXPECT_EQ(arraysize(kLSBReleaseContents),
208 file_util::WriteFile(lsb_release_file_,
209 kLSBReleaseContents,
210 arraysize(kLSBReleaseContents)));
211 EXPECT_EQ(OpenVPNDriver::kLSBReleaseFile, driver_->lsb_release_file_.value());
212 driver_->lsb_release_file_ = lsb_release_file_;
213}
214
Darin Petkov33af05c2012-02-28 10:10:30 +0100215TEST_F(OpenVPNDriverTest, Connect) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100216 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
217 const string interface = kInterfaceName;
Darin Petkovf20994f2012-03-05 16:12:19 +0100218 EXPECT_CALL(device_info_, CreateTunnelInterface(_))
Darin Petkov79d74c92012-03-07 17:20:32 +0100219 .WillOnce(DoAll(SetArgumentPointee<0>(interface), Return(true)));
220 Error error;
221 driver_->Connect(service_, &error);
222 EXPECT_TRUE(error.IsSuccess());
223 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
Darin Petkov602303f2012-06-06 12:15:59 +0200224 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov79d74c92012-03-07 17:20:32 +0100225}
226
227TEST_F(OpenVPNDriverTest, ConnectTunnelFailure) {
228 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200229 EXPECT_CALL(device_info_, CreateTunnelInterface(_)).WillOnce(Return(false));
Darin Petkov79d74c92012-03-07 17:20:32 +0100230 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
231 Error error;
232 driver_->Connect(service_, &error);
233 EXPECT_EQ(Error::kInternalError, error.type());
234 EXPECT_TRUE(driver_->tunnel_interface_.empty());
Darin Petkov602303f2012-06-06 12:15:59 +0200235 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov33af05c2012-02-28 10:10:30 +0100236}
237
Darin Petkov0e9735d2012-04-24 12:33:45 +0200238namespace {
239MATCHER_P(IsIPAddress, address, "") {
240 IPAddress ip_address(IPAddress::kFamilyIPv4);
241 EXPECT_TRUE(ip_address.SetAddressFromString(address));
242 return ip_address.Equals(arg);
243}
244} // namespace
245
Darin Petkov14c29ec2012-03-02 11:34:19 +0100246TEST_F(OpenVPNDriverTest, Notify) {
Darin Petkov0e9735d2012-04-24 12:33:45 +0200247 map<string, string> config;
Darin Petkov3189a472012-10-05 09:55:33 +0200248 driver_->service_ = service_;
Darin Petkov79d74c92012-03-07 17:20:32 +0100249 driver_->device_ = device_;
Darin Petkov602303f2012-06-06 12:15:59 +0200250 driver_->StartConnectTimeout();
Darin Petkove8587e32012-07-02 13:56:07 +0200251 EXPECT_CALL(*device_,
252 UpdateIPConfig(Field(&IPConfig::Properties::address, "")));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200253 driver_->Notify("up", config);
Darin Petkov602303f2012-06-06 12:15:59 +0200254 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov3189a472012-10-05 09:55:33 +0200255 EXPECT_TRUE(GetSelectedService().get() == service_.get());
Darin Petkove8587e32012-07-02 13:56:07 +0200256
257 // Tests that existing properties are reused if no new ones provided.
Darin Petkov3189a472012-10-05 09:55:33 +0200258 driver_->ip_properties_.address = "1.2.3.4";
Darin Petkove8587e32012-07-02 13:56:07 +0200259 EXPECT_CALL(*device_,
260 UpdateIPConfig(Field(&IPConfig::Properties::address, "1.2.3.4")));
261 driver_->Notify("up", config);
Darin Petkov79d74c92012-03-07 17:20:32 +0100262}
263
264TEST_F(OpenVPNDriverTest, NotifyFail) {
265 map<string, string> dict;
266 driver_->device_ = device_;
Darin Petkov602303f2012-06-06 12:15:59 +0200267 driver_->StartConnectTimeout();
Darin Petkov79d74c92012-03-07 17:20:32 +0100268 EXPECT_CALL(*device_, OnDisconnected());
269 driver_->Notify("fail", dict);
Darin Petkov602303f2012-06-06 12:15:59 +0200270 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100271}
272
Darin Petkov60596742012-03-05 12:17:17 +0100273TEST_F(OpenVPNDriverTest, GetRouteOptionEntry) {
274 OpenVPNDriver::RouteOptions routes;
275 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "bar", &routes));
276 EXPECT_TRUE(routes.empty());
277 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "foo", &routes));
278 EXPECT_TRUE(routes.empty());
279 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "fooZ", &routes));
280 EXPECT_TRUE(routes.empty());
281 IPConfig::Route *route =
282 OpenVPNDriver::GetRouteOptionEntry("foo", "foo12", &routes);
283 EXPECT_EQ(1, routes.size());
284 EXPECT_EQ(route, &routes[12]);
285 route = OpenVPNDriver::GetRouteOptionEntry("foo", "foo13", &routes);
286 EXPECT_EQ(2, routes.size());
287 EXPECT_EQ(route, &routes[13]);
288}
289
290TEST_F(OpenVPNDriverTest, ParseRouteOption) {
291 OpenVPNDriver::RouteOptions routes;
292 OpenVPNDriver::ParseRouteOption("foo", "bar", &routes);
293 EXPECT_TRUE(routes.empty());
294 OpenVPNDriver::ParseRouteOption("gateway_2", kGateway2, &routes);
295 OpenVPNDriver::ParseRouteOption("netmask_2", kNetmask2, &routes);
296 OpenVPNDriver::ParseRouteOption("network_2", kNetwork2, &routes);
297 EXPECT_EQ(1, routes.size());
298 OpenVPNDriver::ParseRouteOption("gateway_1", kGateway1, &routes);
299 OpenVPNDriver::ParseRouteOption("netmask_1", kNetmask1, &routes);
300 OpenVPNDriver::ParseRouteOption("network_1", kNetwork1, &routes);
301 EXPECT_EQ(2, routes.size());
302 EXPECT_EQ(kGateway1, routes[1].gateway);
303 EXPECT_EQ(kNetmask1, routes[1].netmask);
304 EXPECT_EQ(kNetwork1, routes[1].host);
305 EXPECT_EQ(kGateway2, routes[2].gateway);
306 EXPECT_EQ(kNetmask2, routes[2].netmask);
307 EXPECT_EQ(kNetwork2, routes[2].host);
308}
309
310TEST_F(OpenVPNDriverTest, SetRoutes) {
311 OpenVPNDriver::RouteOptions routes;
312 routes[1].gateway = "1.2.3.4";
313 routes[1].host= "1.2.3.4";
314 routes[2].host = "2.3.4.5";
315 routes[2].netmask = "255.0.0.0";
316 routes[3].netmask = "255.0.0.0";
317 routes[3].gateway = "1.2.3.5";
318 routes[5].host = kNetwork2;
319 routes[5].netmask = kNetmask2;
320 routes[5].gateway = kGateway2;
321 routes[4].host = kNetwork1;
322 routes[4].netmask = kNetmask1;
323 routes[4].gateway = kGateway1;
324 IPConfig::Properties props;
325 OpenVPNDriver::SetRoutes(routes, &props);
326 ASSERT_EQ(2, props.routes.size());
327 EXPECT_EQ(kGateway1, props.routes[0].gateway);
328 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
329 EXPECT_EQ(kNetwork1, props.routes[0].host);
330 EXPECT_EQ(kGateway2, props.routes[1].gateway);
331 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
332 EXPECT_EQ(kNetwork2, props.routes[1].host);
Darin Petkove8587e32012-07-02 13:56:07 +0200333
334 // Tests that the routes are not reset if no new routes are supplied.
335 OpenVPNDriver::SetRoutes(OpenVPNDriver::RouteOptions(), &props);
336 EXPECT_EQ(2, props.routes.size());
Darin Petkov60596742012-03-05 12:17:17 +0100337}
338
Darin Petkov4b944842012-09-21 10:48:48 +0200339TEST_F(OpenVPNDriverTest, SplitPortFromHost) {
340 string name, port;
341 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", NULL, NULL));
342 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", &name, &port));
343 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com", &name, &port));
344 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:", &name, &port));
345 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost(":1234", &name, &port));
346 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:f:1234", &name, &port));
347 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:x", &name, &port));
348 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:-1", &name, &port));
349 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:+1", &name, &port));
350 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:65536", &name, &port));
351 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("v.com:0", &name, &port));
352 EXPECT_EQ("v.com", name);
353 EXPECT_EQ("0", port);
354 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("w.com:65535", &name, &port));
355 EXPECT_EQ("w.com", name);
356 EXPECT_EQ("65535", port);
357 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("x.com:12345", &name, &port));
358 EXPECT_EQ("x.com", name);
359 EXPECT_EQ("12345", port);
360}
361
Darin Petkov14c29ec2012-03-02 11:34:19 +0100362TEST_F(OpenVPNDriverTest, ParseForeignOption) {
Darin Petkove8587e32012-07-02 13:56:07 +0200363 vector<string> domain_search;
364 vector<string> dns_servers;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100365 IPConfig::Properties props;
Darin Petkove8587e32012-07-02 13:56:07 +0200366 OpenVPNDriver::ParseForeignOption("", &domain_search, &dns_servers);
367 OpenVPNDriver::ParseForeignOption(
368 "dhcp-option DOMAIN", &domain_search, &dns_servers);
369 OpenVPNDriver::ParseForeignOption(
370 "dhcp-option DOMAIN zzz.com foo", &domain_search, &dns_servers);
371 OpenVPNDriver::ParseForeignOption(
372 "dhcp-Option DOmAIN xyz.com", &domain_search, &dns_servers);
373 ASSERT_EQ(1, domain_search.size());
374 EXPECT_EQ("xyz.com", domain_search[0]);
375 OpenVPNDriver::ParseForeignOption(
376 "dhcp-option DnS 1.2.3.4", &domain_search, &dns_servers);
377 ASSERT_EQ(1, dns_servers.size());
378 EXPECT_EQ("1.2.3.4", dns_servers[0]);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100379}
380
381TEST_F(OpenVPNDriverTest, ParseForeignOptions) {
Darin Petkove8587e32012-07-02 13:56:07 +0200382 // This also tests that std::map is a sorted container.
Darin Petkov14c29ec2012-03-02 11:34:19 +0100383 map<int, string> options;
384 options[5] = "dhcp-option DOMAIN five.com";
385 options[2] = "dhcp-option DOMAIN two.com";
386 options[8] = "dhcp-option DOMAIN eight.com";
387 options[7] = "dhcp-option DOMAIN seven.com";
388 options[4] = "dhcp-option DOMAIN four.com";
Darin Petkove8587e32012-07-02 13:56:07 +0200389 options[10] = "dhcp-option dns 1.2.3.4";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100390 IPConfig::Properties props;
391 OpenVPNDriver::ParseForeignOptions(options, &props);
392 ASSERT_EQ(5, props.domain_search.size());
393 EXPECT_EQ("two.com", props.domain_search[0]);
394 EXPECT_EQ("four.com", props.domain_search[1]);
395 EXPECT_EQ("five.com", props.domain_search[2]);
396 EXPECT_EQ("seven.com", props.domain_search[3]);
397 EXPECT_EQ("eight.com", props.domain_search[4]);
Darin Petkove8587e32012-07-02 13:56:07 +0200398 ASSERT_EQ(1, props.dns_servers.size());
399 EXPECT_EQ("1.2.3.4", props.dns_servers[0]);
400
401 // Test that the DNS properties are not updated if no new DNS properties are
402 // supplied.
403 OpenVPNDriver::ParseForeignOptions(map<int, string>(), &props);
404 EXPECT_EQ(5, props.domain_search.size());
405 ASSERT_EQ(1, props.dns_servers.size());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100406}
407
408TEST_F(OpenVPNDriverTest, ParseIPConfiguration) {
409 map<string, string> config;
Darin Petkove8587e32012-07-02 13:56:07 +0200410 IPConfig::Properties props;
411
412 OpenVPNDriver::ParseIPConfiguration(config, &props);
413 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
414 EXPECT_EQ(32, props.subnet_prefix);
415
416 props.subnet_prefix = 18;
417 OpenVPNDriver::ParseIPConfiguration(config, &props);
418 EXPECT_EQ(18, props.subnet_prefix);
419
Darin Petkov14c29ec2012-03-02 11:34:19 +0100420 config["ifconfig_loCal"] = "4.5.6.7";
421 config["ifconfiG_broadcast"] = "1.2.255.255";
422 config["ifconFig_netmAsk"] = "255.255.255.0";
423 config["ifconfig_remotE"] = "33.44.55.66";
424 config["route_vpN_gateway"] = "192.168.1.1";
Paul Stewartce4ec192012-03-14 12:53:46 -0700425 config["trusted_ip"] = "99.88.77.66";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100426 config["tun_mtu"] = "1000";
427 config["foreign_option_2"] = "dhcp-option DNS 4.4.4.4";
428 config["foreign_option_1"] = "dhcp-option DNS 1.1.1.1";
429 config["foreign_option_3"] = "dhcp-option DNS 2.2.2.2";
Darin Petkov60596742012-03-05 12:17:17 +0100430 config["route_network_2"] = kNetwork2;
431 config["route_network_1"] = kNetwork1;
432 config["route_netmask_2"] = kNetmask2;
433 config["route_netmask_1"] = kNetmask1;
434 config["route_gateway_2"] = kGateway2;
435 config["route_gateway_1"] = kGateway1;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100436 config["foo"] = "bar";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100437 OpenVPNDriver::ParseIPConfiguration(config, &props);
438 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
439 EXPECT_EQ("4.5.6.7", props.address);
440 EXPECT_EQ("1.2.255.255", props.broadcast_address);
Paul Stewart48100b02012-03-19 07:53:52 -0700441 EXPECT_EQ(24, props.subnet_prefix);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100442 EXPECT_EQ("33.44.55.66", props.peer_address);
443 EXPECT_EQ("192.168.1.1", props.gateway);
Paul Stewartce4ec192012-03-14 12:53:46 -0700444 EXPECT_EQ("99.88.77.66", props.trusted_ip);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100445 EXPECT_EQ(1000, props.mtu);
446 ASSERT_EQ(3, props.dns_servers.size());
447 EXPECT_EQ("1.1.1.1", props.dns_servers[0]);
448 EXPECT_EQ("4.4.4.4", props.dns_servers[1]);
449 EXPECT_EQ("2.2.2.2", props.dns_servers[2]);
Darin Petkov60596742012-03-05 12:17:17 +0100450 ASSERT_EQ(2, props.routes.size());
451 EXPECT_EQ(kGateway1, props.routes[0].gateway);
452 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
453 EXPECT_EQ(kNetwork1, props.routes[0].host);
454 EXPECT_EQ(kGateway2, props.routes[1].gateway);
455 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
456 EXPECT_EQ(kNetwork2, props.routes[1].host);
Ben Chana0163122012-09-25 15:10:52 -0700457 EXPECT_FALSE(props.blackhole_ipv6);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100458}
459
Darin Petkovfe6a9372012-02-28 16:25:06 +0100460TEST_F(OpenVPNDriverTest, InitOptionsNoHost) {
461 Error error;
462 vector<string> options;
Darin Petkov79d74c92012-03-07 17:20:32 +0100463 driver_->InitOptions(&options, &error);
Darin Petkovfe6a9372012-02-28 16:25:06 +0100464 EXPECT_EQ(Error::kInvalidArguments, error.type());
465 EXPECT_TRUE(options.empty());
466}
467
468TEST_F(OpenVPNDriverTest, InitOptions) {
469 static const char kHost[] = "192.168.2.254";
Darin Petkov1fa81942012-04-02 11:38:08 +0200470 static const char kTLSAuthContents[] = "SOME-RANDOM-CONTENTS\n";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200471 static const char kID[] = "TestPKCS11ID";
472 FilePath empty_cert;
473 SetArg(flimflam::kProviderHostProperty, kHost);
474 SetArg(flimflam::kOpenVPNTLSAuthContentsProperty, kTLSAuthContents);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200475 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
Darin Petkov79d74c92012-03-07 17:20:32 +0100476 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov79d74c92012-03-07 17:20:32 +0100477 driver_->tunnel_interface_ = kInterfaceName;
Darin Petkove0d5dd12012-04-04 16:10:48 +0200478 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200479 ServiceRefPtr null_service;
480 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200481
482 Error error;
483 vector<string> options;
484 driver_->InitOptions(&options, &error);
485 EXPECT_TRUE(error.IsSuccess());
486 EXPECT_EQ("--client", options[0]);
487 ExpectInFlags(options, "--remote", kHost);
Darin Petkov728faa92012-10-12 11:25:47 +0200488 ExpectInFlags(options, kRPCTaskPathVariable, RPCTaskMockAdaptor::kRpcId);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200489 ExpectInFlags(options, "--dev", kInterfaceName);
490 ExpectInFlags(options, "--group", "openvpn");
491 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
492 ASSERT_FALSE(driver_->tls_auth_file_.empty());
493 ExpectInFlags(options, "--tls-auth", driver_->tls_auth_file_.value());
494 string contents;
495 EXPECT_TRUE(
496 file_util::ReadFileToString(driver_->tls_auth_file_, &contents));
497 EXPECT_EQ(kTLSAuthContents, contents);
498 ExpectInFlags(options, "--pkcs11-id", kID);
Darin Petkovc418b4b2012-10-05 11:42:52 +0200499 ExpectInFlags(options, "--ca", OpenVPNDriver::kDefaultCACertificates);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200500 ExpectInFlags(options, "--syslog");
501 ExpectInFlags(options, "--auth-user-pass");
Darin Petkove0d5dd12012-04-04 16:10:48 +0200502}
503
Darin Petkov4b944842012-09-21 10:48:48 +0200504TEST_F(OpenVPNDriverTest, InitOptionsHostWithPort) {
505 SetArg(flimflam::kProviderHostProperty, "v.com:1234");
506 driver_->rpc_task_.reset(new RPCTask(&control_, this));
507 driver_->tunnel_interface_ = kInterfaceName;
508 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
509 ServiceRefPtr null_service;
510 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
511
512 Error error;
513 vector<string> options;
514 driver_->InitOptions(&options, &error);
515 EXPECT_TRUE(error.IsSuccess());
516 vector<string>::const_iterator it =
517 std::find(options.begin(), options.end(), "--remote");
518 ASSERT_TRUE(it != options.end());
519 ASSERT_TRUE(++it != options.end());
520 EXPECT_EQ("v.com", *it);
521 ASSERT_TRUE(++it != options.end());
522 EXPECT_EQ("1234", *it);
523}
524
Darin Petkovca8a0e62012-09-26 13:16:52 +0200525TEST_F(OpenVPNDriverTest, InitCAOptions) {
Darin Petkove0d5dd12012-04-04 16:10:48 +0200526 static const char kHost[] = "192.168.2.254";
Darin Petkovca8a0e62012-09-26 13:16:52 +0200527 static const char kCaCert[] = "foo";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200528 static const char kCaCertNSS[] = "{1234}";
529 static const char kNSSCertfile[] = "/tmp/nss-cert";
Darin Petkovca8a0e62012-09-26 13:16:52 +0200530
531 Error error;
532 vector<string> options;
533 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
534 EXPECT_TRUE(error.IsSuccess());
Darin Petkovc418b4b2012-10-05 11:42:52 +0200535 ExpectInFlags(options, "--ca", OpenVPNDriver::kDefaultCACertificates);
Darin Petkovca8a0e62012-09-26 13:16:52 +0200536
537 options.clear();
538 SetArg(flimflam::kOpenVPNCaCertProperty, kCaCert);
539 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
540 ExpectInFlags(options, "--ca", kCaCert);
541 EXPECT_TRUE(error.IsSuccess());
542
543 SetArg(flimflam::kOpenVPNCaCertNSSProperty, kCaCertNSS);
544 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
545 EXPECT_EQ(Error::kInvalidArguments, error.type());
546 EXPECT_EQ("Can't specify both CACert and CACertNSS.", error.message());
547
548 SetArg(flimflam::kOpenVPNCaCertProperty, "");
549 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200550 FilePath empty_cert;
551 FilePath nss_cert(kNSSCertfile);
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200552 EXPECT_CALL(nss_,
553 GetPEMCertfile(kCaCertNSS,
554 ElementsAreArray(kHost, arraysize(kHost) - 1)))
Darin Petkove0d5dd12012-04-04 16:10:48 +0200555 .WillOnce(Return(empty_cert))
556 .WillOnce(Return(nss_cert));
557
Darin Petkovca8a0e62012-09-26 13:16:52 +0200558 error.Reset();
559 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
560 EXPECT_EQ(Error::kInvalidArguments, error.type());
561 EXPECT_EQ("Unable to extract NSS CA certificate: {1234}", error.message());
562
563 error.Reset();
564 options.clear();
565 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200566 ExpectInFlags(options, "--ca", kNSSCertfile);
567 EXPECT_TRUE(error.IsSuccess());
Darin Petkove0d5dd12012-04-04 16:10:48 +0200568}
569
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200570TEST_F(OpenVPNDriverTest, InitClientAuthOptions) {
571 static const char kTestValue[] = "foo";
572 vector<string> options;
573
574 // No key or cert, assume user/password authentication.
575 driver_->InitClientAuthOptions(&options);
576 ExpectInFlags(options, "--auth-user-pass");
577 ExpectNotInFlags(options, "--key");
578 ExpectNotInFlags(options, "--cert");
579
580 // Cert available, no user/password.
581 options.clear();
582 SetArg(OpenVPNDriver::kOpenVPNCertProperty, kTestValue);
583 driver_->InitClientAuthOptions(&options);
584 ExpectNotInFlags(options, "--auth-user-pass");
585 ExpectNotInFlags(options, "--key");
586 ExpectInFlags(options, "--cert", kTestValue);
587
588 // Key available, no user/password.
589 options.clear();
590 SetArg(OpenVPNDriver::kOpenVPNKeyProperty, kTestValue);
591 driver_->InitClientAuthOptions(&options);
592 ExpectNotInFlags(options, "--auth-user-pass");
593 ExpectInFlags(options, "--key", kTestValue);
594
595 // Key available, AuthUserPass set.
596 options.clear();
597 SetArg(flimflam::kOpenVPNAuthUserPassProperty, kTestValue);
598 driver_->InitClientAuthOptions(&options);
599 ExpectInFlags(options, "--auth-user-pass");
600 ExpectInFlags(options, "--key", kTestValue);
601
602 // Key available, User set.
603 options.clear();
604 RemoveStringArg(flimflam::kOpenVPNAuthUserPassProperty);
605 SetArg(flimflam::kOpenVPNUserProperty, "user");
606 driver_->InitClientAuthOptions(&options);
607 ExpectInFlags(options, "--auth-user-pass");
608 ExpectInFlags(options, "--key", kTestValue);
609}
610
Darin Petkove0d5dd12012-04-04 16:10:48 +0200611TEST_F(OpenVPNDriverTest, InitPKCS11Options) {
612 vector<string> options;
613 driver_->InitPKCS11Options(&options);
614 EXPECT_TRUE(options.empty());
615
616 static const char kID[] = "TestPKCS11ID";
617 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
618 driver_->InitPKCS11Options(&options);
619 ExpectInFlags(options, "--pkcs11-id", kID);
620 ExpectInFlags(options, "--pkcs11-providers", "libchaps.so");
621
622 static const char kProvider[] = "libpkcs11.so";
623 SetArg(flimflam::kOpenVPNProviderProperty, kProvider);
624 options.clear();
625 driver_->InitPKCS11Options(&options);
626 ExpectInFlags(options, "--pkcs11-id", kID);
627 ExpectInFlags(options, "--pkcs11-providers", kProvider);
628}
629
630TEST_F(OpenVPNDriverTest, InitManagementChannelOptions) {
631 vector<string> options;
Darin Petkova5e07ef2012-07-09 14:27:57 +0200632 Error error;
633
Darin Petkove0d5dd12012-04-04 16:10:48 +0200634 EXPECT_CALL(*management_server_,
635 Start(&dispatcher_, &driver_->sockets_, &options))
Darin Petkova5e07ef2012-07-09 14:27:57 +0200636 .Times(4)
Darin Petkove0d5dd12012-04-04 16:10:48 +0200637 .WillOnce(Return(false))
Darin Petkova5e07ef2012-07-09 14:27:57 +0200638 .WillRepeatedly(Return(true));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200639
Darin Petkova5e07ef2012-07-09 14:27:57 +0200640 // Management server fails to start.
Darin Petkove0d5dd12012-04-04 16:10:48 +0200641 EXPECT_FALSE(driver_->InitManagementChannelOptions(&options, &error));
642 EXPECT_EQ(Error::kInternalError, error.type());
643 EXPECT_EQ("Unable to setup management channel.", error.message());
644
Darin Petkova5e07ef2012-07-09 14:27:57 +0200645 // Start with a connected default service.
646 scoped_refptr<MockService> mock_service(
647 new MockService(&control_, &dispatcher_, &metrics_, &manager_));
648 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(mock_service));
649 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(true));
650 EXPECT_CALL(*management_server_, ReleaseHold());
Darin Petkove0d5dd12012-04-04 16:10:48 +0200651 error.Reset();
652 EXPECT_TRUE(driver_->InitManagementChannelOptions(&options, &error));
653 EXPECT_TRUE(error.IsSuccess());
Darin Petkova5e07ef2012-07-09 14:27:57 +0200654
655 // Start with a disconnected default service.
656 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(mock_service));
657 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(false));
658 EXPECT_CALL(*management_server_, ReleaseHold()).Times(0);
659 EXPECT_TRUE(driver_->InitManagementChannelOptions(&options, &error));
660 EXPECT_TRUE(error.IsSuccess());
661
662 // Start with no default service.
663 ServiceRefPtr null_service;
664 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
665 EXPECT_CALL(*management_server_, ReleaseHold()).Times(0);
666 EXPECT_TRUE(driver_->InitManagementChannelOptions(&options, &error));
667 EXPECT_TRUE(error.IsSuccess());
Darin Petkovfe6a9372012-02-28 16:25:06 +0100668}
669
Darin Petkov55771b72012-04-25 09:25:19 +0200670TEST_F(OpenVPNDriverTest, InitLoggingOptions) {
671 vector<string> options;
672 bool vpn_logging = SLOG_IS_ON(VPN, 0);
673 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
674 driver_->InitLoggingOptions(&options);
675 ASSERT_EQ(1, options.size());
676 EXPECT_EQ("--syslog", options[0]);
677 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
678 options.clear();
679 driver_->InitLoggingOptions(&options);
680 ExpectInFlags(options, "--verb", "3");
681 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
682 SetArg("OpenVPN.Verb", "2");
683 options.clear();
684 driver_->InitLoggingOptions(&options);
685 ExpectInFlags(options, "--verb", "2");
686 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
687 SetArg("OpenVPN.Verb", "1");
688 options.clear();
689 driver_->InitLoggingOptions(&options);
690 ExpectInFlags(options, "--verb", "1");
691 if (!vpn_logging) {
692 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
693 }
694}
695
Darin Petkovfe6a9372012-02-28 16:25:06 +0100696TEST_F(OpenVPNDriverTest, AppendValueOption) {
697 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200698 EXPECT_FALSE(
699 driver_->AppendValueOption("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100700 EXPECT_TRUE(options.empty());
701
Darin Petkove0d5dd12012-04-04 16:10:48 +0200702 SetArg(kProperty, "");
Darin Petkov46463022012-03-29 14:57:32 +0200703 EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100704 EXPECT_TRUE(options.empty());
705
Darin Petkove0d5dd12012-04-04 16:10:48 +0200706 SetArg(kProperty, kValue);
707 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200708 EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
709 EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100710 EXPECT_EQ(4, options.size());
711 EXPECT_EQ(kOption, options[0]);
712 EXPECT_EQ(kValue, options[1]);
713 EXPECT_EQ(kOption2, options[2]);
714 EXPECT_EQ(kValue2, options[3]);
715}
716
717TEST_F(OpenVPNDriverTest, AppendFlag) {
718 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200719 EXPECT_FALSE(
720 driver_->AppendFlag("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100721 EXPECT_TRUE(options.empty());
722
Darin Petkove0d5dd12012-04-04 16:10:48 +0200723 SetArg(kProperty, "");
724 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200725 EXPECT_TRUE(driver_->AppendFlag(kProperty, kOption, &options));
726 EXPECT_TRUE(driver_->AppendFlag(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100727 EXPECT_EQ(2, options.size());
728 EXPECT_EQ(kOption, options[0]);
729 EXPECT_EQ(kOption2, options[1]);
730}
731
Paul Stewartca6abd42012-03-01 15:45:29 -0800732TEST_F(OpenVPNDriverTest, ClaimInterface) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100733 driver_->tunnel_interface_ = kInterfaceName;
734 EXPECT_FALSE(driver_->ClaimInterface(string(kInterfaceName) + "XXX",
735 kInterfaceIndex));
736 EXPECT_FALSE(driver_->device_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800737
Darin Petkov36a3ace2012-03-06 17:22:14 +0100738 static const char kHost[] = "192.168.2.254";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200739 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov46463022012-03-29 14:57:32 +0200740 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200741 ServiceRefPtr null_service;
742 EXPECT_CALL(manager_, GetDefaultService()).WillOnce(Return(null_service));
Darin Petkov36a3ace2012-03-06 17:22:14 +0100743 EXPECT_CALL(glib_, SpawnAsyncWithPipesCWD(_, _, _, _, _, _, _, _, _, _))
744 .WillOnce(Return(true));
745 EXPECT_CALL(glib_, ChildWatchAdd(_, _, _)).WillOnce(Return(1));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200746 const int kServiceCallbackTag = 1;
747 EXPECT_EQ(0, driver_->default_service_callback_tag_);
748 EXPECT_CALL(manager_, RegisterDefaultServiceCallback(_))
749 .WillOnce(Return(kServiceCallbackTag));
Darin Petkov79d74c92012-03-07 17:20:32 +0100750 EXPECT_TRUE(driver_->ClaimInterface(kInterfaceName, kInterfaceIndex));
751 ASSERT_TRUE(driver_->device_);
752 EXPECT_EQ(kInterfaceIndex, driver_->device_->interface_index());
Darin Petkova5e07ef2012-07-09 14:27:57 +0200753 EXPECT_EQ(kServiceCallbackTag, driver_->default_service_callback_tag_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800754}
755
Darin Petkov36a3ace2012-03-06 17:22:14 +0100756TEST_F(OpenVPNDriverTest, Cleanup) {
Darin Petkov1fa81942012-04-02 11:38:08 +0200757 driver_->Cleanup(Service::kStateIdle); // Ensure no crash.
758
Darin Petkova5e07ef2012-07-09 14:27:57 +0200759 const unsigned int kChildTag = 123;
Darin Petkov36a3ace2012-03-06 17:22:14 +0100760 const int kPID = 123456;
Darin Petkova5e07ef2012-07-09 14:27:57 +0200761 const int kServiceCallbackTag = 5;
762 driver_->default_service_callback_tag_ = kServiceCallbackTag;
763 driver_->child_watch_tag_ = kChildTag;
Darin Petkov79d74c92012-03-07 17:20:32 +0100764 driver_->pid_ = kPID;
765 driver_->rpc_task_.reset(new RPCTask(&control_, this));
766 driver_->tunnel_interface_ = kInterfaceName;
767 driver_->device_ = device_;
768 driver_->service_ = service_;
Darin Petkov3189a472012-10-05 09:55:33 +0200769 driver_->ip_properties_.address = "1.2.3.4";
Darin Petkov602303f2012-06-06 12:15:59 +0200770 driver_->StartConnectTimeout();
Darin Petkov1fa81942012-04-02 11:38:08 +0200771 FilePath tls_auth_file;
772 EXPECT_TRUE(file_util::CreateTemporaryFile(&tls_auth_file));
773 EXPECT_FALSE(tls_auth_file.empty());
774 EXPECT_TRUE(file_util::PathExists(tls_auth_file));
775 driver_->tls_auth_file_ = tls_auth_file;
Darin Petkov46463022012-03-29 14:57:32 +0200776 // Stop will be called twice -- once by Cleanup and once by the destructor.
777 EXPECT_CALL(*management_server_, Stop()).Times(2);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200778 EXPECT_CALL(glib_, SourceRemove(kChildTag));
779 EXPECT_CALL(manager_, DeregisterDefaultServiceCallback(kServiceCallbackTag));
Darin Petkov5a850472012-06-06 15:44:24 +0200780 EXPECT_CALL(process_killer_, Kill(kPID, _));
781 EXPECT_CALL(device_info_, DeleteInterface(_)).Times(0);
Darin Petkov029d3532012-04-18 14:38:04 +0200782 EXPECT_CALL(*device_, OnDisconnected());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500783 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov79d74c92012-03-07 17:20:32 +0100784 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
Darin Petkov3f9131c2012-03-20 11:37:32 +0100785 driver_->Cleanup(Service::kStateFailure);
Darin Petkov79d74c92012-03-07 17:20:32 +0100786 EXPECT_EQ(0, driver_->child_watch_tag_);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200787 EXPECT_EQ(0, driver_->default_service_callback_tag_);
Darin Petkov79d74c92012-03-07 17:20:32 +0100788 EXPECT_EQ(0, driver_->pid_);
789 EXPECT_FALSE(driver_->rpc_task_.get());
790 EXPECT_TRUE(driver_->tunnel_interface_.empty());
791 EXPECT_FALSE(driver_->device_);
792 EXPECT_FALSE(driver_->service_);
Darin Petkov1fa81942012-04-02 11:38:08 +0200793 EXPECT_FALSE(file_util::PathExists(tls_auth_file));
794 EXPECT_TRUE(driver_->tls_auth_file_.empty());
Darin Petkov3189a472012-10-05 09:55:33 +0200795 EXPECT_TRUE(driver_->ip_properties_.address.empty());
Darin Petkov602303f2012-06-06 12:15:59 +0200796 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov36a3ace2012-03-06 17:22:14 +0100797}
798
Darin Petkov1a462de2012-05-02 11:10:48 +0200799namespace {
800MATCHER(CheckEnv, "") {
801 if (!arg || !arg[0] || !arg[1] || arg[2]) {
802 return false;
803 }
804 return (string(arg[0]) == "IV_PLAT=Chromium OS" &&
805 string(arg[1]) == "IV_PLAT_REL=2202.0");
806}
807} // namespace
808
Darin Petkov36a3ace2012-03-06 17:22:14 +0100809TEST_F(OpenVPNDriverTest, SpawnOpenVPN) {
Darin Petkov1a462de2012-05-02 11:10:48 +0200810 SetupLSBRelease();
811
Darin Petkov79d74c92012-03-07 17:20:32 +0100812 EXPECT_FALSE(driver_->SpawnOpenVPN());
Darin Petkov36a3ace2012-03-06 17:22:14 +0100813
814 static const char kHost[] = "192.168.2.254";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200815 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov79d74c92012-03-07 17:20:32 +0100816 driver_->tunnel_interface_ = "tun0";
817 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov46463022012-03-29 14:57:32 +0200818 EXPECT_CALL(*management_server_, Start(_, _, _))
819 .Times(2)
820 .WillRepeatedly(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200821 ServiceRefPtr null_service;
822 EXPECT_CALL(manager_, GetDefaultService())
823 .Times(2)
824 .WillRepeatedly(Return(null_service));
Darin Petkov36a3ace2012-03-06 17:22:14 +0100825
826 const int kPID = 234678;
Darin Petkov1a462de2012-05-02 11:10:48 +0200827 EXPECT_CALL(glib_,
828 SpawnAsyncWithPipesCWD(_, CheckEnv(), _, _, _, _, _, _, _, _))
Darin Petkov36a3ace2012-03-06 17:22:14 +0100829 .WillOnce(Return(false))
830 .WillOnce(DoAll(SetArgumentPointee<5>(kPID), Return(true)));
831 const int kTag = 6;
Darin Petkov79d74c92012-03-07 17:20:32 +0100832 EXPECT_CALL(glib_, ChildWatchAdd(kPID, &driver_->OnOpenVPNDied, driver_))
Darin Petkov36a3ace2012-03-06 17:22:14 +0100833 .WillOnce(Return(kTag));
Darin Petkov79d74c92012-03-07 17:20:32 +0100834 EXPECT_FALSE(driver_->SpawnOpenVPN());
835 EXPECT_TRUE(driver_->SpawnOpenVPN());
836 EXPECT_EQ(kPID, driver_->pid_);
837 EXPECT_EQ(kTag, driver_->child_watch_tag_);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100838}
839
840TEST_F(OpenVPNDriverTest, OnOpenVPNDied) {
841 const int kPID = 99999;
Darin Petkov5a850472012-06-06 15:44:24 +0200842 driver_->device_ = device_;
Darin Petkov79d74c92012-03-07 17:20:32 +0100843 driver_->child_watch_tag_ = 333;
844 driver_->pid_ = kPID;
Darin Petkov5a850472012-06-06 15:44:24 +0200845 EXPECT_CALL(*device_, OnDisconnected());
846 EXPECT_CALL(*device_, SetEnabled(false));
847 EXPECT_CALL(process_killer_, Kill(_, _)).Times(0);
848 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
Darin Petkov79d74c92012-03-07 17:20:32 +0100849 OpenVPNDriver::OnOpenVPNDied(kPID, 2, driver_);
850 EXPECT_EQ(0, driver_->child_watch_tag_);
851 EXPECT_EQ(0, driver_->pid_);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100852}
853
Darin Petkov6aa21872012-03-09 16:10:19 +0100854TEST_F(OpenVPNDriverTest, Disconnect) {
855 driver_->device_ = device_;
856 driver_->service_ = service_;
Darin Petkov029d3532012-04-18 14:38:04 +0200857 EXPECT_CALL(*device_, OnDisconnected());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500858 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov6aa21872012-03-09 16:10:19 +0100859 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
860 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
861 driver_->Disconnect();
Darin Petkova0e645e2012-04-25 11:38:59 +0200862 EXPECT_FALSE(driver_->device_);
Darin Petkov6aa21872012-03-09 16:10:19 +0100863 EXPECT_FALSE(driver_->service_);
864}
865
Darin Petkov5eb05422012-05-11 15:45:25 +0200866TEST_F(OpenVPNDriverTest, OnConnectionDisconnected) {
867 driver_->service_ = service_;
868 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
869 driver_->OnConnectionDisconnected();
870 EXPECT_FALSE(driver_->service_);
871}
872
Darin Petkov271fe522012-03-27 13:47:29 +0200873TEST_F(OpenVPNDriverTest, OnReconnecting) {
874 driver_->OnReconnecting(); // Expect no crash.
875 driver_->device_ = device_;
876 driver_->service_ = service_;
877 EXPECT_CALL(*device_, OnDisconnected());
878 EXPECT_CALL(*service_, SetState(Service::kStateAssociating));
879 driver_->OnReconnecting();
Darin Petkov602303f2012-06-06 12:15:59 +0200880 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov271fe522012-03-27 13:47:29 +0200881}
882
Paul Stewart291a4732012-03-14 19:19:02 -0700883TEST_F(OpenVPNDriverTest, VerifyPaths) {
884 // Ensure that the various path constants that the OpenVPN driver uses
Darin Petkova0e645e2012-04-25 11:38:59 +0200885 // actually exists in the build image. Due to build dependencies, they should
886 // already exist by the time we run unit tests.
Paul Stewart291a4732012-03-14 19:19:02 -0700887
Darin Petkova0e645e2012-04-25 11:38:59 +0200888 // The OpenVPNDriver path constants are absolute. FilePath::Append asserts
889 // that its argument is not an absolute path, so we need to strip the leading
890 // separators. There's nothing built into FilePath to do so.
891 static const char *kPaths[] = {
892 OpenVPNDriver::kOpenVPNPath,
893 OpenVPNDriver::kOpenVPNScript,
894 };
895 for (size_t i = 0; i < arraysize(kPaths); i++) {
896 string path(kPaths[i]);
897 TrimString(path, FilePath::kSeparators, &path);
898 EXPECT_TRUE(file_util::PathExists(FilePath(SYSROOT).Append(path)))
899 << kPaths[i];
900 }
Paul Stewart291a4732012-03-14 19:19:02 -0700901}
902
Darin Petkovd4325392012-04-23 15:48:22 +0200903TEST_F(OpenVPNDriverTest, InitPropertyStore) {
904 // Sanity test property store initialization.
905 PropertyStore store;
906 driver_->InitPropertyStore(&store);
907 const string kUser = "joe";
908 Error error;
909 EXPECT_TRUE(
910 store.SetStringProperty(flimflam::kOpenVPNUserProperty, kUser, &error));
911 EXPECT_TRUE(error.IsSuccess());
Darin Petkovb536a742012-04-26 11:31:28 +0200912 EXPECT_EQ(kUser, GetArgs()->LookupString(flimflam::kOpenVPNUserProperty, ""));
913}
914
915TEST_F(OpenVPNDriverTest, GetProvider) {
916 PropertyStore store;
917 driver_->InitPropertyStore(&store);
Paul Stewart8e7e4592012-04-29 09:47:48 -0700918 PropertyStoreInspector inspector(&store);
Darin Petkovb536a742012-04-26 11:31:28 +0200919 {
Darin Petkovb536a742012-04-26 11:31:28 +0200920 KeyValueStore props;
921 EXPECT_TRUE(
Paul Stewart8e7e4592012-04-29 09:47:48 -0700922 inspector.GetKeyValueStoreProperty(
Darin Petkov4682aa82012-05-31 16:24:11 +0200923 flimflam::kProviderProperty, &props));
Darin Petkovb536a742012-04-26 11:31:28 +0200924 EXPECT_TRUE(props.LookupBool(flimflam::kPassphraseRequiredProperty, false));
925 }
926 {
Darin Petkovb536a742012-04-26 11:31:28 +0200927 KeyValueStore props;
928 SetArg(flimflam::kOpenVPNPasswordProperty, "random-password");
929 EXPECT_TRUE(
Paul Stewart8e7e4592012-04-29 09:47:48 -0700930 inspector.GetKeyValueStoreProperty(
Darin Petkov4682aa82012-05-31 16:24:11 +0200931 flimflam::kProviderProperty, &props));
Darin Petkovb536a742012-04-26 11:31:28 +0200932 EXPECT_FALSE(props.LookupBool(flimflam::kPassphraseRequiredProperty, true));
Darin Petkov02236552012-06-11 13:15:19 +0200933 EXPECT_FALSE(props.ContainsString(flimflam::kOpenVPNPasswordProperty));
Darin Petkovb536a742012-04-26 11:31:28 +0200934 }
Darin Petkovd4325392012-04-23 15:48:22 +0200935}
936
Darin Petkov1a462de2012-05-02 11:10:48 +0200937TEST_F(OpenVPNDriverTest, ParseLSBRelease) {
938 SetupLSBRelease();
939 map<string, string> lsb_release;
940 EXPECT_TRUE(driver_->ParseLSBRelease(&lsb_release));
941 EXPECT_TRUE(ContainsKey(lsb_release, "foo") && lsb_release["foo"] == "");
942 EXPECT_EQ("=", lsb_release["zoo"]);
943 EXPECT_EQ("Chromium OS", lsb_release[OpenVPNDriver::kChromeOSReleaseName]);
944 EXPECT_EQ("2202.0", lsb_release[OpenVPNDriver::kChromeOSReleaseVersion]);
945 driver_->lsb_release_file_ = FilePath("/non/existent/file");
946 EXPECT_FALSE(driver_->ParseLSBRelease(NULL));
947}
948
949TEST_F(OpenVPNDriverTest, InitEnvironment) {
950 vector<string> env;
951 SetupLSBRelease();
952 driver_->InitEnvironment(&env);
953 ASSERT_EQ(2, env.size());
954 EXPECT_EQ("IV_PLAT=Chromium OS", env[0]);
955 EXPECT_EQ("IV_PLAT_REL=2202.0", env[1]);
956 env.clear();
957 EXPECT_EQ(0, file_util::WriteFile(lsb_release_file_, "", 0));
958 driver_->InitEnvironment(&env);
959 EXPECT_EQ(0, env.size());
960}
961
Darin Petkov5a850472012-06-06 15:44:24 +0200962TEST_F(OpenVPNDriverTest, DeleteInterface) {
963 scoped_ptr<MockDeviceInfo> device_info(
964 new MockDeviceInfo(&control_, &dispatcher_, &metrics_, &manager_));
965 EXPECT_CALL(*device_info, DeleteInterface(kInterfaceIndex))
966 .WillOnce(Return(true));
967 WeakPtr<DeviceInfo> weak = device_info->AsWeakPtr();
968 EXPECT_TRUE(weak);
969 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
970 device_info.reset();
971 EXPECT_FALSE(weak);
972 // Expect no crash.
973 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
974}
975
Darin Petkova5e07ef2012-07-09 14:27:57 +0200976TEST_F(OpenVPNDriverTest, OnDefaultServiceChanged) {
977 driver_->service_ = service_;
978
979 ServiceRefPtr null_service;
980 EXPECT_CALL(*management_server_, Hold());
981 driver_->OnDefaultServiceChanged(null_service);
982
983 EXPECT_CALL(*management_server_, Hold());
984 driver_->OnDefaultServiceChanged(service_);
985
986 scoped_refptr<MockService> mock_service(
987 new MockService(&control_, &dispatcher_, &metrics_, &manager_));
988
989 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(false));
990 EXPECT_CALL(*management_server_, Hold());
991 driver_->OnDefaultServiceChanged(mock_service);
992
993 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(true));
994 EXPECT_CALL(*management_server_, ReleaseHold());
995 driver_->OnDefaultServiceChanged(mock_service);
996}
997
Darin Petkov33af05c2012-02-28 10:10:30 +0100998} // namespace shill