/* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ use binder::{BinderFeatures, Interface, ParcelFileDescriptor, Status, StatusCode}; use std::ffi::CStr; use std::os::fd::{FromRawFd, OwnedFd}; use tipc::Uuid; use trusty_binder_accessor::aidl::trusty::os::ITrustyAccessor::{ BnTrustyAccessor, ITrustyAccessor, ERROR_FAILED_TO_CREATE_SOCKET, }; pub enum SecurityConfig { // The accessor will resolve connections using the AuthMgr protocol. Secure, // The accessor will not perform any authentication or authorization, // but simply establish a connection to the target port. Insecure { target_port: &'static CStr }, } pub struct AuthMgrAccessor { service_name: &'static str, security_config: SecurityConfig, _uuid: Uuid, } impl AuthMgrAccessor { pub fn new_binder( service_name: &'static str, security_config: SecurityConfig, _uuid: Uuid, ) -> binder::Strong { let accessor = AuthMgrAccessor { service_name, security_config, _uuid }; BnTrustyAccessor::new_binder(accessor, BinderFeatures::default()) } } impl ITrustyAccessor for AuthMgrAccessor { fn addConnection(&self) -> Result { match self.security_config { SecurityConfig::Secure => unimplemented!(), SecurityConfig::Insecure { target_port } => add_insecure_connection(target_port), } } fn getInstanceName(&self) -> Result { let mut out_name = String::new(); out_name.try_reserve_exact(self.service_name.len()).map_err(|_| StatusCode::NO_MEMORY)?; out_name.push_str(self.service_name); Ok(out_name) } } impl Interface for AuthMgrAccessor {} fn add_insecure_connection(port: &CStr) -> Result { let handle = tipc::Handle::connect(port).map_err(|_| { binder::Status::new_service_specific_error( ERROR_FAILED_TO_CREATE_SOCKET, Some(c"AuthMgrAccessor failed to connect to port"), ) })?; // TODO: b/395847127 - clean this up once we have Handle::into_raw_fd let fd = handle.as_raw_fd(); // Do not close this fd. We're passing ownership of it // to ParcelFileDescriptor. core::mem::forget(handle); // SAFETY: The fd is open since it was obtained from a successful call to // tipc::Handle::connect. The fd is suitable for transferring ownership because we've leaked // the original handle to ensure it isn't dropped. let owned_fd = unsafe { OwnedFd::from_raw_fd(fd) }; Ok(ParcelFileDescriptor::new(owned_fd)) }