only allow clients that are already registered

This commit is contained in:
soruh 2023-07-09 00:43:52 +02:00
parent 76502f5e00
commit 7ba68cedbd
2 changed files with 34 additions and 18 deletions

View File

@ -16,11 +16,19 @@ use crate::{
auth::dyn_ip_update,
constants::{AUTH_TIMEOUT, CALL_ACK_TIMEOUT, CALL_TIMEOUT, PING_TIMEOUT, SEND_PING_INTERVAL},
http::peer_query,
packets::{Header, Packet, PacketKind, RemConnect, REJECT_OOP, REJECT_TIMEOUT},
packets::{
Header, Packet, PacketKind, RemConnect, REJECT_OOP, REJECT_TIMEOUT, REJECT_UNKNOWN_CLIENT,
},
ports::{PortHandler, PortStatus},
Config, HandlerMetadata,
};
pub enum AuthResult {
OutOfPorts,
UnknownClient,
Success { port: u16 },
}
/// # Errors
/// - the client authentication fails
#[instrument(skip(config, port_handler, handler_metadata))]
@ -30,7 +38,16 @@ async fn authenticate(
handler_metadata: &mut HandlerMetadata,
number: u32,
pin: u16,
) -> eyre::Result<Option<u16>> {
) -> eyre::Result<AuthResult> {
// TODO: do we want to cache this? If so, for how long?
let name = peer_query(&config.dyn_ip_server, number).await?;
let Some(name) = name else {
return Ok(AuthResult::UnknownClient);
};
info!(%name, "found client");
let mut authenticated = false;
loop {
let mut updated_server = false;
@ -41,7 +58,7 @@ async fn authenticate(
.allocate_port_for_number(config, number);
let Some(port) = port else {
return Ok(None);
return Ok(AuthResult::OutOfPorts);
};
// make sure the client is authenticated before opening any ports
@ -71,19 +88,10 @@ async fn authenticate(
let _ip = dyn_ip_update(&config.dyn_ip_server, number, pin, port).await?;
}
// TODO: do we want to cache this? If so, for how long?
#[cfg(feature = "debug_server")]
let name = peer_query(&config.dyn_ip_server, number).await?;
let mut port_handler = port_handler.lock().await;
#[cfg(feature = "debug_server")]
if let Some(name) = name {
info!(%name, "found client name");
port_handler.names.insert(number, name);
}
port_handler.register_update();
port_handler.names.insert(number, name);
port_handler
.port_state
.entry(port)
@ -92,7 +100,7 @@ async fn authenticate(
handler_metadata.port = Some(port);
break Ok(Some(port));
break Ok(AuthResult::Success { port });
}
port_handler.lock().await.mark_port_error(number, port);
@ -340,9 +348,16 @@ pub async fn handler(
handler_metadata.number = Some(number);
let Some(port) = authenticate(config, port_handler, handler_metadata, number, pin).await? else {
let port = match authenticate(config, port_handler, handler_metadata, number, pin).await? {
AuthResult::OutOfPorts => {
writer.write_all(REJECT_OOP).await?;
return Ok(());
}
AuthResult::UnknownClient => {
writer.write_all(REJECT_UNKNOWN_CLIENT).await?;
return Ok(());
}
AuthResult::Success { port } => port,
};
info!(%addr, number, port, "authenticated");

View File

@ -10,6 +10,7 @@ use tokio::{
pub const REJECT_OOP: &[u8; 6] = b"\x04\x04oop\x00";
pub const REJECT_TIMEOUT: &[u8; 10] = b"\x04\x08timeout\x00";
pub const REJECT_UNKNOWN_CLIENT: &[u8; 17] = b"\x04\x0funknown client\x00";
#[derive(Debug)]
pub enum Error {