From 5eaf6e896ef467ae49447c402c0d3624bf69659c Mon Sep 17 00:00:00 2001 From: jusung son Date: Wed, 16 Aug 2023 15:09:54 +0900 Subject: [PATCH] Support method privilege check for C# Generator Change-Id: I5bf46f178257376a4d8b19767a864461b3c41c9b Signed-off-by: jusung son --- idlc/gen/version2/cs_stub_generator.cc | 39 ++++++++++++++++++++++-- idlc/gen/version2/cs_stub_generator.h | 2 ++ idlc/gen/version2/cs_stub_generator_cb.h | 52 ++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/idlc/gen/version2/cs_stub_generator.cc b/idlc/gen/version2/cs_stub_generator.cc index 762974e..73a8e25 100644 --- a/idlc/gen/version2/cs_stub_generator.cc +++ b/idlc/gen/version2/cs_stub_generator.cc @@ -67,6 +67,7 @@ void CsStubGen::GenInterface(std::ofstream& stream, const Interface& iface) { GenMethodId(stream, iface); GenSerializer(stream); GenListSerializer(stream); + GenCheckPrivilege(stream); GenReceivedEvent(stream, iface); GenConnectedEvent(stream); GenDisconnectedEvent(stream); @@ -95,6 +96,10 @@ void CsStubGen::GenDeclarations(std::ofstream& stream, } } +void CsStubGen::GenCheckPrivilege(std::ofstream& stream) { + stream << CB_CHECK_PRIVILEGE_METHOD; +} + void CsStubGen::GenReceivedEvent(std::ofstream& stream, const Interface& iface) { stream << CB_ON_RECEIVED_EVENT_FRONT; @@ -191,10 +196,25 @@ void CsStubGen::GenDisconnectedEvent(std::ofstream& stream) { stream << CB_ON_DISCONNECTED_EVENT; } +std::string CsStubGen::GenPrivileges(const Declaration& decl, + const std::string& id) { + std::string code; + for (const auto& attr : decl.GetAttributes()) { + if (attr->GetKey() != "privilege") + continue; + + code += + Tab(4) + "list" + id + ".Add(\"" + attr->GetValue() + "\");" + NLine(1); + } + + return code; +} + void CsStubGen::GenCtor(std::ofstream& stream, const Interface& iface) { GenTemplate( - CB_CTOR_FRONT, stream, [&]() -> std::string { return iface.GetID(); }, - [&]() -> std::string { return iface.GetID(); }); + CB_CTOR_FRONT, stream, + [&]() -> std::string { return iface.GetID(); }, + [&]() -> std::string { return iface.GetID(); }); for (const auto& i : iface.GetAttributes()) { if (i->GetKey() == "privilege") { @@ -204,6 +224,21 @@ void CsStubGen::GenCtor(std::ofstream& stream, const Interface& iface) { stream << Tab(4) << "SetTrusted(" << i->GetValue() << ");" << NLine(1); } } + + for (const auto& i : iface.GetDeclarations()) { + if (i->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + + std::string code = GenPrivileges(*i, i->GetID()); + if (code.empty()) + continue; + + ReplaceAll(CB_PRIVILEGE_MAP_BASE) + .Change("", i->GetID()) + .Change("", code) + .Out(stream); + } + stream << Tab(3) << "}" << NLine(1); } diff --git a/idlc/gen/version2/cs_stub_generator.h b/idlc/gen/version2/cs_stub_generator.h index ddbafda..35d5f2b 100644 --- a/idlc/gen/version2/cs_stub_generator.h +++ b/idlc/gen/version2/cs_stub_generator.h @@ -40,6 +40,8 @@ class CsStubGen : public CsGeneratorBase { void GenServiceBase(std::ofstream& stream, const Interface& iface); void GenReceivedEvent(std::ofstream& stream, const Interface& iface); void GenConnectedEvent(std::ofstream& stream); + void GenCheckPrivilege(std::ofstream& stream); + std::string GenPrivileges(const Declaration& decl, const std::string& id); void GenDisconnectedEvent(std::ofstream& stream); void GenCtor(std::ofstream& stream, const Interface& iface); void GenCommonMethods(std::ofstream& stream); diff --git a/idlc/gen/version2/cs_stub_generator_cb.h b/idlc/gen/version2/cs_stub_generator_cb.h index 2f8a17c..0340399 100644 --- a/idlc/gen/version2/cs_stub_generator_cb.h +++ b/idlc/gen/version2/cs_stub_generator_cb.h @@ -24,12 +24,16 @@ const char CB_DATA_MEMBERS[] = R"__cs_cb( private List _services = new List(); private Type _serviceType; private static readonly string _tidlVersion = ""; + private Dictionary> _privilege_map = new Dictionary>(); )__cs_cb"; const char CB_SERVICE_BASE_FRONT[] = R"__cs_cb( public abstract class ServiceBase { + internal bool _is_app = true; + internal List _privileges; + /// /// The client app ID /// @@ -56,6 +60,19 @@ R"__cs_cb( { } + internal void LoadPrivilege() + { + ApplicationInfo info = new ApplicationInfo(Sender); + if (info.PackageId == string.Empty) + { + _is_app = false; + return; + } + + Package pkg = PackageManager.GetPackage(info.PackageId); + _privileges = new List(pkg.Privileges); + } + /// /// Disconnects from the proxy app /// @@ -79,6 +96,34 @@ R"__cs_cb( public abstract void OnTerminate(); )__cs_cb"; + +const char CB_CHECK_PRIVILEGE_METHOD[] = +R"__cs_cb( + private bool CheckPrivilege(MethodId id, ServiceBase b) + { + if (_privilege_map.ContainsKey(id) == false) + return true; + + foreach (var item in _privilege_map[id]) + { + if (b._privileges.Contains(item) == false) { + Tizen.Log.Error("RPC_PORT", "Permission denied. " + b.Sender + " : " + item); + return false; + } + } + + return true; + } +)__cs_cb"; + +const char CB_PRIVILEGE_MAP_BASE[] = +R"__cs_cb( + List list = new List(); + + _privilege_map[MethodId.] = list; +)__cs_cb"; + + const char CB_ON_RECEIVED_EVENT_FRONT[] = R"__cs_cb( protected override bool OnReceivedEvent(string sender, string instance, Port port) @@ -120,6 +165,12 @@ R"__cs_cb( map.Read("[METHOD]", "int", out cmd); + if (b._is_app && CheckPrivilege((MethodId)cmd, b) == false) + { + //send exception + return false; + } + switch ((MethodId)cmd) { )__cs_cb"; @@ -150,6 +201,7 @@ R"__cs_cb( { ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase; s.Sender = sender; + s.LoadPrivilege(); s.Instance = instance; s.Port = GetPort(Port.Type.Callback, instance); s.OnCreate(); -- 2.7.4