169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License. 569570cc8Sopenharmony_ci * You may obtain a copy of the License at 669570cc8Sopenharmony_ci * 769570cc8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 869570cc8Sopenharmony_ci * 969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and 1369570cc8Sopenharmony_ci * limitations under the License. 1469570cc8Sopenharmony_ci */ 1569570cc8Sopenharmony_ci#include "appspawn_permission.h" 1669570cc8Sopenharmony_ci#ifdef APPSPAWN_CLIENT 1769570cc8Sopenharmony_ci#include "appspawn_mount_permission.h" 1869570cc8Sopenharmony_ci#else 1969570cc8Sopenharmony_ci#include "appspawn_sandbox.h" 2069570cc8Sopenharmony_ci#endif 2169570cc8Sopenharmony_ci#include "appspawn_msg.h" 2269570cc8Sopenharmony_ci#include "appspawn_utils.h" 2369570cc8Sopenharmony_ci#include "securec.h" 2469570cc8Sopenharmony_ci 2569570cc8Sopenharmony_cistatic int PermissionNodeCompareIndex(ListNode *node, void *data) 2669570cc8Sopenharmony_ci{ 2769570cc8Sopenharmony_ci SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node); 2869570cc8Sopenharmony_ci return permissionNode->permissionIndex - *(int32_t *)data; 2969570cc8Sopenharmony_ci} 3069570cc8Sopenharmony_ci 3169570cc8Sopenharmony_cistatic int PermissionNodeCompareName(ListNode *node, void *data) 3269570cc8Sopenharmony_ci{ 3369570cc8Sopenharmony_ci SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node); 3469570cc8Sopenharmony_ci#ifdef APPSPAWN_CLIENT 3569570cc8Sopenharmony_ci return strcmp(permissionNode->name, (char *)data); 3669570cc8Sopenharmony_ci#else 3769570cc8Sopenharmony_ci return strcmp(permissionNode->section.name, (char *)data); 3869570cc8Sopenharmony_ci#endif 3969570cc8Sopenharmony_ci} 4069570cc8Sopenharmony_ci 4169570cc8Sopenharmony_cistatic int PermissionNodeCompareProc(ListNode *node, ListNode *newNode) 4269570cc8Sopenharmony_ci{ 4369570cc8Sopenharmony_ci SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node); 4469570cc8Sopenharmony_ci SandboxPermissionNode *newPermissionNode = (SandboxPermissionNode *)ListEntry(newNode, SandboxMountNode, node); 4569570cc8Sopenharmony_ci#ifdef APPSPAWN_CLIENT 4669570cc8Sopenharmony_ci return strcmp(permissionNode->name, newPermissionNode->name); 4769570cc8Sopenharmony_ci#else 4869570cc8Sopenharmony_ci return strcmp(permissionNode->section.name, newPermissionNode->section.name); 4969570cc8Sopenharmony_ci#endif 5069570cc8Sopenharmony_ci} 5169570cc8Sopenharmony_ci 5269570cc8Sopenharmony_ciint AddSandboxPermissionNode(const char *name, SandboxQueue *queue) 5369570cc8Sopenharmony_ci{ 5469570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(name != NULL && queue != NULL, return APPSPAWN_ARG_INVALID); 5569570cc8Sopenharmony_ci APPSPAWN_LOGV("Add permission name %{public}s ", name); 5669570cc8Sopenharmony_ci if (GetPermissionNodeInQueue(queue, name) != NULL) { 5769570cc8Sopenharmony_ci APPSPAWN_LOGW("Permission name %{public}s has been exist", name); 5869570cc8Sopenharmony_ci return 0; 5969570cc8Sopenharmony_ci } 6069570cc8Sopenharmony_ci#ifndef APPSPAWN_CLIENT 6169570cc8Sopenharmony_ci size_t len = sizeof(SandboxPermissionNode); 6269570cc8Sopenharmony_ci SandboxPermissionNode *node = (SandboxPermissionNode *)CreateSandboxSection( 6369570cc8Sopenharmony_ci name, len, SANDBOX_TAG_PERMISSION); 6469570cc8Sopenharmony_ci APPSPAWN_CHECK(node != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to create permission node"); 6569570cc8Sopenharmony_ci node->permissionIndex = 0; 6669570cc8Sopenharmony_ci OH_ListAddWithOrder(&queue->front, &node->section.sandboxNode.node, PermissionNodeCompareProc); 6769570cc8Sopenharmony_ci#else 6869570cc8Sopenharmony_ci size_t len = APPSPAWN_ALIGN(strlen(name) + 1) + sizeof(SandboxPermissionNode); 6969570cc8Sopenharmony_ci SandboxPermissionNode *node = (SandboxPermissionNode *)calloc(1, len); 7069570cc8Sopenharmony_ci APPSPAWN_CHECK(node != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to create permission node"); 7169570cc8Sopenharmony_ci OH_ListInit(&node->sandboxNode.node); 7269570cc8Sopenharmony_ci node->permissionIndex = 0; 7369570cc8Sopenharmony_ci int ret = strcpy_s(node->name, len, name); 7469570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, free(node); 7569570cc8Sopenharmony_ci return APPSPAWN_SYSTEM_ERROR, "Failed to copy name"); 7669570cc8Sopenharmony_ci OH_ListAddWithOrder(&queue->front, &node->sandboxNode.node, PermissionNodeCompareProc); 7769570cc8Sopenharmony_ci#endif 7869570cc8Sopenharmony_ci return 0; 7969570cc8Sopenharmony_ci} 8069570cc8Sopenharmony_ci 8169570cc8Sopenharmony_ciint32_t DeleteSandboxPermissions(SandboxQueue *queue) 8269570cc8Sopenharmony_ci{ 8369570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(queue != NULL, return APPSPAWN_ARG_INVALID); 8469570cc8Sopenharmony_ci ListNode *node = queue->front.next; 8569570cc8Sopenharmony_ci while (node != &queue->front) { 8669570cc8Sopenharmony_ci SandboxMountNode *sandboxNode = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node); 8769570cc8Sopenharmony_ci OH_ListRemove(&sandboxNode->node); 8869570cc8Sopenharmony_ci OH_ListInit(&sandboxNode->node); 8969570cc8Sopenharmony_ci#ifndef APPSPAWN_CLIENT 9069570cc8Sopenharmony_ci DeleteSandboxSection((SandboxSection *)sandboxNode); 9169570cc8Sopenharmony_ci#else 9269570cc8Sopenharmony_ci free(sandboxNode); 9369570cc8Sopenharmony_ci#endif 9469570cc8Sopenharmony_ci // get first 9569570cc8Sopenharmony_ci node = queue->front.next; 9669570cc8Sopenharmony_ci } 9769570cc8Sopenharmony_ci return 0; 9869570cc8Sopenharmony_ci} 9969570cc8Sopenharmony_ci 10069570cc8Sopenharmony_ciint32_t PermissionRenumber(SandboxQueue *queue) 10169570cc8Sopenharmony_ci{ 10269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(queue != NULL, return -1); 10369570cc8Sopenharmony_ci ListNode *node = queue->front.next; 10469570cc8Sopenharmony_ci int index = -1; 10569570cc8Sopenharmony_ci while (node != &queue->front) { 10669570cc8Sopenharmony_ci SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node); 10769570cc8Sopenharmony_ci permissionNode->permissionIndex = ++index; 10869570cc8Sopenharmony_ci#ifdef APPSPAWN_CLIENT 10969570cc8Sopenharmony_ci APPSPAWN_LOGV("Permission index %{public}d name %{public}s", 11069570cc8Sopenharmony_ci permissionNode->permissionIndex, permissionNode->name); 11169570cc8Sopenharmony_ci#else 11269570cc8Sopenharmony_ci APPSPAWN_LOGV("Permission index %{public}d name %{public}s", 11369570cc8Sopenharmony_ci permissionNode->permissionIndex, permissionNode->section.name); 11469570cc8Sopenharmony_ci#endif 11569570cc8Sopenharmony_ci node = node->next; 11669570cc8Sopenharmony_ci } 11769570cc8Sopenharmony_ci return index + 1; 11869570cc8Sopenharmony_ci} 11969570cc8Sopenharmony_ci 12069570cc8Sopenharmony_ciconst SandboxPermissionNode *GetPermissionNodeInQueue(SandboxQueue *queue, const char *permission) 12169570cc8Sopenharmony_ci{ 12269570cc8Sopenharmony_ci if (queue == NULL || permission == NULL) { 12369570cc8Sopenharmony_ci return NULL; 12469570cc8Sopenharmony_ci } 12569570cc8Sopenharmony_ci ListNode *node = OH_ListFind(&queue->front, (void *)permission, PermissionNodeCompareName); 12669570cc8Sopenharmony_ci if (node == NULL) { 12769570cc8Sopenharmony_ci return NULL; 12869570cc8Sopenharmony_ci } 12969570cc8Sopenharmony_ci return (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node); 13069570cc8Sopenharmony_ci} 13169570cc8Sopenharmony_ci 13269570cc8Sopenharmony_ciconst SandboxPermissionNode *GetPermissionNodeInQueueByIndex(SandboxQueue *queue, int32_t index) 13369570cc8Sopenharmony_ci{ 13469570cc8Sopenharmony_ci if (queue == NULL) { 13569570cc8Sopenharmony_ci return NULL; 13669570cc8Sopenharmony_ci } 13769570cc8Sopenharmony_ci ListNode *node = OH_ListFind(&queue->front, (void *)&index, PermissionNodeCompareIndex); 13869570cc8Sopenharmony_ci if (node == NULL) { 13969570cc8Sopenharmony_ci return NULL; 14069570cc8Sopenharmony_ci } 14169570cc8Sopenharmony_ci return (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node); 14269570cc8Sopenharmony_ci} 14369570cc8Sopenharmony_ci 14469570cc8Sopenharmony_ciint32_t GetPermissionIndexInQueue(SandboxQueue *queue, const char *permission) 14569570cc8Sopenharmony_ci{ 14669570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(queue != NULL && permission != NULL, return INVALID_PERMISSION_INDEX); 14769570cc8Sopenharmony_ci const SandboxPermissionNode *permissionNode = GetPermissionNodeInQueue(queue, permission); 14869570cc8Sopenharmony_ci return permissionNode == NULL ? INVALID_PERMISSION_INDEX : permissionNode->permissionIndex; 14969570cc8Sopenharmony_ci}