1 /*
2 * Copyright (c) 2021 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 "hal_pms.h"
17 #include <limits.h>
18 #include <pthread.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23
24 #include <mbedtls/md.h>
25 #include "emmc_if.h"
26 #include "parameter.h"
27 #include "securec.h"
28
29 #define CID_LENGTH 16
30 #define UDID_ORI_BYTES 32
31 #define HEX_LEN 2
32 #define P_DIR "/storage/app/etc/permissions/"
33 #define PERM_MAX 1024
34
35 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
36
37 static const PermissionDef g_permissions[] = {
38 // appfwk
39 {"ohos.permission.LISTEN_BUNDLE_CHANGE", SYSTEM_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
40 {"ohos.permission.GET_BUNDLE_INFO", SYSTEM_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
41 {"ohos.permission.INSTALL_BUNDLE", SYSTEM_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
42 // media
43 {"ohos.permission.CAMERA", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
44 {"ohos.permission.MODIFY_AUDIO_SETTINGS", SYSTEM_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
45 {"ohos.permission.READ_MEDIA", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
46 {"ohos.permission.MICROPHONE", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
47 {"ohos.permission.WRITE_MEDIA", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
48 // soft_bus
49 {"ohos.permission.DISTRIBUTED_DATASYNC", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
50 // dvkit
51 {"ohos.permission.DISTRIBUTED_VIRTUALDEVICE", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
52 // might expire in the future
53 {"ohos.permission.RECORD_AUDIO", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
54 {"ohos.permission.READ_MEDIA_AUDIO", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
55 {"ohos.permission.READ_MEDIA_IMAGES", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
56 {"ohos.permission.READ_MEDIA_VIDEO", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
57 {"ohos.permission.WRITE_MEDIA_AUDIO", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
58 {"ohos.permission.WRITE_MEDIA_IMAGES", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
59 {"ohos.permission.WRITE_MEDIA_VIDEO", USER_GRANT, NOT_RESTRICTED, CAP_NOT_BINDED},
60 };
61
GetCId(void)62 static unsigned char *GetCId(void)
63 {
64 int mallocSize = sizeof(unsigned char) * CID_LENGTH;
65 unsigned char *cid = (unsigned char *)malloc(mallocSize);
66
67 if (cid == NULL) {
68 return NULL;
69 }
70 if (memset_s(cid, mallocSize, 0x0, mallocSize) != EOK) {
71 free(cid);
72 return NULL;
73 }
74 EmmcGetHuid(cid, CID_LENGTH);
75 return cid;
76 }
77
GenerateOriginalDevUdid(unsigned char * ori,int size)78 static int GenerateOriginalDevUdid(unsigned char *ori, int size)
79 {
80 if (ori == NULL || size != UDID_ORI_BYTES) {
81 return PERM_ERRORCODE_INVALID_PARAMS;
82 }
83 int result = PERM_ERRORCODE_GENERATE_UDID_FAILED;
84 const mbedtls_md_info_t *mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
85 if (mdInfo == NULL) {
86 return result;
87 }
88 mbedtls_md_context_t mdCtx;
89 mbedtls_md_init(&mdCtx);
90 if (mbedtls_md_setup(&mdCtx, mdInfo, 0) != 0) {
91 goto EXIT;
92 }
93 if (mbedtls_md_starts(&mdCtx) != 0) {
94 goto EXIT;
95 }
96 // Get sn number
97 const char *sn = GetSerial();
98 if (sn == NULL) {
99 goto EXIT;
100 }
101 // Get emmc id
102 unsigned char *cid = GetCId();
103 if (cid == NULL) {
104 goto EXIT;
105 }
106 if (mbedtls_md_update(&mdCtx, sn, strlen(sn)) != 0) {
107 goto FREE_EXIT;
108 }
109 if (mbedtls_md_update(&mdCtx, cid, CID_LENGTH) != 0) {
110 goto FREE_EXIT;
111 }
112 if (mbedtls_md_finish(&mdCtx, ori) != 0) {
113 goto FREE_EXIT;
114 }
115 result = PERM_ERRORCODE_SUCCESS;
116
117 FREE_EXIT:
118 free(cid);
119
120 EXIT:
121 mbedtls_md_free(&mdCtx);
122 return result;
123 }
124
HalGetPermissionList(unsigned int * length)125 PermissionDef* HalGetPermissionList(unsigned int *length)
126 {
127 if (length == NULL) {
128 return NULL;
129 }
130 *length = sizeof(g_permissions) / sizeof(PermissionDef);
131 return (PermissionDef*)g_permissions;
132 }
133
HalGetPermissionPath(void)134 const char *HalGetPermissionPath(void)
135 {
136 return P_DIR;
137 }
138
HalGetMaxPermissionSize(void)139 int HalGetMaxPermissionSize(void)
140 {
141 return PERM_MAX;
142 }
143
HalMalloc(unsigned int size)144 void* HalMalloc(unsigned int size)
145 {
146 if (size == 0) {
147 return NULL;
148 }
149 return malloc(size);
150 }
151
HalFree(void * ptr)152 void HalFree(void *ptr)
153 {
154 if (ptr != NULL) {
155 free(ptr);
156 }
157 }
158
HalAccess(const char * pathname)159 int HalAccess(const char *pathname)
160 {
161 return access(pathname, F_OK);
162 }
163
HalMutexLock(void)164 void HalMutexLock(void)
165 {
166 pthread_mutex_lock(&g_mutex);
167 }
168
HalMutexUnlock(void)169 void HalMutexUnlock(void)
170 {
171 pthread_mutex_unlock(&g_mutex);
172 }
173
HalGetDevUdid(unsigned char * udid,int size)174 int HalGetDevUdid(unsigned char *udid, int size)
175 {
176 unsigned char tempUdid[UDID_ORI_BYTES] = {0};
177 int result = GenerateOriginalDevUdid(tempUdid, UDID_ORI_BYTES);
178 if (result != PERM_ERRORCODE_SUCCESS) {
179 return result;
180 }
181
182 for (int i = 0; i < UDID_ORI_BYTES; i++) {
183 if (sprintf_s(udid + HEX_LEN * i, UDID_FINAL_BYTES + 1 - HEX_LEN * i, "%02X", tempUdid[i]) < 0) {
184 return PERM_ERRORCODE_GENERATE_UDID_FAILED;
185 }
186 }
187 udid[UDID_FINAL_BYTES] = '\0';
188 return PERM_ERRORCODE_SUCCESS;
189 }
190
HalIsValidPath(const char * path)191 bool HalIsValidPath(const char *path)
192 {
193 if (path == NULL) {
194 return false;
195 }
196 char resolvedPath[PATH_MAX + 1] = {0x0};
197 if (strlen(path) > PATH_MAX || NULL == realpath(path, resolvedPath)) {
198 return false;
199 }
200 struct stat buf;
201 stat(path, &buf);
202 if (S_IFDIR & buf.st_mode) {
203 resolvedPath[strlen(resolvedPath)] = '/';
204 }
205
206 return (strncmp(resolvedPath, P_DIR, strlen(P_DIR)) == 0);
207 }
208