arti_rpcserver/connection/auth.rs
1//! RPC commands and related functionality for authentication.
2//!
3//! In Arti's RPC system, authentication is a kind of method that can be invoked
4//! on the special "connection" object, which gives you an RPC _session_ as a
5//! result. The RPC session is the root for all other capabilities.
6
7use tor_rpcbase as rpc;
8
9mod cookie;
10mod inherent;
11
12/// Information about how an RPC session has been authenticated.
13///
14/// Currently, this isn't actually used for anything, since there's only one way
15/// to authenticate a connection. It exists so that later we can pass
16/// information to the session-creator function.
17#[derive(Clone, Debug)]
18#[non_exhaustive]
19pub struct RpcAuthentication {}
20
21/// The authentication scheme as enumerated in the spec.
22///
23/// Conceptually, an authentication scheme answers the question "How can the
24/// Arti process know you have permissions to use or administer it?"
25#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
26enum AuthenticationScheme {
27 /// Inherent authority based on the ability to open the connection to this address.
28 #[serde(rename = "auth:inherent")]
29 Inherent,
30
31 /// Negotiation based on mutual proof of ability to read a file from disk.
32 #[serde(rename = "auth:cookie")]
33 Cookie,
34}
35
36/// An error during authentication.
37#[derive(Debug, Clone, thiserror::Error, serde::Serialize)]
38enum AuthenticationFailure {
39 /// The authentication method wasn't one we support.
40 #[error("Tried to use unexpected authentication method")]
41 IncorrectMethod,
42 /// Tried to reuse a cookie authentication object
43 #[error("Tried to re-authenticate with a cookie authentication object")]
44 CookieNonceReused,
45 /// Tried to provide a secret, MAC, or other object that wasn't correct.
46 #[error("Incorrect authentication value")]
47 IncorrectAuthentication,
48 /// RPC system is shutting down; can't authenticate
49 #[error("Shutting down; can't authenticate")]
50 ShuttingDown,
51}
52
53/// A successful response from an authenticate method.
54#[derive(Debug, serde::Serialize)]
55struct AuthenticateReply {
56 /// An handle for a `Session` object.
57 session: rpc::ObjectId,
58}
59
60impl From<AuthenticationFailure> for rpc::RpcError {
61 fn from(value: AuthenticationFailure) -> Self {
62 use tor_error::ErrorKind as EK;
63 use AuthenticationFailure as AF;
64
65 let mut err = rpc::RpcError::new(value.to_string(), rpc::RpcErrorKind::RequestError);
66 match value {
67 AF::IncorrectMethod | AF::CookieNonceReused | AF::IncorrectAuthentication => {}
68 AF::ShuttingDown => err.set_kind(EK::ArtiShuttingDown),
69 }
70 err
71 }
72}