1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
1633af05c849e0888b15222da38b55515784b821c7Darin Petkov
172240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/openvpn_driver.h"
1833af05c849e0888b15222da38b55515784b821c7Darin Petkov
19a9b1fedcad9d354ff7b0a6a7e4cfd58fa7133084Darin Petkov#include <algorithm>
20a9b1fedcad9d354ff7b0a6a7e4cfd58fa7133084Darin Petkov
21a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/files/file_path.h>
2211c213f3cf64f27a0e42ee6da95e98bd1d4b3202Ben Chan#include <base/files/file_util.h>
23b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart#include <base/files/scoped_temp_dir.h>
24a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/string_util.h>
25a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/stringprintf.h>
26289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#if defined(__ANDROID__)
27289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#include <dbus/service_constants.h>
28289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#else
29fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov#include <chromeos/dbus/service_constants.h>
30289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#endif  // __ANDROID__
3133af05c849e0888b15222da38b55515784b821c7Darin Petkov#include <gtest/gtest.h>
3233af05c849e0888b15222da38b55515784b821c7Darin Petkov
3333af05c849e0888b15222da38b55515784b821c7Darin Petkov#include "shill/error.h"
3414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov#include "shill/ipconfig.h"
35b691efd71561246065eae3cdd73a96ca1b8a528dChristopher Wiley#include "shill/logging.h"
36a9b1fedcad9d354ff7b0a6a7e4cfd58fa7133084Darin Petkov#include "shill/mock_adaptors.h"
375baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart#include "shill/mock_certificate_file.h"
38ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewart#include "shill/mock_device_info.h"
390cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov#include "shill/mock_event_dispatcher.h"
40f20994fa34cea805b8ab1140542285bbf0a1faf4Darin Petkov#include "shill/mock_manager.h"
41f20994fa34cea805b8ab1140542285bbf0a1faf4Darin Petkov#include "shill/mock_metrics.h"
42d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal#include "shill/mock_process_manager.h"
43a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov#include "shill/mock_service.h"
44f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov#include "shill/mock_store.h"
459da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal#include "shill/mock_virtual_device.h"
46a9b1fedcad9d354ff7b0a6a7e4cfd58fa7133084Darin Petkov#include "shill/nice_mock_control.h"
47a9b1fedcad9d354ff7b0a6a7e4cfd58fa7133084Darin Petkov#include "shill/rpc_task.h"
489da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal#include "shill/technology.h"
499da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal#include "shill/virtual_device.h"
502240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/mock_openvpn_management_server.h"
512240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/mock_vpn_service.h"
522240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/vpn_service.h"
5333af05c849e0888b15222da38b55515784b821c7Darin Petkov
540e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulkusing base::FilePath;
555a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkovusing base::WeakPtr;
56a9b1fedcad9d354ff7b0a6a7e4cfd58fa7133084Darin Petkovusing std::map;
57fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkovusing std::string;
58fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkovusing std::vector;
59ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewartusing testing::_;
60f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkovusing testing::AnyNumber;
61ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewartusing testing::DoAll;
623c5e4dc08bef63ba11f215a6aec1ff0d0442d1c5Darin Petkovusing testing::ElementsAreArray;
63e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkovusing testing::Field;
64b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewartusing testing::Mock;
65f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkovusing testing::Ne;
66ce4ec19216ccd15ae349ee42498657afc2c75bd8Paul Stewartusing testing::NiceMock;
67ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewartusing testing::Return;
68ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewartusing testing::SetArgumentPointee;
69ce4ec19216ccd15ae349ee42498657afc2c75bd8Paul Stewartusing testing::StrictMock;
70fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
7133af05c849e0888b15222da38b55515784b821c7Darin Petkovnamespace shill {
7233af05c849e0888b15222da38b55515784b821c7Darin Petkov
73b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewartstruct AuthenticationExpectations {
74b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  AuthenticationExpectations()
75b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      : remote_authentication_type(Metrics::kVpnRemoteAuthenticationTypeMax) {}
76b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  AuthenticationExpectations(
77e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart      const string& ca_cert_in,
78e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart      const string& client_cert_in,
79e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart      const string& user_in,
80e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart      const string& otp_in,
81e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart      const string& token_in,
82b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      Metrics::VpnRemoteAuthenticationType remote_authentication_type_in,
83b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      const vector<Metrics::VpnUserAuthenticationType>
84b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          &user_authentication_types_in)
85b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      : ca_cert(ca_cert_in),
86b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        client_cert(client_cert_in),
87b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        user(user_in),
88b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        otp(otp_in),
89b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        token(token_in),
90b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        remote_authentication_type(remote_authentication_type_in),
91b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        user_authentication_types(user_authentication_types_in) {}
92b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  string ca_cert;
93b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  string client_cert;
94b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  string user;
95b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  string otp;
96b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  string token;
97b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  Metrics::VpnRemoteAuthenticationType remote_authentication_type;
98b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  vector<Metrics::VpnUserAuthenticationType> user_authentication_types;
99b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart};
100b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart
101b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewartclass OpenVPNDriverTest
102b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    : public testing::TestWithParam<AuthenticationExpectations>,
103b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      public RPCTaskDelegate {
10433af05c849e0888b15222da38b55515784b821c7Darin Petkov public:
105fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  OpenVPNDriverTest()
1060e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov      : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
1076c1e3bbca64d642cb30ed9952203626942bc1451Thieu Le        metrics_(&dispatcher_),
108bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal        manager_(&control_, &dispatcher_, &metrics_),
10979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov        driver_(new OpenVPNDriver(&control_, &dispatcher_, &metrics_, &manager_,
110bad1c10ffd2d4ac14f7bd9f4ef6a8982e711f566mukesh agrawal                                  &device_info_, &process_manager_)),
11179d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov        service_(new MockVPNService(&control_, &dispatcher_, &metrics_,
11279d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov                                    &manager_, driver_)),
1139da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal        device_(new MockVirtualDevice(
1149da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal            &control_, &dispatcher_, &metrics_, &manager_,
1159da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal            kInterfaceName, kInterfaceIndex, Technology::kVPN)),
1165baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart        certificate_file_(new MockCertificateFile()),
1178343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart        extra_certificates_file_(new MockCertificateFile()),
1184646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov        management_server_(new NiceMock<MockOpenVPNManagementServer>()) {
1194646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov    driver_->management_server_.reset(management_server_);
1205baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart    driver_->certificate_file_.reset(certificate_file_);  // Passes ownership.
1218343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    driver_->extra_certificates_file_.reset(
1228343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart        extra_certificates_file_);  // Passes ownership.
12362ba51cf8fed1be8f51092ecce6a9588a842cd29mukesh agrawal    CHECK(temporary_directory_.CreateUniqueTempDir());
124b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart    driver_->openvpn_config_directory_ =
125b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart        temporary_directory_.path().Append(kOpenVPNConfigDirectory);
1264646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  }
127fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
12833af05c849e0888b15222da38b55515784b821c7Darin Petkov  virtual ~OpenVPNDriverTest() {}
12933af05c849e0888b15222da38b55515784b821c7Darin Petkov
13036a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov  virtual void TearDown() {
131a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov    driver_->default_service_callback_tag_ = 0;
13279d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov    driver_->pid_ = 0;
1334168b2c8d57755ea6b16763745379e0529541a3fBen Chan    driver_->device_ = nullptr;
1344168b2c8d57755ea6b16763745379e0529541a3fBen Chan    driver_->service_ = nullptr;
1351a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov    if (!lsb_release_file_.empty()) {
136a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan      EXPECT_TRUE(base::DeleteFile(lsb_release_file_, false));
1371a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov      lsb_release_file_.clear();
1381a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov    }
13936a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov  }
140a9b1fedcad9d354ff7b0a6a7e4cfd58fa7133084Darin Petkov
14133af05c849e0888b15222da38b55515784b821c7Darin Petkov protected:
142fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  static const char kOption[];
143fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  static const char kProperty[];
144fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  static const char kValue[];
145fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  static const char kOption2[];
146fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  static const char kProperty2[];
147fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  static const char kValue2[];
148605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  static const char kGateway1[];
149605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  static const char kNetmask1[];
150605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  static const char kNetwork1[];
151605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  static const char kGateway2[];
152605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  static const char kNetmask2[];
153605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  static const char kNetwork2[];
15479d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  static const char kInterfaceName[];
15579d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  static const int kInterfaceIndex;
156b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  static const char kOpenVPNConfigDirectory[];
157fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
158e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void SetArg(const string& arg, const string& value) {
159b451d6e5b5deb3a42ac09c3db349f325e4c8004eDarin Petkov    driver_->args()->SetString(arg, value);
160fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  }
161fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
162e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void SetArgArray(const string& arg, const vector<string>& value) {
1630f9c930955e22e7d6a4a011f565ca5197e2cee8fPaul Stewart    driver_->args()->SetStrings(arg, value);
1640f9c930955e22e7d6a4a011f565ca5197e2cee8fPaul Stewart  }
1650f9c930955e22e7d6a4a011f565ca5197e2cee8fPaul Stewart
166e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  KeyValueStore* GetArgs() {
167b451d6e5b5deb3a42ac09c3db349f325e4c8004eDarin Petkov    return driver_->args();
168f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov  }
169f3c71d70885fdddff8d71db75878c1310af28f9dDarin Petkov
170e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  KeyValueStore GetProviderProperties(const PropertyStore& store) {
171b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    KeyValueStore props;
172b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    Error error;
173b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    EXPECT_TRUE(
174b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        store.GetKeyValueStoreProperty(kProviderProperty, &props, &error));
175b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    return props;
176b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  }
177b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart
178e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void RemoveStringArg(const string& arg) {
1794e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov    driver_->args()->RemoveString(arg);
1804e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  }
1814e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov
182e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  const ServiceRefPtr& GetSelectedService() {
1833189a47b7999f1f95d76553c7ee463ac40186d26Darin Petkov    return device_->selected_service();
1843189a47b7999f1f95d76553c7ee463ac40186d26Darin Petkov  }
1853189a47b7999f1f95d76553c7ee463ac40186d26Darin Petkov
186406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  bool InitManagementChannelOptions(
187e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart      vector<vector<string>>* options, Error* error) {
1884cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov    return driver_->InitManagementChannelOptions(options, error);
1894cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  }
1904cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov
191e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  Sockets* GetSockets() {
1924cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov    return &driver_->sockets_;
1934cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  }
1944cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov
195e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void SetDevice(const VirtualDeviceRefPtr& device) {
196a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    driver_->device_ = device;
197a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
198a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
199e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void SetService(const VPNServiceRefPtr& service) {
200a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    driver_->service_ = service;
201a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
202a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
203a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  VPNServiceRefPtr GetService() {
204a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    return driver_->service_;
205a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
206a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
207a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  void OnConnectionDisconnected() {
208a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    driver_->OnConnectionDisconnected();
209a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
210a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
211a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  void OnConnectTimeout() {
212a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    driver_->OnConnectTimeout();
213a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
214a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
2150cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  void StartConnectTimeout(int timeout_seconds) {
2160cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    driver_->StartConnectTimeout(timeout_seconds);
217a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
218a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
219a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  bool IsConnectTimeoutStarted() {
220a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov    return driver_->IsConnectTimeoutStarted();
221a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  }
222a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
2230cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  static int GetDefaultConnectTimeoutSeconds() {
2240cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    return OpenVPNDriver::kDefaultConnectTimeoutSeconds;
2250cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  }
2260cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
2270cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  static int GetReconnectOfflineTimeoutSeconds() {
2280cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    return OpenVPNDriver::kReconnectOfflineTimeoutSeconds;
2290cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  }
2300cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
2310cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  static int GetReconnectTLSErrorTimeoutSeconds() {
2320cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    return OpenVPNDriver::kReconnectTLSErrorTimeoutSeconds;
2330cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  }
2340cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
2350cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  static int GetReconnectTimeoutSeconds(OpenVPNDriver::ReconnectReason reason) {
2360cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov    return OpenVPNDriver::GetReconnectTimeoutSeconds(reason);
2370cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  }
2380cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
239e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void SetClientState(const string& state) {
2401c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov    management_server_->state_ = state;
2411c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  }
2421c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov
243ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewart  // Used to assert that a flag appears in the options.
244e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void ExpectInFlags(const vector<vector<string>>& options, const string& flag);
245e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void ExpectInFlags(const vector<vector<string>>& options, const string& flag,
246e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart                     const string& value);
247e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void ExpectInFlags(const vector<vector<string>>& options,
248e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart                     const vector<string>& arguments);
249e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  void ExpectNotInFlags(const vector<vector<string>>& options,
250e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart                        const string& flag);
251ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewart
2521a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov  void SetupLSBRelease();
2531a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov
25436a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov  // Inherited from RPCTaskDelegate.
255e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  virtual void GetLogin(string* user, string* password);
256e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  virtual void Notify(const string& reason, const map<string, string>& dict);
257ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewart
258a9b1fedcad9d354ff7b0a6a7e4cfd58fa7133084Darin Petkov  NiceMockControl control_;
2590e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov  NiceMock<MockDeviceInfo> device_info_;
2600cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  MockEventDispatcher dispatcher_;
261f20994fa34cea805b8ab1140542285bbf0a1faf4Darin Petkov  MockMetrics metrics_;
262d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal  MockProcessManager process_manager_;
263f20994fa34cea805b8ab1140542285bbf0a1faf4Darin Petkov  MockManager manager_;
264e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  OpenVPNDriver* driver_;  // Owned by |service_|.
26579d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  scoped_refptr<MockVPNService> service_;
2669da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal  scoped_refptr<MockVirtualDevice> device_;
267e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  MockCertificateFile* certificate_file_;  // Owned by |driver_|.
268e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  MockCertificateFile* extra_certificates_file_;  // Owned by |driver_|.
269b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  base::ScopedTempDir temporary_directory_;
2704646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov
2714646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  // Owned by |driver_|.
272e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  NiceMock<MockOpenVPNManagementServer>* management_server_;
2731a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov
2741a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov  FilePath lsb_release_file_;
27533af05c849e0888b15222da38b55515784b821c7Darin Petkov};
27633af05c849e0888b15222da38b55515784b821c7Darin Petkov
277b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewartconst char OpenVPNDriverTest::kOption[] = "openvpn-option";
278fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkovconst char OpenVPNDriverTest::kProperty[] = "OpenVPN.SomeProperty";
279fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkovconst char OpenVPNDriverTest::kValue[] = "some-property-value";
280b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewartconst char OpenVPNDriverTest::kOption2[] = "openvpn-option2";
281fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkovconst char OpenVPNDriverTest::kProperty2[] = "OpenVPN.SomeProperty2";
282fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkovconst char OpenVPNDriverTest::kValue2[] = "some-property-value2";
283605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkovconst char OpenVPNDriverTest::kGateway1[] = "10.242.2.13";
284605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkovconst char OpenVPNDriverTest::kNetmask1[] = "255.255.255.255";
285605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkovconst char OpenVPNDriverTest::kNetwork1[] = "10.242.2.1";
286605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkovconst char OpenVPNDriverTest::kGateway2[] = "10.242.2.14";
287605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkovconst char OpenVPNDriverTest::kNetmask2[] = "255.255.0.0";
288605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkovconst char OpenVPNDriverTest::kNetwork2[] = "192.168.0.0";
28979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkovconst char OpenVPNDriverTest::kInterfaceName[] = "tun0";
29079d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkovconst int OpenVPNDriverTest::kInterfaceIndex = 123;
291b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewartconst char OpenVPNDriverTest::kOpenVPNConfigDirectory[] = "openvpn";
292fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
293e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartvoid OpenVPNDriverTest::GetLogin(string* /*user*/, string* /*password*/) {}
294209e629754acc6807fd5deff888bf4521867f68dDarin Petkov
295e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartvoid OpenVPNDriverTest::Notify(const string& /*reason*/,
296e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart                               const map<string, string>& /*dict*/) {}
297a9b1fedcad9d354ff7b0a6a7e4cfd58fa7133084Darin Petkov
298e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartvoid OpenVPNDriverTest::ExpectInFlags(const vector<vector<string>>& options,
299e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart                                      const string& flag) {
300406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  ExpectInFlags(options, vector<string> { flag });
301406c473d5680f42b067dbda0a9b011b162130effPaul Stewart}
302406c473d5680f42b067dbda0a9b011b162130effPaul Stewart
303e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartvoid OpenVPNDriverTest::ExpectInFlags(const vector<vector<string>>& options,
304e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart                                      const string& flag,
305e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart                                      const string& value) {
306406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  ExpectInFlags(options, vector<string> { flag, value });
307ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewart}
308ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewart
309e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartvoid OpenVPNDriverTest::ExpectInFlags(const vector<vector<string>>& options,
310e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart                                      const vector<string>& arguments) {
311406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  EXPECT_TRUE(std::find(options.begin(), options.end(), arguments) !=
3124e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov              options.end());
3134e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov}
3144e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov
315e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartvoid OpenVPNDriverTest::ExpectNotInFlags(const vector<vector<string>>& options,
316e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart                                         const string& flag) {
317e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  for (const auto& option : options) {
318406c473d5680f42b067dbda0a9b011b162130effPaul Stewart    EXPECT_NE(flag, option[0]);
319406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  }
3204e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov}
3214e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov
3221a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkovvoid OpenVPNDriverTest::SetupLSBRelease() {
3231a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov  static const char kLSBReleaseContents[] =
3241a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov      "\n"
3251a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov      "=\n"
3261a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov      "foo=\n"
3271a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov      "=bar\n"
3281a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov      "zoo==\n"
3291a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov      "CHROMEOS_RELEASE_BOARD=x86-alex\n"
3301a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov      "CHROMEOS_RELEASE_NAME=Chromium OS\n"
3311a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov      "CHROMEOS_RELEASE_VERSION=2202.0\n";
332a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateTemporaryFile(&lsb_release_file_));
3331a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov  EXPECT_EQ(arraysize(kLSBReleaseContents),
3346fbf64f493a9aae7d743888039c61a57386203dbBen Chan            base::WriteFile(lsb_release_file_,
3356fbf64f493a9aae7d743888039c61a57386203dbBen Chan                            kLSBReleaseContents,
3366fbf64f493a9aae7d743888039c61a57386203dbBen Chan                            arraysize(kLSBReleaseContents)));
3371a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov  EXPECT_EQ(OpenVPNDriver::kLSBReleaseFile, driver_->lsb_release_file_.value());
3381a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov  driver_->lsb_release_file_ = lsb_release_file_;
3391a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov}
3401a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov
34133af05c849e0888b15222da38b55515784b821c7Darin PetkovTEST_F(OpenVPNDriverTest, Connect) {
34279d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
34379d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  const string interface = kInterfaceName;
344f20994fa34cea805b8ab1140542285bbf0a1faf4Darin Petkov  EXPECT_CALL(device_info_, CreateTunnelInterface(_))
34579d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov      .WillOnce(DoAll(SetArgumentPointee<0>(interface), Return(true)));
34679d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  Error error;
34779d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->Connect(service_, &error);
34879d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_TRUE(error.IsSuccess());
34979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
350602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov  EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
35179d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov}
35279d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov
35379d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin PetkovTEST_F(OpenVPNDriverTest, ConnectTunnelFailure) {
35479d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
3550e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov  EXPECT_CALL(device_info_, CreateTunnelInterface(_)).WillOnce(Return(false));
3561c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(*service_, SetFailure(Service::kFailureInternal));
35779d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  Error error;
35879d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->Connect(service_, &error);
35979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_EQ(Error::kInternalError, error.type());
36079d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_TRUE(driver_->tunnel_interface_.empty());
361602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov  EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
36233af05c849e0888b15222da38b55515784b821c7Darin Petkov}
36333af05c849e0888b15222da38b55515784b821c7Darin Petkov
3640e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkovnamespace {
3650e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin PetkovMATCHER_P(IsIPAddress, address, "") {
3660e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov  IPAddress ip_address(IPAddress::kFamilyIPv4);
3670e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov  EXPECT_TRUE(ip_address.SetAddressFromString(address));
3680e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov  return ip_address.Equals(arg);
3690e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov}
3700e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov}  // namespace
3710e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov
37214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin PetkovTEST_F(OpenVPNDriverTest, Notify) {
3730e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov  map<string, string> config;
3743189a47b7999f1f95d76553c7ee463ac40186d26Darin Petkov  driver_->service_ = service_;
37579d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->device_ = device_;
3760cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  StartConnectTimeout(0);
377e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_CALL(*device_,
378e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov              UpdateIPConfig(Field(&IPConfig::Properties::address, "")));
3790e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov  driver_->Notify("up", config);
380602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov  EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
3813189a47b7999f1f95d76553c7ee463ac40186d26Darin Petkov  EXPECT_TRUE(GetSelectedService().get() == service_.get());
382e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov
383e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  // Tests that existing properties are reused if no new ones provided.
3843189a47b7999f1f95d76553c7ee463ac40186d26Darin Petkov  driver_->ip_properties_.address = "1.2.3.4";
385e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_CALL(*device_,
386e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov              UpdateIPConfig(Field(&IPConfig::Properties::address, "1.2.3.4")));
387e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  driver_->Notify("up", config);
38879d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov}
38979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov
390b57682315ba47f8c567b6673f5aa7b87f367a4edPaul StewartTEST_P(OpenVPNDriverTest, NotifyUMA) {
39191a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  map<string, string> config;
39291a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  driver_->service_ = service_;
39391a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  driver_->device_ = device_;
39491a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart
39591a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  // Check that UMA metrics are emitted on Notify.
39691a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  EXPECT_CALL(*device_, UpdateIPConfig(_));
39791a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  EXPECT_CALL(metrics_, SendEnumToUMA(
39891a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart      Metrics::kMetricVpnDriver,
39991a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart      Metrics::kVpnDriverOpenVpn,
40091a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart      Metrics::kMetricVpnDriverMax));
40191a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  EXPECT_CALL(metrics_, SendEnumToUMA(
40291a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart      Metrics::kMetricVpnRemoteAuthenticationType,
403b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      GetParam().remote_authentication_type,
40491a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart      Metrics::kVpnRemoteAuthenticationTypeMax));
405e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  for (const auto& authentication_type : GetParam().user_authentication_types) {
406b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    EXPECT_CALL(metrics_, SendEnumToUMA(
407b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        Metrics::kMetricVpnUserAuthenticationType,
408b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        authentication_type,
409b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart        Metrics::kVpnUserAuthenticationTypeMax));
410b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  }
41191a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart
41291a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  Error unused_error;
41391a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  PropertyStore store;
41491a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  driver_->InitPropertyStore(&store);
415b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  if (!GetParam().ca_cert.empty()) {
416b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    store.SetStringsProperty(kOpenVPNCaCertPemProperty,
417b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart                             vector<string>{ GetParam().ca_cert },
418b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart                             &unused_error);
419b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  }
420b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  if (!GetParam().client_cert.empty()) {
421b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    store.SetStringProperty(kOpenVPNClientCertIdProperty,
422b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart                            GetParam().client_cert,
423b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart                            &unused_error);
424b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  }
425b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  if (!GetParam().user.empty()) {
426b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    store.SetStringProperty(kOpenVPNUserProperty, GetParam().user,
427b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart                            &unused_error);
428b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  }
429b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  if (!GetParam().otp.empty()) {
430b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    store.SetStringProperty(kOpenVPNOTPProperty, GetParam().otp, &unused_error);
431b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  }
432b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  if (!GetParam().token.empty()) {
433b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    store.SetStringProperty(kOpenVPNTokenProperty, GetParam().token,
434b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart                            &unused_error);
435b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  }
43691a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart  driver_->Notify("up", config);
437b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  Mock::VerifyAndClearExpectations(&metrics_);
43891a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart}
43991a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart
440b57682315ba47f8c567b6673f5aa7b87f367a4edPaul StewartINSTANTIATE_TEST_CASE_P(
441b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    OpenVPNDriverAuthenticationTypes,
442b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    OpenVPNDriverTest,
443b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart    ::testing::Values(
444b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      AuthenticationExpectations(
445b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          "", "", "", "", "",
446b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          Metrics::kVpnRemoteAuthenticationTypeOpenVpnDefault,
447b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          vector<Metrics::VpnUserAuthenticationType> {
448b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnNone }),
449b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      AuthenticationExpectations(
450b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          "", "client_cert", "", "", "",
451b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          Metrics::kVpnRemoteAuthenticationTypeOpenVpnDefault,
452b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          vector<Metrics::VpnUserAuthenticationType> {
453b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnCertificate }),
454b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      AuthenticationExpectations(
455b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          "", "client_cert", "user", "", "",
456b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          Metrics::kVpnRemoteAuthenticationTypeOpenVpnDefault,
457b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          vector<Metrics::VpnUserAuthenticationType> {
458b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnCertificate,
459b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernamePassword }),
460b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      AuthenticationExpectations(
461b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          "", "", "user", "", "",
462b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          Metrics::kVpnRemoteAuthenticationTypeOpenVpnDefault,
463b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          vector<Metrics::VpnUserAuthenticationType> {
464b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernamePassword }),
465b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      AuthenticationExpectations(
466b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          "", "client_cert", "user", "otp", "",
467b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          Metrics::kVpnRemoteAuthenticationTypeOpenVpnDefault,
468b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          vector<Metrics::VpnUserAuthenticationType> {
469b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnCertificate,
470b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernamePassword,
471b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernamePasswordOtp }),
472b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      AuthenticationExpectations(
473b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          "", "client_cert", "user", "otp", "token",
474b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          Metrics::kVpnRemoteAuthenticationTypeOpenVpnDefault,
475b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          vector<Metrics::VpnUserAuthenticationType> {
476b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnCertificate,
477b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernamePassword,
478b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernamePasswordOtp,
479b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernameToken }),
480b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart      AuthenticationExpectations(
481b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          "ca_cert", "client_cert", "user", "otp", "token",
482b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          Metrics::kVpnRemoteAuthenticationTypeOpenVpnCertificate,
483b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart          vector<Metrics::VpnUserAuthenticationType> {
484b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnCertificate,
485b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernamePassword,
486b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernamePasswordOtp,
487b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart              Metrics::kVpnUserAuthenticationTypeOpenVpnUsernameToken })));
488b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart
48979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin PetkovTEST_F(OpenVPNDriverTest, NotifyFail) {
49079d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  map<string, string> dict;
49179d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->device_ = device_;
4920cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  StartConnectTimeout(0);
4939da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal  EXPECT_CALL(*device_, DropConnection());
49479d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->Notify("fail", dict);
495602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov  EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
49614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov}
49714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov
498605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin PetkovTEST_F(OpenVPNDriverTest, GetRouteOptionEntry) {
499605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::RouteOptions routes;
5004168b2c8d57755ea6b16763745379e0529541a3fBen Chan  EXPECT_EQ(nullptr, OpenVPNDriver::GetRouteOptionEntry("foo", "bar", &routes));
501605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_TRUE(routes.empty());
5024168b2c8d57755ea6b16763745379e0529541a3fBen Chan  EXPECT_EQ(nullptr, OpenVPNDriver::GetRouteOptionEntry("foo", "foo", &routes));
503605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_TRUE(routes.empty());
5044168b2c8d57755ea6b16763745379e0529541a3fBen Chan  EXPECT_EQ(nullptr,
5054168b2c8d57755ea6b16763745379e0529541a3fBen Chan            OpenVPNDriver::GetRouteOptionEntry("foo", "fooz", &routes));
506605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_TRUE(routes.empty());
507e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart  IPConfig::Route* route =
508605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov      OpenVPNDriver::GetRouteOptionEntry("foo", "foo12", &routes);
509605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(1, routes.size());
510605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(route, &routes[12]);
511605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  route = OpenVPNDriver::GetRouteOptionEntry("foo", "foo13", &routes);
512605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(2, routes.size());
513605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(route, &routes[13]);
514605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov}
515605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov
516605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin PetkovTEST_F(OpenVPNDriverTest, ParseRouteOption) {
517605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::RouteOptions routes;
518605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::ParseRouteOption("foo", "bar", &routes);
519605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_TRUE(routes.empty());
520605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::ParseRouteOption("gateway_2", kGateway2, &routes);
521605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::ParseRouteOption("netmask_2", kNetmask2, &routes);
522605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::ParseRouteOption("network_2", kNetwork2, &routes);
523605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(1, routes.size());
524605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::ParseRouteOption("gateway_1", kGateway1, &routes);
525605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::ParseRouteOption("netmask_1", kNetmask1, &routes);
526605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::ParseRouteOption("network_1", kNetwork1, &routes);
527605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(2, routes.size());
528605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kGateway1, routes[1].gateway);
529605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetmask1, routes[1].netmask);
530605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetwork1, routes[1].host);
531605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kGateway2, routes[2].gateway);
532605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetmask2, routes[2].netmask);
533605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetwork2, routes[2].host);
534605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov}
535605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov
536605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin PetkovTEST_F(OpenVPNDriverTest, SetRoutes) {
537605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::RouteOptions routes;
538605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[1].gateway = "1.2.3.4";
539762bfb8ab200a387fe732ec92423a5f0afe11bcfPrabhu Kaliamoorthi  routes[1].host = "1.2.3.4";
540605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[2].host = "2.3.4.5";
541605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[2].netmask = "255.0.0.0";
542605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[3].netmask = "255.0.0.0";
543605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[3].gateway = "1.2.3.5";
544605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[5].host = kNetwork2;
545605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[5].netmask = kNetmask2;
546605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[5].gateway = kGateway2;
547605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[4].host = kNetwork1;
548605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[4].netmask = kNetmask1;
549605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  routes[4].gateway = kGateway1;
550605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  IPConfig::Properties props;
551605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  OpenVPNDriver::SetRoutes(routes, &props);
552605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  ASSERT_EQ(2, props.routes.size());
553605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kGateway1, props.routes[0].gateway);
554605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetmask1, props.routes[0].netmask);
555605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetwork1, props.routes[0].host);
556605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kGateway2, props.routes[1].gateway);
557605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetmask2, props.routes[1].netmask);
558605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetwork2, props.routes[1].host);
559e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov
560e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  // Tests that the routes are not reset if no new routes are supplied.
561e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  OpenVPNDriver::SetRoutes(OpenVPNDriver::RouteOptions(), &props);
562e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_EQ(2, props.routes.size());
563605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov}
564605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov
5654b94484e232d0803785097556aec88c510af441aDarin PetkovTEST_F(OpenVPNDriverTest, SplitPortFromHost) {
5664b94484e232d0803785097556aec88c510af441aDarin Petkov  string name, port;
5674168b2c8d57755ea6b16763745379e0529541a3fBen Chan  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", nullptr, nullptr));
5684b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("", &name, &port));
5694b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com", &name, &port));
5704b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:", &name, &port));
5714b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost(":1234", &name, &port));
5724b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:f:1234", &name, &port));
5734b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:x", &name, &port));
5744b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:-1", &name, &port));
5754b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:+1", &name, &port));
5764b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_FALSE(OpenVPNDriver::SplitPortFromHost("v.com:65536", &name, &port));
5774b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("v.com:0", &name, &port));
5784b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_EQ("v.com", name);
5794b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_EQ("0", port);
5804b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("w.com:65535", &name, &port));
5814b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_EQ("w.com", name);
5824b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_EQ("65535", port);
5834b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_TRUE(OpenVPNDriver::SplitPortFromHost("x.com:12345", &name, &port));
5844b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_EQ("x.com", name);
5854b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_EQ("12345", port);
5864b94484e232d0803785097556aec88c510af441aDarin Petkov}
5874b94484e232d0803785097556aec88c510af441aDarin Petkov
58814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin PetkovTEST_F(OpenVPNDriverTest, ParseForeignOption) {
589e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  vector<string> domain_search;
590e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  vector<string> dns_servers;
59114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  IPConfig::Properties props;
592e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  OpenVPNDriver::ParseForeignOption("", &domain_search, &dns_servers);
593e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  OpenVPNDriver::ParseForeignOption(
594e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov      "dhcp-option DOMAIN", &domain_search, &dns_servers);
595e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  OpenVPNDriver::ParseForeignOption(
596e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov      "dhcp-option DOMAIN zzz.com foo", &domain_search, &dns_servers);
597e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  OpenVPNDriver::ParseForeignOption(
598e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov      "dhcp-Option DOmAIN xyz.com", &domain_search, &dns_servers);
599e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  ASSERT_EQ(1, domain_search.size());
600e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_EQ("xyz.com", domain_search[0]);
601e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  OpenVPNDriver::ParseForeignOption(
602e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov      "dhcp-option DnS 1.2.3.4", &domain_search, &dns_servers);
603e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  ASSERT_EQ(1, dns_servers.size());
604e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_EQ("1.2.3.4", dns_servers[0]);
60514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov}
60614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov
60714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin PetkovTEST_F(OpenVPNDriverTest, ParseForeignOptions) {
608e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  // This also tests that std::map is a sorted container.
60914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  map<int, string> options;
61014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  options[5] = "dhcp-option DOMAIN five.com";
61114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  options[2] = "dhcp-option DOMAIN two.com";
61214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  options[8] = "dhcp-option DOMAIN eight.com";
61314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  options[7] = "dhcp-option DOMAIN seven.com";
61414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  options[4] = "dhcp-option DOMAIN four.com";
615e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  options[10] = "dhcp-option dns 1.2.3.4";
61614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  IPConfig::Properties props;
61714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  OpenVPNDriver::ParseForeignOptions(options, &props);
61814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  ASSERT_EQ(5, props.domain_search.size());
61914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("two.com", props.domain_search[0]);
62014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("four.com", props.domain_search[1]);
62114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("five.com", props.domain_search[2]);
62214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("seven.com", props.domain_search[3]);
62314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("eight.com", props.domain_search[4]);
624e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  ASSERT_EQ(1, props.dns_servers.size());
625e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_EQ("1.2.3.4", props.dns_servers[0]);
626e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov
627e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  // Test that the DNS properties are not updated if no new DNS properties are
628e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  // supplied.
629e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  OpenVPNDriver::ParseForeignOptions(map<int, string>(), &props);
630e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_EQ(5, props.domain_search.size());
631e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  ASSERT_EQ(1, props.dns_servers.size());
63214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov}
63314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov
63414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin PetkovTEST_F(OpenVPNDriverTest, ParseIPConfiguration) {
63514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  map<string, string> config;
636e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  IPConfig::Properties props;
637e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov
638c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  driver_->ParseIPConfiguration(config, &props);
639e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
640e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_EQ(32, props.subnet_prefix);
641e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov
642e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  props.subnet_prefix = 18;
643c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  driver_->ParseIPConfiguration(config, &props);
644e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov  EXPECT_EQ(18, props.subnet_prefix);
645e8587e382d1566c8b72ec4714c6e39d9b747fe20Darin Petkov
6464698c1a8ea2fc79268bea8b7eb57e30db52f4dc0Paul Stewart  // An "ifconfig_remote" parameter that looks like a netmask should be
6474698c1a8ea2fc79268bea8b7eb57e30db52f4dc0Paul Stewart  // applied to the subnet prefix instead of to the peer address.
6484698c1a8ea2fc79268bea8b7eb57e30db52f4dc0Paul Stewart  config["ifconfig_remotE"] = "255.255.0.0";
649c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  driver_->ParseIPConfiguration(config, &props);
6504698c1a8ea2fc79268bea8b7eb57e30db52f4dc0Paul Stewart  EXPECT_EQ(16, props.subnet_prefix);
6514698c1a8ea2fc79268bea8b7eb57e30db52f4dc0Paul Stewart  EXPECT_EQ("", props.peer_address);
6524698c1a8ea2fc79268bea8b7eb57e30db52f4dc0Paul Stewart
65314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["ifconfig_loCal"] = "4.5.6.7";
65414c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["ifconfiG_broadcast"] = "1.2.255.255";
65514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["ifconFig_netmAsk"] = "255.255.255.0";
65614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["ifconfig_remotE"] = "33.44.55.66";
65714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["route_vpN_gateway"] = "192.168.1.1";
658ce4ec19216ccd15ae349ee42498657afc2c75bd8Paul Stewart  config["trusted_ip"] = "99.88.77.66";
65914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["tun_mtu"] = "1000";
66014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["foreign_option_2"] = "dhcp-option DNS 4.4.4.4";
66114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["foreign_option_1"] = "dhcp-option DNS 1.1.1.1";
66214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["foreign_option_3"] = "dhcp-option DNS 2.2.2.2";
663605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  config["route_network_2"] = kNetwork2;
664605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  config["route_network_1"] = kNetwork1;
665605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  config["route_netmask_2"] = kNetmask2;
666605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  config["route_netmask_1"] = kNetmask1;
667605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  config["route_gateway_2"] = kGateway2;
668605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  config["route_gateway_1"] = kGateway1;
66914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  config["foo"] = "bar";
670c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  driver_->ParseIPConfiguration(config, &props);
67114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
67214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("4.5.6.7", props.address);
67314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("1.2.255.255", props.broadcast_address);
67448100b0f484fb59d5f34eb4565375759202295e1Paul Stewart  EXPECT_EQ(24, props.subnet_prefix);
67514c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("33.44.55.66", props.peer_address);
67614c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("192.168.1.1", props.gateway);
677762bfb8ab200a387fe732ec92423a5f0afe11bcfPrabhu Kaliamoorthi  EXPECT_EQ("99.88.77.66/32", props.exclusion_list[0]);
678762bfb8ab200a387fe732ec92423a5f0afe11bcfPrabhu Kaliamoorthi  EXPECT_EQ(1, props.exclusion_list.size());
67914c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ(1000, props.mtu);
68014c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  ASSERT_EQ(3, props.dns_servers.size());
68114c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("1.1.1.1", props.dns_servers[0]);
68214c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("4.4.4.4", props.dns_servers[1]);
68314c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov  EXPECT_EQ("2.2.2.2", props.dns_servers[2]);
684605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  ASSERT_EQ(2, props.routes.size());
685605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kGateway1, props.routes[0].gateway);
686605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetmask1, props.routes[0].netmask);
687605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetwork1, props.routes[0].host);
688605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kGateway2, props.routes[1].gateway);
689605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetmask2, props.routes[1].netmask);
690605967453c2bfe1340fdfbee1bebe6526d1a9bc6Darin Petkov  EXPECT_EQ(kNetwork2, props.routes[1].host);
691a016312b7470e124774aec197e3b43bc795637c3Ben Chan  EXPECT_FALSE(props.blackhole_ipv6);
692c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart
693c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  // If the driver is configured to ignore the gateway provided, it will
694c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  // not set the "gateway" property for the properties, however the
695c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  // explicitly supplied routes should still be set.
696c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  SetArg(kOpenVPNIgnoreDefaultRouteProperty, "some value");
697c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  IPConfig::Properties props_without_gateway;
698c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  driver_->ParseIPConfiguration(config, &props_without_gateway);
699c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  EXPECT_EQ(kGateway1, props_without_gateway.routes[0].gateway);
700c8e3ef9ef7cfe9a14903bcfbb17693587e576652Paul Stewart  EXPECT_EQ("", props_without_gateway.gateway);
701a64b7d73ddced59e3c01233e2cfea733e410cb81Paul Stewart
702a64b7d73ddced59e3c01233e2cfea733e410cb81Paul Stewart  // A pushed redirect flag should override the IgnoreDefaultRoute property.
703a64b7d73ddced59e3c01233e2cfea733e410cb81Paul Stewart  config["redirect_gateway"] = "def1";
704a64b7d73ddced59e3c01233e2cfea733e410cb81Paul Stewart  IPConfig::Properties props_with_override;
705a64b7d73ddced59e3c01233e2cfea733e410cb81Paul Stewart  driver_->ParseIPConfiguration(config, &props_with_override);
706a64b7d73ddced59e3c01233e2cfea733e410cb81Paul Stewart  EXPECT_EQ("192.168.1.1", props_with_override.gateway);
70714c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov}
70814c29ec4815e8ecda47b7ce5efdaa444580e20ceDarin Petkov
709fe6a93757ab4d84855e757c52e7e114593da1b78Darin PetkovTEST_F(OpenVPNDriverTest, InitOptionsNoHost) {
710fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  Error error;
711406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
71279d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->InitOptions(&options, &error);
713fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  EXPECT_EQ(Error::kInvalidArguments, error.type());
714fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  EXPECT_TRUE(options.empty());
715fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov}
716fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
717fe6a93757ab4d84855e757c52e7e114593da1b78Darin PetkovTEST_F(OpenVPNDriverTest, InitOptions) {
718fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  static const char kHost[] = "192.168.2.254";
7191fa8194d9e0e9f30c88b3e51cc32b8ed904b0076Darin Petkov  static const char kTLSAuthContents[] = "SOME-RANDOM-CONTENTS\n";
720e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  static const char kID[] = "TestPKCS11ID";
72118145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  static const char kKU0[] = "00";
72218145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  static const char kKU1[] = "01";
723e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  FilePath empty_cert;
7247372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kProviderHostProperty, kHost);
7257372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNTLSAuthContentsProperty, kTLSAuthContents);
7267372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNClientCertIdProperty, kID);
72718145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  SetArg(kOpenVPNRemoteCertKUProperty, string(kKU0) + " " + string(kKU1));
72879d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->rpc_task_.reset(new RPCTask(&control_, this));
72979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->tunnel_interface_ = kInterfaceName;
730e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
731700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(false));
732e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
733e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  Error error;
734406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
735e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  driver_->InitOptions(&options, &error);
736e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  EXPECT_TRUE(error.IsSuccess());
737b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  EXPECT_EQ(vector<string> { "client" }, options[0]);
738b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "remote", kHost);
739b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, vector<string> { "setenv", kRPCTaskPathVariable,
740406c473d5680f42b067dbda0a9b011b162130effPaul Stewart                                          RPCTaskMockAdaptor::kRpcId });
741b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "dev", kInterfaceName);
742b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "group", "openvpn");
743e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  EXPECT_EQ(kInterfaceName, driver_->tunnel_interface_);
744e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  ASSERT_FALSE(driver_->tls_auth_file_.empty());
745b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "tls-auth", driver_->tls_auth_file_.value());
746e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  string contents;
747a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::ReadFileToString(driver_->tls_auth_file_, &contents));
748e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  EXPECT_EQ(kTLSAuthContents, contents);
749b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "pkcs11-id", kID);
750b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "ca", OpenVPNDriver::kDefaultCACertificates);
751b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "syslog");
752b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "auth-user-pass");
75318145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  ExpectInFlags(options, vector<string> { "remote-cert-ku", kKU0, kKU1 });
754e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov}
755e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
7564b94484e232d0803785097556aec88c510af441aDarin PetkovTEST_F(OpenVPNDriverTest, InitOptionsHostWithPort) {
7577372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kProviderHostProperty, "v.com:1234");
7584b94484e232d0803785097556aec88c510af441aDarin Petkov  driver_->rpc_task_.reset(new RPCTask(&control_, this));
7594b94484e232d0803785097556aec88c510af441aDarin Petkov  driver_->tunnel_interface_ = kInterfaceName;
7604b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
761700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(false));
7624b94484e232d0803785097556aec88c510af441aDarin Petkov
7634b94484e232d0803785097556aec88c510af441aDarin Petkov  Error error;
764406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
7654b94484e232d0803785097556aec88c510af441aDarin Petkov  driver_->InitOptions(&options, &error);
7664b94484e232d0803785097556aec88c510af441aDarin Petkov  EXPECT_TRUE(error.IsSuccess());
767b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, vector<string> { "remote", "v.com", "1234" });
7684b94484e232d0803785097556aec88c510af441aDarin Petkov}
7694b94484e232d0803785097556aec88c510af441aDarin Petkov
770ca8a0e64861afa2932b9835d85fcefadce3b763aDarin PetkovTEST_F(OpenVPNDriverTest, InitCAOptions) {
771e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  static const char kHost[] = "192.168.2.254";
772ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  static const char kCaCert[] = "foo";
773e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  static const char kCaCertNSS[] = "{1234}";
774ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov
775ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  Error error;
776406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
777ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
778ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  EXPECT_TRUE(error.IsSuccess());
779b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "ca", OpenVPNDriver::kDefaultCACertificates);
780ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov
781ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  options.clear();
7827372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNCaCertProperty, kCaCert);
783ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
784b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "ca", kCaCert);
785ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  EXPECT_TRUE(error.IsSuccess());
786ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov
787c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart  // We should ignore the CaCertNSS property.
7887372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNCaCertNSSProperty, kCaCertNSS);
789c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart  EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
790c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart  ExpectInFlags(options, "ca", kCaCert);
791c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart  EXPECT_TRUE(error.IsSuccess());
792ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov
7937372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNCaCertProperty, "");
7947372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kProviderHostProperty, kHost);
795e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  FilePath empty_cert;
796ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  error.Reset();
797ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
798c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart  ExpectInFlags(options, "ca", OpenVPNDriver::kDefaultCACertificates);
799ca8a0e64861afa2932b9835d85fcefadce3b763aDarin Petkov  EXPECT_TRUE(error.IsSuccess());
8005baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart
801c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart  SetArg(kOpenVPNCaCertProperty, kCaCert);
8020f9c930955e22e7d6a4a011f565ca5197e2cee8fPaul Stewart  const vector<string> kCaCertPEM{ "---PEM CONTENTS---" };
8030f9c930955e22e7d6a4a011f565ca5197e2cee8fPaul Stewart  SetArgArray(kOpenVPNCaCertPemProperty, kCaCertPEM);
8045baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
8055baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  EXPECT_EQ(Error::kInvalidArguments, error.type());
806c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart  EXPECT_EQ("Can't specify more than one of CACert and CACertPEM.",
8075baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart            error.message());
8085baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart
8095baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  options.clear();
810c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart  SetArg(kOpenVPNCaCertProperty, "");
8117372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kProviderHostProperty, "");
8125baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  static const char kPEMCertfile[] = "/tmp/pem-cert";
8135baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  FilePath pem_cert(kPEMCertfile);
8140f9c930955e22e7d6a4a011f565ca5197e2cee8fPaul Stewart  EXPECT_CALL(*certificate_file_, CreatePEMFromStrings(kCaCertPEM))
8155baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart      .WillOnce(Return(empty_cert))
8165baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart      .WillOnce(Return(pem_cert));
8175baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart
8185baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  error.Reset();
8195baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  EXPECT_FALSE(driver_->InitCAOptions(&options, &error));
8205baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  EXPECT_EQ(Error::kInvalidArguments, error.type());
8210f9c930955e22e7d6a4a011f565ca5197e2cee8fPaul Stewart  EXPECT_EQ("Unable to extract PEM CA certificates.", error.message());
8225baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart
8235baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  error.Reset();
8245baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  options.clear();
8255baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  EXPECT_TRUE(driver_->InitCAOptions(&options, &error));
826b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "ca", kPEMCertfile);
8275baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart  EXPECT_TRUE(error.IsSuccess());
828e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov}
829e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
8308343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul StewartTEST_F(OpenVPNDriverTest, InitCertificateVerifyOptions) {
8318343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  {
8328343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    Error error;
8338343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    vector<vector<string>> options;
8348343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    // No options supplied.
8358343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    driver_->InitCertificateVerifyOptions(&options);
8368343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(options.empty());
8378343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  }
8388343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  const char kName[] = "x509-name";
8398343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  {
8408343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    Error error;
8418343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    vector<vector<string>> options;
8428343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    // With Name property alone, we should have the 1-parameter version of the
8438343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    // "x509-verify-name" parameter provided.
8448343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    SetArg(kOpenVPNVerifyX509NameProperty, kName);
8458343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    driver_->InitCertificateVerifyOptions(&options);
8468343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    ExpectInFlags(options, "verify-x509-name", kName);
8478343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  }
8488343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  const char kType[] = "x509-type";
8498343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  {
8508343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    Error error;
8518343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    vector<vector<string>> options;
8528343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    // With both Name property and Type property set, we should have the
8538343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    // 2-parameter version of the "x509-verify-name" parameter provided.
8548343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    SetArg(kOpenVPNVerifyX509TypeProperty, kType);
8558343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    driver_->InitCertificateVerifyOptions(&options);
8568343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    ExpectInFlags(options, vector<string> { "verify-x509-name", kName, kType });
8578343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  }
8588343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  {
8598343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    Error error;
8608343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    vector<vector<string>> options;
8618343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    // We should ignore the Type parameter if no Name parameter is specified.
8628343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    SetArg(kOpenVPNVerifyX509NameProperty, "");
8638343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    driver_->InitCertificateVerifyOptions(&options);
8648343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(options.empty());
8658343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  }
8668343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart}
8678343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart
8684e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin PetkovTEST_F(OpenVPNDriverTest, InitClientAuthOptions) {
8694e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  static const char kTestValue[] = "foo";
870406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
8714e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov
8724e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  // No key or cert, assume user/password authentication.
8734e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  driver_->InitClientAuthOptions(&options);
874b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "auth-user-pass");
875b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "key");
876b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "cert");
8774e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov
8784e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  // Cert available, no user/password.
8794e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  options.clear();
8807080441abbcae2d4fc146fd40958bc11fa3eb169Paul Stewart  SetArg(kOpenVPNCertProperty, kTestValue);
8814e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  driver_->InitClientAuthOptions(&options);
882b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "auth-user-pass");
883b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "key");
884b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "cert", kTestValue);
8854e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov
8864e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  // Key available, no user/password.
8874e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  options.clear();
8887080441abbcae2d4fc146fd40958bc11fa3eb169Paul Stewart  SetArg(kOpenVPNKeyProperty, kTestValue);
8894e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  driver_->InitClientAuthOptions(&options);
890b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "auth-user-pass");
891b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "key", kTestValue);
8924e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov
8934e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  // Key available, AuthUserPass set.
8944e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  options.clear();
8957372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNAuthUserPassProperty, kTestValue);
8964e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  driver_->InitClientAuthOptions(&options);
897b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "auth-user-pass");
898b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "key", kTestValue);
8994e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov
9004e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  // Key available, User set.
9014e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  options.clear();
9027372878af066cc079ad88a7b004ca3f769952de2Ben Chan  RemoveStringArg(kOpenVPNAuthUserPassProperty);
9037372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNUserProperty, "user");
9044e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov  driver_->InitClientAuthOptions(&options);
905b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "auth-user-pass");
906b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "key", kTestValue);
907bb985105b95110ae756be1b570a5e9084694785aPaul Stewart
908bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  // Empty PKCS11 certificate id, no user/password/cert.
909bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  options.clear();
910bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  RemoveStringArg(kOpenVPNKeyProperty);
911bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  RemoveStringArg(kOpenVPNCertProperty);
9127372878af066cc079ad88a7b004ca3f769952de2Ben Chan  RemoveStringArg(kOpenVPNUserProperty);
9137372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNClientCertIdProperty, "");
914bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  driver_->InitClientAuthOptions(&options);
915b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "auth-user-pass");
916b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "key");
917b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "cert");
918b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "pkcs11-id");
919bb985105b95110ae756be1b570a5e9084694785aPaul Stewart
920bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  // Non-empty PKCS11 certificate id, no user/password/cert.
921bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  options.clear();
9227372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNClientCertIdProperty, kTestValue);
923bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  driver_->InitClientAuthOptions(&options);
924b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "auth-user-pass");
925b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "key");
926b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "cert");
927bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  // The "--pkcs11-id" option is added in InitPKCS11Options(), not here.
928b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "pkcs11-id");
929bb985105b95110ae756be1b570a5e9084694785aPaul Stewart
930bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  // PKCS11 certificate id available, AuthUserPass set.
931bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  options.clear();
9327372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNAuthUserPassProperty, kTestValue);
933bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  driver_->InitClientAuthOptions(&options);
934b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "auth-user-pass");
935b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "key");
936b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "cert");
937bb985105b95110ae756be1b570a5e9084694785aPaul Stewart
938bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  // PKCS11 certificate id available, User set.
939bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  options.clear();
9407372878af066cc079ad88a7b004ca3f769952de2Ben Chan  RemoveStringArg(kOpenVPNAuthUserPassProperty);
9417372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNUserProperty, "user");
942bb985105b95110ae756be1b570a5e9084694785aPaul Stewart  driver_->InitClientAuthOptions(&options);
943b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "auth-user-pass");
944b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "key");
945b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectNotInFlags(options, "cert");
9464e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov}
9474e1b3f876be1d534f65933f828b2d6bf0ec2df45Darin Petkov
9488343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul StewartTEST_F(OpenVPNDriverTest, InitExtraCertOptions) {
9498343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  {
9508343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    Error error;
9518343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    vector<vector<string>> options;
9528343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    // No ExtraCertOptions supplied.
9538343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(driver_->InitExtraCertOptions(&options, &error));
9548343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(error.IsSuccess());
9558343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(options.empty());
9568343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  }
9578343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  {
9588343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    Error error;
9598343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    vector<vector<string>> options;
9608343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    SetArgArray(kOpenVPNExtraCertPemProperty, vector<string>());
9618343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    // Empty ExtraCertOptions supplied.
9628343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(driver_->InitExtraCertOptions(&options, &error));
9638343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(error.IsSuccess());
9648343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(options.empty());
9658343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  }
9668343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  const vector<string> kExtraCerts{ "---PEM CONTENTS---" };
9678343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  SetArgArray(kOpenVPNExtraCertPemProperty, kExtraCerts);
9688343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  static const char kPEMCertfile[] = "/tmp/pem-cert";
9698343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  FilePath pem_cert(kPEMCertfile);
9708343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  EXPECT_CALL(*extra_certificates_file_, CreatePEMFromStrings(kExtraCerts))
9718343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart      .WillOnce(Return(FilePath()))
9728343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart      .WillOnce(Return(pem_cert));
9738343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  // CreatePemFromStrings fails.
9748343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  {
9758343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    Error error;
9768343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    vector<vector<string>> options;
9778343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_FALSE(driver_->InitExtraCertOptions(&options, &error));
9788343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_EQ(Error::kInvalidArguments, error.type());
9798343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(options.empty());
9808343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  }
9818343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  // CreatePemFromStrings succeeds.
9828343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  {
9838343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    Error error;
9848343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    vector<vector<string>> options;
9858343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(driver_->InitExtraCertOptions(&options, &error));
9868343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    EXPECT_TRUE(error.IsSuccess());
9878343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart    ExpectInFlags(options, "extra-certs", kPEMCertfile);
9888343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart  }
9898343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart}
9908343c0b3ba4cee4da9af654df3f0c21a0f73923ePaul Stewart
991e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin PetkovTEST_F(OpenVPNDriverTest, InitPKCS11Options) {
992406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
993e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  driver_->InitPKCS11Options(&options);
994e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  EXPECT_TRUE(options.empty());
995e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
996e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  static const char kID[] = "TestPKCS11ID";
9977372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNClientCertIdProperty, kID);
998e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  driver_->InitPKCS11Options(&options);
999b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "pkcs11-id", kID);
1000b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "pkcs11-providers", "libchaps.so");
1001e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
1002e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  static const char kProvider[] = "libpkcs11.so";
10037372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kOpenVPNProviderProperty, kProvider);
1004e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  options.clear();
1005e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  driver_->InitPKCS11Options(&options);
1006b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "pkcs11-id", kID);
1007b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "pkcs11-providers", kProvider);
1008e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov}
1009e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
10104cbff5b5897593f7a2e6de48a98abe72356075afDarin PetkovTEST_F(OpenVPNDriverTest, InitManagementChannelOptionsServerFail) {
1011406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
10124cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_CALL(*management_server_, Start(&dispatcher_, GetSockets(), &options))
10134cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov      .WillOnce(Return(false));
1014a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  Error error;
10154cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_FALSE(InitManagementChannelOptions(&options, &error));
1016e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  EXPECT_EQ(Error::kInternalError, error.type());
1017e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  EXPECT_EQ("Unable to setup management channel.", error.message());
10184cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov}
1019e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov
10204cbff5b5897593f7a2e6de48a98abe72356075afDarin PetkovTEST_F(OpenVPNDriverTest, InitManagementChannelOptionsOnline) {
1021406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
10224cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_CALL(*management_server_, Start(&dispatcher_, GetSockets(), &options))
10234cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov      .WillOnce(Return(true));
1024700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
1025a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(*management_server_, ReleaseHold());
10264cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  Error error;
10274cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_TRUE(InitManagementChannelOptions(&options, &error));
1028a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_TRUE(error.IsSuccess());
10294cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov}
1030a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
10314cbff5b5897593f7a2e6de48a98abe72356075afDarin PetkovTEST_F(OpenVPNDriverTest, InitManagementChannelOptionsOffline) {
1032406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
10334cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_CALL(*management_server_, Start(&dispatcher_, GetSockets(), &options))
10344cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov      .WillOnce(Return(true));
1035700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(false));
1036a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(*management_server_, ReleaseHold()).Times(0);
10374cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  Error error;
10384cbff5b5897593f7a2e6de48a98abe72356075afDarin Petkov  EXPECT_TRUE(InitManagementChannelOptions(&options, &error));
1039a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_TRUE(error.IsSuccess());
1040fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov}
1041fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
104255771b7132993f31e2de4c7319ff8640f49e5cccDarin PetkovTEST_F(OpenVPNDriverTest, InitLoggingOptions) {
1043406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
104455771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  bool vpn_logging = SLOG_IS_ON(VPN, 0);
104555771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
104655771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  driver_->InitLoggingOptions(&options);
104755771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  ASSERT_EQ(1, options.size());
1048b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  EXPECT_EQ(vector<string> { "syslog" }, options[0]);
104955771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
105055771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  options.clear();
105155771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  driver_->InitLoggingOptions(&options);
1052b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "verb", "3");
105355771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
105455771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  SetArg("OpenVPN.Verb", "2");
105555771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  options.clear();
105655771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  driver_->InitLoggingOptions(&options);
1057b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "verb", "2");
105855771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  ScopeLogger::GetInstance()->EnableScopesByName("+vpn");
105955771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  SetArg("OpenVPN.Verb", "1");
106055771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  options.clear();
106155771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  driver_->InitLoggingOptions(&options);
1062b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  ExpectInFlags(options, "verb", "1");
106355771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  if (!vpn_logging) {
106455771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov    ScopeLogger::GetInstance()->EnableScopesByName("-vpn");
106555771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov  }
106655771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov}
106755771b7132993f31e2de4c7319ff8640f49e5cccDarin Petkov
1068fe6a93757ab4d84855e757c52e7e114593da1b78Darin PetkovTEST_F(OpenVPNDriverTest, AppendValueOption) {
1069406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
10704646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_FALSE(
10714646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov      driver_->AppendValueOption("OpenVPN.UnknownProperty", kOption, &options));
1072fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  EXPECT_TRUE(options.empty());
1073fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
1074e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  SetArg(kProperty, "");
10754646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
1076fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  EXPECT_TRUE(options.empty());
1077fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
1078e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  SetArg(kProperty, kValue);
1079e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  SetArg(kProperty2, kValue2);
10804646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
10814646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
1082406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  EXPECT_EQ(2, options.size());
1083406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<string> expected_value { kOption, kValue };
1084406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  EXPECT_EQ(expected_value, options[0]);
1085406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<string> expected_value2 { kOption2, kValue2 };
1086406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  EXPECT_EQ(expected_value2, options[1]);
1087fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov}
1088fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
108918145e99011cdc24e70a42f50c0883cf1ea1419dPaul StewartTEST_F(OpenVPNDriverTest, AppendDelimitedValueOption) {
109018145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  vector<vector<string>> options;
109118145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  EXPECT_FALSE(
109218145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart      driver_->AppendDelimitedValueOption(
109318145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart          "OpenVPN.UnknownProperty", kOption, ' ', &options));
109418145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  EXPECT_TRUE(options.empty());
109518145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart
109618145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  SetArg(kProperty, "");
109718145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  EXPECT_FALSE(
109818145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart      driver_->AppendDelimitedValueOption(kProperty, kOption, ' ', &options));
109918145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  EXPECT_TRUE(options.empty());
110018145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart
110118145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  string kConcatenatedValues(string(kValue) + " " + string(kValue2));
110218145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  SetArg(kProperty, kConcatenatedValues);
110318145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  SetArg(kProperty2, kConcatenatedValues);
110418145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  EXPECT_TRUE(driver_->AppendDelimitedValueOption(
110518145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart      kProperty, kOption, ':', &options));
110618145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  EXPECT_TRUE(driver_->AppendDelimitedValueOption(
110718145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart      kProperty2, kOption2, ' ', &options));
110818145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  EXPECT_EQ(2, options.size());
110918145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  vector<string> expected_value { kOption, kConcatenatedValues };
111018145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  EXPECT_EQ(expected_value, options[0]);
111118145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  vector<string> expected_value2 { kOption2, kValue, kValue2 };
111218145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart  EXPECT_EQ(expected_value2, options[1]);
111318145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart}
111418145e99011cdc24e70a42f50c0883cf1ea1419dPaul Stewart
1115fe6a93757ab4d84855e757c52e7e114593da1b78Darin PetkovTEST_F(OpenVPNDriverTest, AppendFlag) {
1116406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  vector<vector<string>> options;
11174646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_FALSE(
11184646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov      driver_->AppendFlag("OpenVPN.UnknownProperty", kOption, &options));
1119fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  EXPECT_TRUE(options.empty());
1120fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
1121e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  SetArg(kProperty, "");
1122e0d5dd1ef481599ece78f8ff4a84485eb1134b85Darin Petkov  SetArg(kProperty2, kValue2);
11234646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_TRUE(driver_->AppendFlag(kProperty, kOption, &options));
11244646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_TRUE(driver_->AppendFlag(kProperty2, kOption2, &options));
1125fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov  EXPECT_EQ(2, options.size());
1126406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  EXPECT_EQ(vector<string> { kOption }, options[0]);
1127406c473d5680f42b067dbda0a9b011b162130effPaul Stewart  EXPECT_EQ(vector<string> { kOption2 }, options[1]);
1128fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov}
1129fe6a93757ab4d84855e757c52e7e114593da1b78Darin Petkov
1130ca6abd4635507fa5b8f4b8819a37819fb560c464Paul StewartTEST_F(OpenVPNDriverTest, ClaimInterface) {
113179d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->tunnel_interface_ = kInterfaceName;
113279d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_FALSE(driver_->ClaimInterface(string(kInterfaceName) + "XXX",
113379d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov                                       kInterfaceIndex));
113479d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_FALSE(driver_->device_);
1135ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewart
113636a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov  static const char kHost[] = "192.168.2.254";
11377372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kProviderHostProperty, kHost);
11384646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_CALL(*management_server_, Start(_, _, _)).WillOnce(Return(true));
1139700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(false));
1140d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal  EXPECT_CALL(
1141d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal      process_manager_,
1142d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal      StartProcess(_, _, _, _, false /* Don't exit with parent */, _))
1143d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal      .WillOnce(Return(true));
1144a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  const int kServiceCallbackTag = 1;
1145a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_EQ(0, driver_->default_service_callback_tag_);
1146a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(manager_, RegisterDefaultServiceCallback(_))
1147a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov      .WillOnce(Return(kServiceCallbackTag));
114879d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_TRUE(driver_->ClaimInterface(kInterfaceName, kInterfaceIndex));
114979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  ASSERT_TRUE(driver_->device_);
115079d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_EQ(kInterfaceIndex, driver_->device_->interface_index());
1151a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_EQ(kServiceCallbackTag, driver_->default_service_callback_tag_);
1152ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewart}
1153ca6abd4635507fa5b8f4b8819a37819fb560c464Paul Stewart
1154aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin PetkovTEST_F(OpenVPNDriverTest, IdleService) {
1155aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  SetService(service_);
1156aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_CALL(*service_, SetState(Service::kStateIdle));
1157aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  driver_->IdleService();
1158aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov}
1159aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov
1160aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin PetkovTEST_F(OpenVPNDriverTest, FailService) {
1161aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  static const char kErrorDetails[] = "Bad password.";
1162aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  SetService(service_);
11631c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(*service_, SetFailure(Service::kFailureConnect));
11641c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  driver_->FailService(Service::kFailureConnect, kErrorDetails);
1165aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ(kErrorDetails, service_->error_details());
1166aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov}
1167aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov
116836a3acea410a5731b392d0f735e022472e5c55e3Darin PetkovTEST_F(OpenVPNDriverTest, Cleanup) {
1169aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  // Ensure no crash.
11701c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  driver_->Cleanup(Service::kStateIdle,
11711c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov                   Service::kFailureUnknown,
11721c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov                   Service::kErrorDetailsNone);
11731fa8194d9e0e9f30c88b3e51cc32b8ed904b0076Darin Petkov
117436a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov  const int kPID = 123456;
1175a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  const int kServiceCallbackTag = 5;
1176aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  static const char kErrorDetails[] = "Certificate revoked.";
1177a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  driver_->default_service_callback_tag_ = kServiceCallbackTag;
117879d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->pid_ = kPID;
117979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->rpc_task_.reset(new RPCTask(&control_, this));
118079d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->tunnel_interface_ = kInterfaceName;
118179d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->device_ = device_;
118279d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->service_ = service_;
11833189a47b7999f1f95d76553c7ee463ac40186d26Darin Petkov  driver_->ip_properties_.address = "1.2.3.4";
11840cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  StartConnectTimeout(0);
11851fa8194d9e0e9f30c88b3e51cc32b8ed904b0076Darin Petkov  FilePath tls_auth_file;
1186a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::CreateTemporaryFile(&tls_auth_file));
11871fa8194d9e0e9f30c88b3e51cc32b8ed904b0076Darin Petkov  EXPECT_FALSE(tls_auth_file.empty());
1188a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::PathExists(tls_auth_file));
11891fa8194d9e0e9f30c88b3e51cc32b8ed904b0076Darin Petkov  driver_->tls_auth_file_ = tls_auth_file;
11904646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  // Stop will be called twice -- once by Cleanup and once by the destructor.
11914646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_CALL(*management_server_, Stop()).Times(2);
1192609e2f164a71c1b757292c32e8465eaa8bd397cbmukesh agrawal  // UpdateExitCallback will be called twice -- once to ignore exit,
1193609e2f164a71c1b757292c32e8465eaa8bd397cbmukesh agrawal  // and once to re-enabling monitoring of exit.
1194609e2f164a71c1b757292c32e8465eaa8bd397cbmukesh agrawal  EXPECT_CALL(process_manager_, UpdateExitCallback(kPID, _)).Times(2);
1195a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(manager_, DeregisterDefaultServiceCallback(kServiceCallbackTag));
1196609e2f164a71c1b757292c32e8465eaa8bd397cbmukesh agrawal  EXPECT_CALL(process_manager_, StopProcess(kPID));
11975a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  EXPECT_CALL(device_info_, DeleteInterface(_)).Times(0);
11989da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal  EXPECT_CALL(*device_, DropConnection());
11999a24553461df7036755060423f90804011612249Eric Shienbrood  EXPECT_CALL(*device_, SetEnabled(false));
12001c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(*service_, SetFailure(Service::kFailureInternal));
12011c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  driver_->Cleanup(
12021c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov      Service::kStateFailure, Service::kFailureInternal,  kErrorDetails);
1203a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_EQ(0, driver_->default_service_callback_tag_);
120479d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_EQ(0, driver_->pid_);
120579d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_FALSE(driver_->rpc_task_.get());
120679d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_TRUE(driver_->tunnel_interface_.empty());
120779d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_FALSE(driver_->device_);
120879d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_FALSE(driver_->service_);
1209aba893217c9cf1dd0d39c4dee89a23d3b1a3f4c1Darin Petkov  EXPECT_EQ(kErrorDetails, service_->error_details());
1210a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_FALSE(base::PathExists(tls_auth_file));
12111fa8194d9e0e9f30c88b3e51cc32b8ed904b0076Darin Petkov  EXPECT_TRUE(driver_->tls_auth_file_.empty());
12123189a47b7999f1f95d76553c7ee463ac40186d26Darin Petkov  EXPECT_TRUE(driver_->ip_properties_.address.empty());
1213602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov  EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
121436a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov}
121536a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov
121636a3acea410a5731b392d0f735e022472e5c55e3Darin PetkovTEST_F(OpenVPNDriverTest, SpawnOpenVPN) {
12171a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov  SetupLSBRelease();
12181a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov
121979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_FALSE(driver_->SpawnOpenVPN());
122036a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov
122136a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov  static const char kHost[] = "192.168.2.254";
12227372878af066cc079ad88a7b004ca3f769952de2Ben Chan  SetArg(kProviderHostProperty, kHost);
122379d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->tunnel_interface_ = "tun0";
122479d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->rpc_task_.reset(new RPCTask(&control_, this));
12254646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov  EXPECT_CALL(*management_server_, Start(_, _, _))
12264646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov      .Times(2)
12274646302299227516f4979bb27b46ce6249f6ec2fDarin Petkov      .WillRepeatedly(Return(true));
1228700de6400c18f8cba77821f8cd2a1935b96999a6Peter Qiu  EXPECT_CALL(manager_, IsConnected()).Times(2).WillRepeatedly(Return(false));
122936a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov
123036a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov  const int kPID = 234678;
1231d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal  const map<string, string> expected_env{
1232d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal    {"IV_PLAT", "Chromium OS"},
1233d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal    {"IV_PLAT_REL", "2202.0"}};
1234d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal  EXPECT_CALL(process_manager_, StartProcess(_, _, _, expected_env, _, _))
1235d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal      .WillOnce(Return(-1))
1236d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal      .WillOnce(Return(kPID));
123779d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_FALSE(driver_->SpawnOpenVPN());
123879d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_TRUE(driver_->SpawnOpenVPN());
123979d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_EQ(kPID, driver_->pid_);
124036a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov}
124136a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov
124236a3acea410a5731b392d0f735e022472e5c55e3Darin PetkovTEST_F(OpenVPNDriverTest, OnOpenVPNDied) {
124336a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov  const int kPID = 99999;
12445a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  driver_->device_ = device_;
124579d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  driver_->pid_ = kPID;
12469da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal  EXPECT_CALL(*device_, DropConnection());
12475a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  EXPECT_CALL(*device_, SetEnabled(false));
1248609e2f164a71c1b757292c32e8465eaa8bd397cbmukesh agrawal  EXPECT_CALL(process_manager_, StopProcess(_)).Times(0);
12495a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
1250d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal  driver_->OnOpenVPNDied(2);
125179d74c9bdb654be48765c1e7aa416126ffd2ae5eDarin Petkov  EXPECT_EQ(0, driver_->pid_);
125236a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov}
125336a3acea410a5731b392d0f735e022472e5c55e3Darin Petkov
12546aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin PetkovTEST_F(OpenVPNDriverTest, Disconnect) {
12556aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov  driver_->device_ = device_;
12566aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov  driver_->service_ = service_;
12579da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal  EXPECT_CALL(*device_, DropConnection());
12589a24553461df7036755060423f90804011612249Eric Shienbrood  EXPECT_CALL(*device_, SetEnabled(false));
12596aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov  EXPECT_CALL(device_info_, DeleteInterface(kInterfaceIndex));
12606aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov  EXPECT_CALL(*service_, SetState(Service::kStateIdle));
12616aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov  driver_->Disconnect();
1262a0e645ef4df5ed16fef367ec97c3d9cded7980eeDarin Petkov  EXPECT_FALSE(driver_->device_);
12636aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov  EXPECT_FALSE(driver_->service_);
12646aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov}
12656aa2187f18e5a9ba3d6d475669cd27dfee4d92bdDarin Petkov
12665eb0542cb67358d9030367498a4ad741fc42af4fDarin PetkovTEST_F(OpenVPNDriverTest, OnConnectionDisconnected) {
1267a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  EXPECT_CALL(*management_server_, Restart());
1268a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  SetDevice(device_);
1269a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  SetService(service_);
12709da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal  EXPECT_CALL(*device_, DropConnection());
1271a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  EXPECT_CALL(*service_, SetState(Service::kStateAssociating));
1272a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  OnConnectionDisconnected();
1273a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  EXPECT_TRUE(IsConnectTimeoutStarted());
1274a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov}
1275a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov
1276a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin PetkovTEST_F(OpenVPNDriverTest, OnConnectTimeout) {
12770cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  StartConnectTimeout(0);
1278a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  SetService(service_);
12791c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(*service_, SetFailure(Service::kFailureConnect));
12801c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  OnConnectTimeout();
12811c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_FALSE(GetService());
12821c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_FALSE(IsConnectTimeoutStarted());
12831c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov}
12841c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov
12851c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin PetkovTEST_F(OpenVPNDriverTest, OnConnectTimeoutResolve) {
12861c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  StartConnectTimeout(0);
12871c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  SetService(service_);
12881c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  SetClientState(OpenVPNManagementServer::kStateResolve);
12891c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov  EXPECT_CALL(*service_, SetFailure(Service::kFailureDNSLookup));
1290a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  OnConnectTimeout();
1291a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  EXPECT_FALSE(GetService());
1292a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov  EXPECT_FALSE(IsConnectTimeoutStarted());
12935eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov}
12945eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov
12950cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin PetkovTEST_F(OpenVPNDriverTest, OnReconnectingUnknown) {
12960cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_FALSE(IsConnectTimeoutStarted());
12970cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_CALL(dispatcher_,
1298730164cbf080d9c31cd414632f22a52f43d6ef7eAlex Vakulenko              PostDelayedTask(_, GetDefaultConnectTimeoutSeconds() * 1000));
12990cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  SetDevice(device_);
13000cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  SetService(service_);
13019da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal  EXPECT_CALL(*device_, DropConnection());
1302271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov  EXPECT_CALL(*service_, SetState(Service::kStateAssociating));
13030cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonUnknown);
13040cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_TRUE(IsConnectTimeoutStarted());
13050cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov}
13060cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
13070cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin PetkovTEST_F(OpenVPNDriverTest, OnReconnectingTLSError) {
13080cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_CALL(dispatcher_,
1309730164cbf080d9c31cd414632f22a52f43d6ef7eAlex Vakulenko              PostDelayedTask(_, GetReconnectOfflineTimeoutSeconds() * 1000));
13100cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_CALL(dispatcher_,
1311730164cbf080d9c31cd414632f22a52f43d6ef7eAlex Vakulenko              PostDelayedTask(_, GetReconnectTLSErrorTimeoutSeconds() * 1000));
13120cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
13130cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonOffline);
13140cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_TRUE(IsConnectTimeoutStarted());
13150cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
13160cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  // The scheduled timeout should not be affected for unknown reason.
13170cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonUnknown);
13180cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_TRUE(IsConnectTimeoutStarted());
13190cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
13200cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  // Reconnect on TLS error reschedules the timeout once.
13210cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonTLSError);
13220cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_TRUE(IsConnectTimeoutStarted());
13230cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  driver_->OnReconnecting(OpenVPNDriver::kReconnectReasonTLSError);
13240cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_TRUE(IsConnectTimeoutStarted());
1325271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov}
1326271fe5247103d0b76c48796c6f10ba45c6db59c4Darin Petkov
1327d432539fc85363734b2c60290822054087b6c82bDarin PetkovTEST_F(OpenVPNDriverTest, InitPropertyStore) {
1328d432539fc85363734b2c60290822054087b6c82bDarin Petkov  // Sanity test property store initialization.
1329d432539fc85363734b2c60290822054087b6c82bDarin Petkov  PropertyStore store;
1330d432539fc85363734b2c60290822054087b6c82bDarin Petkov  driver_->InitPropertyStore(&store);
1331d432539fc85363734b2c60290822054087b6c82bDarin Petkov  const string kUser = "joe";
1332d432539fc85363734b2c60290822054087b6c82bDarin Petkov  Error error;
13337372878af066cc079ad88a7b004ca3f769952de2Ben Chan  EXPECT_TRUE(store.SetStringProperty(kOpenVPNUserProperty, kUser, &error));
1334d432539fc85363734b2c60290822054087b6c82bDarin Petkov  EXPECT_TRUE(error.IsSuccess());
13357372878af066cc079ad88a7b004ca3f769952de2Ben Chan  EXPECT_EQ(kUser, GetArgs()->LookupString(kOpenVPNUserProperty, ""));
1336b536a74030880f4a4df0ad3d6c1380b0602446c6Darin Petkov}
1337b536a74030880f4a4df0ad3d6c1380b0602446c6Darin Petkov
1338b57682315ba47f8c567b6673f5aa7b87f367a4edPaul StewartTEST_F(OpenVPNDriverTest, PassphraseRequired) {
1339b536a74030880f4a4df0ad3d6c1380b0602446c6Darin Petkov  PropertyStore store;
1340b536a74030880f4a4df0ad3d6c1380b0602446c6Darin Petkov  driver_->InitPropertyStore(&store);
1341b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  KeyValueStore props = GetProviderProperties(store);
1342b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  EXPECT_TRUE(props.LookupBool(kPassphraseRequiredProperty, false));
1343b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart
1344b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  SetArg(kOpenVPNPasswordProperty, "random-password");
1345b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  props = GetProviderProperties(store);
1346b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  EXPECT_FALSE(props.LookupBool(kPassphraseRequiredProperty, true));
1347b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  // This parameter should be write-only.
1348b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  EXPECT_FALSE(props.ContainsString(kOpenVPNPasswordProperty));
1349b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart
1350b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  SetArg(kOpenVPNPasswordProperty, "");
1351b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  props = GetProviderProperties(store);
1352b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  EXPECT_TRUE(props.LookupBool(kPassphraseRequiredProperty, false));
1353b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart
1354b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  SetArg(kOpenVPNTokenProperty, "random-token");
1355b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  props = GetProviderProperties(store);
1356b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  EXPECT_FALSE(props.LookupBool(kPassphraseRequiredProperty, true));
1357b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  // This parameter should be write-only.
1358b57682315ba47f8c567b6673f5aa7b87f367a4edPaul Stewart  EXPECT_FALSE(props.ContainsString(kOpenVPNTokenProperty));
1359d432539fc85363734b2c60290822054087b6c82bDarin Petkov}
1360d432539fc85363734b2c60290822054087b6c82bDarin Petkov
1361d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawalTEST_F(OpenVPNDriverTest, GetEnvironment) {
13621a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov  SetupLSBRelease();
1363d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal  const map<string, string> expected{
1364d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal    {"IV_PLAT", "Chromium OS"},
1365d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal    {"IV_PLAT_REL", "2202.0"}};
1366d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal  ASSERT_EQ(expected, driver_->GetEnvironment());
13671a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov
13686fbf64f493a9aae7d743888039c61a57386203dbBen Chan  EXPECT_EQ(0, base::WriteFile(lsb_release_file_, "", 0));
1369d485f65e984c523b53ae54258c8e861b9445ca6dmukesh agrawal  EXPECT_EQ(0, driver_->GetEnvironment().size());
13701a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov}
13711a462dedc54da1f6195ad74d1b7c1946563edab4Darin Petkov
1372609e2f164a71c1b757292c32e8465eaa8bd397cbmukesh agrawalTEST_F(OpenVPNDriverTest, OnOpenVPNExited) {
1373609e2f164a71c1b757292c32e8465eaa8bd397cbmukesh agrawal  const int kExitStatus = 1;
1374d5dce94ec196e160c0d4bfeeb5ab8d4eb021ef15Ben Chan  std::unique_ptr<MockDeviceInfo> device_info(
13755a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov      new MockDeviceInfo(&control_, &dispatcher_, &metrics_, &manager_));
13765a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  EXPECT_CALL(*device_info, DeleteInterface(kInterfaceIndex))
13775a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov      .WillOnce(Return(true));
13785a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  WeakPtr<DeviceInfo> weak = device_info->AsWeakPtr();
13795a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  EXPECT_TRUE(weak);
1380609e2f164a71c1b757292c32e8465eaa8bd397cbmukesh agrawal  OpenVPNDriver::OnOpenVPNExited(weak, kInterfaceIndex, kExitStatus);
13815a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  device_info.reset();
13825a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  EXPECT_FALSE(weak);
13835a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov  // Expect no crash.
1384609e2f164a71c1b757292c32e8465eaa8bd397cbmukesh agrawal  OpenVPNDriver::OnOpenVPNExited(weak, kInterfaceIndex, kExitStatus);
13855a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov}
13865a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkov
1387a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin PetkovTEST_F(OpenVPNDriverTest, OnDefaultServiceChanged) {
1388a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  driver_->service_ = service_;
1389a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
1390a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  ServiceRefPtr null_service;
1391a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(*management_server_, Hold());
1392a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  driver_->OnDefaultServiceChanged(null_service);
1393a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
1394a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(*management_server_, Hold());
1395a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  driver_->OnDefaultServiceChanged(service_);
1396a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
1397a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  scoped_refptr<MockService> mock_service(
1398a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov      new MockService(&control_, &dispatcher_, &metrics_, &manager_));
1399a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
1400a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(false));
1401a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(*management_server_, Hold());
1402a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  driver_->OnDefaultServiceChanged(mock_service);
1403a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
1404a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(*mock_service, IsConnected()).WillOnce(Return(true));
1405a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  EXPECT_CALL(*management_server_, ReleaseHold());
1406a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov  driver_->OnDefaultServiceChanged(mock_service);
1407a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov}
1408a5e07ef0402aad0635a5e7a0932740b9dfbf46d1Darin Petkov
14090cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin PetkovTEST_F(OpenVPNDriverTest, GetReconnectTimeoutSeconds) {
14100cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_EQ(GetDefaultConnectTimeoutSeconds(),
14110cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov            GetReconnectTimeoutSeconds(OpenVPNDriver::kReconnectReasonUnknown));
14120cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_EQ(GetReconnectOfflineTimeoutSeconds(),
14130cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov            GetReconnectTimeoutSeconds(OpenVPNDriver::kReconnectReasonOffline));
14140cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov  EXPECT_EQ(GetReconnectTLSErrorTimeoutSeconds(),
14150cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov            GetReconnectTimeoutSeconds(
14160cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov                OpenVPNDriver::kReconnectReasonTLSError));
14170cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov}
14180cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov
1419b26347a48e976a890210bb5fcc28892ac7df42e9Paul StewartTEST_F(OpenVPNDriverTest, WriteConfigFile) {
1420b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  const char kOption0[] = "option0";
1421b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  const char kOption1[] = "option1";
1422b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  const char kOption1Argument0[] = "option1-argument0";
1423b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  const char kOption2[] = "option2";
14247590d6f923dc9f3742a423bd0cdaa66271349747Paul Stewart  const char kOption2Argument0[] = "option2-argument0\n\t\"'\\";
14257590d6f923dc9f3742a423bd0cdaa66271349747Paul Stewart  const char kOption2Argument0Transformed[] = "option2-argument0 \t\\\"'\\\\";
14267590d6f923dc9f3742a423bd0cdaa66271349747Paul Stewart  const char kOption2Argument1[] = "option2-argument1 space";
1427b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  vector<vector<string>> options {
1428b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      { kOption0 },
1429b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      { kOption1, kOption1Argument0 },
1430b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      { kOption2, kOption2Argument0, kOption2Argument1 }
1431b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  };
1432b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  FilePath config_directory(
1433b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      temporary_directory_.path().Append(kOpenVPNConfigDirectory));
1434b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  FilePath config_file;
1435a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_FALSE(base::PathExists(config_directory));
1436b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  EXPECT_TRUE(driver_->WriteConfigFile(options, &config_file));
1437a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::PathExists(config_directory));
1438a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::PathExists(config_file));
1439a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(config_directory.IsParent(config_file));
1440b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart
1441b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  string config_contents;
1442a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  EXPECT_TRUE(base::ReadFileToString(config_file, &config_contents));
1443a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan  string expected_config_contents = base::StringPrintf(
14447590d6f923dc9f3742a423bd0cdaa66271349747Paul Stewart      "%s\n%s %s\n%s \"%s\" \"%s\"\n",
1445b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      kOption0,
1446b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart      kOption1, kOption1Argument0,
14477590d6f923dc9f3742a423bd0cdaa66271349747Paul Stewart      kOption2, kOption2Argument0Transformed, kOption2Argument1);
1448b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart  EXPECT_EQ(expected_config_contents, config_contents);
1449b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart}
1450b26347a48e976a890210bb5fcc28892ac7df42e9Paul Stewart
145133af05c849e0888b15222da38b55515784b821c7Darin Petkov}  // namespace shill
1452