diff options
| author | David Lönnhager <david.l@mullvad.net> | 2022-05-20 11:40:32 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2022-06-14 12:37:04 +0200 |
| commit | ad0fdb6d5dc0c0e7c1eb1183784d994d44b459be (patch) | |
| tree | cad8267f22d8567c0f36785c78b48e438bd3f1ff | |
| parent | d8e1e030af2d8a1f900a83c6f8f6f23a6d736be6 (diff) | |
| download | mullvadvpn-ad0fdb6d5dc0c0e7c1eb1183784d994d44b459be.tar.xz mullvadvpn-ad0fdb6d5dc0c0e7c1eb1183784d994d44b459be.zip | |
Add option for enabling PQ PSK exchange to CLI and gRPC service
| -rw-r--r-- | mullvad-cli/src/cmds/relay.rs | 19 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/tunnel.rs | 56 | ||||
| -rw-r--r-- | mullvad-daemon/src/lib.rs | 35 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 11 | ||||
| -rw-r--r-- | mullvad-daemon/src/settings.rs | 16 | ||||
| -rw-r--r-- | mullvad-management-interface/proto/management_interface.proto | 1 |
6 files changed, 137 insertions, 1 deletions
diff --git a/mullvad-cli/src/cmds/relay.rs b/mullvad-cli/src/cmds/relay.rs index c624c2a25b..ac7bd74c63 100644 --- a/mullvad-cli/src/cmds/relay.rs +++ b/mullvad-cli/src/cmds/relay.rs @@ -573,7 +573,24 @@ impl Relay { } if let Some(entry) = matches.values_of("entry location") { wireguard_constraints.entry_location = parse_entry_location_constraint(entry); - wireguard_constraints.use_multihop = wireguard_constraints.entry_location.is_some(); + let use_multihop = wireguard_constraints.entry_location.is_some(); + if use_multihop { + let use_pq = rpc + .get_settings(()) + .await? + .into_inner() + .tunnel_options + .unwrap() + .wireguard + .unwrap() + .use_pq_safe_psk; + if use_pq { + return Err(Error::CommandFailed( + "PQ PSK exchange does not work when multihop is enabled", + )); + } + } + wireguard_constraints.use_multihop = use_multihop; } self.update_constraints(types::RelaySettingsUpdate { diff --git a/mullvad-cli/src/cmds/tunnel.rs b/mullvad-cli/src/cmds/tunnel.rs index f01452a925..7856cc849c 100644 --- a/mullvad-cli/src/cmds/tunnel.rs +++ b/mullvad-cli/src/cmds/tunnel.rs @@ -37,6 +37,7 @@ fn create_wireguard_subcommand() -> clap::App<'static> { .about("Manage options for Wireguard tunnels") .setting(clap::AppSettings::SubcommandRequiredElseHelp) .subcommand(create_wireguard_mtu_subcommand()) + .subcommand(create_wireguard_quantum_resistant_tunnel_subcommand()) .subcommand(create_wireguard_keys_subcommand()); #[cfg(windows)] { @@ -57,6 +58,14 @@ fn create_wireguard_mtu_subcommand() -> clap::App<'static> { .subcommand(clap::App::new("set").arg(clap::Arg::new("mtu").required(true))) } +fn create_wireguard_quantum_resistant_tunnel_subcommand() -> clap::App<'static> { + clap::App::new("quantum-resistant-tunnel") + .about("EXPERIMENTAL: Enables quantum-resistant PSK exchange in the tunnel") + .setting(clap::AppSettings::SubcommandRequiredElseHelp) + .subcommand(clap::App::new("get")) + .subcommand(clap::App::new("set").arg(clap::Arg::new("policy").required(true))) +} + fn create_wireguard_keys_subcommand() -> clap::App<'static> { clap::App::new("key") .about("Manage your wireguard key") @@ -163,6 +172,14 @@ impl Tunnel { _ => unreachable!("unhandled command"), }, + Some(("quantum-resistant-tunnel", matches)) => match matches.subcommand() { + Some(("get", _)) => Self::process_wireguard_quantum_resistant_tunnel_get().await, + Some(("set", matches)) => { + Self::process_wireguard_quantum_resistant_tunnel_set(matches).await + } + _ => unreachable!("unhandled command"), + }, + #[cfg(windows)] Some(("use-wireguard-nt", matches)) => match matches.subcommand() { Some(("get", _)) => Self::process_wireguard_use_wg_nt_get().await, @@ -203,6 +220,45 @@ impl Tunnel { Ok(()) } + async fn process_wireguard_quantum_resistant_tunnel_get() -> Result<()> { + let tunnel_options = Self::get_tunnel_options().await?; + if tunnel_options.wireguard.unwrap().use_pq_safe_psk { + println!("enabled"); + } else { + println!("disabled"); + } + Ok(()) + } + + async fn process_wireguard_quantum_resistant_tunnel_set( + matches: &clap::ArgMatches, + ) -> Result<()> { + let new_state = matches.value_of("policy").unwrap() == "on"; + let mut rpc = new_rpc_client().await?; + let settings = rpc.get_settings(()).await?; + let multihop_is_enabled = settings + .into_inner() + .relay_settings + .unwrap() + .endpoint + .and_then(|endpoint| { + if let types::relay_settings::Endpoint::Normal(settings) = endpoint { + Some(settings.wireguard_constraints.unwrap().use_multihop) + } else { + None + } + }) + .unwrap_or(false); + if multihop_is_enabled { + return Err(Error::CommandFailed( + "PQ PSK exchange does not work when multihop is enabled", + )); + } + rpc.set_quantum_resistant_tunnel(new_state).await?; + println!("Updated quantum resistant tunnel setting"); + Ok(()) + } + #[cfg(windows)] async fn process_wireguard_use_wg_nt_get() -> Result<()> { let tunnel_options = Self::get_tunnel_options().await?; diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index b75ad9121c..9b82470bab 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -220,6 +220,8 @@ pub enum DaemonCommand { SetBridgeState(ResponseTx<(), settings::Error>, BridgeState), /// Set if IPv6 should be enabled in the tunnel SetEnableIpv6(ResponseTx<(), settings::Error>, bool), + /// Set whether to enable PQ PSK exchange in the tunnel + SetQuantumResistantTunnel(ResponseTx<(), settings::Error>, bool), /// Set DNS options or servers to use SetDnsOptions(ResponseTx<(), settings::Error>, DnsOptions), /// Toggle macOS network check leak @@ -979,6 +981,9 @@ where } SetBridgeState(tx, bridge_state) => self.on_set_bridge_state(tx, bridge_state).await, SetEnableIpv6(tx, enable_ipv6) => self.on_set_enable_ipv6(tx, enable_ipv6).await, + SetQuantumResistantTunnel(tx, enable_pq) => { + self.on_set_quantum_resistant_tunnel(tx, enable_pq).await + } SetDnsOptions(tx, dns_servers) => self.on_set_dns_options(tx, dns_servers).await, SetWireguardMtu(tx, mtu) => self.on_set_wireguard_mtu(tx, mtu).await, SetWireguardRotationInterval(tx, interval) => { @@ -1954,6 +1959,36 @@ where } } + async fn on_set_quantum_resistant_tunnel( + &mut self, + tx: ResponseTx<(), settings::Error>, + use_pq_safe_psk: bool, + ) { + let save_result = self + .settings + .set_quantum_resistant_tunnel(use_pq_safe_psk) + .await; + match save_result { + Ok(settings_changed) => { + Self::oneshot_send(tx, Ok(()), "set_quantum_resistant_tunnel response"); + if settings_changed { + self.parameters_generator + .set_tunnel_options(&self.settings.tunnel_options); + self.event_listener + .notify_settings(self.settings.to_settings()); + if self.get_connected_tunnel_type() == Some(TunnelType::Wireguard) { + log::info!("Reconnecting because the PQ safety setting changed"); + self.reconnect_tunnel(); + } + } + } + Err(e) => { + log::error!("{}", e.display_chain_with_msg("Unable to save settings")); + Self::oneshot_send(tx, Err(e), "set_quantum_resistant_tunnel response"); + } + } + } + async fn on_set_dns_options( &mut self, tx: ResponseTx<(), settings::Error>, diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index 2264159fc8..a7478eb048 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -373,6 +373,17 @@ impl ManagementService for ManagementServiceImpl { .map_err(map_settings_error) } + async fn set_quantum_resistant_tunnel(&self, request: Request<bool>) -> ServiceResult<()> { + let enable = request.into_inner(); + log::debug!("set_quantum_resistant_tunnel({})", enable); + let (tx, rx) = oneshot::channel(); + self.send_command_to_daemon(DaemonCommand::SetQuantumResistantTunnel(tx, enable))?; + self.wait_for_result(rx) + .await? + .map(Response::new) + .map_err(map_settings_error) + } + #[cfg(not(target_os = "android"))] async fn set_dns_options(&self, request: Request<types::DnsOptions>) -> ServiceResult<()> { let options = DnsOptions::try_from(request.into_inner()).map_err(map_protobuf_type_err)?; diff --git a/mullvad-daemon/src/settings.rs b/mullvad-daemon/src/settings.rs index 52800028cc..e69ca8316f 100644 --- a/mullvad-daemon/src/settings.rs +++ b/mullvad-daemon/src/settings.rs @@ -236,6 +236,22 @@ impl SettingsPersister { self.update(should_save).await } + pub async fn set_quantum_resistant_tunnel( + &mut self, + use_pq_safe_psk: bool, + ) -> Result<bool, Error> { + let should_save = Self::update_field( + &mut self + .settings + .tunnel_options + .wireguard + .options + .use_pq_safe_psk, + use_pq_safe_psk, + ); + self.update(should_save).await + } + pub async fn set_dns_options(&mut self, options: DnsOptions) -> Result<bool, Error> { let should_save = Self::update_field(&mut self.settings.tunnel_options.dns_options, options); diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto index eb132b2a52..9d53ccf837 100644 --- a/mullvad-management-interface/proto/management_interface.proto +++ b/mullvad-management-interface/proto/management_interface.proto @@ -43,6 +43,7 @@ service ManagementService { rpc SetOpenvpnMssfix(google.protobuf.UInt32Value) returns (google.protobuf.Empty) {} rpc SetWireguardMtu(google.protobuf.UInt32Value) returns (google.protobuf.Empty) {} rpc SetEnableIpv6(google.protobuf.BoolValue) returns (google.protobuf.Empty) {} + rpc SetQuantumResistantTunnel(google.protobuf.BoolValue) returns (google.protobuf.Empty) {} rpc SetDnsOptions(DnsOptions) returns (google.protobuf.Empty) {} // Account management |
