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 | |
parent | 089d20e641e6f19816991c6a59fca4e3df4c7700 (diff) |
initial password authenticated ssh server
-rw-r--r-- | Cargo.lock | 3 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | src/main.rs | 81 |
3 files changed, 84 insertions, 3 deletions
@@ -1184,11 +1184,14 @@ dependencies = [ name = "rsdsl_udpdumpd" version = "0.1.0" dependencies = [ + "async-trait", "pcap", "ringbuf", "rsdsl_netlinklib", "russh", + "russh-keys", "thiserror", + "tokio", ] [[package]] @@ -6,8 +6,11 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-trait = "^0.1" pcap = "1.1.0" ringbuf = "0.3.3" rsdsl_netlinklib = { git = "https://github.com/rsdsl/netlinklib.git", version = "0.4.5", default-features = false, features = ["blocking", "status"] } russh = "0.40.0" +russh-keys = "^0.40" thiserror = "1.0" +tokio = { version = "1.0", features = ["rt", "rt-multi-thread", "macros"] } 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(()) } |