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