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

            
7
use tor_rpcbase as rpc;
8

            
9
mod cookie;
10
mod 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]
19
pub 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)]
26
enum 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)]
38
enum 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)]
55
struct AuthenticateReply {
56
    /// An handle for a `Session` object.
57
    session: rpc::ObjectId,
58
}
59

            
60
impl 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
}