1 /*
2 * Copyright (c) 2020 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 "want_utils.h"
17 #include "element_name_utils.h"
18
19 #include <securec.h>
20 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
21 #include <string>
22 #include <liteipc_adapter.h>
23 #endif
24
25 #include "log.h"
26 #include "utils.h"
27
28 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
29 using UriKeyType = enum {
30 BEGIN,
31 DEVICE,
32 BUNDLE,
33 ABILITY,
34 END,
35 };
36
37 using UriProperties = struct {
38 const char *key; /* key of uri property */
39 uint8_t keyLen; /* key length of uri property */
40 UriKeyType type; /* key type of uri property */
41 };
42
43 const static UriProperties URI_PROPERTIES[] = {
44 { "#Want", 5, BEGIN },
45 { "device=", 7, DEVICE },
46 { "bundle=", 7, BUNDLE },
47 { "ability=", 8, ABILITY },
48 { "end", 3, END },
49 };
50
51 constexpr static char URI_SEPARATOR = ';';
52 constexpr static int VALUE_NULL = 0;
53 constexpr static int VALUE_OBJECT = 1;
54 constexpr static int DATA_LENGTH = 2048;
55 #endif
56
57 constexpr uint8_t INT_VALUE_TYPE = 6;
58 constexpr uint8_t STRING_VALUE_TYPE = 13;
59 constexpr uint8_t KEY_VALUE_PAIR_TYPE = 97;
60
ClearWant(Want * want)61 void ClearWant(Want *want)
62 {
63 if (want == nullptr) {
64 return;
65 }
66
67 ClearElement(want->element);
68 AdapterFree(want->element);
69 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
70 AdapterFree(want->sid);
71 #endif
72 AdapterFree(want->data);
73 }
74
SetWantElement(Want * want,ElementName element)75 bool SetWantElement(Want *want, ElementName element)
76 {
77 if (want == nullptr) {
78 return false;
79 }
80
81 ClearElement(want->element);
82 AdapterFree(want->element);
83 want->element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName)));
84 if (want->element == nullptr) {
85 return false;
86 }
87 want->element->deviceId = OHOS::Utils::Strdup(element.deviceId);
88 want->element->bundleName = OHOS::Utils::Strdup(element.bundleName);
89 want->element->abilityName = OHOS::Utils::Strdup(element.abilityName);
90 return true;
91 }
92
EncapTlv(uint8_t type,uint8_t length,const void * value,uint8_t valueLen)93 Tlv *EncapTlv(uint8_t type, uint8_t length, const void *value, uint8_t valueLen)
94 {
95 void *entity = nullptr;
96
97 // Tlv header can only has 2 bytes.
98 uint8_t totalLen = valueLen + 2;
99 entity = calloc(1, totalLen);
100 if (entity == nullptr) {
101 return nullptr;
102 }
103
104 if (memcpy_s((unsigned char *)entity, 1, &type, 1) != 0 ||
105 memcpy_s((unsigned char *)entity + 1, 1, &length, 1) != 0 ||
106 memcpy_s((unsigned char *)entity + 2, valueLen, value, valueLen) != 0) {
107 AdapterFree(entity);
108 return nullptr;
109 }
110
111 Tlv *newTlv = new Tlv();
112 newTlv->type = type;
113 newTlv->entity = entity;
114 newTlv->totalLen = totalLen;
115 return newTlv;
116 }
117
FreeTlvStruct(Tlv * tlv)118 void FreeTlvStruct(Tlv *tlv)
119 {
120 AdapterFree(tlv->entity);
121 AdapterFree(tlv);
122 }
123
CombineKeyValueTlv(Tlv * keyTlv,Tlv * valueTlv)124 Tlv *CombineKeyValueTlv(Tlv *keyTlv, Tlv *valueTlv)
125 {
126 uint8_t newTlvValueLen = keyTlv->totalLen + valueTlv->totalLen;
127 void *newTlvValue = calloc(1, newTlvValueLen);
128 if (newTlvValue == nullptr) {
129 return nullptr;
130 }
131 if (memcpy_s((unsigned char *)newTlvValue, keyTlv->totalLen, keyTlv->entity, keyTlv->totalLen) != 0 ||
132 memcpy_s((unsigned char *)newTlvValue + keyTlv->totalLen, valueTlv->totalLen,
133 valueTlv->entity, valueTlv->totalLen) != 0) {
134 AdapterFree(newTlvValue);
135 return nullptr;
136 }
137
138 Tlv *newTlv = EncapTlv(KEY_VALUE_PAIR_TYPE, newTlvValueLen, newTlvValue, newTlvValueLen);
139 AdapterFree(newTlvValue);
140 return newTlv;
141 }
142
UpdateWantData(Want * want,Tlv * tlv)143 bool UpdateWantData(Want *want, Tlv *tlv)
144 {
145 bool result = false;
146 if (want->data != nullptr) {
147 void *newWantData = calloc(1, tlv->totalLen + want->dataLength);
148 if (newWantData == nullptr) {
149 return result;
150 }
151 if (memcpy_s(newWantData, want->dataLength, want->data, want->dataLength) != 0 ||
152 memcpy_s((unsigned char*)newWantData + want->dataLength, tlv->totalLen, tlv->entity, tlv->totalLen) != 0) {
153 AdapterFree(newWantData);
154 return result;
155 }
156 SetWantData(want, newWantData, tlv->totalLen + want->dataLength);
157 AdapterFree(newWantData);
158 result = true;
159 } else {
160 SetWantData(want, tlv->entity, tlv->totalLen);
161 result = true;
162 }
163 return result;
164 }
165
SetIntParam(Want * want,const char * key,uint8_t keyLen,int32_t value)166 bool SetIntParam(Want *want, const char *key, uint8_t keyLen, int32_t value)
167 {
168 bool result = false;
169 if (keyLen <= 0) {
170 return result;
171 }
172
173 Tlv *keyTlv = EncapTlv(STRING_VALUE_TYPE, keyLen, (void *)key, keyLen);
174 if (keyTlv == nullptr) {
175 return result;
176 }
177 if (value < 0) {
178 HILOG_ERROR(HILOG_MODULE_APP, "SetIntParam value should be positive");
179 FreeTlvStruct(keyTlv);
180 return result;
181 }
182 int intBufferbNumber = 4;
183 unsigned char intBuffer[4] = {0};
184 for (int i = 0; i < intBufferbNumber; i++) {
185 intBuffer[i] = value >> (8 * (3- i));
186 }
187 Tlv *valueTlv = EncapTlv(INT_VALUE_TYPE, sizeof(int), (void *)intBuffer, sizeof(int));
188 if (valueTlv == nullptr) {
189 FreeTlvStruct(keyTlv);
190 return result;
191 }
192 Tlv *newTlv = CombineKeyValueTlv(keyTlv, valueTlv);
193 FreeTlvStruct(keyTlv);
194 FreeTlvStruct(valueTlv);
195 if (newTlv == nullptr) {
196 return result;
197 }
198 if (UpdateWantData(want, newTlv)) {
199 AdapterFree(newTlv);
200 result = true;
201 }
202 AdapterFree(newTlv);
203 return result;
204 }
205
SetStrParam(Want * want,const char * key,uint8_t keyLen,const char * value,uint8_t valueLen)206 bool SetStrParam(Want *want, const char *key, uint8_t keyLen, const char *value, uint8_t valueLen)
207 {
208 bool result = false;
209 if (keyLen <= 0 || valueLen <= 0) {
210 return result;
211 }
212
213 Tlv *keyTlv = EncapTlv(STRING_VALUE_TYPE, keyLen, (void *)key, keyLen);
214 if (keyTlv == nullptr) {
215 return result;
216 }
217
218 Tlv *valueTlv = EncapTlv(STRING_VALUE_TYPE, valueLen, (void *)value, valueLen);
219 if (valueTlv == nullptr) {
220 FreeTlvStruct(keyTlv);
221 return result;
222 }
223 Tlv *newTlv = CombineKeyValueTlv(keyTlv, valueTlv);
224 FreeTlvStruct(keyTlv);
225 FreeTlvStruct(valueTlv);
226 if (newTlv == nullptr) {
227 return result;
228 }
229 if (UpdateWantData(want, newTlv)) {
230 AdapterFree(newTlv);
231 result = true;
232 }
233 AdapterFree(newTlv);
234 return result;
235 }
236
237 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
SetWantSvcIdentity(Want * want,SvcIdentity sid)238 bool SetWantSvcIdentity(Want *want, SvcIdentity sid)
239 {
240 if (want == nullptr) {
241 return false;
242 }
243
244 AdapterFree(want->sid);
245 want->sid = reinterpret_cast<SvcIdentity *>(AdapterMalloc(sizeof(SvcIdentity)));
246 if (want->sid == nullptr) {
247 return false;
248 }
249 if (memcpy_s(want->sid, sizeof(SvcIdentity), &sid, sizeof(SvcIdentity)) != EOK) {
250 AdapterFree(want->sid);
251 return false;
252 }
253
254 return true;
255 }
256 #endif
257
SetWantData(Want * want,const void * data,uint16_t dataLength)258 bool SetWantData(Want *want, const void *data, uint16_t dataLength)
259 {
260 if (want == nullptr) {
261 return false;
262 }
263
264 AdapterFree(want->data);
265 want->data = OHOS::Utils::Memdup(data, dataLength);
266 if (want->data == nullptr) {
267 want->dataLength = 0;
268 return false;
269 }
270
271 want->dataLength = dataLength;
272 return true;
273 }
274
275 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
SerializeWant(IpcIo * io,const Want * want)276 bool SerializeWant(IpcIo *io, const Want *want)
277 {
278 if ((io == nullptr) || (want == nullptr) || (want->dataLength > DATA_LENGTH)) {
279 return false;
280 }
281
282 if (want->element == nullptr) {
283 IpcIoPushInt32(io, VALUE_NULL);
284 } else {
285 IpcIoPushInt32(io, VALUE_OBJECT);
286 if (!SerializeElement(io, want->element)) {
287 return false;
288 }
289 }
290 IpcIoPushInt32(io, want->dataLength);
291 if (want->dataLength > 0) {
292 #ifdef __LINUX__
293 IpcIoPushFlatObj(io, want->data, want->dataLength);
294 #else
295 const BuffPtr buff = {
296 want->dataLength,
297 want->data,
298 };
299 IpcIoPushDataBuff(io, &buff);
300 #endif
301 }
302 if (want->sid == nullptr) {
303 IpcIoPushInt32(io, VALUE_NULL);
304 } else {
305 IpcIoPushInt32(io, VALUE_OBJECT);
306 IpcIoPushSvc(io, want->sid);
307 }
308
309 return true;
310 }
311
DeserializeWant(Want * want,IpcIo * io)312 bool DeserializeWant(Want *want, IpcIo *io)
313 {
314 if ((want == nullptr) || (io == nullptr)) {
315 return false;
316 }
317
318 if (IpcIoPopInt32(io) == VALUE_OBJECT) {
319 want->element = reinterpret_cast<ElementName *>(AdapterMalloc(sizeof(ElementName)));
320 if (want->element == nullptr ||
321 memset_s(want->element, sizeof(ElementName), 0, sizeof(ElementName)) != EOK ||
322 !DeserializeElement(want->element, io)) {
323 AdapterFree(want->element);
324 return false;
325 }
326 }
327 if (IpcIoPopInt32(io) > 0) {
328 #ifdef __LINUX__
329 uint32_t size = 0;
330 void *data = IpcIoPopFlatObj(io, &size);
331 if (!SetWantData(want, data, size)) {
332 ClearWant(want);
333 return false;
334 }
335 #else
336 BuffPtr *buff = IpcIoPopDataBuff(io);
337 if (buff == nullptr) {
338 ClearWant(want);
339 return false;
340 }
341 if (!SetWantData(want, buff->buff, buff->buffSz)) {
342 FreeBuffer(nullptr, buff->buff);
343 ClearWant(want);
344 return false;
345 }
346 FreeBuffer(nullptr, buff->buff);
347 #endif
348 }
349 if (IpcIoPopInt32(io) == VALUE_OBJECT) {
350 auto sid = IpcIoPopSvc(io);
351 if ((sid == nullptr) || !SetWantSvcIdentity(want, *sid)) {
352 #ifdef __LINUX__
353 AdapterFree(sid);
354 sid = nullptr;
355 #endif
356 ClearWant(want);
357 return false;
358 }
359 #ifdef __LINUX__
360 AdapterFree(sid);
361 sid = nullptr;
362 #endif
363 }
364
365 return true;
366 }
367
WantParseUri(const char * uri)368 Want *WantParseUri(const char *uri)
369 {
370 if (uri == nullptr) {
371 return nullptr;
372 }
373 char *parseUri = OHOS::Utils::Strdup(uri);
374 if (parseUri == nullptr) {
375 return nullptr;
376 }
377 ElementName element = { nullptr, nullptr, nullptr };
378 char *beginIndex = parseUri;
379 for (auto property : URI_PROPERTIES) {
380 if (strstr(beginIndex, property.key) != beginIndex) {
381 AdapterFree(parseUri);
382 return nullptr;
383 }
384 if (property.type == END) {
385 break;
386 }
387 char *endIndex = strchr(beginIndex, URI_SEPARATOR);
388 if ((endIndex == nullptr) || (endIndex <= beginIndex)) {
389 AdapterFree(parseUri);
390 return nullptr;
391 }
392 *endIndex = '\0';
393 beginIndex += property.keyLen;
394 switch (property.type) {
395 case DEVICE: {
396 SetElementDeviceID(&element, beginIndex);
397 break;
398 }
399 case BUNDLE: {
400 SetElementBundleName(&element, beginIndex);
401 break;
402 }
403 case ABILITY: {
404 SetElementAbilityName(&element, beginIndex);
405 break;
406 }
407 default: {
408 break;
409 }
410 }
411 beginIndex = endIndex + 1;
412 }
413 AdapterFree(parseUri);
414 Want *want = new Want();
415 if ((memset_s(want, sizeof(Want), 0, sizeof(Want)) != EOK) || !SetWantElement(want, element)) {
416 ClearElement(&element);
417 delete want;
418 return nullptr;
419 }
420 ClearElement(&element);
421 return want;
422 }
423
WantToUri(Want want)424 const char *WantToUri(Want want)
425 {
426 std::string uriString;
427
428 for (auto property : URI_PROPERTIES) {
429 uriString += property.key;
430 switch (property.type) {
431 case BEGIN: {
432 uriString += URI_SEPARATOR;
433 break;
434 }
435 case DEVICE: {
436 if ((want.element != nullptr) && (want.element->deviceId != nullptr)) {
437 uriString += want.element->deviceId;
438 }
439 uriString += URI_SEPARATOR;
440 break;
441 }
442 case BUNDLE: {
443 if ((want.element != nullptr) && (want.element->bundleName != nullptr)) {
444 uriString += want.element->bundleName;
445 }
446 uriString += URI_SEPARATOR;
447 break;
448 }
449 case ABILITY: {
450 if ((want.element != nullptr) && (want.element->abilityName != nullptr)) {
451 uriString += want.element->abilityName;
452 }
453 uriString += URI_SEPARATOR;
454 break;
455 }
456 default: {
457 break;
458 }
459 }
460 }
461
462 uint16_t len = uriString.size();
463 char *uri = reinterpret_cast<char *>(AdapterMalloc(len + 1));
464 if (uri == nullptr) {
465 return nullptr;
466 }
467 if (strncpy_s(uri, len + 1, uriString.c_str(), len) < 0) {
468 AdapterFree(uri);
469 return nullptr;
470 }
471
472 return uri;
473 }
474 #endif
475