Skip to content

Commit

Permalink
Merge pull request #13 from sirtoobii/parser2.0
Browse files Browse the repository at this point in the history
Version 0.3.0
  • Loading branch information
sirtoobii authored Jul 2, 2021
2 parents f77c4c4 + bb1af90 commit 8be25f1
Show file tree
Hide file tree
Showing 37 changed files with 1,252 additions and 1,682 deletions.
2 changes: 1 addition & 1 deletion .debian/DEBIAN/control
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: wg-meta
Version: 0.0.3
Version: 0.3.0
Section: base
Priority: optional
Architecture: all
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ Makefile
!*/thirdparty/Makefile.am
!*/thirdparty/cpanfile*snapshot
!*/.debian/Makefile
cover_db
9 changes: 9 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
0.3.0 2021-07-03 Tobias Bossert (tobib at cpan.org)
- changed: CLI: Seamless support for custom attributes (set and addpeer)
- added: CLI: Ability to remove peers
- added: CLI: Machine readable output (dump)
- changed: Core: removed any predefined wg-meta attributes (except alias and checksum)
- changed: Core: Rewrote parser architecture to be more general and extendable
- changed: Tests: Are now not dependent on threads any more
- changed: Wrapper: API of set() and add_peer()

0.2.3 2021-04-15 Tobias Bossert (tobib at cpan.org)
- changed: Commit behaviour when set to overwrite = False
- changed: Adding custom attributes is now possible in code
Expand Down
10 changes: 6 additions & 4 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ AUTHORS
bin/wg-meta
CHANGES
COPYRIGHT
dist.sh
lib/Wireguard/WGmeta.pm
lib/Wireguard/WGmeta/Cli/Commands/Add.pm
lib/Wireguard/WGmeta/Cli/Commands/Apply.pm
lib/Wireguard/WGmeta/Cli/Commands/Command.pm
lib/Wireguard/WGmeta/Cli/Commands/Disable.pm
lib/Wireguard/WGmeta/Cli/Commands/Enable.pm
lib/Wireguard/WGmeta/Cli/Commands/Help.pm
lib/Wireguard/WGmeta/Cli/Commands/Remove.pm
lib/Wireguard/WGmeta/Cli/Commands/Set.pm
lib/Wireguard/WGmeta/Cli/Commands/Show.pm
lib/Wireguard/WGmeta/Cli/Human.pm
lib/Wireguard/WGmeta/Cli/Router.pm
lib/Wireguard/WGmeta/Cli/TerminalHelpers.pm
lib/Wireguard/WGmeta/Index.pod
lib/Wireguard/WGmeta/Parser/Config.pm
lib/Wireguard/WGmeta/Parser/Conf.pm
lib/Wireguard/WGmeta/Parser/Middleware.pm
lib/Wireguard/WGmeta/Parser/Show.pm
lib/Wireguard/WGmeta/Utils.pm
lib/Wireguard/WGmeta/Validator.pm
Expand All @@ -42,7 +43,8 @@ t/test_data/mini_wg0.conf_skip
t/test_data/mini_wg1.conf
t/test_data/not_a_wg_config.conf
t/test_data/wg_show_dump
t/wrapper_test.t
t/wrapper_custom_attrs.t
t/wrapper_secure_mode.t
t/wrapper_test.t
VERSION
wg-meta_completions.sh
wg-meta_completions.sh
2 changes: 2 additions & 0 deletions MANIFEST.SKIP
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ cpanfile
\.perl-version
configure\.ac
^_Deparsed_XSubs\.pm
dist.sh
MANIFEST.bak
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ sudo dpkg -i wg-meta_X.X.X.deb
- `Commands::Set|Enable|Disable` omits the header of the generated configuration files.
- Line of code is shown for warnings and errors.
- `WG_NO_COLOR`: If defined, the show command does not prettify the output with colors.
- `WG_META_NO_WG`: If defined, no wireguard commands are run

