• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &paramPtr)
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