# bare-ssh2 This is a **Bare-native port** of the excellent [ssh2](https://github.com/mscdex/ssh2) library by Brian White (mscdex). It exposes the same public API (`Client`, `Server`, agents, `utils`, SFTP helpers, etc.) so code written for `ssh2` can switch the import to `bare-ssh2` and run on the [Bare](https://github.com/holepunchto/bare) / Pear runtime. On **Node.js**, builtin modules are still used (via the `default` branch of this package’s `imports` map), so the same package can be tried on Node for comparison; primary support targets **Bare**. ## Installation ```bash npm install bare-ssh2 ``` ## Drop-in usage Replace `ssh2` with `bare-ssh2`: ```js const { readFileSync } = require('fs') const { Client } = require('bare-ssh2') const conn = new Client() conn .on('ready', () => { conn.exec('uptime', (err, stream) => { if (err) throw err stream .on('close', (code, signal) => { console.log('close', code, signal) conn.end() }) .on('data', (data) => console.log('STDOUT:', data.toString())) stream.stderr.on('data', (data) => console.log('STDERR:', data.toString())) }) }) .connect({ host: 'example.com', port: 22, username: 'you', privateKey: readFileSync('/path/to/key') }) ``` ESM interop follows your bundler/runtime rules for loading this **CommonJS** package. ## How it maps Node builtins on Bare Inside this package, `require('net')`, `require('dns')`, and other Node core names are resolved using `package.json` **`imports`** with the **`bare`** condition to [bare-node-\*](https://github.com/holepunchto/bare-node) wrappers. You do not need to change those specifiers in application code that only imports `bare-ssh2`. **`crypto`:** Bare’s module resolver does not apply this package’s `imports` map to dependencies such as `tweetnacl` (used by `bcrypt-pbkdf`). This package therefore depends on a small local **[`shims/crypto`](shims/crypto/)** package (published as the `crypto` dependency) built on **`bare-crypto`**, with **`getCiphers()`** / **`getHashes()`** lists implemented in [`shims/crypto/lists.js`](shims/crypto/lists.js). The **`bare`** `imports` entry for `crypto` points at the same shim so library code and transitive deps share one implementation. **`assert` / `buffer`:** Declared as **`npm:bare-node-*`** aliases so `asn1` and `safer-buffer` resolve them on Bare. **Buffer:** [`lib/buffer-polyfill.js`](lib/buffer-polyfill.js) adds Node’s `utf8Write` / `latin1Write` / `*Slice` helpers when missing (loaded from `lib/index.js`, `client.js`, `server.js`, `keygen.js`, and `protocol/keyParser.js`). The optional **ssh2** native crypto binding and **`cpu-features`** optional dependency from upstream are **not** used here. For **ChaCha20** packet encryption without OpenSSL, the **`chacha20`** npm package is used when `createCipheriv('chacha20', …)` is unsupported. ## API documentation See the upstream [ssh2 README](https://github.com/mscdex/ssh2/blob/master/README.md) for the full API (client/server events, SFTP, forwarding, HTTP(S) agents, key utilities). ## Testing From this package directory after `npm install`: ```bash npm test ``` This runs **Prettier**, then **`bare test/test-protocol-crypto.js`**, then **`node test/test-protocol-keyparser.js`** (key parser sign/verify checks currently match Node’s OpenSSL more closely than Bare’s crypto for some ECDSA/OpenSSH fixtures). Other useful commands: ```bash bare test/test-protocol-crypto.js npm run test:all ``` `npm run test:all` runs Prettier and **`bare test/test.js`**, which spawns every `test-*.js` (needs OpenSSH, keys, etc. where applicable). ```bash npm run test:node ``` runs the same driver under Node. ### Known gaps on Bare - **RC4 (`arcfour`)** and some legacy ciphers are not implemented in **bare-crypto**; they are omitted from negotiation when unsupported. - **ECDSA signing** for some OpenSSH private key paths may differ between Bare and Node; report issues with minimal key fixtures if you hit this in production. - Tests that shell out to **OpenSSH** or need a full **worker_threads** stack may fail unless the matching **bare-node-\*** test dependencies are installed. - Default cipher/MAC lists follow **`getCiphers()`** / **`getHashes()`** from the crypto shim (subset of OpenSSL’s names). - **SSH agent** helpers that use **`child_process`** depend on **bare-subprocess**; Windows-specific paths (Pageant, Cygwin) may differ from Node. ## TypeScript Upstream `ssh2` does not ship types. You can use **`@types/ssh2`** for typings against this API. ## License **MIT** — same as the original ssh2 code. See [LICENSE](LICENSE) and [NOTICE](NOTICE).