test: RDP through an SSH tunnel, end to end
An opt-in integration test tunnels through the test sshd (direct-tcpip) to a real RDP server and checks that desktop updates arrive — the route VNC already used, now verified for RDP (against xrdp).
This commit is contained in:
@@ -335,3 +335,50 @@ fn host_and_user_certificates() {
|
|||||||
let err = c.connect(never_asked, None, None).unwrap_err().to_string();
|
let err = c.connect(never_asked, None, None).unwrap_err().to_string();
|
||||||
assert!(err.contains("trusted CA"), "{err}");
|
assert!(err.contains("trusted CA"), "{err}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// RDP over an SSH tunnel through the test sshd:
|
||||||
|
/// `NEXUS_RDP_TEST="host port user password" cargo test --test ssh_integration rdp_through -- --ignored`
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn rdp_through_ssh_tunnel() {
|
||||||
|
let spec = std::env::var("NEXUS_RDP_TEST").expect("NEXUS_RDP_TEST");
|
||||||
|
let v: Vec<String> = spec.split_whitespace().map(String::from).collect();
|
||||||
|
let Some(s) = start("rdptunnel") else { return };
|
||||||
|
let t = SshClient::new(&profile(&s), Callbacks::noop());
|
||||||
|
t.connect_tunnel_only(accept_all().0, None, None).unwrap();
|
||||||
|
let (host, port) = (v[0].clone(), v[1].parse::<u16>().unwrap());
|
||||||
|
let frames = Arc::new(std::sync::atomic::AtomicUsize::new(0));
|
||||||
|
let f2 = frames.clone();
|
||||||
|
let tt = t.clone();
|
||||||
|
let c = nexus_core::clients::rdp::Client::new(nexus_core::clients::rdp::Config {
|
||||||
|
host: host.clone(),
|
||||||
|
username: v[2].clone(),
|
||||||
|
domain: String::new(),
|
||||||
|
password: zeroize::Zeroizing::new(v[3].clone()),
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
allow_tls_only: true,
|
||||||
|
audio: false,
|
||||||
|
kerberos_kdc: None,
|
||||||
|
shared_folder: None,
|
||||||
|
printer: None,
|
||||||
|
dial: Arc::new(move || tt.open_tunnel(&host, port)),
|
||||||
|
check_cert: Arc::new(|_| Ok(())),
|
||||||
|
connect_timeout: Duration::from_secs(20),
|
||||||
|
on_frame: Arc::new(move || {
|
||||||
|
f2.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
|
||||||
|
}),
|
||||||
|
on_clipboard: Arc::new(|_| {}),
|
||||||
|
on_error: Arc::new(|e| eprintln!("on_error: {e}")),
|
||||||
|
on_close: Arc::new(|| {}),
|
||||||
|
});
|
||||||
|
c.connect().unwrap();
|
||||||
|
let start = Instant::now();
|
||||||
|
while frames.load(std::sync::atomic::Ordering::SeqCst) == 0 && start.elapsed() < Duration::from_secs(30) {
|
||||||
|
std::thread::sleep(Duration::from_millis(100));
|
||||||
|
}
|
||||||
|
eprintln!("frames over the tunnel: {}", frames.load(std::sync::atomic::Ordering::SeqCst));
|
||||||
|
assert!(frames.load(std::sync::atomic::Ordering::SeqCst) > 0);
|
||||||
|
c.close();
|
||||||
|
t.close();
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user