• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <dlfcn.h>
17 #include <string.h>
18 #include <unistd.h>
19 
20 #include "appspawn_server.h"
21 #include "appspawn_silk.h"
22 #include "appspawn_utils.h"
23 #include "config_policy_utils.h"
24 #include "cJSON.h"
25 #include "json_utils.h"
26 #include "securec.h"
27 
28 #define SILK_JSON_CONFIG_PATH   "/vendor/etc/silk/silk.json"
29 #define SILK_JSON_ENABLE_ITEM   "enabled_app_list"
30 #define SILK_JSON_LIBRARY_PATH  "libsilk.so.0.1"
31 
32 #define SILK_JSON_MAX 128
33 #define SILK_JSON_NAME_MAX 256
34 
35 APPSPAWN_STATIC struct SilkConfig g_silkConfig = {0};
36 
FreeSilkConfigItems(void)37 static void FreeSilkConfigItems(void)
38 {
39     for (int i = 0; i < g_silkConfig.configCursor; i++) {
40         if (g_silkConfig.configItems[i] != NULL) {
41             free(g_silkConfig.configItems[i]);
42             g_silkConfig.configItems[i] = NULL;
43         }
44     }
45 }
46 
FreeSilkConfig(void)47 static void FreeSilkConfig(void)
48 {
49     free(g_silkConfig.configItems);
50     g_silkConfig.configItems = NULL;
51     g_silkConfig.configCursor = 0;
52 }
53 
FreeAllSilkConfig(void)54 static void FreeAllSilkConfig(void)
55 {
56     FreeSilkConfigItems();
57     FreeSilkConfig();
58 }
59 
ParseSilkConfig(const cJSON * root,struct SilkConfig * config)60 APPSPAWN_STATIC bool ParseSilkConfig(const cJSON *root, struct SilkConfig *config)
61 {
62     bool isSuccess = false;
63     cJSON *silkJson = cJSON_GetObjectItemCaseSensitive(root, SILK_JSON_ENABLE_ITEM);
64     if (silkJson == NULL) {
65         return isSuccess;
66     }
67 
68     uint32_t configCount = (uint32_t)cJSON_GetArraySize(silkJson);
69     APPSPAWN_CHECK(configCount <= SILK_JSON_MAX, configCount = SILK_JSON_MAX,
70                    "config count %{public}u is larger than %{public}d", configCount, SILK_JSON_MAX);
71     config->configItems = (char **)malloc(configCount * sizeof(char *));
72     APPSPAWN_CHECK(config->configItems != NULL, return isSuccess, "Alloc for silk config items failed");
73     int ret = memset_s(config->configItems, configCount * sizeof(char *), 0, configCount * sizeof(char *));
74     APPSPAWN_CHECK(ret == 0, free(config->configItems);
75                    config->configItems = NULL; return isSuccess,
76                    "Memset silk config items failed");
77 
78     for (uint32_t i = 0; i < configCount; ++i) {
79         const char *appName = cJSON_GetStringValue(cJSON_GetArrayItem(silkJson, i));
80         APPSPAWN_CHECK(appName != NULL, break, "appName is NULL");
81         APPSPAWN_LOGI("Enable silk appName %{public}s", appName);
82 
83         int len = strlen(appName) + 1;
84         APPSPAWN_CHECK(len <= SILK_JSON_NAME_MAX, continue,
85                        "appName %{public}s is larger than the maximum limit", appName);
86         char **item = &config->configItems[config->configCursor];
87         *item = (char *)malloc(len * sizeof(char));
88         APPSPAWN_CHECK(*item != NULL, break, "Alloc for config item failed");
89 
90         ret = memset_s(*item, len * sizeof(char), 0, len * sizeof(char));
91         APPSPAWN_CHECK(ret == 0, free(*item);
92                        *item = NULL; break,
93                        "Memset config item %{public}s failed", appName);
94 
95         ret = strncpy_s(*item, len, appName, len - 1);
96         APPSPAWN_CHECK(ret == 0, free(*item);
97                        *item = NULL; break,
98                        "Copy config item %{public}s failed", appName);
99         config->configCursor++;
100         if (i == configCount -1) {
101             isSuccess = true;
102         }
103     }
104     if (!isSuccess) {
105         FreeAllSilkConfig();
106     }
107     return isSuccess;
108 }
109 
LoadSilkConfig(void)110 void LoadSilkConfig(void)
111 {
112     cJSON *root = GetJsonObjFromFile(SILK_JSON_CONFIG_PATH);
113     APPSPAWN_CHECK(root != NULL, return, "Failed to load silk config");
114     (void)ParseSilkConfig(root, &g_silkConfig);
115     cJSON_Delete(root);
116 }
117 
LoadSilkLibrary(const char * packageName)118 bool LoadSilkLibrary(const char *packageName)
119 {
120     bool isSuccess = false;
121     APPSPAWN_CHECK_LOGV(g_silkConfig.configItems != NULL, return isSuccess,
122                    "ConfigItems is NULL");
123     APPSPAWN_CHECK_LOGV(packageName != NULL, FreeAllSilkConfig(); return isSuccess,
124                    "PackageName is NULL");
125     char **appName = NULL;
126     void *handle = NULL;
127     for (int i = 0; i < g_silkConfig.configCursor; i++) {
128         appName = &g_silkConfig.configItems[i];
129         if (*appName == NULL) {
130             break;
131         }
132         if (handle == NULL && strcmp(*appName, packageName) == 0) {
133             handle = dlopen(SILK_JSON_LIBRARY_PATH, RTLD_NOW);
134             if (handle != NULL) {
135                 isSuccess = true;
136             }
137             APPSPAWN_LOGI("Enable Silk AppName %{public}s result:%{public}s",
138                 *appName, handle ? "success" : "failed");
139         }
140         free(*appName);
141         *appName = NULL;
142     }
143     FreeSilkConfig();
144     return isSuccess;
145 }