1//
2// Copyright (C) 2012 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17// The term "L2TP / IPSec" refers to a pair of layered protocols used
18// together to establish a tunneled VPN connection.  First, an "IPSec"
19// link is created, which secures a single IP traffic pair between the
20// client and server.  For this link to complete, one or two levels of
21// authentication are performed.  The first, inner mandatory authentication
22// ensures the two parties establishing the IPSec link are correct.  This
23// can use a certificate exchange or a less secure "shared group key"
24// (PSK) authentication.  An optional outer IPSec authentication can also be
25// performed, which is not fully supported by shill's implementation.
26// In order to support "tunnel groups" from some vendor VPNs shill supports
27// supplying the authentication realm portion during the outer authentication.
28// Notably, XAUTH and other forms of user authentication on this outer link
29// are not supported.
30//
31// When IPSec authentication completes, traffic is tunneled through a
32// layer 2 tunnel, called "L2TP".  Using the secured link, we tunnel a
33// PPP link, through which a second layer of authentication is performed,
34// using the provided "user" and "password" properties.
35
36#include "shill/vpn/l2tp_ipsec_driver.h"
37
38#include <base/bind.h>
39#include <base/files/file_util.h>
40#include <base/strings/string_util.h>
41#include <base/strings/stringprintf.h>
42#if defined(__ANDROID__)
43#include <dbus/service_constants.h>
44#else
45#include <chromeos/dbus/service_constants.h>
46#endif  // __ANDROID__
47#include <vpn-manager/service_error.h>
48
49#include "shill/certificate_file.h"
50#include "shill/device_info.h"
51#include "shill/error.h"
52#include "shill/external_task.h"
53#include "shill/ipconfig.h"
54#include "shill/logging.h"
55#include "shill/manager.h"
56#include "shill/ppp_daemon.h"
57#include "shill/ppp_device.h"
58#include "shill/ppp_device_factory.h"
59#include "shill/process_manager.h"
60#include "shill/vpn/vpn_service.h"
61
62using base::Bind;
63using base::Closure;
64using base::FilePath;
65using std::map;
66using std::string;
67using std::vector;
68
69namespace shill {
70
71namespace Logging {
72static auto kModuleLogScope = ScopeLogger::kVPN;
73static string ObjectID(L2TPIPSecDriver* l) {
74  return l->GetServiceRpcIdentifier();
75}
76}
77
78namespace {
79const char kL2TPIPSecIPSecTimeoutProperty[] = "L2TPIPsec.IPsecTimeout";
80const char kL2TPIPSecLeftProtoPortProperty[] = "L2TPIPsec.LeftProtoPort";
81const char kL2TPIPSecLengthBitProperty[] = "L2TPIPsec.LengthBit";
82const char kL2TPIPSecPFSProperty[] = "L2TPIPsec.PFS";
83const char kL2TPIPSecRefusePapProperty[] = "L2TPIPsec.RefusePap";
84const char kL2TPIPSecRekeyProperty[] = "L2TPIPsec.Rekey";
85const char kL2TPIPSecRequireAuthProperty[] = "L2TPIPsec.RequireAuth";
86const char kL2TPIPSecRequireChapProperty[] = "L2TPIPsec.RequireChap";
87const char kL2TPIPSecRightProtoPortProperty[] = "L2TPIPsec.RightProtoPort";
88}  // namespace
89
90// static
91const char L2TPIPSecDriver::kL2TPIPSecVPNPath[] = "/usr/sbin/l2tpipsec_vpn";
92// static
93const VPNDriver::Property L2TPIPSecDriver::kProperties[] = {
94  { kL2tpIpsecAuthenticationType, 0 },
95  { kL2tpIpsecCaCertNssProperty, 0 },
96  { kL2tpIpsecClientCertIdProperty, 0 },
97  { kL2tpIpsecClientCertSlotProperty, 0 },
98  { kL2tpIpsecIkeVersion, 0 },
99  { kL2tpIpsecPasswordProperty, Property::kCredential | Property::kWriteOnly },
100  { kL2tpIpsecPinProperty, Property::kCredential },
101  { kL2tpIpsecPskProperty, Property::kCredential | Property::kWriteOnly },
102  { kL2tpIpsecUserProperty, 0 },
103  { kProviderHostProperty, 0 },
104  { kProviderTypeProperty, 0 },
105  { kL2tpIpsecCaCertPemProperty, Property::kArray },
106  { kL2tpIpsecTunnelGroupProperty, 0 },
107  { kL2TPIPSecIPSecTimeoutProperty, 0 },
108  { kL2TPIPSecLeftProtoPortProperty, 0 },
109  { kL2TPIPSecLengthBitProperty, 0 },
110  { kL2TPIPSecPFSProperty, 0 },
111  { kL2TPIPSecRefusePapProperty, 0 },
112  { kL2TPIPSecRekeyProperty, 0 },
113  { kL2TPIPSecRequireAuthProperty, 0 },
114  { kL2TPIPSecRequireChapProperty, 0 },
115  { kL2TPIPSecRightProtoPortProperty, 0 },
116  { kL2tpIpsecXauthUserProperty, Property::kCredential | Property::kWriteOnly },
117  { kL2tpIpsecXauthPasswordProperty,
118    Property::kCredential | Property::kWriteOnly },
119  { kL2tpIpsecLcpEchoDisabledProperty, 0 },
120};
121
122L2TPIPSecDriver::L2TPIPSecDriver(ControlInterface* control,
123                                 EventDispatcher* dispatcher,
124                                 Metrics* metrics,
125                                 Manager* manager,
126                                 DeviceInfo* device_info,
127                                 ProcessManager* process_manager)
128    : VPNDriver(dispatcher, manager, kProperties, arraysize(kProperties)),
129      control_(control),
130      metrics_(metrics),
131      device_info_(device_info),
132      process_manager_(process_manager),
133      ppp_device_factory_(PPPDeviceFactory::GetInstance()),
134      certificate_file_(new CertificateFile()),
135      weak_ptr_factory_(this) {}
136
137L2TPIPSecDriver::~L2TPIPSecDriver() {
138  IdleService();
139}
140
141std::string L2TPIPSecDriver::GetServiceRpcIdentifier() {
142  if (service_ == nullptr)
143    return "(l2tp_ipsec_driver)";
144  return service_->GetRpcIdentifier();
145}
146
147bool L2TPIPSecDriver::ClaimInterface(const string& link_name,
148                                     int interface_index) {
149  // TODO(petkov): crbug.com/212446.
150  NOTIMPLEMENTED();
151  return false;
152}
153
154void L2TPIPSecDriver::Connect(const VPNServiceRefPtr& service, Error* error) {
155  StartConnectTimeout(kDefaultConnectTimeoutSeconds);
156  service_ = service;
157  service_->SetState(Service::kStateConfiguring);
158  if (!SpawnL2TPIPSecVPN(error)) {
159    FailService(Service::kFailureInternal);
160  }
161}
162
163void L2TPIPSecDriver::Disconnect() {
164  SLOG(this, 2) << __func__;
165  IdleService();
166}
167
168void L2TPIPSecDriver::OnConnectionDisconnected() {
169  LOG(INFO) << "Underlying connection disconnected.";
170  IdleService();
171}
172
173void L2TPIPSecDriver::OnConnectTimeout() {
174  VPNDriver::OnConnectTimeout();
175  FailService(Service::kFailureConnect);
176}
177
178string L2TPIPSecDriver::GetProviderType() const {
179  return kProviderL2tpIpsec;
180}
181
182void L2TPIPSecDriver::IdleService() {
183  Cleanup(Service::kStateIdle, Service::kFailureUnknown);
184}
185
186void L2TPIPSecDriver::FailService(Service::ConnectFailure failure) {
187  Cleanup(Service::kStateFailure, failure);
188}
189
190void L2TPIPSecDriver::Cleanup(Service::ConnectState state,
191                              Service::ConnectFailure failure) {
192  SLOG(this, 2) << __func__ << "("
193                << Service::ConnectStateToString(state) << ", "
194                << Service::ConnectFailureToString(failure) << ")";
195  StopConnectTimeout();
196  DeleteTemporaryFiles();
197  external_task_.reset();
198  if (device_) {
199    device_->DropConnection();
200    device_->SetEnabled(false);
201    device_ = nullptr;
202  }
203  if (service_) {
204    if (state == Service::kStateFailure) {
205      service_->SetFailure(failure);
206    } else {
207      service_->SetState(state);
208    }
209    service_ = nullptr;
210  }
211}
212
213void L2TPIPSecDriver::DeleteTemporaryFile(base::FilePath* temporary_file) {
214  if (!temporary_file->empty()) {
215    base::DeleteFile(*temporary_file, false);
216    temporary_file->clear();
217  }
218}
219
220void L2TPIPSecDriver::DeleteTemporaryFiles() {
221  DeleteTemporaryFile(&psk_file_);
222  DeleteTemporaryFile(&xauth_credentials_file_);
223}
224
225bool L2TPIPSecDriver::SpawnL2TPIPSecVPN(Error* error) {
226  SLOG(this, 2) << __func__;
227  std::unique_ptr<ExternalTask> external_task_local(
228      new ExternalTask(control_,
229                       process_manager_,
230                       weak_ptr_factory_.GetWeakPtr(),
231                       Bind(&L2TPIPSecDriver::OnL2TPIPSecVPNDied,
232                            weak_ptr_factory_.GetWeakPtr())));
233
234  vector<string> options;
235  map<string, string> environment;  // No env vars passed.
236  if (!InitOptions(&options, error)) {
237    return false;
238  }
239  LOG(INFO) << "L2TP/IPSec VPN process options: "
240            << base::JoinString(options, " ");
241
242  if (external_task_local->Start(
243          FilePath(kL2TPIPSecVPNPath), options, environment, true, error)) {
244    external_task_ = std::move(external_task_local);
245    return true;
246  }
247  return false;
248}
249
250bool L2TPIPSecDriver::InitOptions(vector<string>* options, Error* error) {
251  string vpnhost = args()->LookupString(kProviderHostProperty, "");
252  if (vpnhost.empty()) {
253    Error::PopulateAndLog(
254        FROM_HERE, error, Error::kInvalidArguments, "VPN host not specified.");
255    return false;
256  }
257
258  if (!InitPSKOptions(options, error)) {
259    return false;
260  }
261
262  if (!InitXauthOptions(options, error)) {
263    return false;
264  }
265
266  options->push_back(base::StringPrintf("--remote_host=%s", vpnhost.c_str()));
267  options->push_back(base::StringPrintf("--pppd_plugin=%s",
268                                        PPPDaemon::kShimPluginPath));
269  // Disable pppd from configuring IP addresses, routes, DNS.
270  options->push_back("--nosystemconfig");
271
272  // Accept a PEM CA certificate.
273  InitPEMOptions(options);
274
275  AppendValueOption(kL2tpIpsecClientCertIdProperty,
276                    "--client_cert_id", options);
277  AppendValueOption(kL2tpIpsecClientCertSlotProperty,
278                    "--client_cert_slot", options);
279  AppendValueOption(kL2tpIpsecPinProperty, "--user_pin", options);
280  AppendValueOption(kL2tpIpsecUserProperty, "--user", options);
281  AppendValueOption(kL2TPIPSecIPSecTimeoutProperty, "--ipsec_timeout", options);
282  AppendValueOption(kL2TPIPSecLeftProtoPortProperty,
283                    "--leftprotoport", options);
284  AppendFlag(kL2TPIPSecPFSProperty, "--pfs", "--nopfs", options);
285  AppendFlag(kL2TPIPSecRekeyProperty, "--rekey", "--norekey", options);
286  AppendValueOption(kL2TPIPSecRightProtoPortProperty,
287                    "--rightprotoport", options);
288  AppendFlag(kL2TPIPSecRequireChapProperty,
289             "--require_chap", "--norequire_chap", options);
290  AppendFlag(kL2TPIPSecRefusePapProperty,
291             "--refuse_pap", "--norefuse_pap", options);
292  AppendFlag(kL2TPIPSecRequireAuthProperty,
293             "--require_authentication", "--norequire_authentication", options);
294  AppendFlag(kL2TPIPSecLengthBitProperty,
295             "--length_bit", "--nolength_bit", options);
296  AppendFlag(kL2tpIpsecLcpEchoDisabledProperty,
297             "--noppp_lcp_echo", "--ppp_lcp_echo", options);
298  AppendValueOption(kL2tpIpsecTunnelGroupProperty, "--tunnel_group", options);
299  if (SLOG_IS_ON(VPN, 0)) {
300    options->push_back("--debug");
301  }
302  return true;
303}
304
305bool L2TPIPSecDriver::InitPSKOptions(vector<string>* options, Error* error) {
306  string psk = args()->LookupString(kL2tpIpsecPskProperty, "");
307  if (!psk.empty()) {
308    if (!base::CreateTemporaryFileInDir(manager()->run_path(), &psk_file_) ||
309        chmod(psk_file_.value().c_str(), S_IRUSR | S_IWUSR) ||
310        base::WriteFile(psk_file_, psk.data(), psk.size()) !=
311            static_cast<int>(psk.size())) {
312      Error::PopulateAndLog(
313          FROM_HERE, error, Error::kInternalError, "Unable to setup psk file.");
314      return false;
315    }
316    options->push_back(base::StringPrintf("--psk_file=%s",
317                                          psk_file_.value().c_str()));
318  }
319  return true;
320}
321
322bool L2TPIPSecDriver::InitPEMOptions(vector<string>* options) {
323  vector<string> ca_certs;
324  if (args()->ContainsStrings(kL2tpIpsecCaCertPemProperty)) {
325    ca_certs = args()->GetStrings(kL2tpIpsecCaCertPemProperty);
326  }
327  if (ca_certs.empty()) {
328    return false;
329  }
330  FilePath certfile = certificate_file_->CreatePEMFromStrings(ca_certs);
331  if (certfile.empty()) {
332    LOG(ERROR) << "Unable to extract certificates from PEM string.";
333    return false;
334  }
335  options->push_back(base::StringPrintf("--server_ca_file=%s",
336                                        certfile.value().c_str()));
337  return true;
338}
339
340bool L2TPIPSecDriver::InitXauthOptions(vector<string>* options, Error* error) {
341  string user = args()->LookupString(kL2tpIpsecXauthUserProperty, "");
342  string password = args()->LookupString(kL2tpIpsecXauthPasswordProperty, "");
343  if (user.empty() && password.empty()) {
344    // Xauth credentials not configured.
345    return true;
346  }
347  if (user.empty() || password.empty()) {
348      Error::PopulateAndLog(
349          FROM_HERE, error, Error::kInvalidArguments,
350          "XAUTH credentials are partially configured.");
351    return false;
352  }
353  string xauth_credentials = user + "\n" + password + "\n";
354  if (!base::CreateTemporaryFileInDir(manager()->run_path(),
355                                      &xauth_credentials_file_) ||
356      chmod(xauth_credentials_file_.value().c_str(), S_IRUSR | S_IWUSR) ||
357      base::WriteFile(xauth_credentials_file_, xauth_credentials.data(),
358                      xauth_credentials.size()) !=
359          static_cast<int>(xauth_credentials.size())) {
360    Error::PopulateAndLog(
361        FROM_HERE, error, Error::kInternalError,
362        "Unable to setup XAUTH credentials file.");
363    return false;
364  }
365  options->push_back(base::StringPrintf("--xauth_credentials_file=%s",
366                         xauth_credentials_file_.value().c_str()));
367  return true;
368}
369
370bool L2TPIPSecDriver::AppendValueOption(
371    const string& property, const string& option, vector<string>* options) {
372  string value = args()->LookupString(property, "");
373  if (!value.empty()) {
374    options->push_back(base::StringPrintf("%s=%s", option.c_str(),
375                                          value.c_str()));
376    return true;
377  }
378  return false;
379}
380
381bool L2TPIPSecDriver::AppendFlag(const string& property,
382                                 const string& true_option,
383                                 const string& false_option,
384                                 vector<string>* options) {
385  string value = args()->LookupString(property, "");
386  if (!value.empty()) {
387    options->push_back(value == "true" ? true_option : false_option);
388    return true;
389  }
390  return false;
391}
392
393void L2TPIPSecDriver::OnL2TPIPSecVPNDied(pid_t /*pid*/, int status) {
394  FailService(TranslateExitStatusToFailure(status));
395  // TODO(petkov): Figure if we need to restart the connection.
396}
397
398// static
399Service::ConnectFailure L2TPIPSecDriver::TranslateExitStatusToFailure(
400    int status) {
401  if (!WIFEXITED(status)) {
402    return Service::kFailureInternal;
403  }
404  switch (WEXITSTATUS(status)) {
405    case vpn_manager::kServiceErrorResolveHostnameFailed:
406      return Service::kFailureDNSLookup;
407    case vpn_manager::kServiceErrorIpsecConnectionFailed:
408    case vpn_manager::kServiceErrorL2tpConnectionFailed:
409    case vpn_manager::kServiceErrorPppConnectionFailed:
410      return Service::kFailureConnect;
411    case vpn_manager::kServiceErrorIpsecPresharedKeyAuthenticationFailed:
412      return Service::kFailureIPSecPSKAuth;
413    case vpn_manager::kServiceErrorIpsecCertificateAuthenticationFailed:
414      return Service::kFailureIPSecCertAuth;
415    case vpn_manager::kServiceErrorPppAuthenticationFailed:
416      return Service::kFailurePPPAuth;
417    default:
418      break;
419  }
420  return Service::kFailureUnknown;
421}
422
423void L2TPIPSecDriver::GetLogin(string* user, string* password) {
424  LOG(INFO) << "Login requested.";
425  string user_property =
426      args()->LookupString(kL2tpIpsecUserProperty, "");
427  if (user_property.empty()) {
428    LOG(ERROR) << "User not set.";
429    return;
430  }
431  string password_property =
432      args()->LookupString(kL2tpIpsecPasswordProperty, "");
433  if (password_property.empty()) {
434    LOG(ERROR) << "Password not set.";
435    return;
436  }
437  *user = user_property;
438  *password = password_property;
439}
440
441void L2TPIPSecDriver::Notify(
442    const string& reason, const map<string, string>& dict) {
443  LOG(INFO) << "IP configuration received: " << reason;
444
445  if (reason == kPPPReasonAuthenticating ||
446      reason == kPPPReasonAuthenticated) {
447    // These are uninteresting intermediate states that do not indicate failure.
448    return;
449  }
450
451  if (reason != kPPPReasonConnect) {
452    DCHECK_EQ(kPPPReasonDisconnect, reason);
453    // DestroyLater, rather than while on stack.
454    external_task_.release()->DestroyLater(dispatcher());
455    FailService(Service::kFailureUnknown);
456    return;
457  }
458
459  DeleteTemporaryFiles();
460
461  string interface_name = PPPDevice::GetInterfaceName(dict);
462  int interface_index = device_info_->GetIndex(interface_name);
463  if (interface_index < 0) {
464    // TODO(petkov): Consider handling the race when the RTNL notification about
465    // the new PPP device has not been received yet. We can keep the IP
466    // configuration and apply it when ClaimInterface is
467    // invoked. crbug.com/212446.
468    NOTIMPLEMENTED() << ": No device info for " << interface_name << ".";
469    return;
470  }
471
472  // There is no IPv6 support for L2TP/IPsec VPN at this moment, so create a
473  // blackhole route for IPv6 traffic after establishing a IPv4 VPN.
474  // TODO(benchan): Generalize this when IPv6 support is added.
475  bool blackhole_ipv6 = true;
476
477  if (!device_) {
478    device_ = ppp_device_factory_->CreatePPPDevice(
479        control_, dispatcher(), metrics_, manager(), interface_name,
480        interface_index);
481  }
482  device_->SetEnabled(true);
483  device_->SelectService(service_);
484
485  // Reduce MTU to the minimum viable for IPv6, since the IPSec layer consumes
486  // some variable portion of the payload.  Although this system does not yet
487  // support IPv6, it is a reasonable value to start with, since the minimum
488  // IPv6 packet size will plausibly be a size any gateway would support, and
489  // is also larger than the IPv4 minimum size.
490  device_->UpdateIPConfigFromPPPWithMTU(
491      dict, blackhole_ipv6, IPConfig::kMinIPv6MTU);
492
493  ReportConnectionMetrics();
494  StopConnectTimeout();
495}
496
497bool L2TPIPSecDriver::IsPskRequired() const {
498  return
499    const_args()->LookupString(kL2tpIpsecPskProperty, "").empty() &&
500    const_args()->LookupString(kL2tpIpsecClientCertIdProperty, "").empty();
501}
502
503KeyValueStore L2TPIPSecDriver::GetProvider(Error* error) {
504  SLOG(this, 2) << __func__;
505  KeyValueStore props = VPNDriver::GetProvider(error);
506  props.SetBool(kPassphraseRequiredProperty,
507                args()->LookupString(kL2tpIpsecPasswordProperty, "").empty());
508  props.SetBool(kL2tpIpsecPskRequiredProperty, IsPskRequired());
509  return props;
510}
511
512void L2TPIPSecDriver::ReportConnectionMetrics() {
513  metrics_->SendEnumToUMA(
514      Metrics::kMetricVpnDriver,
515      Metrics::kVpnDriverL2tpIpsec,
516      Metrics::kMetricVpnDriverMax);
517
518  // We output an enum for each of the authentication types specified,
519  // even if more than one is set at the same time.
520  bool has_remote_authentication = false;
521  if (args()->LookupString(kL2tpIpsecPskProperty, "") != "") {
522    metrics_->SendEnumToUMA(
523        Metrics::kMetricVpnRemoteAuthenticationType,
524        Metrics::kVpnRemoteAuthenticationTypeL2tpIpsecPsk,
525        Metrics::kMetricVpnRemoteAuthenticationTypeMax);
526    has_remote_authentication = true;
527  }
528  if (!has_remote_authentication) {
529    metrics_->SendEnumToUMA(
530        Metrics::kMetricVpnRemoteAuthenticationType,
531        Metrics::kVpnRemoteAuthenticationTypeL2tpIpsecDefault,
532        Metrics::kMetricVpnRemoteAuthenticationTypeMax);
533  }
534
535  bool has_user_authentication = false;
536  if (args()->LookupString(kL2tpIpsecClientCertIdProperty,
537                           "") != "") {
538    metrics_->SendEnumToUMA(
539        Metrics::kMetricVpnUserAuthenticationType,
540        Metrics::kVpnUserAuthenticationTypeL2tpIpsecCertificate,
541        Metrics::kMetricVpnUserAuthenticationTypeMax);
542    has_user_authentication = true;
543  }
544  if (args()->LookupString(kL2tpIpsecPasswordProperty, "") != "") {
545    metrics_->SendEnumToUMA(
546        Metrics::kMetricVpnUserAuthenticationType,
547        Metrics::kVpnUserAuthenticationTypeL2tpIpsecUsernamePassword,
548        Metrics::kMetricVpnUserAuthenticationTypeMax);
549    has_user_authentication = true;
550  }
551  if (!has_user_authentication) {
552    metrics_->SendEnumToUMA(
553        Metrics::kMetricVpnUserAuthenticationType,
554        Metrics::kVpnUserAuthenticationTypeL2tpIpsecNone,
555        Metrics::kMetricVpnUserAuthenticationTypeMax);
556  }
557}
558
559}  // namespace shill
560