{"id":50509707,"url":"https://github.com/dmatking/esp32-wolfssh-client","last_synced_at":"2026-06-02T19:01:12.951Z","repository":{"id":351360496,"uuid":"1210666735","full_name":"dmatking/esp32-wolfssh-client","owner":"dmatking","description":"wolfSSH client component for ESP-IDF. Wraps wolfSSH in a FreeRTOS task with a callback API. Ships with a pre-tuned user_settings.h and bundled wolfssh sources.","archived":false,"fork":false,"pushed_at":"2026-05-02T17:33:09.000Z","size":268,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-02T19:24:07.444Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmatking.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-14T16:31:54.000Z","updated_at":"2026-05-02T17:33:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dmatking/esp32-wolfssh-client","commit_stats":null,"previous_names":["dmatking/esp-wolfssh-client","dmatking/esp32-wolfssh-client"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dmatking/esp32-wolfssh-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmatking%2Fesp32-wolfssh-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmatking%2Fesp32-wolfssh-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmatking%2Fesp32-wolfssh-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmatking%2Fesp32-wolfssh-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmatking","download_url":"https://codeload.github.com/dmatking/esp32-wolfssh-client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmatking%2Fesp32-wolfssh-client/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33833277,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-02T19:01:10.358Z","updated_at":"2026-06-02T19:01:12.939Z","avatar_url":"https://github.com/dmatking.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# esp32-wolfssh-client\n\nAn ESP-IDF component that wraps [wolfSSH](https://www.wolfssl.com/products/wolfssh/) as a\nFreeRTOS task with a clean callback API.  The hard part — getting wolfSSH to compile and\nrun correctly on ESP32 targets — is done for you.\n\n## What this solves\n\nGetting wolfSSH working on ESP32/FreeRTOS requires:\n\n- A `user_settings.h` for wolfSSL with the SSH-specific settings enabled:\n  `WOLFSSH_TERM` for PTY support, `NO_TERMIOS` (no `tcgetattr` on FreeRTOS),\n  and a reduced `DEFAULT_WINDOW_SZ` for embedded RAM.\n- A single-task I/O model: all wolfSSH calls run in one FreeRTOS task; keystrokes\n  from other tasks arrive via a thread-safe queue.\n- A specific session setup sequence: connect → channel open → PTY request → shell request\n  → read/write loop.\n\nNone of this is in wolfSSH's ESP32 examples.  This component encodes all of it.\n\n## What the component does NOT do\n\n- VT100/ANSI parsing — use libvterm or similar; wire the `on_data` callback.\n- Display anything — render callbacks are the application's job.\n- Keyboard input wiring — call `ssh_client_send()` from whatever source you have.\n- Store SSH targets — NVS schema is application-specific.\n\n## Quick start\n\n### 1. Add the component\n\nIn your project's `main/idf_component.yml`:\n\n```yaml\ndependencies:\n  dmatking/esp32-wolfssh-client: \"\u003e=0.1.0\"\n```\n\nFor local development, use a path dependency instead:\n\n```yaml\ndependencies:\n  esp32-wolfssh-client:\n    path: /path/to/esp32-wolfssh-client\n```\n\n### 2. Initialize wolfSSH once at startup\n\n```c\n#include \"esp_wolfssh_client.h\"\n#include \u003cwolfssh/ssh.h\u003e\n\nwolfSSH_Init();  // call once, before ssh_client_connect()\n```\n\n### 3. Connect\n\n```c\nstatic void on_data(const uint8_t *data, size_t len, void *ctx) {\n    // feed into your VT100 parser / terminal renderer\n}\n\nstatic void on_disconnected(int reason, void *ctx) {\n    // schedule a reconnect if desired\n}\n\nssh_client_config_t cfg = {\n    .host     = \"192.168.1.1\",\n    .port     = 22,\n    .user     = \"myuser\",\n    .password = \"mypassword\",   // or set privkey_pem/pubkey_pem for key auth\n    .term_cols = 80,\n    .term_rows = 24,\n    .callbacks = {\n        .on_data         = on_data,\n        .on_disconnected = on_disconnected,\n    },\n};\nESP_ERROR_CHECK(ssh_client_connect(\u0026cfg));\n```\n\n### 4. Send keystrokes\n\n```c\n// From any FreeRTOS task (e.g. BLE keyboard callback)\nssh_client_send(key_bytes, len);\n```\n\n### 5. Resize the terminal\n\n```c\nssh_client_resize(new_cols, new_rows);\n```\n\n## Public API\n\n```c\nesp_err_t ssh_client_connect(const ssh_client_config_t *cfg);\nesp_err_t ssh_client_send(const uint8_t *data, size_t len);\nesp_err_t ssh_client_resize(uint16_t cols, uint16_t rows);\nvoid      ssh_client_disconnect(void);\nbool      ssh_client_is_connected(void);\n```\n\nSee `include/esp_wolfssh_client.h` for full documentation.\n\n## Security\n\n### Host-key verification\n\nBy default, the component accepts any server host key.  This is convenient for\nLAN-only embedded terminals connecting to a known device, but it means a\nman-in-the-middle on the network path can silently intercept the session —\ncredentials, keystrokes, and output — without any indication to the application.\n\nTo verify the server's identity, implement `on_host_key` in your callbacks:\n\n```c\nstatic bool my_host_key_check(const uint8_t *key, size_t len, void *ctx)\n{\n    // Compare key/len against a pinned fingerprint or a stored known-hosts entry.\n    // Return true to accept, false to abort the connection.\n    return true;  // replace with your actual check\n}\n\nssh_client_config_t cfg = {\n    ...\n    .callbacks = {\n        .on_host_key = my_host_key_check,\n        ...\n    },\n};\n```\n\nThe raw key bytes are passed as-is from wolfSSH's host-key exchange.  The\napplication is responsible for pinning, TOFU (trust-on-first-use), or\nknown-hosts comparison — the component deliberately avoids NVS host-key storage\nsince that schema is application-specific.\n\nIf `on_host_key` is NULL (the default), all host keys are accepted.\n\n## Multi-session note\n\nOnly one SSH session is active at a time.  `ssh_client_connect()` returns\n`ESP_ERR_INVALID_STATE` if called while a session is running.  Call\n`ssh_client_disconnect()` and wait for `on_disconnected` before reconnecting.\n\n## Bundled wolfssh\n\nA copy of [wolfSSH](https://github.com/wolfSSL/wolfssh) v1.4.20 is bundled in `wolfssh/`\n(BSD-3 license).  wolfSSL itself is declared as a registry dependency and pulled in\nautomatically.\n\n## License\n\nComponent code: Apache-2.0.\nBundled wolfSSH: BSD-3 (see `wolfssh/LICENSE.txt`).\nwolfSSL (registry dependency): GPL-2.0 or commercial — see wolfSSL's terms.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmatking%2Fesp32-wolfssh-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmatking%2Fesp32-wolfssh-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmatking%2Fesp32-wolfssh-client/lists"}