use crate::ssh::ReceiveSyncService; use crate::ssh::SshTokenService; use crate::ssh::handle::SSHandle; use db::cache::AppCache; use db::database::AppDatabase; use deadpool_redis::cluster::Pool as RedisPool; use russh::server::Handler; use std::io; use std::net::SocketAddr; pub struct SSHServer { pub db: AppDatabase, pub cache: AppCache, pub redis_pool: RedisPool, pub token_service: SshTokenService, } impl SSHServer { pub fn new( db: AppDatabase, cache: AppCache, redis_pool: RedisPool, token_service: SshTokenService, ) -> Self { SSHServer { db, cache, redis_pool, token_service, } } } impl russh::server::Server for SSHServer { type Handler = SSHandle; fn new_client(&mut self, addr: Option) -> Self::Handler { if let Some(addr) = addr { tracing::info!("New SSH connection ip={} port={}", addr.ip(), addr.port()); } else { tracing::info!("New SSH connection from unknown address"); } let sync_service = ReceiveSyncService::new(self.redis_pool.clone()); SSHandle::new( self.db.clone(), self.cache.clone(), sync_service, self.token_service.clone(), addr, ) } fn handle_session_error(&mut self, error: ::Error) { match error { russh::Error::Disconnect => { tracing::info!("Connection disconnected by peer"); } russh::Error::Inconsistent => { tracing::warn!("Protocol inconsistency detected"); } russh::Error::NotAuthenticated => { tracing::warn!("Authentication failed"); } russh::Error::IO(ref io_err) => { tracing::warn!( "SSH IO error kind={:?} message={} raw_os_error={:?}", io_err.kind(), io_err, io_err.raw_os_error() ); if io_err.kind() == io::ErrorKind::UnexpectedEof { tracing::warn!("Client disconnected during handshake or before authentication"); } } _ => { tracing::warn!("SSH session error error={}", error); } } } }