return false;
}
+ tizen_base::Parcel p;
+ p.WriteParcelable(*parcel_.get());
+ const auto& raw = p.GetRaw();
+ int len = raw.size();
+
// CREATE_DB request type need to be executed directly by the caller
if (req_type_ == pkgmgr_common::ReqType::CREATE_DB) {
is_offline_ = true;
- return RequestHandlerDirectAccess();
+ return RequestHandlerDirectAccess(p.GetRaw());
}
if (!check_server.IsReady()) {
LOG(WARNING) << "Server is not ready, try to direct access";
is_offline_ = true;
- return RequestHandlerDirectAccess();
+ return RequestHandlerDirectAccess(p.GetRaw());
}
+ LOG(WARNING) << "Try to send request, Request type: "
+ << pkgmgr_common::ReqTypeToString(req_type_);
+
if (!socket_->Connect()) {
LOG(ERROR) << "Failed to connect client socket, try to direct access";
is_offline_ = true;
- return RequestHandlerDirectAccess();
+ return RequestHandlerDirectAccess(p.GetRaw());
}
if (socket_->SendData(&req_type_, sizeof(req_type_)) != 0) {
return false;
}
- tizen_base::Parcel p;
- p.WriteParcelable(*parcel_.get());
- const auto& raw = p.GetRaw();
- int len = raw.size();
-
if (socket_->SendData(&len, sizeof(len)) != 0) {
LOG(ERROR) << "fail to send data";
return false;
return res;
}
-bool PkgInfoClient::RequestHandlerDirectAccess() {
- tizen_base::Parcel p;
- p.WriteParcelable(*parcel_.get());
- std::vector<uint8_t> raw = p.GetRaw();
-
+bool PkgInfoClient::RequestHandlerDirectAccess(
+ const std::vector<uint8_t>& raw) {
static void* handle = nullptr;
- static void* (*dl_func)(int, unsigned char*, int, const char *);
+ static void* (*dl_func)(int, const unsigned char*, int, const char *);
if (handle == nullptr) {
handle = dlopen(LIBPKGMGR_INFO, RTLD_GLOBAL | RTLD_LAZY);
return false;
}
dl_func = reinterpret_cast<void* (*)(
- int, unsigned char*, int, const char *)>(
+ int, const unsigned char*, int, const char *)>(
dlsym(handle, DIRECT_ACCESS_FUNC));
if (dl_func == nullptr) {
LOG(ERROR) << "cannot find " << DIRECT_ACCESS_FUNC << " symbol in "
std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> GetResultParcel();
private:
- bool RequestHandlerDirectAccess();
+ bool RequestHandlerDirectAccess(const std::vector<uint8_t>& raw);
std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcel_;
std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> result_parcel_;
namespace pkgmgr_server {
-unsigned char* CreateCacheRequest::GetData() {
+const unsigned char* CreateCacheRequest::GetData() {
return nullptr;
}
return true;
}
+bool CreateCacheRequest::GetPrivilegeChecked() {
+ return true;
+}
+
} // namespace pkgmgr_server
class EXPORT_API CreateCacheRequest : public PkgRequest {
public:
CreateCacheRequest(uid_t uid) : uid_(uid) {}
- unsigned char* GetData() override;
+ const unsigned char* GetData() override;
int GetSize() override;
pid_t GetSenderPID() override;
uid_t GetSenderUID() override;
pkgmgr_common::ReqType GetRequestType() override;
bool SendData(unsigned char* data, int size) override;
+ bool GetPrivilegeChecked() override;
private:
uid_t uid_;
void CynaraChecker::ReplyCb(cynara_check_id id, cynara_async_call_cause cause,
int resp, void* data) {
- auto runner = static_cast<Runner*>(data);
+ auto worker_thread = static_cast<WorkerThread*>(data);
auto& inst = CynaraChecker::GetInst();
switch (cause) {
case CYNARA_CALL_CAUSE_ANSWER: {
}
LOG(DEBUG) << "Allowed request";
- runner->QueueRequest(it->second);
+ it->second->SetPrivilegeChecked(true);
+ worker_thread->PushQueue(it->second);
inst.cynara_id_map_.erase(it);
break;
}
}
-void CynaraChecker::CheckPrivilege(Runner* runner,
+bool CynaraChecker::CheckPrivilege(WorkerThread* worker_thread,
const std::shared_ptr<PkgRequest>& req,
const std::vector<std::string>& privileges) {
if (privileges.empty() || req->GetSenderUID() < REGULAR_USER) {
LOG(DEBUG) << "Allowed request";
- runner->QueueRequest(req);
- return;
+ return true;
}
+ std::unique_lock<std::mutex> u(lock_);
int ret;
if (cynara_ == nullptr) {
ret = cynara_async_initialize(&cynara_, nullptr, StatusCb, nullptr);
if (ret != CYNARA_API_SUCCESS) {
LOG(ERROR) << "Failed to initialize cynara_";
- return;
+ return false;
}
}
&smack_label);
if (ret != CYNARA_API_SUCCESS) {
LOG(ERROR) << "Failed to get smack label";
- return;
+ return false;
}
std::unique_ptr<char, decltype(std::free)*> lblPtr(smack_label, std::free);
if (session == nullptr) {
LOG(ERROR) << "Failed to get client session for pid:"
<< req->GetSenderPID();
- return;
+ return false;
}
std::unique_ptr<char, decltype(std::free)*> sessPtr(session, std::free);
for (auto& priv : privileges) {
ret = cynara_async_create_request(cynara_, smack_label, session,
std::to_string(req->GetSenderUID()).c_str(), priv.c_str(),
- &id, ReplyCb, runner);
+ &id, ReplyCb, worker_thread);
if (check == false) {
cynara_id_map_[id] = req;
check = true;
}
}
+
+ return false;
}
} // namespace pkgmgr_server
#include <glib.h>
#include <cynara-client-async.h>
+#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>
#include "pkg_request.hh"
-#include "runner.hh"
+#include "worker_thread.hh"
namespace pkgmgr_server {
static CynaraChecker& GetInst();
void Init();
void Fini();
- void CheckPrivilege(Runner* runner,
+ bool CheckPrivilege(WorkerThread* worker_thread,
const std::shared_ptr<PkgRequest>& req,
const std::vector<std::string>& privileges);
cynara_async* cynara_ = nullptr;
guint cynara_sid_ = 0;
std::unordered_map<cynara_check_id, std::shared_ptr<PkgRequest>> cynara_id_map_;
+ std::mutex lock_;
};
} // namespace pkgmgr_server
namespace pkgmgr_server {
PkgRequest::PkgRequest()
- : request_type_(pkgmgr_common::REQ_TYPE_NONE), data_size_(-1) {}
+ : request_type_(pkgmgr_common::REQ_TYPE_NONE), data_size_(-1),
+ privilege_checked_(false) {}
PkgRequest::PkgRequest(int fd)
- : request_type_(pkgmgr_common::REQ_TYPE_NONE), data_size_(-1) {
+ : request_type_(pkgmgr_common::REQ_TYPE_NONE), data_size_(-1),
+ privilege_checked_(false) {
socket_ = std::unique_ptr<pkgmgr_common::socket::DataSocket>(
new (std::nothrow) pkgmgr_common::socket::DataSocket(fd));
if (socket_ == nullptr)
delete[] data_;
}
-unsigned char* PkgRequest::GetData() {
+const unsigned char* PkgRequest::GetData() {
return data_;
}
return (socket_->SendData(data, size) == 0);
}
+bool PkgRequest::GetPrivilegeChecked() {
+ return privilege_checked_;
+}
+
+void PkgRequest::SetPrivilegeChecked(bool checked) {
+ privilege_checked_ = checked;
+}
+
} // namespace pkgmgr_server
int GetFd();
bool ReceiveData();
- virtual unsigned char* GetData();
+ virtual const unsigned char* GetData();
virtual int GetSize();
virtual pid_t GetSenderPID();
virtual uid_t GetSenderUID();
virtual pkgmgr_common::ReqType GetRequestType();
virtual bool SendData(unsigned char* data, int size);
+ virtual bool GetPrivilegeChecked();
+ virtual void SetPrivilegeChecked(bool cheked);
private:
std::unique_ptr<pkgmgr_common::socket::DataSocket> socket_;
unsigned char* data_ = nullptr;
pkgmgr_common::ReqType request_type_;
int data_size_;
+ bool privilege_checked_;
};
} // namespace pkgmgr_server
class EXPORT_API AbstractRequestHandler {
public:
virtual ~AbstractRequestHandler() = default;
- virtual bool HandleRequest(unsigned char* data, int size,
+ virtual bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) = 0;
virtual std::vector<uint8_t> ExtractResult() = 0;
namespace pkgmgr_server {
namespace request_handler {
-bool CommandRequestHandler::HandleRequest(unsigned char* data, int size,
+bool CommandRequestHandler::HandleRequest(const unsigned char* data, int size,
const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API CommandRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
CreateCacheRequestHandler::CreateCacheRequestHandler(): scheduler_(gettid()) {
}
-bool CreateCacheRequestHandler::HandleRequest(unsigned char* data, int size,
+bool CreateCacheRequestHandler::HandleRequest(const unsigned char* data, int size,
const std::string& locale) {
psd::CacheDBHandler db(GetUID(), GetPID());
db.SetLocale(locale);
class EXPORT_API CreateCacheRequestHandler : public AbstractRequestHandler {
public:
CreateCacheRequestHandler();
- bool HandleRequest(unsigned char* data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace pkgmgr_server {
namespace request_handler {
-bool CreateDBRequestHandler::HandleRequest(unsigned char* data, int size,
+bool CreateDBRequestHandler::HandleRequest(const unsigned char* data, int size,
const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API CreateDBRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace pkgmgr_server {
namespace request_handler {
-bool GetAppinfoRequestHandler::HandleRequest(unsigned char* data, int size,
- const std::string& locale) {
+bool GetAppinfoRequestHandler::HandleRequest(const unsigned char* data,
+ int size, const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API GetAppinfoRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char *data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string &locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace pkgmgr_server {
namespace request_handler {
-bool GetCertRequestHandler::HandleRequest(unsigned char* data, int size,
+bool GetCertRequestHandler::HandleRequest(const unsigned char* data, int size,
const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API GetCertRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace pkgmgr_server {
namespace request_handler {
-bool GetDepinfoRequestHandler::HandleRequest(unsigned char* data, int size,
+bool GetDepinfoRequestHandler::HandleRequest(const unsigned char* data, int size,
const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API GetDepinfoRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace pkgmgr_server {
namespace request_handler {
-bool GetPkginfoRequestHandler::HandleRequest(unsigned char* data, int size,
- const std::string& locale) {
+bool GetPkginfoRequestHandler::HandleRequest(const unsigned char* data,
+ int size, const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API GetPkginfoRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace pkgmgr_server {
namespace request_handler {
-bool QueryRequestHandler::HandleRequest(unsigned char* data, int size,
+bool QueryRequestHandler::HandleRequest(const unsigned char* data, int size,
const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
class EXPORT_API QueryRequestHandler : public AbstractRequestHandler {
public:
- bool HandleRequest(unsigned char* data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
#define EXPORT_API __attribute__((visibility("default")))
extern "C" EXPORT_API void* _request_handler_direct_access(int req_type,
- unsigned char* data, int size, const char *locale) {
+ const unsigned char* data, int size, const char *locale) {
if (data == nullptr || size < 0 || locale == nullptr) {
LOG(ERROR) << "Invalid parameter";
return nullptr;
extern "C" {
#endif
-void *_request_handler_direct_access(int req_type, unsigned char* data,
+void *_request_handler_direct_access(int req_type, const unsigned char* data,
int size, const char *locale);
#ifdef __cplusplus
namespace pkgmgr_server {
namespace request_handler {
-bool SetCertRequestHandler::HandleRequest(unsigned char* data, int size,
+bool SetCertRequestHandler::HandleRequest(const unsigned char* data, int size,
const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
public:
SetCertRequestHandler(bool is_offline = false) :
AbstractRequestHandler(), is_offline_(is_offline) {}
- bool HandleRequest(unsigned char* data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
namespace pkgmgr_server {
namespace request_handler {
-bool SetPkginfoRequestHandler::HandleRequest(unsigned char* data, int size,
- const std::string& locale) {
+bool SetPkginfoRequestHandler::HandleRequest(const unsigned char* data,
+ int size, const std::string& locale) {
auto abstract_parcel =
pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
public:
SetPkginfoRequestHandler(bool is_offline = false) :
AbstractRequestHandler(), is_offline_(is_offline) {}
- bool HandleRequest(unsigned char* data, int size,
+ bool HandleRequest(const unsigned char* data, int size,
const std::string& locale) override;
std::vector<uint8_t> ExtractResult() override;
#include <algorithm>
#include <string>
-#include <unordered_map>
-#include <vector>
#include "cache_flag.hh"
#include "create_cache_request.hh"
const char PRIVILEGE_PACKAGE_MANAGER_ADMIN[] =
"http://tizen.org/privilege/packagemanager.admin";
-std::vector<std::string> GetPrivileges(pkgmgr_common::ReqType type) {
- std::vector<std::string> ret;
- if (type == pkgmgr_common::SET_CERT_INFO)
- ret.emplace_back(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
- else if (type == pkgmgr_common::SET_PKG_INFO)
- ret.emplace_back(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
-
- return ret;
-}
-
} // namespace
Runner::Runner(unsigned int thread_num) {
}
auto req = std::make_shared<PkgRequest>(client_fd);
- if (req->ReceiveData()) {
- pkgmgr_common::ReqType type = req->GetRequestType();
- if (CacheFlag::SetPreparing()) {
- runner->QueueRequest(
- std::make_shared<CreateCacheRequest>(req->GetSenderUID()));
- }
- std::vector<std::string>&& privileges = GetPrivileges(type);
- CynaraChecker::GetInst().CheckPrivilege(runner, req, privileges);
+
+ if (CacheFlag::SetPreparing()) {
+ runner->QueueRequest(
+ std::make_shared<CreateCacheRequest>(req->GetSenderUID()));
}
+ runner->QueueRequest(std::move(req));
return G_SOURCE_CONTINUE;
}
#include <tzplatform_config.h>
#include "abstract_parcelable.hh"
+#include "cynara_checker.hh"
#include "request_handler_factory.hh"
#include "server/database/db_handle_provider.hh"
#include "utils/logging.hh"
return uid;
}
+const char PRIVILEGE_PACKAGE_MANAGER_ADMIN[] =
+ "http://tizen.org/privilege/packagemanager.admin";
+
+std::vector<std::string> GetPrivileges(pkgmgr_common::ReqType type) {
+ std::vector<std::string> ret;
+ if (type == pkgmgr_common::SET_CERT_INFO)
+ ret.emplace_back(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
+ else if (type == pkgmgr_common::SET_PKG_INFO)
+ ret.emplace_back(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
+
+ return ret;
+}
+
} // namespace
namespace pkgmgr_server {
if (req == nullptr)
return;
+ if (!req->GetPrivilegeChecked()) {
+ if (!req->ReceiveData()) {
+ LOG(ERROR) << "Fail to receive data";
+ continue;
+ }
+
+ pkgmgr_common::ReqType type = req->GetRequestType();
+ std::vector<std::string> privileges = GetPrivileges(type);
+ if (!CynaraChecker::GetInst().CheckPrivilege(this, req, privileges))
+ continue;
+ }
+
auto type = req->GetRequestType();
LOG(WARNING) << "Request type: " << pkgmgr_common::ReqTypeToString(type)
<< " pid: " << req->GetSenderPID();