//! Comprehensive test suite for third-party WireGuard Upstream .conf parsing and validation. use nx9_wg_core::crypto::generate_keypair; use nx9_wg_core::types::wireguard::InterfaceRole; use nx9_wireguard::UpstreamConfigParser; use uuid::Uuid; #[test] fn test_valid_proton_style_configuration() { let (priv_k, pub_k) = generate_keypair(); let (_, peer_pub_k) = generate_keypair(); let conf = format!( r#" # ProtonVPN WireGuard Configuration [Interface] PrivateKey = {} Address = 10.2.0.2/32 DNS = 10.2.0.1 MTU = 1420 [Peer] # Server Node PublicKey = {} AllowedIPs = 0.0.0.0/0, ::/0 Endpoint = 37.19.199.155:51820 PersistentKeepalive = 25 "#, priv_k.as_str(), peer_pub_k.as_str() ); let parsed = UpstreamConfigParser::parse(&conf, "proton0").expect("parse proton config"); assert_eq!(parsed.interface_name, "proton0"); assert_eq!(parsed.public_key.as_str(), pub_k.as_str()); assert_eq!(parsed.address_v4.to_string(), "10.2.0.2/32"); assert_eq!(parsed.address_v6, None); assert_eq!(parsed.dns, Some("10.2.0.1".to_string())); assert_eq!(parsed.mtu, Some(1420)); assert_eq!(parsed.listen_port, None); assert_eq!(parsed.peer.name, "proton0-provider"); assert_eq!(parsed.peer.public_key.as_str(), peer_pub_k.as_str()); assert_eq!(parsed.peer.endpoint, "37.19.199.155:51820"); assert_eq!(parsed.peer.allowed_ips, "0.0.0.0/0, ::/0"); assert_eq!(parsed.peer.persistent_keepalive, Some(25)); assert_eq!(parsed.peer.preshared_key, None); let iface_id = Uuid::new_v4(); let peer_id = Uuid::new_v4(); let (iface, peer) = parsed.into_desired_state(iface_id, peer_id); assert_eq!(iface.id, iface_id); assert_eq!(iface.name, "proton0"); assert_eq!(iface.role, InterfaceRole::Upstream); assert_eq!(iface.listen_port, None); assert!(iface.enabled); assert_eq!(peer.id, peer_id); assert_eq!(peer.interface_id, iface_id); assert_eq!(peer.name, "proton0-provider"); assert_eq!(peer.allowed_ips, "0.0.0.0/0, ::/0"); assert_eq!( peer.server_wireguard_allowed_ips_for_role(InterfaceRole::Upstream), "0.0.0.0/0, ::/0" ); } #[test] fn test_omitted_listen_port_remains_unspecified() { let (priv_k, _) = generate_keypair(); let (_, peer_pub_k) = generate_keypair(); let conf = format!( "[Interface]\nPrivateKey = {}\nAddress = 10.2.0.2/32\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0, ::/0\nEndpoint = 37.19.199.155:51820\n", priv_k.as_str(), peer_pub_k.as_str() ); let parsed = UpstreamConfigParser::parse(&conf, "proton0").expect("parse config"); assert_eq!(parsed.listen_port, None); assert_eq!(parsed.peer.endpoint, "37.19.199.155:51820"); } #[test] fn test_explicit_listen_port_is_preserved() { let (priv_k, _) = generate_keypair(); let (_, peer_pub_k) = generate_keypair(); let conf = format!( "[Interface]\nPrivateKey = {}\nAddress = 10.2.0.2/32\nListenPort = 45000\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0, ::/0\nEndpoint = 37.19.199.155:51820\n", priv_k.as_str(), peer_pub_k.as_str() ); let parsed = UpstreamConfigParser::parse(&conf, "proton0").expect("parse config"); assert_eq!(parsed.listen_port, Some(45000)); } #[test] fn test_endpoint_port_is_not_local_listen_port() { let (priv_k, _) = generate_keypair(); let (_, peer_pub_k) = generate_keypair(); let conf = format!( "[Interface]\nPrivateKey = {}\nAddress = 10.2.0.2/32\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0, ::/0\nEndpoint = 37.19.199.155:51820\n", priv_k.as_str(), peer_pub_k.as_str() ); let parsed = UpstreamConfigParser::parse(&conf, "proton0").expect("parse config"); assert_eq!(parsed.listen_port, None); assert!(parsed.peer.endpoint.ends_with(":51820")); } #[test] fn test_dual_stack_address_and_preshared_key() { let (priv_k, _) = generate_keypair(); let (_, peer_pub_k) = generate_keypair(); let (psk, _) = generate_keypair(); let conf = format!( r#" [Interface] PrivateKey = {} Address = 10.2.0.2/32, fd00::2/64 DNS = 10.2.0.1, 1.1.1.1 [Peer] PublicKey = {} PresharedKey = {} AllowedIPs = 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 Endpoint = vpn.example.com:51820 "#, priv_k.as_str(), peer_pub_k.as_str(), psk.as_str() ); let parsed = UpstreamConfigParser::parse(&conf, "vpn0").expect("parse dual stack"); assert_eq!(parsed.address_v4.to_string(), "10.2.0.2/32"); assert_eq!( parsed.address_v6.map(|ip| ip.to_string()), Some("fd00::2/64".to_string()) ); assert_eq!(parsed.dns, Some("10.2.0.1, 1.1.1.1".to_string())); assert!(parsed.peer.preshared_key.is_some()); assert_eq!(parsed.peer.preshared_key.unwrap().as_str(), psk.as_str()); } #[test] fn test_reject_wg0_interface_name() { let (priv_k, _) = generate_keypair(); let (_, peer_pub_k) = generate_keypair(); let conf = format!( "[Interface]\nPrivateKey = {}\nAddress = 10.2.0.2/32\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0\nEndpoint = 1.2.3.4:51820\n", priv_k.as_str(), peer_pub_k.as_str() ); let err = UpstreamConfigParser::parse(&conf, "wg0").unwrap_err(); assert!(err.to_string().contains("reserved name 'wg0'")); } #[test] fn test_cardinality_rejections() { let (priv_k, _) = generate_keypair(); let (_, peer_pub_k) = generate_keypair(); // 0 peers let no_peers = format!( "[Interface]\nPrivateKey = {}\nAddress = 10.2.0.2/32\n", priv_k.as_str() ); assert!(UpstreamConfigParser::parse(&no_peers, "proton0").is_err()); // 2 peers let multi_peers = format!( r#" [Interface] PrivateKey = {} Address = 10.2.0.2/32 [Peer] PublicKey = {} AllowedIPs = 0.0.0.0/0 Endpoint = 1.2.3.4:51820 [Peer] PublicKey = {} AllowedIPs = 0.0.0.0/0 Endpoint = 5.6.7.8:51820 "#, priv_k.as_str(), peer_pub_k.as_str(), peer_pub_k.as_str() ); let err = UpstreamConfigParser::parse(&multi_peers, "proton0").unwrap_err(); assert!(err.to_string().contains("exactly one [Peer] section")); // Missing [Interface] let no_iface = format!( "[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0\nEndpoint = 1.2.3.4:51820\n", peer_pub_k.as_str() ); assert!(UpstreamConfigParser::parse(&no_iface, "proton0").is_err()); } #[test] fn test_missing_and_malformed_fields_rejections() { let (_, peer_pub_k) = generate_keypair(); // Missing PrivateKey let no_priv = format!( "[Interface]\nAddress = 10.2.0.2/32\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0\nEndpoint = 1.2.3.4:51820\n", peer_pub_k.as_str() ); assert!(UpstreamConfigParser::parse(&no_priv, "proton0").is_err()); // Malformed PrivateKey let bad_priv = format!( "[Interface]\nPrivateKey = not-a-key\nAddress = 10.2.0.2/32\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0\nEndpoint = 1.2.3.4:51820\n", peer_pub_k.as_str() ); assert!(UpstreamConfigParser::parse(&bad_priv, "proton0").is_err()); // Missing Address let (priv_k, _) = generate_keypair(); let no_addr = format!( "[Interface]\nPrivateKey = {}\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0\nEndpoint = 1.2.3.4:51820\n", priv_k.as_str(), peer_pub_k.as_str() ); assert!(UpstreamConfigParser::parse(&no_addr, "proton0").is_err()); // Malformed Address let bad_addr = format!( "[Interface]\nPrivateKey = {}\nAddress = 999.999.999.999/99\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0\nEndpoint = 1.2.3.4:51820\n", priv_k.as_str(), peer_pub_k.as_str() ); assert!(UpstreamConfigParser::parse(&bad_addr, "proton0").is_err()); // Missing PublicKey let no_pub = format!( "[Interface]\nPrivateKey = {}\nAddress = 10.2.0.2/32\n[Peer]\nAllowedIPs = 0.0.0.0/0\nEndpoint = 1.2.3.4:51820\n", priv_k.as_str() ); assert!(UpstreamConfigParser::parse(&no_pub, "proton0").is_err()); // Missing Endpoint let no_ep = format!( "[Interface]\nPrivateKey = {}\nAddress = 10.2.0.2/32\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0\n", priv_k.as_str(), peer_pub_k.as_str() ); assert!(UpstreamConfigParser::parse(&no_ep, "proton0").is_err()); // Missing AllowedIPs let no_aips = format!( "[Interface]\nPrivateKey = {}\nAddress = 10.2.0.2/32\n[Peer]\nPublicKey = {}\nEndpoint = 1.2.3.4:51820\n", priv_k.as_str(), peer_pub_k.as_str() ); assert!(UpstreamConfigParser::parse(&no_aips, "proton0").is_err()); // Unknown section let unknown_sec = format!( "[Interface]\nPrivateKey = {}\nAddress = 10.2.0.2/32\n[Unknown]\nKey = Val\n[Peer]\nPublicKey = {}\nAllowedIPs = 0.0.0.0/0\nEndpoint = 1.2.3.4:51820\n", priv_k.as_str(), peer_pub_k.as_str() ); assert!(UpstreamConfigParser::parse(&unknown_sec, "proton0").is_err()); }