From: Hwankyu Jhun Date: Wed, 16 Aug 2023 05:12:18 +0000 (+0900) Subject: Support method privilege check for C++ Generator X-Git-Tag: accepted/tizen/unified/20230914.164942~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=87eceea507f0f70583c6dd04bf6295e1ff03ac3c;p=platform%2Fcore%2Fappfw%2Ftidl.git Support method privilege check for C++ Generator This patch supports the method privilege check feature. The developer can set the privilege for each methods. Change-Id: I9991b3554712878580700127b17ea969617c3e65 Signed-off-by: Hwankyu Jhun --- diff --git a/idlc/gen/version2/cpp_generator_base_cb.hh b/idlc/gen/version2/cpp_generator_base_cb.hh index b33a373c..88875de7 100644 --- a/idlc/gen/version2/cpp_generator_base_cb.hh +++ b/idlc/gen/version2/cpp_generator_base_cb.hh @@ -68,6 +68,7 @@ R"__cpp_cb( #include #include #include +#include )__cpp_cb"; /** diff --git a/idlc/gen/version2/cpp_stub_body_generator.cc b/idlc/gen/version2/cpp_stub_body_generator.cc index 927ecde3..78de08d2 100644 --- a/idlc/gen/version2/cpp_stub_body_generator.cc +++ b/idlc/gen/version2/cpp_stub_body_generator.cc @@ -94,7 +94,9 @@ std::string CppStubBodyGenerator::GenInterface(const Interface& iface) { .Change("", GenInterfaceImplServiceBaseDispatch()) .Change("", - GenInterfaceImplServiceBaseDispatchFuncs(iface))); + GenInterfaceImplServiceBaseDispatchFuncs(iface)) + .Change("", + GenInterfaceImplServiceBaseSetPrivilegeMap(iface))); } std::string CppStubBodyGenerator::GenInterfaceCallbacks( @@ -265,5 +267,28 @@ std::string CppStubBodyGenerator::GenInterfaceServiceBaseSerialize( return RemoveLine(code); } +std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseSetPrivilegeMap( + const Interface& iface) { + std::string code; + for (auto& decl : iface.GetDeclarations()) { + std::string privileges; + for (auto& attr : decl->GetAttributes()) { + if (attr->GetKey() != "privilege") + continue; + + privileges += "\"" + attr->GetValue() + "\"," + NLine(1); + } + + if (privileges.empty()) + continue; + + code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_SET_PRIVILEGE_MAP) + .Change("", privileges) + .Change("", decl->GetID()); + } + + return RemoveLine(code); +} + } // namespace version2 } // namespace tidl diff --git a/idlc/gen/version2/cpp_stub_body_generator.hh b/idlc/gen/version2/cpp_stub_body_generator.hh index 1727d389..ba3a54ec 100644 --- a/idlc/gen/version2/cpp_stub_body_generator.hh +++ b/idlc/gen/version2/cpp_stub_body_generator.hh @@ -29,7 +29,7 @@ namespace version2 { class CppStubBodyGenerator : public CppGeneratorBase { public: explicit CppStubBodyGenerator(std::shared_ptr doc, - std::shared_ptr options); + std::shared_ptr options); virtual ~CppStubBodyGenerator() = default; void OnInitGen(std::ofstream& stream) override; @@ -49,9 +49,11 @@ class CppStubBodyGenerator : public CppGeneratorBase { std::string GenInterfaceImplServiceBaseDispatch(); std::string GenInterfaceImplServiceBaseDispatchFuncs(const Interface& iface); std::string GenInterfaceImplServiceBaseDispatchFunc(const Interface& iface, - const Declaration& decl); + const Declaration& decl); std::string GenInterfaceServiceBaseDeserialize(const Declaration& decl); std::string GenInterfaceServiceBaseSerialize(const Declaration& decl); + std::string GenInterfaceImplServiceBaseSetPrivilegeMap( + const Interface& iface); private: std::shared_ptr options_; diff --git a/idlc/gen/version2/cpp_stub_body_generator_cb.hh b/idlc/gen/version2/cpp_stub_body_generator_cb.hh index e44426ec..b0c375b8 100644 --- a/idlc/gen/version2/cpp_stub_body_generator_cb.hh +++ b/idlc/gen/version2/cpp_stub_body_generator_cb.hh @@ -27,9 +27,11 @@ constexpr const char CB_STUB_BODY_HEADER[] = R"__cpp_cb( #include "" -#include +#include #include #include +#include +#include )__cpp_cb"; /** @@ -137,12 +139,15 @@ void ::PendingJob::OnRun() { * The implementation of the initialization of thread member variable of the service base. * The implementation of the dispatch method of the service base. * The implementation of the dispatch functions of the service base. + * The implementation of setting privilege map of the service base. */ constexpr const char CB_INTERFACE_BASE[] = R"__cpp_cb( ::ServiceBase::ServiceBase(std::string sender, std::string instance) : sender_(std::move(sender)), instance_(std::move(instance)) { + LoadPrivileges(); + SetPrivilegeMap(); dispatch_funcs_ = { @@ -191,6 +196,62 @@ void ::ServiceBase::Dispatch(rpc_port_h port, rpc_port_h callback_port func(port, callback_port, seq_num, unit_map_); } +bool ::ServiceBase::PrivilegeInfoCb(const char* privilege_name, void *user_data) { + auto* service_base = static_cast<::ServiceBase*>(user_data); + _D("appid: %s, privilege: %s", service_base->GetSender().c_str(), privilege_name); + service_base->privileges_.insert(privilege_name); + return true; +} + +void ::ServiceBase::LoadPrivileges() { + app_info_h app_info = nullptr; + int ret = app_info_create(GetSender().c_str(), &app_info); + if (ret != APP_MANAGER_ERROR_NONE) { + if (ret == APP_MANAGER_ERROR_NO_SUCH_APP) + _W("%s is not an application", GetSender().c_str()); + + return; + } + + char* package = nullptr; + ret = app_info_get_package(app_info, &package); + app_info_destroy(app_info); + if (ret != APP_MANAGER_ERROR_NONE) { + _E("Failed to get package. error(%d)", ret); + return; + } + + package_info_h package_info = nullptr; + ret = package_info_create(package, &package_info); + free(package); + if (ret != PACKAGE_MANAGER_ERROR_NONE) { + _E("Failed to create package info. error(%d)", ret); + return; + } + + package_info_foreach_privilege_info(package_info, PrivilegeInfoCb, this); + package_info_destroy(package_info); +} + +void ::ServiceBase::SetPrivilegeMap() { + +} + +bool ::ServiceBase::CheckPrivileges(int method_id) { + auto found = privilege_map_.find(method_id); + if (found == privilege_map_.end()) + return true; + + for (const auto& privilege : found->second) { + if (privileges_.find(privilege) == privileges_.end()) { + _E("%s does not exist", privilege.c_str()); + return false; + } + } + + return true; +} + ::() { @@ -323,6 +384,11 @@ active_object_->Send(std::make_shared(port, callback_port, parcel, std::mov constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC_ASYNC[] = R"__cpp_cb( void ::ServiceBase::Dispatch(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map) { + if (!CheckPrivileges(static_cast(MethodId::))) { + _E("Permission denied"); + return; + } + (); } @@ -338,15 +404,21 @@ void ::ServiceBase::Dispatch(rpc_port_h port, rpc_port_h callb constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC[] = R"__cpp_cb( void ::ServiceBase::Dispatch(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map) { - UnitMap map_; - try { - auto ret_ = (); - map_.Write("[RESULT]", ret_); - - } catch (const RemoteException& e) { - _E("Exception occurs. cause(%d), message(%s)", e.GetCause(), e.GetMessage().c_str()); - map_.Write("[REMOTE_EXCEPTION]", e); + if (!CheckPrivileges(static_cast(MethodId::))) { + _E("Permission denied"); + RemoteException remote_except(RPC_PORT_ERROR_PERMISSION_DENIED, "Permission denied"); + map_.Write("[REMOTE_EXCEPTION]", remote_except); + } else { + + try { + auto ret_ = (); + map_.Write("[RESULT]", ret_); + + } catch (const RemoteException& e) { + _E("Exception occurs. cause(%d), message(%s)", e.GetCause(), e.GetMessage().c_str()); + map_.Write("[REMOTE_EXCEPTION]", e); + } } map_.Write("[METHOD]", static_cast(MethodId::__Result)); @@ -399,6 +471,20 @@ R"__cpp_cb( unit_map.Read("", ); )__cpp_cb"; +/** + * The privileges of the method. + * The method name. + */ +constexpr const char CB_INTERFACE_SERVICE_BASE_SET_PRIVILEGE_MAP[] = +R"__cpp_cb( +{ + std::vector privileges = { + + }; + privilege_map_[static_cast(MethodId::)] = std::move(privileges); +} +)__cpp_cb"; + } // namespace version2 } // namespace tidl diff --git a/idlc/gen/version2/cpp_stub_header_generator_cb.hh b/idlc/gen/version2/cpp_stub_header_generator_cb.hh index 127510dc..ee4b63b8 100644 --- a/idlc/gen/version2/cpp_stub_header_generator_cb.hh +++ b/idlc/gen/version2/cpp_stub_header_generator_cb.hh @@ -176,10 +176,8 @@ class CallbackBase { int GetId() const; void SetId(int id); - int GetSeqId() const; void SetSeqId(int seq_id); - bool IsOnce() const; void SetOnce(bool once); @@ -311,6 +309,10 @@ class { private: using DispatchFunc = std::function; + static bool PrivilegeInfoCb(const char* privilege_name, void* user_data); + void LoadPrivileges(); + void SetPrivilegeMap(); + bool CheckPrivileges(int method_id); @@ -320,6 +322,8 @@ class { std::string instance_; rpc_port_h port_ = nullptr; std::unordered_map dispatch_funcs_; + std::unordered_map> privilege_map_; + std::unordered_set privileges_; }; ();