pub struct CallContext { /* private fields */ }Expand description
What a handler knows about the request it is serving.
Implementations§
Source§impl CallContext
impl CallContext
pub fn conn_id(&self) -> u64
Sourcepub fn role(&self) -> Option<&str>
pub fn role(&self) -> Option<&str>
The role of a device caller, from the scopes its enrolment granted (see
ROLE_SCOPE_PREFIX). None for a local app.
Sourcepub fn app(&self) -> &str
pub fn app(&self) -> &str
The app label the client declared in hello (already allowlisted); for a device caller,
the device id.
The label is a claim: any process of the current user can declare any allowlisted
label. Use it to choose what a caller may ask for, never as proof of who is asking.
peer is what the OS verified.
Sourcepub fn peer(&self) -> Option<&PeerIdentity>
pub fn peer(&self) -> Option<&PeerIdentity>
Who the OS says is on the other end of this connection, from the peer check that ran
before any byte was read: the uid on Unix, the user SID on Windows, and the process id
where the platform reports it (Linux, macOS and Windows). None for a caller that is not
a local app (a device has no OS peer).
This is the fact, as opposed to the app label. The user is always the
current user, since any other peer was refused. A pid identifies the process only while
it runs: record it for an audit trail, do not authorise by it later.
Sourcepub fn verify_peer_executable(
&self,
expect: &HostExpectation,
) -> Result<HostProcess, HostIdentityError>
pub fn verify_peer_executable( &self, expect: &HostExpectation, ) -> Result<HostProcess, HostIdentityError>
Does the process on the other end of this connection run the program expect names?
The server-side counterpart of Client::connect_expecting:
the same HostExpectation (executable paths compared after canonicalisation, same file
by identity, then the optional HostExpectation::with_verifier check), applied to
peer, so an app gates an owner-only method with RightKit code instead of
its own process inspection:
let owner = HostExpectation::executable(app_exe);
if cx.verify_peer_executable(&owner).is_err() {
return Err(ServiceError::new(ERROR_FORBIDDEN, "owner only"));
}Fails closed: a device caller (no OS peer), a peer whose pid, uid or executable cannot be
established, a process that exited or changed while it was identified, an expectation
naming no executable, a platform that cannot read a process’s executable, a connection
that has closed, and a refusing verifier are all Err. Never Ok on a guess.
Code signing: this crate links no code-signing API. On macOS the signing requirement
(SecRequirementCreateWithString against the process) and on Windows the Authenticode
subject (WinVerifyTrust on HostProcess::executable) go in
HostExpectation::with_verifier, which runs after the executable matched. On macOS
HostProcess::audit_token is the token the kernel captured when the client connected,
the race-free handle for SecCodeCopyGuestWithAttributes.
The process is pinned by pid plus its start time (Windows: an open process handle), and the connection must still be open when the check ends, so a peer that exited and whose pid was reused is refused. The window is the peer-gone watcher’s lag, about 40 ms. Run it per call; do not cache the answer past the connection.
Sourcepub fn peer_closed(&self) -> bool
pub fn peer_closed(&self) -> bool
The client went away while this request was running.
Sourcepub fn handoff_requested(&self) -> bool
pub fn handoff_requested(&self) -> bool
A higher-ranked host asked for the service: return
ServiceError::handoff at the next safe boundary.