Skip to content

Commit

Permalink
Merge pull request #113 from micahmo/release/v2.0.10
Browse files Browse the repository at this point in the history
Release/v2.0.10
  • Loading branch information
micahmo authored Apr 19, 2023
2 parents 7375aed + 71b6a52 commit 913f6a2
Show file tree
Hide file tree
Showing 11 changed files with 310 additions and 50 deletions.
6 changes: 3 additions & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project>
<PropertyGroup>
<!-- Keep in sync with WS4WSetupScript.iss and VersionInfo.xml -->
<AssemblyVersion>2.0.9.0</AssemblyVersion>
<FileVersion>2.0.9.0</FileVersion>
<InformationalVersion>2.0.9.0</InformationalVersion>
<AssemblyVersion>2.0.10.0</AssemblyVersion>
<FileVersion>2.0.10.0</FileVersion>
<InformationalVersion>2.0.10.0</InformationalVersion>
<Authors>Micah Morrison</Authors>
<Product>WS4W</Product>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion Installer/WS4WSetupScript.iss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#define MyAppNameOld "WireGuard Server For Windows"
#define MyAppName "Wg Server for Windows"
#define MyAppVersion "2.0.9"
#define MyAppVersion "2.0.10"
#define MyAppPublisher "Micah Morrison"
#define MyAppURL "https://github.com/micahmo/WgServerforWindows"
#define MyAppExeName "WgServerforWindows.exe"
Expand Down
121 changes: 89 additions & 32 deletions WgServerforWindows/Controls/SelectionWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,58 +1,115 @@
<Window x:Class="WgServerforWindows.Controls.SelectionWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:properties="clr-namespace:WgServerforWindows.Properties"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:models="clr-namespace:WgServerforWindows.Models"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:c="clr-namespace:CalcBinding;assembly=CalcBinding"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=models:SelectionWindowModel}"
Title="{Binding Title}" SizeToContent="WidthAndHeight" MaxWidth="350">
<Window
x:Class="WgServerforWindows.Controls.SelectionWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:c="clr-namespace:CalcBinding;assembly=CalcBinding"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="clr-namespace:WgServerforWindows.Models"
xmlns:properties="clr-namespace:WgServerforWindows.Properties"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
Title="{Binding Title}"
MinWidth="{Binding MinWidth}"
MaxWidth="350"
d:DataContext="{d:DesignInstance Type=models:SelectionWindowModel}"
SizeToContent="WidthAndHeight"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="20"/> <!-- Padding -->
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<!-- Padding -->
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<TextBlock Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="0" Margin="20,10,20,10" Text="{Binding Text}" TextWrapping="Wrap"/>
<TextBlock
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="20,10,20,10"
Text="{Binding Text}"
TextWrapping="Wrap" />

<ComboBox Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Margin="20,10,20,10" IsEditable="False"
ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" DisplayMemberPath="DisplayText"
Visibility="{c:Binding IsList, FalseToVisibility=Collapsed}">
<ComboBox
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="20,10,20,10"
DisplayMemberPath="DisplayText"
IsEditable="False"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
Visibility="{c:Binding IsList,
FalseToVisibility=Collapsed}">
<ComboBox.ItemContainerStyle>
<Style>
<Setter Property="Control.ToolTip" Value="{Binding Description}" />
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>

<xctk:DateTimeUpDown Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Margin="20,10,20,10" Format="Custom" FormatString="HH:mm:ss"
Value="{Binding SelectedItem.BackingObject}"
Visibility="{c:Binding IsTimeSpan, FalseToVisibility=Collapsed}"/>
<xctk:DateTimeUpDown
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="20,10,20,10"
Format="Custom"
FormatString="HH:mm:ss"
Visibility="{c:Binding IsTimeSpan,
FalseToVisibility=Collapsed}"
Value="{Binding SelectedItem.BackingObject}" />

<Button Grid.Column="1" Grid.Row="3" Padding="10,5,10,5" Margin="20,10,10,10" Content="{x:Static properties:Resources.Cancel}" Command="{Binding CancelCommand}">
<TextBox
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="20,10,20,10"
Text="{Binding SelectedItem.BackingObject, UpdateSourceTrigger=PropertyChanged, Delay=100}"
Visibility="{c:Binding IsString,
FalseToVisibility=Collapsed}" />

<TextBlock
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="3"
Margin="20,10,20,10"
Foreground="Red"
Text="{Binding ValidationError}"
TextWrapping="Wrap" />

