1 /*
2 * Copyright (c) 2022-2023 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 "auth_message_processor.h"
17
18 #include "dm_auth_manager.h"
19 #include "dm_anonymous.h"
20 #include "dm_constants.h"
21 #include "dm_log.h"
22
23 namespace OHOS {
24 namespace DistributedHardware {
25 const int32_t MSG_MAX_SIZE = 45 * 1024;
26 const int32_t GROUP_VISIBILITY_IS_PRIVATE = 0;
27
28 constexpr const char* TAG_HOST = "HOST";
29 constexpr const char* TAG_REQUESTER = "REQUESTER";
30 constexpr const char* TAG_VISIBILITY = "VISIBILITY";
31 constexpr const char* TAG_DEVICE_TYPE = "DEVICETYPE";
32 constexpr const char* TAG_APP_ICON = "APPICON";
33 constexpr const char* TAG_APP_THUMBNAIL = "APPTHUM";
34 constexpr const char* TAG_THUMBNAIL_SIZE = "THUMSIZE";
35
AuthMessageProcessor(std::shared_ptr<DmAuthManager> authMgr)36 AuthMessageProcessor::AuthMessageProcessor(std::shared_ptr<DmAuthManager> authMgr) : authMgr_(authMgr)
37 {
38 LOGI("AuthMessageProcessor constructor");
39 }
40
~AuthMessageProcessor()41 AuthMessageProcessor::~AuthMessageProcessor()
42 {
43 authMgr_.reset();
44 }
45
CreateAuthRequestMessage()46 std::vector<std::string> AuthMessageProcessor::CreateAuthRequestMessage()
47 {
48 LOGI("AuthMessageProcessor::CreateAuthRequestMessage start.");
49 std::vector<std::string> jsonStrVec;
50 int32_t thumbnailSize = (int32_t)(authRequestContext_->appThumbnail.size());
51 int32_t thumbnailSlice = ((thumbnailSize / MSG_MAX_SIZE) + (thumbnailSize % MSG_MAX_SIZE) == 0 ? 0 : 1);
52 nlohmann::json jsonObj;
53 jsonObj[TAG_VER] = DM_ITF_VER;
54 jsonObj[TAG_MSG_TYPE] = MSG_TYPE_REQ_AUTH;
55 jsonObj[TAG_SLICE_NUM] = thumbnailSlice + 1;
56 jsonObj[TAG_INDEX] = 0;
57 jsonObj[TAG_REQUESTER] = authRequestContext_->deviceName;
58 jsonObj[TAG_DEVICE_ID] = authRequestContext_->deviceId;
59 jsonObj[TAG_DEVICE_TYPE] = authRequestContext_->deviceTypeId;
60 jsonObj[TAG_LOCAL_DEVICE_ID] = authRequestContext_->localDeviceId;
61 jsonObj[TAG_AUTH_TYPE] = authRequestContext_->authType;
62 jsonObj[TAG_TOKEN] = authRequestContext_->token;
63 jsonObj[TAG_VISIBILITY] = authRequestContext_->groupVisibility;
64 if (authRequestContext_->groupVisibility == GROUP_VISIBILITY_IS_PRIVATE) {
65 jsonObj[TAG_TARGET] = authRequestContext_->targetPkgName;
66 jsonObj[TAG_HOST] = authRequestContext_->hostPkgName;
67 }
68 jsonObj[TAG_APP_NAME] = authRequestContext_->appName;
69 jsonObj[TAG_APP_DESCRIPTION] = authRequestContext_->appDesc;
70 jsonObj[TAG_APP_ICON] = authRequestContext_->appIcon;
71 jsonObj[TAG_THUMBNAIL_SIZE] = thumbnailSize;
72 jsonStrVec.push_back(jsonObj.dump());
73
74 for (int32_t idx = 0; idx < thumbnailSlice; idx++) {
75 nlohmann::json jsonThumbnailObj;
76 jsonThumbnailObj[TAG_VER] = DM_ITF_VER;
77 jsonThumbnailObj[TAG_MSG_TYPE] = MSG_TYPE_REQ_AUTH;
78 jsonThumbnailObj[TAG_SLICE_NUM] = thumbnailSlice + 1;
79 jsonThumbnailObj[TAG_INDEX] = idx + 1;
80 jsonThumbnailObj[TAG_DEVICE_ID] = authRequestContext_->deviceId;
81 jsonThumbnailObj[TAG_THUMBNAIL_SIZE] = thumbnailSize;
82
83 int32_t leftLen = thumbnailSize - idx * MSG_MAX_SIZE;
84 int32_t sliceLen = (leftLen > MSG_MAX_SIZE) ? MSG_MAX_SIZE : leftLen;
85 LOGI("TAG_APP_THUMBNAIL encode, idx %d, sliceLen %d, thumbnailSize %d", idx, (uint32_t)sliceLen, thumbnailSize);
86 jsonObj[TAG_APP_THUMBNAIL] = authRequestContext_->appThumbnail.substr(idx * MSG_MAX_SIZE, sliceLen);
87 jsonStrVec.push_back(jsonThumbnailObj.dump());
88 }
89 return jsonStrVec;
90 }
91
CreateSimpleMessage(int32_t msgType)92 std::string AuthMessageProcessor::CreateSimpleMessage(int32_t msgType)
93 {
94 LOGI("AuthMessageProcessor::CreateSimpleMessage start. msgType is %d", msgType);
95 nlohmann::json jsonObj;
96 jsonObj[TAG_VER] = DM_ITF_VER;
97 jsonObj[TAG_MSG_TYPE] = msgType;
98 switch (msgType) {
99 case MSG_TYPE_NEGOTIATE:
100 case MSG_TYPE_RESP_NEGOTIATE:
101 CreateNegotiateMessage(jsonObj);
102 break;
103 case MSG_TYPE_SYNC_GROUP:
104 CreateSyncGroupMessage(jsonObj);
105 break;
106 case MSG_TYPE_RESP_AUTH:
107 CreateResponseAuthMessage(jsonObj);
108 break;
109 case MSG_TYPE_REQ_AUTH_TERMINATE:
110 CreateResponseFinishMessage(jsonObj);
111 break;
112 default:
113 break;
114 }
115 return jsonObj.dump();
116 }
117
CreateNegotiateMessage(nlohmann::json & json)118 void AuthMessageProcessor::CreateNegotiateMessage(nlohmann::json &json)
119 {
120 if (cryptoAdapter_ == nullptr) {
121 json[TAG_CRYPTO_SUPPORT] = false;
122 } else {
123 json[TAG_CRYPTO_SUPPORT] = true;
124 json[TAG_CRYPTO_NAME] = cryptoAdapter_->GetName();
125 json[TAG_CRYPTO_VERSION] = cryptoAdapter_->GetVersion();
126 json[TAG_DEVICE_ID] = authResponseContext_->deviceId;
127 }
128 json[TAG_AUTH_TYPE] = authResponseContext_->authType;
129 json[TAG_REPLY] = authResponseContext_->reply;
130 json[TAG_LOCAL_DEVICE_ID] = authResponseContext_->localDeviceId;
131 }
132
CreateSyncGroupMessage(nlohmann::json & json)133 void AuthMessageProcessor::CreateSyncGroupMessage(nlohmann::json &json)
134 {
135 json[TAG_DEVICE_ID] = authRequestContext_->deviceId;
136 json[TAG_GROUPIDS] = authRequestContext_->syncGroupList;
137 }
138
CreateResponseAuthMessage(nlohmann::json & json)139 void AuthMessageProcessor::CreateResponseAuthMessage(nlohmann::json &json)
140 {
141 json[TAG_REPLY] = authResponseContext_->reply;
142 json[TAG_DEVICE_ID] = authResponseContext_->deviceId;
143 json[TAG_TOKEN] = authResponseContext_->token;
144 if (authResponseContext_->reply == 0) {
145 std::string groupId = authResponseContext_->groupId;
146 LOGI("AuthMessageProcessor::CreateSimpleMessage groupId %s", GetAnonyString(groupId).c_str());
147 nlohmann::json jsonObject = nlohmann::json::parse(groupId, nullptr, false);
148 if (jsonObject.is_discarded()) {
149 LOGE("DecodeRequestAuth jsonStr error");
150 return;
151 }
152 groupId = jsonObject[TAG_GROUP_ID].get<std::string>();
153 json[TAG_NET_ID] = authResponseContext_->networkId;
154 json[TAG_REQUEST_ID] = authResponseContext_->requestId;
155 json[TAG_GROUP_ID] = groupId;
156 json[TAG_GROUP_NAME] = authResponseContext_->groupName;
157 json[TAG_AUTH_TOKEN] = authResponseContext_->authToken;
158 LOGI("AuthMessageProcessor::ParseAuthResponseMessage %s, %s", GetAnonyString(groupId).c_str(),
159 GetAnonyString(authResponseContext_->groupName).c_str());
160 }
161 }
162
CreateResponseFinishMessage(nlohmann::json & json)163 void AuthMessageProcessor::CreateResponseFinishMessage(nlohmann::json &json)
164 {
165 json[TAG_REPLY] = authResponseContext_->reply;
166 }
167
ParseMessage(const std::string & message)168 int32_t AuthMessageProcessor::ParseMessage(const std::string &message)
169 {
170 nlohmann::json jsonObject = nlohmann::json::parse(message, nullptr, false);
171 if (jsonObject.is_discarded()) {
172 LOGE("DecodeRequestAuth jsonStr error");
173 return ERR_DM_FAILED;
174 }
175 if (!IsInt32(jsonObject, TAG_MSG_TYPE)) {
176 LOGE("err json string, first time");
177 return ERR_DM_FAILED;
178 }
179 int32_t msgType = jsonObject[TAG_MSG_TYPE].get<int32_t>();
180 authResponseContext_->msgType = msgType;
181 LOGI("AuthMessageProcessor::ParseMessage message type %d", authResponseContext_->msgType);
182 switch (msgType) {
183 case MSG_TYPE_NEGOTIATE:
184 ParseNegotiateMessage(jsonObject);
185 break;
186 case MSG_TYPE_RESP_NEGOTIATE:
187 ParseRespNegotiateMessage(jsonObject);
188 break;
189 case MSG_TYPE_REQ_AUTH:
190 return ParseAuthRequestMessage(jsonObject);
191 break;
192 case MSG_TYPE_RESP_AUTH:
193 ParseAuthResponseMessage(jsonObject);
194 break;
195 case MSG_TYPE_REQ_AUTH_TERMINATE:
196 ParseResponseFinishMessage(jsonObject);
197 break;
198 default:
199 break;
200 }
201 return DM_OK;
202 }
203
ParseResponseFinishMessage(nlohmann::json & json)204 void AuthMessageProcessor::ParseResponseFinishMessage(nlohmann::json &json)
205 {
206 if (IsInt32(json, TAG_REPLY)) {
207 authResponseContext_->reply = json[TAG_REPLY].get<int32_t>();
208 }
209 }
210
ParseAuthRequestMessage(nlohmann::json & json)211 int32_t AuthMessageProcessor::ParseAuthRequestMessage(nlohmann::json &json)
212 {
213 LOGI("start ParseAuthRequestMessage");
214 int32_t sliceNum = 0;
215 int32_t idx = 0;
216 if (!IsInt32(json, TAG_INDEX) || !IsInt32(json, TAG_SLICE_NUM)) {
217 LOGE("AuthMessageProcessor::ParseAuthRequestMessage err json string, first time.");
218 return ERR_DM_FAILED;
219 }
220
221 idx = json[TAG_INDEX].get<int32_t>();
222 sliceNum = json[TAG_SLICE_NUM].get<int32_t>();
223 if (idx == 0) {
224 if (!IsString(json, TAG_DEVICE_ID) || !IsInt32(json, TAG_AUTH_TYPE) || !IsString(json, TAG_APP_DESCRIPTION) ||
225 !IsString(json, TAG_TOKEN) || !IsString(json, TAG_TARGET) || !IsString(json, TAG_APP_NAME) ||
226 !IsString(json, TAG_LOCAL_DEVICE_ID)) {
227 LOGE("AuthMessageProcessor::ParseAuthRequestMessage err json string, second.");
228 return ERR_DM_FAILED;
229 }
230 authResponseContext_->localDeviceId = json[TAG_LOCAL_DEVICE_ID].get<std::string>();
231 authResponseContext_->deviceId = json[TAG_DEVICE_ID].get<std::string>();
232 authResponseContext_->authType = json[TAG_AUTH_TYPE].get<int32_t>();
233 authResponseContext_->appDesc = json[TAG_APP_DESCRIPTION].get<std::string>();
234 authResponseContext_->token = json[TAG_TOKEN].get<std::string>();
235 authResponseContext_->targetPkgName = json[TAG_TARGET].get<std::string>();
236 authResponseContext_->appName = json[TAG_APP_NAME].get<std::string>();
237 authResponseContext_->appThumbnail = "";
238 }
239
240 if (idx < sliceNum && IsString(json, TAG_APP_THUMBNAIL)) {
241 std::string appSliceThumbnail = json[TAG_APP_THUMBNAIL].get<std::string>();
242 authResponseContext_->appThumbnail = authResponseContext_->appThumbnail + appSliceThumbnail;
243 return ERR_DM_AUTH_MESSAGE_INCOMPLETE;
244 }
245 return DM_OK;
246 }
247
ParseAuthResponseMessage(nlohmann::json & json)248 void AuthMessageProcessor::ParseAuthResponseMessage(nlohmann::json &json)
249 {
250 LOGI("start ParseAuthResponseMessage");
251 if (!IsInt32(json, TAG_REPLY) || !IsString(json, TAG_DEVICE_ID) || !IsString(json, TAG_TOKEN)) {
252 LOGE("AuthMessageProcessor::ParseAuthResponseMessage err json string, first time.");
253 return;
254 }
255 authResponseContext_->reply = json[TAG_REPLY].get<int32_t>();
256 authResponseContext_->deviceId = json[TAG_DEVICE_ID].get<std::string>();
257 authResponseContext_->token = json[TAG_TOKEN].get<std::string>();
258 if (authResponseContext_->reply == 0) {
259 if (!IsString(json, TAG_NET_ID) || !IsInt64(json, TAG_REQUEST_ID) || !IsString(json, TAG_GROUP_ID) ||
260 !IsString(json, TAG_GROUP_NAME) || !IsString(json, TAG_AUTH_TOKEN)) {
261 LOGE("AuthMessageProcessor::ParseAuthResponseMessage err json string, second time.");
262 return;
263 }
264 authResponseContext_->networkId = json[TAG_NET_ID].get<std::string>();
265 authResponseContext_->requestId = json[TAG_REQUEST_ID].get<int64_t>();
266 authResponseContext_->groupId = json[TAG_GROUP_ID].get<std::string>();
267 authResponseContext_->groupName = json[TAG_GROUP_NAME].get<std::string>();
268 authResponseContext_->authToken = json[TAG_AUTH_TOKEN].get<std::string>();
269 LOGI("AuthMessageProcessor::ParseAuthResponseMessage %s,%s",
270 GetAnonyString(authResponseContext_->groupId).c_str(), authResponseContext_->groupName.c_str());
271 }
272 }
273
ParseNegotiateMessage(const nlohmann::json & json)274 void AuthMessageProcessor::ParseNegotiateMessage(const nlohmann::json &json)
275 {
276 if (IsBool(json, TAG_CRYPTO_SUPPORT)) {
277 authResponseContext_->cryptoSupport = json[TAG_CRYPTO_SUPPORT].get<bool>();
278 }
279 if (IsString(json, TAG_CRYPTO_NAME)) {
280 authResponseContext_->cryptoName = json[TAG_CRYPTO_NAME].get<std::string>();
281 }
282 if (IsString(json, TAG_CRYPTO_VERSION)) {
283 authResponseContext_->cryptoVer = json[TAG_CRYPTO_VERSION].get<std::string>();
284 }
285 if (IsString(json, TAG_DEVICE_ID)) {
286 authResponseContext_->deviceId = json[TAG_DEVICE_ID].get<std::string>();
287 }
288 if (IsString(json, TAG_LOCAL_DEVICE_ID)) {
289 authResponseContext_->localDeviceId = json[TAG_LOCAL_DEVICE_ID].get<std::string>();
290 }
291 if (IsInt32(json, TAG_AUTH_TYPE)) {
292 authResponseContext_->authType = json[TAG_AUTH_TYPE].get<int32_t>();
293 }
294 if (IsInt32(json, TAG_REPLY)) {
295 authResponseContext_->reply = json[TAG_REPLY].get<int32_t>();
296 }
297 }
298
ParseRespNegotiateMessage(const nlohmann::json & json)299 void AuthMessageProcessor::ParseRespNegotiateMessage(const nlohmann::json &json)
300 {
301 if (IsBool(json, TAG_IDENTICAL_ACCOUNT)) {
302 authResponseContext_->isIdenticalAccount = json[TAG_IDENTICAL_ACCOUNT].get<bool>();
303 }
304 if (IsInt32(json, TAG_REPLY)) {
305 authResponseContext_->reply = json[TAG_REPLY].get<int32_t>();
306 }
307 if (IsString(json, TAG_LOCAL_DEVICE_ID)) {
308 authResponseContext_->localDeviceId = json[TAG_LOCAL_DEVICE_ID].get<std::string>();
309 }
310 }
311
SetRequestContext(std::shared_ptr<DmAuthRequestContext> authRequestContext)312 void AuthMessageProcessor::SetRequestContext(std::shared_ptr<DmAuthRequestContext> authRequestContext)
313 {
314 authRequestContext_ = authRequestContext;
315 }
316
SetResponseContext(std::shared_ptr<DmAuthResponseContext> authResponseContext)317 void AuthMessageProcessor::SetResponseContext(std::shared_ptr<DmAuthResponseContext> authResponseContext)
318 {
319 authResponseContext_ = authResponseContext;
320 }
321
GetResponseContext()322 std::shared_ptr<DmAuthResponseContext> AuthMessageProcessor::GetResponseContext()
323 {
324 return authResponseContext_;
325 }
326
GetRequestContext()327 std::shared_ptr<DmAuthRequestContext> AuthMessageProcessor::GetRequestContext()
328 {
329 return authRequestContext_;
330 }
331 } // namespace DistributedHardware
332 } // namespace OHOS
333