[package]
name = "puressh"
version = "0.0.4"
edition = "2021"
rust-version = "1.95"
license = "MIT OR Apache-2.0"
description = "A pure-Rust SSH (Secure Shell) protocol library, in the spirit of libssh, built on purecrypto."
repository = "https://github.com/KarpelesLab/puressh"
documentation = "https://docs.rs/puressh"
readme = "README.md"
keywords = ["ssh", "ssh2", "crypto", "network", "no-std"]
categories = ["cryptography", "network-programming"]
# Cargo's auto-discovery scans `src/bin/` for `.rs` files and turns each one
# into a binary. We list every binary explicitly below; turning auto-discovery
# off lets us drop shared helpers in `src/bin/common.rs` (pulled in via
# `#[path = "common.rs"] mod common;`) without Cargo trying to compile them
# as a standalone binary.
autobins = false

[features]
default = ["std", "client", "server", "compress", "pam", "multichannel"]
std = ["purecrypto/std", "alloc"]
alloc = ["purecrypto/alloc"]
# High-level client and server APIs depend on `std::net` / `std::io` /
# `std::thread`, so they require the `std` feature.
client = ["std"]
server = ["std"]
compress = ["dep:compcol"]
# Concurrent multi-channel client layer (SharedClient, OwnedChannelStream,
# SftpSession). Enables several SFTP / exec / shell / direct-tcpip handles
# to coexist on one connection with per-channel fairness (Condvar-based
# pumper-or-wait) and per-channel backpressure (window credit deferred to
# drain). Default on; turning it off keeps the borrow-based Client API and
# strips ~600 lines of code from `src/shared.rs`.
multichannel = ["client"]
# C ABI surface. Requires `std`, the `client` module, and the multi-channel
# layer (the FFI's PcSshSftp / PcSshAgent depend on `SharedClient`). Produces
# additional `staticlib` / `cdylib` artefacts (see `[lib].crate-type`).
ffi = ["std", "client", "multichannel"]
# PAM session integration for the `sshd` binary. Default-on but opt-out:
# building with `--no-default-features` (or `--features ...` without `pam`)
# drops the libpam runtime dep entirely. The dep itself is also gated to
# `cfg(unix)`, so Windows builds stay clean.
pam = ["dep:pam-client2"]

[dependencies]
purecrypto = { version = "0.6.1", default-features = false, features = [
    "hash", "cipher", "kdf", "rng", "rsa", "dh", "ec", "der",
] }
compcol = { version = "0.4.2", default-features = false, features = ["alloc", "zlib"], optional = true }
# `zeroize` provides `Zeroizing<T>` (drop wipes the inner value) and a derive
# for compound secrets. Kept default-on so `no_std + alloc` builds still get
# secret-wiping for derived KDF output, password buffers carried across FFI,
# and similar transient secrets. The crate itself is `no_std`-friendly.
zeroize = { version = "1", default-features = false, features = ["alloc"] }

# Unix-only deps for the `sshd` binary: fork(), forkpty(), waitpid(),
# set_winsize(), SIGCHLD plumbing. Library code never touches `nix` — it
# stays no-std-friendly. Confined to `cfg(unix)` so Windows builds keep a
# clean dependency graph.
#
# Feature map in nix 0.30:
#   process — waitpid, fork, execvp
#   signal  — signal handlers, kill
#   term    — pty / forkpty / Winsize (the pty module is gated by `term`)
#   fs      — fcntl flags / O_NONBLOCK
#   ioctl   — TIOCSWINSZ
#   user    — User::from_name, setuid/setgid/initgroups, geteuid/getegid
[target.'cfg(unix)'.dependencies]
nix = { version = "0.30", default-features = false, features = [
    "process", "signal", "term", "fs", "ioctl", "user",
] }
# `libc` for the few low-level POSIX bits the binaries need (terminal
# echo control in the password reader; geteuid + Unix-socket stat() for
# the SSH_AUTH_SOCK trust check in the agent client). The library
# proper continues to stay no-std-friendly; only the cfg(unix)-gated
# bin/agent paths reach for libc.
libc = { version = "0.2", default-features = false }

# `pam-client2` is gated to **Linux only**, not all of `cfg(unix)`.
# Upstream `pam-client2 0.5.5` references Linux-PAM constants
# (`PAM_CONV_AGAIN`, `PAM_INCOMPLETE`) that OpenPAM (macOS / *BSD) does not
# expose, so the crate fails to compile there. Confining the dep to Linux
# keeps `cargo build --all-features` green on macOS, at the cost of PAM
# session integration being a Linux-only feature for now.
#
# `default-features = false` drops the `cli` feature (which would pull in
# `rpassword`) — the sshd binary is a non-interactive PAM consumer.
[target.'cfg(target_os = "linux")'.dependencies]
pam-client2 = { version = "0.5", default-features = false, optional = true }

[dev-dependencies]
hex = "0.4"

[lib]
name = "puressh"
path = "src/lib.rs"
# Default builds emit only the rlib. The C ABI surface (staticlib / cdylib)
# is built explicitly via `cargo rustc --crate-type` — see the `c_abi` and
# `release-binaries` workflows — so it isn't tied to every `cargo build`.
# Keeping the default set to just `["lib"]` lets `cargo build` succeed in
# no_std + alloc mode, where the C ABI artefacts would otherwise require
# a #[panic_handler] and #[global_allocator] the library doesn't provide.
crate-type = ["lib"]

[[bin]]
name = "ssh"
path = "src/bin/ssh.rs"
# `multichannel` is needed for the interactive shell path — it spins a
# sibling `SharedClient` clone to deliver SIGWINCH-driven `window-change`
# requests while the stdio threads hold the channel stream.
required-features = ["std", "client", "multichannel"]

[[bin]]
name = "sshd"
path = "src/bin/sshd.rs"
required-features = ["std", "server"]

[[bin]]
name = "ssh-keygen"
path = "src/bin/ssh-keygen.rs"
required-features = ["std"]

[[bin]]
name = "sftp"
path = "src/bin/sftp.rs"
required-features = ["std", "client"]

[[bin]]
name = "scp"
path = "src/bin/scp.rs"
required-features = ["std", "client"]