<Button
Grid.Row="4"
Grid.Column="1"
Margin="20,10,10,10"
Padding="10,5,10,5"
Command="{Binding CancelCommand}"
Content="{x:Static properties:Resources.Cancel}">
<b:Interaction.Triggers>
<b:EventTrigger EventName="Click">
<b:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
<b:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
</b:EventTrigger>
</b:Interaction.Triggers>
</Button>
<Button Grid.Column="2" Grid.Row="3" Padding="10,5,10,5" Margin="10,10,20,10" Content="{x:Static properties:Resources.OK}" Command="{Binding SelectCommand}"
IsEnabled="{Binding CanSelect}">
<Button
Grid.Row="4"
Grid.Column="2"
Margin="10,10,20,10"
Padding="10,5,10,5"
Command="{Binding SelectCommand}"
Content="{x:Static properties:Resources.OK}"
IsEnabled="{Binding CanSelect}">
<b:Interaction.Triggers>
<b:EventTrigger EventName="Click">
<b:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
<b:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
</b:EventTrigger>
</b:Interaction.Triggers>
</Button>
Expand Down
4 changes: 3 additions & 1 deletion WgServerforWindows/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public MainWindow()
var privateNetworkTaskSubCommand = new PrivateNetworkTaskSubCommand();
var privateNetworkPrerequisite = new PrivateNetworkPrerequisite(privateNetworkTaskSubCommand);
var netIpAddressTaskSubCommand = new NewNetIpAddressTaskSubCommand();
var newNetNatPrerequisite = new NewNetNatPrerequisite(netIpAddressTaskSubCommand);
var netNatRangeSubCommand = new NetNatRangeSubCommand();
var newNetNatPrerequisite = new NewNetNatPrerequisite(netIpAddressTaskSubCommand, netNatRangeSubCommand);
var internetSharingPrerequisite = new InternetSharingPrerequisite();
var persistentInternetSharingPrerequisite = new PersistentInternetSharingPrerequisite();
var serverStatusPrerequisite = new ServerStatusPrerequisite();
Expand Down Expand Up @@ -98,6 +99,7 @@ public MainWindow()
&& !persistentInternetSharingPrerequisite.Fulfilled;

netIpAddressTaskSubCommand.CanResolveFunc = netIpAddressTaskSubCommand.CanConfigureFunc = () => newNetNatPrerequisite.Fulfilled;
netNatRangeSubCommand.CanConfigureFunc = () => serverConfigurationPrerequisite.Fulfilled;

var natPrerequisiteGroup = new NatPrerequisiteGroup(newNetNatPrerequisite, internetSharingPrerequisite, persistentInternetSharingPrerequisite);

Expand Down
8 changes: 8 additions & 0 deletions WgServerforWindows/Models/GlobalAppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private GlobalAppSettings()
// Set up AppSettings tracking
Tracker.Configure<GlobalAppSettings>()
.Property(a => a.BootTaskDelay)
.Property(a => a.CustomNetNatRange)
.Track(this);
}

Expand All @@ -56,6 +57,13 @@ public TimeSpan BootTaskDelay
}
private TimeSpan _bootTaskDelay;

public string CustomNetNatRange
{
get => _customNetNatRange;
set => Set(nameof(CustomNetNatRange), ref _customNetNatRange, value);
}
private string _customNetNatRange;

/// <summary>
/// The public tracker instance located in Public\Documents. Can be used to track things other than the <see cref="Instance"/>.
/// </summary>
Expand Down
89 changes: 89 additions & 0 deletions WgServerforWindows/Models/NetNatRangeSubCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System.Net;
using SharpConfig;
using WgServerforWindows.Controls;
using WgServerforWindows.Properties;

