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);
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,
#define _GNU_SOURCE
#endif
+#include <aul.h>
#include <dlog.h>
+#include <pkgmgr-info.h>
#include <cynara-error.h>
#include <cynara-creds-gdbus.h>
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;
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;
}
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_) {
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;
}
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;
}
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:
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
GDBusMessage *msg;
GDBusMessage *reply;
GError *err = nullptr;
- GVariant *body;
GVariant *reply_body;
SocketPair sock_pair(mock_);
FdList fd_list;
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);
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);
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));
}
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,
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>"
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,
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)
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);
void Listen(IEventListener* ev);
void AddPrivilege(const std::string& privilege);
+ void SetTrusted(const bool trusted);
private:
class AcceptedPort : public Port {