a8c0f85132c928fd6f9a3b5bf7568639141a5cb1
[platform/core/appfw/rpc-port.git] / src / ac-internal.cc
1 /*
2  * Copyright (c) 2017 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
17 #ifndef _GNU_SOURCE
18 #define _GNU_SOURCE
19 #endif
20
21 #include <aul.h>
22 #include <dlog.h>
23 #include <pkgmgr-info.h>
24 #include <cynara-error.h>
25 #include <cynara-creds-gdbus.h>
26
27 #include "ac-internal.h"
28
29 #ifdef LOG_TAG
30 #undef LOG_TAG
31 #endif
32
33 #define LOG_TAG "RPC_PORT"
34
35 namespace rpc_port {
36 namespace internal {
37
38 AccessController::~AccessController() {}
39
40 void AccessController::AddPrivilege(std::string privilege) {
41   privileges_.push_back(std::move(privilege));
42 }
43
44 void AccessController::SetTrusted(const bool trusted) {
45   trusted_ = trusted;
46 }
47
48 int AccessController::CheckPrivilege(const Cynara& c) {
49   for (auto& privilege : privileges_) {
50     if (c.Check(privilege) != 0) {
51       return -1;
52     }
53   }
54
55   return 0;
56 }
57
58 int AccessController::CheckTrusted(const char* sender_appid) {
59   if (appid_.empty()) {
60     char appid[255];
61     if (aul_app_get_appid_bypid(getpid(), appid, sizeof(appid)) < 0)
62       return -1;
63
64     appid_ = appid;
65   }
66
67   LOGD("CheckCertificate : %s :: %s", appid_.c_str(), sender_appid);
68   pkgmgrinfo_cert_compare_result_type_e res;
69   int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(appid_.c_str(),
70       sender_appid, getuid(), &res);
71   if (ret < 0) {
72     LOGE("CheckCertificate() Failed");
73     return -1;
74   }
75   if (res != PMINFO_CERT_COMPARE_MATCH) {
76     LOGE("CheckCertificate() Failed : " \
77         "MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH");
78     return -1;
79   }
80
81   return 0;
82 }
83
84 int AccessController::Check(GDBusConnection* connection, const char* sender,
85     const char* sender_appid) {
86   Cynara c;
87   int ret = 0;
88
89   if (c.FetchCredsFromDBus(connection, sender) != 0)
90     return -1;
91
92   if (!privileges_.empty()) {
93     ret = CheckPrivilege(c);
94     if (ret)
95       return ret;
96   }
97
98   if (trusted_) {
99     ret = CheckTrusted(sender_appid);
100   }
101
102   return ret;
103 }
104
105 int AccessController::SetCache(const std::string& sender) {
106   return -1;
107 }
108
109 AccessController::Cynara::Cynara() {
110   cynara_ = nullptr;
111   client_ = nullptr;
112   user_ = nullptr;
113
114   if (cynara_initialize(&cynara_, NULL) != CYNARA_API_SUCCESS) {
115     LOGE("cynara_initialize() is failed");
116   }
117 }
118
119 AccessController::Cynara::~Cynara() {
120   if (client_)
121     free(client_);
122   if (user_)
123     free(user_);
124   if (cynara_)
125     cynara_finish(cynara_);
126 }
127
128 int AccessController::Cynara::FetchCredsFromDBus(GDBusConnection* connection,
129     const char* sender) {
130   int ret;
131
132   if (client_) {
133     free(client_);
134      client_ = nullptr;
135   }
136
137   if (user_) {
138     free(user_);
139     user_ = nullptr;
140   }
141
142   ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT,
143                                     &user_);
144   if (ret != CYNARA_API_SUCCESS) {
145     LOGE("cynara_creds_gdbus_get_user() is failed : %d", ret);
146     return -1;
147   }
148
149   ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT,
150                                       &client_);
151   if (ret != CYNARA_API_SUCCESS) {
152     LOGE("cynara_creds_gdbus_get_client() is failed : %d", ret);
153     return -1;
154   }
155
156   LOGD("cred client : %s, cred user : %s", client_, user_);
157   return 0;
158 }
159
160 int AccessController::Cynara::Check(const std::string& privilege) const {
161   LOGD("check privilege %s", privilege.c_str());
162   if (cynara_check(cynara_, client_, "", user_, privilege.c_str()) !=
163       CYNARA_API_ACCESS_ALLOWED) {
164     LOGE("cynara_check() is not allowed : %s", privilege.c_str());
165     return -1;
166   }
167
168   return 0;
169 }
170
171 }  // namespace internal
172 }  // namespace rpc_port