namespace WgServerforWindows.Models
{
public class NetNatRangeSubCommand : PrerequisiteItem
{
public NetNatRangeSubCommand() : base
(
title: string.Empty,
successMessage: Resources.NetNatRangeSubCommandSuccessMessage,
errorMessage: string.Empty,
resolveText: string.Empty,
configureText: Resources.NewNetNatRangeSubCommandConfigureText
)
{
}

public override void Configure()
{
var serverConfiguration = new ServerConfiguration().Load<ServerConfiguration>(Configuration.LoadFromFile(ServerConfigurationPrerequisite.ServerDataPath));

string networkRange = GlobalAppSettings.Instance.CustomNetNatRange;

var selectionWindowModel = new SelectionWindowModel<string>
{
Title = Resources.NetNatRangeSelectionTitle,
Text = Resources.NetNatRangeSelectionText,
SelectedItem = new SelectionItem<string> { BackingObject = networkRange },
IsList = false,
IsString = true,
MinWidth = 350
};

selectionWindowModel.CanSelectFunc = () =>
{
if (!string.IsNullOrWhiteSpace(selectionWindowModel.SelectedItem.BackingObject))
{
if (!IPNetwork.TryParse(selectionWindowModel.SelectedItem.BackingObject, out _))
{
selectionWindowModel.ValidationError = Resources.NetworkAddressValidationError;
return false;
}
// IPNetwork.TryParse recognizes single IP addresses as CIDR (with 8 mask).
// This is not good, because we want an explicit CIDR for the server.
// Therefore, if IPNetwork.TryParse succeeds, and IPAddress.TryParse also succeeds, we have a problem.
if (IPAddress.TryParse(selectionWindowModel.SelectedItem.BackingObject, out _))
{
// This is just a regular address. We want CIDR.
selectionWindowModel.ValidationError = Resources.NetworkAddressValidationError;
return false;
}

// Ensure that this range contains the server range
IPNetwork netNatRange = IPNetwork.Parse(selectionWindowModel.SelectedItem.BackingObject);
IPNetwork serverRange = IPNetwork.Parse(serverConfiguration.AddressProperty.Value);
if (!netNatRange.Contains(serverRange))
{
selectionWindowModel.ValidationError = string.Format(Resources.NetNatRangeValidationError, serverRange);
return false;
}

// It passed, so we're good.
selectionWindowModel.ValidationError = null;
return true;
}

// It's empty, which is fine.
selectionWindowModel.ValidationError = null;
return true;
};

new SelectionWindow
{
DataContext = selectionWindowModel
}.ShowDialog();

if (selectionWindowModel.DialogResult == true)
{
GlobalAppSettings.Instance.CustomNetNatRange = selectionWindowModel.SelectedItem.BackingObject;
GlobalAppSettings.Instance.Save();

Refresh();
}
}
}
}
25 changes: 21 additions & 4 deletions WgServerforWindows/Models/NewNetNatPrerequisite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public class NewNetNatPrerequisite : PrerequisiteItem
{
#region PrerequisiteItem members

public NewNetNatPrerequisite() : this(new NewNetIpAddressTaskSubCommand()) { }
public NewNetNatPrerequisite() : this(new NewNetIpAddressTaskSubCommand(), new NetNatRangeSubCommand()) { }

public NewNetNatPrerequisite(NewNetIpAddressTaskSubCommand newNetIpAddressTaskSubCommand) : base
public NewNetNatPrerequisite(NewNetIpAddressTaskSubCommand newNetIpAddressTaskSubCommand, NetNatRangeSubCommand netNatRangeSubCommand) : base
(
title: Resources.NewNatName,
successMessage: Resources.NewNetSuccess,
Expand All @@ -28,6 +28,7 @@ public NewNetNatPrerequisite(NewNetIpAddressTaskSubCommand newNetIpAddressTaskSu
{
_newNetIpAddressTaskSubCommand = newNetIpAddressTaskSubCommand;
SubCommands.Add(_newNetIpAddressTaskSubCommand);
SubCommands.Add(netNatRangeSubCommand);
}

public override BooleanTimeCachedProperty Fulfilled => _fulfilled ??= new BooleanTimeCachedProperty(TimeSpan.FromSeconds(1), () =>
Expand All @@ -52,7 +53,7 @@ public NewNetNatPrerequisite(NewNetIpAddressTaskSubCommand newNetIpAddressTaskSu
$"-NoProfile Get-NetNat -Name {_netNatName}"),
out int exitCode);

result &= exitCode == 0 && output.Contains(serverConfiguration.AddressProperty.Value);
result &= exitCode == 0 && output.Contains(GetDesiredAddressRange(serverConfiguration));

// Verify the interface's IP address is correct
output = new WireGuardExe().ExecuteCommand(new WireGuardCommand(string.Empty, WhichExe.Custom,
Expand Down Expand Up @@ -107,7 +108,7 @@ public void Resolve(string serverDataPath)
// Create the NAT routing rule
output = new WireGuardExe().ExecuteCommand(new WireGuardCommand(string.Empty, WhichExe.Custom,
"powershell.exe",
$"-NoProfile New-NetNat -Name {_netNatName} -InternalIPInterfaceAddressPrefix {serverConfiguration.AddressProperty.Value}"),
$"-NoProfile New-NetNat -Name {_netNatName} -InternalIPInterfaceAddressPrefix {GetDesiredAddressRange(serverConfiguration)}"),
out exitCode);

if (exitCode != 0)
Expand Down Expand Up @@ -195,6 +196,22 @@ public override void Configure()

#endregion

#region Private methods

private string GetDesiredAddressRange(ServerConfiguration serverConfiguration)
{
if (!string.IsNullOrEmpty(GlobalAppSettings.Instance.CustomNetNatRange))
{
return GlobalAppSettings.Instance.CustomNetNatRange;
}
else
{
return serverConfiguration.AddressProperty.Value;
}
}

#endregion

#region Public properties

public bool IsSupported
Expand Down
Loading

0 comments on commit 913f6a2

Please sign in to comment.