Fingermouse is a Tokio-based finger server that answers classic finger queries
over TCP. User details are sourced from a TOML document hosted in an
object_store backend, and optional .plan files are delivered when the
client requests verbose output.
- Fully asynchronous request handling on top of
tokio. - Object store integration via
object_store::local::LocalFileSystem, ready to swap for cloud backends in the future. - Strict username and hostname validation to prevent traversal or wildcard enumeration.
- Per-IP sliding window rate limiting backed by injectable clocks for deterministic tests.
- Structured logging through
tracingwith environment-controlled log levels.
The executable reads configuration from command-line options or matching environment variables:
--listen/FINGERMOUSE_LISTEN: TCP socket address to bind to (default0.0.0.0:7979).--default-host/FINGERMOUSE_DEFAULT_HOST: hostname returned when the client omits one (defaultlocalhost).--allowed-hosts/FINGERMOUSE_ALLOWED_HOSTS: comma-separated list of hostnames Fingermouse serves (defaults to the value ofdefault-host).--store-root/FINGERMOUSE_STORE_ROOT: filesystem root used by the object store (default./data). The path is created if missing.--profile-prefix/FINGERMOUSE_PROFILE_PREFIX: directory containing<username>.tomlprofile files (defaultprofiles).--plan-prefix/FINGERMOUSE_PLAN_PREFIX: directory containing<username>.planfiles (defaultplans).--rate-limit/FINGERMOUSE_RATE_LIMIT: permitted requests per window for each IP address (default30).--rate-window-secs/FINGERMOUSE_RATE_WINDOW_SECS: length of the rate- limiting window (default60).--rate-capacity/FINGERMOUSE_RATE_CAPACITY: maximum distinct client IPs retained before eviction (default8192).--metrics-listen/FINGERMOUSE_METRICS_LISTEN: optional socket address that exposes Prometheus metrics (disabled by default).--request-timeout-ms/FINGERMOUSE_REQUEST_TIMEOUT_MS: read timeout for client queries (default3000).--max-request-bytes/FINGERMOUSE_MAX_REQUEST_BYTES: maximum accepted query size (default512).
Profiles must expose a username key matching the requested account. All other
string keys are returned verbatim as Key: Value pairs in the finger response.
When /W is present, Fingermouse appends the user's plan, reports
(empty plan) for blank files, or (no plan) when the plan is missing.
<store-root>/
profiles/
alice.toml
plans/
alice.plan
Each profile TOML file must be UTF-8 and contain string values only. Plans are treated as UTF-8 text and sanitized to printable ASCII to avoid terminal control sequences.
Fingermouse uses crates that support static linking. To produce a musl binary
for a scratch container, use cargo zigbuild:
cargo install cargo-zigbuild
cargo zigbuild --target x86_64-unknown-linux-musl --releaseThe resulting binary in target/x86_64-unknown-linux-musl/release can be
copied into a FROM scratch image together with the profiles/ and plans/
directories.
Fast feedback is available through:
cargo fmtfor formatting checks.make lintfor linting, which runs Clippy (cargo clippy --all-targets --all-features -- -D warnings) followed by the Whitaker Dylint suite with warnings denied.cargo testfor unit tests built withrstestandtokio.make spellingfor en-GB-oxendict prose spelling. The generatedtypos.tomlstarts from the shared estate dictionary, refreshes its untracked local cache only when the authority is newer, and then applies the narrow repository policy intypos.local.toml.
Linting requires the Whitaker suite. Install it with
whitaker-installer:
cargo binstall --no-confirm --locked whitaker-installer # or: cargo install --locked whitaker-installer
whitaker-installerThis provisions the pinned toolchain, cargo-dylint, and the whitaker
wrapper used by make lint.
The rate limiter depends on the mockable clock abstraction, enabling
deterministic control of timestamps in the test suite.