blob: 8ad04c1754a7708b4671b645647d0a6f0e3eb83b [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"
32#include "shill/rpc_task.h"
Darin Petkovf20994f2012-03-05 16:12:19 +010033#include "shill/vpn.h"
Darin Petkov79d74c92012-03-07 17:20:32 +010034#include "shill/vpn_service.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010035
Darin Petkov5a850472012-06-06 15:44:24 +020036using base::WeakPtr;
Darin Petkova9b1fed2012-02-29 11:49:05 +010037using std::map;
Darin Petkovfe6a9372012-02-28 16:25:06 +010038using std::string;
39using std::vector;
Paul Stewartca6abd42012-03-01 15:45:29 -080040using testing::_;
Darin Petkovf3c71d72012-03-21 12:32:15 +010041using testing::AnyNumber;
Paul Stewartca6abd42012-03-01 15:45:29 -080042using testing::DoAll;
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020043using testing::ElementsAreArray;
Darin Petkove8587e32012-07-02 13:56:07 +020044using testing::Field;
Darin Petkovf3c71d72012-03-21 12:32:15 +010045using testing::Ne;
Paul Stewartce4ec192012-03-14 12:53:46 -070046using testing::NiceMock;
Paul Stewartca6abd42012-03-01 15:45:29 -080047using testing::Return;
48using testing::SetArgumentPointee;
Paul Stewartce4ec192012-03-14 12:53:46 -070049using testing::StrictMock;
Darin Petkovfe6a9372012-02-28 16:25:06 +010050
Darin Petkov33af05c2012-02-28 10:10:30 +010051namespace shill {
52
Darin Petkova9b1fed2012-02-29 11:49:05 +010053class OpenVPNDriverTest : public testing::Test,
54 public RPCTaskDelegate {
Darin Petkov33af05c2012-02-28 10:10:30 +010055 public:
Darin Petkovfe6a9372012-02-28 16:25:06 +010056 OpenVPNDriverTest()
Darin Petkov0e9735d2012-04-24 12:33:45 +020057 : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
Darin Petkovf20994f2012-03-05 16:12:19 +010058 manager_(&control_, &dispatcher_, &metrics_, &glib_),
Darin Petkov79d74c92012-03-07 17:20:32 +010059 driver_(new OpenVPNDriver(&control_, &dispatcher_, &metrics_, &manager_,
Paul Stewart451aa7f2012-04-11 19:07:58 -070060 &device_info_, &glib_)),
Darin Petkov79d74c92012-03-07 17:20:32 +010061 service_(new MockVPNService(&control_, &dispatcher_, &metrics_,
62 &manager_, driver_)),
63 device_(new MockVPN(&control_, &dispatcher_, &metrics_, &manager_,
Darin Petkov46463022012-03-29 14:57:32 +020064 kInterfaceName, kInterfaceIndex)),
65 management_server_(new NiceMock<MockOpenVPNManagementServer>()) {
66 driver_->management_server_.reset(management_server_);
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020067 driver_->nss_ = &nss_;
Darin Petkov5a850472012-06-06 15:44:24 +020068 driver_->process_killer_ = &process_killer_;
Darin Petkov46463022012-03-29 14:57:32 +020069 }
Darin Petkovfe6a9372012-02-28 16:25:06 +010070
Darin Petkov33af05c2012-02-28 10:10:30 +010071 virtual ~OpenVPNDriverTest() {}
72
Darin Petkov36a3ace2012-03-06 17:22:14 +010073 virtual void TearDown() {
Darin Petkova5e07ef2012-07-09 14:27:57 +020074 driver_->default_service_callback_tag_ = 0;
Darin Petkov79d74c92012-03-07 17:20:32 +010075 driver_->child_watch_tag_ = 0;
76 driver_->pid_ = 0;
77 driver_->device_ = NULL;
78 driver_->service_ = NULL;
Darin Petkov1a462de2012-05-02 11:10:48 +020079 if (!lsb_release_file_.empty()) {
80 EXPECT_TRUE(file_util::Delete(lsb_release_file_, false));
81 lsb_release_file_.clear();
82 }
Darin Petkov36a3ace2012-03-06 17:22:14 +010083 }
Darin Petkova9b1fed2012-02-29 11:49:05 +010084
Darin Petkov33af05c2012-02-28 10:10:30 +010085 protected:
Darin Petkovfe6a9372012-02-28 16:25:06 +010086 static const char kOption[];
87 static const char kProperty[];
88 static const char kValue[];
89 static const char kOption2[];
90 static const char kProperty2[];
91 static const char kValue2[];
Darin Petkov60596742012-03-05 12:17:17 +010092 static const char kGateway1[];
93 static const char kNetmask1[];
94 static const char kNetwork1[];
95 static const char kGateway2[];
96 static const char kNetmask2[];
97 static const char kNetwork2[];
Darin Petkov79d74c92012-03-07 17:20:32 +010098 static const char kInterfaceName[];
99 static const int kInterfaceIndex;
Darin Petkovfe6a9372012-02-28 16:25:06 +0100100
Darin Petkovb451d6e2012-04-23 11:56:41 +0200101 void SetArg(const string &arg, const string &value) {
102 driver_->args()->SetString(arg, value);
Darin Petkovfe6a9372012-02-28 16:25:06 +0100103 }
104
Darin Petkovf3c71d72012-03-21 12:32:15 +0100105 KeyValueStore *GetArgs() {
Darin Petkovb451d6e2012-04-23 11:56:41 +0200106 return driver_->args();
Darin Petkovf3c71d72012-03-21 12:32:15 +0100107 }
108
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200109 void RemoveStringArg(const string &arg) {
110 driver_->args()->RemoveString(arg);
111 }
112
Darin Petkov3189a472012-10-05 09:55:33 +0200113 const ServiceRefPtr &GetSelectedService() {
114 return device_->selected_service();
115 }
116
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100117 bool InitManagementChannelOptions(vector<string> *options, Error *error) {
118 return driver_->InitManagementChannelOptions(options, error);
119 }
120
121 Sockets *GetSockets() {
122 return &driver_->sockets_;
123 }
124
Paul Stewartca6abd42012-03-01 15:45:29 -0800125 // Used to assert that a flag appears in the options.
126 void ExpectInFlags(const vector<string> &options, const string &flag,
127 const string &value);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200128 void ExpectInFlags(const vector<string> &options, const string &flag);
129 void ExpectNotInFlags(const vector<string> &options, const string &flag);
Paul Stewartca6abd42012-03-01 15:45:29 -0800130
Darin Petkov1a462de2012-05-02 11:10:48 +0200131 void SetupLSBRelease();
132
Darin Petkov36a3ace2012-03-06 17:22:14 +0100133 // Inherited from RPCTaskDelegate.
Darin Petkov209e6292012-04-20 11:33:32 +0200134 virtual void GetLogin(string *user, string *password);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100135 virtual void Notify(const string &reason, const map<string, string> &dict);
Paul Stewartca6abd42012-03-01 15:45:29 -0800136
Darin Petkova9b1fed2012-02-29 11:49:05 +0100137 NiceMockControl control_;
Darin Petkov0e9735d2012-04-24 12:33:45 +0200138 NiceMock<MockDeviceInfo> device_info_;
Darin Petkovf20994f2012-03-05 16:12:19 +0100139 EventDispatcher dispatcher_;
140 MockMetrics metrics_;
141 MockGLib glib_;
142 MockManager manager_;
Darin Petkov46463022012-03-29 14:57:32 +0200143 OpenVPNDriver *driver_; // Owned by |service_|.
Darin Petkov79d74c92012-03-07 17:20:32 +0100144 scoped_refptr<MockVPNService> service_;
145 scoped_refptr<MockVPN> device_;
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200146 MockNSS nss_;
Darin Petkov5a850472012-06-06 15:44:24 +0200147 MockProcessKiller process_killer_;
Darin Petkov46463022012-03-29 14:57:32 +0200148
149 // Owned by |driver_|.
150 NiceMock<MockOpenVPNManagementServer> *management_server_;
Darin Petkov1a462de2012-05-02 11:10:48 +0200151
152 FilePath lsb_release_file_;
Darin Petkov33af05c2012-02-28 10:10:30 +0100153};
154
Darin Petkovfe6a9372012-02-28 16:25:06 +0100155const char OpenVPNDriverTest::kOption[] = "--openvpn-option";
156const char OpenVPNDriverTest::kProperty[] = "OpenVPN.SomeProperty";
157const char OpenVPNDriverTest::kValue[] = "some-property-value";
158const char OpenVPNDriverTest::kOption2[] = "--openvpn-option2";
159const char OpenVPNDriverTest::kProperty2[] = "OpenVPN.SomeProperty2";
160const char OpenVPNDriverTest::kValue2[] = "some-property-value2";
Darin Petkov60596742012-03-05 12:17:17 +0100161const char OpenVPNDriverTest::kGateway1[] = "10.242.2.13";
162const char OpenVPNDriverTest::kNetmask1[] = "255.255.255.255";
163const char OpenVPNDriverTest::kNetwork1[] = "10.242.2.1";
164const char OpenVPNDriverTest::kGateway2[] = "10.242.2.14";
165const char OpenVPNDriverTest::kNetmask2[] = "255.255.0.0";
166const char OpenVPNDriverTest::kNetwork2[] = "192.168.0.0";
Darin Petkov79d74c92012-03-07 17:20:32 +0100167const char OpenVPNDriverTest::kInterfaceName[] = "tun0";
168const int OpenVPNDriverTest::kInterfaceIndex = 123;
Darin Petkovfe6a9372012-02-28 16:25:06 +0100169
Darin Petkov209e6292012-04-20 11:33:32 +0200170void OpenVPNDriverTest::GetLogin(string */*user*/, string */*password*/) {}
171
Darin Petkova9b1fed2012-02-29 11:49:05 +0100172void OpenVPNDriverTest::Notify(const string &/*reason*/,
173 const map<string, string> &/*dict*/) {}
174
Paul Stewartca6abd42012-03-01 15:45:29 -0800175void OpenVPNDriverTest::ExpectInFlags(const vector<string> &options,
176 const string &flag,
177 const string &value) {
178 vector<string>::const_iterator it =
179 std::find(options.begin(), options.end(), flag);
180
181 EXPECT_TRUE(it != options.end());
182 if (it != options.end())
Darin Petkov36a3ace2012-03-06 17:22:14 +0100183 return; // Don't crash below.
Paul Stewartca6abd42012-03-01 15:45:29 -0800184 it++;
185 EXPECT_TRUE(it != options.end());
186 if (it != options.end())
Darin Petkov36a3ace2012-03-06 17:22:14 +0100187 return; // Don't crash below.
Paul Stewartca6abd42012-03-01 15:45:29 -0800188 EXPECT_EQ(value, *it);
189}
190
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200191void OpenVPNDriverTest::ExpectInFlags(const vector<string> &options,
192 const string &flag) {
193 EXPECT_TRUE(std::find(options.begin(), options.end(), flag) !=
194 options.end());
195}
196
197void OpenVPNDriverTest::ExpectNotInFlags(const vector<string> &options,
198 const string &flag) {
199 EXPECT_TRUE(std::find(options.begin(), options.end(), flag) ==
200 options.end());
201}
202
Darin Petkov1a462de2012-05-02 11:10:48 +0200203void OpenVPNDriverTest::SetupLSBRelease() {
204 static const char kLSBReleaseContents[] =
205 "\n"
206 "=\n"
207 "foo=\n"
208 "=bar\n"
209 "zoo==\n"
210 "CHROMEOS_RELEASE_BOARD=x86-alex\n"
211 "CHROMEOS_RELEASE_NAME=Chromium OS\n"
212 "CHROMEOS_RELEASE_VERSION=2202.0\n";
213 EXPECT_TRUE(file_util::CreateTemporaryFile(&lsb_release_file_));
214 EXPECT_EQ(arraysize(kLSBReleaseContents),
215 file_util::WriteFile(lsb_release_file_,
216 kLSBReleaseContents,
217 arraysize(kLSBReleaseContents)));
218 EXPECT_EQ(OpenVPNDriver::kLSBReleaseFile, driver_->lsb_release_file_.value());
219 driver_->lsb_release_file_ = lsb_release_file_;
220}
221
Darin Petkov33af05c2012-02-28 10:10:30 +0100222TEST_F(OpenVPNDriverTest, Connect) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100223 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
224 const string interface = kInterfaceName;
Darin Petkovf20994f2012-03-05 16:12:19 +0100225 EXPECT_CALL(device_info_, CreateTunnelInterface(_))
Darin Petkov79d74c92012-03-07 17:20:32 +0100226 .WillOnce(DoAll(SetArgumentPointee<0>(interface), Return(true)));
227 Error error;
228 driver_->Connect(service_, &error);
229 EXPECT_TRUE(error.IsSuccess());
230 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
Darin Petkov602303f2012-06-06 12:15:59 +0200231 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov79d74c92012-03-07 17:20:32 +0100232}
233
234TEST_F(OpenVPNDriverTest, ConnectTunnelFailure) {
235 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200236 EXPECT_CALL(device_info_, CreateTunnelInterface(_)).WillOnce(Return(false));
Darin Petkov79d74c92012-03-07 17:20:32 +0100237 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
238 Error error;
239 driver_->Connect(service_, &error);
240 EXPECT_EQ(Error::kInternalError, error.type());
241 EXPECT_TRUE(driver_->tunnel_interface_.empty());
Darin Petkov602303f2012-06-06 12:15:59 +0200242 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov33af05c2012-02-28 10:10:30 +0100243}
244
Darin Petkov0e9735d2012-04-24 12:33:45 +0200245namespace {
246MATCHER_P(IsIPAddress, address, "") {
247 IPAddress ip_address(IPAddress::kFamilyIPv4);
248 EXPECT_TRUE(ip_address.SetAddressFromString(address));
249 return ip_address.Equals(arg);
250}
251} // namespace
252
Darin Petkov14c29ec2012-03-02 11:34:19 +0100253TEST_F(OpenVPNDriverTest, Notify) {
Darin Petkov0e9735d2012-04-24 12:33:45 +0200254 map<string, string> config;
Darin Petkov3189a472012-10-05 09:55:33 +0200255 driver_->service_ = service_;
Darin Petkov79d74c92012-03-07 17:20:32 +0100256 driver_->device_ = device_;
Darin Petkov602303f2012-06-06 12:15:59 +0200257 driver_->StartConnectTimeout();
Darin Petkove8587e32012-07-02 13:56:07 +0200258 EXPECT_CALL(*device_,
259 UpdateIPConfig(Field(&IPConfig::Properties::address, "")));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200260 driver_->Notify("up", config);
Darin Petkov602303f2012-06-06 12:15:59 +0200261 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov3189a472012-10-05 09:55:33 +0200262 EXPECT_TRUE(GetSelectedService().get() == service_.get());
Darin Petkove8587e32012-07-02 13:56:07 +0200263
264 // Tests that existing properties are reused if no new ones provided.
Darin Petkov3189a472012-10-05 09:55:33 +0200265 driver_->ip_properties_.address = "1.2.3.4";
Darin Petkove8587e32012-07-02 13:56:07 +0200266 EXPECT_CALL(*device_,
267 UpdateIPConfig(Field(&IPConfig::Properties::address, "1.2.3.4")));
268 driver_->Notify("up", config);
Darin Petkov79d74c92012-03-07 17:20:32 +0100269}
270
271TEST_F(OpenVPNDriverTest, NotifyFail) {
272 map<string, string> dict;
273 driver_->device_ = device_;
Darin Petkov602303f2012-06-06 12:15:59 +0200274 driver_->StartConnectTimeout();
Darin Petkov79d74c92012-03-07 17:20:32 +0100275 EXPECT_CALL(*device_, OnDisconnected());
276 driver_->Notify("fail", dict);
Darin Petkov602303f2012-06-06 12:15:59 +0200277 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100278}
279
Darin Petkov60596742012-03-05 12:17:17 +0100280TEST_F(OpenVPNDriverTest, GetRouteOptionEntry) {
281 OpenVPNDriver::RouteOptions routes;
282 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "bar", &routes));
283 EXPECT_TRUE(routes.empty());
284 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "foo", &routes));
285 EXPECT_TRUE(routes.empty());
286 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "fooZ", &routes));
287 EXPECT_TRUE(routes.empty());
288 IPConfig::Route *route =
289 OpenVPNDriver::GetRouteOptionEntry("foo", "foo12", &routes);
290 EXPECT_EQ(1, routes.size());
291 EXPECT_EQ(route, &routes[12]);
292 route = OpenVPNDriver::GetRouteOptionEntry("foo", "foo13", &routes);
293 EXPECT_EQ(2, routes.size());
294 EXPECT_EQ(route, &routes[13]);
295}
296
297TEST_F(OpenVPNDriverTest, ParseRouteOption) {
298 OpenVPNDriver::RouteOptions routes;
299 OpenVPNDriver::ParseRouteOption("foo", "bar", &routes);
300 EXPECT_TRUE(routes.empty());
301 OpenVPNDriver::ParseRouteOption("gateway_2", kGateway2, &routes);
302 OpenVPNDriver::ParseRouteOption("netmask_2", kNetmask2, &routes);
303 OpenVPNDriver::ParseRouteOption("network_2", kNetwork2, &routes);
304 EXPECT_EQ(1, routes.size());
305 OpenVPNDriver::ParseRouteOption("gateway_1", kGateway1, &routes);
306 OpenVPNDriver::ParseRouteOption("netmask_1", kNetmask1, &routes);
307 OpenVPNDriver::ParseRouteOption("network_1", kNetwork1, &routes);
308 EXPECT_EQ(2, routes.size());
309 EXPECT_EQ(kGateway1, routes[1].gateway);
310 EXPECT_EQ(kNetmask1, routes[1].netmask);
311 EXPECT_EQ(kNetwork1, routes[1].host);
312 EXPECT_EQ(kGateway2, routes[2].gateway);
313 EXPECT_EQ(kNetmask2, routes[2].netmask);
314 EXPECT_EQ(kNetwork2, routes[2].host);
315}
316
317TEST_F(OpenVPNDriverTest, SetRoutes) {
318 OpenVPNDriver::RouteOptions routes;
319 routes[1].gateway = "1.2.3.4";
320 routes[1].host= "1.2.3.4";
321 routes[2].host = "2.3.4.5";
322 routes[2].netmask = "255.0.0.0";
323 routes[3].netmask = "255.0.0.0";
324 routes[3].gateway = "1.2.3.5";
325 routes[5].host = kNetwork2;
326 routes[5].netmask = kNetmask2;
327 routes[5].gateway = kGateway2;
328 routes[4].host = kNetwork1;
329 routes[4].netmask = kNetmask1;
330 routes[4].gateway = kGateway1;
331 IPConfig::Properties props;
332 OpenVPNDriver::SetRoutes(routes, &props);
333 ASSERT_EQ(2, props.routes.size());
334 EXPECT_EQ(kGateway1, props.routes[0].gateway);
335 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
336 EXPECT_EQ(kNetwork1, props.routes[0].host);
337 EXPECT_EQ(kGateway2, props.routes[1].gateway);
338 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
339 EXPECT_EQ(kNetwork2, props.routes[1].host);
Darin Petkove8587e32012-07-02 13:56:07 +0200340
341 // Tests that the routes are not reset if no new routes are supplied.
342 OpenVPNDriver::SetRoutes(OpenVPNDriver::RouteOptions(), &props);
343 EXPECT_EQ(2, props.routes.size());
Darin Petkov60596742012-03-05 12:17:17 +0100344}
345
Darin Petkov4b944842012-09-21 10:48:48 +0200346TEST_F(OpenVPNDriverTest, SplitPortFromHost) {
347 string name, port;
348 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", NULL, NULL));
349 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", &name, &port));
350 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com", &name, &port));
351 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:", &name, &port));
352 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost(":1234", &name, &port));
353 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:f:1234", &name, &port));
354 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:x", &name, &port));
355 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:-1", &name, &port));
356 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:+1", &name, &port));
357 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:65536", &name, &port));
358 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("v.com:0", &name, &port));
359 EXPECT_EQ("v.com", name);
360 EXPECT_EQ("0", port);
361 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("w.com:65535", &name, &port));
362 EXPECT_EQ("w.com", name);
363 EXPECT_EQ("65535", port);
364 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("x.com:12345", &name, &port));
365 EXPECT_EQ("x.com", name);
366 EXPECT_EQ("12345", port);
367}
368
Darin Petkov14c29ec2012-03-02 11:34:19 +0100369TEST_F(OpenVPNDriverTest, ParseForeignOption) {
Darin Petkove8587e32012-07-02 13:56:07 +0200370 vector<string> domain_search;
371 vector<string> dns_servers;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100372 IPConfig::Properties props;
Darin Petkove8587e32012-07-02 13:56:07 +0200373 OpenVPNDriver::ParseForeignOption("", &domain_search, &dns_servers);
374 OpenVPNDriver::ParseForeignOption(
375 "dhcp-option DOMAIN", &domain_search, &dns_servers);
376 OpenVPNDriver::ParseForeignOption(
377 "dhcp-option DOMAIN zzz.com foo", &domain_search, &dns_servers);
378 OpenVPNDriver::ParseForeignOption(
379 "dhcp-Option DOmAIN xyz.com", &domain_search, &dns_servers);
380 ASSERT_EQ(1, domain_search.size());
381 EXPECT_EQ("xyz.com", domain_search[0]);
382 OpenVPNDriver::ParseForeignOption(
383 "dhcp-option DnS 1.2.3.4", &domain_search, &dns_servers);
384 ASSERT_EQ(1, dns_servers.size());
385 EXPECT_EQ("1.2.3.4", dns_servers[0]);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100386}
387
388TEST_F(OpenVPNDriverTest, ParseForeignOptions) {
Darin Petkove8587e32012-07-02 13:56:07 +0200389 // This also tests that std::map is a sorted container.
Darin Petkov14c29ec2012-03-02 11:34:19 +0100390 map<int, string> options;
391 options[5] = "dhcp-option DOMAIN five.com";
392 options[2] = "dhcp-option DOMAIN two.com";
393 options[8] = "dhcp-option DOMAIN eight.com";
394 options[7] = "dhcp-option DOMAIN seven.com";
395 options[4] = "dhcp-option DOMAIN four.com";
Darin Petkove8587e32012-07-02 13:56:07 +0200396 options[10] = "dhcp-option dns 1.2.3.4";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100397 IPConfig::Properties props;
398 OpenVPNDriver::ParseForeignOptions(options, &props);
399 ASSERT_EQ(5, props.domain_search.size());
400 EXPECT_EQ("two.com", props.domain_search[0]);
401 EXPECT_EQ("four.com", props.domain_search[1]);
402 EXPECT_EQ("five.com", props.domain_search[2]);
403 EXPECT_EQ("seven.com", props.domain_search[3]);
404 EXPECT_EQ("eight.com", props.domain_search[4]);
Darin Petkove8587e32012-07-02 13:56:07 +0200405 ASSERT_EQ(1, props.dns_servers.size());
406 EXPECT_EQ("1.2.3.4", props.dns_servers[0]);
407
408 // Test that the DNS properties are not updated if no new DNS properties are
409 // supplied.
410 OpenVPNDriver::ParseForeignOptions(map<int, string>(), &props);
411 EXPECT_EQ(5, props.domain_search.size());
412 ASSERT_EQ(1, props.dns_servers.size());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100413}
414
415TEST_F(OpenVPNDriverTest, ParseIPConfiguration) {
416 map<string, string> config;
Darin Petkove8587e32012-07-02 13:56:07 +0200417 IPConfig::Properties props;
418
419 OpenVPNDriver::ParseIPConfiguration(config, &props);
420 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
421 EXPECT_EQ(32, props.subnet_prefix);
422
423 props.subnet_prefix = 18;
424 OpenVPNDriver::ParseIPConfiguration(config, &props);
425 EXPECT_EQ(18, props.subnet_prefix);
426
Darin Petkov14c29ec2012-03-02 11:34:19 +0100427 config["ifconfig_loCal"] = "4.5.6.7";
428 config["ifconfiG_broadcast"] = "1.2.255.255";
429 config["ifconFig_netmAsk"] = "255.255.255.0";
430 config["ifconfig_remotE"] = "33.44.55.66";
431 config["route_vpN_gateway"] = "192.168.1.1";
Paul Stewartce4ec192012-03-14 12:53:46 -0700432 config["trusted_ip"] = "99.88.77.66";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100433 config["tun_mtu"] = "1000";
434 config["foreign_option_2"] = "dhcp-option DNS 4.4.4.4";
435 config["foreign_option_1"] = "dhcp-option DNS 1.1.1.1";
436 config["foreign_option_3"] = "dhcp-option DNS 2.2.2.2";
Darin Petkov60596742012-03-05 12:17:17 +0100437 config["route_network_2"] = kNetwork2;
438 config["route_network_1"] = kNetwork1;
439 config["route_netmask_2"] = kNetmask2;
440 config["route_netmask_1"] = kNetmask1;
441 config["route_gateway_2"] = kGateway2;
442 config["route_gateway_1"] = kGateway1;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100443 config["foo"] = "bar";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100444 OpenVPNDriver::ParseIPConfiguration(config, &props);
445 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
446 EXPECT_EQ("4.5.6.7", props.address);
447 EXPECT_EQ("1.2.255.255", props.broadcast_address);
Paul Stewart48100b02012-03-19 07:53:52 -0700448 EXPECT_EQ(24, props.subnet_prefix);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100449 EXPECT_EQ("33.44.55.66", props.peer_address);
450 EXPECT_EQ("192.168.1.1", props.gateway);
Paul Stewartce4ec192012-03-14 12:53:46 -0700451 EXPECT_EQ("99.88.77.66", props.trusted_ip);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100452 EXPECT_EQ(1000, props.mtu);
453 ASSERT_EQ(3, props.dns_servers.size());
454 EXPECT_EQ("1.1.1.1", props.dns_servers[0]);
455 EXPECT_EQ("4.4.4.4", props.dns_servers[1]);
456 EXPECT_EQ("2.2.2.2", props.dns_servers[2]);
Darin Petkov60596742012-03-05 12:17:17 +0100457 ASSERT_EQ(2, props.routes.size());
458 EXPECT_EQ(kGateway1, props.routes[0].gateway);
459 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
460 EXPECT_EQ(kNetwork1, props.routes[0].host);
461 EXPECT_EQ(kGateway2, props.routes[1].gateway);
462 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
463 EXPECT_EQ(kNetwork2, props.routes[1].host);
Ben Chana0163122012-09-25 15:10:52 -0700464 EXPECT_FALSE(props.blackhole_ipv6);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100465}
466
Darin Petkovfe6a9372012-02-28 16:25:06 +0100467TEST_F(OpenVPNDriverTest, InitOptionsNoHost) {
468 Error error;
469 vector<string> options;
Darin Petkov79d74c92012-03-07 17:20:32 +0100470 driver_->InitOptions(&options, &error);
Darin Petkovfe6a9372012-02-28 16:25:06 +0100471 EXPECT_EQ(Error::kInvalidArguments, error.type());
472 EXPECT_TRUE(options.empty());
473}
474
475TEST_F(OpenVPNDriverTest, InitOptions) {
476 static const char kHost[] = "192.168.2.254";
Darin Petkov1fa81942012-04-02 11:38:08 +0200477 static const char kTLSAuthContents[] = "SOME-RANDOM-CONTENTS\n";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200478 static const char kID[] = "TestPKCS11ID";
479 FilePath empty_cert;
480 SetArg(flimflam::kProviderHostProperty, kHost);
481 SetArg(flimflam::kOpenVPNTLSAuthContentsProperty, kTLSAuthContents);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200482 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
Darin Petkov79d74c92012-03-07 17:20:32 +0100483 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov79d74c92012-03-07 17:20:32 +0100484 driver_->tunnel_interface_ = kInterfaceName;
Darin Petkove0d5dd12012-04-04 16:10:48 +0200485 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100486 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200487
488 Error error;
489 vector<string> options;
490 driver_->InitOptions(&options, &error);
491 EXPECT_TRUE(error.IsSuccess());
492 EXPECT_EQ("--client", options[0]);
493 ExpectInFlags(options, "--remote", kHost);
Darin Petkov728faa92012-10-12 11:25:47 +0200494 ExpectInFlags(options, kRPCTaskPathVariable, RPCTaskMockAdaptor::kRpcId);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200495 ExpectInFlags(options, "--dev", kInterfaceName);
496 ExpectInFlags(options, "--group", "openvpn");
497 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
498 ASSERT_FALSE(driver_->tls_auth_file_.empty());
499 ExpectInFlags(options, "--tls-auth", driver_->tls_auth_file_.value());
500 string contents;
501 EXPECT_TRUE(
502 file_util::ReadFileToString(driver_->tls_auth_file_, &contents));
503 EXPECT_EQ(kTLSAuthContents, contents);
504 ExpectInFlags(options, "--pkcs11-id", kID);
Darin Petkovc418b4b2012-10-05 11:42:52 +0200505 ExpectInFlags(options, "--ca", OpenVPNDriver::kDefaultCACertificates);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200506 ExpectInFlags(options, "--syslog");
507 ExpectInFlags(options, "--auth-user-pass");
Darin Petkove0d5dd12012-04-04 16:10:48 +0200508}
509
Darin Petkov4b944842012-09-21 10:48:48 +0200510TEST_F(OpenVPNDriverTest, InitOptionsHostWithPort) {
511 SetArg(flimflam::kProviderHostProperty, "v.com:1234");
512 driver_->rpc_task_.reset(new RPCTask(&control_, this));
513 driver_->tunnel_interface_ = kInterfaceName;
514 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100515 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
Darin Petkov4b944842012-09-21 10:48:48 +0200516
517 Error error;
518 vector<string> options;
519 driver_->InitOptions(&options, &error);
520 EXPECT_TRUE(error.IsSuccess());
521 vector<string>::const_iterator it =
522 std::find(options.begin(), options.end(), "--remote");
523 ASSERT_TRUE(it != options.end());
524 ASSERT_TRUE(++it != options.end());
525 EXPECT_EQ("v.com", *it);
526 ASSERT_TRUE(++it != options.end());
527 EXPECT_EQ("1234", *it);
528}
529
Darin Petkovca8a0e62012-09-26 13:16:52 +0200530TEST_F(OpenVPNDriverTest, InitCAOptions) {
Darin Petkove0d5dd12012-04-04 16:10:48 +0200531 static const char kHost[] = "192.168.2.254";
Darin Petkovca8a0e62012-09-26 13:16:52 +0200532 static const char kCaCert[] = "foo";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200533 static const char kCaCertNSS[] = "{1234}";
534 static const char kNSSCertfile[] = "/tmp/nss-cert";
Darin Petkovca8a0e62012-09-26 13:16:52 +0200535
536 Error error;
537 vector<string> options;
538 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
539 EXPECT_TRUE(error.IsSuccess());
Darin Petkovc418b4b2012-10-05 11:42:52 +0200540 ExpectInFlags(options, "--ca", OpenVPNDriver::kDefaultCACertificates);
Darin Petkovca8a0e62012-09-26 13:16:52 +0200541
542 options.clear();
543 SetArg(flimflam::kOpenVPNCaCertProperty, kCaCert);
544 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
545 ExpectInFlags(options, "--ca", kCaCert);
546 EXPECT_TRUE(error.IsSuccess());
547
548 SetArg(flimflam::kOpenVPNCaCertNSSProperty, kCaCertNSS);
549 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
550 EXPECT_EQ(Error::kInvalidArguments, error.type());
551 EXPECT_EQ("Can't specify both CACert and CACertNSS.", error.message());
552
553 SetArg(flimflam::kOpenVPNCaCertProperty, "");
554 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200555 FilePath empty_cert;
556 FilePath nss_cert(kNSSCertfile);
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200557 EXPECT_CALL(nss_,
558 GetPEMCertfile(kCaCertNSS,
559 ElementsAreArray(kHost, arraysize(kHost) - 1)))
Darin Petkove0d5dd12012-04-04 16:10:48 +0200560 .WillOnce(Return(empty_cert))
561 .WillOnce(Return(nss_cert));
562
Darin Petkovca8a0e62012-09-26 13:16:52 +0200563 error.Reset();
564 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
565 EXPECT_EQ(Error::kInvalidArguments, error.type());
566 EXPECT_EQ("Unable to extract NSS CA certificate: {1234}", error.message());
567
568 error.Reset();
569 options.clear();
570 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200571 ExpectInFlags(options, "--ca", kNSSCertfile);
572 EXPECT_TRUE(error.IsSuccess());
Darin Petkove0d5dd12012-04-04 16:10:48 +0200573}
574
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200575TEST_F(OpenVPNDriverTest, InitClientAuthOptions) {
576 static const char kTestValue[] = "foo";
577 vector<string> options;
578
579 // No key or cert, assume user/password authentication.
580 driver_->InitClientAuthOptions(&options);
581 ExpectInFlags(options, "--auth-user-pass");
582 ExpectNotInFlags(options, "--key");
583 ExpectNotInFlags(options, "--cert");
584
585 // Cert available, no user/password.
586 options.clear();
587 SetArg(OpenVPNDriver::kOpenVPNCertProperty, kTestValue);
588 driver_->InitClientAuthOptions(&options);
589 ExpectNotInFlags(options, "--auth-user-pass");
590 ExpectNotInFlags(options, "--key");
591 ExpectInFlags(options, "--cert", kTestValue);
592
593 // Key available, no user/password.
594 options.clear();
595 SetArg(OpenVPNDriver::kOpenVPNKeyProperty, kTestValue);
596 driver_->InitClientAuthOptions(&options);
597 ExpectNotInFlags(options, "--auth-user-pass");
598 ExpectInFlags(options, "--key", kTestValue);
599
600 // Key available, AuthUserPass set.
601 options.clear();
602 SetArg(flimflam::kOpenVPNAuthUserPassProperty, kTestValue);
603 driver_->InitClientAuthOptions(&options);
604 ExpectInFlags(options, "--auth-user-pass");
605 ExpectInFlags(options, "--key", kTestValue);
606
607 // Key available, User set.
608 options.clear();
609 RemoveStringArg(flimflam::kOpenVPNAuthUserPassProperty);
610 SetArg(flimflam::kOpenVPNUserProperty, "user");
611 driver_->InitClientAuthOptions(&options);
612 ExpectInFlags(options, "--auth-user-pass");
613 ExpectInFlags(options, "--key", kTestValue);
614}
615
Darin Petkove0d5dd12012-04-04 16:10:48 +0200616TEST_F(OpenVPNDriverTest, InitPKCS11Options) {
617 vector<string> options;
618 driver_->InitPKCS11Options(&options);
619 EXPECT_TRUE(options.empty());
620
621 static const char kID[] = "TestPKCS11ID";
622 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
623 driver_->InitPKCS11Options(&options);
624 ExpectInFlags(options, "--pkcs11-id", kID);
625 ExpectInFlags(options, "--pkcs11-providers", "libchaps.so");
626
627 static const char kProvider[] = "libpkcs11.so";
628 SetArg(flimflam::kOpenVPNProviderProperty, kProvider);
629 options.clear();
630 driver_->InitPKCS11Options(&options);
631 ExpectInFlags(options, "--pkcs11-id", kID);
632 ExpectInFlags(options, "--pkcs11-providers", kProvider);
633}
634
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100635TEST_F(OpenVPNDriverTest, InitManagementChannelOptionsServerFail) {
Darin Petkove0d5dd12012-04-04 16:10:48 +0200636 vector<string> options;
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100637 EXPECT_CALL(*management_server_, Start(&dispatcher_, GetSockets(), &options))
638 .WillOnce(Return(false));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200639 Error error;
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100640 EXPECT_FALSE(InitManagementChannelOptions(&options, &error));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200641 EXPECT_EQ(Error::kInternalError, error.type());
642 EXPECT_EQ("Unable to setup management channel.", error.message());
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100643}
Darin Petkove0d5dd12012-04-04 16:10:48 +0200644
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100645TEST_F(OpenVPNDriverTest, InitManagementChannelOptionsOnline) {
646 vector<string> options;
647 EXPECT_CALL(*management_server_, Start(&dispatcher_, GetSockets(), &options))
648 .WillOnce(Return(true));
649 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200650 EXPECT_CALL(*management_server_, ReleaseHold());
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100651 Error error;
652 EXPECT_TRUE(InitManagementChannelOptions(&options, &error));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200653 EXPECT_TRUE(error.IsSuccess());
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100654}
Darin Petkova5e07ef2012-07-09 14:27:57 +0200655
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100656TEST_F(OpenVPNDriverTest, InitManagementChannelOptionsOffline) {
657 vector<string> options;
658 EXPECT_CALL(*management_server_, Start(&dispatcher_, GetSockets(), &options))
659 .WillOnce(Return(true));
660 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200661 EXPECT_CALL(*management_server_, ReleaseHold()).Times(0);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100662 Error error;
663 EXPECT_TRUE(InitManagementChannelOptions(&options, &error));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200664 EXPECT_TRUE(error.IsSuccess());
Darin Petkovfe6a9372012-02-28 16:25:06 +0100665}
666
Darin Petkov55771b72012-04-25 09:25:19 +0200667TEST_F(OpenVPNDriverTest, InitLoggingOptions) {
668 vector<string> options;
669 bool vpn_logging = SLOG_IS_ON(VPN, 0);
670 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
671 driver_->InitLoggingOptions(&options);
672 ASSERT_EQ(1, options.size());
673 EXPECT_EQ("--syslog", options[0]);
674 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
675 options.clear();
676 driver_->InitLoggingOptions(&options);
677 ExpectInFlags(options, "--verb", "3");
678 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
679 SetArg("OpenVPN.Verb", "2");
680 options.clear();
681 driver_->InitLoggingOptions(&options);
682 ExpectInFlags(options, "--verb", "2");
683 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
684 SetArg("OpenVPN.Verb", "1");
685 options.clear();
686 driver_->InitLoggingOptions(&options);
687 ExpectInFlags(options, "--verb", "1");
688 if (!vpn_logging) {
689 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
690 }
691}
692
Darin Petkovfe6a9372012-02-28 16:25:06 +0100693TEST_F(OpenVPNDriverTest, AppendValueOption) {
694 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200695 EXPECT_FALSE(
696 driver_->AppendValueOption("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100697 EXPECT_TRUE(options.empty());
698
Darin Petkove0d5dd12012-04-04 16:10:48 +0200699 SetArg(kProperty, "");
Darin Petkov46463022012-03-29 14:57:32 +0200700 EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100701 EXPECT_TRUE(options.empty());
702
Darin Petkove0d5dd12012-04-04 16:10:48 +0200703 SetArg(kProperty, kValue);
704 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200705 EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
706 EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100707 EXPECT_EQ(4, options.size());
708 EXPECT_EQ(kOption, options[0]);
709 EXPECT_EQ(kValue, options[1]);
710 EXPECT_EQ(kOption2, options[2]);
711 EXPECT_EQ(kValue2, options[3]);
712}
713
714TEST_F(OpenVPNDriverTest, AppendFlag) {
715 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200716 EXPECT_FALSE(
717 driver_->AppendFlag("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100718 EXPECT_TRUE(options.empty());
719
Darin Petkove0d5dd12012-04-04 16:10:48 +0200720 SetArg(kProperty, "");
721 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200722 EXPECT_TRUE(driver_->AppendFlag(kProperty, kOption, &options));
723 EXPECT_TRUE(driver_->AppendFlag(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100724 EXPECT_EQ(2, options.size());
725 EXPECT_EQ(kOption, options[0]);
726 EXPECT_EQ(kOption2, options[1]);
727}
728
Paul Stewartca6abd42012-03-01 15:45:29 -0800729TEST_F(OpenVPNDriverTest, ClaimInterface) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100730 driver_->tunnel_interface_ = kInterfaceName;
731 EXPECT_FALSE(driver_->ClaimInterface(string(kInterfaceName) + "XXX",
732 kInterfaceIndex));
733 EXPECT_FALSE(driver_->device_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800734
Darin Petkov36a3ace2012-03-06 17:22:14 +0100735 static const char kHost[] = "192.168.2.254";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200736 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov46463022012-03-29 14:57:32 +0200737 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100738 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
Darin Petkov36a3ace2012-03-06 17:22:14 +0100739 EXPECT_CALL(glib_, SpawnAsyncWithPipesCWD(_, _, _, _, _, _, _, _, _, _))
740 .WillOnce(Return(true));
741 EXPECT_CALL(glib_, ChildWatchAdd(_, _, _)).WillOnce(Return(1));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200742 const int kServiceCallbackTag = 1;
743 EXPECT_EQ(0, driver_->default_service_callback_tag_);
744 EXPECT_CALL(manager_, RegisterDefaultServiceCallback(_))
745 .WillOnce(Return(kServiceCallbackTag));
Darin Petkov79d74c92012-03-07 17:20:32 +0100746 EXPECT_TRUE(driver_->ClaimInterface(kInterfaceName, kInterfaceIndex));
747 ASSERT_TRUE(driver_->device_);
748 EXPECT_EQ(kInterfaceIndex, driver_->device_->interface_index());
Darin Petkova5e07ef2012-07-09 14:27:57 +0200749 EXPECT_EQ(kServiceCallbackTag, driver_->default_service_callback_tag_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800750}
751
Darin Petkov36a3ace2012-03-06 17:22:14 +0100752TEST_F(OpenVPNDriverTest, Cleanup) {
Darin Petkov1fa81942012-04-02 11:38:08 +0200753 driver_->Cleanup(Service::kStateIdle); // Ensure no crash.
754
Darin Petkova5e07ef2012-07-09 14:27:57 +0200755 const unsigned int kChildTag = 123;
Darin Petkov36a3ace2012-03-06 17:22:14 +0100756 const int kPID = 123456;
Darin Petkova5e07ef2012-07-09 14:27:57 +0200757 const int kServiceCallbackTag = 5;
758 driver_->default_service_callback_tag_ = kServiceCallbackTag;
759 driver_->child_watch_tag_ = kChildTag;
Darin Petkov79d74c92012-03-07 17:20:32 +0100760 driver_->pid_ = kPID;
761 driver_->rpc_task_.reset(new RPCTask(&control_, this));
762 driver_->tunnel_interface_ = kInterfaceName;
763 driver_->device_ = device_;
764 driver_->service_ = service_;
Darin Petkov3189a472012-10-05 09:55:33 +0200765 driver_->ip_properties_.address = "1.2.3.4";
Darin Petkov602303f2012-06-06 12:15:59 +0200766 driver_->StartConnectTimeout();
Darin Petkov1fa81942012-04-02 11:38:08 +0200767 FilePath tls_auth_file;
768 EXPECT_TRUE(file_util::CreateTemporaryFile(&tls_auth_file));
769 EXPECT_FALSE(tls_auth_file.empty());
770 EXPECT_TRUE(file_util::PathExists(tls_auth_file));
771 driver_->tls_auth_file_ = tls_auth_file;
Darin Petkov46463022012-03-29 14:57:32 +0200772 // Stop will be called twice -- once by Cleanup and once by the destructor.
773 EXPECT_CALL(*management_server_, Stop()).Times(2);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200774 EXPECT_CALL(glib_, SourceRemove(kChildTag));
775 EXPECT_CALL(manager_, DeregisterDefaultServiceCallback(kServiceCallbackTag));
Darin Petkov5a850472012-06-06 15:44:24 +0200776 EXPECT_CALL(process_killer_, Kill(kPID, _));
777 EXPECT_CALL(device_info_, DeleteInterface(_)).Times(0);
Darin Petkov029d3532012-04-18 14:38:04 +0200778 EXPECT_CALL(*device_, OnDisconnected());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500779 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov79d74c92012-03-07 17:20:32 +0100780 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
Darin Petkov3f9131c2012-03-20 11:37:32 +0100781 driver_->Cleanup(Service::kStateFailure);
Darin Petkov79d74c92012-03-07 17:20:32 +0100782 EXPECT_EQ(0, driver_->child_watch_tag_);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200783 EXPECT_EQ(0, driver_->default_service_callback_tag_);
Darin Petkov79d74c92012-03-07 17:20:32 +0100784 EXPECT_EQ(0, driver_->pid_);
785 EXPECT_FALSE(driver_->rpc_task_.get());
786 EXPECT_TRUE(driver_->tunnel_interface_.empty());
787 EXPECT_FALSE(driver_->device_);
788 EXPECT_FALSE(driver_->service_);
Darin Petkov1fa81942012-04-02 11:38:08 +0200789 EXPECT_FALSE(file_util::PathExists(tls_auth_file));
790 EXPECT_TRUE(driver_->tls_auth_file_.empty());
Darin Petkov3189a472012-10-05 09:55:33 +0200791 EXPECT_TRUE(driver_->ip_properties_.address.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 Petkov4cbff5b2013-01-29 16:29:05 +0100817 EXPECT_CALL(manager_, IsOnline()).Times(2).WillRepeatedly(Return(false));
Darin Petkov36a3ace2012-03-06 17:22:14 +0100818
819 const int kPID = 234678;
Darin Petkov1a462de2012-05-02 11:10:48 +0200820 EXPECT_CALL(glib_,
821 SpawnAsyncWithPipesCWD(_, CheckEnv(), _, _, _, _, _, _, _, _))
Darin Petkov36a3ace2012-03-06 17:22:14 +0100822 .WillOnce(Return(false))
823 .WillOnce(DoAll(SetArgumentPointee<5>(kPID), Return(true)));
824 const int kTag = 6;
Darin Petkov79d74c92012-03-07 17:20:32 +0100825 EXPECT_CALL(glib_, ChildWatchAdd(kPID, &driver_->OnOpenVPNDied, driver_))
Darin Petkov36a3ace2012-03-06 17:22:14 +0100826 .WillOnce(Return(kTag));
Darin Petkov79d74c92012-03-07 17:20:32 +0100827 EXPECT_FALSE(driver_->SpawnOpenVPN());
828 EXPECT_TRUE(driver_->SpawnOpenVPN());
829 EXPECT_EQ(kPID, driver_->pid_);
830 EXPECT_EQ(kTag, driver_->child_watch_tag_);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100831}
832
833TEST_F(OpenVPNDriverTest, OnOpenVPNDied) {
834 const int kPID = 99999;
Darin Petkov5a850472012-06-06 15:44:24 +0200835 driver_->device_ = device_;
Darin Petkov79d74c92012-03-07 17:20:32 +0100836 driver_->child_watch_tag_ = 333;
837 driver_->pid_ = kPID;
Darin Petkov5a850472012-06-06 15:44:24 +0200838 EXPECT_CALL(*device_, OnDisconnected());
839 EXPECT_CALL(*device_, SetEnabled(false));
840 EXPECT_CALL(process_killer_, Kill(_, _)).Times(0);
841 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
Darin Petkov79d74c92012-03-07 17:20:32 +0100842 OpenVPNDriver::OnOpenVPNDied(kPID, 2, driver_);
843 EXPECT_EQ(0, driver_->child_watch_tag_);
844 EXPECT_EQ(0, driver_->pid_);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100845}
846
Darin Petkov6aa21872012-03-09 16:10:19 +0100847TEST_F(OpenVPNDriverTest, Disconnect) {
848 driver_->device_ = device_;
849 driver_->service_ = service_;
Darin Petkov029d3532012-04-18 14:38:04 +0200850 EXPECT_CALL(*device_, OnDisconnected());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500851 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov6aa21872012-03-09 16:10:19 +0100852 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
853 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
854 driver_->Disconnect();
Darin Petkova0e645e2012-04-25 11:38:59 +0200855 EXPECT_FALSE(driver_->device_);
Darin Petkov6aa21872012-03-09 16:10:19 +0100856 EXPECT_FALSE(driver_->service_);
857}
858
Darin Petkov5eb05422012-05-11 15:45:25 +0200859TEST_F(OpenVPNDriverTest, OnConnectionDisconnected) {
860 driver_->service_ = service_;
861 EXPECT_CALL(*service_, SetState(Service::kStateFailure));
862 driver_->OnConnectionDisconnected();
863 EXPECT_FALSE(driver_->service_);
864}
865
Darin Petkov271fe522012-03-27 13:47:29 +0200866TEST_F(OpenVPNDriverTest, OnReconnecting) {
867 driver_->OnReconnecting(); // Expect no crash.
868 driver_->device_ = device_;
869 driver_->service_ = service_;
870 EXPECT_CALL(*device_, OnDisconnected());
871 EXPECT_CALL(*service_, SetState(Service::kStateAssociating));
872 driver_->OnReconnecting();
Darin Petkov602303f2012-06-06 12:15:59 +0200873 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov271fe522012-03-27 13:47:29 +0200874}
875
Paul Stewart291a4732012-03-14 19:19:02 -0700876TEST_F(OpenVPNDriverTest, VerifyPaths) {
877 // Ensure that the various path constants that the OpenVPN driver uses
Darin Petkova0e645e2012-04-25 11:38:59 +0200878 // actually exists in the build image. Due to build dependencies, they should
879 // already exist by the time we run unit tests.
Paul Stewart291a4732012-03-14 19:19:02 -0700880
Darin Petkova0e645e2012-04-25 11:38:59 +0200881 // The OpenVPNDriver path constants are absolute. FilePath::Append asserts
882 // that its argument is not an absolute path, so we need to strip the leading
883 // separators. There's nothing built into FilePath to do so.
884 static const char *kPaths[] = {
885 OpenVPNDriver::kOpenVPNPath,
886 OpenVPNDriver::kOpenVPNScript,
887 };
888 for (size_t i = 0; i < arraysize(kPaths); i++) {
889 string path(kPaths[i]);
890 TrimString(path, FilePath::kSeparators, &path);
891 EXPECT_TRUE(file_util::PathExists(FilePath(SYSROOT).Append(path)))
892 << kPaths[i];
893 }
Paul Stewart291a4732012-03-14 19:19:02 -0700894}
895
Darin Petkovd4325392012-04-23 15:48:22 +0200896TEST_F(OpenVPNDriverTest, InitPropertyStore) {
897 // Sanity test property store initialization.
898 PropertyStore store;
899 driver_->InitPropertyStore(&store);
900 const string kUser = "joe";
901 Error error;
902 EXPECT_TRUE(
903 store.SetStringProperty(flimflam::kOpenVPNUserProperty, kUser, &error));
904 EXPECT_TRUE(error.IsSuccess());
Darin Petkovb536a742012-04-26 11:31:28 +0200905 EXPECT_EQ(kUser, GetArgs()->LookupString(flimflam::kOpenVPNUserProperty, ""));
906}
907
908TEST_F(OpenVPNDriverTest, GetProvider) {
909 PropertyStore store;
910 driver_->InitPropertyStore(&store);
911 {
Darin Petkovb536a742012-04-26 11:31:28 +0200912 KeyValueStore props;
Paul Stewarte6e8e492013-01-17 11:00:50 -0800913 Error error;
Darin Petkovb536a742012-04-26 11:31:28 +0200914 EXPECT_TRUE(
Paul Stewarte6e8e492013-01-17 11:00:50 -0800915 store.GetKeyValueStoreProperty(
916 flimflam::kProviderProperty, &props, &error));
Darin Petkovb536a742012-04-26 11:31:28 +0200917 EXPECT_TRUE(props.LookupBool(flimflam::kPassphraseRequiredProperty, false));
918 }
919 {
Darin Petkovb536a742012-04-26 11:31:28 +0200920 KeyValueStore props;
921 SetArg(flimflam::kOpenVPNPasswordProperty, "random-password");
Paul Stewarte6e8e492013-01-17 11:00:50 -0800922 Error error;
Darin Petkovb536a742012-04-26 11:31:28 +0200923 EXPECT_TRUE(
Paul Stewarte6e8e492013-01-17 11:00:50 -0800924 store.GetKeyValueStoreProperty(
925 flimflam::kProviderProperty, &props, &error));
Darin Petkovb536a742012-04-26 11:31:28 +0200926 EXPECT_FALSE(props.LookupBool(flimflam::kPassphraseRequiredProperty, true));
Darin Petkov02236552012-06-11 13:15:19 +0200927 EXPECT_FALSE(props.ContainsString(flimflam::kOpenVPNPasswordProperty));
Darin Petkovb536a742012-04-26 11:31:28 +0200928 }
Darin Petkovd4325392012-04-23 15:48:22 +0200929}
930
Darin Petkov1a462de2012-05-02 11:10:48 +0200931TEST_F(OpenVPNDriverTest, ParseLSBRelease) {
932 SetupLSBRelease();
933 map<string, string> lsb_release;
934 EXPECT_TRUE(driver_->ParseLSBRelease(&lsb_release));
935 EXPECT_TRUE(ContainsKey(lsb_release, "foo") && lsb_release["foo"] == "");
936 EXPECT_EQ("=", lsb_release["zoo"]);
937 EXPECT_EQ("Chromium OS", lsb_release[OpenVPNDriver::kChromeOSReleaseName]);
938 EXPECT_EQ("2202.0", lsb_release[OpenVPNDriver::kChromeOSReleaseVersion]);
939 driver_->lsb_release_file_ = FilePath("/non/existent/file");
940 EXPECT_FALSE(driver_->ParseLSBRelease(NULL));
941}
942
943TEST_F(OpenVPNDriverTest, InitEnvironment) {
944 vector<string> env;
945 SetupLSBRelease();
946 driver_->InitEnvironment(&env);
947 ASSERT_EQ(2, env.size());
948 EXPECT_EQ("IV_PLAT=Chromium OS", env[0]);
949 EXPECT_EQ("IV_PLAT_REL=2202.0", env[1]);
950 env.clear();
951 EXPECT_EQ(0, file_util::WriteFile(lsb_release_file_, "", 0));
952 driver_->InitEnvironment(&env);
953 EXPECT_EQ(0, env.size());
954}
955
Darin Petkov5a850472012-06-06 15:44:24 +0200956TEST_F(OpenVPNDriverTest, DeleteInterface) {
957 scoped_ptr<MockDeviceInfo> device_info(
958 new MockDeviceInfo(&control_, &dispatcher_, &metrics_, &manager_));
959 EXPECT_CALL(*device_info, DeleteInterface(kInterfaceIndex))
960 .WillOnce(Return(true));
961 WeakPtr<DeviceInfo> weak = device_info->AsWeakPtr();
962 EXPECT_TRUE(weak);
963 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
964 device_info.reset();
965 EXPECT_FALSE(weak);
966 // Expect no crash.
967 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
968}
969
Darin Petkova5e07ef2012-07-09 14:27:57 +0200970TEST_F(OpenVPNDriverTest, OnDefaultServiceChanged) {
971 driver_->service_ = service_;
972
973 ServiceRefPtr null_service;
974 EXPECT_CALL(*management_server_, Hold());
975 driver_->OnDefaultServiceChanged(null_service);
976
977 EXPECT_CALL(*management_server_, Hold());
978 driver_->OnDefaultServiceChanged(service_);
979
980 scoped_refptr<MockService> mock_service(
981 new MockService(&control_, &dispatcher_, &metrics_, &manager_));
982
983 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(false));
984 EXPECT_CALL(*management_server_, Hold());
985 driver_->OnDefaultServiceChanged(mock_service);
986
987 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(true));
988 EXPECT_CALL(*management_server_, ReleaseHold());
989 driver_->OnDefaultServiceChanged(mock_service);
990}
991
Darin Petkov33af05c2012-02-28 10:10:30 +0100992} // namespace shill