2 * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <cynara-creds-socket.h>
19 #include <cynara-error.h>
21 #include <pkgmgr-info.h>
25 #include "ac-internal.hh"
26 #include "aul-internal.hh"
27 #include "log-private.hh"
28 #include "cynara_thread.hh"
34 constexpr const uid_t kRegularUidMin = 5000;
38 void AccessController::AddPrivilege(std::string privilege) {
39 privileges_.push_back(std::move(privilege));
42 void AccessController::SetTrusted(const bool trusted) {
46 int AccessController::CheckPrivilege(const Cynara& c) {
47 for (auto& privilege : privileges_) {
48 if (c.Check(privilege) != 0) {
56 int AccessController::CheckTrusted(const std::string& sender_appid) {
57 if (getuid() < kRegularUidMin)
61 appid_ = Aul::GetAppId(getpid());
63 _D("CheckCertificate : %s :: %s", appid_.c_str(), sender_appid.c_str());
64 pkgmgrinfo_cert_compare_result_type_e res;
65 int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(appid_.c_str(),
66 sender_appid.c_str(), getuid(), &res);
68 _E("CheckCertificate() Failed");
71 if (res != PMINFO_CERT_COMPARE_MATCH) {
72 _E("CheckCertificate() Failed : Certificate Not Matched");
79 int AccessController::Check(int fd, const std::string& sender_appid) {
81 int ret = cynara.FetchCredsFromSocket(fd);
85 if (!privileges_.empty()) {
86 ret = CheckPrivilege(cynara);
92 ret = CheckTrusted(sender_appid);
97 void AccessController::CheckAsync(int fd, std::string sender_appid,
98 CompleteCallback callback) {
99 Job job([=]() -> Job::Type {
100 int res = Check(fd, sender_appid);
101 auto* cbdata = new std::pair<CompleteCallback, int>(callback, res);
102 if (callback != nullptr) {
104 [](gpointer data) -> gboolean {
105 auto* cbdata = static_cast<std::pair<CompleteCallback, int>*>(data);
106 auto [callback, res] = *cbdata;
109 return G_SOURCE_REMOVE;
113 return Job::Type::Continue;
116 CynaraThread::GetInst().Push(std::move(job));
119 AccessController::Cynara::Cynara()
120 : cynara_(nullptr, cynara_finish), client_(nullptr, std::free),
121 user_(nullptr, std::free) {
122 cynara* cynara_inst = nullptr;
124 if (cynara_initialize(&cynara_inst, NULL) != CYNARA_API_SUCCESS) {
125 _E("cynara_initialize() is failed"); // LCOV_EXL_LINE
127 cynara_.reset(cynara_inst);
131 AccessController::Cynara::~Cynara() = default;
133 int AccessController::Cynara::FetchCredsFromSocket(int fd) {
134 char* user = nullptr;
135 int ret = cynara_creds_socket_get_user(fd, USER_METHOD_DEFAULT, &user);
136 if (ret != CYNARA_API_SUCCESS) {
137 char buf[128] = { 0, };
138 cynara_strerror(ret, buf, sizeof(buf));
139 _E("cynara_creds_socket_get_user() is failed. fd(%d), error(%d:%s)",
145 char* client = nullptr;
146 ret = cynara_creds_socket_get_client(fd, CLIENT_METHOD_DEFAULT, &client);
147 if (ret != CYNARA_API_SUCCESS) {
148 char buf[128] = { 0, };
149 cynara_strerror(ret, buf, sizeof(buf));
150 _E("cynara_creds_socket_get_client() is failed. fd(%d), error(%d:%s)",
154 client_.reset(client);
156 _D("Cred client(%s), user(%s)", client_.get(), user_.get());
160 int AccessController::Cynara::Check(const std::string& privilege) const {
161 _D("check privilege %s", privilege.c_str());
162 if (cynara_check(cynara_.get(), client_.get(), "", user_.get(),
163 privilege.c_str()) != CYNARA_API_ACCESS_ALLOWED) {
164 _E("cynara_check() is not allowed : %s", privilege.c_str());
171 } // namespace internal
172 } // namespace rpc_port