From fc87b7c292bb3ab6d9f735c2b52b059a40d17fa9 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Wed, 12 Apr 2017 11:00:27 +0900 Subject: [PATCH] sensord: check privilege everytime for every request - check privilege for get_sensor/get_sensor_list - check privilege for all controls Change-Id: I7148c7d506bb1eaa01046e60b1b81a0ce5ec899a Signed-off-by: kibak.yoon --- src/client/sensor_manager.cpp | 64 +++++++++++++++++++++++++++++------ src/client/sensor_manager.h | 1 + src/server/sensor_listener_proxy.cpp | 6 ++++ src/server/sensor_listener_proxy.h | 1 + src/server/server_channel_handler.cpp | 61 +++++++++++++++++++++++++++++++++ src/server/server_channel_handler.h | 5 +++ src/shared/command_types.h | 6 ++++ 7 files changed, 134 insertions(+), 10 deletions(-) diff --git a/src/client/sensor_manager.cpp b/src/client/sensor_manager.cpp index 5602312..c50cdae 100644 --- a/src/client/sensor_manager.cpp +++ b/src/client/sensor_manager.cpp @@ -27,6 +27,8 @@ #include #include +#define SIZE_STR_SENSOR_ALL 27 + using namespace sensor; class manager_handler : public ipc::channel_handler @@ -81,20 +83,22 @@ int sensor_manager::get_sensors(sensor_type_t type, sensor_t **list, int *count) int sensor_manager::get_sensor(const char *uri, sensor_t *sensor) { - sensor_info *info; - - info = get_info(uri); - if (!info) { + if (!is_supported(uri)) { *sensor = NULL; return -ENODATA; } + sensor_info *info = get_info(uri); + retv_if(!info, -EACCES); + *sensor = (sensor_t)info; return OP_SUCCESS; } int sensor_manager::get_sensors(const char *uri, sensor_t **list, int *count) { + retv_if(!is_supported(uri), -ENODATA); + std::vector infos; int size; @@ -130,8 +134,13 @@ bool sensor_manager::is_supported(sensor_t sensor) bool sensor_manager::is_supported(const char *uri) { + if (strncmp(uri, utils::get_uri(ALL_SENSOR), SIZE_STR_SENSOR_ALL) == 0) + return true; + for (auto it = m_infos.begin(); it != m_infos.end(); ++it) { - if ((*it).get_uri() == uri) + std::size_t found = (*it).get_uri().rfind(uri); + + if (found != std::string::npos) return true; } @@ -260,9 +269,34 @@ bool sensor_manager::get_sensors_internal(void) return true; } +bool sensor_manager::has_privilege(std::string &uri) +{ + retvm_if(!is_connected(), false, "Failed to get sensors"); + + bool ret; + ipc::message msg; + ipc::message reply; + cmd_has_privilege_t buf = {0, }; + + msg.set_type(CMD_HAS_PRIVILEGE); + memcpy(buf.sensor, uri.c_str(), uri.size()); + msg.enclose((const char *)&buf, sizeof(buf)); + + ret = m_channel->send_sync(&msg); + retvm_if(!ret, false, "Failed to send message"); + + ret = m_channel->read_sync(reply); + retvm_if(!ret, false, "Failed to receive message"); + + if (reply.header()->err == OP_SUCCESS) + return true; + + return false; +} + sensor_info *sensor_manager::get_info(const char *uri) { - if (strncmp(uri, utils::get_uri(ALL_SENSOR), 27) == 0) + if (strncmp(uri, utils::get_uri(ALL_SENSOR), SIZE_STR_SENSOR_ALL) == 0) return &m_infos[0]; for (auto it = m_infos.begin(); it != m_infos.end(); ++it) { @@ -271,7 +305,11 @@ sensor_info *sensor_manager::get_info(const char *uri) if (found == std::string::npos) continue; - return &*it; + if ((*it).get_privilege().empty()) + return &*it; + + if (has_privilege((*it).get_uri())) + return &*it; } return NULL; @@ -282,16 +320,22 @@ std::vector sensor_manager::get_infos(const char *uri) std::vector infos; bool all = false; - if (strncmp(uri, utils::get_uri(ALL_SENSOR), 27) == 0) + if (strncmp(uri, utils::get_uri(ALL_SENSOR), SIZE_STR_SENSOR_ALL) == 0) all = true; - for (auto it = m_infos.begin(); it != m_infos.end(); ++it) { +for (auto it = m_infos.begin(); it != m_infos.end(); ++it) { std::size_t found = (*it).get_uri().rfind(uri); if (!all && found == std::string::npos) continue; - infos.push_back(&*it); + if ((*it).get_privilege().empty()) { + infos.push_back(&*it); + continue; + } + + if (has_privilege((*it).get_uri())) + infos.push_back(&*it); } return infos; diff --git a/src/client/sensor_manager.h b/src/client/sensor_manager.h index 35ae863..5cb7d40 100644 --- a/src/client/sensor_manager.h +++ b/src/client/sensor_manager.h @@ -65,6 +65,7 @@ private: void decode_sensors(const char *buf, std::vector &infos); bool get_sensors_internal(void); + bool has_privilege(std::string &uri); sensor_info *get_info(const char *uri); std::vector get_infos(const char *uri); diff --git a/src/server/sensor_listener_proxy.cpp b/src/server/sensor_listener_proxy.cpp index 29608b0..b542af8 100644 --- a/src/server/sensor_listener_proxy.cpp +++ b/src/server/sensor_listener_proxy.cpp @@ -127,3 +127,9 @@ int sensor_listener_proxy::get_data(sensor_data_t **data, int *len) /* TODO : caching the last data & retry logic if there is no data */ return m_sensor->get_data(data, len); } + +std::string sensor_listener_proxy::get_required_privileges(void) +{ + sensor_info info = m_sensor->get_sensor_info(); + return info.get_privilege(); +} diff --git a/src/server/sensor_listener_proxy.h b/src/server/sensor_listener_proxy.h index 709f057..583cf36 100644 --- a/src/server/sensor_listener_proxy.h +++ b/src/server/sensor_listener_proxy.h @@ -48,6 +48,7 @@ public: int set_attribute(int attribute, const char *value, int len); int flush(void); int get_data(sensor_data_t **data, int *len); + std::string get_required_privileges(void); private: uint32_t m_id; diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index a34f58f..1c18d1d 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -22,8 +22,13 @@ #include #include #include +#include #include +#include "permission_checker.h" + +#define PRIV_DELIMINATOR ";" + using namespace sensor; using namespace ipc; @@ -78,6 +83,8 @@ void server_channel_handler::read(channel *ch, message &msg) err = provider_disconnect(ch, msg); break; case CMD_PROVIDER_POST: err = provider_post(ch, msg); break; + case CMD_HAS_PRIVILEGE: + err = has_privileges(ch, msg); break; default: break; } @@ -118,6 +125,8 @@ int server_channel_handler::listener_connect(channel *ch, message &msg) sensor_listener_proxy *listener = new(std::nothrow) sensor_listener_proxy(listener_id, sensor, ch); retvm_if(!listener, OP_ERROR, "Failed to allocate memory"); + retvm_if(!has_privileges(ch->get_fd(), listener->get_required_privileges()), + -EACCES, "Permission denied"); buf.listener_id = listener_id; @@ -142,6 +151,9 @@ int server_channel_handler::listener_disconnect(channel *ch, message &msg) uint32_t id = m_listeners[ch]->get_id(); + retvm_if(!has_privileges(ch->get_fd(), m_listeners[ch]->get_required_privileges()), + -EACCES, "Permission denied"); + delete m_listeners[ch]; m_listeners.erase(ch); @@ -154,6 +166,8 @@ int server_channel_handler::listener_start(channel *ch, message &msg) { auto it = m_listeners.find(ch); retv_if(it == m_listeners.end(), -EINVAL); + retvm_if(!has_privileges(ch->get_fd(), m_listeners[ch]->get_required_privileges()), + -EACCES, "Permission denied"); int ret = m_listeners[ch]->start(); retv_if(ret < 0, ret); @@ -165,6 +179,8 @@ int server_channel_handler::listener_stop(channel *ch, message &msg) { auto it = m_listeners.find(ch); retv_if(it == m_listeners.end(), -EINVAL); + retvm_if(!has_privileges(ch->get_fd(), m_listeners[ch]->get_required_privileges()), + -EACCES, "Permission denied"); int ret = m_listeners[ch]->stop(); retv_if(ret < 0, ret); @@ -178,6 +194,8 @@ int server_channel_handler::listener_attr_int(channel *ch, message &msg) auto it = m_listeners.find(ch); retv_if(it == m_listeners.end(), -EINVAL); + retvm_if(!has_privileges(ch->get_fd(), m_listeners[ch]->get_required_privileges()), + -EACCES, "Permission denied"); cmd_listener_attr_int_t buf; msg.disclose((char *)&buf); @@ -203,6 +221,8 @@ int server_channel_handler::listener_attr_str(channel *ch, message &msg) { auto it = m_listeners.find(ch); retv_if(it == m_listeners.end(), -EINVAL); + retvm_if(!has_privileges(ch->get_fd(), m_listeners[ch]->get_required_privileges()), + -EACCES, "Permission denied"); cmd_listener_attr_str_t buf; msg.disclose((char *)&buf); @@ -215,6 +235,11 @@ int server_channel_handler::listener_attr_str(channel *ch, message &msg) int server_channel_handler::listener_get_data(channel *ch, message &msg) { + auto it = m_listeners.find(ch); + retv_if(it == m_listeners.end(), -EINVAL); + retvm_if(!has_privileges(ch->get_fd(), m_listeners[ch]->get_required_privileges()), + -EACCES, "Permission denied"); + return send_reply(ch, OP_ERROR); } @@ -233,9 +258,45 @@ int server_channel_handler::provider_post(channel *ch, message &msg) return send_reply(ch, OP_ERROR); } +int server_channel_handler::has_privileges(channel *ch, message &msg) +{ + sensor_handler *sensor; + cmd_has_privilege_t buf; + msg.disclose((char *)&buf); + + sensor = m_manager->get_sensor(buf.sensor); + retv_if(!sensor, OP_ERROR); + + sensor_info info = sensor->get_sensor_info(); + + if (!has_privileges(ch->get_fd(), info.get_privilege())) + return OP_ERROR; + + return send_reply(ch, OP_SUCCESS); +} + int server_channel_handler::send_reply(channel *ch, int error) { message reply(error); retvm_if(!ch->send_sync(&reply), OP_ERROR, "Failed to send reply"); return OP_SUCCESS; } + +bool server_channel_handler::has_privilege(int fd, std::string &priv) +{ + static permission_checker checker; + return checker.has_permission(fd, priv); +} + +bool server_channel_handler::has_privileges(int fd, std::string priv) +{ + std::vector privileges; + privileges = utils::tokenize(priv, PRIV_DELIMINATOR); + + for (auto it = privileges.begin(); it != privileges.end(); ++it) { + if (!has_privilege(fd, *it)) + return false; + } + + return true; +} diff --git a/src/server/server_channel_handler.h b/src/server/server_channel_handler.h index d48ff7e..1ccc998 100644 --- a/src/server/server_channel_handler.h +++ b/src/server/server_channel_handler.h @@ -58,6 +58,11 @@ private: int provider_disconnect(ipc::channel *ch, ipc::message &msg); int provider_post(ipc::channel *ch, ipc::message &msg); + int has_privileges(ipc::channel *ch, ipc::message &msg); + + bool has_privilege(int fd, std::string &priv); + bool has_privileges(int fd, std::string priv); + int send_reply(ipc::channel *ch, int error); sensor_manager *m_manager; diff --git a/src/shared/command_types.h b/src/shared/command_types.h index 81d4a21..6b5e0c6 100644 --- a/src/shared/command_types.h +++ b/src/shared/command_types.h @@ -51,6 +51,8 @@ enum cmd_type_e { CMD_PROVIDER_DISCONNECT, CMD_PROVIDER_POST, + CMD_HAS_PRIVILEGE, + CMD_CNT, }; @@ -113,4 +115,8 @@ typedef struct { sensorhub_data_t base_data; } cmd_provider_post_t; +typedef struct { + char sensor[NAME_MAX]; +} cmd_has_privilege_t ; + #endif /* __COMMAND_TYPES_H__ */ -- 2.7.4