feat(network): support for eap peap networks

This commit is contained in:
Ashley Wulber 2025-03-10 18:52:42 -04:00 • committed by Ashley Wulber
parent 6afa338fdb
commit 43eae80b55
4 changed files with 105 additions and 17 deletions

2
Cargo.lock generated
View file

@ -1771,7 +1771,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-settings-subscriptions" name = "cosmic-settings-subscriptions"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-settings-subscriptions#f666c7cfcad79547e55a368640784bca51081bd2" source = "git+https://github.com/pop-os/cosmic-settings-subscriptions?branch=eap-peap#ad9c0d0d2df220b8c9336602be8458227e162b74"
dependencies = [ dependencies = [
"bluez-zbus", "bluez-zbus",
"cosmic-dbus-networkmanager", "cosmic-dbus-networkmanager",

View file

@ -90,6 +90,7 @@ num-derive = "0.4"
[dependencies.cosmic-settings-subscriptions] [dependencies.cosmic-settings-subscriptions]
git = "https://github.com/pop-os/cosmic-settings-subscriptions" git = "https://github.com/pop-os/cosmic-settings-subscriptions"
branch = "eap-peap"
#TODO: only select features as needed #TODO: only select features as needed
features = ["network_manager", "pipewire", "pulse", "bluetooth"] features = ["network_manager", "pipewire", "pulse", "bluetooth"]
optional = true optional = true

View file

@ -10,12 +10,17 @@ use anyhow::Context;
use cosmic::{ use cosmic::{
iced::{Alignment, Length}, iced::{Alignment, Length},
iced_core::text::Wrapping, iced_core::text::Wrapping,
widget::{self, icon}, iced_widget::focus_next,
widget::{self, column, icon},
Apply, Element, Task, Apply, Element, Task,
}; };
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use cosmic_settings_subscriptions::network_manager::{ use cosmic_settings_subscriptions::network_manager::{
self, available_wifi::AccessPoint, current_networks::ActiveConnectionInfo, NetworkManagerState, self,
available_wifi::{AccessPoint, NetworkType},
current_networks::ActiveConnectionInfo,
hw_address::HwAddress,
NetworkManagerState,
}; };
use futures::StreamExt; use futures::StreamExt;
use secure_string::SecureString; use secure_string::SecureString;
@ -36,6 +41,8 @@ pub enum Message {
Disconnect(network_manager::SSID), Disconnect(network_manager::SSID),
/// An error occurred. /// An error occurred.
Error(String), Error(String),
/// Identity update from the dialog
IdentityUpdate(String),
/// Create a dialog to ask for confirmation on forgetting a connection. /// Create a dialog to ask for confirmation on forgetting a connection.
ForgetRequest(network_manager::SSID), ForgetRequest(network_manager::SSID),
/// Forget a known access point. /// Forget a known access point.
@ -52,6 +59,8 @@ pub enum Message {
SelectDevice(Arc<network_manager::devices::DeviceInfo>), SelectDevice(Arc<network_manager::devices::DeviceInfo>),
/// Opens settings page for the access point. /// Opens settings page for the access point.
Settings(network_manager::SSID), Settings(network_manager::SSID),
/// Identity submitted from the dialog
SubmitIdentity,
/// Toggles visibility of the password input /// Toggles visibility of the password input
TogglePasswordVisibility, TogglePasswordVisibility,
/// Update NetworkManagerState /// Update NetworkManagerState
@ -81,6 +90,8 @@ enum WiFiDialog {
Forget(network_manager::SSID), Forget(network_manager::SSID),
Password { Password {
ssid: network_manager::SSID, ssid: network_manager::SSID,
hw_address: HwAddress,
identity: Option<String>,
password: SecureString, password: SecureString,
password_hidden: bool, password_hidden: bool,
}, },
@ -135,6 +146,7 @@ impl page::Page<crate::pages::Message> for Page {
self.dialog.as_ref().map(|dialog| match dialog { self.dialog.as_ref().map(|dialog| match dialog {
WiFiDialog::Password { WiFiDialog::Password {
password, password,
identity,
password_hidden, password_hidden,
.. ..
} => { } => {
@ -153,11 +165,25 @@ impl page::Page<crate::pages::Message> for Page {
let secondary_action = let secondary_action =
widget::button::standard(fl!("cancel")).on_press(Message::CancelDialog); widget::button::standard(fl!("cancel")).on_press(Message::CancelDialog);
let control: Element<_> = if let Some(identity) = identity {
column::column()
.spacing(8)
.push(
widget::text_input::text_input(fl!("identity"), identity)
.on_input(Message::IdentityUpdate)
.on_submit(|_| Message::SubmitIdentity),
)
.push(password)
.into()
} else {
password.into()
};
widget::dialog() widget::dialog()
.title(fl!("auth-dialog")) .title(fl!("auth-dialog"))
.icon(icon::from_name("preferences-wireless-symbolic").size(64)) .icon(icon::from_name("preferences-wireless-symbolic").size(64))
.body(fl!("auth-dialog", "wifi-description")) .body(fl!("auth-dialog", "wifi-description"))
.control(password) .control(control)
.primary_action(primary_action) .primary_action(primary_action)
.secondary_action(secondary_action) .secondary_action(secondary_action)
.apply(Element::from) .apply(Element::from)
@ -246,21 +272,28 @@ impl Page {
} }
match req { match req {
network_manager::Request::Password(ssid, _) => { network_manager::Request::Authenticate {
ssid,
identity,
hw_address,
..
} => {
if success { if success {
self.connecting.remove(&ssid); self.connecting.remove(ssid.as_str());
} else { } else {
// Request to retry // Request to retry
self.dialog = Some(WiFiDialog::Password { self.dialog = Some(WiFiDialog::Password {
ssid, ssid: ssid.into(),
identity,
hw_address,
password: SecureString::from(""), password: SecureString::from(""),
password_hidden: true, password_hidden: true,
}); });
} }
} }
network_manager::Request::SelectAccessPoint(ssid) => { network_manager::Request::SelectAccessPoint(ssid, hw_address, network_type) => {
self.connecting.remove(&ssid); self.connecting.remove(ssid.as_ref());
} }
_ => (), _ => (),
@ -324,19 +357,54 @@ impl Page {
Message::Connect(ssid) => { Message::Connect(ssid) => {
if let Some(nm) = self.nm_state.as_mut() { if let Some(nm) = self.nm_state.as_mut() {
let Some(ap) = nm
.state
.wireless_access_points
.iter()
.chain(nm.state.known_access_points.iter())
.find(|ap| ap.ssid == ssid)
else {
return Task::none();
};
self.connecting.insert(ssid.clone()); self.connecting.insert(ssid.clone());
_ = nm _ = nm
.sender .sender
.unbounded_send(network_manager::Request::SelectAccessPoint(ssid)); .unbounded_send(network_manager::Request::SelectAccessPoint(
ssid,
ap.hw_address,
ap.network_type,
));
}
}
Message::IdentityUpdate(new_identity) => {
if let Some(WiFiDialog::Password {
ref mut identity, ..
}) = self.dialog
{
*identity = Some(new_identity);
} }
} }
Message::PasswordRequest(ssid) => { Message::PasswordRequest(ssid) => {
self.dialog = Some(WiFiDialog::Password { if let Some(nm) = self.nm_state.as_mut() {
ssid, let Some(ap) = nm
password: SecureString::from(""), .state
password_hidden: true, .wireless_access_points
}); .iter()
.chain(nm.state.known_access_points.iter())
.find(|ap| ap.ssid == ssid)
else {
return Task::none();
};
self.dialog = Some(WiFiDialog::Password {
ssid,
identity: matches!(ap.network_type, NetworkType::EAP).then(String::new),
hw_address: ap.hw_address,
password: SecureString::from(""),
password_hidden: true,
});
}
} }
Message::PasswordUpdate(pass) => { Message::PasswordUpdate(pass) => {
@ -353,12 +421,24 @@ impl Page {
return Task::none(); return Task::none();
}; };
if let WiFiDialog::Password { ssid, password, .. } = dialog { if let WiFiDialog::Password {
ssid,
identity,
password,
hw_address,
..
} = dialog
{
if let Some(nm) = self.nm_state.as_mut() { if let Some(nm) = self.nm_state.as_mut() {
self.connecting.insert(ssid.clone()); self.connecting.insert(ssid.clone());
_ = nm _ = nm
.sender .sender
.unbounded_send(network_manager::Request::Password(ssid, password)); .unbounded_send(network_manager::Request::Authenticate {
ssid: ssid.to_string(),
identity,
hw_address,
password,
});
} }
} }
} }
@ -414,6 +494,12 @@ impl Page {
} }
} }
Message::SubmitIdentity => {
if self.dialog.is_some() {
return focus_next();
}
}
Message::WiFiEnable(enable) => { Message::WiFiEnable(enable) => {
if let Some(nm) = self.nm_state.as_mut() { if let Some(nm) = self.nm_state.as_mut() {
_ = nm _ = nm

View file

@ -34,6 +34,7 @@ remove = Remove
settings = Settings settings = Settings
username = Username username = Username
visible-networks = Visible Networks visible-networks = Visible Networks
identity = Identity
auth-dialog = Authentication Required auth-dialog = Authentication Required
.vpn-description = Enter the username and password required by the VPN service. .vpn-description = Enter the username and password required by the VPN service.