1 /*
2 * Copyright (C) 2025 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 use binder::{BinderFeatures, Interface, ParcelFileDescriptor, Status, StatusCode};
18 use std::ffi::CStr;
19 use std::os::fd::{FromRawFd, OwnedFd};
20 use tipc::Uuid;
21 use trusty_binder_accessor::aidl::trusty::os::ITrustyAccessor::{
22 BnTrustyAccessor, ITrustyAccessor, ERROR_FAILED_TO_CREATE_SOCKET,
23 };
24
25 pub enum SecurityConfig {
26 // The accessor will resolve connections using the AuthMgr protocol.
27 Secure,
28 // The accessor will not perform any authentication or authorization,
29 // but simply establish a connection to the target port.
30 Insecure { target_port: &'static CStr },
31 }
32
33 pub struct AuthMgrAccessor {
34 service_name: &'static str,
35 security_config: SecurityConfig,
36 _uuid: Uuid,
37 }
38
39 impl AuthMgrAccessor {
new_binder( service_name: &'static str, security_config: SecurityConfig, _uuid: Uuid, ) -> binder::Strong<dyn ITrustyAccessor>40 pub fn new_binder(
41 service_name: &'static str,
42 security_config: SecurityConfig,
43 _uuid: Uuid,
44 ) -> binder::Strong<dyn ITrustyAccessor> {
45 let accessor = AuthMgrAccessor { service_name, security_config, _uuid };
46 BnTrustyAccessor::new_binder(accessor, BinderFeatures::default())
47 }
48 }
49
50 impl ITrustyAccessor for AuthMgrAccessor {
addConnection(&self) -> Result<ParcelFileDescriptor, Status>51 fn addConnection(&self) -> Result<ParcelFileDescriptor, Status> {
52 match self.security_config {
53 SecurityConfig::Secure => unimplemented!(),
54 SecurityConfig::Insecure { target_port } => add_insecure_connection(target_port),
55 }
56 }
57
getInstanceName(&self) -> Result<String, Status>58 fn getInstanceName(&self) -> Result<String, Status> {
59 let mut out_name = String::new();
60 out_name.try_reserve_exact(self.service_name.len()).map_err(|_| StatusCode::NO_MEMORY)?;
61 out_name.push_str(self.service_name);
62
63 Ok(out_name)
64 }
65 }
66
67 impl Interface for AuthMgrAccessor {}
68
add_insecure_connection(port: &CStr) -> Result<ParcelFileDescriptor, Status>69 fn add_insecure_connection(port: &CStr) -> Result<ParcelFileDescriptor, Status> {
70 let handle = tipc::Handle::connect(port).map_err(|_| {
71 binder::Status::new_service_specific_error(
72 ERROR_FAILED_TO_CREATE_SOCKET,
73 Some(c"AuthMgrAccessor failed to connect to port"),
74 )
75 })?;
76
77 // TODO: b/395847127 - clean this up once we have Handle::into_raw_fd
78 let fd = handle.as_raw_fd();
79 // Do not close this fd. We're passing ownership of it
80 // to ParcelFileDescriptor.
81 core::mem::forget(handle);
82 // SAFETY: The fd is open since it was obtained from a successful call to
83 // tipc::Handle::connect. The fd is suitable for transferring ownership because we've leaked
84 // the original handle to ensure it isn't dropped.
85 let owned_fd = unsafe { OwnedFd::from_raw_fd(fd) };
86 Ok(ParcelFileDescriptor::new(owned_fd))
87 }
88