Merge pull request #27507 from brave/set_vpn_proxy_windows_ikev2
Set VPN proxy url in Windows ikev2 connection
This commit is contained in:
@@ -36,8 +36,9 @@ std::unique_ptr<Hostname> PickBestHostname(
|
||||
return a.capacity_score > b.capacity_score;
|
||||
});
|
||||
|
||||
if (filtered_hostnames.empty())
|
||||
if (filtered_hostnames.empty()) {
|
||||
return std::make_unique<Hostname>();
|
||||
}
|
||||
|
||||
// Pick highest capacity score.
|
||||
return std::make_unique<Hostname>(filtered_hostnames[0]);
|
||||
@@ -47,24 +48,30 @@ std::vector<Hostname> ParseHostnames(const base::Value::List& hostnames_value) {
|
||||
std::vector<Hostname> hostnames;
|
||||
for (const auto& value : hostnames_value) {
|
||||
DCHECK(value.is_dict());
|
||||
if (!value.is_dict())
|
||||
if (!value.is_dict()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& dict = value.GetDict();
|
||||
constexpr char kHostnameKey[] = "hostname";
|
||||
constexpr char kDisplayNameKey[] = "display-name";
|
||||
constexpr char kOfflineKey[] = "offline";
|
||||
constexpr char kCapacityScoreKey[] = "capacity-score";
|
||||
constexpr char kSmartRoutingEnabled[] = "smart-routing-enabled";
|
||||
const std::string* hostname_str = dict.FindString(kHostnameKey);
|
||||
const std::string* display_name_str = dict.FindString(kDisplayNameKey);
|
||||
std::optional<bool> offline = dict.FindBool(kOfflineKey);
|
||||
std::optional<int> capacity_score = dict.FindInt(kCapacityScoreKey);
|
||||
std::optional<bool> smart_routing_enabled =
|
||||
dict.FindBool(kSmartRoutingEnabled);
|
||||
|
||||
if (!hostname_str || !display_name_str || !offline || !capacity_score)
|
||||
if (!hostname_str || !display_name_str || !offline || !capacity_score) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hostnames.push_back(
|
||||
Hostname{*hostname_str, *display_name_str, *offline, *capacity_score});
|
||||
hostnames.push_back(Hostname{*hostname_str, *display_name_str, *offline,
|
||||
*capacity_score,
|
||||
smart_routing_enabled.value_or(false)});
|
||||
}
|
||||
|
||||
return hostnames;
|
||||
|
||||
@@ -20,6 +20,8 @@ void BraveVPNConnectionInfo::Reset() {
|
||||
hostname_.clear();
|
||||
username_.clear();
|
||||
password_.clear();
|
||||
smart_routing_enabled_ = false;
|
||||
proxy_.clear();
|
||||
}
|
||||
|
||||
bool BraveVPNConnectionInfo::IsValid() const {
|
||||
@@ -31,11 +33,15 @@ void BraveVPNConnectionInfo::SetConnectionInfo(
|
||||
const std::string& connection_name,
|
||||
const std::string& hostname,
|
||||
const std::string& username,
|
||||
const std::string& password) {
|
||||
const std::string& password,
|
||||
const bool smart_routing_enabled,
|
||||
const std::string& proxy) {
|
||||
connection_name_ = connection_name;
|
||||
hostname_ = hostname;
|
||||
username_ = username;
|
||||
password_ = password;
|
||||
smart_routing_enabled_ = smart_routing_enabled;
|
||||
proxy_ = proxy;
|
||||
}
|
||||
|
||||
} // namespace brave_vpn
|
||||
|
||||
@@ -22,18 +22,24 @@ class BraveVPNConnectionInfo {
|
||||
void SetConnectionInfo(const std::string& connection_name,
|
||||
const std::string& hostname,
|
||||
const std::string& username,
|
||||
const std::string& password);
|
||||
const std::string& password,
|
||||
bool smart_routing_enabled,
|
||||
const std::string& proxy);
|
||||
|
||||
std::string connection_name() const { return connection_name_; }
|
||||
std::string hostname() const { return hostname_; }
|
||||
std::string username() const { return username_; }
|
||||
std::string password() const { return password_; }
|
||||
bool smart_routing_enabled() const { return smart_routing_enabled_; }
|
||||
std::string proxy() const { return proxy_; }
|
||||
|
||||
private:
|
||||
std::string connection_name_;
|
||||
std::string hostname_;
|
||||
std::string username_;
|
||||
std::string password_;
|
||||
bool smart_routing_enabled_;
|
||||
std::string proxy_;
|
||||
};
|
||||
|
||||
} // namespace brave_vpn
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "brave/components/brave_vpn/browser/api/brave_vpn_api_request.h"
|
||||
#include "brave/components/brave_vpn/browser/connection/brave_vpn_connection_manager.h"
|
||||
#include "brave/components/brave_vpn/common/brave_vpn_data_types.h"
|
||||
#include "brave/components/brave_vpn/common/pref_names.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "services/network/public/cpp/shared_url_loader_factory.h"
|
||||
|
||||
namespace brave_vpn {
|
||||
@@ -171,6 +173,23 @@ void ConnectionAPIImpl::ResetHostname() {
|
||||
hostname_.reset();
|
||||
}
|
||||
|
||||
bool ConnectionAPIImpl::SmartRoutingEnabled() const {
|
||||
if (hostname_ && hostname_->smart_routing_enabled) {
|
||||
bool smart_routing_user_supported = manager_->local_prefs()->GetBoolean(
|
||||
prefs::kBraveVPNSmartProxyRoutingEnabled);
|
||||
VLOG(2) << __func__ << " Host \"" << hostname_->hostname
|
||||
<< "\" supports smart proxy routing. "
|
||||
<< (smart_routing_user_supported
|
||||
? "Smart proxy routing will be used."
|
||||
: "However, user has disabled smart proxy routing.");
|
||||
return smart_routing_user_supported;
|
||||
} else if (hostname_) {
|
||||
VLOG(2) << __func__ << " Host \"" << hostname_->hostname
|
||||
<< "\" does not support smart proxy routing. ";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConnectionAPIImpl::UpdateAndNotifyConnectionStateChange(
|
||||
mojom::ConnectionState state) {
|
||||
// this is a simple state machine for handling connection state
|
||||
|
||||
@@ -46,6 +46,7 @@ class ConnectionAPIImpl
|
||||
void ResetConnectionState();
|
||||
std::string GetLastConnectionError() const;
|
||||
std::string GetHostname() const;
|
||||
bool SmartRoutingEnabled() const;
|
||||
|
||||
virtual void Connect() = 0;
|
||||
virtual void Disconnect() = 0;
|
||||
|
||||
+3
-1
@@ -14,6 +14,7 @@
|
||||
#include "brave/components/brave_vpn/browser/api/brave_vpn_api_request.h"
|
||||
#include "brave/components/brave_vpn/browser/connection/brave_vpn_connection_manager.h"
|
||||
#include "brave/components/brave_vpn/browser/connection/brave_vpn_region_data_manager.h"
|
||||
#include "brave/components/brave_vpn/common/brave_vpn_constants.h"
|
||||
#include "brave/components/brave_vpn/common/brave_vpn_data_types.h"
|
||||
#include "brave/components/brave_vpn/common/brave_vpn_utils.h"
|
||||
|
||||
@@ -325,7 +326,8 @@ void SystemVPNConnectionAPIImplBase::OnGetProfileCredentials(
|
||||
}
|
||||
|
||||
connection_info_.SetConnectionInfo(manager_->target_vpn_entry_name(),
|
||||
GetHostname(), *username, *password);
|
||||
GetHostname(), *username, *password,
|
||||
SmartRoutingEnabled(), kProxyUrl);
|
||||
// Let's create os vpn entry with |connection_info_|.
|
||||
CreateVPNConnection();
|
||||
return;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "brave/components/brave_vpn/browser/connection/ikev2/win/ras_utils.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <ras.h>
|
||||
#include <raserror.h>
|
||||
#include <stdio.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
#include "brave/base/process/process_launcher.h"
|
||||
#include "brave/components/brave_vpn/browser/connection/brave_vpn_connection_info.h"
|
||||
#include "brave/components/brave_vpn/common/brave_vpn_constants.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace brave_vpn {
|
||||
|
||||
@@ -422,6 +424,50 @@ RasOperationResult SetConnectionParamsUsingPowerShell(
|
||||
return GetRasSuccessResult();
|
||||
}
|
||||
|
||||
// `Set-VpnConnectionProxy` cmdlet:
|
||||
// https://learn.microsoft.com/en-us/powershell/module/vpnclient/set-vpnconnectionproxy?view=windowsserver2022-ps
|
||||
RasOperationResult SetConnectionProxyParamsUsingPowerShell(
|
||||
const std::wstring& entry_name,
|
||||
const std::wstring& pac_file_url) {
|
||||
// Validate the entry name
|
||||
DWORD nRet = RasValidateEntryName(NULL, entry_name.c_str());
|
||||
switch (nRet) {
|
||||
case ERROR_INVALID_NAME:
|
||||
return GetRasErrorResult("`entry_name` is not a valid format");
|
||||
case ERROR_CANNOT_FIND_PHONEBOOK_ENTRY:
|
||||
return GetRasErrorResult("`entry_name` is not in phone book");
|
||||
default:
|
||||
// ERROR_SUCCESS
|
||||
// ERROR_ALREADY_EXISTS
|
||||
break;
|
||||
}
|
||||
|
||||
// Validate the URL of the provided PAC file
|
||||
VLOG(2) << __func__ << " validating `pac_file_url`: \"" << pac_file_url
|
||||
<< "\"";
|
||||
GURL pac_file = GURL(base::WideToUTF8(pac_file_url));
|
||||
if (!pac_file.is_valid()) {
|
||||
return GetRasErrorResult("`pac_file_url` is not a valid URL");
|
||||
}
|
||||
if (!pac_file.SchemeIs(url::kHttpsScheme)) {
|
||||
return GetRasErrorResult("`pac_file_url` is not using HTTPS");
|
||||
}
|
||||
|
||||
base::CommandLine power_shell(base::FilePath(L"PowerShell"));
|
||||
power_shell.AppendArg("Set-VpnConnectionProxy");
|
||||
power_shell.AppendArg("-ConnectionName");
|
||||
power_shell.AppendArg(base::WideToUTF8(entry_name));
|
||||
power_shell.AppendArg("-AutoConfigurationScript");
|
||||
power_shell.AppendArg(base::WideToUTF8(pac_file_url));
|
||||
base::LaunchOptions options;
|
||||
options.start_hidden = true;
|
||||
auto result = brave::ProcessLauncher::ReadAppOutput(power_shell, options, 10);
|
||||
if (!result.has_value()) {
|
||||
return GetRasErrorResult(logging::SystemErrorCodeToString(GetLastError()));
|
||||
}
|
||||
return GetRasSuccessResult();
|
||||
}
|
||||
|
||||
RasOperationResult SetConnectionParamsWin32(
|
||||
const std::wstring& entry_name,
|
||||
const std::wstring& phone_book_path) {
|
||||
@@ -466,6 +512,7 @@ RasOperationResult CreateEntry(const BraveVPNConnectionInfo& info) {
|
||||
const auto hostname = base::UTF8ToWide(info.hostname());
|
||||
const auto username = base::UTF8ToWide(info.username());
|
||||
const auto password = base::UTF8ToWide(info.password());
|
||||
const auto proxy = base::UTF8ToWide(info.proxy());
|
||||
|
||||
// `RasSetEntryProperties` can have problems if fields are empty.
|
||||
// Specifically, it will crash if `hostname` is NULL. Entry name
|
||||
@@ -542,6 +589,13 @@ RasOperationResult CreateEntry(const BraveVPNConnectionInfo& info) {
|
||||
if (!SetConnectionParamsUsingPowerShell(entry_name).success) {
|
||||
return SetConnectionParamsWin32(entry_name, phone_book_path);
|
||||
}
|
||||
|
||||
// Only provide proxy params if the host supports smart routing.
|
||||
if (info.smart_routing_enabled()) {
|
||||
// Can ignore proxy setting failure. VPN works w/o it.
|
||||
SetConnectionProxyParamsUsingPowerShell(entry_name, proxy);
|
||||
}
|
||||
|
||||
return GetRasSuccessResult();
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ inline constexpr char kSubscriberCredentialKey[] = "credential";
|
||||
inline constexpr char kSkusCredentialKey[] = "skus_credential";
|
||||
inline constexpr char kRetriedSkusCredentialKey[] = "retried_skus_credential";
|
||||
inline constexpr char kSubscriberCredentialExpirationKey[] = "expiration";
|
||||
inline constexpr char kProxyUrl[] =
|
||||
"https://connect-api.guardianapp.com/api/v1/smart-proxy-routing/static-pac";
|
||||
|
||||
#if !BUILDFLAG(IS_ANDROID)
|
||||
inline constexpr char kTokenNoLongerValid[] = "Token No Longer Valid";
|
||||
|
||||
@@ -15,6 +15,7 @@ struct Hostname {
|
||||
std::string display_name;
|
||||
bool is_offline;
|
||||
int capacity_score;
|
||||
bool smart_routing_enabled;
|
||||
};
|
||||
|
||||
} // namespace brave_vpn
|
||||
|
||||
@@ -53,6 +53,8 @@ void RegisterVPNLocalStatePrefs(PrefRegistrySimple* registry) {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
registry->RegisterBooleanPref(prefs::kBraveVPNOnDemandEnabled, false);
|
||||
#endif
|
||||
registry->RegisterBooleanPref(prefs::kBraveVPNSmartProxyRoutingEnabled,
|
||||
false);
|
||||
registry->RegisterListPref(prefs::kBraveVPNWidgetUsageWeeklyStorage);
|
||||
}
|
||||
|
||||
@@ -244,12 +246,15 @@ std::string GetBraveVPNEntryName(version_info::Channel channel) {
|
||||
}
|
||||
|
||||
std::string GetManageUrl(const std::string& env) {
|
||||
if (env == skus::kEnvProduction)
|
||||
if (env == skus::kEnvProduction) {
|
||||
return brave_vpn::kManageUrlProd;
|
||||
if (env == skus::kEnvStaging)
|
||||
}
|
||||
if (env == skus::kEnvStaging) {
|
||||
return brave_vpn::kManageUrlStaging;
|
||||
if (env == skus::kEnvDevelopment)
|
||||
}
|
||||
if (env == skus::kEnvDevelopment) {
|
||||
return brave_vpn::kManageUrlDev;
|
||||
}
|
||||
|
||||
NOTREACHED() << "All env handled above.";
|
||||
}
|
||||
@@ -300,29 +305,34 @@ void MigrateLocalStatePrefs(PrefService* local_prefs) {
|
||||
bool HasValidSubscriberCredential(PrefService* local_prefs) {
|
||||
const base::Value::Dict& sub_cred_dict =
|
||||
local_prefs->GetDict(prefs::kBraveVPNSubscriberCredential);
|
||||
if (sub_cred_dict.empty())
|
||||
if (sub_cred_dict.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string* cred = sub_cred_dict.FindString(kSubscriberCredentialKey);
|
||||
const base::Value* expiration_time_value =
|
||||
sub_cred_dict.Find(kSubscriberCredentialExpirationKey);
|
||||
|
||||
if (!cred || !expiration_time_value)
|
||||
if (!cred || !expiration_time_value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cred->empty())
|
||||
if (cred->empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto expiration_time = base::ValueToTime(expiration_time_value);
|
||||
if (!expiration_time || expiration_time < base::Time::Now())
|
||||
if (!expiration_time || expiration_time < base::Time::Now()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetSubscriberCredential(PrefService* local_prefs) {
|
||||
if (!HasValidSubscriberCredential(local_prefs))
|
||||
if (!HasValidSubscriberCredential(local_prefs)) {
|
||||
return "";
|
||||
}
|
||||
const base::Value::Dict& sub_cred_dict =
|
||||
local_prefs->GetDict(prefs::kBraveVPNSubscriberCredential);
|
||||
const std::string* cred = sub_cred_dict.FindString(kSubscriberCredentialKey);
|
||||
|
||||
@@ -54,6 +54,9 @@ inline constexpr char kBraveVPNOnDemandEnabled[] =
|
||||
"brave.brave_vpn.on_demand_enabled";
|
||||
#endif
|
||||
|
||||
inline constexpr char kBraveVPNSmartProxyRoutingEnabled[] =
|
||||
"brave.brave_vpn.smart_proxy_routing_enabled";
|
||||
|
||||
inline constexpr char kBraveVPNWireguardProfileCredentials[] =
|
||||
"brave.brave_vpn.wireguard.profile_credentials";
|
||||
inline constexpr char kBraveVPNEnvironment[] = "brave.brave_vpn.env";
|
||||
|
||||
Reference in New Issue
Block a user