mirror of
https://gitee.com/openharmony/startup_appspawn
synced 2024-11-28 01:30:57 +00:00
f7b7dddb2b
Signed-off-by: xlei1030 <xionglei6@huawei.com>
205 lines
5.7 KiB
C
205 lines
5.7 KiB
C
/*
|
|
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include "appspawn_message.h"
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#ifdef __LINUX__
|
|
#include <linux/capability.h>
|
|
#else
|
|
#include <sys/capability.h>
|
|
#endif
|
|
|
|
#include "appspawn_server.h"
|
|
#include "cJSON.h"
|
|
#include "ohos_errno.h"
|
|
#include "securec.h"
|
|
|
|
static const size_t MAX_BUNDLE_NAME_LEN = 127;
|
|
static const size_t MIN_BUNDLE_NAME_LEN = 7;
|
|
static const size_t MAX_IDENTITY_ID_LEN = 24;
|
|
static const size_t MIN_IDENTITY_ID_LEN = 1;
|
|
static const size_t MAX_CAPABILITY_COUNT = 10;
|
|
|
|
void FreeMessageSt(MessageSt *targetSt)
|
|
{
|
|
if (targetSt != NULL) {
|
|
if (targetSt->bundleName != NULL) {
|
|
free(targetSt->bundleName);
|
|
targetSt->bundleName = NULL;
|
|
}
|
|
|
|
if (targetSt->identityID != NULL) {
|
|
free(targetSt->identityID);
|
|
targetSt->identityID = NULL;
|
|
}
|
|
|
|
if (targetSt->caps != NULL) {
|
|
free(targetSt->caps);
|
|
targetSt->caps = NULL;
|
|
}
|
|
|
|
targetSt->uID = -1;
|
|
targetSt->gID = -1;
|
|
targetSt->capsCnt = 0;
|
|
}
|
|
}
|
|
|
|
static enum OHOSLiteErrorCode ReadStringItem(cJSON *strItem, char **buf, size_t maxLen, size_t minLen)
|
|
{
|
|
if (strItem == NULL || !cJSON_IsString(strItem)) {
|
|
return EC_INVALID;
|
|
}
|
|
|
|
char *strPtr = cJSON_GetStringValue(strItem);
|
|
if (strPtr == NULL) {
|
|
return EC_PROTOCOL;
|
|
}
|
|
|
|
size_t strLength = strlen(strPtr);
|
|
if (strLength > maxLen || strLength < minLen) {
|
|
return EC_PROTOCOL;
|
|
}
|
|
|
|
char *bufTmp = (char *)malloc(strLength + 1);
|
|
if (bufTmp == NULL) {
|
|
return EC_NOMEMORY;
|
|
}
|
|
|
|
if (strLength > 0 && memcpy_s(bufTmp, strLength, strPtr, strLength) != EOK) {
|
|
free(bufTmp);
|
|
bufTmp = NULL;
|
|
return EC_FAILURE;
|
|
}
|
|
|
|
bufTmp[strLength] = '\0';
|
|
*buf = bufTmp;
|
|
return EC_SUCCESS;
|
|
}
|
|
|
|
static double ReadNumberItem(cJSON *strItem)
|
|
{
|
|
if (strItem == NULL || !cJSON_IsNumber(strItem)) {
|
|
return -1;
|
|
}
|
|
|
|
return cJSON_GetNumberValue(strItem);
|
|
}
|
|
|
|
static int GetCaps(const cJSON *curItem, MessageSt *msgSt)
|
|
{
|
|
msgSt->capsCnt = 0;
|
|
msgSt->caps = NULL;
|
|
cJSON *capItem = cJSON_GetObjectItem(curItem, "capability");
|
|
if (!cJSON_IsArray(capItem)) {
|
|
APPSPAWN_LOGE("[appspawn] GetCaps failed, no caps array found.");
|
|
return EC_INVALID;
|
|
}
|
|
|
|
// caps array empty, means do not need any capability
|
|
int capsCnt = cJSON_GetArraySize(capItem);
|
|
if (capsCnt <= 0) {
|
|
return EC_SUCCESS;
|
|
}
|
|
|
|
if (capsCnt > MAX_CAPABILITY_COUNT) {
|
|
APPSPAWN_LOGE("[appspawn] GetCaps, too many caps[cnt %d], max %d",
|
|
capsCnt, MAX_CAPABILITY_COUNT);
|
|
return EC_INVALID;
|
|
}
|
|
|
|
msgSt->caps = (unsigned int *)malloc(sizeof(unsigned int) * capsCnt);
|
|
if (msgSt->caps == NULL) {
|
|
APPSPAWN_LOGE("[appspawn] GetCaps, malloc failed! capsCnt[cnt %d].", capsCnt);
|
|
return EC_NOMEMORY;
|
|
}
|
|
|
|
for (int i = 0; i < capsCnt; ++i) {
|
|
cJSON *capJ = cJSON_GetArrayItem(capItem, i);
|
|
if (!cJSON_IsNumber(capJ) || cJSON_GetNumberValue(capJ) < 0) {
|
|
APPSPAWN_LOGE("[appspawn] GetCaps, invalid cap value detected!");
|
|
free(msgSt->caps);
|
|
msgSt->caps = NULL;
|
|
return EC_INVALID;
|
|
}
|
|
msgSt->caps[i] = (unsigned int)cJSON_GetNumberValue(capJ);
|
|
if (msgSt->caps[i] > CAP_LAST_CAP) {
|
|
APPSPAWN_LOGE("[appspawn] GetCaps, invalid cap value %u detected!", \
|
|
msgSt->caps[i]);
|
|
free(msgSt->caps);
|
|
msgSt->caps = NULL;
|
|
return EC_INVALID;
|
|
}
|
|
}
|
|
msgSt->capsCnt = capsCnt;
|
|
return EC_SUCCESS;
|
|
}
|
|
|
|
int SplitMessage(const char *msg, unsigned int msgLen, MessageSt *msgSt)
|
|
{
|
|
if (msgSt == NULL) {
|
|
return EC_INVALID;
|
|
}
|
|
|
|
if (msg == NULL || msgLen == 0) {
|
|
FreeMessageSt(msgSt);
|
|
return EC_INVALID;
|
|
}
|
|
|
|
cJSON *rootJ = cJSON_ParseWithLength(msg, msgLen);
|
|
if (rootJ == NULL) {
|
|
FreeMessageSt(msgSt);
|
|
return EC_PROTOCOL;
|
|
}
|
|
|
|
cJSON *bundleNameItem = cJSON_GetObjectItem(rootJ, "bundleName");
|
|
int ret = (int)ReadStringItem(bundleNameItem, &(msgSt->bundleName), MAX_BUNDLE_NAME_LEN, MIN_BUNDLE_NAME_LEN);
|
|
if (ret != EC_SUCCESS) {
|
|
FreeMessageSt(msgSt);
|
|
cJSON_Delete(rootJ);
|
|
return ret;
|
|
}
|
|
|
|
cJSON *identityIDItem = cJSON_GetObjectItem(rootJ, "identityID");
|
|
ret = (int)ReadStringItem(identityIDItem, &(msgSt->identityID), MAX_IDENTITY_ID_LEN, MIN_IDENTITY_ID_LEN);
|
|
if (ret != EC_SUCCESS) {
|
|
FreeMessageSt(msgSt);
|
|
cJSON_Delete(rootJ);
|
|
return ret;
|
|
}
|
|
|
|
cJSON *uIDItem = cJSON_GetObjectItem(rootJ, "uID");
|
|
cJSON *gIDItem = cJSON_GetObjectItem(rootJ, "gID");
|
|
msgSt->uID = (int)ReadNumberItem(uIDItem);
|
|
msgSt->gID = (int)ReadNumberItem(gIDItem);
|
|
|
|
ret = GetCaps(rootJ, msgSt);
|
|
if (ret != EC_SUCCESS) {
|
|
FreeMessageSt(msgSt);
|
|
cJSON_Delete(rootJ);
|
|
return ret;
|
|
}
|
|
|
|
cJSON_Delete(rootJ);
|
|
|
|
if (msgSt->uID <= 0 || msgSt->gID <= 0 || msgSt->uID == INT_MAX || msgSt->gID == INT_MAX) {
|
|
FreeMessageSt(msgSt);
|
|
return EC_PROTOCOL;
|
|
}
|
|
return EC_SUCCESS;
|
|
}
|