## Usage

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.3
0.3.0
54 changes: 36 additions & 18 deletions bin/wg-meta
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,51 @@ An you don't know the best yet: It's fully compatible with your existing setup (
Intended to use as command wrapper for the C<wg show> and C<wg set> commands. Support for C<wg-quick> is enabled by default.
Please note that B<all> attributes have to be specified in the `wg set` _syntax_, which means _AllowedIPs_ becomes
allowed-ips and so on.
allowed-ips and so on. Also all custom attributes have written in the exact same way as they were introduced!
sudo wg-meta show
sudo wg-meta show wg0
# output
interface: wg0
State: UP
ListenPort: 51888
PublicKey: +qz742hzxD3E5z5QF7VOvleVS1onavQpXBK3NdTh40g=
●interface: wg0
private-key: WG_0_PEER_B_PRIVATE_KEY
public-key: wg0d845RRItYcmcEW3i+dqatmja18F2P9ujy+lAtsBM=
listen-port: 51888
fwmark: off
●peer: IPv6_only1
public-key: WG_0_PEER_A_PUBLIC_KEY
preshared-key: PEER_A-PEER_B-PRESHARED_KEY
allowed-ips: fdc9:281f:04d7:9ee9::1/128
endpoint: 147.86.207.49:10400
latest-handshake: >month ago
transfer-rx: 0.26 MiB
transfer-tx: 1.36 MiB
persistent-keepalive: off
# Access using peer (note the '+' before 'name' -> we add a previously unseen attribute)
sudo wg-meta set wg0 peer WG_0_PEER_A_PUBLIC_KEY +name Fancy_meta_name
+peer: WG_0_PEER_A_PUBLIC_KEY
Name: testero
Alias: Dual_stack_peer1
AllowedIPs: fdc9:281f:04d7:9ee9::1/128, 10.0.3.43/32
endpoint: 147.86.207.49:10400 latest-handshake: >month ago transfer-rx: 0.26 MiB transfer-tx: 1.36 MiB
# Access using alias
sudo wg-meta set wg0 IPv6_only1 +description "Some Desc"
# Access using peer
sudo wg-meta set wg0 peer +qz742hzxD3E5z5QF7VOvleVS1onavQpXBK3NdTh40g= name Fancy_meta_name
# Lets check our newly set attributes
sudo wg-meta show wg0 name description
# Access using alias
sudo wg-meta set wg0 some_alias description "Some Desc"
# output
●interface: wg0
name: (none)
description: (none)
●peer: IPv6_only1
name: Fancy_meta_name
description: Some Desc
# Disable peer
sudo wg-meta disable wg0 some_alias
sudo wg-meta disable wg0 IPv6_only1
# Enable peer
sudo wg-meta enable wg0 +qz742hzxD3E5z5QF7VOvleVS1onavQpXBK3NdTh40g=
sudo wg-meta enable wg0 WG_0_PEER_A_PUBLIC_KEY
# Apply config
sudo wg-meta apply wg0
Expand Down Expand Up @@ -101,7 +119,7 @@ use experimental 'signatures';
use Wireguard::WGmeta::Cli::Router;
use Wireguard::WGmeta::Cli::TerminalHelpers;

our $VERSION = "0.0.0";
our $VERSION = "0.3.0";

local $SIG{__WARN__} = sub($message) {
prettify_message($message, 1);
Expand Down
2 changes: 1 addition & 1 deletion lib/Wireguard/WGmeta.pm
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ use strict;
use warnings FATAL => 'all';
package Wireguard::WGmeta;

our $VERSION = "0.0.0"; # Do not change manually
our $VERSION = "0.3.0"; # Do not change manually

1;
77 changes: 51 additions & 26 deletions lib/Wireguard/WGmeta/Cli/Commands/Add.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use experimental 'signatures';
use parent 'Wireguard::WGmeta::Cli::Commands::Command';

use Wireguard::WGmeta::Wrapper::Bridge;
use Wireguard::WGmeta::ValidAttributes;
use Wireguard::WGmeta::Parser::Middleware;

sub entry_point($self) {
if ($self->_retrieve_or_die($self->{input_args}, 0) eq 'help') {
Expand All @@ -16,53 +18,76 @@ sub entry_point($self) {
# read input parameters
my $len = @{$self->{input_args}};
$self->{interface} = $self->_retrieve_or_die($self->{input_args}, 0);
$self->{name} = $self->_retrieve_or_die($self->{input_args}, 1);
$self->{ips} = $self->_retrieve_or_die($self->{input_args}, 2);
if ($len > 3) {
$self->{alias} = $self->_retrieve_or_die($self->{input_args}, 3);
$self->{ips} = $self->_retrieve_or_die($self->{input_args}, 1);
if ($len > 2) {
# We hav additional arguments
my @additional_args = @{$self->{input_args}}[2 .. $len - 1];
die 'Uneven number of elements (one pair would be without value!)' if scalar @additional_args % 2 != 0;
$self->{additional_args} = \@additional_args;
}
# generate private/public keypair
my ($privkey, $pubkey) = gen_keypair();
$self->{pub_key} = $pubkey;
$self->{priv_key} = $privkey;

# would be very nice if we can set a type hint here...possible?
$self->{'wg_meta'} = Wireguard::WGmeta::Wrapper::Config->new($self->{wireguard_home});
$self->_run_command();
}


sub _run_command($self) {
my ($iface_privkey, $iface_listen) = $self->{wg_meta}->add_peer(
my ($iface_privkey, $iface_listen) = $self->wg_meta->add_peer(
$self->{interface},
$self->{name},
$self->{ips},
$self->{pub_key},
$self->{alias}
$self->{pub_key}
);

# get pubkey of iface priv-key
my $iface_pubkey = get_pub_key($iface_privkey);
my $iface_fqdn = $self->{wg_meta}->get_interface_fqdn($self->{interface});
print "# generated by wg-meta
[Interface]
#+Name = $self->{name}
Address = $self->{ips}
ListenPort = 44544
PrivateKey = $self->{priv_key}

[Peer]
PublicKey = $iface_pubkey
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = $iface_fqdn:$iface_listen
PersistentKeepalive = 25
";
# lets create a temporary interface
$self->wg_meta->add_interface('temp', $self->{ips}, 44544, $self->{priv_key});
$self->wg_meta->add_peer('temp', '0.0.0.0/0, ::/0', $iface_pubkey);
$self->wg_meta->set('temp', $iface_pubkey, 'endpoint', "insert.valid.fqdn.not.valid:$iface_listen");
$self->wg_meta->set('temp', $iface_pubkey, 'persistent-keepalive', 25);

my $unknown_handler_temp = sub($attribute, $value) {
my $prefix = substr $attribute, 0, 1;
$prefix eq '+' ? return (substr $attribute, 1), $value : return $attribute, $value;
};

if (defined $self->{additional_args}) {
my @additional_args = @{$self->{additional_args}};
for (my $i = 0; $i < scalar @additional_args; $i += 2) {
my $attribute = $additional_args[$i];
my $value = $additional_args[$i + 1];
my $attr_type = get_attr_type($attribute);
if ($attr_type == ATTR_TYPE_IS_WG_META) {
$self->wg_meta->set($self->{interface}, $self->{pub_key}, $attribute, $value);
$self->wg_meta->set('temp', 'temp', $attribute, $value);
}
elsif ($attr_type == ATTR_TYPE_IS_WG_ORIG_INTERFACE) {
$self->wg_meta->set('temp', 'temp', $attribute, $value);
}
else {
$self->wg_meta->set($self->{interface}, $self->{pub_key}, $attribute, $value, \&Wireguard::WGmeta::Cli::Commands::Command::_unknown_attr_handler);
$self->wg_meta->set('temp', 'temp', $attribute, $value, $unknown_handler_temp) if $attr_type != ATTR_TYPE_IS_WG_ORIG_PEER;
}

$self->{wg_meta}->commit(1);
}
}

print "#Generated by wg-meta\n" . $self->wg_meta->create_config('temp', 0);
# remove our temp interface again
$self->wg_meta->remove_interface('temp');
$self->wg_meta->commit(1);
}

sub cmd_help($self) {
print "Usage: wg-meta addpeer <interface> <name> <ip-address> [alias]\n";
print "Usage: wg-meta addpeer <interface> <ip-address> [attr1 value1] [attr2 value2] ...\n\n"
. "Notes: \nAttributes meant to reside in the [Interface] section are only applied to the peer's interface\n"
. "wg-meta attributes are applied to the host's peer config and the client interface config\n"
. "and finally, attributes meant to be in the [Peer] section are only applied to the host's peer entry\n\n"
. "Do not forget to reload the configuration afterwards!\n";

exit();
}

Expand Down
8 changes: 6 additions & 2 deletions lib/Wireguard/WGmeta/Cli/Commands/Apply.pm
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ sub entry_point($self) {
$self->_run_command();
}

sub _run_command($self){
sub _run_command($self) {
my $interface = $self->_retrieve_or_die($self->{input_args}, 0);

# please note that there ar potential problems with this commend as mentioned here: https://github.com/WireGuard/wireguard-tools/pull/3
my $cmd_line = "su -c 'wg syncconf $interface <(wg-quick strip $interface)'";
run_external($cmd_line);
unless (defined $ENV{WGmeta_NO_WG}) {
run_external($cmd_line);
} else {
print "Faked apply \n";
}
}

sub cmd_help($self) {
Expand Down
18 changes: 17 additions & 1 deletion lib/Wireguard/WGmeta/Cli/Commands/Command.pm
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,20 @@ sub new($class, @input_arguments) {
else {
$self->{wireguard_home} = WIREGUARD_HOME;
}
$self->{wg_meta} = undef;
bless $self, $class;
return $self;
}

#@returns Wireguard::WGmeta::Wrapper::Config
sub wg_meta($self) {
# (sort of) singleton
unless (defined $self->{wg_meta}){
$self->{wg_meta} = Wireguard::WGmeta::Wrapper::Config->new($self->{wireguard_home});
}
return $self->{wg_meta};
}

=head2 entry_point()
Method called from L<Wireguard::WGmeta::Cli::Router/route_command($ref_list_input_args)>
Expand Down Expand Up @@ -109,7 +119,7 @@ Exception if the user has insufficient privileges .
sub check_privileges($self) {
if (not -w $self->{wireguard_home}) {
my $username = getpwuid($<);
die "Insufficient privileges - `$username` has rw no permissions to `$self->{wireguard_home}`. You probably forgot `sudo`";
die "Insufficient privileges - `$username` has no rw permissions to `$self->{wireguard_home}`. You probably forgot `sudo`";
}
}

Expand All @@ -118,4 +128,10 @@ sub _retrieve_or_die($self, $ref_array, $idx) {
eval {return $arr[$idx]} or $self->cmd_help();
}

sub _unknown_attr_handler($attribute, $value) {
my $prefix = substr $attribute, 0, 1;
die "`$attribute` is unknown, please add `+` as prefix to add it" unless $prefix eq '+';
return (substr $attribute, 1), $value;
}

1;
12 changes: 4 additions & 8 deletions lib/Wireguard/WGmeta/Cli/Commands/Disable.pm
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,22 @@ sub entry_point($self) {
$self->cmd_help();
}
$self->check_privileges();
# would be very nice if we can set a type hint here...possible?
$self->{'wg_meta'} = Wireguard::WGmeta::Wrapper::Config->new($self->{wireguard_home});
$self->_run_command();
}


sub _run_command($self) {
my $interface = $self->_retrieve_or_die($self->{input_args}, 0);
my $identifier = $self->_retrieve_or_die($self->{input_args}, 1);
eval {
$identifier = $self->{wg_meta}->translate_alias($interface, $identifier);
};
$self->{wg_meta}->disable($interface, $identifier);
$identifier = $self->wg_meta->try_translate_alias($interface, $identifier);
$self->wg_meta->disable($interface, $identifier);

if (defined $ENV{IS_TESTING}) {
# omit header
$self->{wg_meta}->commit(1, 1);
$self->wg_meta->commit(1, 1);
}
else {
$self->{wg_meta}->commit(1, 0);
$self->wg_meta->commit(1, 0);
}
}

Expand Down
Loading

0 comments on commit 8be25f1

Please sign in to comment.