File Coverage

lib/Wireguard/WGmeta/Cli/Commands/Add.pm
Criterion Covered Total %
statement 21 81 25.9
branch 0 20 0.0
condition n/a
subroutine 7 11 63.6
pod 2 2 100.0
total 30 114 26.3


line stmt bran cond sub pod time code
1             package Wireguard::WGmeta::Cli::Commands::Add;
2 1     1   7 use strict;
  1         3  
  1         35  
3 1     1   5 use warnings FATAL => 'all';
  1         2  
  1         34  
4              
5 1     1   6 use experimental 'signatures';
  1         1  
  1         9  
6              
7 1     1   84 use parent 'Wireguard::WGmeta::Cli::Commands::Command';
  1         2  
  1         16  
8              
9 1     1   81 use Wireguard::WGmeta::Wrapper::Bridge;
  1         2  
  1         75  
10 1     1   7 use Wireguard::WGmeta::ValidAttributes;
  1         2  
  1         133  
11 1     1   8 use Wireguard::WGmeta::Parser::Middleware;
  1         2  
  1         876  
12              
13 0     0 1   sub entry_point($self) {
  0            
  0            
14 0 0         if ($self->_retrieve_or_die($self->{input_args}, 0) eq 'help') {
15 0           $self->cmd_help();
16             }
17 0           $self->check_privileges();
18             # read input parameters
19 0           my $len = @{$self->{input_args}};
  0            
20 0           $self->{interface} = $self->_retrieve_or_die($self->{input_args}, 0);
21 0           $self->{ips} = $self->_retrieve_or_die($self->{input_args}, 1);
22 0 0         if ($len > 2) {
23             # We hav additional arguments
24 0           my @additional_args = @{$self->{input_args}}[2 .. $len - 1];
  0            
25 0 0         die 'Uneven number of elements (one pair would be without value!)' if scalar @additional_args % 2 != 0;
26 0           $self->{additional_args} = \@additional_args;
27             }
28             # generate private/public keypair
29 0           my ($privkey, $pubkey) = gen_keypair();
30 0           $self->{pub_key} = $pubkey;
31 0           $self->{priv_key} = $privkey;
32              
33 0           $self->_run_command();
34             }
35              
36              
37 0     0     sub _run_command($self) {
  0            
  0            
38             my ($iface_privkey, $iface_listen) = $self->wg_meta->add_peer(
39             $self->{interface},
40             $self->{ips},
41             $self->{pub_key}
42 0           );
43             # get pubkey of iface priv-key
44 0           my $iface_pubkey = get_pub_key($iface_privkey);
45              
46             # get interface config
47 0           my %host_interface = $self->wg_meta->get_interface_section($self->{interface}, $self->{interface});
48 0 0         my $fqdn = exists($host_interface{FQDN}) ? $host_interface{FQDN} : 'insert.valid.fqdn.not.valid';
49              
50             # lets create a temporary interface
51 0           $self->wg_meta->add_interface('temp', $self->{ips}, 44544, $self->{priv_key});
52 0           $self->wg_meta->add_peer('temp', '0.0.0.0/0, ::/0', $iface_pubkey);
53 0           $self->wg_meta->set('temp', $iface_pubkey, 'endpoint', "$fqdn:$iface_listen");
54 0 0         if (exists($host_interface{DNSHost})){
55 0           $self->wg_meta->set('temp', 'temp', 'dns', $host_interface{DNSHost});
56             }
57 0           $self->wg_meta->set('temp', $iface_pubkey, 'persistent-keepalive', 25);
58              
59 0     0     my $unknown_handler_temp = sub($attribute, $value) {
  0            
  0            
  0            
60 0           my $prefix = substr $attribute, 0, 1;
61 0 0         $prefix eq '+' ? return (substr $attribute, 1), $value : return $attribute, $value;
62 0           };
63              
64 0 0         if (defined $self->{additional_args}) {
65 0           my @additional_args = @{$self->{additional_args}};
  0            
66 0           for (my $i = 0; $i < scalar @additional_args; $i += 2) {
67 0           my $attribute = $additional_args[$i];
68 0           my $value = $additional_args[$i + 1];
69 0           my $attr_type = get_attr_type($attribute);
70 0 0         if ($attr_type == ATTR_TYPE_IS_WG_META) {
    0          
71 0           $self->wg_meta->set($self->{interface}, $self->{pub_key}, $attribute, $value);
72 0           $self->wg_meta->set('temp', 'temp', $attribute, $value);
73             }
74             elsif ($attr_type == ATTR_TYPE_IS_WG_ORIG_INTERFACE) {
75 0           $self->wg_meta->set('temp', 'temp', $attribute, $value);
76             }
77             else {
78 0           $self->wg_meta->set($self->{interface}, $self->{pub_key}, $attribute, $value, \&Wireguard::WGmeta::Cli::Commands::Command::_unknown_attr_handler);
79 0 0         $self->wg_meta->set('temp', 'temp', $attribute, $value, $unknown_handler_temp) if $attr_type != ATTR_TYPE_IS_WG_ORIG_PEER;
80             }
81              
82             }
83             }
84              
85 0           print "#Generated by wg-meta\n" . $self->wg_meta->create_config('temp', 0);
86             # remove our temp interface again
87 0           $self->wg_meta->remove_interface('temp');
88 0           $self->wg_meta->commit(1);
89             }
90              
91 0     0 1   sub cmd_help($self) {
  0            
  0            
92 0           print "Usage: wg-meta addpeer [attr1 value1] [attr2 value2] ...\n\n"
93             . "Notes: \nAttributes meant to reside in the [Interface] section are only applied to the peer's interface\n"
94             . "wg-meta attributes are applied to the host's peer config and the client interface config\n"
95             . "and finally, attributes meant to be in the [Peer] section are only applied to the host's peer entry.\n\n"
96             . "To automatically fill in dns and endpoint name, make sure #+DNSHost and #+FQDN is present in [Interface]\n"
97             . "Do not forget to reload the configuration afterwards!\n";
98              
99 0           exit();
100             }
101              
102             1;