Skip to content

Commit

Permalink
Merge branch 'release/3.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Mindaugas Veblauskas committed Dec 18, 2024
2 parents e3f5049 + d444da4 commit 3bfedb3
Show file tree
Hide file tree
Showing 70 changed files with 524 additions and 696 deletions.
5 changes: 3 additions & 2 deletions Setup/Native/arm64/ProtonVPN.CalloutDriver.inf
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Class = WFPCALLOUTS
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
Provider = %ManufacturerName%
CatalogFile = ProtonVPN.CalloutDriver.cat
DriverVer = 08/19/2024,15.41.59.712
DriverVer = 11/19/2024,7.43.45.10
PnpLockdown = 1

[SourceDisksNames]
1 = %DiskName%,,,""
Expand All @@ -26,7 +27,7 @@ CopyFiles = ProtonVPN.CalloutDriver.Files

[DefaultUninstall.NTARM64]
LegacyUninstall = 1
DelFiles = ProtonVPN.CalloutDriver.Files
;DelFiles = ProtonVPN.CalloutDriver.Files

[DefaultInstall.NTARM64.Services]
AddService = %ServiceName%,,ProtonVPN.CalloutDriver.Service
Expand Down
Binary file modified Setup/Native/arm64/ProtonVPN.CalloutDriver.sys
Binary file not shown.
Binary file modified Setup/Native/arm64/protonvpn.calloutdriver.cat
Binary file not shown.
5 changes: 3 additions & 2 deletions Setup/Native/x64/ProtonVPN.CalloutDriver.inf
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Class = WFPCALLOUTS
ClassGuid = {57465043-616C-6C6F-7574-5F636C617373}
Provider = %ManufacturerName%
CatalogFile = ProtonVPN.CalloutDriver.cat
DriverVer = 01/26/2021,18.36.11.107
DriverVer = 11/19/2024,11.46.44.670
PnpLockdown = 1

[SourceDisksNames]
1 = %DiskName%,,,""
Expand All @@ -26,7 +27,7 @@ CopyFiles = ProtonVPN.CalloutDriver.Files

[DefaultUninstall.NTamd64]
LegacyUninstall = 1
DelFiles = ProtonVPN.CalloutDriver.Files
;DelFiles = ProtonVPN.CalloutDriver.Files

[DefaultInstall.NTamd64.Services]
AddService = %ServiceName%,,ProtonVPN.CalloutDriver.Service
Expand Down
Binary file modified Setup/Native/x64/ProtonVPN.CalloutDriver.sys
Binary file not shown.
Binary file modified Setup/Native/x64/protonvpn.calloutdriver.cat
Binary file not shown.
2 changes: 1 addition & 1 deletion Setup/SetupBase.iss
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ var
begin
SetSilentModes();
SetIsToDisableAutoUpdate();
if IsWindowsVersionEqualOrHigher(10, 0, 17763) = False then begin
if IsWindowsVersionEqualOrHigher(10, 0, 19041) = False then begin
if WizardSilent() = false then begin
MsgBox('This application does not support your Windows version. You will be redirected to a download page with an application suitable for your Windows version. ', mbInformation, MB_OK);
ShellExec('open', 'https://protonvpn.com/free-vpn/windows/windows7', '', '', SW_SHOW, ewNoWait, ErrCode);
Expand Down
6 changes: 3 additions & 3 deletions src/Api/ProtonVPN.Api.Contracts/IApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ public interface IApiClient : IClientBase
Task<ApiResponseResult<PhysicalServerWrapperResponse>> GetServerAsync(string serverId);
Task<ApiResponseResult<VpnInfoWrapperResponse>> GetVpnInfoResponse();
Task<ApiResponseResult<BaseResponse>> GetLogoutResponse();
Task<ApiResponseResult<ServersResponse>> GetServersAsync(string ip);
Task<ApiResponseResult<ServersResponse>> GetServersAsync(string countryCode, string ip);
Task<ApiResponseResult<ReportAnIssueFormResponse>> GetReportAnIssueFormData();
Task<ApiResponseResult<ServersResponse>> GetServerLoadsAsync(string ip);
Task<ApiResponseResult<ServersResponse>> GetServerLoadsAsync(string countryCode, string ip);
Task<ApiResponseResult<UserLocationResponse>> GetLocationDataAsync();
Task<ApiResponseResult<BaseResponse>> ReportBugAsync(IEnumerable<KeyValuePair<string, string>> fields, IEnumerable<File> files);
Task<ApiResponseResult<SessionsResponse>> GetSessions();
Task<ApiResponseResult<VpnConfigResponse>> GetVpnConfig(string country, string ip);
Task<ApiResponseResult<VpnConfigResponse>> GetVpnConfig(string countryCode, string ip);
Task<ApiResponseResult<AnnouncementsResponse>> GetAnnouncementsAsync(AnnouncementsRequest request);
Task<ApiResponseResult<StreamingServicesResponse>> GetStreamingServicesAsync();
Task<ApiResponseResult<BaseResponse>> CheckAuthenticationServerStatusAsync();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Proton AG
* Copyright (c) 2024 Proton AG
*
* This file is part of ProtonVPN.
*
Expand All @@ -17,11 +17,13 @@
* along with ProtonVPN. If not, see <https://www.gnu.org/licenses/>.
*/

