Home | History | Annotate | Download | only in vpn
      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 #ifndef SHILL_VPN_OPENVPN_DRIVER_H_
     18 #define SHILL_VPN_OPENVPN_DRIVER_H_
     19 
     20 #include <map>
     21 #include <memory>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include <base/files/file_path.h>
     26 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
     27 
     28 #include "shill/ipconfig.h"
     29 #include "shill/net/sockets.h"
     30 #include "shill/refptr_types.h"
     31 #include "shill/rpc_task.h"
     32 #include "shill/service.h"
     33 #include "shill/vpn/vpn_driver.h"
     34 
     35 namespace base {
     36 
     37 template<typename T>
     38 class WeakPtr;
     39 
     40 }  // namespace base
     41 
     42 namespace shill {
     43 
     44 class CertificateFile;
     45 class ControlInterface;
     46 class DeviceInfo;
     47 class Error;
     48 class Metrics;
     49 class OpenVPNManagementServer;
     50 class ProcessManager;
     51 
     52 class OpenVPNDriver : public VPNDriver,
     53                       public RPCTaskDelegate {
     54  public:
     55   enum ReconnectReason {
     56     kReconnectReasonUnknown,
     57     kReconnectReasonOffline,
     58     kReconnectReasonTLSError,
     59   };
     60 
     61   OpenVPNDriver(ControlInterface* control,
     62                 EventDispatcher* dispatcher,
     63                 Metrics* metrics,
     64                 Manager* manager,
     65                 DeviceInfo* device_info,
     66                 ProcessManager* process_manager);
     67   ~OpenVPNDriver() override;
     68 
     69   virtual void OnReconnecting(ReconnectReason reason);
     70 
     71   // Resets the VPN state and deallocates all resources. If there's a service
     72   // associated through Connect, sets its state to Service::kStateIdle and
     73   // disassociates from the service.
     74   virtual void IdleService();
     75 
     76   // Resets the VPN state and deallocates all resources. If there's a service
     77   // associated through Connect, sets its state to Service::kStateFailure, sets
     78   // the failure reason to |failure|, sets its ErrorDetails property to
     79   // |error_details|, and disassociates from the service.
     80   virtual void FailService(Service::ConnectFailure failure,
     81                            const std::string& error_details);
     82 
     83   // Append zero-valued, single-valued and double-valued options to the
     84   // |options| array.
     85   static void AppendOption(
     86       const std::string& option,
     87       std::vector<std::vector<std::string>>* options);
     88   static void AppendOption(
     89       const std::string& option,
     90       const std::string& value,
     91       std::vector<std::vector<std::string>>* options);
     92   static void AppendOption(
     93       const std::string& option,
     94       const std::string& value0,
     95       const std::string& value1,
     96       std::vector<std::vector<std::string>>* options);
     97 
     98   // Returns true if an option was appended.
     99   bool AppendValueOption(const std::string& property,
    100                          const std::string& option,
    101                          std::vector<std::vector<std::string>>* options);
    102 
    103   // If |property| exists, split its value up using |delimiter|.  Each element
    104   // will be a separate argument to |option|. Returns true if the option was
    105   // appended to |options|.
    106   bool AppendDelimitedValueOption(
    107       const std::string& property,
    108       const std::string& option,
    109       char delimiter,
    110       std::vector<std::vector<std::string>>* options);
    111 
    112   // Returns true if a flag was appended.
    113   bool AppendFlag(const std::string& property,
    114                   const std::string& option,
    115                   std::vector<std::vector<std::string>>* options);
    116 
    117   virtual std::string GetServiceRpcIdentifier() const;
    118 
    119  protected:
    120   // Inherited from VPNDriver. |Connect| initiates the VPN connection by
    121   // creating a tunnel device. When the device index becomes available, this
    122   // instance is notified through |ClaimInterface| and resumes the connection
    123   // process by setting up and spawning an external 'openvpn' process. IP
    124   // configuration settings are passed back from the external process through
    125   // the |Notify| RPC service method.
    126   void Connect(const VPNServiceRefPtr& service, Error* error) override;
    127   bool ClaimInterface(const std::string& link_name,
    128                       int interface_index) override;
    129   void Disconnect() override;
    130   std::string GetProviderType() const override;
    131   void OnConnectionDisconnected() override;
    132   void OnConnectTimeout() override;
    133 
    134  private:
    135   friend class OpenVPNDriverTest;
    136   FRIEND_TEST(OpenVPNDriverTest, ClaimInterface);
    137   FRIEND_TEST(OpenVPNDriverTest, Cleanup);
    138   FRIEND_TEST(OpenVPNDriverTest, Connect);
    139   FRIEND_TEST(OpenVPNDriverTest, ConnectTunnelFailure);
    140   FRIEND_TEST(OpenVPNDriverTest, Disconnect);
    141   FRIEND_TEST(OpenVPNDriverTest, GetEnvironment);
    142   FRIEND_TEST(OpenVPNDriverTest, GetRouteOptionEntry);
    143   FRIEND_TEST(OpenVPNDriverTest, InitCAOptions);
    144   FRIEND_TEST(OpenVPNDriverTest, InitCertificateVerifyOptions);
    145   FRIEND_TEST(OpenVPNDriverTest, InitClientAuthOptions);
    146   FRIEND_TEST(OpenVPNDriverTest, InitExtraCertOptions);
    147   FRIEND_TEST(OpenVPNDriverTest, InitLoggingOptions);
    148   FRIEND_TEST(OpenVPNDriverTest, InitOptions);
    149   FRIEND_TEST(OpenVPNDriverTest, InitOptionsHostWithPort);
    150   FRIEND_TEST(OpenVPNDriverTest, InitOptionsNoHost);
    151   FRIEND_TEST(OpenVPNDriverTest, InitPKCS11Options);
    152   FRIEND_TEST(OpenVPNDriverTest, Notify);
    153   FRIEND_TEST(OpenVPNDriverTest, NotifyUMA);
    154   FRIEND_TEST(OpenVPNDriverTest, NotifyFail);
    155   FRIEND_TEST(OpenVPNDriverTest, OnDefaultServiceChanged);
    156   FRIEND_TEST(OpenVPNDriverTest, OnOpenVPNDied);
    157   FRIEND_TEST(OpenVPNDriverTest, OnOpenVPNExited);
    158   FRIEND_TEST(OpenVPNDriverTest, ParseForeignOption);
    159   FRIEND_TEST(OpenVPNDriverTest, ParseForeignOptions);
    160   FRIEND_TEST(OpenVPNDriverTest, ParseIPConfiguration);
    161   FRIEND_TEST(OpenVPNDriverTest, ParseRouteOption);
    162   FRIEND_TEST(OpenVPNDriverTest, SetRoutes);
    163   FRIEND_TEST(OpenVPNDriverTest, SpawnOpenVPN);
    164   FRIEND_TEST(OpenVPNDriverTest, SplitPortFromHost);
    165   FRIEND_TEST(OpenVPNDriverTest, WriteConfigFile);
    166 
    167   // The map is a sorted container that allows us to iterate through the options
    168   // in order.
    169   typedef std::map<int, std::string> ForeignOptions;
    170   typedef std::map<int, IPConfig::Route> RouteOptions;
    171 
    172   static const char kDefaultCACertificates[];
    173 
    174   static const char kOpenVPNPath[];
    175   static const char kOpenVPNScript[];
    176   static const Property kProperties[];
    177 
    178   static const char kLSBReleaseFile[];
    179 
    180   static const char kDefaultOpenVPNConfigurationDirectory[];
    181 
    182   static const int kReconnectOfflineTimeoutSeconds;
    183   static const int kReconnectTLSErrorTimeoutSeconds;
    184 
    185   static void ParseForeignOptions(const ForeignOptions& options,
    186                                   IPConfig::Properties* properties);
    187   static void ParseForeignOption(const std::string& option,
    188                                  std::vector<std::string>* domain_search,
    189                                  std::vector<std::string>* dns_servers);
    190   static IPConfig::Route* GetRouteOptionEntry(const std::string& prefix,
    191                                               const std::string& key,
    192                                               RouteOptions* routes);
    193   static void ParseRouteOption(const std::string& key,
    194                                const std::string& value,
    195                                RouteOptions* routes);
    196   static void SetRoutes(const RouteOptions& routes,
    197                         IPConfig::Properties* properties);
    198 
    199   // If |host| is in the "name:port" format, sets up |name| and |port|
    200   // appropriately and returns true. Otherwise, returns false.
    201   static bool SplitPortFromHost(const std::string& host,
    202                                 std::string* name,
    203                                 std::string* port);
    204 
    205   void InitOptions(
    206       std::vector<std::vector<std::string>>* options, Error* error);
    207   bool InitCAOptions(
    208       std::vector<std::vector<std::string>>* options, Error* error);
    209   void InitCertificateVerifyOptions(
    210       std::vector<std::vector<std::string>>* options);
    211   void InitClientAuthOptions(std::vector<std::vector<std::string>>* options);
    212   bool InitExtraCertOptions(
    213       std::vector<std::vector<std::string>>* options, Error* error);
    214   void InitPKCS11Options(std::vector<std::vector<std::string>>* options);
    215   bool InitManagementChannelOptions(
    216       std::vector<std::vector<std::string>>* options, Error* error);
    217   void InitLoggingOptions(std::vector<std::vector<std::string>>* options);
    218 
    219   std::map<std::string, std::string> GetEnvironment();
    220   void ParseIPConfiguration(
    221       const std::map<std::string, std::string>& configuration,
    222       IPConfig::Properties* properties) const;
    223 
    224   bool SpawnOpenVPN();
    225 
    226   // Implements the public IdleService and FailService methods. Resets the VPN
    227   // state and deallocates all resources. If there's a service associated
    228   // through Connect, sets its state |state|; if |state| is
    229   // Service::kStateFailure, sets the failure reason to |failure| and its
    230   // ErrorDetails property to |error_details|; disassociates from the service.
    231   void Cleanup(Service::ConnectState state,
    232                Service::ConnectFailure failure,
    233                const std::string& error_details);
    234 
    235   static int GetReconnectTimeoutSeconds(ReconnectReason reason);
    236 
    237   // Join a list of options into a single string.
    238   static std::string JoinOptions(
    239       const std::vector<std::vector<std::string>>& options, char separator);
    240 
    241   // Output an OpenVPN configuration.
    242   bool WriteConfigFile(const std::vector<std::vector<std::string>>& options,
    243                        base::FilePath* config_file);
    244 
    245   // Called when the openpvn process exits.
    246   void OnOpenVPNDied(int exit_status);
    247 
    248   // Standalone callback used to delete the tunnel interface when the
    249   // openvpn process exits as we clean up. ("Exiting" is expected
    250   // termination during cleanup, while "dying" is any unexpected
    251   // termination.)
    252   static void OnOpenVPNExited(const base::WeakPtr<DeviceInfo>& device_info,
    253                               int interface_index,
    254                               int exit_status);
    255 
    256   // Inherit from VPNDriver to add custom properties.
    257   KeyValueStore GetProvider(Error* error) override;
    258 
    259   // Implements RPCTaskDelegate.
    260   void GetLogin(std::string* user, std::string* password) override;
    261   void Notify(const std::string& reason,
    262               const std::map<std::string, std::string>& dict) override;
    263 
    264   void OnDefaultServiceChanged(const ServiceRefPtr& service);
    265 
    266   void ReportConnectionMetrics();
    267 
    268   ControlInterface* control_;
    269   Metrics* metrics_;
    270   DeviceInfo* device_info_;
    271   ProcessManager* process_manager_;
    272   Sockets sockets_;
    273   std::unique_ptr<OpenVPNManagementServer> management_server_;
    274   std::unique_ptr<CertificateFile> certificate_file_;
    275   std::unique_ptr<CertificateFile> extra_certificates_file_;
    276   base::FilePath lsb_release_file_;
    277 
    278   VPNServiceRefPtr service_;
    279   std::unique_ptr<RPCTask> rpc_task_;
    280   std::string tunnel_interface_;
    281   VirtualDeviceRefPtr device_;
    282   base::FilePath tls_auth_file_;
    283   base::FilePath openvpn_config_directory_;
    284   base::FilePath openvpn_config_file_;
    285   IPConfig::Properties ip_properties_;
    286 
    287   // The PID of the spawned openvpn process. May be 0 if no process has been
    288   // spawned yet or the process has died.
    289   int pid_;
    290 
    291   // Default service watch callback tag.
    292   int default_service_callback_tag_;
    293 
    294   DISALLOW_COPY_AND_ASSIGN(OpenVPNDriver);
    295 };
    296 
    297 }  // namespace shill
    298 
    299 #endif  // SHILL_VPN_OPENVPN_DRIVER_H_
    300