pub struct ChannelServer<H> { /* private fields */ }Expand description
Implementation of russh::server::Handler which provides per-channel session
handlers using a parametric ChannelHandler.
Primary motivation is to support custom console or TUI sessions over tailnet SSH connections.
§Authentication and authorization
Incoming connections are gated by the control-pushed Tailscale SSH policy: auth_none
resolves the source IP to a known tailnet peer and evaluates the policy via
Device::authorize_ssh (fail-closed — an unknown peer, an
absent policy, or a non-matching policy all reject). The ssh policy block’s accept/reject
rules, principal matching, and SSH-user mapping are honored. A rule that demands session
recording (non-empty recorders) or holdAndDelegate is enforced fail-closed: since this
fork has no recorder transport / delegate round-trip yet, such a session is refused rather than
silently accepted un-recorded (see auth_none). Building those transports is deferred.
Trait Implementations§
Source§impl<H> Handler for ChannelServer<H>
impl<H> Handler for ChannelServer<H>
type Error = Box<dyn Error + Send + Sync>
Source§async fn auth_none(&mut self, user: &str) -> Result<Auth, Self::Error>
async fn auth_none(&mut self, user: &str) -> Result<Auth, Self::Error>
Source§async fn channel_open_session(
&mut self,
channel: Channel<Msg>,
session: &mut Session,
) -> Result<bool, Self::Error>
async fn channel_open_session( &mut self, channel: Channel<Msg>, session: &mut Session, ) -> Result<bool, Self::Error>
Source§async fn channel_close(
&mut self,
channel: ChannelId,
session: &mut Session,
) -> Result<(), Self::Error>
async fn channel_close( &mut self, channel: ChannelId, session: &mut Session, ) -> Result<(), Self::Error>
Source§async fn signal(
&mut self,
channel: ChannelId,
signal: Sig,
session: &mut Session,
) -> Result<(), Self::Error>
async fn signal( &mut self, channel: ChannelId, signal: Sig, session: &mut Session, ) -> Result<(), Self::Error>
Source§async fn data(
&mut self,
channel: ChannelId,
data: &[u8],
session: &mut Session,
) -> Result<(), Self::Error>
async fn data( &mut self, channel: ChannelId, data: &[u8], session: &mut Session, ) -> Result<(), Self::Error>
response argument.Source§async fn channel_eof(
&mut self,
channel: ChannelId,
session: &mut Session,
) -> Result<(), Self::Error>
async fn channel_eof( &mut self, channel: ChannelId, session: &mut Session, ) -> Result<(), Self::Error>
Source§async fn window_change_request(
&mut self,
channel: ChannelId,
col_width: u32,
row_height: u32,
_: u32,
_: u32,
session: &mut Session,
) -> Result<(), Self::Error>
async fn window_change_request( &mut self, channel: ChannelId, col_width: u32, row_height: u32, _: u32, _: u32, session: &mut Session, ) -> Result<(), Self::Error>
Source§async fn pty_request(
&mut self,
channel: ChannelId,
_: &str,
col_width: u32,
row_height: u32,
_: u32,
_: u32,
_: &[(Pty, u32)],
session: &mut Session,
) -> Result<(), Self::Error>
async fn pty_request( &mut self, channel: ChannelId, _: &str, col_width: u32, row_height: u32, _: u32, _: u32, _: &[(Pty, u32)], session: &mut Session, ) -> Result<(), Self::Error>
Source§fn auth_password(
&mut self,
user: &str,
password: &str,
) -> impl Future<Output = Result<Auth, Self::Error>> + Send
fn auth_password( &mut self, user: &str, password: &str, ) -> impl Future<Output = Result<Auth, Self::Error>> + Send
Source§fn auth_publickey_offered(
&mut self,
user: &str,
public_key: &PublicKey,
) -> impl Future<Output = Result<Auth, Self::Error>> + Send
fn auth_publickey_offered( &mut self, user: &str, public_key: &PublicKey, ) -> impl Future<Output = Result<Auth, Self::Error>> + Send
Source§fn auth_publickey(
&mut self,
user: &str,
public_key: &PublicKey,
) -> impl Future<Output = Result<Auth, Self::Error>> + Send
fn auth_publickey( &mut self, user: &str, public_key: &PublicKey, ) -> impl Future<Output = Result<Auth, Self::Error>> + Send
Source§fn auth_openssh_certificate(
&mut self,
user: &str,
certificate: &Certificate,
) -> impl Future<Output = Result<Auth, Self::Error>> + Send
fn auth_openssh_certificate( &mut self, user: &str, certificate: &Certificate, ) -> impl Future<Output = Result<Auth, Self::Error>> + Send
Source§fn auth_keyboard_interactive<'a>(
&'a mut self,
user: &str,
submethods: &str,
response: Option<Response<'a>>,
) -> impl Future<Output = Result<Auth, Self::Error>> + Send
fn auth_keyboard_interactive<'a>( &'a mut self, user: &str, submethods: &str, response: Option<Response<'a>>, ) -> impl Future<Output = Result<Auth, Self::Error>> + Send
Source§fn auth_succeeded(
&mut self,
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn auth_succeeded( &mut self, session: &mut Session, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Source§fn channel_open_x11(
&mut self,
channel: Channel<Msg>,
originator_address: &str,
originator_port: u32,
session: &mut Session,
) -> impl Future<Output = Result<bool, Self::Error>> + Send
fn channel_open_x11( &mut self, channel: Channel<Msg>, originator_address: &str, originator_port: u32, session: &mut Session, ) -> impl Future<Output = Result<bool, Self::Error>> + Send
Source§fn channel_open_direct_tcpip(
&mut self,
channel: Channel<Msg>,
host_to_connect: &str,
port_to_connect: u32,
originator_address: &str,
originator_port: u32,
session: &mut Session,
) -> impl Future<Output = Result<bool, Self::Error>> + Send
fn channel_open_direct_tcpip( &mut self, channel: Channel<Msg>, host_to_connect: &str, port_to_connect: u32, originator_address: &str, originator_port: u32, session: &mut Session, ) -> impl Future<Output = Result<bool, Self::Error>> + Send
Source§fn channel_open_forwarded_tcpip(
&mut self,
channel: Channel<Msg>,
host_to_connect: &str,
port_to_connect: u32,
originator_address: &str,
originator_port: u32,
session: &mut Session,
) -> impl Future<Output = Result<bool, Self::Error>> + Send
fn channel_open_forwarded_tcpip( &mut self, channel: Channel<Msg>, host_to_connect: &str, port_to_connect: u32, originator_address: &str, originator_port: u32, session: &mut Session, ) -> impl Future<Output = Result<bool, Self::Error>> + Send
Source§fn channel_open_direct_streamlocal(
&mut self,
channel: Channel<Msg>,
socket_path: &str,
session: &mut Session,
) -> impl Future<Output = Result<bool, Self::Error>> + Send
fn channel_open_direct_streamlocal( &mut self, channel: Channel<Msg>, socket_path: &str, session: &mut Session, ) -> impl Future<Output = Result<bool, Self::Error>> + Send
Source§fn channel_open_confirmation(
&mut self,
id: ChannelId,
max_packet_size: u32,
window_size: u32,
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn channel_open_confirmation( &mut self, id: ChannelId, max_packet_size: u32, window_size: u32, session: &mut Session, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Source§fn extended_data(
&mut self,
channel: ChannelId,
code: u32,
data: &[u8],
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn extended_data( &mut self, channel: ChannelId, code: u32, data: &[u8], session: &mut Session, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Source§fn window_adjusted(
&mut self,
channel: ChannelId,
new_size: u32,
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn window_adjusted( &mut self, channel: ChannelId, new_size: u32, session: &mut Session, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Source§fn adjust_window(&mut self, channel: ChannelId, current: u32) -> u32
fn adjust_window(&mut self, channel: ChannelId, current: u32) -> u32
Source§fn x11_request(
&mut self,
channel: ChannelId,
single_connection: bool,
x11_auth_protocol: &str,
x11_auth_cookie: &str,
x11_screen_number: u32,
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn x11_request( &mut self, channel: ChannelId, single_connection: bool, x11_auth_protocol: &str, x11_auth_cookie: &str, x11_screen_number: u32, session: &mut Session, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Source§fn env_request(
&mut self,
channel: ChannelId,
variable_name: &str,
variable_value: &str,
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn env_request( &mut self, channel: ChannelId, variable_name: &str, variable_value: &str, session: &mut Session, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Source§fn shell_request(
&mut self,
channel: ChannelId,
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn shell_request( &mut self, channel: ChannelId, session: &mut Session, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Source§fn exec_request(
&mut self,
channel: ChannelId,
data: &[u8],
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn exec_request( &mut self, channel: ChannelId, data: &[u8], session: &mut Session, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Source§fn subsystem_request(
&mut self,
channel: ChannelId,
name: &str,
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn subsystem_request( &mut self, channel: ChannelId, name: &str, session: &mut Session, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Source§fn agent_request(
&mut self,
channel: ChannelId,
session: &mut Session,
) -> impl Future<Output = Result<bool, Self::Error>> + Send
fn agent_request( &mut self, channel: ChannelId, session: &mut Session, ) -> impl Future<Output = Result<bool, Self::Error>> + Send
Source§fn tcpip_forward(
&mut self,
address: &str,
port: &mut u32,
session: &mut Session,
) -> impl Future<Output = Result<bool, Self::Error>> + Send
fn tcpip_forward( &mut self, address: &str, port: &mut u32, session: &mut Session, ) -> impl Future<Output = Result<bool, Self::Error>> + Send
port is 0, you should set it to the allocated port number.Source§fn cancel_tcpip_forward(
&mut self,
address: &str,
port: u32,
session: &mut Session,
) -> impl Future<Output = Result<bool, Self::Error>> + Send
fn cancel_tcpip_forward( &mut self, address: &str, port: u32, session: &mut Session, ) -> impl Future<Output = Result<bool, Self::Error>> + Send
fn streamlocal_forward( &mut self, socket_path: &str, session: &mut Session, ) -> impl Future<Output = Result<bool, Self::Error>> + Send
fn cancel_streamlocal_forward( &mut self, socket_path: &str, session: &mut Session, ) -> impl Future<Output = Result<bool, Self::Error>> + Send
Source§impl<H> TailnetServer for ChannelServer<H>
impl<H> TailnetServer for ChannelServer<H>
Source§fn new_client(dev: Arc<Device>, addr: SocketAddr) -> Self
fn new_client(dev: Arc<Device>, addr: SocketAddr) -> Self
Auto Trait Implementations§
impl<H> !RefUnwindSafe for ChannelServer<H>
impl<H> !UnwindSafe for ChannelServer<H>
impl<H> Freeze for ChannelServer<H>
impl<H> Send for ChannelServer<H>
impl<H> Sync for ChannelServer<H>
impl<H> Unpin for ChannelServer<H>
impl<H> UnsafeUnpin for ChannelServer<H>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<A, T> DynMessage<A> for T
impl<A, T> DynMessage<A> for T
Source§fn handle_dyn<'a>(
self: Box<T>,
state: &'a mut A,
actor_ref: ActorRef<A>,
tx: Option<Sender<Result<Box<dyn Any + Send>, SendError<Box<dyn Any + Send>, Box<dyn Any + Send>>>>>,
stop: &'a mut bool,
) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn ReplyError>>> + Send + 'a>>
fn handle_dyn<'a>( self: Box<T>, state: &'a mut A, actor_ref: ActorRef<A>, tx: Option<Sender<Result<Box<dyn Any + Send>, SendError<Box<dyn Any + Send>, Box<dyn Any + Send>>>>>, stop: &'a mut bool, ) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn ReplyError>>> + Send + 'a>>
impl<T> ErasedDestructor for Twhere
T: 'static,
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more