namespace ProtonVPN.Vpn.Networks
using Newtonsoft.Json;

namespace ProtonVPN.Api.Contracts.Servers
{
public interface INetworkAdapterManager
public class EntryPerProtocolEntryResponse
{
int DisableDuplicatedWireGuardAdapters();
int EnableOpenVpnAdapters();
[JsonProperty("IPv4")]
public string Ipv4 { get; set; }
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Proton AG
* Copyright (c) 2024 Proton AG
*
* This file is part of ProtonVPN.
*
Expand All @@ -17,24 +17,25 @@
* along with ProtonVPN. If not, see <https://www.gnu.org/licenses/>.
*/

using System.Collections.Generic;
using System.Management;
using Newtonsoft.Json;

namespace ProtonVPN.Vpn.Networks.Adapters
namespace ProtonVPN.Api.Contracts.Servers
{
public class NetworkAdaptersLoader : INetworkAdaptersLoader
public class EntryPerProtocolResponse
{
public IList<INetworkAdapter> GetAll()
{
SelectQuery query = new("Win32_NetworkAdapter");
ManagementObjectSearcher search = new(query);
IList<INetworkAdapter> networkAdapters = new List<INetworkAdapter>();
foreach (ManagementObject result in search.Get())
{
networkAdapters.Add(new NetworkAdapter(result));
}
[JsonProperty("WireGuardUDP")]
public EntryPerProtocolEntryResponse WireGuardUdp { get; set; }

return networkAdapters;
}
[JsonProperty("WireGuardTCP")]
public EntryPerProtocolEntryResponse WireGuardTcp { get; set; }

[JsonProperty("WireGuardTLS")]
public EntryPerProtocolEntryResponse WireGuardTls { get; set; }

[JsonProperty("OpenVPNUDP")]
public EntryPerProtocolEntryResponse OpenVpnUdp { get; set; }

[JsonProperty("OpenVPNTCP")]
public EntryPerProtocolEntryResponse OpenVpnTcp { get; set; }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class LogicalServerResponse
public string HostCountry { get; set; }
public string GatewayName { get; set; }
public List<PhysicalServerResponse> Servers { get; set; }

public static LogicalServerResponse Empty => new()
{
Id = string.Empty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,7 @@ public class PhysicalServerResponse
public string X25519PublicKey;

public string Signature;

public EntryPerProtocolResponse EntryPerProtocol { get; set; }
}
}
4 changes: 2 additions & 2 deletions src/Api/ProtonVPN.Api.Tests/ApiClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
using ProtonVPN.Api.Contracts;
using ProtonVPN.Api.Contracts.Servers;
using ProtonVPN.Common.Configuration;
using ProtonVPN.Logging.Contracts;
using ProtonVPN.Core.Settings;
using ProtonVPN.Logging.Contracts;
using RichardSzalay.MockHttp;

namespace ProtonVPN.Api.Tests
Expand Down Expand Up @@ -78,7 +78,7 @@ public async Task ServerListDownloaded()
Content = new StringContent("{'Code' : '1000', 'Servers': []}")
});

ApiResponseResult<ServersResponse> response = await _apiClient.GetServersAsync("127.0.0.0");
ApiResponseResult<ServersResponse> response = await _apiClient.GetServersAsync(countryCode: "CH", ip: "127.0.0.0");

response.Success.Should().BeTrue();
}
Expand Down
20 changes: 8 additions & 12 deletions src/Api/ProtonVPN.Api/ApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
using ProtonVPN.Api.Contracts.VpnConfig;
using ProtonVPN.Api.Contracts.VpnSessions;
using ProtonVPN.Common.Configuration;
using ProtonVPN.Common.Extensions;
using ProtonVPN.Common.OS.Net.Http;
using ProtonVPN.Common.StatisticalEvents;
using ProtonVPN.Core.Settings;
Expand Down Expand Up @@ -105,19 +104,20 @@ public async Task<ApiResponseResult<BaseResponse>> GetLogoutResponse()
return await SendRequest<BaseResponse>(request, "Logout");
}

