blob: 4a356e96ccf78871babff70e542ddea106652839 [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 Stewart5baebb72013-03-14 11:43:29 -070020#include "shill/mock_certificate_file.h"
Paul Stewartca6abd42012-03-01 15:45:29 -080021#include "shill/mock_device_info.h"
Darin Petkov0cd0d1e2013-02-11 12:49:10 +010022#include "shill/mock_event_dispatcher.h"
Darin Petkovf20994f2012-03-05 16:12:19 +010023#include "shill/mock_glib.h"
24#include "shill/mock_manager.h"
25#include "shill/mock_metrics.h"
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020026#include "shill/mock_nss.h"
Darin Petkov46463022012-03-29 14:57:32 +020027#include "shill/mock_openvpn_management_server.h"
Darin Petkov5a850472012-06-06 15:44:24 +020028#include "shill/mock_process_killer.h"
Darin Petkova5e07ef2012-07-09 14:27:57 +020029#include "shill/mock_service.h"
Darin Petkovf3c71d72012-03-21 12:32:15 +010030#include "shill/mock_store.h"
mukesh agrawal9da07772013-05-15 14:15:17 -070031#include "shill/mock_virtual_device.h"
Darin Petkov79d74c92012-03-07 17:20:32 +010032#include "shill/mock_vpn_service.h"
Darin Petkova9b1fed2012-02-29 11:49:05 +010033#include "shill/nice_mock_control.h"
34#include "shill/rpc_task.h"
mukesh agrawal9da07772013-05-15 14:15:17 -070035#include "shill/technology.h"
36#include "shill/virtual_device.h"
Darin Petkov79d74c92012-03-07 17:20:32 +010037#include "shill/vpn_service.h"
Darin Petkov33af05c2012-02-28 10:10:30 +010038
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080039using base::FilePath;
Darin Petkov5a850472012-06-06 15:44:24 +020040using base::WeakPtr;
Darin Petkova9b1fed2012-02-29 11:49:05 +010041using std::map;
Darin Petkovfe6a9372012-02-28 16:25:06 +010042using std::string;
43using std::vector;
Paul Stewartca6abd42012-03-01 15:45:29 -080044using testing::_;
Darin Petkovf3c71d72012-03-21 12:32:15 +010045using testing::AnyNumber;
Paul Stewartca6abd42012-03-01 15:45:29 -080046using testing::DoAll;
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020047using testing::ElementsAreArray;
Darin Petkove8587e32012-07-02 13:56:07 +020048using testing::Field;
Darin Petkovf3c71d72012-03-21 12:32:15 +010049using testing::Ne;
Paul Stewartce4ec192012-03-14 12:53:46 -070050using testing::NiceMock;
Paul Stewartca6abd42012-03-01 15:45:29 -080051using testing::Return;
52using testing::SetArgumentPointee;
Paul Stewartce4ec192012-03-14 12:53:46 -070053using testing::StrictMock;
Darin Petkovfe6a9372012-02-28 16:25:06 +010054
Darin Petkov33af05c2012-02-28 10:10:30 +010055namespace shill {
56
Darin Petkova9b1fed2012-02-29 11:49:05 +010057class OpenVPNDriverTest : public testing::Test,
58 public RPCTaskDelegate {
Darin Petkov33af05c2012-02-28 10:10:30 +010059 public:
Darin Petkovfe6a9372012-02-28 16:25:06 +010060 OpenVPNDriverTest()
Darin Petkov0e9735d2012-04-24 12:33:45 +020061 : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
Thieu Le6c1e3bb2013-02-06 15:20:35 -080062 metrics_(&dispatcher_),
Darin Petkovf20994f2012-03-05 16:12:19 +010063 manager_(&control_, &dispatcher_, &metrics_, &glib_),
Darin Petkov79d74c92012-03-07 17:20:32 +010064 driver_(new OpenVPNDriver(&control_, &dispatcher_, &metrics_, &manager_,
Paul Stewart451aa7f2012-04-11 19:07:58 -070065 &device_info_, &glib_)),
Darin Petkov79d74c92012-03-07 17:20:32 +010066 service_(new MockVPNService(&control_, &dispatcher_, &metrics_,
67 &manager_, driver_)),
mukesh agrawal9da07772013-05-15 14:15:17 -070068 device_(new MockVirtualDevice(
69 &control_, &dispatcher_, &metrics_, &manager_,
70 kInterfaceName, kInterfaceIndex, Technology::kVPN)),
Paul Stewart5baebb72013-03-14 11:43:29 -070071 certificate_file_(new MockCertificateFile()),
Darin Petkov46463022012-03-29 14:57:32 +020072 management_server_(new NiceMock<MockOpenVPNManagementServer>()) {
73 driver_->management_server_.reset(management_server_);
Darin Petkov3c5e4dc2012-04-02 14:44:27 +020074 driver_->nss_ = &nss_;
Paul Stewart5baebb72013-03-14 11:43:29 -070075 driver_->certificate_file_.reset(certificate_file_); // Passes ownership.
Darin Petkov5a850472012-06-06 15:44:24 +020076 driver_->process_killer_ = &process_killer_;
Darin Petkov46463022012-03-29 14:57:32 +020077 }
Darin Petkovfe6a9372012-02-28 16:25:06 +010078
Darin Petkov33af05c2012-02-28 10:10:30 +010079 virtual ~OpenVPNDriverTest() {}
80
Darin Petkov36a3ace2012-03-06 17:22:14 +010081 virtual void TearDown() {
Darin Petkova5e07ef2012-07-09 14:27:57 +020082 driver_->default_service_callback_tag_ = 0;
Darin Petkov79d74c92012-03-07 17:20:32 +010083 driver_->child_watch_tag_ = 0;
84 driver_->pid_ = 0;
85 driver_->device_ = NULL;
86 driver_->service_ = NULL;
Darin Petkov1a462de2012-05-02 11:10:48 +020087 if (!lsb_release_file_.empty()) {
88 EXPECT_TRUE(file_util::Delete(lsb_release_file_, false));
89 lsb_release_file_.clear();
90 }
Darin Petkov36a3ace2012-03-06 17:22:14 +010091 }
Darin Petkova9b1fed2012-02-29 11:49:05 +010092
Darin Petkov33af05c2012-02-28 10:10:30 +010093 protected:
Darin Petkovfe6a9372012-02-28 16:25:06 +010094 static const char kOption[];
95 static const char kProperty[];
96 static const char kValue[];
97 static const char kOption2[];
98 static const char kProperty2[];
99 static const char kValue2[];
Darin Petkov60596742012-03-05 12:17:17 +0100100 static const char kGateway1[];
101 static const char kNetmask1[];
102 static const char kNetwork1[];
103 static const char kGateway2[];
104 static const char kNetmask2[];
105 static const char kNetwork2[];
Darin Petkov79d74c92012-03-07 17:20:32 +0100106 static const char kInterfaceName[];
107 static const int kInterfaceIndex;
Darin Petkovfe6a9372012-02-28 16:25:06 +0100108
Darin Petkovb451d6e2012-04-23 11:56:41 +0200109 void SetArg(const string &arg, const string &value) {
110 driver_->args()->SetString(arg, value);
Darin Petkovfe6a9372012-02-28 16:25:06 +0100111 }
112
Paul Stewart0f9c9302013-06-14 15:41:28 -0700113 void SetArgArray(const string &arg, const vector<string> &value) {
114 driver_->args()->SetStrings(arg, value);
115 }
116
Darin Petkovf3c71d72012-03-21 12:32:15 +0100117 KeyValueStore *GetArgs() {
Darin Petkovb451d6e2012-04-23 11:56:41 +0200118 return driver_->args();
Darin Petkovf3c71d72012-03-21 12:32:15 +0100119 }
120
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200121 void RemoveStringArg(const string &arg) {
122 driver_->args()->RemoveString(arg);
123 }
124
Darin Petkov3189a472012-10-05 09:55:33 +0200125 const ServiceRefPtr &GetSelectedService() {
126 return device_->selected_service();
127 }
128
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100129 bool InitManagementChannelOptions(vector<string> *options, Error *error) {
130 return driver_->InitManagementChannelOptions(options, error);
131 }
132
133 Sockets *GetSockets() {
134 return &driver_->sockets_;
135 }
136
mukesh agrawal9da07772013-05-15 14:15:17 -0700137 void SetDevice(const VirtualDeviceRefPtr &device) {
Darin Petkova42afe32013-02-05 16:53:52 +0100138 driver_->device_ = device;
139 }
140
141 void SetService(const VPNServiceRefPtr &service) {
142 driver_->service_ = service;
143 }
144
145 VPNServiceRefPtr GetService() {
146 return driver_->service_;
147 }
148
149 void OnConnectionDisconnected() {
150 driver_->OnConnectionDisconnected();
151 }
152
153 void OnConnectTimeout() {
154 driver_->OnConnectTimeout();
155 }
156
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100157 void StartConnectTimeout(int timeout_seconds) {
158 driver_->StartConnectTimeout(timeout_seconds);
Darin Petkova42afe32013-02-05 16:53:52 +0100159 }
160
161 bool IsConnectTimeoutStarted() {
162 return driver_->IsConnectTimeoutStarted();
163 }
164
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100165 static int GetDefaultConnectTimeoutSeconds() {
166 return OpenVPNDriver::kDefaultConnectTimeoutSeconds;
167 }
168
169 static int GetReconnectOfflineTimeoutSeconds() {
170 return OpenVPNDriver::kReconnectOfflineTimeoutSeconds;
171 }
172
173 static int GetReconnectTLSErrorTimeoutSeconds() {
174 return OpenVPNDriver::kReconnectTLSErrorTimeoutSeconds;
175 }
176
177 static int GetReconnectTimeoutSeconds(OpenVPNDriver::ReconnectReason reason) {
178 return OpenVPNDriver::GetReconnectTimeoutSeconds(reason);
179 }
180
Darin Petkov1c049c72013-03-21 13:15:45 +0100181 void SetClientState(const string &state) {
182 management_server_->state_ = state;
183 }
184
Paul Stewartca6abd42012-03-01 15:45:29 -0800185 // Used to assert that a flag appears in the options.
186 void ExpectInFlags(const vector<string> &options, const string &flag,
187 const string &value);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200188 void ExpectInFlags(const vector<string> &options, const string &flag);
189 void ExpectNotInFlags(const vector<string> &options, const string &flag);
Paul Stewartca6abd42012-03-01 15:45:29 -0800190
Darin Petkov1a462de2012-05-02 11:10:48 +0200191 void SetupLSBRelease();
192
Darin Petkov36a3ace2012-03-06 17:22:14 +0100193 // Inherited from RPCTaskDelegate.
Darin Petkov209e6292012-04-20 11:33:32 +0200194 virtual void GetLogin(string *user, string *password);
Darin Petkov36a3ace2012-03-06 17:22:14 +0100195 virtual void Notify(const string &reason, const map<string, string> &dict);
Paul Stewartca6abd42012-03-01 15:45:29 -0800196
Darin Petkova9b1fed2012-02-29 11:49:05 +0100197 NiceMockControl control_;
Darin Petkov0e9735d2012-04-24 12:33:45 +0200198 NiceMock<MockDeviceInfo> device_info_;
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100199 MockEventDispatcher dispatcher_;
Darin Petkovf20994f2012-03-05 16:12:19 +0100200 MockMetrics metrics_;
201 MockGLib glib_;
202 MockManager manager_;
Darin Petkov46463022012-03-29 14:57:32 +0200203 OpenVPNDriver *driver_; // Owned by |service_|.
Darin Petkov79d74c92012-03-07 17:20:32 +0100204 scoped_refptr<MockVPNService> service_;
mukesh agrawal9da07772013-05-15 14:15:17 -0700205 scoped_refptr<MockVirtualDevice> device_;
Paul Stewart5baebb72013-03-14 11:43:29 -0700206 MockCertificateFile *certificate_file_; // Owned by |driver_|.
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200207 MockNSS nss_;
Darin Petkov5a850472012-06-06 15:44:24 +0200208 MockProcessKiller process_killer_;
Darin Petkov46463022012-03-29 14:57:32 +0200209
210 // Owned by |driver_|.
211 NiceMock<MockOpenVPNManagementServer> *management_server_;
Darin Petkov1a462de2012-05-02 11:10:48 +0200212
213 FilePath lsb_release_file_;
Darin Petkov33af05c2012-02-28 10:10:30 +0100214};
215
Darin Petkovfe6a9372012-02-28 16:25:06 +0100216const char OpenVPNDriverTest::kOption[] = "--openvpn-option";
217const char OpenVPNDriverTest::kProperty[] = "OpenVPN.SomeProperty";
218const char OpenVPNDriverTest::kValue[] = "some-property-value";
219const char OpenVPNDriverTest::kOption2[] = "--openvpn-option2";
220const char OpenVPNDriverTest::kProperty2[] = "OpenVPN.SomeProperty2";
221const char OpenVPNDriverTest::kValue2[] = "some-property-value2";
Darin Petkov60596742012-03-05 12:17:17 +0100222const char OpenVPNDriverTest::kGateway1[] = "10.242.2.13";
223const char OpenVPNDriverTest::kNetmask1[] = "255.255.255.255";
224const char OpenVPNDriverTest::kNetwork1[] = "10.242.2.1";
225const char OpenVPNDriverTest::kGateway2[] = "10.242.2.14";
226const char OpenVPNDriverTest::kNetmask2[] = "255.255.0.0";
227const char OpenVPNDriverTest::kNetwork2[] = "192.168.0.0";
Darin Petkov79d74c92012-03-07 17:20:32 +0100228const char OpenVPNDriverTest::kInterfaceName[] = "tun0";
229const int OpenVPNDriverTest::kInterfaceIndex = 123;
Darin Petkovfe6a9372012-02-28 16:25:06 +0100230
Darin Petkov209e6292012-04-20 11:33:32 +0200231void OpenVPNDriverTest::GetLogin(string */*user*/, string */*password*/) {}
232
Darin Petkova9b1fed2012-02-29 11:49:05 +0100233void OpenVPNDriverTest::Notify(const string &/*reason*/,
234 const map<string, string> &/*dict*/) {}
235
Paul Stewartca6abd42012-03-01 15:45:29 -0800236void OpenVPNDriverTest::ExpectInFlags(const vector<string> &options,
237 const string &flag,
238 const string &value) {
239 vector<string>::const_iterator it =
240 std::find(options.begin(), options.end(), flag);
241
242 EXPECT_TRUE(it != options.end());
243 if (it != options.end())
Darin Petkov36a3ace2012-03-06 17:22:14 +0100244 return; // Don't crash below.
Paul Stewartca6abd42012-03-01 15:45:29 -0800245 it++;
246 EXPECT_TRUE(it != options.end());
247 if (it != options.end())
Darin Petkov36a3ace2012-03-06 17:22:14 +0100248 return; // Don't crash below.
Paul Stewartca6abd42012-03-01 15:45:29 -0800249 EXPECT_EQ(value, *it);
250}
251
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200252void OpenVPNDriverTest::ExpectInFlags(const vector<string> &options,
253 const string &flag) {
254 EXPECT_TRUE(std::find(options.begin(), options.end(), flag) !=
255 options.end());
256}
257
258void OpenVPNDriverTest::ExpectNotInFlags(const vector<string> &options,
259 const string &flag) {
260 EXPECT_TRUE(std::find(options.begin(), options.end(), flag) ==
261 options.end());
262}
263
Darin Petkov1a462de2012-05-02 11:10:48 +0200264void OpenVPNDriverTest::SetupLSBRelease() {
265 static const char kLSBReleaseContents[] =
266 "\n"
267 "=\n"
268 "foo=\n"
269 "=bar\n"
270 "zoo==\n"
271 "CHROMEOS_RELEASE_BOARD=x86-alex\n"
272 "CHROMEOS_RELEASE_NAME=Chromium OS\n"
273 "CHROMEOS_RELEASE_VERSION=2202.0\n";
274 EXPECT_TRUE(file_util::CreateTemporaryFile(&lsb_release_file_));
275 EXPECT_EQ(arraysize(kLSBReleaseContents),
276 file_util::WriteFile(lsb_release_file_,
277 kLSBReleaseContents,
278 arraysize(kLSBReleaseContents)));
279 EXPECT_EQ(OpenVPNDriver::kLSBReleaseFile, driver_->lsb_release_file_.value());
280 driver_->lsb_release_file_ = lsb_release_file_;
281}
282
Darin Petkov33af05c2012-02-28 10:10:30 +0100283TEST_F(OpenVPNDriverTest, Connect) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100284 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
285 const string interface = kInterfaceName;
Darin Petkovf20994f2012-03-05 16:12:19 +0100286 EXPECT_CALL(device_info_, CreateTunnelInterface(_))
Darin Petkov79d74c92012-03-07 17:20:32 +0100287 .WillOnce(DoAll(SetArgumentPointee<0>(interface), Return(true)));
288 Error error;
289 driver_->Connect(service_, &error);
290 EXPECT_TRUE(error.IsSuccess());
291 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
Darin Petkov602303f2012-06-06 12:15:59 +0200292 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov79d74c92012-03-07 17:20:32 +0100293}
294
295TEST_F(OpenVPNDriverTest, ConnectTunnelFailure) {
296 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200297 EXPECT_CALL(device_info_, CreateTunnelInterface(_)).WillOnce(Return(false));
Darin Petkov1c049c72013-03-21 13:15:45 +0100298 EXPECT_CALL(*service_, SetFailure(Service::kFailureInternal));
Darin Petkov79d74c92012-03-07 17:20:32 +0100299 Error error;
300 driver_->Connect(service_, &error);
301 EXPECT_EQ(Error::kInternalError, error.type());
302 EXPECT_TRUE(driver_->tunnel_interface_.empty());
Darin Petkov602303f2012-06-06 12:15:59 +0200303 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov33af05c2012-02-28 10:10:30 +0100304}
305
Darin Petkov0e9735d2012-04-24 12:33:45 +0200306namespace {
307MATCHER_P(IsIPAddress, address, "") {
308 IPAddress ip_address(IPAddress::kFamilyIPv4);
309 EXPECT_TRUE(ip_address.SetAddressFromString(address));
310 return ip_address.Equals(arg);
311}
312} // namespace
313
Darin Petkov14c29ec2012-03-02 11:34:19 +0100314TEST_F(OpenVPNDriverTest, Notify) {
Darin Petkov0e9735d2012-04-24 12:33:45 +0200315 map<string, string> config;
Darin Petkov3189a472012-10-05 09:55:33 +0200316 driver_->service_ = service_;
Darin Petkov79d74c92012-03-07 17:20:32 +0100317 driver_->device_ = device_;
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100318 StartConnectTimeout(0);
Darin Petkove8587e32012-07-02 13:56:07 +0200319 EXPECT_CALL(*device_,
320 UpdateIPConfig(Field(&IPConfig::Properties::address, "")));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200321 driver_->Notify("up", config);
Darin Petkov602303f2012-06-06 12:15:59 +0200322 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov3189a472012-10-05 09:55:33 +0200323 EXPECT_TRUE(GetSelectedService().get() == service_.get());
Darin Petkove8587e32012-07-02 13:56:07 +0200324
325 // Tests that existing properties are reused if no new ones provided.
Darin Petkov3189a472012-10-05 09:55:33 +0200326 driver_->ip_properties_.address = "1.2.3.4";
Darin Petkove8587e32012-07-02 13:56:07 +0200327 EXPECT_CALL(*device_,
328 UpdateIPConfig(Field(&IPConfig::Properties::address, "1.2.3.4")));
329 driver_->Notify("up", config);
Darin Petkov79d74c92012-03-07 17:20:32 +0100330}
331
Paul Stewart91a43cb2013-03-02 21:34:15 -0800332TEST_F(OpenVPNDriverTest, NotifyUMA) {
333 map<string, string> config;
334 driver_->service_ = service_;
335 driver_->device_ = device_;
336
337 // Check that UMA metrics are emitted on Notify.
338 EXPECT_CALL(*device_, UpdateIPConfig(_));
339 EXPECT_CALL(metrics_, SendEnumToUMA(
340 Metrics::kMetricVpnDriver,
341 Metrics::kVpnDriverOpenVpn,
342 Metrics::kMetricVpnDriverMax));
343 EXPECT_CALL(metrics_, SendEnumToUMA(
344 Metrics::kMetricVpnRemoteAuthenticationType,
345 Metrics::kVpnRemoteAuthenticationTypeOpenVpnCertificate,
346 Metrics::kVpnRemoteAuthenticationTypeMax));
347 EXPECT_CALL(metrics_, SendEnumToUMA(
348 Metrics::kMetricVpnUserAuthenticationType,
349 Metrics::kVpnUserAuthenticationTypeOpenVpnUsernamePassword,
350 Metrics::kVpnUserAuthenticationTypeMax));
351
352 Error unused_error;
353 PropertyStore store;
354 driver_->InitPropertyStore(&store);
Paul Stewarte8e71da2013-03-20 08:48:33 -0700355 store.SetStringProperty(flimflam::kOpenVPNCaCertProperty, "x",
Paul Stewart91a43cb2013-03-02 21:34:15 -0800356 &unused_error);
Paul Stewarte8e71da2013-03-20 08:48:33 -0700357 store.SetStringProperty(flimflam::kOpenVPNUserProperty, "y",
Paul Stewart91a43cb2013-03-02 21:34:15 -0800358 &unused_error);
359 driver_->Notify("up", config);
360}
361
Darin Petkov79d74c92012-03-07 17:20:32 +0100362TEST_F(OpenVPNDriverTest, NotifyFail) {
363 map<string, string> dict;
364 driver_->device_ = device_;
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100365 StartConnectTimeout(0);
mukesh agrawal9da07772013-05-15 14:15:17 -0700366 EXPECT_CALL(*device_, DropConnection());
Darin Petkov79d74c92012-03-07 17:20:32 +0100367 driver_->Notify("fail", dict);
Darin Petkov602303f2012-06-06 12:15:59 +0200368 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100369}
370
Darin Petkov60596742012-03-05 12:17:17 +0100371TEST_F(OpenVPNDriverTest, GetRouteOptionEntry) {
372 OpenVPNDriver::RouteOptions routes;
373 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "bar", &routes));
374 EXPECT_TRUE(routes.empty());
375 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "foo", &routes));
376 EXPECT_TRUE(routes.empty());
377 EXPECT_EQ(NULL, OpenVPNDriver::GetRouteOptionEntry("foo", "fooZ", &routes));
378 EXPECT_TRUE(routes.empty());
379 IPConfig::Route *route =
380 OpenVPNDriver::GetRouteOptionEntry("foo", "foo12", &routes);
381 EXPECT_EQ(1, routes.size());
382 EXPECT_EQ(route, &routes[12]);
383 route = OpenVPNDriver::GetRouteOptionEntry("foo", "foo13", &routes);
384 EXPECT_EQ(2, routes.size());
385 EXPECT_EQ(route, &routes[13]);
386}
387
388TEST_F(OpenVPNDriverTest, ParseRouteOption) {
389 OpenVPNDriver::RouteOptions routes;
390 OpenVPNDriver::ParseRouteOption("foo", "bar", &routes);
391 EXPECT_TRUE(routes.empty());
392 OpenVPNDriver::ParseRouteOption("gateway_2", kGateway2, &routes);
393 OpenVPNDriver::ParseRouteOption("netmask_2", kNetmask2, &routes);
394 OpenVPNDriver::ParseRouteOption("network_2", kNetwork2, &routes);
395 EXPECT_EQ(1, routes.size());
396 OpenVPNDriver::ParseRouteOption("gateway_1", kGateway1, &routes);
397 OpenVPNDriver::ParseRouteOption("netmask_1", kNetmask1, &routes);
398 OpenVPNDriver::ParseRouteOption("network_1", kNetwork1, &routes);
399 EXPECT_EQ(2, routes.size());
400 EXPECT_EQ(kGateway1, routes[1].gateway);
401 EXPECT_EQ(kNetmask1, routes[1].netmask);
402 EXPECT_EQ(kNetwork1, routes[1].host);
403 EXPECT_EQ(kGateway2, routes[2].gateway);
404 EXPECT_EQ(kNetmask2, routes[2].netmask);
405 EXPECT_EQ(kNetwork2, routes[2].host);
406}
407
408TEST_F(OpenVPNDriverTest, SetRoutes) {
409 OpenVPNDriver::RouteOptions routes;
410 routes[1].gateway = "1.2.3.4";
411 routes[1].host= "1.2.3.4";
412 routes[2].host = "2.3.4.5";
413 routes[2].netmask = "255.0.0.0";
414 routes[3].netmask = "255.0.0.0";
415 routes[3].gateway = "1.2.3.5";
416 routes[5].host = kNetwork2;
417 routes[5].netmask = kNetmask2;
418 routes[5].gateway = kGateway2;
419 routes[4].host = kNetwork1;
420 routes[4].netmask = kNetmask1;
421 routes[4].gateway = kGateway1;
422 IPConfig::Properties props;
423 OpenVPNDriver::SetRoutes(routes, &props);
424 ASSERT_EQ(2, props.routes.size());
425 EXPECT_EQ(kGateway1, props.routes[0].gateway);
426 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
427 EXPECT_EQ(kNetwork1, props.routes[0].host);
428 EXPECT_EQ(kGateway2, props.routes[1].gateway);
429 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
430 EXPECT_EQ(kNetwork2, props.routes[1].host);
Darin Petkove8587e32012-07-02 13:56:07 +0200431
432 // Tests that the routes are not reset if no new routes are supplied.
433 OpenVPNDriver::SetRoutes(OpenVPNDriver::RouteOptions(), &props);
434 EXPECT_EQ(2, props.routes.size());
Darin Petkov60596742012-03-05 12:17:17 +0100435}
436
Darin Petkov4b944842012-09-21 10:48:48 +0200437TEST_F(OpenVPNDriverTest, SplitPortFromHost) {
438 string name, port;
439 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", NULL, NULL));
440 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", &name, &port));
441 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com", &name, &port));
442 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:", &name, &port));
443 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost(":1234", &name, &port));
444 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:f:1234", &name, &port));
445 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:x", &name, &port));
446 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:-1", &name, &port));
447 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:+1", &name, &port));
448 EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:65536", &name, &port));
449 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("v.com:0", &name, &port));
450 EXPECT_EQ("v.com", name);
451 EXPECT_EQ("0", port);
452 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("w.com:65535", &name, &port));
453 EXPECT_EQ("w.com", name);
454 EXPECT_EQ("65535", port);
455 EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("x.com:12345", &name, &port));
456 EXPECT_EQ("x.com", name);
457 EXPECT_EQ("12345", port);
458}
459
Darin Petkov14c29ec2012-03-02 11:34:19 +0100460TEST_F(OpenVPNDriverTest, ParseForeignOption) {
Darin Petkove8587e32012-07-02 13:56:07 +0200461 vector<string> domain_search;
462 vector<string> dns_servers;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100463 IPConfig::Properties props;
Darin Petkove8587e32012-07-02 13:56:07 +0200464 OpenVPNDriver::ParseForeignOption("", &domain_search, &dns_servers);
465 OpenVPNDriver::ParseForeignOption(
466 "dhcp-option DOMAIN", &domain_search, &dns_servers);
467 OpenVPNDriver::ParseForeignOption(
468 "dhcp-option DOMAIN zzz.com foo", &domain_search, &dns_servers);
469 OpenVPNDriver::ParseForeignOption(
470 "dhcp-Option DOmAIN xyz.com", &domain_search, &dns_servers);
471 ASSERT_EQ(1, domain_search.size());
472 EXPECT_EQ("xyz.com", domain_search[0]);
473 OpenVPNDriver::ParseForeignOption(
474 "dhcp-option DnS 1.2.3.4", &domain_search, &dns_servers);
475 ASSERT_EQ(1, dns_servers.size());
476 EXPECT_EQ("1.2.3.4", dns_servers[0]);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100477}
478
479TEST_F(OpenVPNDriverTest, ParseForeignOptions) {
Darin Petkove8587e32012-07-02 13:56:07 +0200480 // This also tests that std::map is a sorted container.
Darin Petkov14c29ec2012-03-02 11:34:19 +0100481 map<int, string> options;
482 options[5] = "dhcp-option DOMAIN five.com";
483 options[2] = "dhcp-option DOMAIN two.com";
484 options[8] = "dhcp-option DOMAIN eight.com";
485 options[7] = "dhcp-option DOMAIN seven.com";
486 options[4] = "dhcp-option DOMAIN four.com";
Darin Petkove8587e32012-07-02 13:56:07 +0200487 options[10] = "dhcp-option dns 1.2.3.4";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100488 IPConfig::Properties props;
489 OpenVPNDriver::ParseForeignOptions(options, &props);
490 ASSERT_EQ(5, props.domain_search.size());
491 EXPECT_EQ("two.com", props.domain_search[0]);
492 EXPECT_EQ("four.com", props.domain_search[1]);
493 EXPECT_EQ("five.com", props.domain_search[2]);
494 EXPECT_EQ("seven.com", props.domain_search[3]);
495 EXPECT_EQ("eight.com", props.domain_search[4]);
Darin Petkove8587e32012-07-02 13:56:07 +0200496 ASSERT_EQ(1, props.dns_servers.size());
497 EXPECT_EQ("1.2.3.4", props.dns_servers[0]);
498
499 // Test that the DNS properties are not updated if no new DNS properties are
500 // supplied.
501 OpenVPNDriver::ParseForeignOptions(map<int, string>(), &props);
502 EXPECT_EQ(5, props.domain_search.size());
503 ASSERT_EQ(1, props.dns_servers.size());
Darin Petkov14c29ec2012-03-02 11:34:19 +0100504}
505
506TEST_F(OpenVPNDriverTest, ParseIPConfiguration) {
507 map<string, string> config;
Darin Petkove8587e32012-07-02 13:56:07 +0200508 IPConfig::Properties props;
509
510 OpenVPNDriver::ParseIPConfiguration(config, &props);
511 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
512 EXPECT_EQ(32, props.subnet_prefix);
513
514 props.subnet_prefix = 18;
515 OpenVPNDriver::ParseIPConfiguration(config, &props);
516 EXPECT_EQ(18, props.subnet_prefix);
517
Paul Stewart4698c1a2013-05-16 15:42:19 -0700518 // An "ifconfig_remote" parameter that looks like a netmask should be
519 // applied to the subnet prefix instead of to the peer address.
520 config["ifconfig_remotE"] = "255.255.0.0";
521 OpenVPNDriver::ParseIPConfiguration(config, &props);
522 EXPECT_EQ(16, props.subnet_prefix);
523 EXPECT_EQ("", props.peer_address);
524
Darin Petkov14c29ec2012-03-02 11:34:19 +0100525 config["ifconfig_loCal"] = "4.5.6.7";
526 config["ifconfiG_broadcast"] = "1.2.255.255";
527 config["ifconFig_netmAsk"] = "255.255.255.0";
528 config["ifconfig_remotE"] = "33.44.55.66";
529 config["route_vpN_gateway"] = "192.168.1.1";
Paul Stewartce4ec192012-03-14 12:53:46 -0700530 config["trusted_ip"] = "99.88.77.66";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100531 config["tun_mtu"] = "1000";
532 config["foreign_option_2"] = "dhcp-option DNS 4.4.4.4";
533 config["foreign_option_1"] = "dhcp-option DNS 1.1.1.1";
534 config["foreign_option_3"] = "dhcp-option DNS 2.2.2.2";
Darin Petkov60596742012-03-05 12:17:17 +0100535 config["route_network_2"] = kNetwork2;
536 config["route_network_1"] = kNetwork1;
537 config["route_netmask_2"] = kNetmask2;
538 config["route_netmask_1"] = kNetmask1;
539 config["route_gateway_2"] = kGateway2;
540 config["route_gateway_1"] = kGateway1;
Darin Petkov14c29ec2012-03-02 11:34:19 +0100541 config["foo"] = "bar";
Darin Petkov14c29ec2012-03-02 11:34:19 +0100542 OpenVPNDriver::ParseIPConfiguration(config, &props);
543 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
544 EXPECT_EQ("4.5.6.7", props.address);
545 EXPECT_EQ("1.2.255.255", props.broadcast_address);
Paul Stewart48100b02012-03-19 07:53:52 -0700546 EXPECT_EQ(24, props.subnet_prefix);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100547 EXPECT_EQ("33.44.55.66", props.peer_address);
548 EXPECT_EQ("192.168.1.1", props.gateway);
Paul Stewartce4ec192012-03-14 12:53:46 -0700549 EXPECT_EQ("99.88.77.66", props.trusted_ip);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100550 EXPECT_EQ(1000, props.mtu);
551 ASSERT_EQ(3, props.dns_servers.size());
552 EXPECT_EQ("1.1.1.1", props.dns_servers[0]);
553 EXPECT_EQ("4.4.4.4", props.dns_servers[1]);
554 EXPECT_EQ("2.2.2.2", props.dns_servers[2]);
Darin Petkov60596742012-03-05 12:17:17 +0100555 ASSERT_EQ(2, props.routes.size());
556 EXPECT_EQ(kGateway1, props.routes[0].gateway);
557 EXPECT_EQ(kNetmask1, props.routes[0].netmask);
558 EXPECT_EQ(kNetwork1, props.routes[0].host);
559 EXPECT_EQ(kGateway2, props.routes[1].gateway);
560 EXPECT_EQ(kNetmask2, props.routes[1].netmask);
561 EXPECT_EQ(kNetwork2, props.routes[1].host);
Ben Chana0163122012-09-25 15:10:52 -0700562 EXPECT_FALSE(props.blackhole_ipv6);
Darin Petkov14c29ec2012-03-02 11:34:19 +0100563}
564
Darin Petkovfe6a9372012-02-28 16:25:06 +0100565TEST_F(OpenVPNDriverTest, InitOptionsNoHost) {
566 Error error;
567 vector<string> options;
Darin Petkov79d74c92012-03-07 17:20:32 +0100568 driver_->InitOptions(&options, &error);
Darin Petkovfe6a9372012-02-28 16:25:06 +0100569 EXPECT_EQ(Error::kInvalidArguments, error.type());
570 EXPECT_TRUE(options.empty());
571}
572
573TEST_F(OpenVPNDriverTest, InitOptions) {
574 static const char kHost[] = "192.168.2.254";
Darin Petkov1fa81942012-04-02 11:38:08 +0200575 static const char kTLSAuthContents[] = "SOME-RANDOM-CONTENTS\n";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200576 static const char kID[] = "TestPKCS11ID";
577 FilePath empty_cert;
578 SetArg(flimflam::kProviderHostProperty, kHost);
579 SetArg(flimflam::kOpenVPNTLSAuthContentsProperty, kTLSAuthContents);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200580 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
Darin Petkov79d74c92012-03-07 17:20:32 +0100581 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov79d74c92012-03-07 17:20:32 +0100582 driver_->tunnel_interface_ = kInterfaceName;
Darin Petkove0d5dd12012-04-04 16:10:48 +0200583 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100584 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200585
586 Error error;
587 vector<string> options;
588 driver_->InitOptions(&options, &error);
589 EXPECT_TRUE(error.IsSuccess());
590 EXPECT_EQ("--client", options[0]);
591 ExpectInFlags(options, "--remote", kHost);
Darin Petkov728faa92012-10-12 11:25:47 +0200592 ExpectInFlags(options, kRPCTaskPathVariable, RPCTaskMockAdaptor::kRpcId);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200593 ExpectInFlags(options, "--dev", kInterfaceName);
594 ExpectInFlags(options, "--group", "openvpn");
595 EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
596 ASSERT_FALSE(driver_->tls_auth_file_.empty());
597 ExpectInFlags(options, "--tls-auth", driver_->tls_auth_file_.value());
598 string contents;
599 EXPECT_TRUE(
600 file_util::ReadFileToString(driver_->tls_auth_file_, &contents));
601 EXPECT_EQ(kTLSAuthContents, contents);
602 ExpectInFlags(options, "--pkcs11-id", kID);
Darin Petkovc418b4b2012-10-05 11:42:52 +0200603 ExpectInFlags(options, "--ca", OpenVPNDriver::kDefaultCACertificates);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200604 ExpectInFlags(options, "--syslog");
Paul Stewartbb985102013-06-27 16:51:11 -0700605 ExpectNotInFlags(options, "--auth-user-pass");
Darin Petkove0d5dd12012-04-04 16:10:48 +0200606}
607
Darin Petkov4b944842012-09-21 10:48:48 +0200608TEST_F(OpenVPNDriverTest, InitOptionsHostWithPort) {
609 SetArg(flimflam::kProviderHostProperty, "v.com:1234");
610 driver_->rpc_task_.reset(new RPCTask(&control_, this));
611 driver_->tunnel_interface_ = kInterfaceName;
612 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100613 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
Darin Petkov4b944842012-09-21 10:48:48 +0200614
615 Error error;
616 vector<string> options;
617 driver_->InitOptions(&options, &error);
618 EXPECT_TRUE(error.IsSuccess());
619 vector<string>::const_iterator it =
620 std::find(options.begin(), options.end(), "--remote");
621 ASSERT_TRUE(it != options.end());
622 ASSERT_TRUE(++it != options.end());
623 EXPECT_EQ("v.com", *it);
624 ASSERT_TRUE(++it != options.end());
625 EXPECT_EQ("1234", *it);
626}
627
Darin Petkovca8a0e62012-09-26 13:16:52 +0200628TEST_F(OpenVPNDriverTest, InitCAOptions) {
Darin Petkove0d5dd12012-04-04 16:10:48 +0200629 static const char kHost[] = "192.168.2.254";
Darin Petkovca8a0e62012-09-26 13:16:52 +0200630 static const char kCaCert[] = "foo";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200631 static const char kCaCertNSS[] = "{1234}";
632 static const char kNSSCertfile[] = "/tmp/nss-cert";
Darin Petkovca8a0e62012-09-26 13:16:52 +0200633
634 Error error;
635 vector<string> options;
636 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
637 EXPECT_TRUE(error.IsSuccess());
Darin Petkovc418b4b2012-10-05 11:42:52 +0200638 ExpectInFlags(options, "--ca", OpenVPNDriver::kDefaultCACertificates);
Darin Petkovca8a0e62012-09-26 13:16:52 +0200639
640 options.clear();
641 SetArg(flimflam::kOpenVPNCaCertProperty, kCaCert);
642 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
643 ExpectInFlags(options, "--ca", kCaCert);
644 EXPECT_TRUE(error.IsSuccess());
645
646 SetArg(flimflam::kOpenVPNCaCertNSSProperty, kCaCertNSS);
647 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
648 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart5baebb72013-03-14 11:43:29 -0700649 EXPECT_EQ("Can't specify more than one of CACert, CACertNSS and CACertPEM.",
650 error.message());
Darin Petkovca8a0e62012-09-26 13:16:52 +0200651
652 SetArg(flimflam::kOpenVPNCaCertProperty, "");
653 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkove0d5dd12012-04-04 16:10:48 +0200654 FilePath empty_cert;
655 FilePath nss_cert(kNSSCertfile);
Darin Petkov3c5e4dc2012-04-02 14:44:27 +0200656 EXPECT_CALL(nss_,
657 GetPEMCertfile(kCaCertNSS,
658 ElementsAreArray(kHost, arraysize(kHost) - 1)))
Darin Petkove0d5dd12012-04-04 16:10:48 +0200659 .WillOnce(Return(empty_cert))
660 .WillOnce(Return(nss_cert));
661
Darin Petkovca8a0e62012-09-26 13:16:52 +0200662 error.Reset();
663 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
664 EXPECT_EQ(Error::kInvalidArguments, error.type());
665 EXPECT_EQ("Unable to extract NSS CA certificate: {1234}", error.message());
666
667 error.Reset();
668 options.clear();
669 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200670 ExpectInFlags(options, "--ca", kNSSCertfile);
671 EXPECT_TRUE(error.IsSuccess());
Paul Stewart5baebb72013-03-14 11:43:29 -0700672
Paul Stewart0f9c9302013-06-14 15:41:28 -0700673 const vector<string> kCaCertPEM{ "---PEM CONTENTS---" };
674 SetArgArray(kOpenVPNCaCertPemProperty, kCaCertPEM);
Paul Stewart5baebb72013-03-14 11:43:29 -0700675 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
676 EXPECT_EQ(Error::kInvalidArguments, error.type());
677 EXPECT_EQ("Can't specify more than one of CACert, CACertNSS and CACertPEM.",
678 error.message());
679
680 options.clear();
681 SetArg(flimflam::kOpenVPNCaCertNSSProperty, "");
682 SetArg(flimflam::kProviderHostProperty, "");
683 static const char kPEMCertfile[] = "/tmp/pem-cert";
684 FilePath pem_cert(kPEMCertfile);
Paul Stewart0f9c9302013-06-14 15:41:28 -0700685 EXPECT_CALL(*certificate_file_, CreatePEMFromStrings(kCaCertPEM))
Paul Stewart5baebb72013-03-14 11:43:29 -0700686 .WillOnce(Return(empty_cert))
687 .WillOnce(Return(pem_cert));
688
689 error.Reset();
690 EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
691 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart0f9c9302013-06-14 15:41:28 -0700692 EXPECT_EQ("Unable to extract PEM CA certificates.", error.message());
Paul Stewart5baebb72013-03-14 11:43:29 -0700693
694 error.Reset();
695 options.clear();
696 EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
697 ExpectInFlags(options, "--ca", kPEMCertfile);
698 EXPECT_TRUE(error.IsSuccess());
Darin Petkove0d5dd12012-04-04 16:10:48 +0200699}
700
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200701TEST_F(OpenVPNDriverTest, InitClientAuthOptions) {
702 static const char kTestValue[] = "foo";
703 vector<string> options;
704
705 // No key or cert, assume user/password authentication.
706 driver_->InitClientAuthOptions(&options);
707 ExpectInFlags(options, "--auth-user-pass");
708 ExpectNotInFlags(options, "--key");
709 ExpectNotInFlags(options, "--cert");
710
711 // Cert available, no user/password.
712 options.clear();
Paul Stewart70804412013-06-17 15:00:59 -0700713 SetArg(kOpenVPNCertProperty, kTestValue);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200714 driver_->InitClientAuthOptions(&options);
715 ExpectNotInFlags(options, "--auth-user-pass");
716 ExpectNotInFlags(options, "--key");
717 ExpectInFlags(options, "--cert", kTestValue);
718
719 // Key available, no user/password.
720 options.clear();
Paul Stewart70804412013-06-17 15:00:59 -0700721 SetArg(kOpenVPNKeyProperty, kTestValue);
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200722 driver_->InitClientAuthOptions(&options);
723 ExpectNotInFlags(options, "--auth-user-pass");
724 ExpectInFlags(options, "--key", kTestValue);
725
726 // Key available, AuthUserPass set.
727 options.clear();
728 SetArg(flimflam::kOpenVPNAuthUserPassProperty, kTestValue);
729 driver_->InitClientAuthOptions(&options);
730 ExpectInFlags(options, "--auth-user-pass");
731 ExpectInFlags(options, "--key", kTestValue);
732
733 // Key available, User set.
734 options.clear();
735 RemoveStringArg(flimflam::kOpenVPNAuthUserPassProperty);
736 SetArg(flimflam::kOpenVPNUserProperty, "user");
737 driver_->InitClientAuthOptions(&options);
738 ExpectInFlags(options, "--auth-user-pass");
739 ExpectInFlags(options, "--key", kTestValue);
Paul Stewartbb985102013-06-27 16:51:11 -0700740
741 // Empty PKCS11 certificate id, no user/password/cert.
742 options.clear();
743 RemoveStringArg(kOpenVPNKeyProperty);
744 RemoveStringArg(kOpenVPNCertProperty);
745 RemoveStringArg(flimflam::kOpenVPNUserProperty);
746 SetArg(flimflam::kOpenVPNClientCertIdProperty, "");
747 driver_->InitClientAuthOptions(&options);
748 ExpectInFlags(options, "--auth-user-pass");
749 ExpectNotInFlags(options, "--key");
750 ExpectNotInFlags(options, "--cert");
751 ExpectNotInFlags(options, "--pkcs11-id");
752
753 // Non-empty PKCS11 certificate id, no user/password/cert.
754 options.clear();
755 SetArg(flimflam::kOpenVPNClientCertIdProperty, kTestValue);
756 driver_->InitClientAuthOptions(&options);
757 ExpectNotInFlags(options, "--auth-user-pass");
758 ExpectNotInFlags(options, "--key");
759 ExpectNotInFlags(options, "--cert");
760 // The "--pkcs11-id" option is added in InitPKCS11Options(), not here.
761 ExpectNotInFlags(options, "--pkcs11-id");
762
763 // PKCS11 certificate id available, AuthUserPass set.
764 options.clear();
765 SetArg(flimflam::kOpenVPNAuthUserPassProperty, kTestValue);
766 driver_->InitClientAuthOptions(&options);
767 ExpectInFlags(options, "--auth-user-pass");
768 ExpectNotInFlags(options, "--key");
769 ExpectNotInFlags(options, "--cert");
770
771 // PKCS11 certificate id available, User set.
772 options.clear();
773 RemoveStringArg(flimflam::kOpenVPNAuthUserPassProperty);
774 SetArg(flimflam::kOpenVPNUserProperty, "user");
775 driver_->InitClientAuthOptions(&options);
776 ExpectInFlags(options, "--auth-user-pass");
777 ExpectNotInFlags(options, "--key");
778 ExpectNotInFlags(options, "--cert");
Darin Petkov4e1b3f82012-09-27 13:22:37 +0200779}
780
Darin Petkove0d5dd12012-04-04 16:10:48 +0200781TEST_F(OpenVPNDriverTest, InitPKCS11Options) {
782 vector<string> options;
783 driver_->InitPKCS11Options(&options);
784 EXPECT_TRUE(options.empty());
785
786 static const char kID[] = "TestPKCS11ID";
787 SetArg(flimflam::kOpenVPNClientCertIdProperty, kID);
788 driver_->InitPKCS11Options(&options);
789 ExpectInFlags(options, "--pkcs11-id", kID);
790 ExpectInFlags(options, "--pkcs11-providers", "libchaps.so");
791
792 static const char kProvider[] = "libpkcs11.so";
793 SetArg(flimflam::kOpenVPNProviderProperty, kProvider);
794 options.clear();
795 driver_->InitPKCS11Options(&options);
796 ExpectInFlags(options, "--pkcs11-id", kID);
797 ExpectInFlags(options, "--pkcs11-providers", kProvider);
798}
799
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100800TEST_F(OpenVPNDriverTest, InitManagementChannelOptionsServerFail) {
Darin Petkove0d5dd12012-04-04 16:10:48 +0200801 vector<string> options;
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100802 EXPECT_CALL(*management_server_, Start(&dispatcher_, GetSockets(), &options))
803 .WillOnce(Return(false));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200804 Error error;
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100805 EXPECT_FALSE(InitManagementChannelOptions(&options, &error));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200806 EXPECT_EQ(Error::kInternalError, error.type());
807 EXPECT_EQ("Unable to setup management channel.", error.message());
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100808}
Darin Petkove0d5dd12012-04-04 16:10:48 +0200809
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100810TEST_F(OpenVPNDriverTest, InitManagementChannelOptionsOnline) {
811 vector<string> options;
812 EXPECT_CALL(*management_server_, Start(&dispatcher_, GetSockets(), &options))
813 .WillOnce(Return(true));
814 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200815 EXPECT_CALL(*management_server_, ReleaseHold());
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100816 Error error;
817 EXPECT_TRUE(InitManagementChannelOptions(&options, &error));
Darin Petkove0d5dd12012-04-04 16:10:48 +0200818 EXPECT_TRUE(error.IsSuccess());
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100819}
Darin Petkova5e07ef2012-07-09 14:27:57 +0200820
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100821TEST_F(OpenVPNDriverTest, InitManagementChannelOptionsOffline) {
822 vector<string> options;
823 EXPECT_CALL(*management_server_, Start(&dispatcher_, GetSockets(), &options))
824 .WillOnce(Return(true));
825 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200826 EXPECT_CALL(*management_server_, ReleaseHold()).Times(0);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100827 Error error;
828 EXPECT_TRUE(InitManagementChannelOptions(&options, &error));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200829 EXPECT_TRUE(error.IsSuccess());
Darin Petkovfe6a9372012-02-28 16:25:06 +0100830}
831
Darin Petkov55771b72012-04-25 09:25:19 +0200832TEST_F(OpenVPNDriverTest, InitLoggingOptions) {
833 vector<string> options;
834 bool vpn_logging = SLOG_IS_ON(VPN, 0);
835 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
836 driver_->InitLoggingOptions(&options);
837 ASSERT_EQ(1, options.size());
838 EXPECT_EQ("--syslog", options[0]);
839 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
840 options.clear();
841 driver_->InitLoggingOptions(&options);
842 ExpectInFlags(options, "--verb", "3");
843 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
844 SetArg("OpenVPN.Verb", "2");
845 options.clear();
846 driver_->InitLoggingOptions(&options);
847 ExpectInFlags(options, "--verb", "2");
848 ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
849 SetArg("OpenVPN.Verb", "1");
850 options.clear();
851 driver_->InitLoggingOptions(&options);
852 ExpectInFlags(options, "--verb", "1");
853 if (!vpn_logging) {
854 ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
855 }
856}
857
Darin Petkovfe6a9372012-02-28 16:25:06 +0100858TEST_F(OpenVPNDriverTest, AppendValueOption) {
859 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200860 EXPECT_FALSE(
861 driver_->AppendValueOption("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100862 EXPECT_TRUE(options.empty());
863
Darin Petkove0d5dd12012-04-04 16:10:48 +0200864 SetArg(kProperty, "");
Darin Petkov46463022012-03-29 14:57:32 +0200865 EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100866 EXPECT_TRUE(options.empty());
867
Darin Petkove0d5dd12012-04-04 16:10:48 +0200868 SetArg(kProperty, kValue);
869 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200870 EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
871 EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100872 EXPECT_EQ(4, options.size());
873 EXPECT_EQ(kOption, options[0]);
874 EXPECT_EQ(kValue, options[1]);
875 EXPECT_EQ(kOption2, options[2]);
876 EXPECT_EQ(kValue2, options[3]);
877}
878
879TEST_F(OpenVPNDriverTest, AppendFlag) {
880 vector<string> options;
Darin Petkov46463022012-03-29 14:57:32 +0200881 EXPECT_FALSE(
882 driver_->AppendFlag("OpenVPN.UnknownProperty", kOption, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100883 EXPECT_TRUE(options.empty());
884
Darin Petkove0d5dd12012-04-04 16:10:48 +0200885 SetArg(kProperty, "");
886 SetArg(kProperty2, kValue2);
Darin Petkov46463022012-03-29 14:57:32 +0200887 EXPECT_TRUE(driver_->AppendFlag(kProperty, kOption, &options));
888 EXPECT_TRUE(driver_->AppendFlag(kProperty2, kOption2, &options));
Darin Petkovfe6a9372012-02-28 16:25:06 +0100889 EXPECT_EQ(2, options.size());
890 EXPECT_EQ(kOption, options[0]);
891 EXPECT_EQ(kOption2, options[1]);
892}
893
Paul Stewartca6abd42012-03-01 15:45:29 -0800894TEST_F(OpenVPNDriverTest, ClaimInterface) {
Darin Petkov79d74c92012-03-07 17:20:32 +0100895 driver_->tunnel_interface_ = kInterfaceName;
896 EXPECT_FALSE(driver_->ClaimInterface(string(kInterfaceName) + "XXX",
897 kInterfaceIndex));
898 EXPECT_FALSE(driver_->device_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800899
Darin Petkov36a3ace2012-03-06 17:22:14 +0100900 static const char kHost[] = "192.168.2.254";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200901 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov46463022012-03-29 14:57:32 +0200902 EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100903 EXPECT_CALL(manager_, IsOnline()).WillOnce(Return(false));
Darin Petkov68710d72013-02-13 14:22:56 +0100904 EXPECT_CALL(glib_, SpawnAsync(_, _, _, _, _, _, _, _)).WillOnce(Return(true));
Darin Petkov36a3ace2012-03-06 17:22:14 +0100905 EXPECT_CALL(glib_, ChildWatchAdd(_, _, _)).WillOnce(Return(1));
Darin Petkova5e07ef2012-07-09 14:27:57 +0200906 const int kServiceCallbackTag = 1;
907 EXPECT_EQ(0, driver_->default_service_callback_tag_);
908 EXPECT_CALL(manager_, RegisterDefaultServiceCallback(_))
909 .WillOnce(Return(kServiceCallbackTag));
Darin Petkov79d74c92012-03-07 17:20:32 +0100910 EXPECT_TRUE(driver_->ClaimInterface(kInterfaceName, kInterfaceIndex));
911 ASSERT_TRUE(driver_->device_);
912 EXPECT_EQ(kInterfaceIndex, driver_->device_->interface_index());
Darin Petkova5e07ef2012-07-09 14:27:57 +0200913 EXPECT_EQ(kServiceCallbackTag, driver_->default_service_callback_tag_);
Paul Stewartca6abd42012-03-01 15:45:29 -0800914}
915
Darin Petkovaba89322013-03-11 14:48:22 +0100916TEST_F(OpenVPNDriverTest, IdleService) {
917 SetService(service_);
Darin Petkovaba89322013-03-11 14:48:22 +0100918 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
919 driver_->IdleService();
Darin Petkovaba89322013-03-11 14:48:22 +0100920}
921
922TEST_F(OpenVPNDriverTest, FailService) {
923 static const char kErrorDetails[] = "Bad password.";
924 SetService(service_);
Darin Petkov1c049c72013-03-21 13:15:45 +0100925 EXPECT_CALL(*service_, SetFailure(Service::kFailureConnect));
926 driver_->FailService(Service::kFailureConnect, kErrorDetails);
Darin Petkovaba89322013-03-11 14:48:22 +0100927 EXPECT_EQ(kErrorDetails, service_->error_details());
928}
929
Darin Petkov36a3ace2012-03-06 17:22:14 +0100930TEST_F(OpenVPNDriverTest, Cleanup) {
Darin Petkovaba89322013-03-11 14:48:22 +0100931 // Ensure no crash.
Darin Petkov1c049c72013-03-21 13:15:45 +0100932 driver_->Cleanup(Service::kStateIdle,
933 Service::kFailureUnknown,
934 Service::kErrorDetailsNone);
Darin Petkov1fa81942012-04-02 11:38:08 +0200935
Darin Petkova5e07ef2012-07-09 14:27:57 +0200936 const unsigned int kChildTag = 123;
Darin Petkov36a3ace2012-03-06 17:22:14 +0100937 const int kPID = 123456;
Darin Petkova5e07ef2012-07-09 14:27:57 +0200938 const int kServiceCallbackTag = 5;
Darin Petkovaba89322013-03-11 14:48:22 +0100939 static const char kErrorDetails[] = "Certificate revoked.";
Darin Petkova5e07ef2012-07-09 14:27:57 +0200940 driver_->default_service_callback_tag_ = kServiceCallbackTag;
941 driver_->child_watch_tag_ = kChildTag;
Darin Petkov79d74c92012-03-07 17:20:32 +0100942 driver_->pid_ = kPID;
943 driver_->rpc_task_.reset(new RPCTask(&control_, this));
944 driver_->tunnel_interface_ = kInterfaceName;
945 driver_->device_ = device_;
946 driver_->service_ = service_;
Darin Petkov3189a472012-10-05 09:55:33 +0200947 driver_->ip_properties_.address = "1.2.3.4";
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100948 StartConnectTimeout(0);
Darin Petkov1fa81942012-04-02 11:38:08 +0200949 FilePath tls_auth_file;
950 EXPECT_TRUE(file_util::CreateTemporaryFile(&tls_auth_file));
951 EXPECT_FALSE(tls_auth_file.empty());
952 EXPECT_TRUE(file_util::PathExists(tls_auth_file));
953 driver_->tls_auth_file_ = tls_auth_file;
Darin Petkov46463022012-03-29 14:57:32 +0200954 // Stop will be called twice -- once by Cleanup and once by the destructor.
955 EXPECT_CALL(*management_server_, Stop()).Times(2);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200956 EXPECT_CALL(glib_, SourceRemove(kChildTag));
957 EXPECT_CALL(manager_, DeregisterDefaultServiceCallback(kServiceCallbackTag));
Darin Petkov5a850472012-06-06 15:44:24 +0200958 EXPECT_CALL(process_killer_, Kill(kPID, _));
959 EXPECT_CALL(device_info_, DeleteInterface(_)).Times(0);
mukesh agrawal9da07772013-05-15 14:15:17 -0700960 EXPECT_CALL(*device_, DropConnection());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500961 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov1c049c72013-03-21 13:15:45 +0100962 EXPECT_CALL(*service_, SetFailure(Service::kFailureInternal));
963 driver_->Cleanup(
964 Service::kStateFailure, Service::kFailureInternal, kErrorDetails);
Darin Petkov79d74c92012-03-07 17:20:32 +0100965 EXPECT_EQ(0, driver_->child_watch_tag_);
Darin Petkova5e07ef2012-07-09 14:27:57 +0200966 EXPECT_EQ(0, driver_->default_service_callback_tag_);
Darin Petkov79d74c92012-03-07 17:20:32 +0100967 EXPECT_EQ(0, driver_->pid_);
968 EXPECT_FALSE(driver_->rpc_task_.get());
969 EXPECT_TRUE(driver_->tunnel_interface_.empty());
970 EXPECT_FALSE(driver_->device_);
971 EXPECT_FALSE(driver_->service_);
Darin Petkovaba89322013-03-11 14:48:22 +0100972 EXPECT_EQ(kErrorDetails, service_->error_details());
Darin Petkov1fa81942012-04-02 11:38:08 +0200973 EXPECT_FALSE(file_util::PathExists(tls_auth_file));
974 EXPECT_TRUE(driver_->tls_auth_file_.empty());
Darin Petkov3189a472012-10-05 09:55:33 +0200975 EXPECT_TRUE(driver_->ip_properties_.address.empty());
Darin Petkov602303f2012-06-06 12:15:59 +0200976 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov36a3ace2012-03-06 17:22:14 +0100977}
978
Darin Petkov1a462de2012-05-02 11:10:48 +0200979namespace {
980MATCHER(CheckEnv, "") {
981 if (!arg || !arg[0] || !arg[1] || arg[2]) {
982 return false;
983 }
984 return (string(arg[0]) == "IV_PLAT=Chromium OS" &&
985 string(arg[1]) == "IV_PLAT_REL=2202.0");
986}
987} // namespace
988
Darin Petkov36a3ace2012-03-06 17:22:14 +0100989TEST_F(OpenVPNDriverTest, SpawnOpenVPN) {
Darin Petkov1a462de2012-05-02 11:10:48 +0200990 SetupLSBRelease();
991
Darin Petkov79d74c92012-03-07 17:20:32 +0100992 EXPECT_FALSE(driver_->SpawnOpenVPN());
Darin Petkov36a3ace2012-03-06 17:22:14 +0100993
994 static const char kHost[] = "192.168.2.254";
Darin Petkove0d5dd12012-04-04 16:10:48 +0200995 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov79d74c92012-03-07 17:20:32 +0100996 driver_->tunnel_interface_ = "tun0";
997 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov46463022012-03-29 14:57:32 +0200998 EXPECT_CALL(*management_server_, Start(_, _, _))
999 .Times(2)
1000 .WillRepeatedly(Return(true));
Darin Petkov4cbff5b2013-01-29 16:29:05 +01001001 EXPECT_CALL(manager_, IsOnline()).Times(2).WillRepeatedly(Return(false));
Darin Petkov36a3ace2012-03-06 17:22:14 +01001002
1003 const int kPID = 234678;
Darin Petkov68710d72013-02-13 14:22:56 +01001004 EXPECT_CALL(glib_, SpawnAsync(_, _, CheckEnv(), _, _, _, _, _))
Darin Petkov36a3ace2012-03-06 17:22:14 +01001005 .WillOnce(Return(false))
Darin Petkov68710d72013-02-13 14:22:56 +01001006 .WillOnce(DoAll(SetArgumentPointee<6>(kPID), Return(true)));
Darin Petkov36a3ace2012-03-06 17:22:14 +01001007 const int kTag = 6;
Darin Petkov79d74c92012-03-07 17:20:32 +01001008 EXPECT_CALL(glib_, ChildWatchAdd(kPID, &driver_->OnOpenVPNDied, driver_))
Darin Petkov36a3ace2012-03-06 17:22:14 +01001009 .WillOnce(Return(kTag));
Darin Petkov79d74c92012-03-07 17:20:32 +01001010 EXPECT_FALSE(driver_->SpawnOpenVPN());
1011 EXPECT_TRUE(driver_->SpawnOpenVPN());
1012 EXPECT_EQ(kPID, driver_->pid_);
1013 EXPECT_EQ(kTag, driver_->child_watch_tag_);
Darin Petkov36a3ace2012-03-06 17:22:14 +01001014}
1015
1016TEST_F(OpenVPNDriverTest, OnOpenVPNDied) {
1017 const int kPID = 99999;
Darin Petkov5a850472012-06-06 15:44:24 +02001018 driver_->device_ = device_;
Darin Petkov79d74c92012-03-07 17:20:32 +01001019 driver_->child_watch_tag_ = 333;
1020 driver_->pid_ = kPID;
mukesh agrawal9da07772013-05-15 14:15:17 -07001021 EXPECT_CALL(*device_, DropConnection());
Darin Petkov5a850472012-06-06 15:44:24 +02001022 EXPECT_CALL(*device_, SetEnabled(false));
1023 EXPECT_CALL(process_killer_, Kill(_, _)).Times(0);
1024 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
Darin Petkov79d74c92012-03-07 17:20:32 +01001025 OpenVPNDriver::OnOpenVPNDied(kPID, 2, driver_);
1026 EXPECT_EQ(0, driver_->child_watch_tag_);
1027 EXPECT_EQ(0, driver_->pid_);
Darin Petkov36a3ace2012-03-06 17:22:14 +01001028}
1029
Darin Petkov6aa21872012-03-09 16:10:19 +01001030TEST_F(OpenVPNDriverTest, Disconnect) {
1031 driver_->device_ = device_;
1032 driver_->service_ = service_;
mukesh agrawal9da07772013-05-15 14:15:17 -07001033 EXPECT_CALL(*device_, DropConnection());
Eric Shienbrood9a245532012-03-07 14:20:39 -05001034 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov6aa21872012-03-09 16:10:19 +01001035 EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
1036 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
1037 driver_->Disconnect();
Darin Petkova0e645e2012-04-25 11:38:59 +02001038 EXPECT_FALSE(driver_->device_);
Darin Petkov6aa21872012-03-09 16:10:19 +01001039 EXPECT_FALSE(driver_->service_);
1040}
1041
Darin Petkov5eb05422012-05-11 15:45:25 +02001042TEST_F(OpenVPNDriverTest, OnConnectionDisconnected) {
Darin Petkova42afe32013-02-05 16:53:52 +01001043 EXPECT_CALL(*management_server_, Restart());
1044 SetDevice(device_);
1045 SetService(service_);
mukesh agrawal9da07772013-05-15 14:15:17 -07001046 EXPECT_CALL(*device_, DropConnection());
Darin Petkova42afe32013-02-05 16:53:52 +01001047 EXPECT_CALL(*service_, SetState(Service::kStateAssociating));
1048 OnConnectionDisconnected();
1049 EXPECT_TRUE(IsConnectTimeoutStarted());
1050}
1051
1052TEST_F(OpenVPNDriverTest, OnConnectTimeout) {
Darin Petkov0cd0d1e2013-02-11 12:49:10 +01001053 StartConnectTimeout(0);
Darin Petkova42afe32013-02-05 16:53:52 +01001054 SetService(service_);
Darin Petkov1c049c72013-03-21 13:15:45 +01001055 EXPECT_CALL(*service_, SetFailure(Service::kFailureConnect));
1056 OnConnectTimeout();
1057 EXPECT_FALSE(GetService());
1058 EXPECT_FALSE(IsConnectTimeoutStarted());
1059}
1060
1061TEST_F(OpenVPNDriverTest, OnConnectTimeoutResolve) {
1062 StartConnectTimeout(0);
1063 SetService(service_);
1064 SetClientState(OpenVPNManagementServer::kStateResolve);
1065 EXPECT_CALL(*service_, SetFailure(Service::kFailureDNSLookup));
Darin Petkova42afe32013-02-05 16:53:52 +01001066 OnConnectTimeout();
1067 EXPECT_FALSE(GetService());
1068 EXPECT_FALSE(IsConnectTimeoutStarted());
Darin Petkov5eb05422012-05-11 15:45:25 +02001069}
1070
Darin Petkov0cd0d1e2013-02-11 12:49:10 +01001071TEST_F(OpenVPNDriverTest, OnReconnectingUnknown) {
1072 EXPECT_FALSE(IsConnectTimeoutStarted());
1073 EXPECT_CALL(dispatcher_,
1074 PostDelayedTask(_, GetDefaultConnectTimeoutSeconds() * 1000))
1075 .WillOnce(Return(true));
1076 SetDevice(device_);
1077 SetService(service_);
mukesh agrawal9da07772013-05-15 14:15:17 -07001078 EXPECT_CALL(*device_, DropConnection());
Darin Petkov271fe522012-03-27 13:47:29 +02001079 EXPECT_CALL(*service_, SetState(Service::kStateAssociating));
Darin Petkov0cd0d1e2013-02-11 12:49:10 +01001080 driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonUnknown);
1081 EXPECT_TRUE(IsConnectTimeoutStarted());
1082}
1083
1084TEST_F(OpenVPNDriverTest, OnReconnectingTLSError) {
1085 EXPECT_CALL(dispatcher_,
1086 PostDelayedTask(_, GetReconnectOfflineTimeoutSeconds() * 1000))
1087 .WillOnce(Return(true));
1088 EXPECT_CALL(dispatcher_,
1089 PostDelayedTask(_, GetReconnectTLSErrorTimeoutSeconds() * 1000))
1090 .WillOnce(Return(true));
1091
1092 driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonOffline);
1093 EXPECT_TRUE(IsConnectTimeoutStarted());
1094
1095 // The scheduled timeout should not be affected for unknown reason.
1096 driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonUnknown);
1097 EXPECT_TRUE(IsConnectTimeoutStarted());
1098
1099 // Reconnect on TLS error reschedules the timeout once.
1100 driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonTLSError);
1101 EXPECT_TRUE(IsConnectTimeoutStarted());
1102 driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonTLSError);
1103 EXPECT_TRUE(IsConnectTimeoutStarted());
Darin Petkov271fe522012-03-27 13:47:29 +02001104}
1105
Paul Stewart291a4732012-03-14 19:19:02 -07001106TEST_F(OpenVPNDriverTest, VerifyPaths) {
1107 // Ensure that the various path constants that the OpenVPN driver uses
Darin Petkova0e645e2012-04-25 11:38:59 +02001108 // actually exists in the build image. Due to build dependencies, they should
1109 // already exist by the time we run unit tests.
Paul Stewart291a4732012-03-14 19:19:02 -07001110
Darin Petkova0e645e2012-04-25 11:38:59 +02001111 // The OpenVPNDriver path constants are absolute. FilePath::Append asserts
1112 // that its argument is not an absolute path, so we need to strip the leading
1113 // separators. There's nothing built into FilePath to do so.
1114 static const char *kPaths[] = {
1115 OpenVPNDriver::kOpenVPNPath,
1116 OpenVPNDriver::kOpenVPNScript,
1117 };
1118 for (size_t i = 0; i < arraysize(kPaths); i++) {
1119 string path(kPaths[i]);
1120 TrimString(path, FilePath::kSeparators, &path);
1121 EXPECT_TRUE(file_util::PathExists(FilePath(SYSROOT).Append(path)))
1122 << kPaths[i];
1123 }
Paul Stewart291a4732012-03-14 19:19:02 -07001124}
1125
Darin Petkovd4325392012-04-23 15:48:22 +02001126TEST_F(OpenVPNDriverTest, InitPropertyStore) {
1127 // Sanity test property store initialization.
1128 PropertyStore store;
1129 driver_->InitPropertyStore(&store);
1130 const string kUser = "joe";
1131 Error error;
1132 EXPECT_TRUE(
1133 store.SetStringProperty(flimflam::kOpenVPNUserProperty, kUser, &error));
1134 EXPECT_TRUE(error.IsSuccess());
Darin Petkovb536a742012-04-26 11:31:28 +02001135 EXPECT_EQ(kUser, GetArgs()->LookupString(flimflam::kOpenVPNUserProperty, ""));
1136}
1137
1138TEST_F(OpenVPNDriverTest, GetProvider) {
1139 PropertyStore store;
1140 driver_->InitPropertyStore(&store);
1141 {
Darin Petkovb536a742012-04-26 11:31:28 +02001142 KeyValueStore props;
Paul Stewarte6e8e492013-01-17 11:00:50 -08001143 Error error;
Darin Petkovb536a742012-04-26 11:31:28 +02001144 EXPECT_TRUE(
Paul Stewarte6e8e492013-01-17 11:00:50 -08001145 store.GetKeyValueStoreProperty(
1146 flimflam::kProviderProperty, &props, &error));
Darin Petkovb536a742012-04-26 11:31:28 +02001147 EXPECT_TRUE(props.LookupBool(flimflam::kPassphraseRequiredProperty, false));
1148 }
1149 {
Darin Petkovb536a742012-04-26 11:31:28 +02001150 KeyValueStore props;
1151 SetArg(flimflam::kOpenVPNPasswordProperty, "random-password");
Paul Stewarte6e8e492013-01-17 11:00:50 -08001152 Error error;
Darin Petkovb536a742012-04-26 11:31:28 +02001153 EXPECT_TRUE(
Paul Stewarte6e8e492013-01-17 11:00:50 -08001154 store.GetKeyValueStoreProperty(
1155 flimflam::kProviderProperty, &props, &error));
Darin Petkovb536a742012-04-26 11:31:28 +02001156 EXPECT_FALSE(props.LookupBool(flimflam::kPassphraseRequiredProperty, true));
Darin Petkov02236552012-06-11 13:15:19 +02001157 EXPECT_FALSE(props.ContainsString(flimflam::kOpenVPNPasswordProperty));
Darin Petkovb536a742012-04-26 11:31:28 +02001158 }
Darin Petkovd4325392012-04-23 15:48:22 +02001159}
1160
Darin Petkov1a462de2012-05-02 11:10:48 +02001161TEST_F(OpenVPNDriverTest, ParseLSBRelease) {
1162 SetupLSBRelease();
1163 map<string, string> lsb_release;
1164 EXPECT_TRUE(driver_->ParseLSBRelease(&lsb_release));
1165 EXPECT_TRUE(ContainsKey(lsb_release, "foo") && lsb_release["foo"] == "");
1166 EXPECT_EQ("=", lsb_release["zoo"]);
1167 EXPECT_EQ("Chromium OS", lsb_release[OpenVPNDriver::kChromeOSReleaseName]);
1168 EXPECT_EQ("2202.0", lsb_release[OpenVPNDriver::kChromeOSReleaseVersion]);
1169 driver_->lsb_release_file_ = FilePath("/non/existent/file");
1170 EXPECT_FALSE(driver_->ParseLSBRelease(NULL));
1171}
1172
1173TEST_F(OpenVPNDriverTest, InitEnvironment) {
1174 vector<string> env;
1175 SetupLSBRelease();
1176 driver_->InitEnvironment(&env);
1177 ASSERT_EQ(2, env.size());
1178 EXPECT_EQ("IV_PLAT=Chromium OS", env[0]);
1179 EXPECT_EQ("IV_PLAT_REL=2202.0", env[1]);
1180 env.clear();
1181 EXPECT_EQ(0, file_util::WriteFile(lsb_release_file_, "", 0));
1182 driver_->InitEnvironment(&env);
1183 EXPECT_EQ(0, env.size());
1184}
1185
Darin Petkov5a850472012-06-06 15:44:24 +02001186TEST_F(OpenVPNDriverTest, DeleteInterface) {
1187 scoped_ptr<MockDeviceInfo> device_info(
1188 new MockDeviceInfo(&control_, &dispatcher_, &metrics_, &manager_));
1189 EXPECT_CALL(*device_info, DeleteInterface(kInterfaceIndex))
1190 .WillOnce(Return(true));
1191 WeakPtr<DeviceInfo> weak = device_info->AsWeakPtr();
1192 EXPECT_TRUE(weak);
1193 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
1194 device_info.reset();
1195 EXPECT_FALSE(weak);
1196 // Expect no crash.
1197 OpenVPNDriver::DeleteInterface(weak, kInterfaceIndex);
1198}
1199
Darin Petkova5e07ef2012-07-09 14:27:57 +02001200TEST_F(OpenVPNDriverTest, OnDefaultServiceChanged) {
1201 driver_->service_ = service_;
1202
1203 ServiceRefPtr null_service;
1204 EXPECT_CALL(*management_server_, Hold());
1205 driver_->OnDefaultServiceChanged(null_service);
1206
1207 EXPECT_CALL(*management_server_, Hold());
1208 driver_->OnDefaultServiceChanged(service_);
1209
1210 scoped_refptr<MockService> mock_service(
1211 new MockService(&control_, &dispatcher_, &metrics_, &manager_));
1212
1213 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(false));
1214 EXPECT_CALL(*management_server_, Hold());
1215 driver_->OnDefaultServiceChanged(mock_service);
1216
1217 EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(true));
1218 EXPECT_CALL(*management_server_, ReleaseHold());
1219 driver_->OnDefaultServiceChanged(mock_service);
1220}
1221
Darin Petkov0cd0d1e2013-02-11 12:49:10 +01001222TEST_F(OpenVPNDriverTest, GetReconnectTimeoutSeconds) {
1223 EXPECT_EQ(GetDefaultConnectTimeoutSeconds(),
1224 GetReconnectTimeoutSeconds(OpenVPNDriver::kReconnectReasonUnknown));
1225 EXPECT_EQ(GetReconnectOfflineTimeoutSeconds(),
1226 GetReconnectTimeoutSeconds(OpenVPNDriver::kReconnectReasonOffline));
1227 EXPECT_EQ(GetReconnectTLSErrorTimeoutSeconds(),
1228 GetReconnectTimeoutSeconds(
1229 OpenVPNDriver::kReconnectReasonTLSError));
1230}
1231
Darin Petkov33af05c2012-02-28 10:10:30 +01001232} // namespace shill