]> git.ipfire.org Git - people/stevee/ipfire-2.x.git/commitdiff
wireguard.cgi: Dynamically allocate a pool address for clients
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 25 Apr 2024 17:15:53 +0000 (19:15 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 22 Apr 2025 14:48:31 +0000 (16:48 +0200)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
12 files changed:
doc/language_issues.de
doc/language_issues.en
doc/language_issues.es
doc/language_issues.fr
doc/language_issues.it
doc/language_issues.nl
doc/language_issues.pl
doc/language_issues.ru
doc/language_issues.tr
doc/language_missings
html/cgi-bin/wireguard.cgi
langs/en/cgi-bin/en.pl

index c57603fc6475173ab6627ad662ebd862152f6ce2..1dc31d6e7e6d2d87d1b3812fcdf8d2f7189b5b2a 100644 (file)
@@ -1051,6 +1051,7 @@ WARNING: untranslated string: wg invalid remote subnet = Invalid remote subnet
 WARNING: untranslated string: wg keepalive interval = Keepalive Interval
 WARNING: untranslated string: wg name is already used = The name is already in use
 WARNING: untranslated string: wg no local subnets = No local subnets given
+WARNING: untranslated string: wg no more free addresses in pool = No more free addresses in pool
 WARNING: untranslated string: wg no remote subnets = No remote subnets given
 WARNING: untranslated string: wg peer configuration = Peer Configuration
 WARNING: untranslated string: wg peer does not exist = Peer does not exist
index 5ddce9b817eecc795efc2dba8fe3be47bbc287c4..49d51e046016139a66fecd0c189d16d46a109fbd 100644 (file)
@@ -2158,6 +2158,7 @@ WARNING: untranslated string: wg invalid remote subnet = Invalid remote subnet
 WARNING: untranslated string: wg keepalive interval = Keepalive Interval
 WARNING: untranslated string: wg name is already used = The name is already in use
 WARNING: untranslated string: wg no local subnets = No local subnets given
+WARNING: untranslated string: wg no more free addresses in pool = No more free addresses in pool
 WARNING: untranslated string: wg no remote subnets = No remote subnets given
 WARNING: untranslated string: wg peer configuration = Peer Configuration
 WARNING: untranslated string: wg peer does not exist = Peer does not exist
index 9d2d5d0dd41f4c28322610c92d1076caa5f94ffa..9e6ce3b909a3e3fa223a392aaf4b37f8afe05a79 100644 (file)
@@ -1118,6 +1118,7 @@ WARNING: untranslated string: wg invalid remote subnet = Invalid remote subnet
 WARNING: untranslated string: wg keepalive interval = Keepalive Interval
 WARNING: untranslated string: wg name is already used = The name is already in use
 WARNING: untranslated string: wg no local subnets = No local subnets given
+WARNING: untranslated string: wg no more free addresses in pool = No more free addresses in pool
 WARNING: untranslated string: wg no remote subnets = No remote subnets given
 WARNING: untranslated string: wg peer configuration = Peer Configuration
 WARNING: untranslated string: wg peer does not exist = Peer does not exist
index a7af2c1d04975791c3b68216637edd780acd1e13..f87f98eb7cd38f8a248c39a31eeb1000bc97f226 100644 (file)
@@ -1058,6 +1058,7 @@ WARNING: untranslated string: wg invalid remote subnet = Invalid remote subnet
 WARNING: untranslated string: wg keepalive interval = Keepalive Interval
 WARNING: untranslated string: wg name is already used = The name is already in use
 WARNING: untranslated string: wg no local subnets = No local subnets given
+WARNING: untranslated string: wg no more free addresses in pool = No more free addresses in pool
 WARNING: untranslated string: wg no remote subnets = No remote subnets given
 WARNING: untranslated string: wg peer configuration = Peer Configuration
 WARNING: untranslated string: wg peer does not exist = Peer does not exist
index 069cf7f276891a1f5364384d3419e625b5da239c..e47ac4624d2a50a5dcaee4c77eb8f9f2339c35dd 100644 (file)
@@ -1404,6 +1404,7 @@ WARNING: untranslated string: wg invalid remote subnet = Invalid remote subnet
 WARNING: untranslated string: wg keepalive interval = Keepalive Interval
 WARNING: untranslated string: wg name is already used = The name is already in use
 WARNING: untranslated string: wg no local subnets = No local subnets given
+WARNING: untranslated string: wg no more free addresses in pool = No more free addresses in pool
 WARNING: untranslated string: wg no remote subnets = No remote subnets given
 WARNING: untranslated string: wg peer configuration = Peer Configuration
 WARNING: untranslated string: wg peer does not exist = Peer does not exist
index c49c7ad9a8202a7807934c6b2db7543606b83d5c..832bb3805519b549cf9f68614158eb2cdef6b70b 100644 (file)
@@ -1425,6 +1425,7 @@ WARNING: untranslated string: wg invalid remote subnet = Invalid remote subnet
 WARNING: untranslated string: wg keepalive interval = Keepalive Interval
 WARNING: untranslated string: wg name is already used = The name is already in use
 WARNING: untranslated string: wg no local subnets = No local subnets given
+WARNING: untranslated string: wg no more free addresses in pool = No more free addresses in pool
 WARNING: untranslated string: wg no remote subnets = No remote subnets given
 WARNING: untranslated string: wg peer configuration = Peer Configuration
 WARNING: untranslated string: wg peer does not exist = Peer does not exist
index 5a599ff50e60e9846176529f6d68d9a460412e01..b60fc6e4f9e43831063b161ff70e644bf0aa3312 100644 (file)
@@ -1667,6 +1667,7 @@ WARNING: untranslated string: wg invalid remote subnet = Invalid remote subnet
 WARNING: untranslated string: wg keepalive interval = Keepalive Interval
 WARNING: untranslated string: wg name is already used = The name is already in use
 WARNING: untranslated string: wg no local subnets = No local subnets given
+WARNING: untranslated string: wg no more free addresses in pool = No more free addresses in pool
 WARNING: untranslated string: wg no remote subnets = No remote subnets given
 WARNING: untranslated string: wg peer configuration = Peer Configuration
 WARNING: untranslated string: wg peer does not exist = Peer does not exist
index f70efde448a1bce293b31c86fe089948541b51ca..28e43001ac1ed733601ad3d62e6cf7c7b7ad3345 100644 (file)
@@ -1660,6 +1660,7 @@ WARNING: untranslated string: wg invalid remote subnet = Invalid remote subnet
 WARNING: untranslated string: wg keepalive interval = Keepalive Interval
 WARNING: untranslated string: wg name is already used = The name is already in use
 WARNING: untranslated string: wg no local subnets = No local subnets given
+WARNING: untranslated string: wg no more free addresses in pool = No more free addresses in pool
 WARNING: untranslated string: wg no remote subnets = No remote subnets given
 WARNING: untranslated string: wg peer configuration = Peer Configuration
 WARNING: untranslated string: wg peer does not exist = Peer does not exist
index ba2f4871cb1452d588942d86a7a1379722af46d5..e1c8027ce4622f108d99a8154aa2805224d1ea9f 100644 (file)
@@ -1287,6 +1287,7 @@ WARNING: untranslated string: wg invalid remote subnet = Invalid remote subnet
 WARNING: untranslated string: wg keepalive interval = Keepalive Interval
 WARNING: untranslated string: wg name is already used = The name is already in use
 WARNING: untranslated string: wg no local subnets = No local subnets given
+WARNING: untranslated string: wg no more free addresses in pool = No more free addresses in pool
 WARNING: untranslated string: wg no remote subnets = No remote subnets given
 WARNING: untranslated string: wg peer configuration = Peer Configuration
 WARNING: untranslated string: wg peer does not exist = Peer does not exist
index 10013f2f2f44e80fb49ba2034e5fbef40683c6a2..5d363fe71fd96f854541c0590b419824211bd009 100644 (file)
 < wg keepalive interval
 < wg name is already used
 < wg no local subnets
+< wg no more free addresses in pool
 < wg no remote subnets
 < wg peer configuration
 < wg peer does not exist
 < wg keepalive interval
 < wg name is already used
 < wg no local subnets
+< wg no more free addresses in pool
 < wg no remote subnets
 < wg peer configuration
 < wg peer does not exist
 < wg keepalive interval
 < wg name is already used
 < wg no local subnets
+< wg no more free addresses in pool
 < wg no remote subnets
 < wg peer configuration
 < wg peer does not exist
 < wg keepalive interval
 < wg name is already used
 < wg no local subnets
+< wg no more free addresses in pool
 < wg no remote subnets
 < wg peer configuration
 < wg peer does not exist
 < wg keepalive interval
 < wg name is already used
 < wg no local subnets
+< wg no more free addresses in pool
 < wg no remote subnets
 < wg peer configuration
 < wg peer does not exist
 < wg keepalive interval
 < wg name is already used
 < wg no local subnets
+< wg no more free addresses in pool
 < wg no remote subnets
 < wg peer configuration
 < wg peer does not exist
 < wg keepalive interval
 < wg name is already used
 < wg no local subnets
+< wg no more free addresses in pool
 < wg no remote subnets
 < wg peer configuration
 < wg peer does not exist
 < wg keepalive interval
 < wg name is already used
 < wg no local subnets
+< wg no more free addresses in pool
 < wg no remote subnets
 < wg peer configuration
 < wg peer does not exist
index 8f5cababe8931e8cb7617a9118534f93554403f8..5f84c7a2084bee60cf297a3134bc3ddbf57016ea 100644 (file)
@@ -272,12 +272,16 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) {
        }
 
 } elsif ($cgiparams{"ACTION"} eq "SAVE-PEER-HOST") {
+       my @free_addresses = ();
        my @local_subnets = ();
        my $private_key;
 
        # Fetch or allocate a new key
        my $key = $cgiparams{'KEY'} || &General::findhasharraykey(\%peers);
 
+       # Is this a new connection?
+       my $is_new = !exists $peers{$key};
+
        # Check if the name is valid
        unless (&name_is_valid($cgiparams{"NAME"})) {
                push(@errormessages, $Lang::tr{'wg invalid name'});
@@ -304,12 +308,20 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) {
                push(@errormessages, $Lang::tr{'wg no local subnets'});
        }
 
+       # Check if we have address space left in the pool
+       if ($is_new) {
+               # Fetch the next free address
+               @free_addresses = &free_pool_addresses($settings{'CLIENT_POOL'}, 1);
+
+               # Fail if we ran out of addresses
+               if (scalar @free_addresses == 0) {
+                       push(@errormessages, $Lang::tr{'wg no more free addresses in pool'});
+               }
+       }
+
        # If there are any errors, we go back to the editor
        goto EDITHOST if (scalar @errormessages);
 
-       # Is this a new connection?
-       my $is_new = !exists $peers{$key};
-
        # Generate things for a new peer
        if ($is_new) {
                # Generate a new private key
@@ -321,10 +333,17 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) {
                # Generate a new PSK
                $cgiparams{"PSK"} = &generate_private_key();
 
+               # Fetch a free address from the pool
+               foreach (@free_addresses) {
+                       $cgiparams{'CLIENT_ADDRESS'} = $_;
+                       last;
+               }
+
        # Fetch some configuration parts
        } else {
-               $cgiparams{"PUBLIC_KEY"} = $peers{$key}[3];
-               $cgiparams{"PSK"}        = $peers{$key}[9];
+               $cgiparams{"PUBLIC_KEY"}     = $peers{$key}[3];
+               $cgiparams{'CLIENT_ADDRESS'} = $peers{$key}[6];
+               $cgiparams{"PSK"}            = $peers{$key}[9];
        }
 
        # Save the connection
@@ -342,7 +361,7 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) {
                # 5 = Endpoint Port
                "",
                # 6 = Remote Subnets
-               "", #&encode_subnets(@remote_subnets),
+               $cgiparams{'CLIENT_ADDRESS'},
                # 7 = Remark
                &encode_remarks($cgiparams{"REMARKS"}),
                # 8 = Local Subnets
@@ -1167,6 +1186,49 @@ sub pool_is_in_use($) {
        return 0;
 }
 
+# Takes the pool and an optional limit of up to how many addresses to return
+sub free_pool_addresses($$) {
+       my $pool = shift;
+       my $limit = shift || 0;
+
+       my @used_addresses = ();
+       my @free_addresses = ();
+
+       # Collect all used addresses
+       foreach my $key (keys %peers) {
+               my $type    = $peers{$key}[1];
+               my $address = $peers{$key}[6];
+
+               # Only check hosts
+               next if ($type ne "host");
+
+               push(@used_addresses, &Network::ip2bin($address));
+       }
+
+       # Fetch the first address
+       my $address = &Network::get_netaddress($pool);
+
+       # Fetch the last address
+       my $broadcast = &Network::get_broadcast($pool);
+       $broadcast = &Network::ip2bin($broadcast);
+
+       # Walk through all addresses excluding the first and last address.
+       # No technical reason, we just don't want to confuse people.
+       OUTER: for (my $i = &Network::ip2bin($address) + 1; $i < $broadcast; $i++) {
+               # Skip any addresses that already in use
+               foreach my $used_address (@used_addresses) {
+                       next OUTER if ($i == $used_address);
+               }
+
+               push(@free_addresses, &Network::bin2ip($i));
+
+               # Check limit
+               last if ($limit > 0 && scalar @free_addresses >= $limit);
+       }
+
+       return @free_addresses;
+}
+
 sub generate_client_configuration($) {
        my $peer = shift;
 
index feee700f4aaec0ec75a65fbe35dc7bcc8566731e..754a4ddb7f2beab68e2a6c874608678b6ee04b2a 100644 (file)
 'wg keepalive interval' => 'Keepalive Interval',
 'wg name is already used' => 'The name is already in use',
 'wg no local subnets' => 'No local subnets given',
+'wg no more free addresses in pool' => 'No more free addresses in pool',
 'wg no remote subnets' => 'No remote subnets given',
 'wg peer configuration' => 'Peer Configuration',
 'wg peer does not exist' => 'Peer does not exist',