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 ipc::Skeleton;
19 
20 use asset_definition::{log_throw_error, ErrCode, Result};
21 
22 use crate::{get_user_id, OwnerType, SUCCESS};
23 
24 #[repr(C)]
25 struct HapInfoFfi {
26     app_id: *mut u8,
27     app_id_len: u32,
28     app_index: i32,
29 }
30 
31 #[repr(C)]
32 struct NativeInfoFfi {
33     uid: u32,
34 }
35 
36 #[repr(C)]
37 struct ProcessInfoFfi {
38     user_id: u32,
39     owner_type: u32,
40 
41     process_name: *mut u8,
42     process_name_len: u32,
43 
44     hap_info: HapInfoFfi,
45     native_info: NativeInfoFfi,
46 }
47 
48 impl ProcessInfoFfi {
init(user_id: u32, uid: u32, process_name: &mut Vec<u8>, app_id: &mut Vec<u8>) -> Self49     fn init(user_id: u32, uid: u32, process_name: &mut Vec<u8>, app_id: &mut Vec<u8>) -> Self {
50         ProcessInfoFfi {
51             user_id,
52             owner_type: 0,
53             process_name: process_name.as_mut_ptr(),
54             process_name_len: process_name.len() as u32,
55             hap_info: HapInfoFfi { app_id: app_id.as_mut_ptr(), app_id_len: app_id.len() as u32, app_index: 0 },
56             native_info: NativeInfoFfi { uid },
57         }
58     }
59 }
60 
61 extern "C" {
GetCallingProcessInfo(userId: u32, uid: u64, ownerInfo: *mut ProcessInfoFfi) -> i3262     fn GetCallingProcessInfo(userId: u32, uid: u64, ownerInfo: *mut ProcessInfoFfi) -> i32;
63 }
64 
65 /// hap-relative information
66 #[derive(Clone)]
67 #[derive(PartialEq, Eq)]
68 pub struct HapInfo {
69     /// app id for a hap
70     pub app_id: Vec<u8>,
71 
72     /// app index
73     pub app_index: i32,
74 }
75 
76 /// native-relative information
77 #[derive(Clone)]
78 #[derive(PartialEq, Eq)]
79 pub struct NativeInfo {
80     /// uid
81     pub uid: u32,
82 }
83 
84 /// process detail information
85 #[derive(Clone)]
86 #[derive(PartialEq, Eq)]
87 pub enum ProcessInfoDetail {
88     /// hap-relative information
89     Hap(HapInfo),
90 
91     /// native-relative information
92     Native(NativeInfo),
93 }
94 
95 /// The identity of calling process.
96 #[derive(Clone)]
97 #[derive(PartialEq, Eq)]
98 pub struct ProcessInfo {
99     /// user id of the process
100     pub user_id: u32,
101 
102     /// the owner type of the process
103     pub owner_type: OwnerType,
104 
105     /// process name
106     pub process_name: Vec<u8>,
107 
108     /// process information
109     pub process_info_detail: ProcessInfoDetail,
110 }
111 
112 impl ProcessInfo {
113     /// Build process info.
build() -> Result<Self>114     pub fn build() -> Result<Self> {
115         let uid = Skeleton::calling_uid();
116         let user_id = get_user_id(uid)?;
117         let mut process_name = vec![0u8; 256];
118         let mut app_id: Vec<u8> = vec![0u8; 256];
119         let mut process_info_ffi = ProcessInfoFfi::init(user_id, uid as u32, &mut process_name, &mut app_id);
120         match unsafe { GetCallingProcessInfo(user_id, uid, &mut process_info_ffi) } {
121             SUCCESS => {
122                 process_name.truncate(process_info_ffi.process_name_len as usize);
123                 app_id.truncate(process_info_ffi.hap_info.app_id_len as usize);
124             },
125             error => {
126                 let error = ErrCode::try_from(error as u32)?;
127                 return log_throw_error!(error, "[FATAL]Get calling package name failed, res is {}.", error);
128             },
129         }
130 
131         let process_info_detail = match OwnerType::try_from(process_info_ffi.owner_type)? {
132             OwnerType::Hap => {
133                 ProcessInfoDetail::Hap(HapInfo { app_id, app_index: process_info_ffi.hap_info.app_index })
134             },
135             OwnerType::Native => ProcessInfoDetail::Native(NativeInfo { uid: process_info_ffi.native_info.uid }),
136         };
137 
138         Ok(Self {
139             user_id,
140             owner_type: OwnerType::try_from(process_info_ffi.owner_type)?,
141             process_name,
142             process_info_detail,
143         })
144     }
145 }
146