blob: b74486fa12b40c33b1aff854b77b96863f4ac410 [file] [log] [blame]
// 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_THIRD_PARTY_VPN_DRIVER_H_
#define SHILL_VPN_THIRD_PARTY_VPN_DRIVER_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include <base/callback.h>
#include <gtest/gtest_prod.h>
#include "shill/ipconfig.h"
#include "shill/net/io_handler.h"
#include "shill/refptr_types.h"
#include "shill/service.h"
#include "shill/vpn/vpn_driver.h"
namespace shill {
class Error;
class FileIO;
class IOHandlerFactory;
class ThirdPartyVpnAdaptorInterface;
class ThirdPartyVpnDriver : public VPNDriver {
public:
enum PlatformMessage {
kConnected = 1,
kDisconnected,
kError,
kLinkDown,
kLinkUp,
kLinkChanged,
kSuspend,
kResume
};
ThirdPartyVpnDriver(Manager* manager, ProcessManager* process_manager);
ThirdPartyVpnDriver(const ThirdPartyVpnDriver&) = delete;
ThirdPartyVpnDriver& operator=(const ThirdPartyVpnDriver&) = delete;
~ThirdPartyVpnDriver() override;
// UpdateConnectionState is called by DBus adaptor when
// "UpdateConnectionState" method is called on the DBus interface.
void UpdateConnectionState(Service::ConnectState connection_state,
std::string* error_message);
// SendPacket is called by the DBus adaptor when "SendPacket" method is called
// on the DBus interface.
void SendPacket(const std::vector<uint8_t>& data, std::string* error_message);
// SetParameters is called by the DBus adaptor when "SetParameter" method is
// called on the DBus interface.
void SetParameters(const std::map<std::string, std::string>& parameters,
std::string* error_message,
std::string* warning_message);
void ClearExtensionId(Error* error);
bool SetExtensionId(const std::string& value, Error* error);
// Implementation of VPNDriver
void InitPropertyStore(PropertyStore* store) override;
void ConnectAsync(const VPNService::DriverEventCallback& callback) override;
IPConfig::Properties GetIPProperties() const override;
std::string GetProviderType() const override;
IfType GetIfType() const override;
void Disconnect() override;
void OnDefaultPhysicalServiceEvent(
DefaultPhysicalServiceEvent event) override;
bool Load(const StoreInterface* storage,
const std::string& storage_id) override;
bool Save(StoreInterface* storage,
const std::string& storage_id,
bool save_credentials) override;
void OnBeforeSuspend(const ResultCallback& callback) override;
void OnAfterResume() override;
const std::string& object_path_suffix() const { return object_path_suffix_; }
protected:
void OnConnectTimeout() override;
private:
friend class ThirdPartyVpnDriverTest;
FRIEND_TEST(ThirdPartyVpnDriverTest, ConnectAndDisconnect);
FRIEND_TEST(ThirdPartyVpnDriverTest, ReconnectionEvents);
FRIEND_TEST(ThirdPartyVpnDriverTest, PowerEvents);
FRIEND_TEST(ThirdPartyVpnDriverTest, SetParameters);
FRIEND_TEST(ThirdPartyVpnDriverTest, UpdateConnectionState);
FRIEND_TEST(ThirdPartyVpnDriverTest, SendPacket);
// Resets the internal state and deallocates all resources - closes the
// handle to tun device, IO handler if open and deactivates itself with the
// |thirdpartyvpn_adaptor_| if active.
void Cleanup();
// First do Cleanup(). Then if there's a service associated through
// ConnectAsync, notify it to sets its state to Service::kStateFailure, sets
// the failure reason to |failure|, sets its ErrorDetails property to
// |error_details|, and disassociates from the service.
void FailService(Service::ConnectFailure failure,
const std::string& error_details);
// This function first checks if a value is present for a particular |key| in
// the dictionary |parameters|.
// If present it ensures the value is a valid IP address and then sets it to
// the |target|.
// The flag |mandatory| when set to true, makes the function treat a missing
// key as an error. The function adds to |error_messages|, when there is a
// failure.
// This function supports only IPV4 addresses now.
void ProcessIp(const std::map<std::string, std::string>& parameters,
const char* key,
std::string* target,
bool mandatory,
std::string* error_message);
// This function first checks if a value is present for a particular |key| in
// the dictionary |parameters|.
// If present it treats the value as a list of string separated by
// |delimiter|. Each string value is verified to be a valid IP address,
// deleting ones that are not. The list of string is set to |target|.
// The flag |mandatory| when set to true, makes the function treat a missing
// key as an error. The function adds to |error_message|, when there is a
// failure and |warn_message| when there is a warning.
void ProcessIPArray(const std::map<std::string, std::string>& parameters,
const char* key,
char delimiter,
std::vector<std::string>* target,
bool mandatory,
std::string* error_message,
std::string* warn_message);
// This function first checks if a value is present for a particular |key| in
// the dictionary |parameters|.
// If present it treats the value as a list of string separated by
// |delimiter|. Each string value is verified to be a valid IP address in
// CIDR format, deleting ones that are not. The list of string is set to
// |target|. The flag |mandatory| when set to true, makes the function treat a
// missing key as an error. The function adds to |error_message|, when there
// is a failure and |warn_message| when there is a warning.
void ProcessIPArrayCIDR(const std::map<std::string, std::string>& parameters,
const char* key,
char delimiter,
std::vector<std::string>* target,
bool mandatory,
std::string* error_message,
std::string* warn_message);
// This function first checks if a value is present for a particular |key| in
// the dictionary |parameters|.
// If present it treats the value as a list of string separated by
// |delimiter|. The list of string is set to |target|.
// The flag |mandatory| when set to true, makes the function treat a missing
// key as an error. The function adds to |error_messages|, when there is a
// failure.
void ProcessSearchDomainArray(
const std::map<std::string, std::string>& parameters,
const char* key,
char delimiter,
std::vector<std::string>* target,
bool mandatory,
std::string* error_message);
// This function first checks if a value is present for a particular |key| in
// the dictionary |parameters|.
// If present it treats the value as an integer and verifies if the value lies
// between |min_value| and |max_value|. It then updates |target| with the
// integer value if it is in range.
// The flag |mandatory| when set to true, makes the function treat a missing
// key as an error. The function adds to |error_messages|, when there is a
// failure.
void ProcessInt32(const std::map<std::string, std::string>& parameters,
const char* key,
int32_t* target,
int32_t min_value,
int32_t max_value,
bool mandatory,
std::string* error_message);
// This function first checks if a value is present for a particular |key| in
// the dictionary |parameters|.
// If present it treats the value as a boolean. It then updates |target|
// with the boolean value if it is valid;
// The flag |mandatory| when set to true, makes the function treat a missing
// key as an error. The function adds to |error_messages|, when there is a
// failure.
void ProcessBoolean(const std::map<std::string, std::string>& parameters,
const char* key,
bool* target,
bool mandatory,
std::string* error_message);
// These functions are called whe there is input and error in the tun
// interface.
void OnInput(InputData* data);
void OnInputError(const std::string& error);
static const Property kProperties[];
// This variable keeps track of the active instance. There can be multiple
// instance of this class at a time but only one would be active that can
// communicate with the VPN client over DBUS.
static ThirdPartyVpnDriver* active_client_;
// ThirdPartyVpnAdaptorInterface manages the DBus communication and provides
// an unique identifier for the ThirdPartyVpnDriver.
std::unique_ptr<ThirdPartyVpnAdaptorInterface> adaptor_interface_;
// Object path suffix is made of Extension ID and name that collectively
// identifies the configuration of the third party VPN client.
std::string object_path_suffix_;
// File descriptor for the tun device.
int tun_fd_;
// Configuration properties of the virtual VPN device set by the VPN client.
IPConfig::Properties ip_properties_;
bool ip_properties_set_;
IOHandlerFactory* io_handler_factory_;
// IO handler triggered when there is an error or data ready for read in the
// tun device.
std::unique_ptr<IOHandler> io_handler_;
// The object is used to write to tun device.
FileIO* file_io_;
// Set used to identify duplicate entries in inclusion and exclusion list.
std::set<std::string> known_cidrs_;
// The boolean indicates if parameters are expected from the VPN client.
bool parameters_expected_;
// Flag indicating whether the extension supports reconnections - a feature
// that wasn't in the original API. If not, we won't send link_* or
// suspend/resume signals.
bool reconnect_supported_;
VPNService::DriverEventCallback service_callback_;
base::WeakPtrFactory<ThirdPartyVpnDriver> weak_factory_{this};
};
} // namespace shill
#endif // SHILL_VPN_THIRD_PARTY_VPN_DRIVER_H_