Skip to content

Commit

Permalink
WIP: 8021x
Browse files Browse the repository at this point in the history
  • Loading branch information
jcronenberg committed Sep 4, 2024
1 parent ee5b812 commit f767f83
Show file tree
Hide file tree
Showing 6 changed files with 492 additions and 2 deletions.
26 changes: 26 additions & 0 deletions rust/agama-lib/src/network/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,30 @@ impl Default for BondSettings {
}
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IEEE8021XSettings {
#[serde(skip_serializing_if = "Vec::is_empty", default)]
pub eap: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub identity: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub password: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ca_cert: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ca_cert_password: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub client_cert: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub client_cert_password: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub private_key: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub private_key_password: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub anonymous_identity: Option<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct NetworkDevice {
pub id: String,
Expand Down Expand Up @@ -105,6 +129,8 @@ pub struct NetworkConnection {
pub status: Option<Status>,
#[serde(skip_serializing_if = "is_zero", default)]
pub mtu: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub ieee_8021x: Option<IEEE8021XSettings>,
}

fn is_zero(u: &u32) -> bool {
Expand Down
2 changes: 2 additions & 0 deletions rust/agama-server/src/network/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub enum NetworkStateError {
InvalidWEPAuthAlg(String),
#[error("Invalid WEP key type: '{0}'")]
InvalidWEPKeyType(u32),
#[error("Invalid EAP method: '{0}'")]
InvalidEAPMethod(String),
}

impl From<NetworkStateError> for zbus::fdo::Error {
Expand Down
128 changes: 127 additions & 1 deletion rust/agama-server/src/network/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
//! * This module contains the types that represent the network concepts. They are supposed to be
//! agnostic from the real network service (e.g., NetworkManager).
use crate::network::error::NetworkStateError;
use agama_lib::network::settings::{BondSettings, NetworkConnection, WirelessSettings};
use agama_lib::network::settings::{
BondSettings, IEEE8021XSettings, NetworkConnection, WirelessSettings,
};
use agama_lib::network::types::{BondMode, DeviceState, DeviceType, Status, SSID};
use cidr::IpInet;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -490,6 +492,7 @@ pub struct Connection {
pub port_config: PortConfig,
pub match_config: MatchConfig,
pub config: ConnectionConfig,
pub ieee_8021x_config: Option<IEEE8021XConfig>,
}

impl Connection {
Expand Down Expand Up @@ -560,6 +563,7 @@ impl Default for Connection {
port_config: Default::default(),
match_config: Default::default(),
config: Default::default(),
ieee_8021x_config: Default::default(),
}
}
}
Expand Down Expand Up @@ -599,6 +603,10 @@ impl TryFrom<NetworkConnection> for Connection {
connection.config = config.into();
}

if let Some(ieee_8021x_config) = conn.ieee_8021x {
connection.ieee_8021x_config = Some(IEEE8021XConfig::try_from(ieee_8021x_config)?);
}

connection.ip_config.addresses = conn.addresses;
connection.ip_config.nameservers = conn.nameservers;
connection.ip_config.dns_searchlist = conn.dns_searchlist;
Expand Down Expand Up @@ -629,6 +637,9 @@ impl TryFrom<Connection> for NetworkConnection {
let interface = conn.interface;
let status = Some(conn.status);
let mtu = conn.mtu;
let ieee_8021x: Option<IEEE8021XSettings> = conn
.ieee_8021x_config
.and_then(|x| IEEE8021XSettings::try_from(x).ok());

let mut connection = NetworkConnection {
id,
Expand All @@ -644,6 +655,7 @@ impl TryFrom<Connection> for NetworkConnection {
interface,
addresses,
mtu,
ieee_8021x,
..Default::default()
};

Expand Down Expand Up @@ -1353,3 +1365,117 @@ pub enum NetworkChange {
/// device gets renamed.
DeviceUpdated(String, Device),
}

#[derive(Default, Debug, PartialEq, Clone, Serialize)]
pub struct IEEE8021XConfig {
pub eap: Vec<EAPMethod>,
pub identity: Option<String>,
pub password: Option<String>,
pub ca_cert: Option<String>,
pub ca_cert_password: Option<String>,
pub client_cert: Option<String>,
pub client_cert_password: Option<String>,
pub private_key: Option<String>,
pub private_key_password: Option<String>,
pub anonymous_identity: Option<String>,
}

impl TryFrom<IEEE8021XSettings> for IEEE8021XConfig {
type Error = NetworkStateError;

fn try_from(value: IEEE8021XSettings) -> Result<Self, Self::Error> {
let eap = value
.eap
.iter()
.map(|x| {
EAPMethod::from_str(x)
.map_err(|_| NetworkStateError::InvalidEAPMethod(x.to_string()))
})
.collect::<Result<Vec<EAPMethod>, NetworkStateError>>()?;

Ok(IEEE8021XConfig {
eap,
identity: value.identity,
password: value.password,
ca_cert: value.ca_cert,
ca_cert_password: value.ca_cert_password,
client_cert: value.client_cert,
client_cert_password: value.client_cert_password,
private_key: value.private_key,
private_key_password: value.private_key_password,
anonymous_identity: value.anonymous_identity,
})
}
}

impl TryFrom<IEEE8021XConfig> for IEEE8021XSettings {
type Error = NetworkStateError;

fn try_from(value: IEEE8021XConfig) -> Result<Self, Self::Error> {
let eap = value
.eap
.iter()
.map(|x| x.to_string())
.collect::<Vec<String>>();

Ok(IEEE8021XSettings {
eap,
identity: value.identity,
password: value.password,
ca_cert: value.ca_cert,
ca_cert_password: value.ca_cert_password,
client_cert: value.client_cert,
client_cert_password: value.client_cert_password,
private_key: value.private_key,
private_key_password: value.private_key_password,
anonymous_identity: value.anonymous_identity,
})
}
}

#[derive(Debug, Error)]
#[error("Invalid eap method: {0}")]
pub struct InvalidEAPMethod(String);

#[derive(Debug, PartialEq, Clone, Serialize)]
pub enum EAPMethod {
LEAP,
MD5,
TLS,
PEAP,
TTLS,
PWD,
FAST,
}

impl FromStr for EAPMethod {
type Err = InvalidEAPMethod;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"leap" => Ok(Self::LEAP),
"md5" => Ok(Self::MD5),
"tls" => Ok(Self::TLS),
"peap" => Ok(Self::PEAP),
"ttls" => Ok(Self::TTLS),
"pwd" => Ok(Self::PWD),
"fast" => Ok(Self::FAST),
_ => Err(InvalidEAPMethod(s.to_string())),
}
}
}

impl fmt::Display for EAPMethod {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let value = match &self {
Self::LEAP => "leap",
Self::MD5 => "md5",
Self::TLS => "tls",
Self::PEAP => "peap",
Self::TTLS => "ttls",
Self::PWD => "pwd",
Self::FAST => "fast",
};
write!(f, "{}", value)
}
}
Loading

0 comments on commit f767f83

Please sign in to comment.