mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 08:25:38 +00:00
wireguard: exit on invalid configurations
With this commit, the WireGuard component exits with a descriptive uncaught exception on invalid configurations or when the user attempts to re-configure attributes that are not re-configurable (private_key, listen_port, interface). This is particularly important when it comes to the not re-configurable private key. If the component would just ignore the attempt to override the private key, the user may come to believe that his old (potentially compromised) private key is not in use anymore. The fact that the component now exits instead shouldn't be a problem, as the user would have to restart the component anyway in order to apply the new attribute values. The commit also extends the wg_reconfig run script to test that WireGuard exits on the attempt to re-configure the private key. Ref #4520
This commit is contained in:
parent
86259b998e
commit
36d2374ff9
@ -4,9 +4,10 @@
|
||||
# WireGuard changes. Each peer has its own WireGuard instance and talks
|
||||
# to the other peers only through WireGuard. The server WireGuard (peer 2)
|
||||
# initially accepts only peer 1. After some time it gets re-configured to
|
||||
# accept only peer 3. At the end, it gets re-configured to accept only peer 1
|
||||
# again. Note that the peer 1 WireGuard has to be reconfigured as well, in
|
||||
# order to be forced to redo the initiation handshake for the last
|
||||
# accept only peer 3. Then, it gets re-configured to accept only peer 1 again
|
||||
# and, in the end, an attempt is made to re-configure the private key, which
|
||||
# should fail. Note that the peer 1 WireGuard has to be reconfigured as well,
|
||||
# in order to be forced to redo the initiation handshake for the third
|
||||
# configuration phase of the server WireGuard.
|
||||
#
|
||||
|
||||
@ -26,13 +27,13 @@ import_from_depot [depot_user]/src/libc \
|
||||
[depot_user]/src/vfs_lwip \
|
||||
[depot_user]/src/zlib
|
||||
|
||||
proc peer1_wg_config {variant} {
|
||||
proc peer_1_wg_config {peers} {
|
||||
|
||||
append result {
|
||||
<config private_key="0CtU34qsl97IGiYKSO4tMaF/SJvy04zzeQkhZEbZSk0="
|
||||
listen_port="49001">
|
||||
}
|
||||
if {$variant == "with_peer3"} {
|
||||
if {$peers == "peer_3"} {
|
||||
append result {
|
||||
<peer public_key="GrvyALPZ3PQ2AWM+ovxJqnxSqKpmTyqUui5jH+C8I0E="
|
||||
endpoint_ip="10.1.2.1"
|
||||
@ -46,22 +47,35 @@ proc peer1_wg_config {variant} {
|
||||
return $result
|
||||
}
|
||||
|
||||
proc peer2_wg_config {variant} {
|
||||
proc peer_2_wg_config {peers private_key} {
|
||||
|
||||
append result {
|
||||
<config private_key="8GRSQZMgG1uuvz4APIBqrDmiLj8L886r++hzixjjHFc="
|
||||
listen_port="49002">
|
||||
}
|
||||
if {$variant == "with_peer1"} {
|
||||
append result {
|
||||
<peer public_key="r1Gslnm82X8NaijsWzPoSFzDZGl2tTJoPa+EJL4gYQw="
|
||||
allowed_ip="10.0.9.1/32" />
|
||||
switch $private_key {
|
||||
private_key_1 {
|
||||
append result {
|
||||
<config private_key="8GRSQZMgG1uuvz4APIBqrDmiLj8L886r++hzixjjHFc="
|
||||
}
|
||||
}
|
||||
private_key_2 {
|
||||
append result {
|
||||
<config private_key="oKzvdG6XOPRyFaruEfwTTNiGlsDKHqO4HOrN0lnrcGM="
|
||||
}
|
||||
}
|
||||
}
|
||||
if {$variant == "with_peer3"} {
|
||||
append result {
|
||||
<peer public_key="gFRbQOj7cVLoLKDIFfNZbguw89vuZrc0i74TV5qOexY="
|
||||
allowed_ip="10.0.9.3/32" />
|
||||
append result {
|
||||
listen_port="49002">
|
||||
}
|
||||
switch $peers {
|
||||
peer_1 {
|
||||
append result {
|
||||
<peer public_key="r1Gslnm82X8NaijsWzPoSFzDZGl2tTJoPa+EJL4gYQw="
|
||||
allowed_ip="10.0.9.1/32" />
|
||||
}
|
||||
}
|
||||
peer_3 {
|
||||
append result {
|
||||
<peer public_key="gFRbQOj7cVLoLKDIFfNZbguw89vuZrc0i74TV5qOexY="
|
||||
allowed_ip="10.0.9.3/32" />
|
||||
}
|
||||
}
|
||||
}
|
||||
append result {
|
||||
@ -100,38 +114,44 @@ append config {
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides><service name="ROM"/></provides>
|
||||
<config verbose="yes">
|
||||
<rom name="peer2_wg_config">
|
||||
<rom name="peer_2_wg_config">
|
||||
|
||||
<inline description="permit peer1_ping only">
|
||||
} [peer2_wg_config with_peer1] {
|
||||
<inline description="permit peer_1_ping only">
|
||||
} [peer_2_wg_config peer_1 private_key_1] {
|
||||
</inline>
|
||||
|
||||
<sleep milliseconds="5000"/>
|
||||
|
||||
<inline description="permit peer3_fetchurl only">
|
||||
} [peer2_wg_config with_peer3] {
|
||||
<inline description="permit peer_3_fetchurl only">
|
||||
} [peer_2_wg_config peer_3 private_key_1] {
|
||||
</inline>
|
||||
|
||||
<sleep milliseconds="5000"/>
|
||||
|
||||
<inline description="permit peer1_ping only">
|
||||
} [peer2_wg_config with_peer1] {
|
||||
<inline description="permit peer_1_ping only">
|
||||
} [peer_2_wg_config peer_1 private_key_1] {
|
||||
</inline>
|
||||
|
||||
<sleep milliseconds="3000"/>
|
||||
|
||||
<inline description="permit peer_1_ping only">
|
||||
} [peer_2_wg_config peer_1 private_key_2] {
|
||||
</inline>
|
||||
|
||||
<sleep milliseconds="600000"/>
|
||||
|
||||
</rom>
|
||||
<rom name="peer1_wg_config">
|
||||
<rom name="peer_1_wg_config">
|
||||
|
||||
<inline> } [peer1_wg_config with_peer3] { </inline>
|
||||
<inline> } [peer_1_wg_config peer_3] { </inline>
|
||||
|
||||
<sleep milliseconds="9000"/>
|
||||
|
||||
<inline> } [peer1_wg_config without_peer] { </inline>
|
||||
<inline> } [peer_1_wg_config no_peer] { </inline>
|
||||
|
||||
<sleep milliseconds="1000"/>
|
||||
|
||||
<inline> } [peer1_wg_config with_peer3] { </inline>
|
||||
<inline> } [peer_1_wg_config peer_3] { </inline>
|
||||
|
||||
<sleep milliseconds="600000"/>
|
||||
|
||||
@ -158,7 +178,7 @@ append config {
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="peer1_ping" caps="100">
|
||||
<start name="peer_1_ping" caps="100">
|
||||
<binary name="ping"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<config dst_ip="10.0.9.2" period_sec="1" count="1000"/>
|
||||
@ -172,7 +192,7 @@ append config {
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="peer3_fetchurl" caps="200">
|
||||
<start name="peer_3_fetchurl" caps="200">
|
||||
<binary name="fetchurl"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<config progress_timeout="3000">
|
||||
@ -205,12 +225,12 @@ append config {
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="peer1_wg" caps="200">
|
||||
<start name="peer_1_wg" caps="200">
|
||||
<binary name="wireguard"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<route>
|
||||
<service name="ROM" label="config">
|
||||
<child label="peer1_wg_config" name="dynamic_rom"/>
|
||||
<child label="peer_1_wg_config" name="dynamic_rom"/>
|
||||
</service>
|
||||
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
@ -223,12 +243,12 @@ append config {
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="peer2_wg" caps="200">
|
||||
<start name="peer_2_wg" caps="200">
|
||||
<binary name="wireguard"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<route>
|
||||
<service name="ROM" label="config">
|
||||
<child label="peer2_wg_config" name="dynamic_rom"/>
|
||||
<child label="peer_2_wg_config" name="dynamic_rom"/>
|
||||
</service>
|
||||
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
@ -241,7 +261,7 @@ append config {
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="peer3_wg" caps="200">
|
||||
<start name="peer_3_wg" caps="200">
|
||||
<binary name="wireguard"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<config private_key="EA+4fJCOJM5/C90zCwsh4jTdKMnlQ2JOnW1bvkwdnEA="
|
||||
@ -275,63 +295,63 @@ append config {
|
||||
|
||||
<!-- Peer 1 (ping) -->
|
||||
|
||||
<policy label="peer1_wg -> nic_session" domain="peer1_outer_downlink"/>
|
||||
<policy label="peer1_wg -> uplink_session" domain="peer1_inner_uplink"/>
|
||||
<policy label="peer1_ping -> " domain="peer1_inner_downlink"/>
|
||||
<policy label="peer_1_wg -> nic_session" domain="peer_1_outer_downlink"/>
|
||||
<policy label="peer_1_wg -> uplink_session" domain="peer_1_inner_uplink"/>
|
||||
<policy label="peer_1_ping -> " domain="peer_1_inner_downlink"/>
|
||||
|
||||
<domain name="peer1_outer_downlink" interface="10.1.2.1/24">
|
||||
<domain name="peer_1_outer_downlink" interface="10.1.2.1/24">
|
||||
<dhcp-server ip_first="10.1.2.2" ip_last="10.1.2.2"/>
|
||||
<udp-forward port="49002" domain="peer2_outer_downlink" to="10.0.3.2"/>
|
||||
<udp-forward port="49002" domain="peer_2_outer_downlink" to="10.0.3.2"/>
|
||||
</domain>
|
||||
|
||||
<domain name="peer1_inner_uplink" interface="10.0.9.1/24" use_arp="no">
|
||||
<nat domain="peer1_inner_downlink" icmp-ids="1000"/>
|
||||
<domain name="peer_1_inner_uplink" interface="10.0.9.1/24" use_arp="no">
|
||||
<nat domain="peer_1_inner_downlink" icmp-ids="1000"/>
|
||||
</domain>
|
||||
|
||||
<domain name="peer1_inner_downlink" interface="10.1.3.1/24">
|
||||
<domain name="peer_1_inner_downlink" interface="10.1.3.1/24">
|
||||
<dhcp-server ip_first="10.1.3.2" ip_last="10.1.3.2"/>
|
||||
<icmp dst="10.0.9.2/24" domain="peer1_inner_uplink"/>
|
||||
<icmp dst="10.0.9.2/24" domain="peer_1_inner_uplink"/>
|
||||
</domain>
|
||||
|
||||
|
||||
<!-- Peer 2 (lighttpd) -->
|
||||
|
||||
<policy label="peer2_wg -> nic_session" domain="peer2_outer_downlink"/>
|
||||
<policy label="peer2_wg -> uplink_session" domain="peer2_inner_uplink"/>
|
||||
<policy label="peer2_lighttpd -> lwip" domain="peer2_inner_downlink"/>
|
||||
<policy label="peer_2_wg -> nic_session" domain="peer_2_outer_downlink"/>
|
||||
<policy label="peer_2_wg -> uplink_session" domain="peer_2_inner_uplink"/>
|
||||
<policy label="peer_2_lighttpd -> lwip" domain="peer_2_inner_downlink"/>
|
||||
|
||||
<domain name="peer2_outer_downlink" interface="10.0.3.1/24">
|
||||
<domain name="peer_2_outer_downlink" interface="10.0.3.1/24">
|
||||
<dhcp-server ip_first="10.0.3.2" ip_last="10.0.3.2"/>
|
||||
</domain>
|
||||
|
||||
<domain name="peer2_inner_uplink" interface="10.0.9.2/24" use_arp="no" icmp_echo_server="yes">
|
||||
<tcp-forward port="80" domain="peer2_inner_downlink" to="10.0.5.2"/>
|
||||
<domain name="peer_2_inner_uplink" interface="10.0.9.2/24" use_arp="no" icmp_echo_server="yes">
|
||||
<tcp-forward port="80" domain="peer_2_inner_downlink" to="10.0.5.2"/>
|
||||
</domain>
|
||||
|
||||
<domain name="peer2_inner_downlink" interface="10.0.5.1/24">
|
||||
<domain name="peer_2_inner_downlink" interface="10.0.5.1/24">
|
||||
<dhcp-server ip_first="10.0.5.2" ip_last="10.0.5.2"/>
|
||||
</domain>
|
||||
|
||||
|
||||
<!-- Peer 3 (fetchurl)-->
|
||||
|
||||
<policy label="peer3_wg -> nic_session" domain="peer3_outer_downlink"/>
|
||||
<policy label="peer3_wg -> uplink_session" domain="peer3_inner_uplink"/>
|
||||
<policy label="peer3_fetchurl -> lwip" domain="peer3_inner_downlink"/>
|
||||
<policy label="peer_3_wg -> nic_session" domain="peer_3_outer_downlink"/>
|
||||
<policy label="peer_3_wg -> uplink_session" domain="peer_3_inner_uplink"/>
|
||||
<policy label="peer_3_fetchurl -> lwip" domain="peer_3_inner_downlink"/>
|
||||
|
||||
<domain name="peer3_outer_downlink" interface="10.3.2.1/24">
|
||||
<domain name="peer_3_outer_downlink" interface="10.3.2.1/24">
|
||||
<dhcp-server ip_first="10.3.2.2" ip_last="10.3.2.2"/>
|
||||
<udp-forward port="49002" domain="peer2_outer_downlink" to="10.0.3.2"/>
|
||||
<udp-forward port="49002" domain="peer_2_outer_downlink" to="10.0.3.2"/>
|
||||
</domain>
|
||||
|
||||
<domain name="peer3_inner_uplink" interface="10.0.9.3/24" use_arp="no">
|
||||
<nat domain="peer3_inner_downlink" tcp-ports="1000"/>
|
||||
<domain name="peer_3_inner_uplink" interface="10.0.9.3/24" use_arp="no">
|
||||
<nat domain="peer_3_inner_downlink" tcp-ports="1000"/>
|
||||
</domain>
|
||||
|
||||
<domain name="peer3_inner_downlink" interface="10.3.3.1/24">
|
||||
<domain name="peer_3_inner_downlink" interface="10.3.3.1/24">
|
||||
<dhcp-server ip_first="10.3.3.2" ip_last="10.3.3.2"/>
|
||||
<tcp dst="10.0.9.2/24">
|
||||
<permit port="80" domain="peer3_inner_uplink"/>
|
||||
<permit port="80" domain="peer_3_inner_uplink"/>
|
||||
</tcp>
|
||||
</domain>
|
||||
|
||||
@ -346,7 +366,7 @@ append config {
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="peer2_lighttpd" caps="200">
|
||||
<start name="peer_2_lighttpd" caps="200">
|
||||
<binary name="lighttpd"/>
|
||||
<resource name="RAM" quantum="50M" />
|
||||
<config>
|
||||
@ -486,11 +506,12 @@ build_boot_image $boot_modules
|
||||
|
||||
append qemu_args "-nographic "
|
||||
|
||||
append output_pattern "peer1_ping. 64 bytes from 10.0.9.2.*\n"
|
||||
append output_pattern ".*peer1_ping. 64 bytes from 10.0.9.2.*\n"
|
||||
append output_pattern ".*child \"peer3_fetchurl\" exited with exit value 0.*\n"
|
||||
append output_pattern ".*peer1_ping. 64 bytes from 10.0.9.2.*\n"
|
||||
append output_pattern ".*peer1_ping. 64 bytes from 10.0.9.2.*\n"
|
||||
append output_pattern "peer_1_ping. 64 bytes from 10.0.9.2.*\n"
|
||||
append output_pattern ".*peer_1_ping. 64 bytes from 10.0.9.2.*\n"
|
||||
append output_pattern ".*child \"peer_3_fetchurl\" exited with exit value 0.*\n"
|
||||
append output_pattern ".*peer_1_ping. 64 bytes from 10.0.9.2.*\n"
|
||||
append output_pattern ".*peer_1_ping. 64 bytes from 10.0.9.2.*\n"
|
||||
append output_pattern ".*peer_2_wg. .*Error: Uncaught exception of type .*Invalid_reconfiguration_attempt.*\n"
|
||||
|
||||
run_genode_until $output_pattern 30
|
||||
run_genode_until $output_pattern 45
|
||||
|
||||
|
@ -33,19 +33,35 @@ Config_model::Config_model(Genode::Allocator &alloc)
|
||||
void Config_model::update(genode_wg_config_callbacks &callbacks,
|
||||
Xml_node node)
|
||||
{
|
||||
if (!_config.constructed()) {
|
||||
Key_base64 const private_key_b64 {
|
||||
node.attribute_value("private_key", Key_base64 { }) };
|
||||
|
||||
_config.construct(
|
||||
node.attribute_value("private_key", Key_base64 { }),
|
||||
node.attribute_value("listen_port", (uint16_t)0U),
|
||||
node.attribute_value("interface", Ipv4_address_prefix { }));
|
||||
uint16_t const listen_port {
|
||||
node.attribute_value("listen_port", (uint16_t)0U) };
|
||||
|
||||
Ipv4_address_prefix const interface {
|
||||
node.attribute_value("interface", Ipv4_address_prefix { }) };
|
||||
|
||||
if (_config.constructed()) {
|
||||
|
||||
if (_config->private_key_b64() != private_key_b64 ||
|
||||
_config->listen_port() != listen_port ||
|
||||
_config->interface() != interface)
|
||||
{
|
||||
class Invalid_reconfiguration_attempt { };
|
||||
throw Invalid_reconfiguration_attempt { };
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
uint8_t private_key[WG_KEY_LEN];
|
||||
if (!_config->private_key_b64().valid() ||
|
||||
!key_from_base64(private_key, _config->private_key_b64().string())) {
|
||||
if (!private_key_b64.valid() ||
|
||||
!key_from_base64(private_key, private_key_b64.string())) {
|
||||
|
||||
error("Invalid private key!");
|
||||
class Invalid_private_key { };
|
||||
throw Invalid_private_key { };
|
||||
}
|
||||
_config.construct(private_key_b64, listen_port, interface);
|
||||
callbacks.add_device(_config->listen_port(), private_key);
|
||||
}
|
||||
Peer_update_policy policy { _alloc, callbacks, _config->listen_port() };
|
||||
@ -91,7 +107,9 @@ void Config_model::Peer_update_policy::destroy_element(Element &peer)
|
||||
{
|
||||
uint8_t public_key[WG_KEY_LEN];
|
||||
if (!key_from_base64(public_key, peer._public_key_b64.string())) {
|
||||
error("Invalid public key!");
|
||||
|
||||
class Invalid_public_key { };
|
||||
throw Invalid_public_key { };
|
||||
}
|
||||
_callbacks.remove_peer(public_key);
|
||||
|
||||
@ -111,10 +129,13 @@ Config_model::Peer_update_policy::create_element(Xml_node node)
|
||||
if (!public_key_b64.valid() ||
|
||||
!key_from_base64(public_key, public_key_b64.string())) {
|
||||
|
||||
error("Invalid public key!");
|
||||
class Invalid_public_key { };
|
||||
throw Invalid_public_key { };
|
||||
}
|
||||
if (!allowed_ip.valid()) {
|
||||
error("Invalid allowed ip!");
|
||||
|
||||
class Invalid_allowed_ip { };
|
||||
throw Invalid_allowed_ip { };
|
||||
}
|
||||
_callbacks.add_peer(
|
||||
_listen_port, endpoint_ip.addr, endpoint_port, public_key,
|
||||
|
Loading…
x
Reference in New Issue
Block a user