1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <iostream>
18 #include <memory>
19 #include <string>
20 
21 #include "./command-line.h"
22 #include "./context.h"
23 #include "./execute.h"
24 
main(const int argc,char * const argv[])25 int main(const int argc, char* const argv[]) {
26   bool verbose = false;
27   auto context = std::make_unique<shell_as::SecurityContext>();
28   char* const* execute_arguments = nullptr;
29   if (!shell_as::ParseOptions(argc, argv, &verbose, context.get(),
30                               &execute_arguments)) {
31     return 1;
32   }
33 
34   if (verbose) {
35     std::cerr << "Dropping privileges to:" << std::endl;
36     std::cerr << "\tuser ID = "
37               << (context->user_id.has_value()
38                       ? std::to_string(context->user_id.value())
39                       : "<no value>")
40               << std::endl;
41 
42     std::cerr << "\tgroup ID = "
43               << (context->group_id.has_value()
44                       ? std::to_string(context->group_id.value())
45                       : "<no value>")
46               << std::endl;
47 
48     std::cerr << "\tsupplementary group IDs = ";
49     if (!context->supplementary_group_ids.has_value()) {
50       std::cerr << "<no value>";
51     } else {
52       for (auto& id : context->supplementary_group_ids.value()) {
53         std::cerr << id << " ";
54       }
55     }
56     std::cerr << std::endl;
57 
58     std::cerr << "\tSELinux = "
59               << (context->selinux_context.has_value()
60                       ? context->selinux_context.value()
61                       : "<no value>")
62               << std::endl;
63 
64     std::cerr << "\tseccomp = ";
65     if (!context->seccomp_filter.has_value()) {
66       std::cerr << "<no value>";
67     } else {
68       switch (context->seccomp_filter.value()) {
69         case shell_as::kAppFilter:
70           std::cerr << "app";
71           break;
72         case shell_as::kAppZygoteFilter:
73           std::cerr << "app-zygote";
74           break;
75         case shell_as::kSystemFilter:
76           std::cerr << "system";
77           break;
78       }
79     }
80     std::cerr << std::endl;
81 
82     std::cerr << "\tcapabilities = ";
83     if (!context->capabilities.has_value()) {
84       std::cerr << "<no value>";
85     } else {
86       std::cerr << "'" << cap_to_text(context->capabilities.value(), nullptr)
87                 << "'";
88     }
89     std::cerr << std::endl;
90   }
91 
92   return !shell_as::ExecuteInContext(execute_arguments, context.get());
93 }
94