mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-20 19:31:00 +03:00
server: test that the unauthenticated cap is on before the handshake reads
hbb_common covers each transport's cap; nothing covered where the connection layer puts it. A header one byte over MAX_UNAUTHORIZED_MESSAGE, written to a connection stalled in the identity handshake, has to end the handshake on the header alone and release the connection's place: the test fails with the cap moved past the handshake or dropped. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab
This commit is contained in:
@@ -7252,6 +7252,41 @@ mod test {
|
|||||||
assert_eq!(unauthorized_count(), 0, "no handshake outlives the test");
|
assert_eq!(unauthorized_count(), 0, "no handshake outlives the test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The cap is on before the identity handshake reads. A header declaring one byte over it,
|
||||||
|
// written to the wire as the codec would read it, ends the handshake on the header alone -
|
||||||
|
// the payload is neither waited for nor read - and releases the place the connection held.
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_unauthorized_frame_is_refused_on_its_header() {
|
||||||
|
use hbb_common::tokio::io::AsyncWriteExt;
|
||||||
|
let _serial = UNAUTHORIZED_TESTS.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
|
let server = crate::server::new_for_test();
|
||||||
|
let listener = hbb_common::tcp::new_listener("127.0.0.1:0", false)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let (controller, accepted) = tokio::join!(
|
||||||
|
tokio::net::TcpStream::connect(listener.local_addr().unwrap()),
|
||||||
|
listener.accept()
|
||||||
|
);
|
||||||
|
let (mut controller, (accepted, addr)) = (controller.unwrap(), accepted.unwrap());
|
||||||
|
let served = Stream::Tcp(hbb_common::tcp::FramedStream::from(accepted, addr));
|
||||||
|
let handshake = tokio::spawn(async move {
|
||||||
|
crate::server::create_tcp_connection(server, served, addr, true, Default::default())
|
||||||
|
.await
|
||||||
|
});
|
||||||
|
let n = MAX_UNAUTHORIZED_MESSAGE + 1;
|
||||||
|
controller
|
||||||
|
.write_all(&(((n << 2) | 0x3) as u32).to_le_bytes())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
match hbb_common::timeout(2000, handshake).await {
|
||||||
|
Ok(Ok(Err(e))) => assert!(e.to_string().contains("Too big packet"), "{}", e),
|
||||||
|
Ok(Ok(Ok(_))) => panic!("a frame over the cap was accepted"),
|
||||||
|
Ok(Err(e)) => panic!("the handshake task panicked: {}", e),
|
||||||
|
Err(_) => panic!("the handshake waited for a payload the header should have refused"),
|
||||||
|
}
|
||||||
|
assert_eq!(unauthorized_count(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "flutter")]
|
#[cfg(feature = "flutter")]
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user