merge: branch 'bg/nmcli-wg-peers'
nmcli: allow setting the wireguard peers https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2220
This commit is contained in:
1
NEWS
1
NEWS
@@ -8,6 +8,7 @@ subject to change and not guaranteed to be compatible with
|
|||||||
the later release.
|
the later release.
|
||||||
USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
|
USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
|
||||||
|
|
||||||
|
* nmcli now supports viewing and managing WireGuard peers.
|
||||||
|
|
||||||
=============================================
|
=============================================
|
||||||
NetworkManager-1.54
|
NetworkManager-1.54
|
||||||
|
@@ -234,6 +234,227 @@ test_team_link_watcher_tofro_string(void)
|
|||||||
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE);
|
NM_TEAM_LINK_WATCHER_ARP_PING_FLAG_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_wireguard_peer(void)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
struct {
|
||||||
|
const char *input;
|
||||||
|
const char *canonical; /* canonical string representation */
|
||||||
|
|
||||||
|
gboolean invalid;
|
||||||
|
const char *pubkey;
|
||||||
|
const char *endpoint;
|
||||||
|
guint16 keepalive;
|
||||||
|
guint num_allowed_ips;
|
||||||
|
const char *allowed_ips[2];
|
||||||
|
const char *psk;
|
||||||
|
int psk_flags;
|
||||||
|
} tests[] = {{
|
||||||
|
/* Public key only */
|
||||||
|
.input = "MWEKYcE9MEh5RoGDuJYrJ2YgkoosONGhuHRBAC00e14=",
|
||||||
|
.canonical = "MWEKYcE9MEh5RoGDuJYrJ2YgkoosONGhuHRBAC00e14=",
|
||||||
|
.pubkey = "MWEKYcE9MEh5RoGDuJYrJ2YgkoosONGhuHRBAC00e14=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* IPv4 endpoint */
|
||||||
|
.input = "+DIX0qWKQ4E6hy7MWzsSRXjqAHCtffWrXTdJPe/xS04="
|
||||||
|
" endpoint=1.2.3.4:5555",
|
||||||
|
.canonical = "+DIX0qWKQ4E6hy7MWzsSRXjqAHCtffWrXTdJPe/xS04="
|
||||||
|
" endpoint=1.2.3.4:5555",
|
||||||
|
.pubkey = "+DIX0qWKQ4E6hy7MWzsSRXjqAHCtffWrXTdJPe/xS04=",
|
||||||
|
.endpoint = "1.2.3.4:5555",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* IPv6 endpoint */
|
||||||
|
.input = "aPsdPkeqH4l5Nax3g3e8A8f7g0hJk2l3m4N5p6q7R8s="
|
||||||
|
" endpoint=[fd01:db8::1]:8080",
|
||||||
|
.canonical = "aPsdPkeqH4l5Nax3g3e8A8f7g0hJk2l3m4N5p6q7R8s="
|
||||||
|
" endpoint=[fd01:db8::1]:8080",
|
||||||
|
.pubkey = "aPsdPkeqH4l5Nax3g3e8A8f7g0hJk2l3m4N5p6q7R8s=",
|
||||||
|
.endpoint = "[fd01:db8::1]:8080",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* IPv6 endpoint, without brackets */
|
||||||
|
.input = "+DIX0qWKQ4E6hy7MWzsSRXjqAHCtffWrXTdJPe/xS04="
|
||||||
|
" endpoint=fd01::12:8080",
|
||||||
|
.canonical = "+DIX0qWKQ4E6hy7MWzsSRXjqAHCtffWrXTdJPe/xS04="
|
||||||
|
" endpoint=fd01::12:8080",
|
||||||
|
.pubkey = "+DIX0qWKQ4E6hy7MWzsSRXjqAHCtffWrXTdJPe/xS04=",
|
||||||
|
.endpoint = "fd01::12:8080",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Single IPv4 allowed-ip */
|
||||||
|
.input = "s4fmZZA3gMGVv8+0hkSwrmeLC6nNd+Pd6DlSaufLKhY="
|
||||||
|
" allowed-ips=172.16.0.0/16",
|
||||||
|
.canonical = "s4fmZZA3gMGVv8+0hkSwrmeLC6nNd+Pd6DlSaufLKhY="
|
||||||
|
" allowed-ips=172.16.0.0/16",
|
||||||
|
.pubkey = "s4fmZZA3gMGVv8+0hkSwrmeLC6nNd+Pd6DlSaufLKhY=",
|
||||||
|
.num_allowed_ips = 1,
|
||||||
|
.allowed_ips = {"172.16.0.0/16"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Multiple allowed-ips */
|
||||||
|
.input = "V02J2zmCi2LHX2KMK+ZOgDNhZzK4JXjGNr7CYfz9DxQ="
|
||||||
|
" allowed-ips=192.168.2.0/24;2001:db8:a::/48",
|
||||||
|
.canonical = "V02J2zmCi2LHX2KMK+ZOgDNhZzK4JXjGNr7CYfz9DxQ="
|
||||||
|
" allowed-ips=192.168.2.0/24;2001:db8:a::/48",
|
||||||
|
.pubkey = "V02J2zmCi2LHX2KMK+ZOgDNhZzK4JXjGNr7CYfz9DxQ=",
|
||||||
|
.num_allowed_ips = 2,
|
||||||
|
.allowed_ips = {"192.168.2.0/24", "2001:db8:a::/48"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Persistent-keepalive */
|
||||||
|
.input = "D1FTp8Wy1oJQI045yXo9EMdxJqjXHC3VhTCPTh3lSQM="
|
||||||
|
" persistent-keepalive=25",
|
||||||
|
.canonical = "D1FTp8Wy1oJQI045yXo9EMdxJqjXHC3VhTCPTh3lSQM="
|
||||||
|
" persistent-keepalive=25",
|
||||||
|
.pubkey = "D1FTp8Wy1oJQI045yXo9EMdxJqjXHC3VhTCPTh3lSQM=",
|
||||||
|
.keepalive = 25,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Preshared-key without flags (should default to 0) */
|
||||||
|
.input = "H5cWWgpWgJH+nHFhsuPS3adgZHuc6Z4cRzfiNRTinE0="
|
||||||
|
" preshared-key=16uGwZvROnwyNGoW6Z3pvJB5GKbd6ncYROA/FFleLQA=",
|
||||||
|
.canonical = "H5cWWgpWgJH+nHFhsuPS3adgZHuc6Z4cRzfiNRTinE0="
|
||||||
|
" preshared-key=16uGwZvROnwyNGoW6Z3pvJB5GKbd6ncYROA/FFleLQA="
|
||||||
|
" preshared-key-flags=0",
|
||||||
|
.pubkey = "H5cWWgpWgJH+nHFhsuPS3adgZHuc6Z4cRzfiNRTinE0=",
|
||||||
|
.psk = "16uGwZvROnwyNGoW6Z3pvJB5GKbd6ncYROA/FFleLQA=",
|
||||||
|
.psk_flags = 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Preshared-key flags as string */
|
||||||
|
.input = "H5cWWgpWgJH+nHFhsuPS3adgZHuc6Z4cRzfiNRTinE0="
|
||||||
|
" preshared-key=16uGwZvROnwyNGoW6Z3pvJB5GKbd6ncYROA/FFleLQA="
|
||||||
|
" preshared-key-flags=not-saved",
|
||||||
|
.canonical = "H5cWWgpWgJH+nHFhsuPS3adgZHuc6Z4cRzfiNRTinE0="
|
||||||
|
" preshared-key=16uGwZvROnwyNGoW6Z3pvJB5GKbd6ncYROA/FFleLQA="
|
||||||
|
" preshared-key-flags=2",
|
||||||
|
.pubkey = "H5cWWgpWgJH+nHFhsuPS3adgZHuc6Z4cRzfiNRTinE0=",
|
||||||
|
.psk = "16uGwZvROnwyNGoW6Z3pvJB5GKbd6ncYROA/FFleLQA=",
|
||||||
|
.psk_flags = 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Non-canonical order and extra whitespaces */
|
||||||
|
.input = "gqQ9dUqKQNfz/KOqELJpS0MKBvRcYWL8sm/LGEWKKQY="
|
||||||
|
" preshared-key=EVVP8pOzn8R3nQtv62/hnGsXzyagEgykSboFe4EFhQc="
|
||||||
|
" endpoint=vpn.example.com:51820 "
|
||||||
|
" preshared-key-flags=1"
|
||||||
|
" persistent-keepalive=45"
|
||||||
|
" allowed-ips=0.0.0.0/0;::/0",
|
||||||
|
.canonical = "gqQ9dUqKQNfz/KOqELJpS0MKBvRcYWL8sm/LGEWKKQY="
|
||||||
|
" allowed-ips=0.0.0.0/0;::/0"
|
||||||
|
" endpoint=vpn.example.com:51820"
|
||||||
|
" persistent-keepalive=45"
|
||||||
|
" preshared-key=EVVP8pOzn8R3nQtv62/hnGsXzyagEgykSboFe4EFhQc="
|
||||||
|
" preshared-key-flags=1",
|
||||||
|
.pubkey = "gqQ9dUqKQNfz/KOqELJpS0MKBvRcYWL8sm/LGEWKKQY=",
|
||||||
|
.endpoint = "vpn.example.com:51820",
|
||||||
|
.keepalive = 45,
|
||||||
|
.num_allowed_ips = 2,
|
||||||
|
.allowed_ips = {"0.0.0.0/0", "::/0"},
|
||||||
|
.psk = "EVVP8pOzn8R3nQtv62/hnGsXzyagEgykSboFe4EFhQc=",
|
||||||
|
.psk_flags = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Empty string */
|
||||||
|
.input = "",
|
||||||
|
.invalid = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Invalid public key*/
|
||||||
|
.input = "aaaaaaaaaaaaaaaaaaaaaaa=",
|
||||||
|
.invalid = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Missing value*/
|
||||||
|
.input = "gqQ9dUqKQNfz/KOqELJpS0MKBvRcYWL8sm/LGEWKKQY= "
|
||||||
|
"persistent-keepalive=",
|
||||||
|
.invalid = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Unknown attribute */
|
||||||
|
.input = "gqQ9dUqKQNfz/KOqELJpS0MKBvRcYWL8sm/LGEWKKQY= "
|
||||||
|
"persistent-keepalive=12 foobarness=13",
|
||||||
|
.invalid = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Invalid IPv4 allowed-ip*/
|
||||||
|
.input = "gqQ9dUqKQNfz/KOqELJpS0MKBvRcYWL8sm/LGEWKKQY= "
|
||||||
|
"allowed-ips=192.168.10.256/32",
|
||||||
|
.invalid = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Invalid IPv6 allowed-ip */
|
||||||
|
.input = "gqQ9dUqKQNfz/KOqELJpS0MKBvRcYWL8sm/LGEWKKQY= "
|
||||||
|
"allowed-ips=fd01::1::3/64",
|
||||||
|
.invalid = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Endpoint with no port */
|
||||||
|
.input = "+DIX0qWKQ4E6hy7MWzsSRXjqAHCtffWrXTdJPe/xS04="
|
||||||
|
" endpoint=1.2.3.4",
|
||||||
|
.invalid = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Invalid endpoint */
|
||||||
|
.input = "+DIX0qWKQ4E6hy7MWzsSRXjqAHCtffWrXTdJPe/xS04="
|
||||||
|
" endpoint=1.2.3.5.6",
|
||||||
|
.invalid = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Invalid persistent-keepalive */
|
||||||
|
.input = "gqQ9dUqKQNfz/KOqELJpS0MKBvRcYWL8sm/LGEWKKQY= "
|
||||||
|
"persistent-keepalive=yes",
|
||||||
|
.invalid = TRUE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Invalid PSK */
|
||||||
|
.input = "gqQ9dUqKQNfz/KOqELJpS0MKBvRcYWL8sm/LGEWKKQY="
|
||||||
|
" preshared-key=pskpskpskpskpskpskpskpskpskpskpskpsk",
|
||||||
|
.invalid = TRUE,
|
||||||
|
}};
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS(tests); i++) {
|
||||||
|
nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL;
|
||||||
|
gs_free_error GError *error = NULL;
|
||||||
|
gs_free char *newstr = NULL;
|
||||||
|
guint j;
|
||||||
|
|
||||||
|
peer = _nm_utils_wireguard_peer_from_string(tests[i].input, &error);
|
||||||
|
if (tests[i].invalid) {
|
||||||
|
g_assert(!peer);
|
||||||
|
g_assert(error);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
g_assert_no_error(error);
|
||||||
|
g_assert_nonnull(peer);
|
||||||
|
|
||||||
|
newstr = _nm_utils_wireguard_peer_to_string(peer);
|
||||||
|
g_assert_nonnull(newstr);
|
||||||
|
g_assert_cmpstr(tests[i].canonical, ==, newstr);
|
||||||
|
|
||||||
|
g_assert_cmpstr(tests[i].pubkey, ==, nm_wireguard_peer_get_public_key(peer));
|
||||||
|
g_assert_cmpstr(tests[i].endpoint, ==, nm_wireguard_peer_get_endpoint(peer));
|
||||||
|
|
||||||
|
g_assert_cmpint(tests[i].num_allowed_ips, ==, nm_wireguard_peer_get_allowed_ips_len(peer));
|
||||||
|
for (j = 0; j < tests[i].num_allowed_ips; j++) {
|
||||||
|
g_assert_cmpstr(tests[i].allowed_ips[j],
|
||||||
|
==,
|
||||||
|
nm_wireguard_peer_get_allowed_ip(peer, j, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_cmpint(tests[i].keepalive, ==, nm_wireguard_peer_get_persistent_keepalive(peer));
|
||||||
|
g_assert_cmpstr(tests[i].psk, ==, nm_wireguard_peer_get_preshared_key(peer));
|
||||||
|
if (tests[i].psk) {
|
||||||
|
g_assert_cmpint(tests[i].psk_flags,
|
||||||
|
==,
|
||||||
|
nm_wireguard_peer_get_preshared_key_flags(peer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
NMTST_DEFINE();
|
NMTST_DEFINE();
|
||||||
@@ -245,6 +466,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
g_test_add_func("/libnm-core-aux/test_team_link_watcher_tofro_string",
|
g_test_add_func("/libnm-core-aux/test_team_link_watcher_tofro_string",
|
||||||
test_team_link_watcher_tofro_string);
|
test_team_link_watcher_tofro_string);
|
||||||
|
g_test_add_func("/libnm-core-aux/test-wireguard-peer", test_wireguard_peer);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "nm-libnm-core-aux.h"
|
#include "nm-libnm-core-aux.h"
|
||||||
|
|
||||||
|
#include "nm-errors.h"
|
||||||
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
|
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
|
||||||
#include "libnm-glib-aux/nm-str-buf.h"
|
#include "libnm-glib-aux/nm-str-buf.h"
|
||||||
|
|
||||||
@@ -475,3 +476,177 @@ _nm_ip_route_to_string(NMIPRoute *route, NMStrBuf *strbuf)
|
|||||||
nm_str_buf_append_printf(strbuf, " metric %" G_GINT64_FORMAT, metric);
|
nm_str_buf_append_printf(strbuf, " metric %" G_GINT64_FORMAT, metric);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
char *
|
||||||
|
_nm_utils_wireguard_peer_to_string(NMWireGuardPeer *peer)
|
||||||
|
{
|
||||||
|
GString *str;
|
||||||
|
const char *endpoint;
|
||||||
|
const char *psk;
|
||||||
|
guint16 keepalive;
|
||||||
|
guint i;
|
||||||
|
guint len;
|
||||||
|
|
||||||
|
g_return_val_if_fail(peer, "");
|
||||||
|
|
||||||
|
nm_assert(nm_wireguard_peer_is_valid(peer, TRUE, TRUE, NULL));
|
||||||
|
|
||||||
|
str = g_string_new("");
|
||||||
|
g_string_append(str, nm_wireguard_peer_get_public_key(peer));
|
||||||
|
|
||||||
|
len = nm_wireguard_peer_get_allowed_ips_len(peer);
|
||||||
|
if (len > 0) {
|
||||||
|
g_string_append(str, " allowed-ips=");
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
g_string_append(str, nm_wireguard_peer_get_allowed_ip(peer, i, NULL));
|
||||||
|
if (i < len - 1)
|
||||||
|
g_string_append(str, ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint = nm_wireguard_peer_get_endpoint(peer);
|
||||||
|
if (endpoint) {
|
||||||
|
g_string_append_printf(str, " endpoint=%s", endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
keepalive = nm_wireguard_peer_get_persistent_keepalive(peer);
|
||||||
|
if (keepalive != 0) {
|
||||||
|
g_string_append_printf(str, " persistent-keepalive=%hu", keepalive);
|
||||||
|
}
|
||||||
|
|
||||||
|
psk = nm_wireguard_peer_get_preshared_key(peer);
|
||||||
|
if (psk) {
|
||||||
|
g_string_append_printf(str, " preshared-key=%s", psk);
|
||||||
|
g_string_append_printf(str,
|
||||||
|
" preshared-key-flags=%u",
|
||||||
|
(guint) nm_wireguard_peer_get_preshared_key_flags(peer));
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_string_free(str, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NMWireGuardPeer *
|
||||||
|
_nm_utils_wireguard_peer_from_string(const char *str, GError **error)
|
||||||
|
{
|
||||||
|
nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL;
|
||||||
|
gs_strfreev char **tokens = NULL;
|
||||||
|
gboolean has_psk = FALSE;
|
||||||
|
gboolean has_psk_flags = FALSE;
|
||||||
|
char *value;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
peer = nm_wireguard_peer_new();
|
||||||
|
|
||||||
|
tokens = g_strsplit_set(str, " ", 0);
|
||||||
|
for (i = 0; tokens[i]; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
if (!nm_wireguard_peer_set_public_key(peer, tokens[i], FALSE)) {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
"invalid public key '%s'",
|
||||||
|
tokens[i]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokens[i][0] == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
value = strchr(tokens[i], '=');
|
||||||
|
if (!value || value[1] == '\0') {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
"attribute without value '%s'",
|
||||||
|
tokens[i]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = '\0';
|
||||||
|
value++;
|
||||||
|
|
||||||
|
if (nm_streq(tokens[i], "allowed-ips")) {
|
||||||
|
gs_strfreev char **ips = NULL;
|
||||||
|
guint j;
|
||||||
|
|
||||||
|
ips = g_strsplit_set(value, ";", 0);
|
||||||
|
for (j = 0; ips[j]; j++) {
|
||||||
|
if (!nm_wireguard_peer_append_allowed_ip(peer, ips[j], FALSE)) {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
"invalid allowed-ip '%s'",
|
||||||
|
ips[j]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nm_streq(tokens[i], "endpoint")) {
|
||||||
|
if (!nm_wireguard_peer_set_endpoint(peer, value, FALSE)) {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
"invalid endpoint '%s'",
|
||||||
|
value);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else if (nm_streq(tokens[i], "persistent-keepalive")) {
|
||||||
|
gint64 keepalive;
|
||||||
|
|
||||||
|
keepalive = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT16, -1);
|
||||||
|
if (keepalive == -1) {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
"invalid persistent-keepalive value '%s'",
|
||||||
|
value);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
nm_wireguard_peer_set_persistent_keepalive(peer, (guint16) keepalive);
|
||||||
|
} else if (nm_streq(tokens[i], "preshared-key")) {
|
||||||
|
if (!nm_wireguard_peer_set_preshared_key(peer, value, FALSE)) {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
"invalid preshared-key '%s'",
|
||||||
|
value);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
has_psk = TRUE;
|
||||||
|
} else if (nm_streq(tokens[i], "preshared-key-flags")) {
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
if (!nm_utils_enum_from_str(NM_TYPE_SETTING_SECRET_FLAGS, value, &flags, NULL)) {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
"invalid preshared-key-flags '%s'",
|
||||||
|
value);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
nm_wireguard_peer_set_preshared_key_flags(peer, (NMSettingSecretFlags) flags);
|
||||||
|
has_psk_flags = TRUE;
|
||||||
|
} else {
|
||||||
|
g_set_error(error,
|
||||||
|
NM_CONNECTION_ERROR,
|
||||||
|
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||||
|
"invalid attribute '%s'",
|
||||||
|
tokens[i]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_psk && !has_psk_flags) {
|
||||||
|
/* The flags are NOT_REQUIRED by default. With this flag, the PSK would not
|
||||||
|
* be saved by default, unless the user explicitly sets a different value. */
|
||||||
|
nm_wireguard_peer_set_preshared_key_flags(peer, NM_SETTING_SECRET_FLAG_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nm_wireguard_peer_is_valid(peer, TRUE, TRUE, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return g_steal_pointer(&peer);
|
||||||
|
}
|
||||||
|
@@ -6,8 +6,9 @@
|
|||||||
#ifndef __NM_LIBNM_CORE_AUX_H__
|
#ifndef __NM_LIBNM_CORE_AUX_H__
|
||||||
#define __NM_LIBNM_CORE_AUX_H__
|
#define __NM_LIBNM_CORE_AUX_H__
|
||||||
|
|
||||||
#include "nm-setting-team.h"
|
|
||||||
#include "nm-setting-ip-config.h"
|
#include "nm-setting-ip-config.h"
|
||||||
|
#include "nm-setting-team.h"
|
||||||
|
#include "nm-setting-wireguard.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NM_TEAM_LINK_WATCHER_TYPE_NONE = 0,
|
NM_TEAM_LINK_WATCHER_TYPE_NONE = 0,
|
||||||
@@ -39,4 +40,7 @@ void _nm_ip_route_to_string(NMIPRoute *route, struct _NMStrBuf *strbuf);
|
|||||||
|
|
||||||
NMTeamLinkWatcher *nm_utils_team_link_watcher_from_string(const char *str, GError **error);
|
NMTeamLinkWatcher *nm_utils_team_link_watcher_from_string(const char *str, GError **error);
|
||||||
|
|
||||||
|
char *_nm_utils_wireguard_peer_to_string(NMWireGuardPeer *peer);
|
||||||
|
NMWireGuardPeer *_nm_utils_wireguard_peer_from_string(const char *str, GError **error);
|
||||||
|
|
||||||
#endif /* __NM_LIBNM_CORE_AUX_H__ */
|
#endif /* __NM_LIBNM_CORE_AUX_H__ */
|
||||||
|
@@ -2515,6 +2515,73 @@ nm_setting_wireguard_class_init(NMSettingWireGuardClass *klass)
|
|||||||
NMSettingWireGuard,
|
NMSettingWireGuard,
|
||||||
_priv.ip6_auto_default_route);
|
_priv.ip6_auto_default_route);
|
||||||
|
|
||||||
|
/* ---nmcli---
|
||||||
|
* property: peers
|
||||||
|
* format: a comma-separated list of WireGuard peers
|
||||||
|
* description:
|
||||||
|
* A comma-separated list of WireGuard peers. Each peer has the following syntax:
|
||||||
|
*
|
||||||
|
* PUBLIC_KEY [ATTRIBUTE=VALUE [ATTRIBUTE=VALUE]...]
|
||||||
|
*
|
||||||
|
* The supported attributes are: endpoint, allowed-ips, persistent-keepalive,
|
||||||
|
* preshared-key, preshared-key-flags.
|
||||||
|
* description-docbook:
|
||||||
|
* <para>
|
||||||
|
* A comma-separated list of WireGuard peers. Each peer has the following syntax:
|
||||||
|
* </para>
|
||||||
|
* <para>
|
||||||
|
* <literal>
|
||||||
|
* <replaceable>public-key</replaceable>
|
||||||
|
* [<replaceable>attribute</replaceable>=<replaceable>value</replaceable>
|
||||||
|
* [<replaceable>attribute</replaceable>=<replaceable>value</replaceable>]...]
|
||||||
|
* </literal>
|
||||||
|
* </para>
|
||||||
|
* <para>
|
||||||
|
* The public key is required and must be encoded as base64; it can be
|
||||||
|
* calculated by running <command>wg pubkey</command> on the private key,
|
||||||
|
* and it is usually transmitted out of band to the author of the configuration
|
||||||
|
* file.
|
||||||
|
* </para>
|
||||||
|
* <para>
|
||||||
|
* The supported attributes are:
|
||||||
|
* <variablelist>
|
||||||
|
* <varlistentry>
|
||||||
|
* <term><varname>endpoint</varname></term>
|
||||||
|
* <listitem><para>An endpoint IP or hostname, followed by a colon, and then
|
||||||
|
* a port number.</para></listitem>
|
||||||
|
* </varlistentry>
|
||||||
|
*
|
||||||
|
* <varlistentry>
|
||||||
|
* <term><varname></varname></term>
|
||||||
|
* <listitem><para></para></listitem>
|
||||||
|
* </varlistentry>
|
||||||
|
* <varlistentry>
|
||||||
|
* <term><varname>allowed-ips</varname></term>
|
||||||
|
* <listitem><para>A semicolon-separated list of IP (v4 or v6) addresses
|
||||||
|
* with CIDR masks from which incoming traffic for this peer is allowed
|
||||||
|
* and to which outgoing traffic for this peer is directed
|
||||||
|
* </para></listitem>
|
||||||
|
* </varlistentry>
|
||||||
|
* <varlistentry>
|
||||||
|
* <term><varname>persistent-keepalive</varname></term>
|
||||||
|
* <listitem><para>An interval in seconds, between 1 and 65535, of
|
||||||
|
* how often to send an authenticated empty packet to the peer for the
|
||||||
|
* purpose of keeping a stateful firewall or NAT mapping valid persistently.
|
||||||
|
* </para></listitem>
|
||||||
|
* </varlistentry>
|
||||||
|
* <varlistentry>
|
||||||
|
* <term><varname>preshared-key</varname></term>
|
||||||
|
* <listitem><para>A base64 preshared key generated by "wg genpsk". Optional,
|
||||||
|
* and may be omitted.</para></listitem>
|
||||||
|
* </varlistentry>
|
||||||
|
* <varlistentry>
|
||||||
|
* <term><varname>preshared-key-flags</varname></term>
|
||||||
|
* <listitem><para>The secret flags for the preshared-key.</para></listitem>
|
||||||
|
* </varlistentry>
|
||||||
|
* </variablelist>
|
||||||
|
* </para>
|
||||||
|
* ---end---
|
||||||
|
*/
|
||||||
/* ---dbus---
|
/* ---dbus---
|
||||||
* property: peers
|
* property: peers
|
||||||
* format: array of 'a{sv}'
|
* format: array of 'a{sv}'
|
||||||
|
@@ -4156,6 +4156,50 @@ _optionlist_set_fcn_vpn_secrets(NMSetting *setting,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_objlist_obj_to_str_fcn_wireguard_peers(NMMetaAccessorGetType get_type,
|
||||||
|
NMSetting *setting,
|
||||||
|
guint idx,
|
||||||
|
GString *str)
|
||||||
|
{
|
||||||
|
NMWireGuardPeer *peer;
|
||||||
|
gs_free char *peer_str = NULL;
|
||||||
|
|
||||||
|
peer = nm_setting_wireguard_get_peer(NM_SETTING_WIREGUARD(setting), idx);
|
||||||
|
peer_str = _nm_utils_wireguard_peer_to_string(peer);
|
||||||
|
g_string_append(str, peer_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_objlist_set_fcn_wireguard_peers(NMSetting *setting,
|
||||||
|
gboolean do_add,
|
||||||
|
const char *value,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
NMSettingWireGuard *s_wg = NM_SETTING_WIREGUARD(setting);
|
||||||
|
nm_auto_unref_wgpeer NMWireGuardPeer *peer = NULL;
|
||||||
|
|
||||||
|
peer = _nm_utils_wireguard_peer_from_string(value, error);
|
||||||
|
if (!peer)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (do_add) {
|
||||||
|
nm_setting_wireguard_append_peer(s_wg, peer);
|
||||||
|
} else {
|
||||||
|
NMWireGuardPeer *match;
|
||||||
|
guint idx;
|
||||||
|
|
||||||
|
match = nm_setting_wireguard_get_peer_by_public_key(s_wg,
|
||||||
|
nm_wireguard_peer_get_public_key(peer),
|
||||||
|
&idx);
|
||||||
|
if (match) {
|
||||||
|
nm_setting_wireguard_remove_peer(s_wg, idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_set_fcn_wired_s390_subchannels(ARGS_SET_FCN)
|
_set_fcn_wired_s390_subchannels(ARGS_SET_FCN)
|
||||||
{
|
{
|
||||||
@@ -8423,6 +8467,21 @@ static const NMMetaPropertyInfo *const property_infos_WIREGUARD[] = {
|
|||||||
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE,
|
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_IP6_AUTO_DEFAULT_ROUTE,
|
||||||
.property_type = &_pt_gobject_ternary,
|
.property_type = &_pt_gobject_ternary,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_PEERS,
|
||||||
|
.property_type = &_pt_objlist,
|
||||||
|
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
|
||||||
|
PROPERTY_TYP_DATA_SUBTYPE (objlist,
|
||||||
|
.get_num_fcn = OBJLIST_GET_NUM_FCN (NMSettingWireGuard, nm_setting_wireguard_get_peers_len),
|
||||||
|
.clear_all_fcn = (void (*) (NMSetting *))(void (*)(void)) nm_setting_wireguard_clear_peers,
|
||||||
|
.obj_to_str_fcn = _objlist_obj_to_str_fcn_wireguard_peers,
|
||||||
|
.set_fcn = _objlist_set_fcn_wireguard_peers,
|
||||||
|
.remove_by_idx_fcn_u = (void (*) (NMSetting *, guint idx))(void (*)(void)) nm_setting_wireguard_remove_peer,
|
||||||
|
.strsplit_plain = TRUE,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -443,6 +443,7 @@
|
|||||||
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_LISTEN_PORT N_("The listen-port. If listen-port is not specified, the port will be chosen randomly when the interface comes up.")
|
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_LISTEN_PORT N_("The listen-port. If listen-port is not specified, the port will be chosen randomly when the interface comes up.")
|
||||||
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments. If zero a default MTU is used. Note that contrary to wg-quick's MTU setting, this does not take into account the current routes at the time of activation.")
|
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments. If zero a default MTU is used. Note that contrary to wg-quick's MTU setting, this does not take into account the current routes at the time of activation.")
|
||||||
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PEER_ROUTES N_("Whether to automatically add routes for the AllowedIPs ranges of the peers. If TRUE (the default), NetworkManager will automatically add routes in the routing tables according to ipv4.route-table and ipv6.route-table. Usually you want this automatism enabled. If FALSE, no such routes are added automatically. In this case, the user may want to configure static routes in ipv4.routes and ipv6.routes, respectively. Note that if the peer's AllowedIPs is \"0.0.0.0/0\" or \"::/0\" and the profile's ipv4.never-default or ipv6.never-default setting is enabled, the peer route for this peer won't be added automatically.")
|
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PEER_ROUTES N_("Whether to automatically add routes for the AllowedIPs ranges of the peers. If TRUE (the default), NetworkManager will automatically add routes in the routing tables according to ipv4.route-table and ipv6.route-table. Usually you want this automatism enabled. If FALSE, no such routes are added automatically. In this case, the user may want to configure static routes in ipv4.routes and ipv6.routes, respectively. Note that if the peer's AllowedIPs is \"0.0.0.0/0\" or \"::/0\" and the profile's ipv4.never-default or ipv6.never-default setting is enabled, the peer route for this peer won't be added automatically.")
|
||||||
|
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PEERS N_("A comma-separated list of WireGuard peers. Each peer has the following syntax: PUBLIC_KEY [ATTRIBUTE=VALUE [ATTRIBUTE=VALUE]...] The supported attributes are: endpoint, allowed-ips, persistent-keepalive, preshared-key, preshared-key-flags.")
|
||||||
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY N_("The 256 bit private-key in base64 encoding.")
|
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY N_("The 256 bit private-key in base64 encoding.")
|
||||||
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS N_("Flags indicating how to handle the \"private-key\" property.")
|
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS N_("Flags indicating how to handle the \"private-key\" property.")
|
||||||
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_AP_ISOLATION N_("Configures AP isolation, which prevents communication between wireless devices connected to this AP. This property can be set to a value different from \"default\" (-1) only when the interface is configured in AP mode. If set to \"true\" (1), devices are not able to communicate with each other. This increases security because it protects devices against attacks from other clients in the network. At the same time, it prevents devices to access resources on the same wireless networks as file shares, printers, etc. If set to \"false\" (0), devices can talk to each other. When set to \"default\" (-1), the global default is used; in case the global default is unspecified it is assumed to be \"false\" (0).")
|
#define DESCRIBE_DOC_NM_SETTING_WIRELESS_AP_ISOLATION N_("Configures AP isolation, which prevents communication between wireless devices connected to this AP. This property can be set to a value different from \"default\" (-1) only when the interface is configured in AP mode. If set to \"true\" (1), devices are not able to communicate with each other. This increases security because it protects devices against attacks from other clients in the network. At the same time, it prevents devices to access resources on the same wireless networks as file shares, printers, etc. If set to \"false\" (0), devices can talk to each other. When set to \"default\" (-1), the global default is used; in case the global default is unspecified it is assumed to be \"false\" (0).")
|
||||||
|
@@ -2320,6 +2320,9 @@
|
|||||||
nmcli-description="Like ip4-auto-default-route, but for the IPv6 default route."
|
nmcli-description="Like ip4-auto-default-route, but for the IPv6 default route."
|
||||||
format="ternary"
|
format="ternary"
|
||||||
values="true/yes/on, false/no/off, default/unknown" />
|
values="true/yes/on, false/no/off, default/unknown" />
|
||||||
|
<property name="peers"
|
||||||
|
nmcli-description="A comma-separated list of WireGuard peers. Each peer has the following syntax: PUBLIC_KEY [ATTRIBUTE=VALUE [ATTRIBUTE=VALUE]...] The supported attributes are: endpoint, allowed-ips, persistent-keepalive, preshared-key, preshared-key-flags."
|
||||||
|
format="list of wireguard.peers objects" />
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="wpan" >
|
<setting name="wpan" >
|
||||||
<property name="mac-address"
|
<property name="mac-address"
|
||||||
|
Reference in New Issue
Block a user