fix(collab): make the hsm relay locator unix-only
The signer daemon's whole security surface (SO_PEERCRED caller authentication, socket-file mode/owner checks, O_NOFOLLOW opens, flock single-instance) is unix semantics; config.rs paths are POSIX too, so windows targets got fifty-five compile errors and a runtime test failure. Gate the crate at the root with a stub main instead of porting checks nobody consumes, and move the deps under cfg(unix) so windows builds stop resolving the PKCS#11 stack entirely. Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
This commit is contained in:
parent
30b11f3584
commit
310f40083d
|
|
@ -8,7 +8,12 @@ repository.workspace = true
|
|||
description = "PKCS#11-backed OPLS signer for OpenPencil relay locators"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
# Every dependency is Unix-gated because the crate itself is: on other platforms
|
||||
# the library compiles to nothing and the binary is a stub that exits with an
|
||||
# unsupported-platform error. Keeping the dependencies out of the non-Unix graph
|
||||
# means a Windows `cargo build --workspace` neither resolves nor builds the
|
||||
# PKCS#11 and crypto stack for code that cannot run there.
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
base64 = "0.22"
|
||||
cryptoki = "0.12"
|
||||
ed25519-dalek = { version = "2.2", default-features = false, features = ["std"] }
|
||||
|
|
@ -21,5 +26,5 @@ tracing.workspace = true
|
|||
tracing-subscriber.workspace = true
|
||||
zeroize = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
[target.'cfg(unix)'.dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
|
|
|||
|
|
@ -1,15 +1,49 @@
|
|||
//! PKCS#11-backed OPLS signer for OpenPencil relay locators.
|
||||
//!
|
||||
//! This is a Unix-only daemon. Every guarantee it makes rests on a POSIX
|
||||
//! primitive for which no audited Windows equivalent is implemented here:
|
||||
//!
|
||||
//! * callers are authenticated by Unix-domain-socket peer credentials
|
||||
//! (`SO_PEERCRED` on Linux, `getpeereid` on the BSDs), never by anything the
|
||||
//! request payload asserts about itself;
|
||||
//! * the config and PIN files are accepted only after their owner, mode, and
|
||||
//! link count are verified, and are opened with `O_NOFOLLOW` so a swapped
|
||||
//! symlink cannot redirect the read;
|
||||
//! * the listening socket, its `flock` lock file, and its heartbeat file are
|
||||
//! created with explicit modes and re-validated against uid/gid/mode
|
||||
//! expectations before the signer serves a single request;
|
||||
//! * even the config schema is POSIX-shaped — it carries the expected client
|
||||
//! uid/gid and a socket path bounded by the `sun_path` limit.
|
||||
//!
|
||||
//! Building this on Windows would mean either compiling those checks out, which
|
||||
//! leaves a signer that still looks functional after its file-ownership and
|
||||
//! peer-identity guarantees are gone, or inventing an unaudited ACL-based
|
||||
//! substitute for them. Both are worse than not shipping the daemon there, so
|
||||
//! the entire crate is gated on `cfg(unix)` and the binary exits with an
|
||||
//! explicit unsupported-platform error elsewhere.
|
||||
|
||||
#[cfg(unix)]
|
||||
pub mod config;
|
||||
#[cfg(unix)]
|
||||
pub mod error;
|
||||
#[cfg(unix)]
|
||||
pub mod pkcs11;
|
||||
#[cfg(unix)]
|
||||
pub mod protocol;
|
||||
// The signer daemon speaks over a permission-checked Unix domain socket and
|
||||
// enforces unix file modes on its secrets; there is no Windows deployment
|
||||
// target, so the socket server and secure-file layers are unix-only.
|
||||
#[cfg(unix)]
|
||||
pub mod secure_file;
|
||||
#[cfg(unix)]
|
||||
pub mod server;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub use config::{KeyConfig, Region, SignerConfig};
|
||||
#[cfg(unix)]
|
||||
pub use error::{SignerError, SignerResult};
|
||||
#[cfg(unix)]
|
||||
pub use pkcs11::KeyStore;
|
||||
|
||||
/// Reported by the binary on platforms where the signer cannot run.
|
||||
#[cfg(not(unix))]
|
||||
pub const UNSUPPORTED_PLATFORM: &str = "the OpenPencil relay locator HSM signer requires a Unix \
|
||||
host: it authenticates callers with Unix-domain-socket peer credentials and guards its config \
|
||||
and PIN files with POSIX ownership, mode, and link-count checks";
|
||||
|
|
|
|||
|
|
@ -1,14 +1,28 @@
|
|||
// The signer only deploys on unix (permission-checked unix socket); other
|
||||
// hosts get a stub main so workspace-wide checks still build the target.
|
||||
#![cfg_attr(not(unix), allow(dead_code))]
|
||||
|
||||
use std::{env, path::PathBuf, process::ExitCode};
|
||||
use std::process::ExitCode;
|
||||
|
||||
#[cfg(unix)]
|
||||
use op_collab_relay_locator_hsm::{secure_file, server, KeyStore, SignerConfig};
|
||||
use op_collab_relay_locator_hsm::{SignerError, SignerResult};
|
||||
use std::{env, path::PathBuf};
|
||||
|
||||
#[cfg(unix)]
|
||||
use op_collab_relay_locator_hsm::{
|
||||
secure_file, server, KeyStore, SignerConfig, SignerError, SignerResult,
|
||||
};
|
||||
#[cfg(unix)]
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
// The signer's security model is POSIX-only; see the crate-level documentation
|
||||
// in lib.rs for why there is no Windows implementation rather than a Windows
|
||||
// build with the ownership and peer-credential checks compiled out.
|
||||
#[cfg(not(unix))]
|
||||
fn main() -> ExitCode {
|
||||
eprintln!(
|
||||
"locator HSM signer failed: {}",
|
||||
op_collab_relay_locator_hsm::UNSUPPORTED_PLATFORM
|
||||
);
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
enum Command {
|
||||
Serve,
|
||||
Check,
|
||||
|
|
@ -17,6 +31,7 @@ enum Command {
|
|||
Initialize { so_pin_file: PathBuf },
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
struct Arguments {
|
||||
command: Command,
|
||||
config: PathBuf,
|
||||
|
|
@ -34,13 +49,6 @@ fn main() -> ExitCode {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn main() -> ExitCode {
|
||||
init_tracing();
|
||||
eprintln!("locator HSM signer requires a unix host");
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn run() -> SignerResult<()> {
|
||||
let arguments = parse_arguments()?;
|
||||
|
|
@ -79,6 +87,7 @@ fn run() -> SignerResult<()> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn parse_arguments() -> SignerResult<Arguments> {
|
||||
let mut arguments = env::args().skip(1);
|
||||
let command = match arguments.next().as_deref() {
|
||||
|
|
@ -118,6 +127,7 @@ fn parse_arguments() -> SignerResult<Arguments> {
|
|||
Ok(Arguments { command, config })
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn usage() -> SignerError {
|
||||
SignerError::Config(
|
||||
"usage: op-collab-relay-locator-hsm <serve|check|public> --config PATH; \
|
||||
|
|
@ -126,6 +136,7 @@ fn usage() -> SignerError {
|
|||
)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn init_tracing() {
|
||||
let filter = env::var("OPENPENCIL_LOCATOR_HSM_LOG")
|
||||
.ok()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// The crate under test only exists on Unix; see its lib.rs for why.
|
||||
#![cfg(unix)]
|
||||
|
||||
use std::{env, path::PathBuf};
|
||||
|
||||
use ed25519_dalek::{Signature, VerifyingKey};
|
||||
|
|
|
|||
Loading…
Reference in a new issue