Files

45 lines
2.1 KiB
Go

// Package licensing provides pluggable signing strategies for the per-login
// CMD_MASTERSETTING signature. Three modes are picked at startup by env var:
//
// - LocalSigner (YAMA_SIGN_PASSWORD set): operator's own deployment.
// Signs directly with the HMAC master key. Optionally serves as License
// Server for RemoteSigner deployments (see server.go) when
// YAMA_LICENSE_HTTP_ADDR is also set.
//
// - RemoteSigner (YAMA_LICENSE_SERVER + YAMA_LICENSE_TOKEN set): customer
// deployments. Never sees the HMAC master key — each new device login
// does an HTTPS POST to the operator's License Server to fetch a
// signature. Successful results are cached for 24h so transient
// License Server outages don't break new logins.
//
// - NoOpSigner (neither set): free-tier mode. Returns empty signature so
// the client's private library refuses screen/file features; device
// list keeps working.
//
// The Sign call is on the per-login critical path — keep it fast.
// LocalSigner is microseconds (HMAC). RemoteSigner is one HTTPS round-trip
// on cache miss (~100-300 ms), zero on cache hit.
package licensing
// Signer produces the per-login signature for CMD_MASTERSETTING.
//
// Sign returns the 64-char lowercase hex HMAC-SHA256 of "<startTime>|<clientID>"
// keyed by the deployment's master HMAC secret. Returning "" means "no
// signature available" — sendMasterSetting will ship a zeroed Signature[64]
// field, and the client's private library will refuse screen/file init.
type Signer interface {
// Sign generates the signature for a new device login. SHOULD be quick
// (sub-300ms target). Returning ("", nil) is allowed and means "this
// deployment doesn't sign" (NoOpSigner). Returning ("", err) means a
// transient failure — callers ship zeroed signature and log the error;
// the device can retry by reconnecting.
Sign(startTime, clientID string) (string, error)
// Mode returns a short identifier for logging: "local", "remote", "noop".
Mode() string
// Close releases background resources (HTTP keepalives, caches).
// Idempotent.
Close() error
}