5c674977f4839c55f7b6294430d9abe283048c5f
[platform/core/system/libdbuspolicy.git] / src / internal / print_content.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
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 #include "policy.hpp"
17 #include "print_content.hpp"
18 #include "serialized_convert.hpp"
19 #include <boost/algorithm/string/predicate.hpp>
20 #include <ostream>
21
22 /************ PRINTING CONTENT ********************/
23 std::ostream &print_content_item_own(std::ostream &stream, const std::string &name, bool is_prefix) {
24         return stream << "ItemOwn: service(" << (name.empty() ? "*" : name) << "), pref(" << is_prefix << ")";
25 }
26
27 namespace {
28 const char* message_access[] = {"USER", "GROUP", "ALL_USERS", "ALL_GROUPS"};
29 inline const char* __access_type_to_str(ldp_xml_parser::BusAccessType type) {
30         return message_access[static_cast<std::size_t>(type)];
31 }
32 }
33
34 template <typename T>
35 std::ostream &print_val(std::ostream &stream, const boost::string_ref &name, const T &val) {
36         return stream << name << "(" << val << ")";
37 }
38
39 template <typename T>
40 std::ostream &print_next_val(std::ostream &stream, const boost::string_ref &name, const T &val) {
41         stream << ", ";
42         return print_val(stream, name, val);
43 }
44
45 std::ostream &print_content_item_access(std::ostream &stream,
46                                                                                 ldp_xml_parser::BusAccessType type,
47                                                                                 uid_t uid,
48                                                                                 gid_t gid,
49                                                                                 const ldp_xml_parser::DecisionItem &decisionItem) {
50         stream << "ItemAccess: ";
51         print_val(stream, "type", __access_type_to_str(type));
52         print_next_val(stream, "uid", uid);
53         print_next_val(stream, "gid", gid);
54         return print_next_val(stream, "decision", decisionItem);
55 }
56
57 namespace {
58 static const char* message_type[] = { "ANY", "METHOD_CALL", "METHOD_RETURN", "ERROR", "SIGNAL"};
59 static inline const char* __message_type_to_str(ldp_xml_parser::MessageType type) {
60         return message_type[static_cast<std::size_t>(type)];
61 }
62 }
63
64 std::ostream &print_content_item_sr(std::ostream &stream,
65                                                                         const boost::string_ref &item_type,
66                                                                         const boost::string_ref &name,
67                                                                         const boost::string_ref &interface,
68                                                                         const boost::string_ref &member,
69                                                                         const boost::string_ref &path,
70                                                                         ldp_xml_parser::MessageType type,
71                                                                         const ldp_xml_parser::DecisionItem &decisionItem)
72 {
73         stream << item_type << ": ";
74         print_val(stream, "name", name);
75         print_next_val(stream, "inter", interface);
76         print_next_val(stream, "member", member);
77         print_next_val(stream, "path", path);
78         print_next_val(stream, "type", __message_type_to_str(type));
79         return print_next_val(stream, "decision", decisionItem);
80 }
81
82 namespace {
83 static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"};
84 static inline const char* __decision_to_str(ldp_xml_parser::Decision dec) {
85         return message_decision[static_cast<std::size_t>(dec)];
86 }
87 }
88
89 std::ostream &print_content_decision_item(std::ostream &stream,
90                                                                                   ldp_xml_parser::Decision decision,
91                                                                                   const boost::string_ref &privilege) {
92         stream << __decision_to_str(decision);
93         if (!privilege.empty())
94                 stream << ":" << privilege;
95         return stream;
96 }
97
98 template <typename T>
99 void printContentItem(std::ostream &stream, const T *item);
100
101 template <> void printContentItem(std::ostream &stream, const FB::ItemAccess *item) {
102         print_content_item_access(stream, makeBusAccessType(item->type()), item->uid(),
103                         item->gid(), makeDecisionItem(item->decision()));
104 }
105
106 template <typename T>
107 void printContentItemSR(std::ostream &stream, const boost::string_ref &item_type, const T *item) {
108         print_content_item_sr(stream, item_type, item->name()->c_str(), item->interface()->c_str(),
109                         item->member()->c_str(), item->path()->c_str(), makeMessageType(item->type()),
110                         makeDecisionItem(item->decision()));
111 }
112
113 template <> void printContentItem(std::ostream &stream, const FB::ItemSend *item) {
114         printContentItemSR(stream, "ItemSend", item);
115 }
116
117 template <> void printContentItem(std::ostream &stream, const FB::ItemReceive *item) {
118         printContentItemSR(stream, "ItemReceive", item);
119 }
120
121 template <typename T>
122 void printContentPolicy(std::ostream &stream, const T *policy) {
123         for (const auto *i: *policy->items()) {
124                 printContentItem(stream, i);
125                 stream << std::endl;
126         }
127 }
128
129 void printDecisionItem(std::ostream &stream, const FB::DecisionItem *item) {
130         print_content_decision_item(stream, makeDecision(item->decision()), item->privilege()->c_str());
131 }
132
133 void printTreeLevel(std::ostream &stream, const FB::PolicyOwnNode *node, unsigned indent) {
134         for (decltype(indent) i = 0; i < indent; ++i)
135                 stream << "\t";
136         stream << "| " << node->token()->c_str() << " (" << node->children()->size() << ") | ";
137         printDecisionItem(stream, node->decision_item());
138         stream << " ";
139         printDecisionItem(stream, node->prefix_decision_item());
140         stream << std::endl;
141
142         for (const auto &i: *node->children())
143                 printTreeLevel(stream, i, indent+1);
144 }
145
146 template <> void printContentPolicy(std::ostream &stream, const FB::PolicyOwn *policy) {
147         printTreeLevel(stream, policy->tree(), 0);
148 }
149
150 template <typename T>
151 void printContentUserGroup(std::ostream &stream, const T *set) {
152         for (const auto *i: *set->user()) {
153                 stream << "user: " << i->id() << std::endl;
154                 printContentPolicy(stream, i->policy());
155         }
156
157         for (const auto *i: *set->group()) {
158                 stream << "group: " << i->id() << std::endl;
159                 printContentPolicy(stream, i->policy());
160         }
161 }
162
163 template <> void printContentUserGroup(std::ostream &, const FB::AccessSet *) {}
164
165 template <typename T>
166 void printContentSet(std::ostream &stream, const T *set) {
167         stream << "context default" << std::endl;
168         printContentPolicy(stream, set->context_default());
169         stream << "context mandatory" << std::endl;
170         printContentPolicy(stream, set->context_mandatory());
171
172         printContentUserGroup(stream, set);
173 }
174
175 namespace FB {
176 std::ostream &operator<<(std::ostream &stream, const FB::File &file) {
177         printContentSet(stream, file.m_own_set());
178         printContentSet(stream, file.m_send_set());
179         printContentSet(stream, file.m_receive_set());
180         printContentSet(stream, file.m_access_set());
181         return stream;
182 }
183 }
184
185 /********* PRINTING ITEMS PARSED FROM XML *******************/
186 namespace ldp_xml_parser {
187 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemOwn &item) {
188         return print_content_item_own(stream, item.getName(), item.isPrefix());
189 }
190
191 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemSend &item) {
192         return print_content_item_sr(stream, "ItemSend", item.getName(), item.getInterface(), item.getMember(),
193                         item.getPath(), item.getType(), item.getDecision());
194 }
195
196 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemReceive &item) {
197         return print_content_item_sr(stream, "ItemReceive", item.getName(), item.getInterface(), item.getMember(),
198                         item.getPath(), item.getType(), item.getDecision());
199 }
200
201 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::ItemAccess &item) {
202         return print_content_item_access(stream, item.getType(), item.getUid(), item.getGid(), item.getDecision());
203 }
204
205 std::ostream &operator<<(std::ostream &stream, const ldp_xml_parser::DecisionItem &item) {
206         return print_content_decision_item(stream, item.getDecision(), item.getPrivilege());
207 }
208 std::ostream &operator<<(std::ostream& stream, const MatchItemOwn &item)
209 {
210         return stream << (item.getName().empty() ? "NULL" : item.getName());
211 }
212
213 std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemSR &item)
214 {
215         stream << ": services(";
216         for (const auto &name: item.names)
217                 stream << name << " ";
218
219         return stream << "), interface(" << item.interface << "), member(" << item.member <<
220                 "), path(" << item.path << "), type(" << __message_type_to_str(item.type) << ")";
221 }
222
223 std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemSend &item)
224 {
225         stream << "MatchItemSend";
226         return stream << static_cast<const MatchItemSR>(item);
227 }
228
229 std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemReceive &item)
230 {
231         stream << "MatchItemReceive";
232         return stream << static_cast<const MatchItemSR>(item);
233 }
234
235 std::ostream &operator<<(std::ostream& stream, const ldp_xml_parser::MatchItemAccess &item)
236 {
237         stream << "uid: " << item.getUid() << ", gid: ";
238         for (auto gid : item.getGids())
239                 stream << gid << ", ";
240         return stream << std::endl;
241 }
242
243 }