1fc0b0055Sopenharmony_ci/*
2fc0b0055Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3fc0b0055Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fc0b0055Sopenharmony_ci * you may not use this file except in compliance with the License.
5fc0b0055Sopenharmony_ci * You may obtain a copy of the License at
6fc0b0055Sopenharmony_ci *
7fc0b0055Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fc0b0055Sopenharmony_ci *
9fc0b0055Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fc0b0055Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fc0b0055Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fc0b0055Sopenharmony_ci * See the License for the specific language governing permissions and
13fc0b0055Sopenharmony_ci * limitations under the License.
14fc0b0055Sopenharmony_ci */
15fc0b0055Sopenharmony_ci
16fc0b0055Sopenharmony_ci#include "atm_command.h"
17fc0b0055Sopenharmony_ci
18fc0b0055Sopenharmony_ci#include <getopt.h>
19fc0b0055Sopenharmony_ci#include <string>
20fc0b0055Sopenharmony_ci
21fc0b0055Sopenharmony_ci#include "access_token_error.h"
22fc0b0055Sopenharmony_ci#include "accesstoken_kit.h"
23fc0b0055Sopenharmony_ci#include "privacy_kit.h"
24fc0b0055Sopenharmony_ci#include "to_string.h"
25fc0b0055Sopenharmony_ci
26fc0b0055Sopenharmony_cinamespace OHOS {
27fc0b0055Sopenharmony_cinamespace Security {
28fc0b0055Sopenharmony_cinamespace AccessToken {
29fc0b0055Sopenharmony_cinamespace {
30fc0b0055Sopenharmony_cistatic constexpr int32_t MIN_ARGUMENT_NUMBER = 2;
31fc0b0055Sopenharmony_cistatic constexpr int32_t MAX_ARGUMENT_NUMBER = 4096;
32fc0b0055Sopenharmony_cistatic const std::string HELP_MSG_NO_OPTION = "error: you must specify an option at least.\n";
33fc0b0055Sopenharmony_cistatic const std::string SHORT_OPTIONS_DUMP = "h::t::r::v::i:p:b:n:";
34fc0b0055Sopenharmony_cistatic const std::string TOOLS_NAME = "atm";
35fc0b0055Sopenharmony_cistatic const std::string HELP_MSG =
36fc0b0055Sopenharmony_ci    "usage: atm <command> <option>\n"
37fc0b0055Sopenharmony_ci    "These are common atm commands list:\n"
38fc0b0055Sopenharmony_ci    "  help    list available commands\n"
39fc0b0055Sopenharmony_ci#ifndef ATM_BUILD_VARIANT_USER_ENABLE
40fc0b0055Sopenharmony_ci    "  perm    grant/cancel permission\n"
41fc0b0055Sopenharmony_ci    "  toggle  set/get toggle status\n"
42fc0b0055Sopenharmony_ci#endif
43fc0b0055Sopenharmony_ci    "  dump    dump system command\n";
44fc0b0055Sopenharmony_ci
45fc0b0055Sopenharmony_cistatic const std::string HELP_MSG_DUMP =
46fc0b0055Sopenharmony_ci    "usage: atm dump <option>.\n"
47fc0b0055Sopenharmony_ci    "options list:\n"
48fc0b0055Sopenharmony_ci    "  -h, --help                                               list available options\n"
49fc0b0055Sopenharmony_ci    "  -t, --all                                                list all name of token info in system\n"
50fc0b0055Sopenharmony_ci    "  -t, --token-info -i <token-id>                           list single token info by specific tokenId\n"
51fc0b0055Sopenharmony_ci    "  -t, --token-info -b <bundle-name>                        list all token info by specific bundleName\n"
52fc0b0055Sopenharmony_ci    "  -t, --token-info -n <process-name>                       list single token info by specific native processName\n"
53fc0b0055Sopenharmony_ci#ifndef ATM_BUILD_VARIANT_USER_ENABLE
54fc0b0055Sopenharmony_ci    "  -r, --record-info [-i <token-id>] [-p <permission-name>] list used records in system\n"
55fc0b0055Sopenharmony_ci#endif
56fc0b0055Sopenharmony_ci    "  -v, --visit-type [-i <token-id>] [-p <permission-name>]  list all token used type in system\n";
57fc0b0055Sopenharmony_ci
58fc0b0055Sopenharmony_cistatic const std::string HELP_MSG_PERM =
59fc0b0055Sopenharmony_ci#ifndef ATM_BUILD_VARIANT_USER_ENABLE
60fc0b0055Sopenharmony_ci    "usage: atm perm <option>.\n"
61fc0b0055Sopenharmony_ci    "options list:\n"
62fc0b0055Sopenharmony_ci    "  -h, --help                                       list available options\n"
63fc0b0055Sopenharmony_ci    "  -g, --grant -i <token-id> -p <permission-name>   grant a permission by a specified token-id\n"
64fc0b0055Sopenharmony_ci    "  -c, --cancel -i <token-id> -p <permission-name>  cancel a permission by a specified token-id\n";
65fc0b0055Sopenharmony_ci#else
66fc0b0055Sopenharmony_ci    "";
67fc0b0055Sopenharmony_ci#endif
68fc0b0055Sopenharmony_ci
69fc0b0055Sopenharmony_cistatic const std::string HELP_MSG_TOGGLE =
70fc0b0055Sopenharmony_ci#ifndef ATM_BUILD_VARIANT_USER_ENABLE
71fc0b0055Sopenharmony_ci    "usage: atm toggle <option>.\n"
72fc0b0055Sopenharmony_ci    "options list:\n"
73fc0b0055Sopenharmony_ci    "  -h, --help                                               list available options\n"
74fc0b0055Sopenharmony_ci    "  -s, --set -u <user-id> -p <permission-name> -k <status>  set the status by a specified user-id and permission\n"
75fc0b0055Sopenharmony_ci    "  -o, --get -u <user-id> -p <permission-name>              get the status by a specified user-id and permission\n";
76fc0b0055Sopenharmony_ci#else
77fc0b0055Sopenharmony_ci    "";
78fc0b0055Sopenharmony_ci#endif
79fc0b0055Sopenharmony_ci
80fc0b0055Sopenharmony_cistatic const struct option LONG_OPTIONS_DUMP[] = {
81fc0b0055Sopenharmony_ci    {"help", no_argument, nullptr, 'h'},
82fc0b0055Sopenharmony_ci    {"token-info", no_argument, nullptr, 't'},
83fc0b0055Sopenharmony_ci    {"record-info", no_argument, nullptr, 'r'},
84fc0b0055Sopenharmony_ci    {"token-id", required_argument, nullptr, 'i'},
85fc0b0055Sopenharmony_ci    {"permission-name", required_argument, nullptr, 'p'},
86fc0b0055Sopenharmony_ci    {"bundle-name", required_argument, nullptr, 'b'},
87fc0b0055Sopenharmony_ci    {"process-name", required_argument, nullptr, 'n'},
88fc0b0055Sopenharmony_ci    {nullptr, 0, nullptr, 0}
89fc0b0055Sopenharmony_ci};
90fc0b0055Sopenharmony_ci
91fc0b0055Sopenharmony_cistatic const std::string SHORT_OPTIONS_PERM = "hg::c::i:p:";
92fc0b0055Sopenharmony_cistatic const struct option LONG_OPTIONS_PERM[] = {
93fc0b0055Sopenharmony_ci    {"help", no_argument, nullptr, 'h'},
94fc0b0055Sopenharmony_ci    {"grant", no_argument, nullptr, 'g'},
95fc0b0055Sopenharmony_ci    {"cancel", no_argument, nullptr, 'c'},
96fc0b0055Sopenharmony_ci    {"token-id", required_argument, nullptr, 'i'},
97fc0b0055Sopenharmony_ci    {"permission-name", required_argument, nullptr, 'p'},
98fc0b0055Sopenharmony_ci    {nullptr, 0, nullptr, 0}
99fc0b0055Sopenharmony_ci};
100fc0b0055Sopenharmony_ci
101fc0b0055Sopenharmony_cistatic const std::string SHORT_OPTIONS_TOGGLE = "hs::o::u:p:k:";
102fc0b0055Sopenharmony_cistatic const struct option LONG_OPTIONS_TOGGLE[] = {
103fc0b0055Sopenharmony_ci    {"help", no_argument, nullptr, 'h'},
104fc0b0055Sopenharmony_ci    {"set", no_argument, nullptr, 's'},
105fc0b0055Sopenharmony_ci    {"get", no_argument, nullptr, 'o'},
106fc0b0055Sopenharmony_ci    {"user-id", required_argument, nullptr, 'u'},
107fc0b0055Sopenharmony_ci    {"permission-name", required_argument, nullptr, 'p'},
108fc0b0055Sopenharmony_ci    {"status", required_argument, nullptr, 'k'},
109fc0b0055Sopenharmony_ci    {nullptr, 0, nullptr, 0}
110fc0b0055Sopenharmony_ci};
111fc0b0055Sopenharmony_ci
112fc0b0055Sopenharmony_cistd::map<char, OptType> COMMAND_TYPE = {
113fc0b0055Sopenharmony_ci    {'t', DUMP_TOKEN},
114fc0b0055Sopenharmony_ci    {'r', DUMP_RECORD},
115fc0b0055Sopenharmony_ci    {'v', DUMP_TYPE},
116fc0b0055Sopenharmony_ci    {'g', PERM_GRANT},
117fc0b0055Sopenharmony_ci    {'c', PERM_REVOKE},
118fc0b0055Sopenharmony_ci    {'s', TOGGLE_SET},
119fc0b0055Sopenharmony_ci    {'o', TOGGLE_GET},
120fc0b0055Sopenharmony_ci};
121fc0b0055Sopenharmony_ci}
122fc0b0055Sopenharmony_ci
123fc0b0055Sopenharmony_ciAtmCommand::AtmCommand(int32_t argc, char *argv[]) : argc_(argc), argv_(argv), name_(TOOLS_NAME)
124fc0b0055Sopenharmony_ci{
125fc0b0055Sopenharmony_ci    opterr = 0;
126fc0b0055Sopenharmony_ci
127fc0b0055Sopenharmony_ci    commandMap_ = {
128fc0b0055Sopenharmony_ci        {"help", [this](){return RunAsHelpCommand();}},
129fc0b0055Sopenharmony_ci        {"dump", [this]() {return RunAsCommonCommand();}},
130fc0b0055Sopenharmony_ci        {"perm", [this]() {return RunAsCommonCommand();}},
131fc0b0055Sopenharmony_ci        {"toggle", [this]() {return RunAsCommonCommand();}},
132fc0b0055Sopenharmony_ci    };
133fc0b0055Sopenharmony_ci
134fc0b0055Sopenharmony_ci    if ((argc < MIN_ARGUMENT_NUMBER) || (argc > MAX_ARGUMENT_NUMBER)) {
135fc0b0055Sopenharmony_ci        cmd_ = "help";
136fc0b0055Sopenharmony_ci
137fc0b0055Sopenharmony_ci        return;
138fc0b0055Sopenharmony_ci    }
139fc0b0055Sopenharmony_ci
140fc0b0055Sopenharmony_ci    cmd_ = argv[1];
141fc0b0055Sopenharmony_ci
142fc0b0055Sopenharmony_ci    for (int32_t i = 2; i < argc; i++) {
143fc0b0055Sopenharmony_ci        argList_.push_back(argv[i]);
144fc0b0055Sopenharmony_ci    }
145fc0b0055Sopenharmony_ci}
146fc0b0055Sopenharmony_ci
147fc0b0055Sopenharmony_cistd::string AtmCommand::GetCommandErrorMsg() const
148fc0b0055Sopenharmony_ci{
149fc0b0055Sopenharmony_ci    std::string commandErrorMsg =
150fc0b0055Sopenharmony_ci        name_ + ": '" + cmd_ + "' is not a valid " + name_ + " command. See '" + name_ + " help'.\n";
151fc0b0055Sopenharmony_ci
152fc0b0055Sopenharmony_ci    return commandErrorMsg;
153fc0b0055Sopenharmony_ci}
154fc0b0055Sopenharmony_ci
155fc0b0055Sopenharmony_cistd::string AtmCommand::ExecCommand()
156fc0b0055Sopenharmony_ci{
157fc0b0055Sopenharmony_ci    auto respond = commandMap_[cmd_];
158fc0b0055Sopenharmony_ci    if (respond == nullptr) {
159fc0b0055Sopenharmony_ci        resultReceiver_.append(GetCommandErrorMsg());
160fc0b0055Sopenharmony_ci    } else {
161fc0b0055Sopenharmony_ci        respond();
162fc0b0055Sopenharmony_ci    }
163fc0b0055Sopenharmony_ci
164fc0b0055Sopenharmony_ci    return resultReceiver_;
165fc0b0055Sopenharmony_ci}
166fc0b0055Sopenharmony_ci
167fc0b0055Sopenharmony_ciint32_t AtmCommand::RunAsHelpCommand()
168fc0b0055Sopenharmony_ci{
169fc0b0055Sopenharmony_ci    resultReceiver_.append(HELP_MSG);
170fc0b0055Sopenharmony_ci
171fc0b0055Sopenharmony_ci    return RET_SUCCESS;
172fc0b0055Sopenharmony_ci}
173fc0b0055Sopenharmony_ci
174fc0b0055Sopenharmony_ciint32_t AtmCommand::RunAsCommandError(void)
175fc0b0055Sopenharmony_ci{
176fc0b0055Sopenharmony_ci    int32_t result = RET_SUCCESS;
177fc0b0055Sopenharmony_ci
178fc0b0055Sopenharmony_ci    if ((optind < 0) || (optind >= argc_)) {
179fc0b0055Sopenharmony_ci        return ERR_INVALID_VALUE;
180fc0b0055Sopenharmony_ci    }
181fc0b0055Sopenharmony_ci
182fc0b0055Sopenharmony_ci    // When scanning the first argument
183fc0b0055Sopenharmony_ci    if (strcmp(argv_[optind], cmd_.c_str()) == 0) {
184fc0b0055Sopenharmony_ci        // 'atm dump' with no option: atm dump
185fc0b0055Sopenharmony_ci        // 'atm dump' with a wrong argument: atm dump xxx
186fc0b0055Sopenharmony_ci
187fc0b0055Sopenharmony_ci        resultReceiver_.append(HELP_MSG_NO_OPTION + "\n");
188fc0b0055Sopenharmony_ci        result = ERR_INVALID_VALUE;
189fc0b0055Sopenharmony_ci    }
190fc0b0055Sopenharmony_ci    return result;
191fc0b0055Sopenharmony_ci}
192fc0b0055Sopenharmony_ci
193fc0b0055Sopenharmony_cistd::string AtmCommand::GetUnknownOptionMsg() const
194fc0b0055Sopenharmony_ci{
195fc0b0055Sopenharmony_ci    std::string result;
196fc0b0055Sopenharmony_ci
197fc0b0055Sopenharmony_ci    if ((optind < 0) || (optind > argc_)) {
198fc0b0055Sopenharmony_ci        return result;
199fc0b0055Sopenharmony_ci    }
200fc0b0055Sopenharmony_ci
201fc0b0055Sopenharmony_ci    result.append("error: unknown option\n.");
202fc0b0055Sopenharmony_ci
203fc0b0055Sopenharmony_ci    return result;
204fc0b0055Sopenharmony_ci}
205fc0b0055Sopenharmony_ci
206fc0b0055Sopenharmony_ciint32_t AtmCommand::RunAsCommandMissingOptionArgument(void)
207fc0b0055Sopenharmony_ci{
208fc0b0055Sopenharmony_ci    int32_t result = RET_SUCCESS;
209fc0b0055Sopenharmony_ci    switch (optopt) {
210fc0b0055Sopenharmony_ci        case 'h':
211fc0b0055Sopenharmony_ci            // 'atm dump -h'
212fc0b0055Sopenharmony_ci            result = ERR_INVALID_VALUE;
213fc0b0055Sopenharmony_ci            break;
214fc0b0055Sopenharmony_ci        case 'i':
215fc0b0055Sopenharmony_ci        case 'p':
216fc0b0055Sopenharmony_ci        case 'g':
217fc0b0055Sopenharmony_ci        case 'c':
218fc0b0055Sopenharmony_ci            resultReceiver_.append("error: option ");
219fc0b0055Sopenharmony_ci            resultReceiver_.append("requires a value.\n");
220fc0b0055Sopenharmony_ci            result = ERR_INVALID_VALUE;
221fc0b0055Sopenharmony_ci            break;
222fc0b0055Sopenharmony_ci        default: {
223fc0b0055Sopenharmony_ci            std::string unknownOptionMsg = GetUnknownOptionMsg();
224fc0b0055Sopenharmony_ci
225fc0b0055Sopenharmony_ci            resultReceiver_.append(unknownOptionMsg);
226fc0b0055Sopenharmony_ci            result = ERR_INVALID_VALUE;
227fc0b0055Sopenharmony_ci            break;
228fc0b0055Sopenharmony_ci        }
229fc0b0055Sopenharmony_ci    }
230fc0b0055Sopenharmony_ci    return result;
231fc0b0055Sopenharmony_ci}
232fc0b0055Sopenharmony_ci
233fc0b0055Sopenharmony_civoid AtmCommand::RunAsCommandExistentOptionArgument(const int32_t& option, AtmToolsParamInfo& info)
234fc0b0055Sopenharmony_ci{
235fc0b0055Sopenharmony_ci    switch (option) {
236fc0b0055Sopenharmony_ci        case 't':
237fc0b0055Sopenharmony_ci        case 'r':
238fc0b0055Sopenharmony_ci        case 'v':
239fc0b0055Sopenharmony_ci        case 'g':
240fc0b0055Sopenharmony_ci        case 'c':
241fc0b0055Sopenharmony_ci        case 's':
242fc0b0055Sopenharmony_ci        case 'o':
243fc0b0055Sopenharmony_ci            info.type = COMMAND_TYPE[option];
244fc0b0055Sopenharmony_ci            break;
245fc0b0055Sopenharmony_ci        case 'i':
246fc0b0055Sopenharmony_ci            if (optarg != nullptr) {
247fc0b0055Sopenharmony_ci                info.tokenId = static_cast<AccessTokenID>(std::atoi(optarg));
248fc0b0055Sopenharmony_ci            }
249fc0b0055Sopenharmony_ci            break;
250fc0b0055Sopenharmony_ci        case 'p':
251fc0b0055Sopenharmony_ci            if (optarg != nullptr) {
252fc0b0055Sopenharmony_ci                info.permissionName = optarg;
253fc0b0055Sopenharmony_ci            }
254fc0b0055Sopenharmony_ci            break;
255fc0b0055Sopenharmony_ci        case 'b':
256fc0b0055Sopenharmony_ci            if (optarg != nullptr) {
257fc0b0055Sopenharmony_ci                info.bundleName = optarg;
258fc0b0055Sopenharmony_ci            }
259fc0b0055Sopenharmony_ci            break;
260fc0b0055Sopenharmony_ci        case 'n':
261fc0b0055Sopenharmony_ci            if (optarg != nullptr) {
262fc0b0055Sopenharmony_ci                info.processName = optarg;
263fc0b0055Sopenharmony_ci            }
264fc0b0055Sopenharmony_ci            break;
265fc0b0055Sopenharmony_ci        case 'u':
266fc0b0055Sopenharmony_ci            if (optarg != nullptr) {
267fc0b0055Sopenharmony_ci                info.userID = static_cast<int32_t>(std::atoi(optarg));
268fc0b0055Sopenharmony_ci            }
269fc0b0055Sopenharmony_ci            break;
270fc0b0055Sopenharmony_ci        case 'k':
271fc0b0055Sopenharmony_ci            if (optarg != nullptr) {
272fc0b0055Sopenharmony_ci                info.status = static_cast<uint32_t>(std::atoi(optarg));
273fc0b0055Sopenharmony_ci            }
274fc0b0055Sopenharmony_ci            break;
275fc0b0055Sopenharmony_ci        default:
276fc0b0055Sopenharmony_ci            break;
277fc0b0055Sopenharmony_ci    }
278fc0b0055Sopenharmony_ci}
279fc0b0055Sopenharmony_ci
280fc0b0055Sopenharmony_cistd::string AtmCommand::DumpRecordInfo(uint32_t tokenId, const std::string& permissionName)
281fc0b0055Sopenharmony_ci{
282fc0b0055Sopenharmony_ci    PermissionUsedRequest request;
283fc0b0055Sopenharmony_ci    request.tokenId = tokenId;
284fc0b0055Sopenharmony_ci    request.flag = FLAG_PERMISSION_USAGE_DETAIL;
285fc0b0055Sopenharmony_ci    if (!permissionName.empty()) {
286fc0b0055Sopenharmony_ci        request.permissionList.emplace_back(permissionName);
287fc0b0055Sopenharmony_ci    }
288fc0b0055Sopenharmony_ci
289fc0b0055Sopenharmony_ci    PermissionUsedResult result;
290fc0b0055Sopenharmony_ci    if (PrivacyKit::GetPermissionUsedRecords(request, result) != 0) {
291fc0b0055Sopenharmony_ci        return "";
292fc0b0055Sopenharmony_ci    }
293fc0b0055Sopenharmony_ci
294fc0b0055Sopenharmony_ci    std::string dumpInfo;
295fc0b0055Sopenharmony_ci    ToString::PermissionUsedResultToString(result, dumpInfo);
296fc0b0055Sopenharmony_ci    return dumpInfo;
297fc0b0055Sopenharmony_ci}
298fc0b0055Sopenharmony_ci
299fc0b0055Sopenharmony_cistd::string AtmCommand::DumpUsedTypeInfo(uint32_t tokenId, const std::string& permissionName)
300fc0b0055Sopenharmony_ci{
301fc0b0055Sopenharmony_ci    std::vector<PermissionUsedTypeInfo> results;
302fc0b0055Sopenharmony_ci    if (PrivacyKit::GetPermissionUsedTypeInfos(tokenId, permissionName, results) != 0) {
303fc0b0055Sopenharmony_ci        return "";
304fc0b0055Sopenharmony_ci    }
305fc0b0055Sopenharmony_ci
306fc0b0055Sopenharmony_ci    std::string dumpInfo;
307fc0b0055Sopenharmony_ci    for (const auto& result : results) {
308fc0b0055Sopenharmony_ci        ToString::PermissionUsedTypeInfoToString(result, dumpInfo);
309fc0b0055Sopenharmony_ci    }
310fc0b0055Sopenharmony_ci
311fc0b0055Sopenharmony_ci    return dumpInfo;
312fc0b0055Sopenharmony_ci}
313fc0b0055Sopenharmony_ci
314fc0b0055Sopenharmony_ciint32_t AtmCommand::ModifyPermission(const OptType& type, AccessTokenID tokenId, const std::string& permissionName)
315fc0b0055Sopenharmony_ci{
316fc0b0055Sopenharmony_ci    if ((tokenId == 0) || (permissionName.empty())) {
317fc0b0055Sopenharmony_ci        return ERR_INVALID_VALUE;
318fc0b0055Sopenharmony_ci    }
319fc0b0055Sopenharmony_ci
320fc0b0055Sopenharmony_ci    int32_t result = 0;
321fc0b0055Sopenharmony_ci    if (type == PERM_GRANT) {
322fc0b0055Sopenharmony_ci        result = AccessTokenKit::GrantPermission(tokenId, permissionName, PERMISSION_USER_FIXED);
323fc0b0055Sopenharmony_ci    } else if (type == PERM_REVOKE) {
324fc0b0055Sopenharmony_ci        result = AccessTokenKit::RevokePermission(tokenId, permissionName, PERMISSION_USER_FIXED);
325fc0b0055Sopenharmony_ci    } else {
326fc0b0055Sopenharmony_ci        return ERR_INVALID_VALUE;
327fc0b0055Sopenharmony_ci    }
328fc0b0055Sopenharmony_ci    return result;
329fc0b0055Sopenharmony_ci}
330fc0b0055Sopenharmony_ci
331fc0b0055Sopenharmony_ciint32_t AtmCommand::SetToggleStatus(int32_t userID, const std::string& permissionName, const uint32_t& status)
332fc0b0055Sopenharmony_ci{
333fc0b0055Sopenharmony_ci    if ((userID < 0) || (permissionName.empty()) ||
334fc0b0055Sopenharmony_ci        ((status != PermissionRequestToggleStatus::OPEN) &&
335fc0b0055Sopenharmony_ci         (status != PermissionRequestToggleStatus::CLOSED))) {
336fc0b0055Sopenharmony_ci        return ERR_INVALID_VALUE;
337fc0b0055Sopenharmony_ci    }
338fc0b0055Sopenharmony_ci
339fc0b0055Sopenharmony_ci    return AccessTokenKit::SetPermissionRequestToggleStatus(permissionName, status, userID);
340fc0b0055Sopenharmony_ci}
341fc0b0055Sopenharmony_ci
342fc0b0055Sopenharmony_ciint32_t AtmCommand::GetToggleStatus(int32_t userID, const std::string& permissionName, std::string& statusInfo)
343fc0b0055Sopenharmony_ci{
344fc0b0055Sopenharmony_ci    if ((userID < 0) || (permissionName.empty())) {
345fc0b0055Sopenharmony_ci        return ERR_INVALID_VALUE;
346fc0b0055Sopenharmony_ci    }
347fc0b0055Sopenharmony_ci
348fc0b0055Sopenharmony_ci    uint32_t status;
349fc0b0055Sopenharmony_ci    int32_t result = AccessTokenKit::GetPermissionRequestToggleStatus(permissionName, status, userID);
350fc0b0055Sopenharmony_ci    if (result != RET_SUCCESS) {
351fc0b0055Sopenharmony_ci        return result;
352fc0b0055Sopenharmony_ci    }
353fc0b0055Sopenharmony_ci
354fc0b0055Sopenharmony_ci    if (status == PermissionRequestToggleStatus::OPEN) {
355fc0b0055Sopenharmony_ci        statusInfo = "Toggle status is open";
356fc0b0055Sopenharmony_ci    } else {
357fc0b0055Sopenharmony_ci        statusInfo = "Toggle status is closed";
358fc0b0055Sopenharmony_ci    }
359fc0b0055Sopenharmony_ci
360fc0b0055Sopenharmony_ci    return result;
361fc0b0055Sopenharmony_ci}
362fc0b0055Sopenharmony_ci
363fc0b0055Sopenharmony_ciint32_t AtmCommand::RunCommandByOperationType(const AtmToolsParamInfo& info)
364fc0b0055Sopenharmony_ci{
365fc0b0055Sopenharmony_ci    std::string dumpInfo;
366fc0b0055Sopenharmony_ci    int32_t ret = RET_SUCCESS;
367fc0b0055Sopenharmony_ci    switch (info.type) {
368fc0b0055Sopenharmony_ci        case DUMP_TOKEN:
369fc0b0055Sopenharmony_ci            AccessTokenKit::DumpTokenInfo(info, dumpInfo);
370fc0b0055Sopenharmony_ci            break;
371fc0b0055Sopenharmony_ci        case DUMP_RECORD:
372fc0b0055Sopenharmony_ci#ifndef ATM_BUILD_VARIANT_USER_ENABLE
373fc0b0055Sopenharmony_ci            dumpInfo = DumpRecordInfo(info.tokenId, info.permissionName);
374fc0b0055Sopenharmony_ci#endif
375fc0b0055Sopenharmony_ci            break;
376fc0b0055Sopenharmony_ci        case DUMP_TYPE:
377fc0b0055Sopenharmony_ci            dumpInfo = DumpUsedTypeInfo(info.tokenId, info.permissionName);
378fc0b0055Sopenharmony_ci            break;
379fc0b0055Sopenharmony_ci        case PERM_GRANT:
380fc0b0055Sopenharmony_ci        case PERM_REVOKE:
381fc0b0055Sopenharmony_ci#ifndef ATM_BUILD_VARIANT_USER_ENABLE
382fc0b0055Sopenharmony_ci            ret = ModifyPermission(info.type, info.tokenId, info.permissionName);
383fc0b0055Sopenharmony_ci            dumpInfo = (ret == RET_SUCCESS) ? "Success" : "Failure";
384fc0b0055Sopenharmony_ci#endif
385fc0b0055Sopenharmony_ci            break;
386fc0b0055Sopenharmony_ci        case TOGGLE_SET:
387fc0b0055Sopenharmony_ci#ifndef ATM_BUILD_VARIANT_USER_ENABLE
388fc0b0055Sopenharmony_ci            ret = SetToggleStatus(info.userID, info.permissionName, info.status);
389fc0b0055Sopenharmony_ci            dumpInfo = (ret == RET_SUCCESS) ? "Success" : "Failure";
390fc0b0055Sopenharmony_ci#endif
391fc0b0055Sopenharmony_ci            break;
392fc0b0055Sopenharmony_ci        case TOGGLE_GET:
393fc0b0055Sopenharmony_ci#ifndef ATM_BUILD_VARIANT_USER_ENABLE
394fc0b0055Sopenharmony_ci            ret = GetToggleStatus(info.userID, info.permissionName, dumpInfo);
395fc0b0055Sopenharmony_ci            if (ret != RET_SUCCESS) {
396fc0b0055Sopenharmony_ci                dumpInfo = "Failure.";
397fc0b0055Sopenharmony_ci            }
398fc0b0055Sopenharmony_ci#endif
399fc0b0055Sopenharmony_ci            break;
400fc0b0055Sopenharmony_ci        default:
401fc0b0055Sopenharmony_ci            resultReceiver_.append("error: miss option \n");
402fc0b0055Sopenharmony_ci            return ERR_INVALID_VALUE;
403fc0b0055Sopenharmony_ci    }
404fc0b0055Sopenharmony_ci    resultReceiver_.append(dumpInfo + "\n");
405fc0b0055Sopenharmony_ci    return ret;
406fc0b0055Sopenharmony_ci}
407fc0b0055Sopenharmony_ci
408fc0b0055Sopenharmony_ciint32_t AtmCommand::HandleComplexCommand(const std::string& shortOption, const struct option longOption[],
409fc0b0055Sopenharmony_ci    const std::string& helpMsg)
410fc0b0055Sopenharmony_ci{
411fc0b0055Sopenharmony_ci    int32_t result = RET_SUCCESS;
412fc0b0055Sopenharmony_ci    AtmToolsParamInfo info;
413fc0b0055Sopenharmony_ci    int32_t counter = 0;
414fc0b0055Sopenharmony_ci
415fc0b0055Sopenharmony_ci    while (true) {
416fc0b0055Sopenharmony_ci        counter++;
417fc0b0055Sopenharmony_ci        int32_t option = getopt_long(argc_, argv_, shortOption.c_str(), longOption, nullptr);
418fc0b0055Sopenharmony_ci        if ((optind < 0) || (optind > argc_)) {
419fc0b0055Sopenharmony_ci            return ERR_INVALID_VALUE;
420fc0b0055Sopenharmony_ci        }
421fc0b0055Sopenharmony_ci
422fc0b0055Sopenharmony_ci        if (option == -1) {
423fc0b0055Sopenharmony_ci            if (counter == 1) {
424fc0b0055Sopenharmony_ci                result = RunAsCommandError();
425fc0b0055Sopenharmony_ci            }
426fc0b0055Sopenharmony_ci            break;
427fc0b0055Sopenharmony_ci        }
428fc0b0055Sopenharmony_ci
429fc0b0055Sopenharmony_ci        if (option == '?') {
430fc0b0055Sopenharmony_ci            result = RunAsCommandMissingOptionArgument();
431fc0b0055Sopenharmony_ci            break;
432fc0b0055Sopenharmony_ci        }
433fc0b0055Sopenharmony_ci
434fc0b0055Sopenharmony_ci        if (option == 'h') {
435fc0b0055Sopenharmony_ci            // 'atm dump -h'
436fc0b0055Sopenharmony_ci            result = ERR_INVALID_VALUE;
437fc0b0055Sopenharmony_ci            continue;
438fc0b0055Sopenharmony_ci        }
439fc0b0055Sopenharmony_ci        RunAsCommandExistentOptionArgument(option, info);
440fc0b0055Sopenharmony_ci    }
441fc0b0055Sopenharmony_ci
442fc0b0055Sopenharmony_ci    if (result != RET_SUCCESS) {
443fc0b0055Sopenharmony_ci        resultReceiver_.append(helpMsg + "\n");
444fc0b0055Sopenharmony_ci    } else {
445fc0b0055Sopenharmony_ci        result = RunCommandByOperationType(info);
446fc0b0055Sopenharmony_ci    }
447fc0b0055Sopenharmony_ci    return result;
448fc0b0055Sopenharmony_ci}
449fc0b0055Sopenharmony_ci
450fc0b0055Sopenharmony_ciint32_t AtmCommand::RunAsCommonCommand()
451fc0b0055Sopenharmony_ci{
452fc0b0055Sopenharmony_ci    if (cmd_ == "dump") {
453fc0b0055Sopenharmony_ci        return HandleComplexCommand(SHORT_OPTIONS_DUMP, LONG_OPTIONS_DUMP, HELP_MSG_DUMP);
454fc0b0055Sopenharmony_ci    } else if (cmd_ == "perm") {
455fc0b0055Sopenharmony_ci        return HandleComplexCommand(SHORT_OPTIONS_PERM, LONG_OPTIONS_PERM, HELP_MSG_PERM);
456fc0b0055Sopenharmony_ci    } else if (cmd_ == "toggle") {
457fc0b0055Sopenharmony_ci        return HandleComplexCommand(SHORT_OPTIONS_TOGGLE, LONG_OPTIONS_TOGGLE, HELP_MSG_TOGGLE);
458fc0b0055Sopenharmony_ci    }
459fc0b0055Sopenharmony_ci
460fc0b0055Sopenharmony_ci    return ERR_PARAM_INVALID;
461fc0b0055Sopenharmony_ci}
462fc0b0055Sopenharmony_ci} // namespace AccessToken
463fc0b0055Sopenharmony_ci} // namespace Security
464fc0b0055Sopenharmony_ci} // namespace OHOS
465