only allow clients that are already registered
This commit is contained in:
parent
76502f5e00
commit
7ba68cedbd
@ -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");
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user