1 /*
2 * Copyright (c) 2023-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 "security_manager_addon.h"
17
18 #include <fcntl.h>
19 #include <fstream>
20 #include "cJSON.h"
21 #include "cjson_check.h"
22 #include "clipboard_policy.h"
23 #include "device_settings_proxy.h"
24 #include "edm_constants.h"
25 #include "edm_log.h"
26 #include "pixel_map_napi.h"
27
28 using namespace OHOS::EDM;
29
30 constexpr int64_t MAX_VALIDITY_PERIOD = 31536000000000; // 60 * 60 * 24 * 365 * 1000 * 1000
31 constexpr int32_t MAX_WATERMARK_IMAGE_SIZE = 512000; // 500 * 1024
32 static const std::string VALIDITY_PERIOD_OUT_OF_RANGE_ERROR = "validityPeriod out of range!";
33
Init(napi_env env,napi_value exports)34 napi_value SecurityManagerAddon::Init(napi_env env, napi_value exports)
35 {
36 napi_value nClipboardPolicy = nullptr;
37 NAPI_CALL(env, napi_create_object(env, &nClipboardPolicy));
38 CreateClipboardPolicyObject(env, nClipboardPolicy);
39 napi_property_descriptor property[] = {
40 DECLARE_NAPI_FUNCTION("getSecurityPatchTag", GetSecurityPatchTag),
41 DECLARE_NAPI_FUNCTION("getDeviceEncryptionStatus", GetDeviceEncryptionStatus),
42 DECLARE_NAPI_FUNCTION("setPasswordPolicy", SetPasswordPolicy),
43 DECLARE_NAPI_FUNCTION("getPasswordPolicy", GetPasswordPolicy),
44 DECLARE_NAPI_FUNCTION("getSecurityStatus", GetSecurityStatus),
45 DECLARE_NAPI_FUNCTION("installUserCertificate", InstallUserCertificate),
46 DECLARE_NAPI_FUNCTION("uninstallUserCertificate", UninstallUserCertificate),
47 DECLARE_NAPI_FUNCTION("getUserCertificates", GetUserCertificates),
48 DECLARE_NAPI_FUNCTION("setAppClipboardPolicy", SetAppClipboardPolicy),
49 DECLARE_NAPI_FUNCTION("getAppClipboardPolicy", GetAppClipboardPolicy),
50 DECLARE_NAPI_FUNCTION("setWatermarkImage", SetWatermarkImage),
51 DECLARE_NAPI_FUNCTION("cancelWatermarkImage", CancelWatermarkImage),
52 DECLARE_NAPI_PROPERTY("ClipboardPolicy", nClipboardPolicy),
53 };
54 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
55 return exports;
56 }
57
GetSecurityPatchTag(napi_env env,napi_callback_info info)58 napi_value SecurityManagerAddon::GetSecurityPatchTag(napi_env env, napi_callback_info info)
59 {
60 AddonMethodSign addonMethodSign;
61 addonMethodSign.name = "GetSecurityPatchTag";
62 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
63 addonMethodSign.methodAttribute = MethodAttribute::GET;
64 AdapterAddonData adapterAddonData{};
65 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
66 if (result == nullptr) {
67 return nullptr;
68 }
69 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
70 int32_t ret = securityManagerProxy->GetSecurityPatchTag(adapterAddonData.data, adapterAddonData.stringRet);
71 if (FAILED(ret)) {
72 napi_throw(env, CreateError(env, ret));
73 return nullptr;
74 }
75 napi_value securityPatchTag;
76 NAPI_CALL(env, napi_create_string_utf8(env, adapterAddonData.stringRet.c_str(),
77 adapterAddonData.stringRet.size(), &securityPatchTag));
78 return securityPatchTag;
79 }
80
GetDeviceEncryptionStatus(napi_env env,napi_callback_info info)81 napi_value SecurityManagerAddon::GetDeviceEncryptionStatus(napi_env env, napi_callback_info info)
82 {
83 AddonMethodSign addonMethodSign;
84 addonMethodSign.name = "GetDeviceEncryptionStatus";
85 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
86 addonMethodSign.methodAttribute = MethodAttribute::GET;
87 AdapterAddonData adapterAddonData{};
88 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
89 if (result == nullptr) {
90 return nullptr;
91 }
92 DeviceEncryptionStatus deviceEncryptionStatus;
93 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
94 int32_t ret = securityManagerProxy->GetDeviceEncryptionStatus(adapterAddonData.data, deviceEncryptionStatus);
95 if (FAILED(ret)) {
96 napi_throw(env, CreateError(env, ret));
97 return nullptr;
98 }
99 return ConvertDeviceEncryptionStatus(env, deviceEncryptionStatus);
100 }
101
ConvertDeviceEncryptionStatus(napi_env env,DeviceEncryptionStatus & deviceEncryptionStatus)102 napi_value SecurityManagerAddon::ConvertDeviceEncryptionStatus(napi_env env,
103 DeviceEncryptionStatus &deviceEncryptionStatus)
104 {
105 napi_value objDeviceEncryptionStatus = nullptr;
106 NAPI_CALL(env, napi_create_object(env, &objDeviceEncryptionStatus));
107 napi_value nIsEncrypted;
108 NAPI_CALL(env, napi_get_boolean(env, deviceEncryptionStatus.isEncrypted, &nIsEncrypted));
109 NAPI_CALL(env, napi_set_named_property(env, objDeviceEncryptionStatus, "isEncrypted", nIsEncrypted));
110 return objDeviceEncryptionStatus;
111 }
112
SetPasswordPolicy(napi_env env,napi_callback_info info)113 napi_value SecurityManagerAddon::SetPasswordPolicy(napi_env env, napi_callback_info info)
114 {
115 auto convertpasswordPolicy2Data = [](napi_env env, napi_value argv, MessageParcel &data,
116 const AddonMethodSign &methodSign) {
117 PasswordPolicy policy;
118 if (!JsObjectToString(env, argv, "complexityRegex", false, policy.complexityReg)) {
119 EDMLOGE("Parameter passwordPolicy error");
120 return false;
121 }
122 if (!JsObjectToLong(env, argv, "validityPeriod", false, policy.validityPeriod)) {
123 EDMLOGE("Parameter passwordPolicy error");
124 return false;
125 }
126 if (policy.validityPeriod > MAX_VALIDITY_PERIOD || policy.validityPeriod < 0) {
127 napi_throw(env, CreateError(env, EdmReturnErrCode::PARAM_ERROR, VALIDITY_PERIOD_OUT_OF_RANGE_ERROR));
128 return false;
129 }
130 if (!JsObjectToString(env, argv, "additionalDescription", false, policy.additionalDescription)) {
131 EDMLOGE("Parameter passwordPolicy error");
132 return false;
133 }
134 data.WriteString(policy.complexityReg);
135 data.WriteInt64(policy.validityPeriod);
136 data.WriteString(policy.additionalDescription);
137 return true;
138 };
139 AddonMethodSign addonMethodSign;
140 addonMethodSign.name = "SetPasswordPolicy";
141 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM};
142 addonMethodSign.argsConvert = {nullptr, convertpasswordPolicy2Data};
143 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
144 AdapterAddonData adapterAddonData{};
145 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
146 if (result == nullptr) {
147 return nullptr;
148 }
149 int32_t retCode = SecurityManagerProxy::GetSecurityManagerProxy()->SetPasswordPolicy(adapterAddonData.data);
150 if (FAILED(retCode)) {
151 napi_throw(env, CreateError(env, retCode));
152 }
153 return nullptr;
154 }
155
GetPasswordPolicy(napi_env env,napi_callback_info info)156 napi_value SecurityManagerAddon::GetPasswordPolicy(napi_env env, napi_callback_info info)
157 {
158 EDMLOGI("NAPI_GetPasswordPolicy called");
159 size_t argc = ARGS_SIZE_ONE;
160 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
161 napi_value thisArg = nullptr;
162 void* data = nullptr;
163 OHOS::AppExecFwk::ElementName elementName;
164 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
165
166 PasswordPolicy policy;
167 int32_t retCode = EdmReturnErrCode::SYSTEM_ABNORMALLY;
168 if (argc >= ARGS_SIZE_ONE) {
169 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "admin type error");
170 ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]),
171 "Parameter admin error");
172 retCode = SecurityManagerProxy::GetSecurityManagerProxy()->GetPasswordPolicy(elementName, policy);
173 } else {
174 retCode = SecurityManagerProxy::GetSecurityManagerProxy()->GetPasswordPolicy(policy);
175 }
176
177 if (FAILED(retCode)) {
178 napi_throw(env, CreateError(env, retCode));
179 return nullptr;
180 }
181 napi_value ret;
182 napi_value complexityReg;
183 napi_value validityPeriod;
184 napi_value additionalDescription;
185 NAPI_CALL(env, napi_create_object(env, &ret));
186 NAPI_CALL(env, napi_create_string_utf8(env, policy.complexityReg.c_str(), NAPI_AUTO_LENGTH, &complexityReg));
187 NAPI_CALL(env, napi_create_int64(env, policy.validityPeriod, &validityPeriod));
188 NAPI_CALL(env,
189 napi_create_string_utf8(env, policy.additionalDescription.c_str(), NAPI_AUTO_LENGTH, &additionalDescription));
190 NAPI_CALL(env, napi_set_named_property(env, ret, "complexityRegex", complexityReg));
191 NAPI_CALL(env, napi_set_named_property(env, ret, "validityPeriod", validityPeriod));
192 NAPI_CALL(env, napi_set_named_property(env, ret, "additionalDescription", additionalDescription));
193 return ret;
194 }
195
GetSecurityStatus(napi_env env,napi_callback_info info)196 napi_value SecurityManagerAddon::GetSecurityStatus(napi_env env, napi_callback_info info)
197 {
198 EDMLOGI("NAPI_GetSecurityStatus called");
199 size_t argc = ARGS_SIZE_TWO;
200 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
201 napi_value thisArg = nullptr;
202 void* data = nullptr;
203 OHOS::AppExecFwk::ElementName elementName;
204 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
205 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "parameter count error");
206 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "parameter type error");
207 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ONE], napi_string),
208 "The second parameter must be string.");
209 bool boolret = ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]);
210 ASSERT_AND_THROW_PARAM_ERROR(env, boolret, "element name param error");
211 EDMLOGD(
212 "EnableAdmin: elementName.bundlename %{public}s, "
213 "elementName.abilityname:%{public}s",
214 elementName.GetBundleName().c_str(),
215 elementName.GetAbilityName().c_str());
216 std::string item;
217 boolret = ParseString(env, item, argv[ARR_INDEX_ONE]);
218 ASSERT_AND_THROW_PARAM_ERROR(env, boolret, "param 'item' parse error");
219 std::string stringRet;
220 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
221 int32_t ret = ERR_OK;
222 if (item == EdmConstants::SecurityManager::PATCH) {
223 ret = securityManagerProxy->GetSecurityPatchTag(elementName, stringRet);
224 } else if (item == EdmConstants::SecurityManager::ENCRYPTION) {
225 DeviceEncryptionStatus deviceEncryptionStatus;
226 ret = securityManagerProxy->GetDeviceEncryptionStatus(elementName, deviceEncryptionStatus);
227 if (SUCCEEDED(ret)) {
228 ret = ConvertDeviceEncryptionToJson(env, deviceEncryptionStatus, stringRet);
229 }
230 } else if (item == EdmConstants::SecurityManager::ROOT) {
231 ret = securityManagerProxy->GetRootCheckStatus(elementName, stringRet);
232 } else {
233 ret = EdmReturnErrCode::INTERFACE_UNSUPPORTED;
234 }
235 if (FAILED(ret)) {
236 napi_throw(env, CreateError(env, ret));
237 return nullptr;
238 }
239 napi_value status;
240 NAPI_CALL(env, napi_create_string_utf8(env, stringRet.c_str(), stringRet.size(), &status));
241 return status;
242 }
243
ConvertDeviceEncryptionToJson(napi_env env,DeviceEncryptionStatus & deviceEncryptionStatus,std::string & stringRet)244 int32_t SecurityManagerAddon::ConvertDeviceEncryptionToJson(napi_env env,
245 DeviceEncryptionStatus &deviceEncryptionStatus, std::string &stringRet)
246 {
247 cJSON *json = nullptr;
248 CJSON_CREATE_OBJECT_AND_CHECK(json, EdmReturnErrCode::SYSTEM_ABNORMALLY);
249 cJSON_AddBoolToObject(json, "isEncrypted", deviceEncryptionStatus.isEncrypted);
250 char *jsonStr = cJSON_PrintUnformatted(json);
251 if (jsonStr == nullptr) {
252 cJSON_Delete(json);
253 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
254 }
255 stringRet = std::string(jsonStr);
256 cJSON_Delete(json);
257 cJSON_free(jsonStr);
258 return ERR_OK;
259 }
260
InstallUserCertificateSync(napi_env env,napi_value argv,AsyncCertCallbackInfo * asyncCallbackInfo)261 napi_value SecurityManagerAddon::InstallUserCertificateSync(napi_env env, napi_value argv,
262 AsyncCertCallbackInfo *asyncCallbackInfo)
263 {
264 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv, napi_number),
265 "accountId type error");
266 ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->certblobCA.accountId,
267 argv), "Parameter accountId error");
268 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
269 int32_t ret = securityManagerProxy->InstallUserCertificate(asyncCallbackInfo->elementName,
270 asyncCallbackInfo->certblobCA, asyncCallbackInfo->stringRet,
271 asyncCallbackInfo->innerCodeMsg);
272 if (FAILED(ret)) {
273 if (asyncCallbackInfo->innerCodeMsg.empty()) {
274 napi_throw(env, CreateError(env, ret));
275 } else {
276 napi_throw(env, CreateError(env, ret, asyncCallbackInfo->innerCodeMsg));
277 }
278 return nullptr;
279 }
280 napi_value status;
281 NAPI_CALL(env, napi_create_string_utf8(env, asyncCallbackInfo->stringRet.c_str(),
282 asyncCallbackInfo->stringRet.size(), &status));
283 return status;
284 }
285
InstallUserCertificate(napi_env env,napi_callback_info info)286 napi_value SecurityManagerAddon::InstallUserCertificate(napi_env env, napi_callback_info info)
287 {
288 EDMLOGI("NAPI_InstallUserCertificate called");
289 size_t argc = ARGS_SIZE_FOUR;
290 napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
291 napi_value thisArg = nullptr;
292 void *data = nullptr;
293 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
294 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "parameter count error");
295 bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object);
296 ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter want error");
297 matchFlag = MatchValueType(env, argv[ARR_INDEX_ONE], napi_object);
298 ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter certblob error");
299 auto asyncCallbackInfo = new (std::nothrow) AsyncCertCallbackInfo();
300 if (asyncCallbackInfo == nullptr) {
301 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
302 return nullptr;
303 }
304 std::unique_ptr<AsyncCertCallbackInfo> callbackPtr{asyncCallbackInfo};
305 bool retAdmin = ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]);
306 ASSERT_AND_THROW_PARAM_ERROR(env, retAdmin, "element name param error");
307 bool retCertBlob = ParseCertBlob(env, argv[ARR_INDEX_ONE], asyncCallbackInfo);
308 ASSERT_AND_THROW_PARAM_ERROR(env, retCertBlob, "element cert blob error");
309 if (argc > ARGS_SIZE_TWO) {
310 return InstallUserCertificateSync(env, argv[ARR_INDEX_TWO], asyncCallbackInfo);
311 }
312 napi_value asyncWorkReturn = HandleAsyncWork(env, asyncCallbackInfo, "InstallUserCertificate",
313 NativeInstallUserCertificate, NativeStringCallbackComplete);
314 callbackPtr.release();
315 return asyncWorkReturn;
316 }
317
NativeInstallUserCertificate(napi_env env,void * data)318 void SecurityManagerAddon::NativeInstallUserCertificate(napi_env env, void *data)
319 {
320 EDMLOGI("NAPI_NativeInstallUserCertificate called");
321 if (data == nullptr) {
322 EDMLOGE("data is nullptr");
323 return;
324 }
325 AsyncCertCallbackInfo *asyncCallbackInfo = static_cast<AsyncCertCallbackInfo *>(data);
326 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
327 asyncCallbackInfo->ret = securityManagerProxy->InstallUserCertificate(asyncCallbackInfo->elementName,
328 asyncCallbackInfo->certblobCA, asyncCallbackInfo->stringRet, asyncCallbackInfo->innerCodeMsg);
329 }
330
UninstallUserCertificate(napi_env env,napi_callback_info info)331 napi_value SecurityManagerAddon::UninstallUserCertificate(napi_env env, napi_callback_info info)
332 {
333 auto convertCertBlob2Data = [](napi_env env, napi_value argv, MessageParcel &data,
334 const AddonMethodSign &methodSign) {
335 std::string alias;
336 if (!ParseString(env, alias, argv)) {
337 EDMLOGE("element alias error");
338 return false;
339 }
340 data.WriteString(alias);
341 return true;
342 };
343 AddonMethodSign addonMethodSign;
344 addonMethodSign.name = "UninstallUserCertificate";
345 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM};
346 addonMethodSign.argsConvert = {nullptr, convertCertBlob2Data};
347 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
348 return AddonMethodAdapter(env, info, addonMethodSign, NativeUninstallUserCertificate, NativeVoidCallbackComplete);
349 }
350
NativeUninstallUserCertificate(napi_env env,void * data)351 void SecurityManagerAddon::NativeUninstallUserCertificate(napi_env env, void *data)
352 {
353 EDMLOGI("NAPI_NativeUninstallUserCertificate called");
354 if (data == nullptr) {
355 EDMLOGE("data is nullptr");
356 return;
357 }
358 AdapterAddonData *asyncCallbackInfo = static_cast<AdapterAddonData *>(data);
359 asyncCallbackInfo->ret = DeviceSettingsProxy::GetDeviceSettingsProxy()->UninstallUserCertificate(
360 asyncCallbackInfo->data, asyncCallbackInfo->innerCodeMsg);
361 }
362
GetUserCertificates(napi_env env,napi_callback_info info)363 napi_value SecurityManagerAddon::GetUserCertificates(napi_env env, napi_callback_info info)
364 {
365 EDMLOGI("NAPI_GetUserCertificates called");
366 AddonMethodSign addonMethodSign;
367 addonMethodSign.name = "GetUserCertificates";
368 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::INT32};
369 addonMethodSign.methodAttribute = MethodAttribute::GET;
370 AdapterAddonData adapterAddonData{};
371 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
372 if (result == nullptr) {
373 return nullptr;
374 }
375 std::vector<std::string> uriList;
376 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
377 int32_t ret = securityManagerProxy->GetUserCertificates(adapterAddonData.data, uriList);
378 if (FAILED(ret)) {
379 napi_throw(env, CreateError(env, ret));
380 return nullptr;
381 }
382 napi_value jsUriList = nullptr;
383 NAPI_CALL(env, napi_create_array(env, &jsUriList));
384 ConvertStringVectorToJS(env, uriList, jsUriList);
385 return jsUriList;
386 }
387
ParseCertBlob(napi_env env,napi_value object,AsyncCertCallbackInfo * asyncCertCallbackInfo)388 bool SecurityManagerAddon::ParseCertBlob(napi_env env, napi_value object, AsyncCertCallbackInfo *asyncCertCallbackInfo)
389 {
390 napi_valuetype type = napi_undefined;
391 NAPI_CALL_BASE(env, napi_typeof(env, object, &type), false);
392 if (type != napi_object) {
393 EDMLOGE("type of param certblob is not object");
394 return false;
395 }
396 if (!JsObjectToU8Vector(env, object, "inData", asyncCertCallbackInfo->certblobCA.certArray)) {
397 EDMLOGE("uint8Array to vector failed");
398 return false;
399 }
400 return JsObjectToString(env, object, "alias", true, asyncCertCallbackInfo->certblobCA.alias);
401 }
402
SetAppClipboardPolicy(napi_env env,napi_callback_info info)403 napi_value SecurityManagerAddon::SetAppClipboardPolicy(napi_env env, napi_callback_info info)
404 {
405 EDMLOGI("NAPI_SetAppClipboardPolicy called");
406 size_t argc = ARGS_SIZE_FOUR;
407 napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
408 napi_value thisArg = nullptr;
409 void *data = nullptr;
410 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
411 AddonMethodSign addonMethodSign;
412 if (argc == ARGS_SIZE_THREE) {
413 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::INT32, EdmAddonCommonType::INT32};
414 EDMLOGI(" SetAppClipboardPolicy argc == ARGS_SIZE_THREE");
415 SetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::SET_HAS_TOKEN_ID);
416 } else if (argc > ARGS_SIZE_THREE) {
417 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::STRING,
418 EdmAddonCommonType::INT32, EdmAddonCommonType::INT32};
419 EDMLOGI(" SetAppClipboardPolicy argc > ARGS_SIZE_THREE");
420 SetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::SET_HAS_BUNDLE_NAME);
421 } else {
422 EDMLOGI(" argc < ARGS_SIZE_THREE Parameter error");
423 napi_throw(env, CreateError(env, EdmReturnErrCode::PARAM_ERROR, "Parameter error"));
424 return nullptr;
425 }
426 addonMethodSign.name = "SetAppClipboardPolicy";
427 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
428 AdapterAddonData adapterAddonData{};
429 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
430 if (result == nullptr) {
431 return nullptr;
432 }
433 int32_t retCode =
434 SecurityManagerProxy::GetSecurityManagerProxy()->SetAppClipboardPolicy(adapterAddonData.data);
435 if (FAILED(retCode)) {
436 napi_throw(env, CreateError(env, retCode));
437 }
438 return nullptr;
439 }
440
SetClipboardPolicyParamHandle(AddonMethodSign & addonMethodSign,int flag)441 void SecurityManagerAddon::SetClipboardPolicyParamHandle(AddonMethodSign &addonMethodSign, int flag)
442 {
443 if (flag == ClipboardFunctionType::SET_HAS_TOKEN_ID) {
444 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
445 const AddonMethodSign &methodSign) {
446 int32_t tokenId;
447 if (!ParseInt(env, tokenId, argv)) {
448 EDMLOGE("element tokenId error");
449 return false;
450 }
451 data.WriteInt32(ClipboardFunctionType::SET_HAS_TOKEN_ID);
452 data.WriteInt32(tokenId);
453 return true;
454 };
455 addonMethodSign.argsConvert = {nullptr, convertData, nullptr};
456 }
457 if (flag == ClipboardFunctionType::SET_HAS_BUNDLE_NAME) {
458 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
459 const AddonMethodSign &methodSign) {
460 std::string bundleName;
461 if (!ParseString(env, bundleName, argv)) {
462 EDMLOGE("Parameter bundleName error");
463 return false;
464 }
465 data.WriteInt32(ClipboardFunctionType::SET_HAS_BUNDLE_NAME);
466 data.WriteString(bundleName);
467 return true;
468 };
469 addonMethodSign.argsConvert = {nullptr, convertData, nullptr, nullptr};
470 }
471 }
472
GetClipboardPolicyParamHandle(AddonMethodSign & addonMethodSign,int flag)473 void SecurityManagerAddon::GetClipboardPolicyParamHandle(AddonMethodSign &addonMethodSign, int flag)
474 {
475 if (flag == ClipboardFunctionType::GET_HAS_TOKEN_ID) {
476 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
477 const AddonMethodSign &methodSign) {
478 int32_t tokenId;
479 if (!ParseInt(env, tokenId, argv)) {
480 EDMLOGE("element tokenId error");
481 return false;
482 }
483 data.WriteInt32(ClipboardFunctionType::GET_HAS_TOKEN_ID);
484 data.WriteInt32(tokenId);
485 return true;
486 };
487 addonMethodSign.argsConvert = {nullptr, convertData};
488 }
489 if (flag == ClipboardFunctionType::GET_HAS_BUNDLE_NAME) {
490 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
491 const AddonMethodSign &methodSign) {
492 std::string bundleName;
493 if (!ParseString(env, bundleName, argv)) {
494 EDMLOGE("Parameter bundleName error");
495 return false;
496 }
497 data.WriteInt32(ClipboardFunctionType::GET_HAS_BUNDLE_NAME);
498 data.WriteString(bundleName);
499 return true;
500 };
501 addonMethodSign.argsConvert = {nullptr, convertData, nullptr};
502 }
503 if (flag == ClipboardFunctionType::GET_NO_TOKEN_ID) {
504 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
505 const AddonMethodSign &methodSign) {
506 OHOS::AppExecFwk::ElementName elementName;
507 if (!ParseElementName(env, elementName, argv)) {
508 EDMLOGE("Parameter admin error");
509 return false;
510 }
511 data.WriteString(methodSign.apiVersionTag);
512 data.WriteInt32(HAS_ADMIN);
513 data.WriteParcelable(&elementName);
514 data.WriteInt32(ClipboardFunctionType::GET_NO_TOKEN_ID);
515 return true;
516 };
517 addonMethodSign.argsConvert = {convertData};
518 }
519 }
520
GetAppClipboardPolicy(napi_env env,napi_callback_info info)521 napi_value SecurityManagerAddon::GetAppClipboardPolicy(napi_env env, napi_callback_info info)
522 {
523 size_t argc = ARGS_SIZE_THREE;
524 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
525 napi_value thisArg = nullptr;
526 void *data = nullptr;
527 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
528 AddonMethodSign addonMethodSign;
529 if (argc == ARGS_SIZE_ONE) {
530 EDMLOGI(" GetAppClipboardPolicy argc == ARGS_SIZE_ONE");
531 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
532 GetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::GET_NO_TOKEN_ID);
533 } else if (argc == ARGS_SIZE_TWO) {
534 EDMLOGI(" GetAppClipboardPolicy argc == ARGS_SIZE_TWO");
535 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::INT32};
536 GetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::GET_HAS_TOKEN_ID);
537 } else if (argc >= ARGS_SIZE_THREE) {
538 EDMLOGI(" GetAppClipboardPolicy argc >= ARGS_SIZE_THREE");
539 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::STRING, EdmAddonCommonType::INT32};
540 GetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::GET_HAS_BUNDLE_NAME);
541 } else {
542 EDMLOGI(" argc < ARGS_SIZE_ONE Parameter error");
543 napi_throw(env, CreateError(env, EdmReturnErrCode::PARAM_ERROR, "Parameter error"));
544 return nullptr;
545 }
546 addonMethodSign.name = "GetAppClipboardPolicy";
547 addonMethodSign.methodAttribute = MethodAttribute::GET;
548 AdapterAddonData adapterAddonData{};
549 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
550 if (result == nullptr) {
551 return nullptr;
552 }
553 std::string policy;
554 int32_t retCode =
555 SecurityManagerProxy::GetSecurityManagerProxy()->GetAppClipboardPolicy(adapterAddonData.data, policy);
556 if (FAILED(retCode)) {
557 napi_throw(env, CreateError(env, retCode));
558 return nullptr;
559 }
560 napi_value clipboardPolicy;
561 NAPI_CALL(env, napi_create_string_utf8(env, policy.c_str(), NAPI_AUTO_LENGTH, &clipboardPolicy));
562 return clipboardPolicy;
563 }
564
CreateClipboardPolicyObject(napi_env env,napi_value value)565 void SecurityManagerAddon::CreateClipboardPolicyObject(napi_env env, napi_value value)
566 {
567 napi_value nDefault;
568 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ClipboardPolicy::DEFAULT), &nDefault));
569 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "DEFAULT", nDefault));
570 napi_value nInApp;
571 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ClipboardPolicy::IN_APP), &nInApp));
572 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "IN_APP", nInApp));
573 napi_value nLocalDevice;
574 NAPI_CALL_RETURN_VOID(env,
575 napi_create_int32(env, static_cast<int32_t>(ClipboardPolicy::LOCAL_DEVICE), &nLocalDevice));
576 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "LOCAL_DEVICE", nLocalDevice));
577 napi_value nCrossDevice;
578 NAPI_CALL_RETURN_VOID(env,
579 napi_create_int32(env, static_cast<int32_t>(ClipboardPolicy::CROSS_DEVICE), &nCrossDevice));
580 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "CROSS_DEVICE", nCrossDevice));
581 }
582
SetWatermarkImage(napi_env env,napi_callback_info info)583 napi_value SecurityManagerAddon::SetWatermarkImage(napi_env env, napi_callback_info info)
584 {
585 EDMLOGI("NAPI_SetWatermarkImage called");
586 size_t argc = ARGS_SIZE_FOUR;
587 napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
588 napi_value thisArg = nullptr;
589 void *data = nullptr;
590 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
591 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_FOUR, "parameter count error");
592 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "admin type error");
593
594 OHOS::AppExecFwk::ElementName elementName;
595 ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]),
596 "Parameter admin error");
597 std::shared_ptr<WatermarkParam> paramPtr = nullptr;
598 napi_value ret = CheckBuildWatermarkParam(env, argv, paramPtr);
599 if (ret == nullptr) {
600 return nullptr;
601 }
602 int32_t retCode = -1;
603 NAPI_CALL(env, napi_get_value_int32(env, ret, &retCode));
604 if (FAILED(retCode)) {
605 return nullptr;
606 }
607 retCode = SecurityManagerProxy::GetSecurityManagerProxy()->SetWatermarkImage(elementName, paramPtr);
608 if (FAILED(retCode)) {
609 napi_throw(env, CreateError(env, retCode));
610 }
611 return nullptr;
612 }
613
CancelWatermarkImage(napi_env env,napi_callback_info info)614 napi_value SecurityManagerAddon::CancelWatermarkImage(napi_env env, napi_callback_info info)
615 {
616 AddonMethodSign addonMethodSign;
617 addonMethodSign.name = "CancelWatermarkImage";
618 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::STRING, EdmAddonCommonType::INT32};
619 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
620 AdapterAddonData adapterAddonData{};
621 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
622 if (result == nullptr) {
623 return nullptr;
624 }
625 int32_t retCode =
626 SecurityManagerProxy::GetSecurityManagerProxy()->CancelWatermarkImage(adapterAddonData.data);
627 if (FAILED(retCode)) {
628 napi_throw(env, CreateError(env, retCode));
629 }
630 return nullptr;
631 }
632
Decode(const std::string url)633 std::shared_ptr<OHOS::Media::PixelMap> SecurityManagerAddon::Decode(const std::string url)
634 {
635 char canonicalPath[PATH_MAX + 1] = { 0 };
636 if (url.size() > PATH_MAX || realpath(url.c_str(), canonicalPath) == nullptr) {
637 EDMLOGE("realpath error");
638 return nullptr;
639 }
640 int fd = open(canonicalPath, O_RDONLY);
641 if (fd == -1) {
642 EDMLOGE("Decode Open file fail!");
643 return nullptr;
644 }
645 uint32_t ret = ERR_INVALID_VALUE;
646 std::shared_ptr<int> fdPtr(&fd, [](int *fd) {
647 close(*fd);
648 *fd = -1;
649 });
650 Media::SourceOptions sourceOption;
651 auto imageSourcePtr = Media::ImageSource::CreateImageSource(*fdPtr, sourceOption, ret);
652 if (ret != ERR_OK || imageSourcePtr == nullptr) {
653 EDMLOGE("CreateImageSource error");
654 return nullptr;
655 }
656 Media::DecodeOptions option;
657 auto pixelMapPtr = imageSourcePtr->CreatePixelMap(option, ret);
658 if (ret != ERR_OK) {
659 EDMLOGE("CreatePixelMap error");
660 return nullptr;
661 }
662 return std::shared_ptr<Media::PixelMap>(std::move(pixelMapPtr));
663 }
664
GetPixelMapData(std::shared_ptr<Media::PixelMap> pixelMap,std::shared_ptr<WatermarkParam> param)665 bool SecurityManagerAddon::GetPixelMapData(std::shared_ptr<Media::PixelMap> pixelMap,
666 std::shared_ptr<WatermarkParam> param)
667 {
668 param->size = pixelMap->GetByteCount();
669 if (param->size <= 0) {
670 EDMLOGE("GetPixelMapData size %{public}d", param->size);
671 return false;
672 }
673 void* data = malloc(param->size);
674 if (data == nullptr) {
675 EDMLOGE("GetPixelMapData malloc fail");
676 return false;
677 }
678 uint32_t ret = pixelMap->ReadPixels(param->size, reinterpret_cast<uint8_t*>(data));
679 param->SetPixels(data);
680 if (ret != ERR_OK) {
681 EDMLOGE("GetPixelMapData ReadPixels fail!");
682 return false;
683 }
684 param->width = pixelMap->GetWidth();
685 param->height = pixelMap->GetHeight();
686 return true;
687 }
688
CheckBuildWatermarkParam(napi_env env,napi_value * argv,std::shared_ptr<WatermarkParam> & paramPtr)689 napi_value SecurityManagerAddon::CheckBuildWatermarkParam(napi_env env, napi_value* argv,
690 std::shared_ptr<WatermarkParam> ¶mPtr)
691 {
692 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ONE], napi_string), "bundleName type error");
693 napi_valuetype imageValueType = napi_undefined;
694 NAPI_CALL(env, napi_typeof(env, argv[ARR_INDEX_TWO], &imageValueType));
695 ASSERT_AND_THROW_PARAM_ERROR(env, imageValueType == napi_object || imageValueType == napi_string,
696 "image type error");
697 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_THREE], napi_number),
698 "accountId type error");
699 auto param = new (std::nothrow) WatermarkParam();
700 if (param == nullptr) {
701 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
702 return nullptr;
703 }
704 paramPtr = std::shared_ptr<WatermarkParam>(param, [](WatermarkParam *param) {
705 param->CheckAndFreePixels();
706 delete param;
707 });
708 std::shared_ptr<Media::PixelMap> pixelMap;
709
710 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, paramPtr->bundleName, argv[ARR_INDEX_ONE]),
711 "Parameter bundleName error");
712 if (imageValueType == napi_object) {
713 pixelMap = Media::PixelMapNapi::GetPixelMap(env, argv[ARR_INDEX_TWO]);
714 } else {
715 std::string url;
716 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, url, argv[ARR_INDEX_TWO]),
717 "Parameter pixelMap error");
718 pixelMap = Decode(url);
719 }
720 ASSERT_AND_THROW_PARAM_ERROR(env, pixelMap != nullptr &&
721 pixelMap->GetByteCount() <= MAX_WATERMARK_IMAGE_SIZE, "Parameter pixelMap error");
722 ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, paramPtr->accountId, argv[ARR_INDEX_THREE]),
723 "Parameter accountId error");
724 if (!GetPixelMapData(pixelMap, paramPtr)) {
725 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
726 return nullptr;
727 }
728 napi_value ret;
729 NAPI_CALL(env, napi_create_int32(env, ERR_OK, &ret));
730 return ret;
731 }
732
733 static napi_module g_securityModule = {
734 .nm_version = 1,
735 .nm_flags = 0,
736 .nm_filename = nullptr,
737 .nm_register_func = SecurityManagerAddon::Init,
738 .nm_modname = "enterprise.securityManager",
739 .nm_priv = ((void *)0),
740 .reserved = {0},
741 };
742
SecurityManagerRegister()743 extern "C" __attribute__((constructor)) void SecurityManagerRegister()
744 {
745 napi_module_register(&g_securityModule);
746 }
747