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 #define MLOG_TAG "Distributed"
16 
17 #include "device_permission_verification.h"
18 #include "device_auth.h"
19 #include "media_log.h"
20 #include "medialibrary_db_const.h"
21 #include "medialibrary_device.h"
22 #include "medialibrary_errno.h"
23 #include "nlohmann/json.hpp"
24 #include "parameter.h"
25 #include "parameters.h"
26 
27 namespace OHOS {
28 namespace Media {
29 using namespace std;
30 const std::string SAME_ACCOUNT_MARK = "const.distributed_file_only_for_same_account_test";
31 
CheckPermission(const std::string & udid)32 bool DevicePermissionVerification::CheckPermission(const std::string &udid)
33 {
34     if (!CheckIsSameAccount()) {
35         return false;
36     }
37     QueryTrustedRelationship(udid);
38     return ReqDestDevSecLevel(udid);
39 }
40 
from_json(const nlohmann::json & jsonObject,TrustedRelationshipGroupInfo & groupInfo)41 void from_json(const nlohmann::json &jsonObject, TrustedRelationshipGroupInfo &groupInfo)
42 {
43     if (jsonObject.find(FIELD_GROUP_NAME) != jsonObject.end()) {
44         groupInfo.groupName = jsonObject.at(FIELD_GROUP_NAME).get<std::string>();
45     }
46 
47     if (jsonObject.find(FIELD_GROUP_ID) != jsonObject.end()) {
48         groupInfo.groupId = jsonObject.at(FIELD_GROUP_ID).get<std::string>();
49     }
50 
51     if (jsonObject.find(FIELD_GROUP_OWNER) != jsonObject.end()) {
52         groupInfo.groupOwner = jsonObject.at(FIELD_GROUP_OWNER).get<std::string>();
53     }
54 
55     if (jsonObject.find(FIELD_GROUP_TYPE) != jsonObject.end()) {
56         groupInfo.groupType = jsonObject.at(FIELD_GROUP_TYPE).get<int32_t>();
57     }
58 }
59 
QueryTrustedRelationship(const std::string & udid)60 bool DevicePermissionVerification::QueryTrustedRelationship(const std::string &udid)
61 {
62     int ret = InitDeviceAuthService();
63     if (ret != 0) {
64         MEDIA_ERR_LOG("InitDeviceAuthService failed, ret %{public}d", ret);
65         return false;
66     }
67 
68     auto hichainDevGroupMgr_ = GetGmInstance();
69     if (hichainDevGroupMgr_ == nullptr) {
70         MEDIA_ERR_LOG("failed to get hichain device group manager");
71         return false;
72     }
73 
74     char *returnGroupVec = nullptr;
75     uint32_t groupNum = 0;
76     ret = hichainDevGroupMgr_->getRelatedGroups(ANY_OS_ACCOUNT, BUNDLE_NAME.c_str(), udid.c_str(),
77         &returnGroupVec, &groupNum);
78     if (ret != 0 || returnGroupVec == nullptr) {
79         MEDIA_ERR_LOG("failed to get related groups, ret %{public}d", ret);
80         return false;
81     }
82 
83     if (groupNum == 0) {
84         MEDIA_ERR_LOG("failed to get related groups, groupNum is %{public}u", groupNum);
85         return false;
86     }
87 
88     std::string groups = std::string(returnGroupVec);
89     nlohmann::json jsonObject = nlohmann::json::parse(groups); // transform from cjson to cppjson
90     if (jsonObject.is_discarded()) {
91         MEDIA_INFO_LOG("returnGroupVec parse failed");
92         return false;
93     }
94 
95     std::vector<TrustedRelationshipGroupInfo> groupList;
96     groupList = jsonObject.get<std::vector<TrustedRelationshipGroupInfo>>();
97     for (auto &a : groupList) {
98         MEDIA_INFO_LOG("group info:[groupName] %{private}s, [groupId] %{private}s, [groupType] %{private}d,",
99                        a.groupName.c_str(), a.groupId.c_str(), a.groupType);
100         if (a.groupType == PEER_TO_PEER_GROUP || a.groupType == ACROSS_ACCOUNT_AUTHORIZE_GROUP) {
101             return true;
102         }
103     }
104 
105     return false;
106 }
107 
CheckIsSameAccount()108 bool DevicePermissionVerification::CheckIsSameAccount()
109 {
110     // because of there no same_account, only for test, del later
111     bool ret = system::GetBoolParameter(SAME_ACCOUNT_MARK, false);
112     MEDIA_INFO_LOG("SAME_ACCOUNT_MARK val is %{public}d", ret);
113     return ret;
114 }
115 
MLDevSecInfoCb(const DeviceIdentify * identify,struct DeviceSecurityInfo * info)116 void DevicePermissionVerification::MLDevSecInfoCb(const DeviceIdentify *identify, struct DeviceSecurityInfo *info)
117 {
118     int32_t level = 0;
119     int32_t ret = GetDeviceSecurityLevelValue(info, &level);
120     FreeDeviceSecurityInfo(info);
121     if (ret != E_SUCCESS) {
122         MEDIA_ERR_LOG("get device sec level failed %{public}d", ret);
123         return;
124     }
125     std::string udid(reinterpret_cast<char *>(const_cast<uint8_t *>(identify->identity)), identify->length);
126     MediaLibraryDevice::GetInstance()->OnGetDevSecLevel(udid, level);
127 }
128 
ReqDestDevSecLevel(const std::string & udid)129 bool DevicePermissionVerification::ReqDestDevSecLevel(const std::string &udid)
130 {
131     DeviceIdentify devIdentify;
132     devIdentify.length = DEVICE_ID_MAX_LEN;
133     int ret = memcpy_s(devIdentify.identity, DEVICE_ID_MAX_LEN, udid.c_str(), DEVICE_ID_MAX_LEN);
134     if (ret != 0) {
135         MEDIA_ERR_LOG("str copy failed %{public}d", ret);
136     }
137     ret = RequestDeviceSecurityInfoAsync(&devIdentify, nullptr, DevicePermissionVerification::MLDevSecInfoCb);
138     if (ret != E_SUCCESS) {
139         MEDIA_ERR_LOG("request device sec info failed %{public}d", ret);
140         return false;
141     }
142     return true;
143 }
144 } // namespace Media
145 } // namespace OHOS
146