feat(network): support for eap peap networks
This commit is contained in:
parent
4f1ef57fe2
commit
31afd3fa8b
4 changed files with 265 additions and 129 deletions
|
|
@ -3,6 +3,7 @@ airplane-mode = Airplane mode
|
||||||
airplane-mode-on = Airplane mode is on
|
airplane-mode-on = Airplane mode is on
|
||||||
turn-off-airplane-mode = Turn off to enable Wi-Fi, Bluetooth and mobile broadband.
|
turn-off-airplane-mode = Turn off to enable Wi-Fi, Bluetooth and mobile broadband.
|
||||||
wifi = Wi-Fi
|
wifi = Wi-Fi
|
||||||
|
identity = Identity
|
||||||
ipv4 = IPv4 address
|
ipv4 = IPv4 address
|
||||||
ipv6 = IPv6 address
|
ipv6 = IPv6 address
|
||||||
mac = MAC
|
mac = MAC
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,14 @@ use zbus::Connection;
|
||||||
use crate::{
|
use crate::{
|
||||||
config, fl,
|
config, fl,
|
||||||
network_manager::{
|
network_manager::{
|
||||||
active_conns::active_conns_subscription, available_wifi::AccessPoint,
|
active_conns::active_conns_subscription,
|
||||||
current_networks::ActiveConnectionInfo, devices::devices_subscription,
|
available_wifi::{AccessPoint, NetworkType},
|
||||||
hw_address::HwAddress, network_manager_subscription,
|
current_networks::ActiveConnectionInfo,
|
||||||
wireless_enabled::wireless_enabled_subscription, NetworkManagerEvent,
|
devices::devices_subscription,
|
||||||
NetworkManagerRequest, NetworkManagerState,
|
hw_address::HwAddress,
|
||||||
|
network_manager_subscription,
|
||||||
|
wireless_enabled::wireless_enabled_subscription,
|
||||||
|
NetworkManagerEvent, NetworkManagerRequest, NetworkManagerState,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -50,6 +53,7 @@ pub fn run() -> cosmic::iced::Result {
|
||||||
enum NewConnectionState {
|
enum NewConnectionState {
|
||||||
EnterPassword {
|
EnterPassword {
|
||||||
access_point: AccessPoint,
|
access_point: AccessPoint,
|
||||||
|
identity: String,
|
||||||
password: String,
|
password: String,
|
||||||
password_hidden: bool,
|
password_hidden: bool,
|
||||||
},
|
},
|
||||||
|
|
@ -235,6 +239,7 @@ pub(crate) enum Message {
|
||||||
SelectWirelessAccessPoint(AccessPoint),
|
SelectWirelessAccessPoint(AccessPoint),
|
||||||
CancelNewConnection,
|
CancelNewConnection,
|
||||||
Password(String),
|
Password(String),
|
||||||
|
Identity(String),
|
||||||
SubmitPassword,
|
SubmitPassword,
|
||||||
Frame(Instant),
|
Frame(Instant),
|
||||||
Token(TokenUpdate),
|
Token(TokenUpdate),
|
||||||
|
|
@ -331,41 +336,57 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
success,
|
success,
|
||||||
req,
|
req,
|
||||||
} => {
|
} => {
|
||||||
if let NetworkManagerRequest::SelectAccessPoint(ssid, hw_address) = &req {
|
if let NetworkManagerRequest::SelectAccessPoint(
|
||||||
let conn_match = self
|
ssid,
|
||||||
.new_connection
|
hw_address,
|
||||||
.as_ref()
|
_network_type,
|
||||||
.map(|c| c.ssid() == ssid && c.hw_address() == *hw_address)
|
) = &req
|
||||||
.unwrap_or_default();
|
{
|
||||||
if conn_match && success {
|
let conn_match = self
|
||||||
if let Some(s) =
|
.new_connection
|
||||||
state.active_conns.iter_mut().find(|ap| &ap.name() == ssid && ap.hw_address() == *hw_address)
|
.as_ref()
|
||||||
{
|
.map(|c| c.ssid() == ssid && c.hw_address() == *hw_address)
|
||||||
match s {
|
.unwrap_or_default();
|
||||||
ActiveConnectionInfo::WiFi { state, .. } => {
|
|
||||||
*state = ActiveConnectionState::Activated;
|
if conn_match && success {
|
||||||
}
|
if let Some(s) = state
|
||||||
_ => {}
|
.active_conns
|
||||||
};
|
.iter_mut()
|
||||||
|
.find(|ap| &ap.name() == ssid && ap.hw_address() == *hw_address)
|
||||||
|
{
|
||||||
|
match s {
|
||||||
|
ActiveConnectionInfo::WiFi { state, .. } => {
|
||||||
|
*state = ActiveConnectionState::Activated;
|
||||||
}
|
}
|
||||||
self.failed_known_ssids.remove(ssid);
|
_ => {}
|
||||||
self.new_connection = None;
|
};
|
||||||
self.show_visible_networks = false;
|
}
|
||||||
} else if !matches!(
|
self.failed_known_ssids.remove(ssid);
|
||||||
&self.new_connection,
|
self.new_connection = None;
|
||||||
Some(NewConnectionState::EnterPassword { .. })
|
self.show_visible_networks = false;
|
||||||
)
|
} else if !matches!(
|
||||||
{
|
&self.new_connection,
|
||||||
self.failed_known_ssids.insert(ssid.clone());
|
Some(NewConnectionState::EnterPassword { .. })
|
||||||
}
|
) {
|
||||||
} else if let NetworkManagerRequest::Password(ssid, _, hw_address) = &req {
|
self.failed_known_ssids.insert(ssid.clone());
|
||||||
if let Some(NewConnectionState::Waiting(access_point)) =
|
}
|
||||||
self.new_connection.clone()
|
} else if let NetworkManagerRequest::Authenticate {
|
||||||
{
|
ssid,
|
||||||
if !success && ssid == &access_point.ssid && *hw_address == access_point.hw_address {
|
identity: _,
|
||||||
self.new_connection =
|
password: _,
|
||||||
Some(NewConnectionState::Failure(access_point.clone()));
|
hw_address,
|
||||||
} else {
|
} = &req
|
||||||
|
{
|
||||||
|
if let Some(NewConnectionState::Waiting(access_point)) =
|
||||||
|
self.new_connection.clone()
|
||||||
|
{
|
||||||
|
if !success
|
||||||
|
&& ssid == &access_point.ssid
|
||||||
|
&& *hw_address == access_point.hw_address
|
||||||
|
{
|
||||||
|
self.new_connection =
|
||||||
|
Some(NewConnectionState::Failure(access_point.clone()));
|
||||||
|
} else {
|
||||||
self.new_connection = None;
|
self.new_connection = None;
|
||||||
self.show_visible_networks = false;
|
self.show_visible_networks = false;
|
||||||
}
|
}
|
||||||
|
|
@ -412,13 +433,19 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
let _ = tx.unbounded_send(NetworkManagerRequest::SelectAccessPoint(
|
let _ = tx.unbounded_send(NetworkManagerRequest::SelectAccessPoint(
|
||||||
access_point.ssid.clone(),
|
access_point.ssid.clone(),
|
||||||
access_point.hw_address,
|
access_point.hw_address,
|
||||||
|
access_point.network_type,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.new_connection = Some(NewConnectionState::EnterPassword {
|
if matches!(access_point.network_type, NetworkType::Open) {
|
||||||
access_point,
|
self.new_connection = Some(NewConnectionState::Waiting(access_point));
|
||||||
password: String::new(),
|
} else {
|
||||||
password_hidden: true,
|
self.new_connection = Some(NewConnectionState::EnterPassword {
|
||||||
});
|
access_point,
|
||||||
|
identity: String::new(),
|
||||||
|
password: String::new(),
|
||||||
|
password_hidden: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Message::ToggleVisibleNetworks => {
|
Message::ToggleVisibleNetworks => {
|
||||||
self.new_connection = None;
|
self.new_connection = None;
|
||||||
|
|
@ -450,19 +477,24 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
if let Some(NewConnectionState::EnterPassword {
|
if let Some(NewConnectionState::EnterPassword {
|
||||||
password,
|
password,
|
||||||
access_point,
|
access_point,
|
||||||
|
identity,
|
||||||
..
|
..
|
||||||
}) = self.new_connection.take()
|
}) = self.new_connection.take()
|
||||||
{
|
{
|
||||||
let _ = tx.unbounded_send(NetworkManagerRequest::Password(
|
let is_enterprise: bool = matches!(access_point.network_type, NetworkType::EAP);
|
||||||
access_point.ssid.clone(),
|
|
||||||
password,
|
let _ = tx.unbounded_send(NetworkManagerRequest::Authenticate {
|
||||||
access_point.hw_address,
|
ssid: access_point.ssid.clone(),
|
||||||
));
|
identity: is_enterprise.then(|| identity.clone()),
|
||||||
|
password: password,
|
||||||
|
hw_address: access_point.hw_address,
|
||||||
|
});
|
||||||
self.new_connection
|
self.new_connection
|
||||||
.replace(NewConnectionState::Waiting(access_point));
|
.replace(NewConnectionState::Waiting(access_point));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Message::ActivateKnownWifi(ssid, hw_address) => {
|
Message::ActivateKnownWifi(ssid, hw_address) => {
|
||||||
|
let mut network_type = NetworkType::Open;
|
||||||
let tx = if let Some(tx) = self.nm_sender.as_ref() {
|
let tx = if let Some(tx) = self.nm_sender.as_ref() {
|
||||||
if let Some(ap) = self
|
if let Some(ap) = self
|
||||||
.nm_state
|
.nm_state
|
||||||
|
|
@ -470,14 +502,18 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.find(|c| c.ssid == ssid && c.hw_address == hw_address)
|
.find(|c| c.ssid == ssid && c.hw_address == hw_address)
|
||||||
{
|
{
|
||||||
|
network_type = ap.network_type;
|
||||||
ap.working = true;
|
ap.working = true;
|
||||||
}
|
}
|
||||||
tx
|
tx
|
||||||
} else {
|
} else {
|
||||||
return Task::none();
|
return Task::none();
|
||||||
};
|
};
|
||||||
let _ =
|
let _ = tx.unbounded_send(NetworkManagerRequest::SelectAccessPoint(
|
||||||
tx.unbounded_send(NetworkManagerRequest::SelectAccessPoint(ssid, hw_address));
|
ssid,
|
||||||
|
hw_address,
|
||||||
|
network_type,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Message::CancelNewConnection => {
|
Message::CancelNewConnection => {
|
||||||
self.new_connection = None;
|
self.new_connection = None;
|
||||||
|
|
@ -570,6 +606,13 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
cosmic::app::Action::Surface(a),
|
cosmic::app::Action::Surface(a),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
Message::Identity(new_identity) => {
|
||||||
|
if let Some(NewConnectionState::EnterPassword { identity, .. }) =
|
||||||
|
&mut self.new_connection
|
||||||
|
{
|
||||||
|
*identity = new_identity;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
@ -964,6 +1007,7 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
match new_conn_state {
|
match new_conn_state {
|
||||||
NewConnectionState::EnterPassword {
|
NewConnectionState::EnterPassword {
|
||||||
access_point,
|
access_point,
|
||||||
|
identity,
|
||||||
password,
|
password,
|
||||||
password_hidden,
|
password_hidden,
|
||||||
} => {
|
} => {
|
||||||
|
|
@ -978,30 +1022,38 @@ impl cosmic::Application for CosmicNetworkApplet {
|
||||||
.spacing(12),
|
.spacing(12),
|
||||||
);
|
);
|
||||||
content = content.push(id);
|
content = content.push(id);
|
||||||
let enter_password_col = column![
|
|
||||||
text::body(fl!("enter-password")),
|
let is_enterprise = matches!(access_point.network_type, NetworkType::EAP);
|
||||||
text_input::secure_input(
|
let enter_password_col = column![]
|
||||||
"",
|
.push_maybe(is_enterprise.then(|| text::body(fl!("identity"))))
|
||||||
password,
|
.push_maybe(is_enterprise.then(|| {
|
||||||
Some(Message::TogglePasswordVisibility),
|
text_input::text_input("", identity).on_input(Message::Identity)
|
||||||
*password_hidden,
|
}))
|
||||||
|
.push(text::body(fl!("enter-password")))
|
||||||
|
.push(
|
||||||
|
text_input::secure_input(
|
||||||
|
"",
|
||||||
|
password,
|
||||||
|
Some(Message::TogglePasswordVisibility),
|
||||||
|
*password_hidden,
|
||||||
|
)
|
||||||
|
.on_input(Message::Password)
|
||||||
|
.on_paste(Message::Password)
|
||||||
|
.on_submit(|_| Message::SubmitPassword),
|
||||||
)
|
)
|
||||||
.on_input(Message::Password)
|
.push_maybe(
|
||||||
.on_paste(Message::Password)
|
access_point.wps_push.then(|| {
|
||||||
.on_submit(|_| Message::SubmitPassword)
|
container(text::body(fl!("router-wps-button"))).padding(8)
|
||||||
]
|
}),
|
||||||
.push_maybe(
|
)
|
||||||
access_point
|
.push(
|
||||||
.wps_push
|
row![
|
||||||
.then(|| container(text::body(fl!("router-wps-button"))).padding(8)),
|
button::standard(fl!("cancel"))
|
||||||
)
|
.on_press(Message::CancelNewConnection),
|
||||||
.push(
|
button::suggested(fl!("connect")).on_press(Message::SubmitPassword)
|
||||||
row![
|
]
|
||||||
button::standard(fl!("cancel")).on_press(Message::CancelNewConnection),
|
.spacing(24),
|
||||||
button::suggested(fl!("connect")).on_press(Message::SubmitPassword)
|
);
|
||||||
]
|
|
||||||
.spacing(24),
|
|
||||||
);
|
|
||||||
let col =
|
let col =
|
||||||
padded_control(enter_password_col.spacing(8).align_x(Alignment::Center))
|
padded_control(enter_password_col.spacing(8).align_x(Alignment::Center))
|
||||||
.align_x(Alignment::Center);
|
.align_x(Alignment::Center);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@
|
||||||
|
|
||||||
use cosmic_dbus_networkmanager::{
|
use cosmic_dbus_networkmanager::{
|
||||||
device::wireless::WirelessDevice,
|
device::wireless::WirelessDevice,
|
||||||
interface::enums::{ApFlags, DeviceState},
|
interface::{
|
||||||
|
access_point::AccessPointProxy,
|
||||||
|
enums::{ApFlags, ApSecurityFlags, DeviceState},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
|
|
@ -42,7 +45,22 @@ pub async fn handle_wireless_device(
|
||||||
if access_point.strength > strength {
|
if access_point.strength > strength {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
let proxy: &AccessPointProxy = ≈
|
||||||
|
let Ok(flags) = ap.rsn_flags().await else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let network_type = if flags.intersects(ApSecurityFlags::KEY_MGMT_802_1X) {
|
||||||
|
NetworkType::EAP
|
||||||
|
} else if flags.intersects(ApSecurityFlags::KEY_MGMTPSK) {
|
||||||
|
NetworkType::PSK
|
||||||
|
} else if flags.is_empty() {
|
||||||
|
NetworkType::Open
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
aps.insert(
|
aps.insert(
|
||||||
ssid.clone(),
|
ssid.clone(),
|
||||||
AccessPoint {
|
AccessPoint {
|
||||||
|
|
@ -56,6 +74,7 @@ pub async fn handle_wireless_device(
|
||||||
.and_then(|str_addr| HwAddress::from_str(str_addr))
|
.and_then(|str_addr| HwAddress::from_str(str_addr))
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
wps_push,
|
wps_push,
|
||||||
|
network_type,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -75,4 +94,15 @@ pub struct AccessPoint {
|
||||||
pub path: ObjectPath<'static>,
|
pub path: ObjectPath<'static>,
|
||||||
pub hw_address: HwAddress,
|
pub hw_address: HwAddress,
|
||||||
pub wps_push: bool,
|
pub wps_push: bool,
|
||||||
|
pub network_type: NetworkType,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO do we want to support eap methods other than peap in the applet?
|
||||||
|
// Then we'd need a dropdown for the eap method,
|
||||||
|
// and tls requires a cert instead of a password
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum NetworkType {
|
||||||
|
Open,
|
||||||
|
PSK,
|
||||||
|
EAP,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ pub mod wireless_enabled;
|
||||||
|
|
||||||
use std::{collections::HashMap, fmt::Debug, time::Duration};
|
use std::{collections::HashMap, fmt::Debug, time::Duration};
|
||||||
|
|
||||||
|
use available_wifi::NetworkType;
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
iced::{self, Subscription},
|
iced::{self, Subscription},
|
||||||
iced_futures::stream,
|
iced_futures::stream,
|
||||||
|
|
@ -186,39 +187,52 @@ async fn start_listening(
|
||||||
};
|
};
|
||||||
_ = output.send(response).await;
|
_ = output.send(response).await;
|
||||||
}
|
}
|
||||||
Some(NetworkManagerRequest::Password(ssid, password, hw_address)) => {
|
Some(NetworkManagerRequest::Authenticate {
|
||||||
|
ssid,
|
||||||
|
identity,
|
||||||
|
password,
|
||||||
|
hw_address,
|
||||||
|
}) => {
|
||||||
let nm_state = NetworkManagerState::new(&conn).await.unwrap_or_default();
|
let nm_state = NetworkManagerState::new(&conn).await.unwrap_or_default();
|
||||||
let success = nm_state
|
let mut success = true;
|
||||||
.connect_wifi(&conn, &ssid, Some(&password), hw_address)
|
let err = nm_state
|
||||||
.await
|
.connect_wifi(
|
||||||
.is_ok();
|
&conn,
|
||||||
|
&ssid,
|
||||||
let status = Some(NetworkManagerEvent::RequestResponse {
|
identity.as_deref(),
|
||||||
req: NetworkManagerRequest::Password(
|
Some(&password),
|
||||||
ssid.clone(),
|
|
||||||
password.clone(),
|
|
||||||
hw_address,
|
hw_address,
|
||||||
),
|
)
|
||||||
success,
|
.await;
|
||||||
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(e) = status {
|
if let Err(err) = err {
|
||||||
_ = output.send(e).await;
|
success = false;
|
||||||
} else {
|
tracing::error!("{:?}", &err);
|
||||||
_ = output
|
|
||||||
.send(NetworkManagerEvent::RequestResponse {
|
|
||||||
req: NetworkManagerRequest::Password(ssid, password, hw_address),
|
|
||||||
success: false,
|
|
||||||
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ = output
|
||||||
|
.send(NetworkManagerEvent::RequestResponse {
|
||||||
|
req: NetworkManagerRequest::Authenticate {
|
||||||
|
ssid: ssid.clone(),
|
||||||
|
identity: identity.clone(),
|
||||||
|
password: password.clone(),
|
||||||
|
hw_address,
|
||||||
|
},
|
||||||
|
success,
|
||||||
|
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
|
||||||
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
Some(NetworkManagerRequest::SelectAccessPoint(ssid, hw_address)) => {
|
Some(NetworkManagerRequest::SelectAccessPoint(ssid, hw_address, network_type)) => {
|
||||||
|
// wait for identity before attempting to connect.
|
||||||
|
if !matches!(network_type, NetworkType::Open) {
|
||||||
|
return State::Waiting(conn, rx);
|
||||||
|
}
|
||||||
let state = NetworkManagerState::new(&conn).await.unwrap_or_default();
|
let state = NetworkManagerState::new(&conn).await.unwrap_or_default();
|
||||||
let success = if let Err(err) =
|
|
||||||
state.connect_wifi(&conn, &ssid, None, hw_address).await
|
let success = if let Err(err) = state
|
||||||
|
.connect_wifi(&conn, &ssid, None, None, hw_address)
|
||||||
|
.await
|
||||||
{
|
{
|
||||||
tracing::error!("Failed to connect to access point: {:?}", err);
|
tracing::error!("Failed to connect to access point: {:?}", err);
|
||||||
false
|
false
|
||||||
|
|
@ -228,7 +242,11 @@ async fn start_listening(
|
||||||
|
|
||||||
_ = output
|
_ = output
|
||||||
.send(NetworkManagerEvent::RequestResponse {
|
.send(NetworkManagerEvent::RequestResponse {
|
||||||
req: NetworkManagerRequest::SelectAccessPoint(ssid.clone(), hw_address),
|
req: NetworkManagerRequest::SelectAccessPoint(
|
||||||
|
ssid.clone(),
|
||||||
|
hw_address,
|
||||||
|
network_type,
|
||||||
|
),
|
||||||
success,
|
success,
|
||||||
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
|
state: NetworkManagerState::new(&conn).await.unwrap_or_default(),
|
||||||
})
|
})
|
||||||
|
|
@ -287,9 +305,14 @@ async fn start_listening(
|
||||||
pub enum NetworkManagerRequest {
|
pub enum NetworkManagerRequest {
|
||||||
SetAirplaneMode(bool),
|
SetAirplaneMode(bool),
|
||||||
SetWiFi(bool),
|
SetWiFi(bool),
|
||||||
SelectAccessPoint(String, HwAddress),
|
SelectAccessPoint(String, HwAddress, NetworkType),
|
||||||
Disconnect(String, HwAddress),
|
Disconnect(String, HwAddress),
|
||||||
Password(String, String, HwAddress),
|
Authenticate {
|
||||||
|
ssid: String,
|
||||||
|
identity: Option<String>,
|
||||||
|
password: String,
|
||||||
|
hw_address: HwAddress,
|
||||||
|
},
|
||||||
Forget(String, HwAddress),
|
Forget(String, HwAddress),
|
||||||
Reload,
|
Reload,
|
||||||
}
|
}
|
||||||
|
|
@ -415,6 +438,15 @@ impl NetworkManagerState {
|
||||||
.collect();
|
.collect();
|
||||||
wireless_access_points.sort_by(|a, b| b.strength.cmp(&a.strength));
|
wireless_access_points.sort_by(|a, b| b.strength.cmp(&a.strength));
|
||||||
self_.wireless_access_points = wireless_access_points;
|
self_.wireless_access_points = wireless_access_points;
|
||||||
|
for ap in &self_.wireless_access_points {
|
||||||
|
tracing::info!(
|
||||||
|
"AP ssid: {},\ttype: {:?},\tworking: {},\tstate: {:?}",
|
||||||
|
ap.ssid,
|
||||||
|
ap.network_type,
|
||||||
|
ap.working,
|
||||||
|
ap.state
|
||||||
|
)
|
||||||
|
}
|
||||||
self_.active_conns = active_conns;
|
self_.active_conns = active_conns;
|
||||||
self_.known_access_points = known_access_points;
|
self_.known_access_points = known_access_points;
|
||||||
self_.connectivity = network_manager.connectivity().await?;
|
self_.connectivity = network_manager.connectivity().await?;
|
||||||
|
|
@ -433,6 +465,7 @@ impl NetworkManagerState {
|
||||||
&self,
|
&self,
|
||||||
conn: &Connection,
|
conn: &Connection,
|
||||||
ssid: &str,
|
ssid: &str,
|
||||||
|
identity: Option<&str>,
|
||||||
password: Option<&str>,
|
password: Option<&str>,
|
||||||
hw_address: HwAddress,
|
hw_address: HwAddress,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
|
@ -470,7 +503,26 @@ impl NetworkManagerState {
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if let Some(pass) = password {
|
if let Some(identity) = identity {
|
||||||
|
conn_settings.insert(
|
||||||
|
"802-1x",
|
||||||
|
HashMap::from([
|
||||||
|
("identity", Value::Str(identity.into())),
|
||||||
|
// most common default
|
||||||
|
("eap", Value::Array(vec!["peap"].into())),
|
||||||
|
// most common default
|
||||||
|
("phase2-auth", Value::Str("mschapv2".into())),
|
||||||
|
("password", Value::Str(password.unwrap_or("").into())),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
let wireless = conn_settings.get_mut("802-11-wireless").unwrap();
|
||||||
|
wireless.insert("security", Value::Str("802-11-wireless-security".into()));
|
||||||
|
wireless.insert("mode", Value::Str("infrastructure".into()));
|
||||||
|
conn_settings.insert(
|
||||||
|
"802-11-wireless-security",
|
||||||
|
HashMap::from([("key-mgmt", Value::Str("wpa-eap".into()))]),
|
||||||
|
);
|
||||||
|
} else if let Some(pass) = password {
|
||||||
conn_settings.insert(
|
conn_settings.insert(
|
||||||
"802-11-wireless-security",
|
"802-11-wireless-security",
|
||||||
HashMap::from([
|
HashMap::from([
|
||||||
|
|
@ -543,30 +595,31 @@ impl NetworkManagerState {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
ActiveConnection::from(active)
|
ActiveConnection::from(active)
|
||||||
};
|
};
|
||||||
|
let mut changes = active_conn.receive_state_changed().await;
|
||||||
_ = tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
|
_ = tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
|
||||||
let mut state =
|
let mut count = 5;
|
||||||
enums::ActiveConnectionState::from(active_conn.state().await.unwrap_or_default());
|
loop {
|
||||||
return match state {
|
let state = active_conn.state().await;
|
||||||
ActiveConnectionState::Activating => {
|
if let Ok(enums::ActiveConnectionState::Activated) = state {
|
||||||
if let Ok(Some(s)) = tokio::time::timeout(
|
return Ok(());
|
||||||
Duration::from_secs(20),
|
} else if let Ok(enums::ActiveConnectionState::Deactivated) = state {
|
||||||
active_conn.receive_state_changed().await.next(),
|
anyhow::bail!("Failed to activate connection");
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
state = s.get().await.unwrap_or_default().into();
|
|
||||||
if matches!(state, enums::ActiveConnectionState::Activated) {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(anyhow::anyhow!("Failed to activate connection"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Err(anyhow::anyhow!("Failed to activate connection"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ActiveConnectionState::Activated => Ok(()),
|
match tokio::time::timeout(Duration::from_secs(20), changes.next()).await {
|
||||||
_ => Err(anyhow::anyhow!("Failed to activate connection")),
|
Ok(Some(s)) => {
|
||||||
};
|
let state = s.get().await.unwrap_or_default().into();
|
||||||
|
if matches!(state, enums::ActiveConnectionState::Activated) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
count -= 1;
|
||||||
|
if count <= 0 {
|
||||||
|
anyhow::bail!("Failed to activate connection");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(anyhow::anyhow!("No wifi device found"))
|
Err(anyhow::anyhow!("No wifi device found"))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue