1/*
2 * Copyright (c) 2020-2022 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 <ohos_errno.h>
17#include <ohos_init.h>
18#include <pthread.h>
19#include <string.h>
20
21#include "feature.h"
22#include "iproxy_client.h"
23#include "iproxy_server.h"
24#include "iunknown.h"
25#include "ipc_skeleton.h"
26#include "log.h"
27
28#include "pms.h"
29#include "pms_common.h"
30#include "pms_types.h"
31#include "samgr_lite.h"
32#include "service.h"
33
34typedef struct PermLiteApi {
35    INHERIT_SERVER_IPROXY;
36    int (*CheckPermission)(int uid, const char *permissionName);
37    int (*QueryPermission)(const char *identifier, PermissionSaved **permissions, int *permNum);
38} PermLiteApi;
39
40typedef struct PermLite {
41    INHERIT_FEATURE;
42    INHERIT_IUNKNOWNENTRY(PermLiteApi);
43    Identity identity;
44} PermLite;
45
46enum FUNCID {
47    ID_CHECK_SELF = 0,
48    ID_QUERY,
49};
50
51static void Init(void);
52static const char *GetName(Feature *feature);
53static void OnInitialize(Feature *feature, Service *parent, Identity identity);
54static void OnStop(Feature *feature, Identity identity);
55static BOOL OnMessage(const Feature *feature, const Request *request);
56static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply);
57
58static PermLite g_permlite = {
59    .GetName = GetName,
60    .OnInitialize = OnInitialize,
61    .OnStop = OnStop,
62    .OnMessage = OnMessage,
63    SERVER_IPROXY_IMPL_BEGIN,
64    .Invoke = Invoke,
65    .CheckPermission = CheckPermissionStat,
66    .QueryPermission = QueryPermission,
67    IPROXY_END,
68    .identity = {-1, -1, NULL},
69};
70
71static void Init(void)
72{
73    SAMGR_GetInstance()->RegisterFeature(PERMISSION_SERVICE, (Feature *)&g_permlite);
74    SAMGR_GetInstance()->RegisterFeatureApi(PERMISSION_SERVICE, PERM_FEATURE, GET_IUNKNOWN(g_permlite));
75    HILOG_INFO(HILOG_MODULE_APP, "Init pms lite feature success");
76}
77APP_FEATURE_INIT(Init);
78
79static const char *GetName(Feature *feature)
80{
81    (void)feature;
82    return PERM_FEATURE;
83}
84
85static void OnInitialize(Feature *feature, Service *parent, Identity identity)
86{
87    (void)parent;
88    if (feature == NULL) {
89        return;
90    }
91    PermLite *permlite = (PermLite *)feature;
92    permlite->identity = identity;
93    HILOG_INFO(HILOG_MODULE_APP, "onInitialize pms lite feature");
94}
95
96static void OnStop(Feature *feature, Identity identity)
97{
98    (void)feature;
99    (void)identity;
100}
101
102static BOOL OnMessage(const Feature *feature, const Request *request)
103{
104    if (feature == NULL || request == NULL) {
105        return FALSE;
106    }
107    // call func
108    return TRUE;
109}
110
111static void ReplyCheckSelfPermission(const void *origin, IpcIo *req, IpcIo *reply, PermLiteApi* api)
112{
113    pid_t callingPid = GetCallingPid();
114    uid_t callingUid = GetCallingUid();
115    HILOG_INFO(HILOG_MODULE_APP, "Enter ID_CHECKSELF, [callerPid: %d][callerUid: %u]", callingPid, callingUid);
116
117    size_t permLen = 0;
118    char *permName = (char *)ReadString(req, &permLen);
119    int32_t ret = api->CheckPermission(callingUid, permName);
120    HILOG_INFO(HILOG_MODULE_APP, "check self permission, [uid: %u][perm: %s][ret: %d]", callingUid, permName, ret);
121    WriteInt32(reply, ret);
122}
123
124static void ReplyQueryPermission(const void *origin, IpcIo *req, IpcIo *reply)
125{
126    pid_t callingPid = GetCallingPid();
127    uid_t callingUid = GetCallingUid();
128    HILOG_INFO(HILOG_MODULE_APP, "Enter ID_Query, [callerPid: %d][callerUid: %u]", callingPid, callingUid);
129    size_t idLen = 0;
130    int ret = 0;
131    char *identifier = (char *)ReadString(req, &idLen);
132    char *jsonStr = QueryPermissionString(identifier, &ret);
133    if (jsonStr == NULL) {
134        return;
135    }
136
137    WriteInt32(reply, ret);
138    if (ret != PERM_ERRORCODE_SUCCESS) {
139        free(jsonStr);
140        return;
141    }
142    WriteString(reply, jsonStr);
143    free(jsonStr);
144}
145
146static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
147{
148    PermLiteApi *api = (PermLiteApi *)iProxy;
149    switch (funcId) {
150        case ID_CHECK_SELF:
151            ReplyCheckSelfPermission(origin, req, reply, api);
152            break;
153        case ID_QUERY:
154            ReplyQueryPermission(origin, req, reply);
155            break;
156        default:
157            break;
158    }
159    return EC_SUCCESS;
160}
161