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