public async Task<ApiResponseResult<ServersResponse>> GetServersAsync(string ip)
public async Task<ApiResponseResult<ServersResponse>> GetServersAsync(string countryCode, string ip)
{
HttpRequestMessage request = GetAuthorizedRequest(HttpMethod.Get,
"vpn/logicals?SignServer=Server.EntryIP,Server.Label", ip);
HttpRequestMessage request = GetAuthorizedRequestWithLocation(HttpMethod.Get, "vpn/logicals?" +
"SignServer=Server.EntryIP,Server.Label&" +
"WithEntriesForProtocols=WireGuardUDP,WireGuardTCP,WireGuardTLS,OpenVPNUDP,OpenVPNTCP", countryCode, ip);
request.SetRetryCount(SERVERS_RETRY_COUNT);
request.SetCustomTimeout(TimeSpan.FromSeconds(SERVERS_TIMEOUT_IN_SECONDS));
request.Headers.IfModifiedSince = AppSettings.LogicalsLastModifiedDate;
return await SendRequest<ServersResponse>(request, "Get servers");
}

public async Task<ApiResponseResult<ServersResponse>> GetServerLoadsAsync(string ip)
public async Task<ApiResponseResult<ServersResponse>> GetServerLoadsAsync(string countryCode, string ip)
{
HttpRequestMessage request = GetAuthorizedRequest(HttpMethod.Get, "vpn/loads", ip);
HttpRequestMessage request = GetAuthorizedRequestWithLocation(HttpMethod.Get, "vpn/loads", countryCode, ip);
return await SendRequest<ServersResponse>(request, "Get server loads");
}

Expand Down Expand Up @@ -163,13 +163,9 @@ public async Task<ApiResponseResult<SessionsResponse>> GetSessions()
return await SendRequest<SessionsResponse>(request, "Get sessions");
}

public async Task<ApiResponseResult<VpnConfigResponse>> GetVpnConfig(string country, string ip)
public async Task<ApiResponseResult<VpnConfigResponse>> GetVpnConfig(string countryCode, string ip)
{
HttpRequestMessage request = GetAuthorizedRequest(HttpMethod.Get, "vpn/v2/clientconfig", ip);
if (!country.IsNullOrEmpty())
{
request.Headers.Add("x-pm-country", country);
}
HttpRequestMessage request = GetAuthorizedRequestWithLocation(HttpMethod.Get, "vpn/v2/clientconfig", countryCode, ip);
return await SendRequest<VpnConfigResponse>(request, "Get VPN config");
}

