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// 167476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 175bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// The term "L2TP / IPSec" refers to a pair of layered protocols used 185bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// together to establish a tunneled VPN connection. First, an "IPSec" 195bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// link is created, which secures a single IP traffic pair between the 205bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// client and server. For this link to complete, one or two levels of 215bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// authentication are performed. The first, inner mandatory authentication 225bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// ensures the two parties establishing the IPSec link are correct. This 235bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// can use a certificate exchange or a less secure "shared group key" 245bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// (PSK) authentication. An optional outer IPSec authentication can also be 255bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// performed, which is not fully supported by shill's implementation. 265bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// In order to support "tunnel groups" from some vendor VPNs shill supports 275bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// supplying the authentication realm portion during the outer authentication. 285bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// Notably, XAUTH and other forms of user authentication on this outer link 295bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// are not supported. 305bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// 315bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// When IPSec authentication completes, traffic is tunneled through a 325bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// layer 2 tunnel, called "L2TP". Using the secured link, we tunnel a 335bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// PPP link, through which a second layer of authentication is performed, 345bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart// using the provided "user" and "password" properties. 355bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart 362240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/l2tp_ipsec_driver.h" 377476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 386999022029507e90bc8a032b85e87ef83d2c4d1dDarin Petkov#include <base/bind.h> 3911c213f3cf64f27a0e42ee6da95e98bd1d4b3202Ben Chan#include <base/files/file_util.h> 40a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/string_util.h> 41fca1a04aac5f5817e9e681567716826821c9790dSteve Fung#include <base/strings/stringprintf.h> 42289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#if defined(__ANDROID__) 43289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#include <dbus/service_constants.h> 44289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#else 457476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov#include <chromeos/dbus/service_constants.h> 46289a5a5e18bb1a676b3dfce111af4c2c00c7776eSamuel Tan#endif // __ANDROID__ 47ef342b4400ad2338d3caf8f30ae06ba9f9fa4d77Liam McLoughlin#include <vpn-manager/service_error.h> 487476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 495baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart#include "shill/certificate_file.h" 50f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov#include "shill/device_info.h" 51f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov#include "shill/error.h" 52ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal#include "shill/external_task.h" 5334628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart#include "shill/ipconfig.h" 54b691efd71561246065eae3cdd73a96ca1b8a528dChristopher Wiley#include "shill/logging.h" 55f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov#include "shill/manager.h" 56cb832e8df5f61b223de86a9d4204c86f1e7d9c36Garret Kelly#include "shill/ppp_daemon.h" 579da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal#include "shill/ppp_device.h" 582e38263961190298d7198058ed91649dee106257mukesh agrawal#include "shill/ppp_device_factory.h" 59a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu#include "shill/process_manager.h" 602240e8c03451c6b6f21eb8944d8a1c0747ac10b3Ben Chan#include "shill/vpn/vpn_service.h" 61f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 626999022029507e90bc8a032b85e87ef83d2c4d1dDarin Petkovusing base::Bind; 635a850476dd0d049fa07e54015430c4d19d3d6ae8Darin Petkovusing base::Closure; 640e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulkusing base::FilePath; 65209e629754acc6807fd5deff888bf4521867f68dDarin Petkovusing std::map; 667476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkovusing std::string; 67f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovusing std::vector; 687476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 697476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkovnamespace shill { 707476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 71c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silbersteinnamespace Logging { 72c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silbersteinstatic auto kModuleLogScope = ScopeLogger::kVPN; 73e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartstatic string ObjectID(L2TPIPSecDriver* l) { 74c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein return l->GetServiceRpcIdentifier(); 75c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein} 76c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein} 77c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein 78f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovnamespace { 79f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovconst char kL2TPIPSecIPSecTimeoutProperty[] = "L2TPIPsec.IPsecTimeout"; 80f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovconst char kL2TPIPSecLeftProtoPortProperty[] = "L2TPIPsec.LeftProtoPort"; 81f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovconst char kL2TPIPSecLengthBitProperty[] = "L2TPIPsec.LengthBit"; 82f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovconst char kL2TPIPSecPFSProperty[] = "L2TPIPsec.PFS"; 83f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovconst char kL2TPIPSecRefusePapProperty[] = "L2TPIPsec.RefusePap"; 84f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovconst char kL2TPIPSecRekeyProperty[] = "L2TPIPsec.Rekey"; 85f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovconst char kL2TPIPSecRequireAuthProperty[] = "L2TPIPsec.RequireAuth"; 86f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovconst char kL2TPIPSecRequireChapProperty[] = "L2TPIPsec.RequireChap"; 87f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovconst char kL2TPIPSecRightProtoPortProperty[] = "L2TPIPsec.RightProtoPort"; 88f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov} // namespace 89f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 90f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov// static 91209e629754acc6807fd5deff888bf4521867f68dDarin Petkovconst char L2TPIPSecDriver::kL2TPIPSecVPNPath[] = "/usr/sbin/l2tpipsec_vpn"; 92d432539fc85363734b2c60290822054087b6c82bDarin Petkov// static 93d432539fc85363734b2c60290822054087b6c82bDarin Petkovconst VPNDriver::Property L2TPIPSecDriver::kProperties[] = { 947372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kL2tpIpsecAuthenticationType, 0 }, 957372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kL2tpIpsecCaCertNssProperty, 0 }, 967372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kL2tpIpsecClientCertIdProperty, 0 }, 977372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kL2tpIpsecClientCertSlotProperty, 0 }, 987372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kL2tpIpsecIkeVersion, 0 }, 997372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kL2tpIpsecPasswordProperty, Property::kCredential | Property::kWriteOnly }, 1007372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kL2tpIpsecPinProperty, Property::kCredential }, 101a7109d354b49f747a81bd9c87aa199336b7081d5Paul Stewart { kL2tpIpsecPskProperty, Property::kCredential | Property::kWriteOnly }, 1027372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kL2tpIpsecUserProperty, 0 }, 1037372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kProviderHostProperty, 0 }, 1047372878af066cc079ad88a7b004ca3f769952de2Ben Chan { kProviderTypeProperty, 0 }, 105eb713e8da9f6c97f3ac2218edef8d190ca4f99b0Paul Stewart { kL2tpIpsecCaCertPemProperty, Property::kArray }, 1065bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart { kL2tpIpsecTunnelGroupProperty, 0 }, 107d432539fc85363734b2c60290822054087b6c82bDarin Petkov { kL2TPIPSecIPSecTimeoutProperty, 0 }, 108d432539fc85363734b2c60290822054087b6c82bDarin Petkov { kL2TPIPSecLeftProtoPortProperty, 0 }, 109d432539fc85363734b2c60290822054087b6c82bDarin Petkov { kL2TPIPSecLengthBitProperty, 0 }, 110d432539fc85363734b2c60290822054087b6c82bDarin Petkov { kL2TPIPSecPFSProperty, 0 }, 111d432539fc85363734b2c60290822054087b6c82bDarin Petkov { kL2TPIPSecRefusePapProperty, 0 }, 112d432539fc85363734b2c60290822054087b6c82bDarin Petkov { kL2TPIPSecRekeyProperty, 0 }, 113d432539fc85363734b2c60290822054087b6c82bDarin Petkov { kL2TPIPSecRequireAuthProperty, 0 }, 114d432539fc85363734b2c60290822054087b6c82bDarin Petkov { kL2TPIPSecRequireChapProperty, 0 }, 115d432539fc85363734b2c60290822054087b6c82bDarin Petkov { kL2TPIPSecRightProtoPortProperty, 0 }, 116a7109d354b49f747a81bd9c87aa199336b7081d5Paul Stewart { kL2tpIpsecXauthUserProperty, Property::kCredential | Property::kWriteOnly }, 117a7109d354b49f747a81bd9c87aa199336b7081d5Paul Stewart { kL2tpIpsecXauthPasswordProperty, 118a7109d354b49f747a81bd9c87aa199336b7081d5Paul Stewart Property::kCredential | Property::kWriteOnly }, 119c062538b3440f566120e302aac70e527e1cf5b07Paul Stewart { kL2tpIpsecLcpEchoDisabledProperty, 0 }, 120d432539fc85363734b2c60290822054087b6c82bDarin Petkov}; 121f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 122e42d186ab3383b4a6bb267f490770af5932588b8Paul StewartL2TPIPSecDriver::L2TPIPSecDriver(ControlInterface* control, 123e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart EventDispatcher* dispatcher, 124e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart Metrics* metrics, 125e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart Manager* manager, 126e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart DeviceInfo* device_info, 127a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu ProcessManager* process_manager) 128602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov : VPNDriver(dispatcher, manager, kProperties, arraysize(kProperties)), 129b451d6e5b5deb3a42ac09c3db349f325e4c8004eDarin Petkov control_(control), 130f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov metrics_(metrics), 131f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov device_info_(device_info), 132a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu process_manager_(process_manager), 1332e38263961190298d7198058ed91649dee106257mukesh agrawal ppp_device_factory_(PPPDeviceFactory::GetInstance()), 134eb713e8da9f6c97f3ac2218edef8d190ca4f99b0Paul Stewart certificate_file_(new CertificateFile()), 135ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal weak_ptr_factory_(this) {} 1367476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 137209e629754acc6807fd5deff888bf4521867f68dDarin PetkovL2TPIPSecDriver::~L2TPIPSecDriver() { 13885d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov IdleService(); 139209e629754acc6807fd5deff888bf4521867f68dDarin Petkov} 1407476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 141c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silbersteinstd::string L2TPIPSecDriver::GetServiceRpcIdentifier() { 142c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein if (service_ == nullptr) 143c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein return "(l2tp_ipsec_driver)"; 144c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein return service_->GetRpcIdentifier(); 145c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein} 146c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein 147e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartbool L2TPIPSecDriver::ClaimInterface(const string& link_name, 1487476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov int interface_index) { 149ee6b3d7f9d49fa52072a352fbb59f06127b1ba4cPaul Stewart // TODO(petkov): crbug.com/212446. 1507476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov NOTIMPLEMENTED(); 1517476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov return false; 1527476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov} 1537476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 154e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartvoid L2TPIPSecDriver::Connect(const VPNServiceRefPtr& service, Error* error) { 1550cd0d1e07270b05016b29cd7c9d6f4c5440fb078Darin Petkov StartConnectTimeout(kDefaultConnectTimeoutSeconds); 156209e629754acc6807fd5deff888bf4521867f68dDarin Petkov service_ = service; 157209e629754acc6807fd5deff888bf4521867f68dDarin Petkov service_->SetState(Service::kStateConfiguring); 158209e629754acc6807fd5deff888bf4521867f68dDarin Petkov if (!SpawnL2TPIPSecVPN(error)) { 1591c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov FailService(Service::kFailureInternal); 160209e629754acc6807fd5deff888bf4521867f68dDarin Petkov } 1617476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov} 1627476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 1637476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkovvoid L2TPIPSecDriver::Disconnect() { 164c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 16585d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov IdleService(); 1667476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov} 1677476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 1685eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkovvoid L2TPIPSecDriver::OnConnectionDisconnected() { 169a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov LOG(INFO) << "Underlying connection disconnected."; 17085d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov IdleService(); 171a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov} 172a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov 173a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkovvoid L2TPIPSecDriver::OnConnectTimeout() { 174a42afe3a1621b8262d5404ecfaf200d3d76bd454Darin Petkov VPNDriver::OnConnectTimeout(); 17585d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov FailService(Service::kFailureConnect); 1765eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov} 1775eb0542cb67358d9030367498a4ad741fc42af4fDarin Petkov 1787476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkovstring L2TPIPSecDriver::GetProviderType() const { 1797372878af066cc079ad88a7b004ca3f769952de2Ben Chan return kProviderL2tpIpsec; 1807476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov} 1817476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov 18285d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkovvoid L2TPIPSecDriver::IdleService() { 18385d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov Cleanup(Service::kStateIdle, Service::kFailureUnknown); 18485d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov} 18585d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov 18685d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkovvoid L2TPIPSecDriver::FailService(Service::ConnectFailure failure) { 18785d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov Cleanup(Service::kStateFailure, failure); 18885d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov} 18985d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov 19085d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkovvoid L2TPIPSecDriver::Cleanup(Service::ConnectState state, 19185d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov Service::ConnectFailure failure) { 192c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__ << "(" 193c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << Service::ConnectStateToString(state) << ", " 194c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein << Service::ConnectFailureToString(failure) << ")"; 195602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov StopConnectTimeout(); 1963f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart DeleteTemporaryFiles(); 197ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal external_task_.reset(); 198f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov if (device_) { 1999da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal device_->DropConnection(); 200f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov device_->SetEnabled(false); 2014168b2c8d57755ea6b16763745379e0529541a3fBen Chan device_ = nullptr; 202f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov } 203209e629754acc6807fd5deff888bf4521867f68dDarin Petkov if (service_) { 20485d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov if (state == Service::kStateFailure) { 20585d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov service_->SetFailure(failure); 20685d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov } else { 20785d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov service_->SetState(state); 20885d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov } 2094168b2c8d57755ea6b16763745379e0529541a3fBen Chan service_ = nullptr; 210209e629754acc6807fd5deff888bf4521867f68dDarin Petkov } 211209e629754acc6807fd5deff888bf4521867f68dDarin Petkov} 212209e629754acc6807fd5deff888bf4521867f68dDarin Petkov 213e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartvoid L2TPIPSecDriver::DeleteTemporaryFile(base::FilePath* temporary_file) { 2143f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart if (!temporary_file->empty()) { 215a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan base::DeleteFile(*temporary_file, false); 2163f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart temporary_file->clear(); 2170e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov } 2180e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov} 2190e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov 2203f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewartvoid L2TPIPSecDriver::DeleteTemporaryFiles() { 2213f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart DeleteTemporaryFile(&psk_file_); 2223f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart DeleteTemporaryFile(&xauth_credentials_file_); 2233f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart} 2243f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart 225e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartbool L2TPIPSecDriver::SpawnL2TPIPSecVPN(Error* error) { 226c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 227d5dce94ec196e160c0d4bfeeb5ab8d4eb021ef15Ben Chan std::unique_ptr<ExternalTask> external_task_local( 228a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu new ExternalTask(control_, 229a24480aaca4d392d6d08cebdc508ee49615839d3Peter Qiu process_manager_, 230ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal weak_ptr_factory_.GetWeakPtr(), 231ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal Bind(&L2TPIPSecDriver::OnL2TPIPSecVPNDied, 232ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal weak_ptr_factory_.GetWeakPtr()))); 233209e629754acc6807fd5deff888bf4521867f68dDarin Petkov 234209e629754acc6807fd5deff888bf4521867f68dDarin Petkov vector<string> options; 235ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal map<string, string> environment; // No env vars passed. 236209e629754acc6807fd5deff888bf4521867f68dDarin Petkov if (!InitOptions(&options, error)) { 237209e629754acc6807fd5deff888bf4521867f68dDarin Petkov return false; 238209e629754acc6807fd5deff888bf4521867f68dDarin Petkov } 2393a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenko LOG(INFO) << "L2TP/IPSec VPN process options: " 2403a62e235646ec19bee71e8dbee5208282dcd13b5Alex Vakulenko << base::JoinString(options, " "); 241209e629754acc6807fd5deff888bf4521867f68dDarin Petkov 242ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal if (external_task_local->Start( 243c4f9aa0e795b6f79c628a763831d4dc6c01fb72bmukesh agrawal FilePath(kL2TPIPSecVPNPath), options, environment, true, error)) { 244d5dce94ec196e160c0d4bfeeb5ab8d4eb021ef15Ben Chan external_task_ = std::move(external_task_local); 245ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal return true; 246209e629754acc6807fd5deff888bf4521867f68dDarin Petkov } 247ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal return false; 248f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov} 249f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 250e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartbool L2TPIPSecDriver::InitOptions(vector<string>* options, Error* error) { 2517372878af066cc079ad88a7b004ca3f769952de2Ben Chan string vpnhost = args()->LookupString(kProviderHostProperty, ""); 252f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov if (vpnhost.empty()) { 253f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov Error::PopulateAndLog( 25434f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart FROM_HERE, error, Error::kInvalidArguments, "VPN host not specified."); 255209e629754acc6807fd5deff888bf4521867f68dDarin Petkov return false; 256f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov } 257f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 258f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov if (!InitPSKOptions(options, error)) { 259209e629754acc6807fd5deff888bf4521867f68dDarin Petkov return false; 260f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov } 261f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 2623f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart if (!InitXauthOptions(options, error)) { 2633f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart return false; 2643f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart } 2653f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart 266fca1a04aac5f5817e9e681567716826821c9790dSteve Fung options->push_back(base::StringPrintf("--remote_host=%s", vpnhost.c_str())); 267fca1a04aac5f5817e9e681567716826821c9790dSteve Fung options->push_back(base::StringPrintf("--pppd_plugin=%s", 2681e8414cbca190baa946388ede87a0b417c1f3d95Garret Kelly PPPDaemon::kShimPluginPath)); 269f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov // Disable pppd from configuring IP addresses, routes, DNS. 270f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov options->push_back("--nosystemconfig"); 271f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 272c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart // Accept a PEM CA certificate. 273c350e68360d08626cff8c4020c743b61d7da5a2bPaul Stewart InitPEMOptions(options); 274f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 2757372878af066cc079ad88a7b004ca3f769952de2Ben Chan AppendValueOption(kL2tpIpsecClientCertIdProperty, 276f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov "--client_cert_id", options); 2777372878af066cc079ad88a7b004ca3f769952de2Ben Chan AppendValueOption(kL2tpIpsecClientCertSlotProperty, 278f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov "--client_cert_slot", options); 2797372878af066cc079ad88a7b004ca3f769952de2Ben Chan AppendValueOption(kL2tpIpsecPinProperty, "--user_pin", options); 2807372878af066cc079ad88a7b004ca3f769952de2Ben Chan AppendValueOption(kL2tpIpsecUserProperty, "--user", options); 281f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov AppendValueOption(kL2TPIPSecIPSecTimeoutProperty, "--ipsec_timeout", options); 282f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov AppendValueOption(kL2TPIPSecLeftProtoPortProperty, 283f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov "--leftprotoport", options); 284f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov AppendFlag(kL2TPIPSecPFSProperty, "--pfs", "--nopfs", options); 285f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov AppendFlag(kL2TPIPSecRekeyProperty, "--rekey", "--norekey", options); 286f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov AppendValueOption(kL2TPIPSecRightProtoPortProperty, 287f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov "--rightprotoport", options); 288f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov AppendFlag(kL2TPIPSecRequireChapProperty, 289f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov "--require_chap", "--norequire_chap", options); 290f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov AppendFlag(kL2TPIPSecRefusePapProperty, 291f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov "--refuse_pap", "--norefuse_pap", options); 292f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov AppendFlag(kL2TPIPSecRequireAuthProperty, 293f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov "--require_authentication", "--norequire_authentication", options); 294f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov AppendFlag(kL2TPIPSecLengthBitProperty, 295f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov "--length_bit", "--nolength_bit", options); 296c062538b3440f566120e302aac70e527e1cf5b07Paul Stewart AppendFlag(kL2tpIpsecLcpEchoDisabledProperty, 297c062538b3440f566120e302aac70e527e1cf5b07Paul Stewart "--noppp_lcp_echo", "--ppp_lcp_echo", options); 2985bbf93bb7049fa216983763cae3b51e552edd36dPaul Stewart AppendValueOption(kL2tpIpsecTunnelGroupProperty, "--tunnel_group", options); 299209e629754acc6807fd5deff888bf4521867f68dDarin Petkov if (SLOG_IS_ON(VPN, 0)) { 300209e629754acc6807fd5deff888bf4521867f68dDarin Petkov options->push_back("--debug"); 301209e629754acc6807fd5deff888bf4521867f68dDarin Petkov } 302209e629754acc6807fd5deff888bf4521867f68dDarin Petkov return true; 303f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov} 304f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 305e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartbool L2TPIPSecDriver::InitPSKOptions(vector<string>* options, Error* error) { 3067372878af066cc079ad88a7b004ca3f769952de2Ben Chan string psk = args()->LookupString(kL2tpIpsecPskProperty, ""); 307f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov if (!psk.empty()) { 308a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan if (!base::CreateTemporaryFileInDir(manager()->run_path(), &psk_file_) || 309f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov chmod(psk_file_.value().c_str(), S_IRUSR | S_IWUSR) || 3106fbf64f493a9aae7d743888039c61a57386203dbBen Chan base::WriteFile(psk_file_, psk.data(), psk.size()) != 311a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan static_cast<int>(psk.size())) { 312f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov Error::PopulateAndLog( 31334f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart FROM_HERE, error, Error::kInternalError, "Unable to setup psk file."); 314f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov return false; 315f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov } 316fca1a04aac5f5817e9e681567716826821c9790dSteve Fung options->push_back(base::StringPrintf("--psk_file=%s", 317fca1a04aac5f5817e9e681567716826821c9790dSteve Fung psk_file_.value().c_str())); 318f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov } 319f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov return true; 320f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov} 321f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 322e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartbool L2TPIPSecDriver::InitPEMOptions(vector<string>* options) { 323eb713e8da9f6c97f3ac2218edef8d190ca4f99b0Paul Stewart vector<string> ca_certs; 324eb713e8da9f6c97f3ac2218edef8d190ca4f99b0Paul Stewart if (args()->ContainsStrings(kL2tpIpsecCaCertPemProperty)) { 325eb713e8da9f6c97f3ac2218edef8d190ca4f99b0Paul Stewart ca_certs = args()->GetStrings(kL2tpIpsecCaCertPemProperty); 326eb713e8da9f6c97f3ac2218edef8d190ca4f99b0Paul Stewart } 327eb713e8da9f6c97f3ac2218edef8d190ca4f99b0Paul Stewart if (ca_certs.empty()) { 3285baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart return false; 3295baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart } 330eb713e8da9f6c97f3ac2218edef8d190ca4f99b0Paul Stewart FilePath certfile = certificate_file_->CreatePEMFromStrings(ca_certs); 3315baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart if (certfile.empty()) { 332eb713e8da9f6c97f3ac2218edef8d190ca4f99b0Paul Stewart LOG(ERROR) << "Unable to extract certificates from PEM string."; 3335baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart return false; 3345baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart } 335fca1a04aac5f5817e9e681567716826821c9790dSteve Fung options->push_back(base::StringPrintf("--server_ca_file=%s", 336fca1a04aac5f5817e9e681567716826821c9790dSteve Fung certfile.value().c_str())); 3375baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart return true; 3385baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart} 3395baebb73bd597f5896b43d38e8ed3447680f47f4Paul Stewart 340e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartbool L2TPIPSecDriver::InitXauthOptions(vector<string>* options, Error* error) { 3413f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart string user = args()->LookupString(kL2tpIpsecXauthUserProperty, ""); 3423f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart string password = args()->LookupString(kL2tpIpsecXauthPasswordProperty, ""); 3433f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart if (user.empty() && password.empty()) { 3443f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart // Xauth credentials not configured. 3453f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart return true; 3463f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart } 3473f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart if (user.empty() || password.empty()) { 3483f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart Error::PopulateAndLog( 34934f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart FROM_HERE, error, Error::kInvalidArguments, 3503f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart "XAUTH credentials are partially configured."); 3513f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart return false; 3523f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart } 3533f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart string xauth_credentials = user + "\n" + password + "\n"; 354a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan if (!base::CreateTemporaryFileInDir(manager()->run_path(), 355a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan &xauth_credentials_file_) || 3563f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart chmod(xauth_credentials_file_.value().c_str(), S_IRUSR | S_IWUSR) || 3576fbf64f493a9aae7d743888039c61a57386203dbBen Chan base::WriteFile(xauth_credentials_file_, xauth_credentials.data(), 3586fbf64f493a9aae7d743888039c61a57386203dbBen Chan xauth_credentials.size()) != 3593f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart static_cast<int>(xauth_credentials.size())) { 3603f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart Error::PopulateAndLog( 36134f424e672439bdf237a755f85245ebd7b66e8e2Paul Stewart FROM_HERE, error, Error::kInternalError, 3623f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart "Unable to setup XAUTH credentials file."); 3633f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart return false; 3643f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart } 365fca1a04aac5f5817e9e681567716826821c9790dSteve Fung options->push_back(base::StringPrintf("--xauth_credentials_file=%s", 366fca1a04aac5f5817e9e681567716826821c9790dSteve Fung xauth_credentials_file_.value().c_str())); 3673f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart return true; 3683f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart} 3693f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart 370f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkovbool L2TPIPSecDriver::AppendValueOption( 371e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart const string& property, const string& option, vector<string>* options) { 37201c6604021f3a47813c3dc98d3a5c3d1d45b5bccDarin Petkov string value = args()->LookupString(property, ""); 373f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov if (!value.empty()) { 374fca1a04aac5f5817e9e681567716826821c9790dSteve Fung options->push_back(base::StringPrintf("%s=%s", option.c_str(), 375fca1a04aac5f5817e9e681567716826821c9790dSteve Fung value.c_str())); 376f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov return true; 377f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov } 378f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov return false; 379f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov} 380f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 381e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartbool L2TPIPSecDriver::AppendFlag(const string& property, 382e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart const string& true_option, 383e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart const string& false_option, 384e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart vector<string>* options) { 38501c6604021f3a47813c3dc98d3a5c3d1d45b5bccDarin Petkov string value = args()->LookupString(property, ""); 386f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov if (!value.empty()) { 387f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov options->push_back(value == "true" ? true_option : false_option); 388f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov return true; 389f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov } 390f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov return false; 391f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov} 392f7ef50a6054414c446f891fa87401e6f0a00097fDarin Petkov 393ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawalvoid L2TPIPSecDriver::OnL2TPIPSecVPNDied(pid_t /*pid*/, int status) { 394ae30e9e4f9050a5a2c3b18d20f8bd23f20aa8f38mukesh agrawal FailService(TranslateExitStatusToFailure(status)); 395209e629754acc6807fd5deff888bf4521867f68dDarin Petkov // TODO(petkov): Figure if we need to restart the connection. 396209e629754acc6807fd5deff888bf4521867f68dDarin Petkov} 397209e629754acc6807fd5deff888bf4521867f68dDarin Petkov 39885d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov// static 39985d5317bed668c1fb0e4225de614c7b386e3de25Darin PetkovService::ConnectFailure L2TPIPSecDriver::TranslateExitStatusToFailure( 40085d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov int status) { 40185d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov if (!WIFEXITED(status)) { 4021c049c794175356e5b6c2b6bbb5ef4a12fbfe9a3Darin Petkov return Service::kFailureInternal; 40385d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov } 40485d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov switch (WEXITSTATUS(status)) { 40585d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov case vpn_manager::kServiceErrorResolveHostnameFailed: 40685d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov return Service::kFailureDNSLookup; 40785d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov case vpn_manager::kServiceErrorIpsecConnectionFailed: 40885d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov case vpn_manager::kServiceErrorL2tpConnectionFailed: 40985d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov case vpn_manager::kServiceErrorPppConnectionFailed: 41085d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov return Service::kFailureConnect; 41185d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov case vpn_manager::kServiceErrorIpsecPresharedKeyAuthenticationFailed: 41285d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov return Service::kFailureIPSecPSKAuth; 41385d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov case vpn_manager::kServiceErrorIpsecCertificateAuthenticationFailed: 41485d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov return Service::kFailureIPSecCertAuth; 41585d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov case vpn_manager::kServiceErrorPppAuthenticationFailed: 41685d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov return Service::kFailurePPPAuth; 41785d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov default: 41885d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov break; 41985d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov } 42085d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov return Service::kFailureUnknown; 42185d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov} 42285d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov 423e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewartvoid L2TPIPSecDriver::GetLogin(string* user, string* password) { 424602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov LOG(INFO) << "Login requested."; 425209e629754acc6807fd5deff888bf4521867f68dDarin Petkov string user_property = 4267372878af066cc079ad88a7b004ca3f769952de2Ben Chan args()->LookupString(kL2tpIpsecUserProperty, ""); 427209e629754acc6807fd5deff888bf4521867f68dDarin Petkov if (user_property.empty()) { 428209e629754acc6807fd5deff888bf4521867f68dDarin Petkov LOG(ERROR) << "User not set."; 429209e629754acc6807fd5deff888bf4521867f68dDarin Petkov return; 430209e629754acc6807fd5deff888bf4521867f68dDarin Petkov } 431209e629754acc6807fd5deff888bf4521867f68dDarin Petkov string password_property = 4327372878af066cc079ad88a7b004ca3f769952de2Ben Chan args()->LookupString(kL2tpIpsecPasswordProperty, ""); 433209e629754acc6807fd5deff888bf4521867f68dDarin Petkov if (password_property.empty()) { 434209e629754acc6807fd5deff888bf4521867f68dDarin Petkov LOG(ERROR) << "Password not set."; 435209e629754acc6807fd5deff888bf4521867f68dDarin Petkov return; 436209e629754acc6807fd5deff888bf4521867f68dDarin Petkov } 437209e629754acc6807fd5deff888bf4521867f68dDarin Petkov *user = user_property; 438209e629754acc6807fd5deff888bf4521867f68dDarin Petkov *password = password_property; 439209e629754acc6807fd5deff888bf4521867f68dDarin Petkov} 440209e629754acc6807fd5deff888bf4521867f68dDarin Petkov 441209e629754acc6807fd5deff888bf4521867f68dDarin Petkovvoid L2TPIPSecDriver::Notify( 442e42d186ab3383b4a6bb267f490770af5932588b8Paul Stewart const string& reason, const map<string, string>& dict) { 443602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov LOG(INFO) << "IP configuration received: " << reason; 4440e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov 44516de98cbcfdf89e9ee6c9fe29a0f46341ecfb9a4Paul Stewart if (reason == kPPPReasonAuthenticating || 44616de98cbcfdf89e9ee6c9fe29a0f46341ecfb9a4Paul Stewart reason == kPPPReasonAuthenticated) { 44716de98cbcfdf89e9ee6c9fe29a0f46341ecfb9a4Paul Stewart // These are uninteresting intermediate states that do not indicate failure. 44816de98cbcfdf89e9ee6c9fe29a0f46341ecfb9a4Paul Stewart return; 44916de98cbcfdf89e9ee6c9fe29a0f46341ecfb9a4Paul Stewart } 45016de98cbcfdf89e9ee6c9fe29a0f46341ecfb9a4Paul Stewart 4519da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal if (reason != kPPPReasonConnect) { 4529da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal DCHECK_EQ(kPPPReasonDisconnect, reason); 4539da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal // DestroyLater, rather than while on stack. 4549da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal external_task_.release()->DestroyLater(dispatcher()); 45585d5317bed668c1fb0e4225de614c7b386e3de25Darin Petkov FailService(Service::kFailureUnknown); 4560e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov return; 4570e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov } 4580e9735db6db73a48c4b0cc3151a5272e3a8b9d2fDarin Petkov 4593f71326c17aa63e13343d06cbdc8ee0a2cbac3d7Paul Stewart DeleteTemporaryFiles(); 460f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov 4619da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal string interface_name = PPPDevice::GetInterfaceName(dict); 462f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov int interface_index = device_info_->GetIndex(interface_name); 463f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov if (interface_index < 0) { 464f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov // TODO(petkov): Consider handling the race when the RTNL notification about 465f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov // the new PPP device has not been received yet. We can keep the IP 466f8f970a33a751ccdbe6d058879aade2b0a9ad2cdDarin Petkov // configuration and apply it when ClaimInterface is 467ee6b3d7f9d49fa52072a352fbb59f06127b1ba4cPaul Stewart // invoked. crbug.com/212446. 468f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov NOTIMPLEMENTED() << ": No device info for " << interface_name << "."; 469f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov return; 470f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov } 471f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov 4729da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal // There is no IPv6 support for L2TP/IPsec VPN at this moment, so create a 4739da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal // blackhole route for IPv6 traffic after establishing a IPv4 VPN. 4749da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal // TODO(benchan): Generalize this when IPv6 support is added. 4759da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal bool blackhole_ipv6 = true; 4769da07771df3dbbc99ff99114c26317d01f29f7fcmukesh agrawal 477f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov if (!device_) { 4782e38263961190298d7198058ed91649dee106257mukesh agrawal device_ = ppp_device_factory_->CreatePPPDevice( 4792e38263961190298d7198058ed91649dee106257mukesh agrawal control_, dispatcher(), metrics_, manager(), interface_name, 4802e38263961190298d7198058ed91649dee106257mukesh agrawal interface_index); 481f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov } 482f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov device_->SetEnabled(true); 483f8046b8f975417255baf5cc7cdd025c63aa2f918Darin Petkov device_->SelectService(service_); 48434628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart 48534628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart // Reduce MTU to the minimum viable for IPv6, since the IPSec layer consumes 48634628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart // some variable portion of the payload. Although this system does not yet 48734628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart // support IPv6, it is a reasonable value to start with, since the minimum 48834628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart // IPv6 packet size will plausibly be a size any gateway would support, and 48934628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart // is also larger than the IPv4 minimum size. 49034628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart device_->UpdateIPConfigFromPPPWithMTU( 49134628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart dict, blackhole_ipv6, IPConfig::kMinIPv6MTU); 49234628593c4c51e8f1d393d6a03e3ebf06e4d9979Paul Stewart 49391a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart ReportConnectionMetrics(); 494602303fdc8e4a50c8f89bc7e1048a4b5438555bfDarin Petkov StopConnectTimeout(); 495209e629754acc6807fd5deff888bf4521867f68dDarin Petkov} 496209e629754acc6807fd5deff888bf4521867f68dDarin Petkov 497ba8f141693168a9613b1f86de0d6bf6ae4057e9cPaul Stewartbool L2TPIPSecDriver::IsPskRequired() const { 498ba8f141693168a9613b1f86de0d6bf6ae4057e9cPaul Stewart return 499ba8f141693168a9613b1f86de0d6bf6ae4057e9cPaul Stewart const_args()->LookupString(kL2tpIpsecPskProperty, "").empty() && 500ba8f141693168a9613b1f86de0d6bf6ae4057e9cPaul Stewart const_args()->LookupString(kL2tpIpsecClientCertIdProperty, "").empty(); 501ba8f141693168a9613b1f86de0d6bf6ae4057e9cPaul Stewart} 502ba8f141693168a9613b1f86de0d6bf6ae4057e9cPaul Stewart 503e42d186ab3383b4a6bb267f490770af5932588b8Paul StewartKeyValueStore L2TPIPSecDriver::GetProvider(Error* error) { 504c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein SLOG(this, 2) << __func__; 505b536a74030880f4a4df0ad3d6c1380b0602446c6Darin Petkov KeyValueStore props = VPNDriver::GetProvider(error); 5067372878af066cc079ad88a7b004ca3f769952de2Ben Chan props.SetBool(kPassphraseRequiredProperty, 5077372878af066cc079ad88a7b004ca3f769952de2Ben Chan args()->LookupString(kL2tpIpsecPasswordProperty, "").empty()); 508ba8f141693168a9613b1f86de0d6bf6ae4057e9cPaul Stewart props.SetBool(kL2tpIpsecPskRequiredProperty, IsPskRequired()); 509b536a74030880f4a4df0ad3d6c1380b0602446c6Darin Petkov return props; 510b536a74030880f4a4df0ad3d6c1380b0602446c6Darin Petkov} 511b536a74030880f4a4df0ad3d6c1380b0602446c6Darin Petkov 51291a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewartvoid L2TPIPSecDriver::ReportConnectionMetrics() { 51391a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart metrics_->SendEnumToUMA( 51491a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnDriver, 51591a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kVpnDriverL2tpIpsec, 51691a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnDriverMax); 51791a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart 51891a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart // We output an enum for each of the authentication types specified, 51991a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart // even if more than one is set at the same time. 52091a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart bool has_remote_authentication = false; 5217372878af066cc079ad88a7b004ca3f769952de2Ben Chan if (args()->LookupString(kL2tpIpsecPskProperty, "") != "") { 52291a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart metrics_->SendEnumToUMA( 52391a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnRemoteAuthenticationType, 52491a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kVpnRemoteAuthenticationTypeL2tpIpsecPsk, 52591a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnRemoteAuthenticationTypeMax); 52691a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart has_remote_authentication = true; 52791a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart } 52891a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart if (!has_remote_authentication) { 52991a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart metrics_->SendEnumToUMA( 53091a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnRemoteAuthenticationType, 53191a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kVpnRemoteAuthenticationTypeL2tpIpsecDefault, 53291a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnRemoteAuthenticationTypeMax); 53391a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart } 53491a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart 53591a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart bool has_user_authentication = false; 5367372878af066cc079ad88a7b004ca3f769952de2Ben Chan if (args()->LookupString(kL2tpIpsecClientCertIdProperty, 537e8e71da2bb8487f2ae78fbe38dc6e01cdc5ad1c9Paul Stewart "") != "") { 53891a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart metrics_->SendEnumToUMA( 53991a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnUserAuthenticationType, 54091a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kVpnUserAuthenticationTypeL2tpIpsecCertificate, 54191a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnUserAuthenticationTypeMax); 54291a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart has_user_authentication = true; 54391a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart } 5447372878af066cc079ad88a7b004ca3f769952de2Ben Chan if (args()->LookupString(kL2tpIpsecPasswordProperty, "") != "") { 54591a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart metrics_->SendEnumToUMA( 54691a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnUserAuthenticationType, 54791a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kVpnUserAuthenticationTypeL2tpIpsecUsernamePassword, 54891a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnUserAuthenticationTypeMax); 54991a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart has_user_authentication = true; 55091a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart } 55191a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart if (!has_user_authentication) { 55291a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart metrics_->SendEnumToUMA( 55391a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnUserAuthenticationType, 55491a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kVpnUserAuthenticationTypeL2tpIpsecNone, 55591a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart Metrics::kMetricVpnUserAuthenticationTypeMax); 55691a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart } 55791a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart} 55891a43cb5ddb565ed9e4abcaee2d5f9373250012aPaul Stewart 5597476a26345c7b36be98c1e14b5d54d00d823ce07Darin Petkov} // namespace shill 560