From b70753f17485378068def96a05e3e17d5fa75023 Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Wed, 29 May 2024 15:18:50 +0200 Subject: [PATCH 1/3] Add client example to README.md Signed-off-by: Wiktor Kwapisiewicz --- README.md | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0d618e1..b667269 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,16 @@ [![CI](https://github.com/wiktor-k/ssh-agent-lib/actions/workflows/rust.yml/badge.svg)](https://github.com/wiktor-k/ssh-agent-lib/actions/workflows/rust.yml) [![Crates.io](https://img.shields.io/crates/v/ssh-agent-lib)](https://crates.io/crates/ssh-agent-lib) -A collection of types for writing custom SSH agents as specified by the [SSH Agent Protocol Internet Draft](https://datatracker.ietf.org/doc/html/draft-miller-ssh-agent). +A collection of types for writing custom SSH agents and connecting to existing ones. -This makes it possible to utilize remote keys not supported by the default OpenSSH agent. +The types in this crate closely follow the [SSH Agent Protocol Internet Draft](https://datatracker.ietf.org/doc/html/draft-miller-ssh-agent) specification and can be used to utilize remote keys not supported by the default OpenSSH agent. -## Example +## Examples + +The following examples show a sample agent and a sample client. +For more elaborate example see the `examples` directory or [crates using `ssh-agent-lib`](https://crates.io/crates/ssh-agent-lib/reverse_dependencies). + +### Agent The following example starts listening on a socket and processing requests. On Unix it uses `ssh-agent.sock` Unix domain socket while on Windows it uses a named pipe `\\.\pipe\agent`. @@ -67,7 +72,32 @@ On Windows the path of the pipe has to be used: SSH_AUTH_SOCK=\\.\pipe\agent ssh user@example.com ``` -For more elaborate example see the `examples` directory or [crates using `ssh-agent-lib`](https://crates.io/crates/ssh-agent-lib/reverse_dependencies). +### Client + +The following example connects to the agent pointed to by the `SSH_AUTH_SOCK` environment variable and prints identities (public keys) that the agent knows of: + +```rust,no_run +use service_binding::Binding; +use ssh_agent_lib::client::connect; + +#[tokio::main] +async fn main() -> Result<(), Box> { + #[cfg(unix)] + let mut client = + connect(Binding::FilePath(std::env::var("SSH_AUTH_SOCK")?.into()).try_into()?)?; + + #[cfg(windows)] + let mut client = + connect(Binding::NamedPipe(std::env::var("SSH_AUTH_SOCK")?.into()).try_into()?)?; + + eprintln!( + "Identities that this agent knows of: {:#?}", + client.request_identities().await? + ); + + Ok(()) +} +``` ## License From 91dd0f15549eb740c5e156bcd7c49a0f1290e7bc Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Wed, 29 May 2024 15:33:32 +0200 Subject: [PATCH 2/3] Rename key storage example to be consistent Signed-off-by: Wiktor Kwapisiewicz --- .github/workflows/misc.yml | 2 +- Cargo.toml | 4 ---- examples/{key_storage.rs => key-storage.rs} | 0 tests/sign-and-verify-win.bat | 2 +- tests/sign-and-verify.sh | 2 +- 5 files changed, 3 insertions(+), 7 deletions(-) rename examples/{key_storage.rs => key-storage.rs} (100%) diff --git a/.github/workflows/misc.yml b/.github/workflows/misc.yml index 1181a7d..6d9492f 100644 --- a/.github/workflows/misc.yml +++ b/.github/workflows/misc.yml @@ -32,7 +32,7 @@ jobs: # If the example doesn't compile the integration test will # be stuck. Check for compilation issues earlier to abort the job - name: Check if the example compiles - run: cargo check --example key_storage + run: cargo check --example key-storage - name: Run integration tests run: ./tests/sign-and-verify.sh if: ${{ ! matrix.windows }} diff --git a/Cargo.toml b/Cargo.toml index 5edd5c9..62ca83f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,10 +39,6 @@ default = ["agent"] codec = ["tokio-util"] agent = ["futures", "log", "tokio", "async-trait", "codec"] -[[example]] -name = "key_storage" -required-features = ["agent"] - [dev-dependencies] env_logger = "0.11.0" rand = "0.8.5" diff --git a/examples/key_storage.rs b/examples/key-storage.rs similarity index 100% rename from examples/key_storage.rs rename to examples/key-storage.rs diff --git a/tests/sign-and-verify-win.bat b/tests/sign-and-verify-win.bat index da3258a..af178cb 100755 --- a/tests/sign-and-verify-win.bat +++ b/tests/sign-and-verify-win.bat @@ -1,6 +1,6 @@ rem del /F /Q Cargo.toml.sig id_rsa id_rsa.pub agent.pub -cmd /c "START /b cargo run --example key_storage" +cmd /c "START /b cargo run --example key-storage" @echo off :waitloop diff --git a/tests/sign-and-verify.sh b/tests/sign-and-verify.sh index 40dbc38..7754f80 100755 --- a/tests/sign-and-verify.sh +++ b/tests/sign-and-verify.sh @@ -3,7 +3,7 @@ set -euxo pipefail rm -rf ssh-agent.sock Cargo.toml.sig id_rsa id_rsa.pub agent.pub ca_user_key ca_user_key.pub id_rsa-cert.pub -RUST_LOG=info cargo run --example key_storage & +RUST_LOG=info cargo run --example key-storage & while [ ! -e ssh-agent.sock ]; do echo "Waiting for ssh-agent.sock" From 3ae4dc2805a3fd2b488158cbd24bf7318f112332 Mon Sep 17 00:00:00 2001 From: Wiktor Kwapisiewicz Date: Wed, 29 May 2024 15:33:46 +0200 Subject: [PATCH 3/3] Add README to examples Signed-off-by: Wiktor Kwapisiewicz --- examples/README.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 examples/README.md diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..0b2aa63 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,45 @@ +# Agent examples + +The examples in this directory show slightly more elaborate use-cases that can be implemented using this crate. + +## Agents + +### `key-storage` + +Implements a simple agent which remembers RSA private keys (added via `ssh-add`) and allows fetching their public keys and signing using three different signing mechanisms. + +This example additionally shows how to extract extensions from messages and works on all major OSes. + +It is used in integration tests that run as part of the CI. + +### `openpgp-card-agent` + +Allows using OpenPGP Card devices to sign SSH requests. +The PIN is stored in memory and can be time-constrained using SSH constraints. +For the sake of simplicity this agent supports only `ed25519` subkeys. + +This example additionally shows how to create custom protocol based on SSH extensions (in this case decrypt/derive feature). + +### `agent-socket-info` + +Shows how to extract information about the underlying connection. +For example under Unix systems this displays connecting process PID. +To keep the example brief the data is printed as part of a fake public key comment. + +## Clients + +### `pgp-wrapper` + +Wraps SSH keys in OpenPGP data thus allowing OpenPGP applications (such as GnuPG) to read and work with SSH keys. +This makes it possible to create OpenPGP signatures utilizing SSH keys. + +If the connecting agent supports derive/decrypt extension this example additionally creates a decryption subkey and can be used to decrypt OpenPGP data. + +### `proto-dumper` + +A simple forwarding example which works as an agent and client at the same time dumping all messages and forwarding them to the next agent. + +### `ssh-agent-client` + +Dumps identities stored by the agent. +Additionally invokes an extension and reads the result.