Skip to content

Commit

Permalink
Add feature gate for russh impl
Browse files Browse the repository at this point in the history
  • Loading branch information
Tehforsch committed Oct 7, 2024
1 parent 2b63150 commit fec4099
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 41 deletions.
14 changes: 12 additions & 2 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ rand = "0.8.5"
redis = "0.22.3"
regex = "1.10.6"
ripemd = "0.1.3"
russh = "0.45.0"
rustls = "0.23.5"
rustls-pemfile = "2.1.2"
rustls-pemfile-old = { version = "1.0.2", package = "rustls-pemfile" }
Expand Down Expand Up @@ -98,16 +99,17 @@ tracing-test = "0.2.5"
criterion = "0"
russh = "0.45.0"
russh-keys = "0.45.0"
once_cell = "1.20.1"

[features]
dep-graph-parallel = ["rayon", "crossbeam-channel"]
openvas_serde_support = []
serde_support = []
default = ["dep-graph-parallel", "openvas_serde_support", "enforce-no-trailing-arguments", "serde_support", "experimental"]
default = ["dep-graph-parallel", "openvas_serde_support", "enforce-no-trailing-arguments", "serde_support"]

nasl-builtin-raw-ip = ["pcap", "pnet_base", "pnet", "socket2", "pnet_macros", "pnet_macros_support",]
nasl-builtin-ssh = ["libssh-rs"]
experimental = ["nasl-builtin-raw-ip", "nasl-builtin-ssh", "nasl-c-lib"]
nasl-builtin-libssh = ["libssh-rs"]
experimental = ["nasl-builtin-raw-ip", "nasl-builtin-libssh", "nasl-c-lib"]

enforce-no-trailing-arguments = []

Expand Down
16 changes: 0 additions & 16 deletions rust/src/nasl/builtin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,3 @@ and then extend the register builder within the [nasl_std_variables] with the im
builder = builder.push_register(nasl_builtin_raw_ip::RawIp)
```


### Mark as experimental

When you have to mark your functions as experimental than you have to declare that crate as optional and add it to the experimental feature.


```toml

nasl-builtin-ssh = {path = "../nasl-builtin-ssh", optional = true}

