// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SHILL_VPN_OPENVPN_DRIVER_H_
#define SHILL_VPN_OPENVPN_DRIVER_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <gtest/gtest_prod.h>  // for FRIEND_TEST

#include "shill/default_service_observer.h"
#include "shill/ipconfig.h"
#include "shill/net/sockets.h"
#include "shill/refptr_types.h"
#include "shill/rpc_task.h"
#include "shill/service.h"
#include "shill/vpn/vpn_driver.h"

namespace shill {

class CertificateFile;
class DeviceInfo;
class Error;
class OpenVPNManagementServer;

class OpenVPNDriver : public VPNDriver,
                      public RpcTaskDelegate,
                      public DefaultServiceObserver {
 public:
  enum ReconnectReason {
    kReconnectReasonUnknown,
    kReconnectReasonOffline,
    kReconnectReasonTLSError,
  };

  OpenVPNDriver(Manager* manager,
                ProcessManager* process_manager);
  ~OpenVPNDriver() override;

  virtual void OnReconnecting(ReconnectReason reason);

  // Resets the VPN state and deallocates all resources. If there's a service
  // associated through Connect, sets its state to Service::kStateIdle and
  // disassociates from the service.
  virtual void IdleService();

  // Resets the VPN state and deallocates all resources. If there's a service
  // associated through Connect, sets its state to Service::kStateFailure, sets
  // the failure reason to |failure|, sets its ErrorDetails property to
  // |error_details|, and disassociates from the service.
  virtual void FailService(Service::ConnectFailure failure,
                           const std::string& error_details);

  // Append zero-valued, single-valued and double-valued options to the
  // |options| array.
  static void AppendOption(const std::string& option,
                           std::vector<std::vector<std::string>>* options);
  static void AppendOption(const std::string& option,
                           const std::string& value,
                           std::vector<std::vector<std::string>>* options);
  static void AppendOption(const std::string& option,
                           const std::string& value0,
                           const std::string& value1,
                           std::vector<std::vector<std::string>>* options);

  // Appends remote option to the |options| array.
  void AppendRemoteOption(const std::string& host,
                          std::vector<std::vector<std::string>>* options);

  // Returns true if an option was appended.
  bool AppendValueOption(const std::string& property,
                         const std::string& option,
                         std::vector<std::vector<std::string>>* options);

  // If |property| exists, split its value up using |delimiter|.  Each element
  // will be a separate argument to |option|. Returns true if the option was
  // appended to |options|.
  bool AppendDelimitedValueOption(
      const std::string& property,
      const std::string& option,
      char delimiter,
      std::vector<std::vector<std::string>>* options);

  // Returns true if a flag was appended.
  bool AppendFlag(const std::string& property,
                  const std::string& option,
                  std::vector<std::vector<std::string>>* options);

  const RpcIdentifier& GetServiceRpcIdentifier() const;

 protected:
  // Inherited from VPNDriver. |Connect| initiates the VPN connection by
  // creating a tunnel device. When the device index becomes available, this
  // instance is notified through |ClaimInterface| and resumes the connection
  // process by setting up and spawning an external 'openvpn' process. IP
  // configuration settings are passed back from the external process through
  // the |Notify| RPC service method.
  void Connect(const VPNServiceRefPtr& service, Error* error) override;
  bool ClaimInterface(const std::string& link_name,
                      int interface_index) override;
  void Disconnect() override;
  std::string GetProviderType() const override;
  void OnConnectTimeout() override;

 private:
  friend class OpenVPNDriverTest;
  FRIEND_TEST(OpenVPNDriverTest, ClaimInterface);
  FRIEND_TEST(OpenVPNDriverTest, Cleanup);
  FRIEND_TEST(OpenVPNDriverTest, Connect);
  FRIEND_TEST(OpenVPNDriverTest, ConnectTunnelFailure);
  FRIEND_TEST(OpenVPNDriverTest, Disconnect);
  FRIEND_TEST(OpenVPNDriverTest, GetCommandLineArgs);
  FRIEND_TEST(OpenVPNDriverTest, GetRouteOptionEntry);
  FRIEND_TEST(OpenVPNDriverTest, InitCAOptions);
  FRIEND_TEST(OpenVPNDriverTest, InitCertificateVerifyOptions);
  FRIEND_TEST(OpenVPNDriverTest, InitClientAuthOptions);
  FRIEND_TEST(OpenVPNDriverTest, InitExtraCertOptions);
  FRIEND_TEST(OpenVPNDriverTest, InitLoggingOptions);
  FRIEND_TEST(OpenVPNDriverTest, InitOptions);
  FRIEND_TEST(OpenVPNDriverTest, InitOptionsHostWithExtraHosts);
  FRIEND_TEST(OpenVPNDriverTest, InitOptionsHostWithPort);
  FRIEND_TEST(OpenVPNDriverTest, InitOptionsNoHost);
  FRIEND_TEST(OpenVPNDriverTest, InitOptionsNoPrimaryHost);
  FRIEND_TEST(OpenVPNDriverTest, InitPKCS11Options);
  FRIEND_TEST(OpenVPNDriverTest, Notify);
  FRIEND_TEST(OpenVPNDriverTest, NotifyUMA);
  FRIEND_TEST(OpenVPNDriverTest, NotifyFail);
  FRIEND_TEST(OpenVPNDriverTest, OnDefaultServiceChanged);
  FRIEND_TEST(OpenVPNDriverTest, OnOpenVPNDied);
  FRIEND_TEST(OpenVPNDriverTest, ParseForeignOption);
  FRIEND_TEST(OpenVPNDriverTest, ParseForeignOptions);
  FRIEND_TEST(OpenVPNDriverTest, ParseIPConfiguration);
  FRIEND_TEST(OpenVPNDriverTest, ParseRouteOption);
  FRIEND_TEST(OpenVPNDriverTest, SetRoutes);
  FRIEND_TEST(OpenVPNDriverTest, SpawnOpenVPN);
  FRIEND_TEST(OpenVPNDriverTest, SplitPortFromHost);
  FRIEND_TEST(OpenVPNDriverTest, WriteConfigFile);

  // The map is a sorted container that allows us to iterate through the options
  // in order.
  using ForeignOptions = std::map<int, std::string>;
  using RouteOptions = std::map<int, IPConfig::Route>;

  static const char kDefaultCACertificates[];

  static const char kOpenVPNPath[];
  static const char kOpenVPNScript[];
  static const Property kProperties[];

  static const char kLSBReleaseFile[];

  static const char kDefaultOpenVPNConfigurationDirectory[];

  static const int kConnectTimeoutSeconds;
  static const int kReconnectOfflineTimeoutSeconds;
  static const int kReconnectTLSErrorTimeoutSeconds;

  static void ParseForeignOptions(const ForeignOptions& options,
                                  IPConfig::Properties* properties);
  static void ParseForeignOption(const std::string& option,
                                 std::vector<std::string>* domain_search,
                                 std::vector<std::string>* dns_servers);
  static IPConfig::Route* GetRouteOptionEntry(const std::string& prefix,
                                              const std::string& key,
                                              RouteOptions* routes);
  static void ParseRouteOption(const std::string& key,
                               const std::string& value,
                               RouteOptions* routes);
  static void SetRoutes(const RouteOptions& routes,
                        IPConfig::Properties* properties);

  // If |host| is in the "name:port" format, sets up |name| and |port|
  // appropriately and returns true. Otherwise, returns false.
  static bool SplitPortFromHost(const std::string& host,
                                std::string* name,
                                std::string* port);

  void InitOptions(std::vector<std::vector<std::string>>* options,
                   Error* error);
  bool InitCAOptions(std::vector<std::vector<std::string>>* options,
                     Error* error);
  void InitCertificateVerifyOptions(
      std::vector<std::vector<std::string>>* options);
  void InitClientAuthOptions(std::vector<std::vector<std::string>>* options);
  bool InitExtraCertOptions(std::vector<std::vector<std::string>>* options,
                            Error* error);
  void InitPKCS11Options(std::vector<std::vector<std::string>>* options);
  bool InitManagementChannelOptions(
      std::vector<std::vector<std::string>>* options, Error* error);
  void InitLoggingOptions(std::vector<std::vector<std::string>>* options);

  std::vector<std::string> GetCommandLineArgs();
  void ParseIPConfiguration(
      const std::map<std::string, std::string>& configuration,
      IPConfig::Properties* properties) const;

  bool SpawnOpenVPN();

  // Implements the public IdleService and FailService methods. Resets the VPN
  // state and deallocates all resources. If there's a service associated
  // through Connect, sets its state |state|; if |state| is
  // Service::kStateFailure, sets the failure reason to |failure| and its
  // ErrorDetails property to |error_details|; disassociates from the service.
  void Cleanup(Service::ConnectState state,
               Service::ConnectFailure failure,
               const std::string& error_details);

  static int GetReconnectTimeoutSeconds(ReconnectReason reason);

  // Join a list of options into a single string.
  static std::string JoinOptions(
      const std::vector<std::vector<std::string>>& options, char separator);

  // Output an OpenVPN configuration.
  bool WriteConfigFile(const std::vector<std::vector<std::string>>& options,
                       base::FilePath* config_file);

  // Called when the openpvn process exits.
  void OnOpenVPNDied(int exit_status);

  // Inherit from VPNDriver to add custom properties.
  KeyValueStore GetProvider(Error* error) override;

  // Implements RpcTaskDelegate.
  void GetLogin(std::string* user, std::string* password) override;
  void Notify(const std::string& reason,
              const std::map<std::string, std::string>& dict) override;

  // Implements DefaultServiceObserver.
  void OnDefaultServiceChanged(const ServiceRefPtr& logical_service,
                               bool logical_service_changed,
                               const ServiceRefPtr& physical_service,
                               bool physical_service_changed) override;

  void OnDefaultServiceStateChanged(const ServiceRefPtr& service) override;

  void ReportConnectionMetrics();

  Sockets sockets_;
  std::unique_ptr<OpenVPNManagementServer> management_server_;
  std::unique_ptr<CertificateFile> certificate_file_;
  std::unique_ptr<CertificateFile> extra_certificates_file_;
  base::FilePath lsb_release_file_;

  std::unique_ptr<RpcTask> rpc_task_;
  std::string tunnel_interface_;
  VirtualDeviceRefPtr device_;
  base::FilePath tls_auth_file_;
  base::FilePath openvpn_config_directory_;
  base::FilePath openvpn_config_file_;
  IPConfig::Properties ip_properties_;

  // The PID of the spawned openvpn process. May be 0 if no process has been
  // spawned yet or the process has died.
  int pid_;

  // Helps distinguish between a network->network transition (where the
  // client simply reconnects), and a network->link_down->network transition
  // (where the client should disconnect, wait for link up, then reconnect).
  bool link_down_;

  DISALLOW_COPY_AND_ASSIGN(OpenVPNDriver);
};

}  // namespace shill

#endif  // SHILL_VPN_OPENVPN_DRIVER_H_