Expand Down
6 changes: 5 additions & 1 deletion src/Api/ProtonVPN.Api/BaseApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,13 @@ protected HttpRequestMessage GetAuthorizedRequest(HttpMethod method, string requ
return request;
}

protected HttpRequestMessage GetAuthorizedRequest(HttpMethod method, string requestUri, string ip)
protected HttpRequestMessage GetAuthorizedRequestWithLocation(HttpMethod method, string requestUri, string countryCode, string ip)
{
HttpRequestMessage request = GetAuthorizedRequest(method, requestUri);
if (!countryCode.IsNullOrEmpty())
{
request.Headers.Add("x-pm-country", countryCode);
}
if (!ip.IsNullOrEmpty())
{
request.Headers.Add("x-pm-netzone", ip);
Expand Down
18 changes: 18 additions & 0 deletions src/Api/ProtonVPN.Api/Handlers/LoggingHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
*/

using System;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using ProtonVPN.Common.Extensions;
Expand Down Expand Up @@ -47,8 +49,18 @@ protected override async Task<HttpResponseMessage> SendAsync(
try
{
_logger.Info<ApiRequestLog>(req);

#if DEBUG
LogHttpHeaders($"{req} request", request.Headers);
#endif

HttpResponseMessage result = await base.SendAsync(request, cancellationToken);
_logger.Info<ApiResponseLog>($"{req}: {(int)result.StatusCode} {result.StatusCode}");

#if DEBUG
LogHttpHeaders($"{req} response", result.Headers);
#endif

return result;
}
catch (Exception ex)
Expand All @@ -57,5 +69,11 @@ protected override async Task<HttpResponseMessage> SendAsync(
throw;
}
}

private void LogHttpHeaders(string req, HttpHeaders headers)
{
string mergedHeaders = string.Join(',', headers.Select(kvp => $"{kvp.Key}: [{string.Join("],[", kvp.Value)}]"));
_logger.Debug<ApiRequestLog>($"{req} headers: {mergedHeaders}");
}
}
}
4 changes: 2 additions & 2 deletions src/GlobalAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: AssemblyVersion("3.4.3.0")]
[assembly: AssemblyFileVersion("3.4.3.0")]
[assembly: AssemblyVersion("3.5.0.0")]
[assembly: AssemblyFileVersion("3.5.0.0")]
[assembly: ComVisible(false)]
[assembly: AssemblyInformationalVersion("$AssemblyVersion")]
[assembly: SupportedOSPlatform("windows")]
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,8 @@ public class VpnServerIpcEntity

[DataMember(Order = 5)]
public string Signature { get; set; }

[DataMember(Order = 6)]
public Dictionary<VpnProtocolIpcEntity, string> RelayIpByProtocol { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

using Microsoft.VisualStudio.TestTools.UnitTesting;
using NSubstitute;
using ProtonVPN.Common.Networking;
using ProtonVPN.Common.Vpn;
using ProtonVPN.Crypto;
using ProtonVPN.EntityMapping.Contracts;
Expand Down Expand Up @@ -50,6 +51,11 @@ public void Initialize()
_expectedPublicKey = new PublicKey("PVPN", KeyAlgorithm.Unknown);
_entityMapper.Map<ServerPublicKeyIpcEntity, PublicKey>(Arg.Any<ServerPublicKeyIpcEntity>())
.Returns(_expectedPublicKey);

_entityMapper.Map<VpnProtocol, VpnProtocolIpcEntity>(Arg.Any<VpnProtocol>())
.Returns(x => (VpnProtocolIpcEntity)(int)x.Arg<VpnProtocol>());
_entityMapper.Map<VpnProtocolIpcEntity, VpnProtocol>(Arg.Any<VpnProtocolIpcEntity>())
.Returns(x => (VpnProtocol)(int)x.Arg<VpnProtocolIpcEntity>());
}

