add_definitions(-DUSE_DLOG_LOGGING=1)
ENDIF(DLOG_FOUND)
-IF(SECURITY_MANAGER_FOUND)
- include_directories(${SECURITY_MANAGER_INCLUDE_DIRS})
- link_directories(${SECURITY_MANAGER_LIBRARY_DIRS})
- add_definitions(${SECURITY_MANAGER_CFLAGS_OTHER})
- add_definitions(-DUSE_SECURITY_MANAGER=1)
-ENDIF(SECURITY_MANAGER_FOUND)
-
IF(ENABLE_SYSTEMD_SUPPORT)
include_directories(${SYSTEMD_INCLUDE_DIRS})
link_directories(${SYSTEMD_LIBRARY_DIRS})
add_definitions(-DUSE_ARTIK_SECURITY_HEADERS=1)
ENDIF(ARTIK_SECURITY_FOUND)
-IF(SMACK_FOUND)
- include_directories(${SMACK_INCLUDE_DIRS})
- link_directories(${SMACK_LIBRARY_DIRS})
- add_definitions(${SMACK_CFLAGS_OTHER})
- add_definitions(-DUSE_SMACK=1)
-ENDIF(SMACK_FOUND)
+IF(CYNARA_FOUND)
+ include_directories(${CYNARA_INCLUDE_DIRS})
+ link_directories(${CYNARA_LIBRARY_DIRS})
+ add_definitions(${CYNARA_CFLAGS_OTHER})
+ add_definitions(-DUSE_CYNARA=1)
+ENDIF(CYNARA_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
IF(ENABLE_DUMMY_BACKEND)
SET(DUMMY_BACKEND_OBJECTS $<TARGET_OBJECTS:dummy_backend_objects>)
+ add_definitions(-DENABLE_DUMMY_BACKEND=1)
ENDIF(ENABLE_DUMMY_BACKEND)
-IF(SECURITY_MANAGER_FOUND)
- SET(SEE_BACKEND_OBJECTS $<TARGET_OBJECTS:see-backend>)
-ENDIF(SECURITY_MANAGER_FOUND)
+SET(SEE_BACKEND_OBJECTS $<TARGET_OBJECTS:see-backend>)
###### Main executable #######
target_link_libraries(device-certificate-managerd ${DLOG_LIBRARIES})
ENDIF(DLOG_FOUND)
-IF(SECURITY_MANAGER_FOUND)
- target_link_libraries(device-certificate-managerd ${SECURITY_MANAGER_LIBRARIES})
-ENDIF(SECURITY_MANAGER_FOUND)
-
IF(ENABLE_SYSTEMD_SUPPORT)
target_link_libraries(device-certificate-managerd ${SYSTEMD_LIBRARIES})
ENDIF(ENABLE_SYSTEMD_SUPPORT)
-IF(SMACK_FOUND)
- target_link_libraries(device-certificate-managerd ${SMACK_LIBRARIES})
-ENDIF(SMACK_FOUND)
+IF(CYNARA_FOUND)
+ target_link_libraries(device-certificate-managerd ${CYNARA_LIBRARIES})
+ENDIF(CYNARA_FOUND)
###### Installation #######
#include <map>
#include <mutex>
-#ifdef USE_SMACK
-#include <sys/smack.h>
+#ifdef USE_CYNARA
+#include <cynara-client.h>
+#include <cynara-creds-socket.h>
+#include <cynara-session.h>
#endif
-#ifdef USE_SECURITY_MANAGER
-#include <security-manager.h>
-#endif
-
-#ifdef USE_SMACK
-static char const *const OWNER_ID_SYSTEM = "/System";
-#endif
+#ifdef USE_CYNARA
+extern cynara * gGlobalCynaraInstance;
-#if defined(USE_SECURITY_MANAGER) && defined(USE_SMACK)
-static std::map<std::string, std::string> sPackageIdMapping;
-static std::mutex sPackageIdMappingMutex;
+static inline std::string cynara_error_to_string(int error) {
+ char buffer[256];
+ int ret = cynara_strerror(error, buffer, sizeof(buffer));
+ if(ret == CYNARA_API_SUCCESS)
+ return std::string(buffer);
+ return std::string("Can't translate error");
+}
#endif
dcm_session::dcm_session(boost::asio::io_service& io_service, const std::shared_ptr<dcm_server>& server) :
BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Destroy session object " << this;
}
-#if defined(USE_SMACK) && defined(USE_SECURITY_MANAGER)
-static int assignToString(std::vector<char> &vec, socklen_t len, std::string &res)
-{
- if (vec.size() <= len)
- return -1;
- vec[len] = 0; // old implementation getsockopt returns cstring without 0
- if (vec[len - 1] == 0) --len;// new implementation of getsockopt returns cstring size+1
- res.assign(vec.data(), len);
- return 0;
-}
-
-static int getCredentialsFromSocket(int sock, std::string &res)
-{
- std::vector<char> result(SMACK_LABEL_LEN + 1);
- socklen_t length = SMACK_LABEL_LEN;
-
- if (0 == getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) {
- return assignToString(result, length, res);
- }
-
- if (errno != ERANGE) {
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "getsockopt failed";
- return -1;
+struct string_free_deleter {
+ void operator()(char * p) const {
+ free(p);
}
+};
- result.resize(length + 1);
-
- if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) {
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "getsockopt failed with errno: " << errno;
- return -1;
- }
-
- return assignToString(result, length, res);
-}
-
-static int getPkgIdFromSocket(int sock, std::string &pkgId)
+bool dcm_session::verify_privileges(int handle)
{
- char *pkg = nullptr;
+#ifdef USE_CYNARA
+ BOOST_LOG_FUNCTION();
- int ret = security_manager_identify_app_from_socket(sock, &pkg, nullptr);
+ int ret = 0;
+ char * tmp_str;
+ pid_t pid = 0;
- if (ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT) {
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Owner of socket is not connected with pkgid. "
- "This case must be special-labled client. e.g. User, System";
- return 1;
- }
+ std::unique_ptr<char, string_free_deleter> user;
+ std::unique_ptr<char, string_free_deleter> client;
+ std::unique_ptr<char, string_free_deleter> client_session;
- if (ret != SECURITY_MANAGER_SUCCESS) {
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "security_manager_identify_app_from_socket failed with error: "
- << ret;
- return -1;
+ /* Get user info */
+ tmp_str = nullptr;
+ ret = cynara_creds_socket_get_user(handle, USER_METHOD_DEFAULT, &tmp_str);
+ if(ret != CYNARA_API_SUCCESS) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get user from socket : " << ret << " - " << cynara_error_to_string(ret);
+ return false;
}
+ user.reset(tmp_str);
- try {
- pkgId = pkg;
- } catch(...) {
- free(pkg);
- throw;
+ /* Get client info */
+ tmp_str = nullptr;
+ ret = cynara_creds_socket_get_client(handle, CLIENT_METHOD_DEFAULT, &tmp_str);
+ if(ret != CYNARA_API_SUCCESS) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get client from socket : " << ret << " - " << cynara_error_to_string(ret);
+ return false;
}
+ client.reset(tmp_str);
- free(pkg);
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Socket: " << sock << " Was translated to owner id: " << pkgId;
- return 0;
-}
-
-static void mapToDomainLabel(std::string &label)
-{
- static const std::string subdomainSep = "::";
- static const auto systemLabelLen = strlen(OWNER_ID_SYSTEM);
- if (label.length() > systemLabelLen + subdomainSep.length() &&
- label.compare(0, systemLabelLen, OWNER_ID_SYSTEM) == 0 &&
- label.compare(systemLabelLen, subdomainSep.length(), subdomainSep) == 0) {
- label = OWNER_ID_SYSTEM;
+ /* Get client PID from socket */
+ ret = cynara_creds_socket_get_pid(handle, &pid);
+ if(ret != CYNARA_API_SUCCESS) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get PID from socket : " << ret << " - " << cynara_error_to_string(ret);
+ return false;
}
-}
-#endif
-
-bool dcm_session::get_client_id(int handle, std::string& result)
-{
- BOOST_LOG_FUNCTION();
-
-#if defined(USE_SMACK) && defined(USE_SECURITY_MANAGER)
- try {
- std::string smackLabel;
- int error = getCredentialsFromSocket(handle, smackLabel);
-
- if(error < 0) {
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Socket access failure. Disconnecting";
- return false;
- }
-
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Client credential is " << smackLabel;
-
- std::unique_lock<std::mutex> locker(sPackageIdMappingMutex);
-
- auto it = sPackageIdMapping.find(smackLabel);
- if(it != sPackageIdMapping.end()) {
- result = it->second;
- return true;
- }
-
- std::string pkgId;
- int retCode = getPkgIdFromSocket(handle, pkgId);
-
- if (retCode < 0) {
- return false;
- }
-
- if (retCode == 1) {
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Special smack label case. label: " << smackLabel;
- pkgId = "/" + smackLabel;
- }
+ client_session.reset(cynara_session_from_pid(pid));
+ if(!client_session) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't get session identifier from PID";
+ return false;
+ }
- mapToDomainLabel(pkgId);
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Got new session from " << pid << " with user " <<
+ user.get() << ", client ID " << client.get() << " and session ID " << client_session.get();
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << smackLabel << " mapped to " << pkgId;
+ ret = cynara_check(gGlobalCynaraInstance,
+ client.get(),
+ client_session.get(),
+ user.get(),
+ "http://tizen.org/privilege/internet");
- result = pkgId;
- sPackageIdMapping.emplace(std::move(smackLabel), std::move(pkgId));
+ if(ret != CYNARA_API_ACCESS_ALLOWED) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) <<
+ "Application access denied - no internet permission for " <<
+ pid <<
+ " - " <<
+ cynara_error_to_string(ret);
- return true;
- } catch(std::exception& ex) {
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught exception when translating socket: " << ex.what();
- return false;
- } catch(...) {
- BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Caught unknown exception when translating socket";
return false;
}
+
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Access granted for " << pid;
+#else
+ (void)handle;
#endif
return true;
BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Accepted connection with socket " << fSocket.native_handle();
std::string label;
- if(get_client_id(handle, label)) {
+ if(verify_privileges(handle)) {
do_receive();
+ } else {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Client privilege check failure. Disconnect";
}
}
#include <boost_log_dlog_sink.h>
+#ifdef USE_CYNARA
+#include <cynara-client.h>
+#endif
+
namespace po = boost::program_options;
struct OptionContext {
boost::log::core::get()->add_thread_attribute("Scope", boost::log::attributes::named_scope());
}
+#ifdef USE_CYNARA
+cynara * gGlobalCynaraInstance;
+#endif
+
int main(int argc, char ** argv)
{
+ int error = 0;
+
init_logging();
BOOST_LOG_FUNCTION();
service_adapter serviceAdapter(options.fSocketName);
+#ifdef USE_CYNARA
+ cynara_configuration * cynara_conf = nullptr;
+ error = cynara_configuration_create(&cynara_conf);
+ if(error != CYNARA_API_SUCCESS) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't initialize Cynara configuration: " << error;
+ serviceAdapter.notify_start_failure(error);
+ return EXIT_FAILURE;
+ }
+
+ error = cynara_initialize(&gGlobalCynaraInstance, cynara_conf);
+
+ cynara_configuration_destroy(cynara_conf);
+
+ if(error != CYNARA_API_SUCCESS) {
+ BOOST_LOG_SEV(dcm_logger::get(), log_severity::error) << "Can't initialize Cynara instance: " << error;
+ serviceAdapter.notify_start_failure(error);
+ return EXIT_FAILURE;
+ }
+#endif
+
try {
boost::asio::io_service io_service;
(void)umask(0);
/* Use root directory as working directory */
- int error = chdir("/");
+ error = chdir("/");
(void)error; // Don't care
BOOST_LOG_SEV(dcm_logger::get(), log_severity::debug) << "Create platform socket";
return EXIT_FAILURE;
}
+#ifdef USE_CYNARA
+ cynara_finish(gGlobalCynaraInstance);
+ gGlobalCynaraInstance = nullptr;
+#endif
+
BOOST_LOG_SEV(dcm_logger::get(), log_severity::normal) << "Server terminated";
return 0;