aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2023-12-04 16:39:10 +0100
committerHimbeerserverDE <himbeerserverde@gmail.com>2023-12-04 16:39:10 +0100
commita5380a3af66698b0295f985a8c6d80c17b74f060 (patch)
tree2478ea0ba4c85e350440f7665f768200917d2194
parent089d20e641e6f19816991c6a59fca4e3df4c7700 (diff)
initial password authenticated ssh server
-rw-r--r--Cargo.lock3
-rw-r--r--Cargo.toml3
-rw-r--r--src/main.rs81
3 files changed, 84 insertions, 3 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ef37319..14e3042 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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]]
diff --git a/Cargo.toml b/Cargo.toml
index 11cf8ed..fdc3947 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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(())
}