• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include <pthread.h>
17 #include <securec.h>
18 
19 #include "device_security_level_defines.h"
20 #include "device_security_level_proxy.h"
21 
22 #include "ohos_types.h"
23 #include "utils_log.h"
24 #include "utils_mem.h"
25 #include "utils_mutex.h"
26 
27 #define MAX_IPC_DATA_LEN 0x100
28 
GetMutex(void)29 static inline Mutex *GetMutex(void)
30 {
31     static Mutex mutex = INITED_MUTEX;
32     return &mutex;
33 }
34 
DslmIpcCallback(IOwner owner,int code,IpcIo * reply)35 static int DslmIpcCallback(IOwner owner, int code, IpcIo *reply)
36 {
37     uint32_t result = ERR_DEFAULT;
38     uint32_t level = 0;
39 
40     if (owner == NULL) {
41         return ERR_INVALID_PARA;
42     }
43 
44     struct DslmCallbackHolder *holder = (struct DslmCallbackHolder *)owner;
45 
46     ReadUint32(reply, &result);
47     if (result == SUCCESS) {
48         ReadUint32(reply, &level);
49         SECURITY_LOG_INFO("[TID:0x%lx] Notify Remote result: %u, level: %u", pthread_self(), result, level);
50     } else {
51         level = 0;
52         SECURITY_LOG_ERROR("RequestDeviceSecurityLevelSendRequest result value error, ret is %d", result);
53     }
54 
55     if (holder->callback != NULL) {
56         DeviceSecurityInfo *info = (DeviceSecurityInfo *)MALLOC(sizeof(DeviceSecurityInfo));
57         if (info == NULL) {
58             return ERR_NO_MEMORY;
59         }
60         info->magicNum = SECURITY_MAGIC;
61         info->result = result;
62         info->level = level;
63         SECURITY_LOG_INFO("calling user callback");
64         holder->callback(&holder->identity, info);
65     }
66 
67     return SUCCESS;
68 }
69 
DslmIpcAsyncCallImpl(IUnknown * iUnknown,const DeviceIdentify identify,const RequestOption option,uint32_t cookie,const DeviceSecurityInfoCallback callback)70 static BOOL DslmIpcAsyncCallImpl(IUnknown *iUnknown, const DeviceIdentify identify, const RequestOption option,
71     uint32_t cookie, const DeviceSecurityInfoCallback callback)
72 {
73     if (identify.length == 0 || identify.length > DEVICE_ID_MAX_LEN) {
74         SECURITY_LOG_ERROR("RequestDeviceSecurityLevel invalid para len.");
75         return ERR_INVALID_PARA;
76     }
77     struct DslmCallbackHolder owner = {identify, callback};
78     DslmClientProxy *proxy = (DslmClientProxy *)iUnknown;
79     IpcIo request;
80     char data[MAX_IPC_DATA_LEN];
81     IpcIoInit(&request, data, MAX_IPC_DATA_LEN, 0);
82     /* DeviceIdentify */
83     WriteUint32(&request, identify.length);
84     WriteBuffer(&request, identify.identity, DEVICE_ID_MAX_LEN);
85     /* option */
86     WriteUint64(&request, option.challenge);
87     WriteUint32(&request, option.timeout);
88     WriteUint32(&request, option.extra);
89     /* cookie */
90     WriteUint32(&request, cookie);
91 
92     int ret = proxy->Invoke((IClientProxy *)proxy, CMD_SET_DEVICE_SECURITY_LEVEL, &request, &owner, DslmIpcCallback);
93     if (ret != EC_SUCCESS) {
94         SECURITY_LOG_ERROR("RequestDeviceSecurityLevelSendRequest send failed, ret is %d", ret);
95         return ret;
96     }
97 
98     return SUCCESS;
99 }
100 
DslmCreatClient(const char * service,const char * feature,uint32 size)101 void *DslmCreatClient(const char *service, const char *feature, uint32 size)
102 {
103     (void)service;
104     (void)feature;
105     uint32_t len = size + sizeof(DslmClientEntry);
106     uint8_t *client = (uint8_t *)MALLOC(len);
107     if (client == NULL) {
108         SECURITY_LOG_ERROR("malloc error");
109         return NULL;
110     }
111     (void)memset_s(client, len, 0, len);
112     DslmClientEntry *entry = (DslmClientEntry *)&client[size];
113     entry->ver = ((uint16_t)CLIENT_PROXY_VER | (uint16_t)DEFAULT_VERSION);
114     entry->ref = 1;
115     entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
116     entry->iUnknown.AddRef = IUNKNOWN_AddRef;
117     entry->iUnknown.Release = IUNKNOWN_Release;
118     entry->iUnknown.Invoke = NULL;
119     entry->iUnknown.DslmIpcAsyncCall = DslmIpcAsyncCallImpl;
120     return client;
121 }
122 
DslmDestroyClient(const char * service,const char * feature,void * proxy)123 void DslmDestroyClient(const char *service, const char *feature, void *proxy)
124 {
125     (void)service;
126     (void)feature;
127     FREE(proxy);
128 }
129 
GetClientProxy(void)130 static DslmClientProxy *GetClientProxy(void)
131 {
132     SAMGR_RegisterFactory(DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE, DslmCreatClient, DslmDestroyClient);
133     DslmClientProxy *proxy = NULL;
134     SECURITY_LOG_INFO("[GetFeatureApi S:%s F:%s] begin", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
135     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
136     if (iUnknown == NULL) {
137         SECURITY_LOG_ERROR("[GetFeatureApi S:%s F:%s]: failed", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
138         return NULL;
139     }
140 
141     int32_t ret = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&proxy);
142     if (ret != SUCCESS || proxy == NULL) {
143         SECURITY_LOG_ERROR("[QueryInterface CLIENT_PROXY_VER S:%s, F:%s] failed", DSLM_SAMGR_SERVICE,
144             DSLM_SAMGR_FEATURE);
145         return NULL;
146     }
147     SECURITY_LOG_INFO("[QueryInterface CLIENT_PROXY_VER S:%s, F:%s] success", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
148     return proxy;
149 }
150 
ReleaseClientProxy(DslmClientProxy * clientProxy)151 static void ReleaseClientProxy(DslmClientProxy *clientProxy)
152 {
153     if (clientProxy == NULL) {
154         return;
155     }
156 
157     int32 ret = clientProxy->Release((IUnknown *)clientProxy);
158     SECURITY_LOG_INFO("[Release api S:%s, F:%s]: ret:%d", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE, ret);
159 }
160 
RequestDeviceSecurityInfoAsyncImpl(const DeviceIdentify * identify,const RequestOption * option,DeviceSecurityInfoCallback callback)161 int32_t RequestDeviceSecurityInfoAsyncImpl(const DeviceIdentify *identify, const RequestOption *option,
162     DeviceSecurityInfoCallback callback)
163 {
164     static uint32_t generated = 0;
165     if (identify == NULL || callback == NULL) {
166         SECURITY_LOG_ERROR("GetDeviceSecurityInfo input error");
167         return ERR_INVALID_PARA;
168     }
169 
170     static RequestOption defaultOption = {0, DEFAULT_KEEP_LEN, 0};
171     if (option == NULL) {
172         option = &defaultOption;
173     }
174     if (option->timeout > MAX_KEEP_LEN) {
175         SECURITY_LOG_ERROR("GetDeviceSecurityInfo input error, timeout too long");
176         return ERR_INVALID_PARA;
177     }
178 
179     LockMutex(GetMutex());
180     uint32_t cookie = ++generated;
181     UnlockMutex(GetMutex());
182     DslmClientProxy *proxy = GetClientProxy();
183     if (proxy == NULL) {
184         SECURITY_LOG_ERROR("[GetFeatureApi S:%s F:%s]: failed", DSLM_SAMGR_SERVICE, DSLM_SAMGR_FEATURE);
185         return ERR_IPC_PROXY_ERR;
186     }
187 
188     if (proxy->DslmIpcAsyncCall == NULL) {
189         SECURITY_LOG_ERROR("proxy has NULL api");
190         return ERR_IPC_PROXY_ERR;
191     }
192     BOOL result = proxy->DslmIpcAsyncCall((IUnknown *)proxy, *identify, *option, cookie, callback);
193     if (result != SUCCESS) {
194         SECURITY_LOG_ERROR("GetDeviceSecurityInfo RequestDeviceSecurityLevel error");
195         return result;
196     }
197     SECURITY_LOG_INFO("GetDeviceSecurityInfo RequestDeviceSecurityLevel success");
198     ReleaseClientProxy(proxy);
199     return SUCCESS;
200 }