Add new AccessControl and Remove sender_appid from dbus 50/170650/8 submit/tizen/20180312.233038
authorInkyun Kil <inkyun.kil@samsung.com>
Wed, 21 Feb 2018 07:11:44 +0000 (16:11 +0900)
committerInkyun Kil <inkyun.kil@samsung.com>
Wed, 28 Feb 2018 05:57:22 +0000 (14:57 +0900)
- Add new AccessControl for trusted app
- Remove sender_appid that was passed through dbus

Change-Id: I648bdbfa8bc97a8c363ffa994ebe5d71a10c6288
Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
include/rpc-port.h
src/ac-internal.cc
src/ac-internal.h
src/fdbroker-internal.cc
src/fdbroker-internal.h
src/rpc-port.cc
src/stub-internal.cc
src/stub-internal.h

index 7897990..855c14e 100755 (executable)
@@ -21,6 +21,8 @@
 extern "C" {
 #endif
 
+#include <stdbool.h>
+
 /* common */
 typedef void *rpc_port_h;
 int rpc_port_read(rpc_port_h h, void *buf, unsigned int size);
@@ -62,6 +64,7 @@ int rpc_port_stub_create(rpc_port_stub_h *h, const char *port_name);
 int rpc_port_stub_destroy(rpc_port_stub_h h);
 int rpc_port_stub_listen(rpc_port_stub_h h);
 int rpc_port_stub_add_privilege(rpc_port_stub_h h, const char *privilege);
+int rpc_port_stub_set_trusted(rpc_port_stub_h h, const bool trusted);
 int rpc_port_stub_add_connected_event_cb(rpc_port_stub_h h,
                rpc_port_stub_connected_event_cb cb, void *data);
 int rpc_port_stub_add_disconnected_event_cb(rpc_port_stub_h h,
index 7ce273c..97f47af 100644 (file)
@@ -18,7 +18,9 @@
 #define _GNU_SOURCE
 #endif
 
+#include <aul.h>
 #include <dlog.h>
+#include <pkgmgr-info.h>
 #include <cynara-error.h>
 #include <cynara-creds-gdbus.h>
 
@@ -39,12 +41,11 @@ void AccessController::AddPrivilege(const std::string& privilege) {
   privileges_.push_back(privilege);
 }
 
-int AccessController::CheckPrivilege(GDBusConnection *connection, const char* sender_appid) {
-  Cynara c;
-
-  if (c.FetchCredsFromDBus(connection, sender_appid) != 0 )
-    return -1;
+void AccessController::SetTrusted(const bool trusted) {
+  trusted_ = trusted;
+}
 
+int AccessController::CheckPrivilege(Cynara& c) {
   for (auto& privilege : privileges_) {
     if (c.Check(privilege) != 0) {
       return -1;
@@ -54,6 +55,51 @@ int AccessController::CheckPrivilege(GDBusConnection *connection, const char* se
   return 0;
 }
 
+int AccessController::CheckTrusted(const char* sender_appid) {
+  if (appid_.empty()) {
+    char appid[255];
+    if (aul_app_get_appid_bypid(getpid(), appid, sizeof(appid)) < 0)
+      return -1;
+
+    appid_ = appid;
+  }
+
+  LOGD("CheckCertificate : %s :: %s", appid_.c_str(), sender_appid);
+  pkgmgrinfo_cert_compare_result_type_e res;
+  int ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(appid_.c_str(), sender_appid, getuid(), &res);
+  if (ret < 0) {
+    LOGE("CheckCertificate() Failed");
+    return -1;
+  }
+  if (res != PMINFO_CERT_COMPARE_MATCH) {
+    LOGE("CheckCertificate() Failed : MESSAGE_PORT_ERROR_CERTIFICATE_NOT_MATCH");
+    return -1;
+  }
+
+  return 0;
+}
+
+int AccessController::Check(GDBusConnection* connection, const char* sender,
+    const char* sender_appid) {
+  Cynara c;
+  int ret = 0;
+
+  if (c.FetchCredsFromDBus(connection, sender) != 0)
+    return -1;
+
+  if (!privileges_.empty()) {
+    ret = CheckPrivilege(c);
+    if (ret)
+      return ret;
+  }
+
+  if (trusted_) {
+    ret = CheckTrusted(sender_appid);
+  }
+
+  return ret;
+}
+
 int AccessController::SetCache(const std::string& sender) {
   return -1;
 }
@@ -77,7 +123,7 @@ AccessController::Cynara::~Cynara() {
     cynara_finish(cynara_);
 }
 
-int AccessController::Cynara::FetchCredsFromDBus(GDBusConnection *connection, const char *sender_appid) {
+int AccessController::Cynara::FetchCredsFromDBus(GDBusConnection* connection, const char* sender) {
   int ret;
 
   if (client_) {
@@ -90,13 +136,13 @@ int AccessController::Cynara::FetchCredsFromDBus(GDBusConnection *connection, co
     user_ = nullptr;
   }
 
-  ret = cynara_creds_gdbus_get_user(connection, sender_appid, USER_METHOD_DEFAULT, &user_);
+  ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user_);
   if (ret != CYNARA_API_SUCCESS) {
     LOGE("cynara_creds_gdbus_get_user() is failed : %d", ret);
     return -1;
   }
 
-  ret = cynara_creds_gdbus_get_client(connection, sender_appid, CLIENT_METHOD_DEFAULT, &client_);
+  ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client_);
   if (ret != CYNARA_API_SUCCESS) {
     LOGE("cynara_creds_gdbus_get_client() is failed : %d", ret);
     return -1;
@@ -107,9 +153,9 @@ int AccessController::Cynara::FetchCredsFromDBus(GDBusConnection *connection, co
 }
 
 int AccessController::Cynara::Check(const std::string& privilege) {
-  LOGD("check %s", privilege.c_str());
+  LOGD("check privilege %s", privilege.c_str());
   if (cynara_check(cynara_, client_, "", user_, privilege.c_str()) != CYNARA_API_ACCESS_ALLOWED) {
-    LOGE("cynara_check() is failed : %s", privilege.c_str());
+    LOGD("cynara_check() is not allowed : %s", privilege.c_str());
     return -1;
   }
 
index 1948ff0..9a9ae63 100644 (file)
@@ -31,20 +31,20 @@ namespace internal {
 
 class AccessController {
  public:
+  AccessController(bool trusted = false) : trusted_(trusted) {}
   virtual ~AccessController();
 
   void AddPrivilege(const std::string& privilege);
-  int CheckPrivilege(GDBusConnection *connection, const char* sender_appid);
+  void SetTrusted(const bool trusted);
+  int Check(GDBusConnection *connection, const char *sender, const char* sender_appid);
 
  private:
-  int SetCache(const std::string& sender);
-
   class Cynara {
    public:
      Cynara();
      ~Cynara();
 
-     int FetchCredsFromDBus(GDBusConnection *connection, const char *sender_appid);
+     int FetchCredsFromDBus(GDBusConnection *connection, const char *sender);
      int Check(const std::string& privilege);
 
    private:
@@ -53,9 +53,15 @@ class AccessController {
      char *user_;
   };
 
+  int SetCache(const std::string& sender);
+  int CheckTrusted(const char *sender_appid);
+  int CheckPrivilege(Cynara& c);
+
  private:
   std::vector<std::string> privileges_;
   std::map<std::string, bool> cache_;
+  bool trusted_;
+  std::string appid_;
 };
 
 }  // namespace internal
index 451ab34..ce59d32 100644 (file)
@@ -225,7 +225,6 @@ int FdBroker::Send(const std::string& target_appid,
   GDBusMessage *msg;
   GDBusMessage *reply;
   GError *err = nullptr;
-  GVariant *body;
   GVariant *reply_body;
   SocketPair sock_pair(mock_);
   FdList fd_list;
@@ -261,9 +260,7 @@ int FdBroker::Send(const std::string& target_appid,
     return -1;
   }
 
-  body = g_variant_new("(s)", sender_appid);
   g_dbus_message_set_unix_fd_list(msg, fd_list.GetRaw());
-  g_dbus_message_set_body(msg, body);
   reply = g_dbus_connection_send_message_with_reply_sync(DBusConnectionManager::GetInst().GetConnection(),
                                  msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 500,
                                  nullptr, nullptr, &err);
@@ -298,21 +295,13 @@ int FdBroker::Send(const std::string& target_appid,
   return fd;
 }
 
-void FdBroker::ReceiveMessage(GVariant* parameters,
+void FdBroker::ReceiveMessage(const char* sender_appid,
                               GDBusMethodInvocation* invocation) {
-  char* sender_appid = nullptr;
   GDBusMessage* msg;
   GUnixFDList* fd_list;
   int fd_len;
   int* returned_fds = nullptr;
 
-  g_variant_get(parameters, "(&s)", &sender_appid);
-
-  if (sender_appid == nullptr) {
-    LOGE("Invalid argument : sender_appid is NULL");
-    return;
-  }
-
   msg = g_dbus_method_invocation_get_message(invocation);
   fd_list = g_dbus_message_get_unix_fd_list(msg);
 
@@ -335,12 +324,20 @@ void FdBroker::OnReceiveDbusMethod(GDBusConnection *conn,
     GVariant *parameters, GDBusMethodInvocation *invocation,
     gpointer user_data) {
   FdBroker* broker = static_cast<FdBroker*>(user_data);
-  int ret;
+  int ret = -1;
+  char sender_appid[255];
+  int sender_pid;
+
+  sender_pid = broker->GetSenderPid(conn, sender);
+  if (aul_app_get_appid_bypid(sender_pid, sender_appid, sizeof(sender_appid)) < 0) {
+    g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", ret));
+    return;
+  }
 
   AccessController& ac = broker->GetAccessController();
-  ret = ac.CheckPrivilege(conn, sender);
+  ret = ac.Check(conn, sender, sender_appid);
   if (ret == 0)
-    broker->ReceiveMessage(parameters, invocation);
+    broker->ReceiveMessage(sender_appid, invocation);
 
   g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", ret));
 }
@@ -386,6 +383,44 @@ int FdBroker::GetOwnerId(const std::string& interface_name) {
   return owner_id;
 }
 
+int FdBroker::GetSenderPid(GDBusConnection *connection, const gchar *sender) {
+  GDBusMessage *msg = NULL;
+  GDBusMessage *reply = NULL;
+  GError *err = NULL;
+  GVariant *body;
+  int pid = 0;
+
+  msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
+      "org.freedesktop.DBus", "GetConnectionUnixProcessID");
+  if (!msg) {
+    LOGE("Can't allocate new method call");
+    goto out;
+  }
+
+  g_dbus_message_set_body(msg, g_variant_new("(s)", sender));
+  reply = g_dbus_connection_send_message_with_reply_sync(connection, msg,
+      G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
+
+  if (!reply) {
+    if (err != NULL) {
+      LOGE("Failed to get pid [%s]", err->message);
+      g_error_free(err);
+    }
+    goto out;
+  }
+
+  body = g_dbus_message_get_body(reply);
+  g_variant_get(body, "(u)", &pid);
+
+out:
+  if (msg)
+    g_object_unref(msg);
+  if (reply)
+    g_object_unref(reply);
+
+  return pid;
+}
+
 int FdBroker::RegisterDbusInterface(const std::string& port_name) {
   static const GDBusInterfaceVTable interface_vtable = {
     OnReceiveDbusMethod,
@@ -398,7 +433,6 @@ int FdBroker::RegisterDbusInterface(const std::string& port_name) {
   static const char introspection_postfix[] =
     "'>"
     "  <method name='send_message'>"
-    "    <arg type='s' name='sender_appid' direction='in'/>"
     "    <arg type='i' name='response' direction='out'/>"
     "  </method>"
     "  </interface>"
index 77ff32d..b5fba79 100644 (file)
@@ -143,8 +143,9 @@ class FdBroker {
                                   GDBusMethodInvocation *invocation,
                                   gpointer user_data);
   int GetOwnerId(const std::string& interface_name);
+  int GetSenderPid(GDBusConnection *connection, const gchar *sender);
   int RegisterDbusInterface(const std::string& port_name);
-  void ReceiveMessage(GVariant* parameters, GDBusMethodInvocation* invocation);
+  void ReceiveMessage(const char* sender_appid, GDBusMethodInvocation* invocation);
   std::string GetInterfaceName(const std::string& target_appid,
                                const std::string& port_name);
   static void OnNameAppeared(GDBusConnection *connection,
index 5c81f93..3c9e142 100755 (executable)
@@ -331,6 +331,19 @@ RPC_API int rpc_port_stub_add_privilege(rpc_port_stub_h h,
   return 0;
 }
 
+RPC_API int rpc_port_stub_set_trusted(rpc_port_stub_h h,
+    const bool trusted) {
+  if (h == nullptr)
+    return -1;
+
+  auto p = static_cast<::StubExt*>(h);
+  std::lock_guard<std::recursive_mutex> lock(p->GetMutex());
+
+  p->SetTrusted(trusted);
+  return 0;
+}
+
+
 RPC_API int rpc_port_stub_add_connected_event_cb(rpc_port_stub_h h,
     rpc_port_stub_connected_event_cb cb, void* data) {
   if (h == nullptr)
index 18a2dbb..c981ba5 100644 (file)
@@ -55,6 +55,11 @@ void Stub::AddPrivilege(const std::string& privilege) {
   ac.AddPrivilege(privilege);
 }
 
+void Stub::SetTrusted(const bool trusted) {
+  AccessController& ac = fd_broker_.GetAccessController();
+  ac.SetTrusted(trusted);
+}
+
 gboolean Stub::OnDataReceived(GIOChannel *gio, GIOCondition cond,
                               gpointer data) {
   Stub* stub = static_cast<Stub*>(data);
index 5819428..ab89aa3 100644 (file)
@@ -48,6 +48,7 @@ class Stub : private FdBroker::IEventListener {
 
   void Listen(IEventListener* ev);
   void AddPrivilege(const std::string& privilege);
+  void SetTrusted(const bool trusted);
 
  private:
   class AcceptedPort : public Port {