[features]
experimental = ["nasl-builtin-ssh"]
```

It is recommended to toggle on the crate name and not on experimental to also enable toggling those without using experimental.
6 changes: 2 additions & 4 deletions rust/src/nasl/builtin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ mod network;
mod raw_ip;
mod regex;
mod report_functions;
#[cfg(feature = "nasl-builtin-ssh")]
mod ssh;
mod string;

Expand Down Expand Up @@ -46,10 +45,9 @@ pub fn nasl_std_functions() -> Executor {
.add_set(regex::RegularExpressions)
.add_set(cryptographic::Cryptographic)
.add_set(description::Description)
.add_set(isotime::NaslIsotime);
.add_set(isotime::NaslIsotime)
.add_set(ssh::Ssh::default());

#[cfg(feature = "nasl-builtin-ssh")]
executor.add_set(ssh::Ssh::default());
#[cfg(feature = "nasl-builtin-raw-ip")]
executor.add_set(raw_ip::RawIp);

Expand Down
5 changes: 5 additions & 0 deletions rust/src/nasl/builtin/ssh/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use super::SessionId;

pub type Result<T> = std::result::Result<T, SshError>;

#[cfg(feature = "nasl-builtin-libssh")]
#[derive(Debug, Error)]
pub enum SshError {
#[error("Failed to open new SSH session: {0}")]
Expand Down Expand Up @@ -66,6 +67,10 @@ pub enum SshError {
Sftp(SessionId, libssh_rs::Error),
}

#[cfg(not(feature = "nasl-builtin-libssh"))]
#[derive(Debug, Error)]
pub enum SshError {}

impl From<SshError> for FunctionErrorKind {
fn from(e: SshError) -> Self {
FunctionErrorKind::Dirty(e.to_string())
Expand Down
10 changes: 9 additions & 1 deletion rust/src/nasl/builtin/ssh/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
mod error;

#[cfg(feature = "nasl-builtin-libssh")]
mod libssh;
#[cfg(feature = "nasl-builtin-libssh")]
pub use self::libssh::Ssh;

#[cfg(not(feature = "nasl-builtin-libssh"))]
mod russh;
#[cfg(not(feature = "nasl-builtin-libssh"))]
pub use self::russh::Ssh;

#[cfg(test)]
mod tests;

type SessionId = i32;
pub use self::libssh::Ssh;
30 changes: 30 additions & 0 deletions rust/src/nasl/builtin/ssh/russh/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use russh::client::Session;
use tokio::sync::Mutex;

use crate::nasl::{
prelude::*,
utils::{IntoFunctionSet, StoredFunctionSet},
};

#[derive(Default)]
pub struct Ssh {
sessions: Vec<Mutex<Session>>,
}

impl Ssh {
#[nasl_function]
async fn ssh_connect(&mut self) {
todo!()
}
}

impl IntoFunctionSet for Ssh {
type State = Ssh;

fn into_function_set(self) -> StoredFunctionSet<Self::State> {
let mut set = StoredFunctionSet::new(self);

set.async_stateful_mut("ssh_connect", Ssh::ssh_connect);
set
}
}
66 changes: 51 additions & 15 deletions rust/src/nasl/builtin/ssh/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,71 @@ mod server;
use std::sync::Arc;
use std::time::Duration;

use russh::server::Config as ServerConfig;
use russh::server::Server as _;
use russh_keys::key::KeyPair;
use server::TestServer;

use crate::nasl::test_prelude::TestBuilder;
use crate::nasl::NoOpLoader;
use crate::storage::DefaultDispatcher;

use once_cell::sync::Lazy;
use std::sync::Mutex;

static LOCK: Lazy<Mutex<()>> = Lazy::new(Mutex::default);

const PORT: u16 = 2223;

fn default_config() -> ServerConfig {
ServerConfig {
keys: vec![KeyPair::generate_ed25519().unwrap()],
..Default::default()
}
}

#[tokio::test]
async fn ssh_connect() {
run_test(|mut t| {
t.ok(format!("id = ssh_connect(port:{});", PORT), 9000);
t.ok(format!("id = ssh_connect(port:{});", PORT), 9001);
})
run_test(
|mut t| {
t.ok(format!("id = ssh_connect(port:{});", PORT), 9000);
t.ok(format!("id = ssh_connect(port:{});", PORT), 9001);
},
default_config(),
)
.await
}

async fn run_test(f: impl Fn(TestBuilder<NoOpLoader, DefaultDispatcher>) -> () + Send + 'static) {
let server = tokio::time::timeout(Duration::from_millis(2000), run_server());
#[tokio::test]
async fn ssh_auth() {
run_test(
|mut t| {
t.run(format!(
r#"session_id = ssh_connect(port: {}, keytype: "ssh-rsa,ssh-dss,ssh-ed25519");"#,
PORT
));
// t.run(r#"#prompt = ssh_login_interactive(session_id, login: "user");"#);
// t.run(r#"#display(prompt);"#);
// t.run(r#"#auth = ssh_login_interactive_pass(session_id, pass: "pass");"#);
// t.run(r#"#a = ssh_set_login(session_id, login: "admin");"#);
t.run(r#"auth = ssh_userauth(session_id, login: "user", password: "pass");"#);
// t.run(r#"display(auth);"#);
},
default_config(),
)
.await
}

async fn run_test(
f: impl Fn(TestBuilder<NoOpLoader, DefaultDispatcher>) -> () + Send + 'static,
config: ServerConfig,
) {
// Acquire the global lock to prevent multiple
// tests from opening a server at the same time.
let _guard = LOCK.lock();
let server = tokio::time::timeout(Duration::from_millis(200), run_server(config));
let client = tokio::task::spawn_blocking(move || {
std::thread::sleep(Duration::from_millis(1000));
std::thread::sleep(Duration::from_millis(100));
let t = TestBuilder::default();
f(t)
});
Expand All @@ -33,14 +76,7 @@ async fn run_test(f: impl Fn(TestBuilder<NoOpLoader, DefaultDispatcher>) -> () +
res.unwrap()
}

async fn run_server() {
let config = russh::server::Config {
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![russh_keys::key::KeyPair::generate_ed25519().unwrap()],
..Default::default()
};
async fn run_server(config: ServerConfig) {
let config = Arc::new(config);
let mut server = TestServer::default();
server
Expand Down
12 changes: 12 additions & 0 deletions rust/src/nasl/builtin/ssh/tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use async_trait::async_trait;
use russh::keys::*;
use russh::server::{Msg, Session};
use russh::*;
use server::{Auth, Response};
use tokio::sync::Mutex;

#[derive(Clone, Default)]
Expand Down Expand Up @@ -62,6 +63,17 @@ impl server::Handler for TestServer {
Ok(server::Auth::Accept)
}

async fn auth_keyboard_interactive(
&mut self,
user: &str,
submethods: &str,
response: Option<Response<'async_trait>>,
) -> Result<Auth, Self::Error> {
Ok(Auth::Reject {
proceed_with_methods: None,
})
}

async fn data(
&mut self,
channel: ChannelId,
Expand Down

0 comments on commit fec4099

Please sign in to comment.