1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 //! This module implements the capability of processing the identity information of the Asset caller. 17 18 use std::ptr::{null, null_mut}; 19 20 use ipc::Skeleton; 21 22 use asset_definition::{log_throw_error, ErrCode, Result, Value}; 23 24 use crate::{get_user_id, ConstAssetBlob, MutAssetBlob, OwnerType, SUCCESS}; 25 26 #[repr(C)] 27 struct HapInfoFfi { 28 app_index: i32, 29 app_id: MutAssetBlob, 30 group_id: ConstAssetBlob, 31 developer_id: MutAssetBlob, 32 } 33 34 #[repr(C)] 35 struct NativeInfoFfi { 36 uid: u32, 37 } 38 39 #[repr(C)] 40 struct ProcessInfoFfi { 41 user_id: u32, 42 owner_type: u32, 43 process_name: MutAssetBlob, 44 hap_info: HapInfoFfi, 45 native_info: NativeInfoFfi, 46 } 47 48 impl ProcessInfoFfi { build( group_id: &Option<Vec<u8>>, process_name: &mut Vec<u8>, app_id: &mut Vec<u8>, developer_id: &mut Option<Vec<u8>>, ) -> Result<Self>49 fn build( 50 group_id: &Option<Vec<u8>>, 51 process_name: &mut Vec<u8>, 52 app_id: &mut Vec<u8>, 53 developer_id: &mut Option<Vec<u8>>, 54 ) -> Result<Self> { 55 let process_name = MutAssetBlob { size: process_name.len() as u32, data: process_name.as_mut_ptr() }; 56 let app_id = MutAssetBlob { size: app_id.len() as u32, data: app_id.as_mut_ptr() }; 57 let group_id = match group_id { 58 Some(group_id) => ConstAssetBlob { size: group_id.len() as u32, data: group_id.as_ptr() }, 59 None => ConstAssetBlob { size: 0, data: null() }, 60 }; 61 let developer_id = match developer_id { 62 Some(developer_id) => MutAssetBlob { size: developer_id.len() as u32, data: developer_id.as_mut_ptr() }, 63 None => MutAssetBlob { size: 0, data: null_mut() }, 64 }; 65 Ok(ProcessInfoFfi { 66 user_id: 0, 67 owner_type: OwnerType::Hap as u32, 68 process_name, 69 hap_info: HapInfoFfi { app_index: 0, app_id, group_id, developer_id }, 70 native_info: NativeInfoFfi { uid: 0 }, 71 }) 72 } 73 } 74 75 extern "C" { GetCallingProcessInfo(userId: u32, uid: u64, ownerInfo: *mut ProcessInfoFfi) -> i3276 fn GetCallingProcessInfo(userId: u32, uid: u64, ownerInfo: *mut ProcessInfoFfi) -> i32; 77 } 78 79 /// hap-relative information 80 #[derive(Clone)] 81 #[derive(PartialEq, Eq)] 82 pub struct HapInfo { 83 /// app id for a hap 84 pub app_id: Vec<u8>, 85 86 /// app index 87 pub app_index: i32, 88 89 /// group id for a hap 90 pub group_id: Option<Vec<u8>>, 91 92 /// developer id for a hap 93 pub developer_id: Option<Vec<u8>>, 94 } 95 96 /// native-relative information 97 #[derive(Clone)] 98 #[derive(PartialEq, Eq)] 99 pub struct NativeInfo { 100 /// uid 101 pub uid: u32, 102 } 103 104 /// process detail information 105 #[derive(Clone)] 106 #[derive(PartialEq, Eq)] 107 pub enum ProcessInfoDetail { 108 /// hap-relative information 109 Hap(HapInfo), 110 111 /// native-relative information 112 Native(NativeInfo), 113 } 114 115 /// The identity of calling process. 116 #[derive(Clone)] 117 #[derive(PartialEq, Eq)] 118 pub struct ProcessInfo { 119 /// user id of the process 120 pub user_id: u32, 121 122 /// the owner type of the process 123 pub owner_type: OwnerType, 124 125 /// process name 126 pub process_name: Vec<u8>, 127 128 /// process information 129 pub process_info_detail: ProcessInfoDetail, 130 } 131 132 impl ProcessInfo { 133 /// Build process info. build(group_attr: Option<&Value>) -> Result<Self>134 pub fn build(group_attr: Option<&Value>) -> Result<Self> { 135 let uid = Skeleton::calling_uid(); 136 let user_id = get_user_id(uid)?; 137 let mut process_name = vec![0u8; 256]; 138 let mut app_id = vec![0u8; 256]; 139 let (group_id, mut developer_id) = match group_attr { 140 Some(Value::Bytes(group_attr)) => (Some(group_attr.clone()), Some(vec![0u8; 128])), 141 _ => (None, None), 142 }; 143 let mut process_info_ffi = ProcessInfoFfi::build(&group_id, &mut process_name, &mut app_id, &mut developer_id)?; 144 match unsafe { GetCallingProcessInfo(user_id, uid, &mut process_info_ffi) } { 145 SUCCESS => { 146 process_name.truncate(process_info_ffi.process_name.size as usize); 147 app_id.truncate(process_info_ffi.hap_info.app_id.size as usize); 148 if let Some(developer_id) = &mut developer_id { 149 developer_id.truncate(process_info_ffi.hap_info.developer_id.size as usize); 150 } 151 }, 152 error => { 153 let error = ErrCode::try_from(error as u32)?; 154 return log_throw_error!(error, "[FATAL]Get calling package name failed, res is {}.", error); 155 }, 156 } 157 158 let process_info_detail = match OwnerType::try_from(process_info_ffi.owner_type)? { 159 OwnerType::Hap | OwnerType::HapGroup => ProcessInfoDetail::Hap(HapInfo { 160 app_id, 161 app_index: process_info_ffi.hap_info.app_index, 162 group_id, 163 developer_id, 164 }), 165 OwnerType::Native => ProcessInfoDetail::Native(NativeInfo { uid: process_info_ffi.native_info.uid }), 166 }; 167 168 Ok(Self { 169 user_id: process_info_ffi.user_id, 170 owner_type: OwnerType::try_from(process_info_ffi.owner_type)?, 171 process_name, 172 process_info_detail, 173 }) 174 } 175 } 176