Skip to content

Add Stateful ssh_session for Persistent SSH Connections#2380

Open
jabbate19 wants to merge 1 commit into
mainfrom
2003-ssh-session
Open

Add Stateful ssh_session for Persistent SSH Connections#2380
jabbate19 wants to merge 1 commit into
mainfrom
2003-ssh-session

Conversation

@jabbate19

Copy link
Copy Markdown
Collaborator

What type of PR is this?

/kind feature
/kind eldritch-function

What this PR does / why we need it:

Introduce pivot.ssh_session(target, port, username, password, key, key_password, timeout) -> <ssh_session> — the first ForeignValue object with methods in Eldritch. It solves the per-call auth-spam problem of ssh_exec by holding a single russh transport open for many channel_open_session+exec calls.

<ssh_session>.exec(command) returns Dict{stdout, stderr, status} identical to ssh_exec. <ssh_session>.close() disconnects the transport and is idempotent; subsequent exec() raises "session closed".

Implementation:

  • implants/lib/eldritch/stdlib/eldritch-libpivot/src/lib.rs: add ssh_session signature to PivotLibrary trait
  • implants/lib/eldritch/stdlib/eldritch-libpivot/src/std/mod.rs: wire factory, add pub mod ssh_session_impl
  • implants/lib/eldritch/stdlib/eldritch-libpivot/src/std/ssh_session_impl.rs (new): SshSessionHandle = Arc<Mutex<Option>>; eager connect with timeout wrapper, take-restore across await to avoid holding lock, custom Debug that only prints target/port/connected (no secret leak), async helpers for tokio tests (wrap_for_test, exec_async, close_async, is_closed), mock sshd that supports multiple execs per connection with rising start-up guard (wait_until_listening)
  • implants/lib/eldritch/stdlib/eldritch-libpivot/src/fake.rs: FakeSshSessionHandle + FakeSshSessionLibrary (exec/close) with closed-flag via spin::Mutex; PivotLibraryFake::ssh_session returns Foreign handle
  • implants/lib/eldritch/stdlib/eldritch-libpivot/Cargo.toml: add spin optional dep for fake_bindings
  • implants/lib/eldritch/eldritch/src/bindings_test.rs: fix registration-order bug where with_context re-registered Std pivot over fake (chain with_fake_agent after with_context); add file bindings drift (list_named_pipes, read_named_pipe, tmp_dir); add pivot.ssh_session to expected bindings; add test_ssh_session_object_methods, test_ssh_session_fake_exec_and_close, test_ssh_session_fake_reuse_multiple_execs

Tests: cargo test -p eldritch-libpivot --lib 48 passed (6 new),
cargo test -p eldritch --features fake_bindings 17 passed

Docs: user guide update for pivot.ssh_session is out of scope for this commit per repo conventions.

Which issue(s) this PR fixes:

Fixes #2003

Introduce pivot.ssh_session(target, port, username, password, key,
key_password, timeout) -> <ssh_session> — the first ForeignValue
object with methods in Eldritch. It solves the per-call auth-spam
problem of ssh_exec by holding a single russh transport open for
many channel_open_session+exec calls.

<ssh_session>.exec(command) returns Dict{stdout, stderr, status}
identical to ssh_exec. <ssh_session>.close() disconnects the
transport and is idempotent; subsequent exec() raises "session closed".

Implementation:
- implants/lib/eldritch/stdlib/eldritch-libpivot/src/lib.rs:
  add ssh_session signature to PivotLibrary trait
- implants/lib/eldritch/stdlib/eldritch-libpivot/src/std/mod.rs:
  wire factory, add pub mod ssh_session_impl
- implants/lib/eldritch/stdlib/eldritch-libpivot/src/std/ssh_session_impl.rs (new):
  SshSessionHandle = Arc<Mutex<Option<Session>>>; eager connect with
  timeout wrapper, take-restore across await to avoid holding lock,
  custom Debug that only prints target/port/connected (no secret leak),
  async helpers for tokio tests (wrap_for_test, exec_async, close_async,
  is_closed), mock sshd that supports multiple execs per connection
  with rising start-up guard (wait_until_listening)
- implants/lib/eldritch/stdlib/eldritch-libpivot/src/fake.rs:
  FakeSshSessionHandle + FakeSshSessionLibrary (exec/close) with
  closed-flag via spin::Mutex; PivotLibraryFake::ssh_session returns
  Foreign handle
- implants/lib/eldritch/stdlib/eldritch-libpivot/Cargo.toml:
  add spin optional dep for fake_bindings
- implants/lib/eldritch/eldritch/src/bindings_test.rs:
  fix registration-order bug where with_context re-registered Std
  pivot over fake (chain with_fake_agent after with_context); add
  file bindings drift (list_named_pipes, read_named_pipe, tmp_dir);
  add pivot.ssh_session to expected bindings; add
  test_ssh_session_object_methods, test_ssh_session_fake_exec_and_close,
  test_ssh_session_fake_reuse_multiple_execs

Tests: cargo test -p eldritch-libpivot --lib 48 passed (6 new),
       cargo test -p eldritch --features fake_bindings 17 passed

Docs: user guide update for pivot.ssh_session is out of scope for this
commit per repo conventions.
@jabbate19 jabbate19 marked this pull request as ready for review July 10, 2026 01:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature] pivot.ssh_session()

1 participant