diff --git a/rust/migrate-wicked/src/wireless.rs b/rust/migrate-wicked/src/wireless.rs index 93b39e0760..91d06a7110 100644 --- a/rust/migrate-wicked/src/wireless.rs +++ b/rust/migrate-wicked/src/wireless.rs @@ -22,7 +22,7 @@ pub struct Wireless { #[serde_as] #[skip_serializing_none] -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Serialize, Deserialize, Default)] pub struct Network { pub essid: String, #[serde(rename = "scan-ssid")] @@ -95,7 +95,7 @@ pub struct Wep { } #[serde_as] -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Serialize, Deserialize, Default)] pub struct WpaEap { pub method: WickedEapMethods, pub identity: Option, @@ -211,11 +211,20 @@ impl From<&EapAuthProto> for model::WPAProtocolVersion { } #[derive( - Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display, Clone, Copy, + Debug, + PartialEq, + SerializeDisplay, + DeserializeFromStr, + EnumString, + Display, + Clone, + Copy, + Default, )] #[strum(serialize_all = "snake_case")] pub enum WickedEapMethods { Wpa, + #[default] None, Md5, Tls, @@ -416,27 +425,93 @@ where Ok(Some(Networks::deserialize(deserializer)?.network)) } -fn wireless_security_protocol( - wicked_value: &[String], +fn all(array: &[String], needle: &[&str]) -> bool { + if array.is_empty() { + return false; + } + + array.iter().all(|x| needle.iter().any(|&y| x == y)) +} + +fn any(array: &[String], needle: &[&str]) -> bool { + if array.is_empty() { + return false; + } + + array.iter().any(|x| needle.iter().any(|&y| x == y)) +} + +fn guess_wireless_security_protocol( + network: &Network, ) -> Result { - if wicked_value.contains(&"wpa-psk".to_string()) - || wicked_value.contains(&"wpa-psk-sha256".to_string()) - { + let mgmt = &network.key_management; + + let v = if any(mgmt, &["wpa-eap", "wpa-eap-sha256"]) { + Ok(model::SecurityProtocol::WPA2Enterprise) + } else if any(mgmt, &["wpa-eap-suite-b-192", "wpa-eap-suite-b"]) { + Ok(model::SecurityProtocol::WPA3Only) + } else if any(mgmt, &["wpa-psk", "wpa-psk-sha256"]) { Ok(model::SecurityProtocol::WPA2) - } else if wicked_value.contains(&"sae".to_string()) { + } else if any(mgmt, &["sae", "ft-sae"]) { Ok(model::SecurityProtocol::WPA3Personal) - } else if wicked_value.contains(&"wpa-eap".to_string()) - || wicked_value.contains(&"wpa-eap-sha256".to_string()) - { - Ok(model::SecurityProtocol::WPA2Enterprise) - } else if wicked_value.contains(&"owe".to_string()) { + } else if any(mgmt, &["owe"]) { Ok(model::SecurityProtocol::OWE) - } else if wicked_value.contains(&"wpa-eap-suite-b-192".to_string()) { + } else if any(mgmt, &["none"]) { + Ok(model::SecurityProtocol::WEP) + } else if network.wpa_eap.is_some() { + Ok(model::SecurityProtocol::WPA2Enterprise) + } else if network.wpa_psk.is_some() { + Ok(model::SecurityProtocol::WPA2) + } else { + Ok(model::SecurityProtocol::WEP) + }; + log::warn!( + "Unsupported key-management protocol(s) '{}' guess '{}'", + mgmt.join(","), + match v { + Ok(s) => s.to_string(), + _ => "-".to_string(), + } + ); + v +} + +fn wireless_security_protocol(network: &Network) -> Result { + let mgmt = &network.key_management; + + if all(mgmt, &["sae", "ft-sae"]) { + Ok(model::SecurityProtocol::WPA3Personal) + } else if all(mgmt, &["wpa-psk", "wpa-psk-sha256", "sae", "ft-sae"]) { + Ok(model::SecurityProtocol::WPA2) + } else if all(mgmt, &["wpa-eap-suite-b-192", "wpa-eap-suite-b"]) { Ok(model::SecurityProtocol::WPA3Only) - } else if wicked_value.contains(&"none".to_string()) { + } else if all( + mgmt, + &[ + "wpa-eap", + "wpa-eap-sha256", + "wpa-eap-suite-b-192", + "wpa-eap-suite-b", + ], + ) { + Ok(model::SecurityProtocol::WPA2Enterprise) + } else if all(mgmt, &["owe"]) { + Ok(model::SecurityProtocol::OWE) + } else if all(mgmt, &["none"]) { Ok(model::SecurityProtocol::WEP) + } else if mgmt.is_empty() { + if network.wpa_eap.is_some() { + Ok(model::SecurityProtocol::WPA2Enterprise) + } else if network.wpa_psk.is_some() { + Ok(model::SecurityProtocol::WPA2) + } else { + Ok(model::SecurityProtocol::WEP) + } } else { - Err(anyhow!("Unrecognized key-management protocol")) + Err(anyhow!( + "Unrecognized key-management protocol(s): {}", + mgmt.join(",") + )) } } @@ -451,14 +526,16 @@ impl TryFrom<&Network> for model::ConnectionConfig { ..Default::default() }; - if network.key_management.len() > 1 && settings.continue_migration { - log::warn!("Migration of multiple key-management algorithms isn't supported") - } else if network.key_management.len() > 1 { - return Err(anyhow!( - "Migration of multiple key-management algorithms isn't supported" - )); - } - config.security = wireless_security_protocol(&network.key_management)?; + config.security = match wireless_security_protocol(network) { + Ok(sec) => Ok(sec), + Err(e) => { + if settings.continue_migration { + guess_wireless_security_protocol(network) + } else { + Err(e) + } + } + }?; if let Some(wpa_psk) = &network.wpa_psk { config.password = Some(wpa_psk.passphrase.clone()); @@ -639,4 +716,147 @@ mod tests { ); assert_eq!(wireless.band, Some("bg".try_into().unwrap())); } + + #[test] + fn wireless_security_protocol_strict() { + setup_default_migration_settings(); + + let mut net = Network { + ..Default::default() + }; + + net.key_management = vec![]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WEP + ); + + net.key_management = vec![]; + net.wpa_eap = Some(WpaEap { + ..Default::default() + }); + + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2Enterprise + ); + + net.wpa_eap = None; + net.wpa_psk = Some(WpaPsk { + ..Default::default() + }); + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2 + ); + + net.wpa_psk = None; + net.key_management = vec!["wpa-psk".to_string()]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2 + ); + net.key_management = vec!["sae".to_string(), "wpa-psk".to_string()]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2 + ); + net.key_management = vec!["sae".to_string()]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA3Personal + ); + + net.key_management = vec!["wpa-eap".to_string()]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2Enterprise + ); + net.key_management = vec!["wpa-eap".to_string(), "wpa-eap-suite-b".to_string()]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2Enterprise + ); + net.key_management = vec!["wpa-eap-suite-b".to_string()]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA3Only + ); + + net.key_management = vec!["owe".to_string()]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::OWE + ); + + net.key_management = vec!["none".to_string()]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WEP + ); + + net.key_management = vec!["none".to_string(), "wpa-psk".to_string()]; + assert!(!wireless_security_protocol(&net).is_ok()); + net.key_management = vec!["wpa-eap".to_string(), "wpa-psk".to_string()]; + assert!(!wireless_security_protocol(&net).is_ok()); + net.key_management = vec!["wpa-eap".to_string(), "sae".to_string()]; + assert!(!wireless_security_protocol(&net).is_ok()); + net.key_management = vec!["wpa-eap-suite-b".to_string(), "sae".to_string()]; + assert!(!wireless_security_protocol(&net).is_ok()); + net.key_management = vec!["wpa-eap-suite-b".to_string(), "owe".to_string()]; + assert!(!wireless_security_protocol(&net).is_ok()); + net.key_management = vec!["wpa-psk".to_string(), "owe".to_string()]; + assert!(!wireless_security_protocol(&net).is_ok()); + } + + #[test] + fn wireless_security_protocol_continue_migration() { + setup_default_migration_settings(); + + let mut net = Network { + ..Default::default() + }; + + net.key_management = vec![]; + assert_eq!( + wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WEP + ); + + net.key_management = vec![]; + net.wpa_eap = Some(WpaEap { + ..Default::default() + }); + + net.key_management = vec!["none".to_string(), "wpa-psk".to_string()]; + assert_eq!( + guess_wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2 + ); + net.key_management = vec!["wpa-eap".to_string(), "wpa-psk".to_string()]; + assert_eq!( + guess_wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2Enterprise + ); + net.key_management = vec!["wpa-eap".to_string(), "sae".to_string()]; + assert_eq!( + guess_wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2Enterprise + ); + net.key_management = vec!["wpa-eap-suite-b".to_string(), "sae".to_string()]; + assert_eq!( + guess_wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA3Only + ); + net.key_management = vec!["wpa-eap-suite-b".to_string(), "owe".to_string()]; + assert_eq!( + guess_wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA3Only + ); + net.key_management = vec!["wpa-psk".to_string(), "owe".to_string()]; + assert_eq!( + guess_wireless_security_protocol(&net).unwrap(), + model::SecurityProtocol::WPA2 + ); + } } diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan0-0.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan0-0.nmconnection index 48a8c6f36e..d25bca2a2f 100644 --- a/rust/migrate-wicked/tests/wireless/system-connections/wlan0-0.nmconnection +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan0-0.nmconnection @@ -1,6 +1,6 @@ [connection] id=wlan0-0 -uuid=1089cc84-f99f-4bb8-8a0d-fafde6544e85 +uuid=2a262d6e-ccba-4afb-a190-ec08d0175c56 type=wifi interface-name=wlan0 diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan0-1.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan0-1.nmconnection index a4a21b4957..24f42377c7 100644 --- a/rust/migrate-wicked/tests/wireless/system-connections/wlan0-1.nmconnection +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan0-1.nmconnection @@ -1,6 +1,6 @@ [connection] id=wlan0-1 -uuid=b0c56f00-cf58-4c6c-b6dd-edf97a612063 +uuid=e05ab8eb-9905-4746-b81a-54e190b16354 type=wifi interface-name=wlan0 diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan1.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan1.nmconnection index a42db83883..919820c398 100644 --- a/rust/migrate-wicked/tests/wireless/system-connections/wlan1.nmconnection +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan1.nmconnection @@ -1,13 +1,13 @@ [connection] id=wlan1 -uuid=3bc52d5e-4095-4e1a-9976-d46f766bb627 +uuid=9d48ef42-2c96-4e43-8ab6-6c66385efdb6 type=wifi interface-name=wlan1 [wifi] bssid=12:34:56:78:9A:BC mode=infrastructure -ssid=test +ssid=wep_1 [wifi-security] auth-alg=shared diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan2-0.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan2-0.nmconnection new file mode 100644 index 0000000000..c80743a477 --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan2-0.nmconnection @@ -0,0 +1,24 @@ +[connection] +id=wlan2-0 +uuid=81ea2b2d-e6bb-4897-aded-de95eb298de5 +type=wifi +interface-name=wlan2 + +[wifi] +hidden=true +mode=infrastructure +ssid=open_1 + +[wifi-security] +key-mgmt=none + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan2-1.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan2-1.nmconnection new file mode 100644 index 0000000000..ddccf8d711 --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan2-1.nmconnection @@ -0,0 +1,23 @@ +[connection] +id=wlan2-1 +uuid=30a3966f-3005-4cab-bc0d-48b47d2d2ce6 +type=wifi +interface-name=wlan2 + +[wifi] +mode=infrastructure +ssid=open_2 + +[wifi-security] +key-mgmt=none + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan3-0.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan3-0.nmconnection new file mode 100644 index 0000000000..d8a4b82e5f --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan3-0.nmconnection @@ -0,0 +1,25 @@ +[connection] +id=wlan3-0 +uuid=899c6026-3000-4ca2-8526-216471cef61a +type=wifi +interface-name=wlan3 + +[wifi] +hidden=true +mode=infrastructure +ssid=psk_1 + +[wifi-security] +key-mgmt=wpa-psk +psk=total_geheim!! + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan3-1.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan3-1.nmconnection new file mode 100644 index 0000000000..084c4b3362 --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan3-1.nmconnection @@ -0,0 +1,24 @@ +[connection] +id=wlan3-1 +uuid=f2465ff2-fc04-46ff-88be-b14805f0e972 +type=wifi +interface-name=wlan3 + +[wifi] +mode=infrastructure +ssid=psk_2 + +[wifi-security] +key-mgmt=wpa-psk +psk=total_geheim!! + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan3-2.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan3-2.nmconnection new file mode 100644 index 0000000000..a7b14173f3 --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan3-2.nmconnection @@ -0,0 +1,24 @@ +[connection] +id=wlan3-2 +uuid=8676060a-0b82-4207-b0a2-a3420992ac2c +type=wifi +interface-name=wlan3 + +[wifi] +mode=infrastructure +ssid=psk_3 + +[wifi-security] +key-mgmt=sae +psk=total_geheim!! + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan3-3.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan3-3.nmconnection new file mode 100644 index 0000000000..0ef959e5bc --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan3-3.nmconnection @@ -0,0 +1,24 @@ +[connection] +id=wlan3-3 +uuid=c2f7bf46-9d1c-4dc0-b347-ac8973d1feb9 +type=wifi +interface-name=wlan3 + +[wifi] +mode=infrastructure +ssid=psk_4 + +[wifi-security] +key-mgmt=wpa-psk +psk=total_geheim!! + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan4-0.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan4-0.nmconnection new file mode 100644 index 0000000000..d958d1ba61 --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan4-0.nmconnection @@ -0,0 +1,32 @@ +[connection] +id=wlan4-0 +uuid=10de7698-31f0-4af8-a55f-a4526f6693de +type=wifi +interface-name=wlan4 + +[wifi] +hidden=true +mode=infrastructure +ssid=eap_1 + +[wifi-security] +key-mgmt=wpa-eap + +[802-1x] +anonymous-identity=anonymous +eap=peap; +identity=tester +password=test1234 +phase1-peaplabel=0 +phase2-auth=mschapv2 + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan4-1.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan4-1.nmconnection new file mode 100644 index 0000000000..29333f7d0f --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan4-1.nmconnection @@ -0,0 +1,32 @@ +[connection] +id=wlan4-1 +uuid=2b177278-d460-4c93-95bb-c01bfca3782f +type=wifi +interface-name=wlan4 + +[wifi] +hidden=true +mode=infrastructure +ssid=eap_2 + +[wifi-security] +key-mgmt=wpa-eap + +[802-1x] +anonymous-identity=anonymous +eap=peap; +identity=tester +password=test1234 +phase1-peaplabel=0 +phase2-auth=mschapv2 + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan4-2.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan4-2.nmconnection new file mode 100644 index 0000000000..e6d7d541ba --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan4-2.nmconnection @@ -0,0 +1,32 @@ +[connection] +id=wlan4-2 +uuid=06236476-7fdb-4d3d-97e6-a24ec71fbf44 +type=wifi +interface-name=wlan4 + +[wifi] +hidden=true +mode=infrastructure +ssid=eap_3 + +[wifi-security] +key-mgmt=wpa-eap-suite-b-192 + +[802-1x] +anonymous-identity=anonymous +eap=peap; +identity=tester +password=test1234 +phase1-peaplabel=0 +phase2-auth=mschapv2 + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/system-connections/wlan4-3.nmconnection b/rust/migrate-wicked/tests/wireless/system-connections/wlan4-3.nmconnection new file mode 100644 index 0000000000..c79b91f961 --- /dev/null +++ b/rust/migrate-wicked/tests/wireless/system-connections/wlan4-3.nmconnection @@ -0,0 +1,32 @@ +[connection] +id=wlan4-3 +uuid=f8adfd38-7127-4a25-bddd-a65e8add0887 +type=wifi +interface-name=wlan4 + +[wifi] +hidden=true +mode=infrastructure +ssid=eap_4 + +[wifi-security] +key-mgmt=wpa-eap + +[802-1x] +anonymous-identity=anonymous +eap=peap; +identity=tester +password=test1234 +phase1-peaplabel=0 +phase2-auth=mschapv2 + +[match] + +[ipv4] +method=disabled + +[ipv6] +addr-gen-mode=default +method=disabled + +[proxy] diff --git a/rust/migrate-wicked/tests/wireless/wicked_xml/wireless.xml b/rust/migrate-wicked/tests/wireless/wicked_xml/wireless.xml index 0edebaf1ce..dc9456d647 100644 --- a/rust/migrate-wicked/tests/wireless/wicked_xml/wireless.xml +++ b/rust/migrate-wicked/tests/wireless/wicked_xml/wireless.xml @@ -53,7 +53,7 @@ 1 - test + wep_1 false infrastructure 12:34:56:78:9a:bc @@ -75,3 +75,182 @@ false + + wlan2 + + auto + + + + 1 + + + open_1 + true + infrastructure + + + open_2 + false + infrastructure + none + + + + + + false + + + false + + + + wlan3 + + boot + + + + 1 + + + psk_1 + true + infrastructure + + total_geheim!! + + + + psk_2 + false + infrastructure + wpa-psk + + total_geheim!! + + + + psk_3 + false + infrastructure + sae + + total_geheim!! + + + + psk_4 + false + infrastructure + none,wpa-psk + + total_geheim!! + + + + + + + false + + + false + + + + wlan4 + + boot + + + + 1 + nl80211 + + + eap_1 + true + infrastructure + + peap + tester + + false + + + mschapv2 + test1234 + + anonymous + + + + + eap_2 + true + infrastructure + wpa-eap + + peap + tester + + false + + + mschapv2 + test1234 + + anonymous + + + + + eap_3 + true + infrastructure + wpa-eap-suite-b + + peap + tester + + false + + + mschapv2 + test1234 + + anonymous + + + + + eap_4 + true + infrastructure + wpa-psk,wpa-eap + + peap + tester + + false + + + mschapv2 + test1234 + + anonymous + + + + + + + + false + + + false + +