[TestCleanup]
Expand All @@ -63,14 +69,15 @@ public void Cleanup()
}

[TestMethod]
public void TestMapLeftToRight()
public void TestMapLeftToRight_WithNullRelayIpByProtocol()
{
VpnHost entityToTest = new(
name: "protonvpn.com",
ip: "192.168.0.0",
label: DateTime.UtcNow.Millisecond.ToString(),
x25519PublicKey: new PublicKey("PVPN", KeyAlgorithm.Unknown),
signature: DateTime.UtcNow.Ticks.ToString());
signature: DateTime.UtcNow.Ticks.ToString(),
relayIpByProtocol: null);

VpnServerIpcEntity result = _mapper.Map(entityToTest);

Expand All @@ -80,6 +87,45 @@ public void TestMapLeftToRight()
Assert.AreEqual(entityToTest.Label, result.Label);
Assert.AreEqual(_expectedServerPublicKeyIpcEntity, result.X25519PublicKey);
Assert.AreEqual(entityToTest.Signature, result.Signature);
Assert.IsNull(result.RelayIpByProtocol);
}

[TestMethod]
public void TestMapLeftToRight_WithRelayIpByProtocol()
{
Dictionary<VpnProtocol, string> relayIpByProtocol = new()
{
{ VpnProtocol.WireGuardUdp, "1.1.1.1" },
{ VpnProtocol.WireGuardTcp, "2.2.2.2" },
{ VpnProtocol.WireGuardTls, "3.3.3.3" },
{ VpnProtocol.OpenVpnUdp, "4.4.4.4" },
{ VpnProtocol.OpenVpnTcp, "5.5.5.5" }
};

VpnHost entityToTest = new(
name: "protonvpn.com",
ip: "192.168.0.0",
label: DateTime.UtcNow.Millisecond.ToString(),
x25519PublicKey: new PublicKey("PVPN", KeyAlgorithm.Unknown),
signature: DateTime.UtcNow.Ticks.ToString(),
relayIpByProtocol: relayIpByProtocol);

VpnServerIpcEntity result = _mapper.Map(entityToTest);

Assert.IsNotNull(result);
Assert.AreEqual(entityToTest.Name, result.Name);
Assert.AreEqual(entityToTest.Ip, result.Ip);
Assert.AreEqual(entityToTest.Label, result.Label);
Assert.AreEqual(_expectedServerPublicKeyIpcEntity, result.X25519PublicKey);
Assert.AreEqual(entityToTest.Signature, result.Signature);

Assert.IsNotNull(result.RelayIpByProtocol);
Assert.AreEqual(relayIpByProtocol.Count, result.RelayIpByProtocol.Count);
Assert.AreEqual(relayIpByProtocol[VpnProtocol.WireGuardUdp], result.RelayIpByProtocol[VpnProtocolIpcEntity.WireGuardUdp]);
Assert.AreEqual(relayIpByProtocol[VpnProtocol.WireGuardTcp], result.RelayIpByProtocol[VpnProtocolIpcEntity.WireGuardTcp]);
Assert.AreEqual(relayIpByProtocol[VpnProtocol.WireGuardTls], result.RelayIpByProtocol[VpnProtocolIpcEntity.WireGuardTls]);
Assert.AreEqual(relayIpByProtocol[VpnProtocol.OpenVpnUdp], result.RelayIpByProtocol[VpnProtocolIpcEntity.OpenVpnUdp]);
Assert.AreEqual(relayIpByProtocol[VpnProtocol.OpenVpnTcp], result.RelayIpByProtocol[VpnProtocolIpcEntity.OpenVpnTcp]);
}

[TestMethod]
Expand Down
Loading

0 comments on commit 3bfedb3

Please sign in to comment.