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