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}