1
//! "Inherent" authentication, where the ability to establish a connection proves that the user is
2
//! authorized.
3
use std::sync::Arc;
4

            
5
use super::{AuthenticateReply, AuthenticationFailure, AuthenticationScheme, RpcAuthentication};
6
use crate::Connection;
7
use derive_deftly::Deftly;
8
use tor_rpc_connect::auth::RpcAuth;
9
use tor_rpcbase as rpc;
10
use tor_rpcbase::templates::*;
11

            
12
/// Authenticate on an RPC Connection, returning a new Session.
13
///
14
/// After connecting to Arti, clients use this method to create a Session,
15
/// which they then use to access other functionality.
16
///
17
/// This method supports simple authentication schemes,
18
/// where only a single pass is necessary to open a session.
19
/// For now, only the `auth:inherent` scheme is supported here;
20
/// other schemes will be implemented in the future.
21
///
22
/// See also the `auth:begin_cookie` method.
23
///
24
/// You typically won't need to invoke this method yourself;
25
/// instead, your RPC library (such as `arti-rpc-client-core`)
26
/// should handle it for you.
27
#[derive(Debug, serde::Deserialize, Deftly)]
28
#[derive_deftly(DynMethod)]
29
#[deftly(rpc(method_name = "auth:authenticate"))]
30
struct Authenticate {
31
    /// The authentication scheme as enumerated in the spec.
32
    ///
33
    /// The only supported one for now is "auth:inherent"
34
    scheme: AuthenticationScheme,
35
}
36

            
37
impl rpc::RpcMethod for Authenticate {
38
    type Output = AuthenticateReply;
39
    type Update = rpc::NoUpdates;
40
}
41

            
42
/// Invoke the "authenticate" method on a connection.
43
async fn authenticate_connection(
44
    unauth: Arc<Connection>,
45
    method: Box<Authenticate>,
46
    ctx: Arc<dyn rpc::Context>,
47
) -> Result<AuthenticateReply, rpc::RpcError> {
48
    match (method.scheme, &unauth.require_auth) {
49
        // For now, we only support AF_UNIX connections, and we assume that if
50
        // you have permission to open such a connection to us, you have
51
        // permission to use Arti. We will refine this later on!
52
        (AuthenticationScheme::Inherent, RpcAuth::Inherent) => {}
53
        (_, _) => return Err(AuthenticationFailure::IncorrectMethod.into()),
54
    }
55

            
56
    let auth = RpcAuthentication {};
57
    let session = {
58
        let mgr = unauth.mgr()?;
59
        mgr.create_session(&auth)
60
    };
61
    let session = ctx.register_owned(session);
62
    Ok(AuthenticateReply { session })
63
}
64
rpc::static_rpc_invoke_fn! {
65
    authenticate_connection;
66
}