Fix stale client rejection and terminal cursor mode
This commit is contained in:
+24
-3
@@ -9,8 +9,8 @@ use dosh::auth::{
|
|||||||
use dosh::config::{expand_tilde, load_client_config, load_server_config};
|
use dosh::config::{expand_tilde, load_client_config, load_server_config};
|
||||||
use dosh::crypto;
|
use dosh::crypto;
|
||||||
use dosh::protocol::{
|
use dosh::protocol::{
|
||||||
self, AttachOk, BootstrapAttachRequest, CLIENT_TO_SERVER, Frame, Input, PacketKind, Resize,
|
self, AttachOk, AttachReject, BootstrapAttachRequest, CLIENT_TO_SERVER, Frame, Input,
|
||||||
ResumeRequest, SERVER_TO_CLIENT, TicketAttachBody, TicketAttachEnvelope,
|
PacketKind, Resize, ResumeRequest, SERVER_TO_CLIENT, TicketAttachBody, TicketAttachEnvelope,
|
||||||
TicketAttachOkEnvelope,
|
TicketAttachOkEnvelope,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -633,6 +633,10 @@ async fn run_terminal(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PacketKind::Pong => {}
|
PacketKind::Pong => {}
|
||||||
|
PacketKind::AttachReject => {
|
||||||
|
let reject: AttachReject = protocol::from_body(&packet.body)?;
|
||||||
|
return Err(anyhow!("server rejected session: {}", reject.reason));
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -773,7 +777,7 @@ impl RawMode {
|
|||||||
fn enter() -> Result<Self> {
|
fn enter() -> Result<Self> {
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
let mut stdout = std::io::stdout();
|
let mut stdout = std::io::stdout();
|
||||||
stdout.write_all(TERMINAL_CLEANUP)?;
|
stdout.write_all(TERMINAL_OPEN)?;
|
||||||
stdout.flush()?;
|
stdout.flush()?;
|
||||||
Ok(Self)
|
Ok(Self)
|
||||||
}
|
}
|
||||||
@@ -788,6 +792,23 @@ impl Drop for RawMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TERMINAL_OPEN: &[u8] = concat!(
|
||||||
|
"\x1b[?1l",
|
||||||
|
"\x1b[0m",
|
||||||
|
"\x1b[?25h",
|
||||||
|
"\x1b[?1003l",
|
||||||
|
"\x1b[?1002l",
|
||||||
|
"\x1b[?1001l",
|
||||||
|
"\x1b[?1000l",
|
||||||
|
"\x1b[?1015l",
|
||||||
|
"\x1b[?1006l",
|
||||||
|
"\x1b[?1005l",
|
||||||
|
"\x1b[?2004l",
|
||||||
|
"\x1b[?1049l",
|
||||||
|
"\x1b[?1h"
|
||||||
|
)
|
||||||
|
.as_bytes();
|
||||||
|
|
||||||
const TERMINAL_CLEANUP: &[u8] = concat!(
|
const TERMINAL_CLEANUP: &[u8] = concat!(
|
||||||
"\x1b[?1l",
|
"\x1b[?1l",
|
||||||
"\x1b[0m",
|
"\x1b[0m",
|
||||||
|
|||||||
+15
-1
@@ -226,6 +226,11 @@ async fn handle_packet(
|
|||||||
handle_ticket_attach(state, socket, peer, packet.body).await
|
handle_ticket_attach(state, socket, peer, packet.body).await
|
||||||
}
|
}
|
||||||
PacketKind::ResumeRequest => handle_resume(state, socket, peer, &packet).await,
|
PacketKind::ResumeRequest => handle_resume(state, socket, peer, &packet).await,
|
||||||
|
PacketKind::Input | PacketKind::Resize | PacketKind::Ping | PacketKind::Ack
|
||||||
|
if find_client_key(state, &packet.header.conn_id).is_err() =>
|
||||||
|
{
|
||||||
|
send_reject_to_client(socket, peer, packet.header.conn_id, "unknown client").await
|
||||||
|
}
|
||||||
PacketKind::Input => handle_input(state, peer, &packet).await,
|
PacketKind::Input => handle_input(state, peer, &packet).await,
|
||||||
PacketKind::Resize => handle_resize(state, peer, &packet).await,
|
PacketKind::Resize => handle_resize(state, peer, &packet).await,
|
||||||
PacketKind::Ping => handle_ping(state, socket, peer, &packet).await,
|
PacketKind::Ping => handle_ping(state, socket, peer, &packet).await,
|
||||||
@@ -425,10 +430,19 @@ async fn handle_ticket_attach(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn send_reject(socket: &UdpSocket, peer: SocketAddr, reason: &str) -> Result<()> {
|
async fn send_reject(socket: &UdpSocket, peer: SocketAddr, reason: &str) -> Result<()> {
|
||||||
|
send_reject_to_client(socket, peer, [0u8; 16], reason).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_reject_to_client(
|
||||||
|
socket: &UdpSocket,
|
||||||
|
peer: SocketAddr,
|
||||||
|
client_id: [u8; 16],
|
||||||
|
reason: &str,
|
||||||
|
) -> Result<()> {
|
||||||
let body = protocol::to_body(&AttachReject {
|
let body = protocol::to_body(&AttachReject {
|
||||||
reason: reason.to_string(),
|
reason: reason.to_string(),
|
||||||
})?;
|
})?;
|
||||||
let out = protocol::encode_plain(PacketKind::AttachReject, [0u8; 16], 0, 0, &body)?;
|
let out = protocol::encode_plain(PacketKind::AttachReject, client_id, 0, 0, &body)?;
|
||||||
socket.send_to(&out, peer).await?;
|
socket.send_to(&out, peer).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ use dosh::auth::{build_bootstrap, load_or_create_server_secret};
|
|||||||
use dosh::config::load_server_config;
|
use dosh::config::load_server_config;
|
||||||
use dosh::crypto;
|
use dosh::crypto;
|
||||||
use dosh::protocol::{
|
use dosh::protocol::{
|
||||||
self, AttachOk, BootstrapAttachRequest, CLIENT_TO_SERVER, Frame, Input, PacketKind, Resize,
|
self, AttachOk, AttachReject, BootstrapAttachRequest, CLIENT_TO_SERVER, Frame, Input,
|
||||||
ResumeRequest, SERVER_TO_CLIENT,
|
PacketKind, Resize, ResumeRequest, SERVER_TO_CLIENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn free_udp_port() -> u16 {
|
fn free_udp_port() -> u16 {
|
||||||
@@ -176,6 +176,45 @@ fn collect_frame_text(socket: &UdpSocket, key: &[u8; 32], millis: u64) -> String
|
|||||||
text
|
text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unknown_live_client_gets_reject() {
|
||||||
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
let port = free_udp_port();
|
||||||
|
let config = write_server_config(&dir, port);
|
||||||
|
let mut server = start_server(&dir, &config);
|
||||||
|
let socket = std::net::UdpSocket::bind("127.0.0.1:0").unwrap();
|
||||||
|
socket
|
||||||
|
.set_read_timeout(Some(Duration::from_secs(2)))
|
||||||
|
.unwrap();
|
||||||
|
let client_id = crypto::random_16();
|
||||||
|
let key = crypto::random_32();
|
||||||
|
let packet = protocol::encode_encrypted(
|
||||||
|
PacketKind::Ping,
|
||||||
|
client_id,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
&key,
|
||||||
|
CLIENT_TO_SERVER,
|
||||||
|
b"",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
socket
|
||||||
|
.send_to(&packet, format!("127.0.0.1:{port}"))
|
||||||
|
.unwrap();
|
||||||
|
let mut buf = [0u8; 65535];
|
||||||
|
let (n, _) = socket.recv_from(&mut buf).unwrap();
|
||||||
|
let packet = protocol::decode(&buf[..n]).unwrap();
|
||||||
|
let reject: AttachReject = protocol::from_body(&packet.body).unwrap();
|
||||||
|
|
||||||
|
let _ = server.kill();
|
||||||
|
let _ = server.wait();
|
||||||
|
|
||||||
|
assert_eq!(packet.header.kind, PacketKind::AttachReject);
|
||||||
|
assert_eq!(packet.header.conn_id, client_id);
|
||||||
|
assert_eq!(reject.reason, "unknown client");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn local_attach_only_smoke() {
|
fn local_attach_only_smoke() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user