arti_rpcserver/connection/auth/inherent.rs
1//! "Inherent" authentication, where the ability to establish a connection proves that the user is
2//! authorized.
3use std::sync::Arc;
4
5use super::{AuthenticateReply, AuthenticationFailure, AuthenticationScheme, RpcAuthentication};
6use crate::Connection;
7use derive_deftly::Deftly;
8use tor_rpc_connect::auth::RpcAuth;
9use tor_rpcbase as rpc;
10use 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"))]
30struct 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
37impl rpc::RpcMethod for Authenticate {
38 type Output = AuthenticateReply;
39 type Update = rpc::NoUpdates;
40}
41
42/// Invoke the "authenticate" method on a connection.
43async 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}
64rpc::static_rpc_invoke_fn! {
65 authenticate_connection;
66}