Add new AccessControl and Remove sender_appid from dbus
[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(const std::string& privilege) {
41   privileges_.push_back(privilege);
42 }
43
44 void AccessController::SetTrusted(const bool trusted) {
45   trusted_ = trusted;
46 }
47
48 int AccessController::CheckPrivilege(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(), sender_appid, getuid(), &res);
70   if (ret < 0) {
71     LOGE("CheckCertificate() Failed");
72     return -1;
73   }
74   if (res != PMINFO_CERT_COMPARE_MATCH) {
75     LOGE("CheckCertificate() Failed : MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH");
76     return -1;
77   }
78
79   return 0;
80 }
81
82 int AccessController::Check(GDBusConnection* connection, const char* sender,
83     const char* sender_appid) {
84   Cynara c;
85   int ret = 0;
86
87   if (c.FetchCredsFromDBus(connection, sender) != 0)
88     return -1;
89
90   if (!privileges_.empty()) {
91     ret = CheckPrivilege(c);
92     if (ret)
93       return ret;
94   }
95
96   if (trusted_) {
97     ret = CheckTrusted(sender_appid);
98   }
99
100   return ret;
101 }
102
103 int AccessController::SetCache(const std::string& sender) {
104   return -1;
105 }
106
107 AccessController::Cynara::Cynara() {
108   cynara_ = nullptr;
109   client_ = nullptr;
110   user_ = nullptr;
111
112   if (cynara_initialize(&cynara_, NULL) != CYNARA_API_SUCCESS) {
113     LOGE("cynara_initialize() is failed");
114   }
115 }
116
117 AccessController::Cynara::~Cynara() {
118   if (client_)
119     free(client_);
120   if (user_)
121     free(user_);
122   if (cynara_)
123     cynara_finish(cynara_);
124 }
125
126 int AccessController::Cynara::FetchCredsFromDBus(GDBusConnection* connection, const char* sender) {
127   int ret;
128
129   if (client_) {
130     free(client_);
131      client_ = nullptr;
132   }
133
134   if (user_) {
135     free(user_);
136     user_ = nullptr;
137   }
138
139   ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user_);
140   if (ret != CYNARA_API_SUCCESS) {
141     LOGE("cynara_creds_gdbus_get_user() is failed : %d", ret);
142     return -1;
143   }
144
145   ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client_);
146   if (ret != CYNARA_API_SUCCESS) {
147     LOGE("cynara_creds_gdbus_get_client() is failed : %d", ret);
148     return -1;
149   }
150
151   LOGD("cred client : %s, cred user : %s", client_, user_);
152   return 0;
153 }
154
155 int AccessController::Cynara::Check(const std::string& privilege) {
156   LOGD("check privilege %s", privilege.c_str());
157   if (cynara_check(cynara_, client_, "", user_, privilege.c_str()) != CYNARA_API_ACCESS_ALLOWED) {
158     LOGD("cynara_check() is not allowed : %s", privilege.c_str());
159     return -1;
160   }
161
162   return 0;
163 }
164
165 }  // namespace internal
166 }  // namespace rpc_port