diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-12-04 16:39:10 +0100 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-12-04 16:39:10 +0100 |
commit | a5380a3af66698b0295f985a8c6d80c17b74f060 (patch) | |
tree | 2478ea0ba4c85e350440f7665f768200917d2194 /src | |
parent | 089d20e641e6f19816991c6a59fca4e3df4c7700 (diff) |
initial password authenticated ssh server
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 81 |
1 files changed, 78 insertions, 3 deletions
diff --git a/src/main.rs b/src/main.rs index c3f1be1..7977723 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,22 @@ use std::array; +use std::collections::HashMap; +use std::fs; use std::io::{self, Read}; -use std::net::{SocketAddr, UdpSocket}; +use std::net::SocketAddr; use std::os::fd::{AsRawFd, RawFd}; -use std::sync::{mpsc, Arc, Mutex}; +use std::sync::{mpsc, Arc}; use std::thread; use std::time::{Duration, Instant}; +use tokio::sync::Mutex; + +use async_trait::async_trait; use pcap::Capture; use ringbuf::{HeapRb, Rb}; use rsdsl_netlinklib::blocking::Connection; +use russh::server::{Auth, Handle, Msg, Session}; +use russh::{Channel, ChannelId, MethodSet}; +use russh_keys::key::KeyPair; use thiserror::Error; const PEER_TIMEOUT: Duration = Duration::from_secs(30); @@ -28,6 +36,8 @@ enum Error { Netlinklib(#[from] rsdsl_netlinklib::Error), #[error("pcap error: {0}")] Pcap(#[from] pcap::Error), + #[error("russh error: {0}")] + Russh(#[from] russh::Error), } impl From<mpsc::SendError<Vec<u8>>> for Error { @@ -38,6 +48,71 @@ impl From<mpsc::SendError<Vec<u8>>> for Error { type Result<T> = std::result::Result<T, Error>; -fn main() -> Result<()> { +#[derive(Clone)] +struct Server { + clients: Arc<Mutex<HashMap<(usize, ChannelId), Handle>>>, + id: usize, +} + +impl russh::server::Server for Server { + type Handler = Self; + + fn new_client(&mut self, _: Option<SocketAddr>) -> Self { + let s = self.clone(); + self.id += 1; + s + } +} + +#[async_trait] +impl russh::server::Handler for Server { + type Error = Error; + + async fn channel_open_session( + self, + channel: Channel<Msg>, + session: Session, + ) -> Result<(Self, bool, Session)> { + { + let mut clients = self.clients.lock().await; + clients.insert((self.id, channel.id()), session.handle()); + } + + Ok((self, true, session)) + } + + async fn auth_password(self, user: &str, password: &str) -> Result<(Self, Auth)> { + let correct_password = fs::read("/data/admind.passwd")?; + + if user == "rustkrazy" && password.as_bytes() == correct_password { + Ok((self, Auth::Accept)) + } else { + Ok(( + self, + Auth::Reject { + proceed_with_methods: None, + }, + )) + } + } +} + +#[tokio::main] +async fn main() -> Result<()> { + let config = Arc::new(russh::server::Config { + methods: MethodSet::PASSWORD, + inactivity_timeout: Some(Duration::from_secs(3600)), + auth_rejection_time: Duration::from_secs(3), + auth_rejection_time_initial: Some(Duration::from_secs(0)), + keys: vec![KeyPair::generate_ed25519().expect("ed25519 keypair generation")], + ..Default::default() + }); + + let server = Server { + clients: Arc::new(Mutex::new(HashMap::new())), + id: 0, + }; + + russh::server::run(config, "[::]:2222", server).await?; Ok(()) } |