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,
|
auth::dyn_ip_update,
|
||||||
constants::{AUTH_TIMEOUT, CALL_ACK_TIMEOUT, CALL_TIMEOUT, PING_TIMEOUT, SEND_PING_INTERVAL},
|
constants::{AUTH_TIMEOUT, CALL_ACK_TIMEOUT, CALL_TIMEOUT, PING_TIMEOUT, SEND_PING_INTERVAL},
|
||||||
http::peer_query,
|
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},
|
ports::{PortHandler, PortStatus},
|
||||||
Config, HandlerMetadata,
|
Config, HandlerMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub enum AuthResult {
|
||||||
|
OutOfPorts,
|
||||||
|
UnknownClient,
|
||||||
|
Success { port: u16 },
|
||||||
|
}
|
||||||
|
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// - the client authentication fails
|
/// - the client authentication fails
|
||||||
#[instrument(skip(config, port_handler, handler_metadata))]
|
#[instrument(skip(config, port_handler, handler_metadata))]
|
||||||
@ -30,7 +38,16 @@ async fn authenticate(
|
|||||||
handler_metadata: &mut HandlerMetadata,
|
handler_metadata: &mut HandlerMetadata,
|
||||||
number: u32,
|
number: u32,
|
||||||
pin: u16,
|
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;
|
let mut authenticated = false;
|
||||||
loop {
|
loop {
|
||||||
let mut updated_server = false;
|
let mut updated_server = false;
|
||||||
@ -41,7 +58,7 @@ async fn authenticate(
|
|||||||
.allocate_port_for_number(config, number);
|
.allocate_port_for_number(config, number);
|
||||||
|
|
||||||
let Some(port) = port else {
|
let Some(port) = port else {
|
||||||
return Ok(None);
|
return Ok(AuthResult::OutOfPorts);
|
||||||
};
|
};
|
||||||
|
|
||||||
// make sure the client is authenticated before opening any ports
|
// 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?;
|
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;
|
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.register_update();
|
||||||
|
|
||||||
|
port_handler.names.insert(number, name);
|
||||||
port_handler
|
port_handler
|
||||||
.port_state
|
.port_state
|
||||||
.entry(port)
|
.entry(port)
|
||||||
@ -92,7 +100,7 @@ async fn authenticate(
|
|||||||
|
|
||||||
handler_metadata.port = Some(port);
|
handler_metadata.port = Some(port);
|
||||||
|
|
||||||
break Ok(Some(port));
|
break Ok(AuthResult::Success { port });
|
||||||
}
|
}
|
||||||
|
|
||||||
port_handler.lock().await.mark_port_error(number, port);
|
port_handler.lock().await.mark_port_error(number, port);
|
||||||
@ -340,9 +348,16 @@ pub async fn handler(
|
|||||||
|
|
||||||
handler_metadata.number = Some(number);
|
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? {
|
||||||
writer.write_all(REJECT_OOP).await?;
|
AuthResult::OutOfPorts => {
|
||||||
return Ok(());
|
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");
|
info!(%addr, number, port, "authenticated");
|
||||||
|
@ -10,6 +10,7 @@ use tokio::{
|
|||||||
|
|
||||||
pub const REJECT_OOP: &[u8; 6] = b"\x04\x04oop\x00";
|
pub const REJECT_OOP: &[u8; 6] = b"\x04\x04oop\x00";
|
||||||
pub const REJECT_TIMEOUT: &[u8; 10] = b"\x04\x08timeout\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)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
Loading…
Reference in New Issue
Block a user