From de33ab8e1abc2552745de54967f3b3516a26723e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Oskar=20=C5=9Awitalski?= Date: Mon, 16 Nov 2015 13:01:34 +0100 Subject: [PATCH] Add cynara privilege checks MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Privilege "http://tizen.org/privilege/imemanager" is checked when set_initial_ise_by_uuid() or set_active_ise_by_uuid() is used Change-Id: I0f3a8edfef79eddf098ced86814e79b263353643 Signed-off-by: Oskar Świtalski --- configure.ac | 7 ++- ism/src/Makefile.am | 8 ++- ism/src/privilege_checker.cpp | 120 ++++++++++++++++++++++++++++++++++++++++++ ism/src/privilege_checker.h | 25 +++++++++ ism/src/scim_panel_agent.cpp | 16 ++++-- ism/src/scim_socket.cpp | 9 +++- ism/src/scim_socket.h | 11 ++++ packaging/isf.spec | 3 ++ 8 files changed, 191 insertions(+), 8 deletions(-) create mode 100644 ism/src/privilege_checker.cpp create mode 100644 ism/src/privilege_checker.h diff --git a/configure.ac b/configure.ac index 4dbfa3c..63756bf 100644 --- a/configure.ac +++ b/configure.ac @@ -40,7 +40,7 @@ SCIM_CURRENT=10 SCIM_REVISION=3 # increment if any interfaces have been added; set to 0 -# if any interfaces have been removed. removal has +# if any interfaces have been removed. removal has # precedence over adding, so set to 0 if both happened. SCIM_AGE=2 @@ -109,7 +109,7 @@ DOXYGEN=no if test "x$with_doxygen" != "xno"; then AC_PATH_PROG(DOXYGEN, doxygen, no) fi - + AM_CONDITIONAL(HAVE_DOXYGEN, test x$DOXYGEN != xno) AC_SUBST(DOXYGEN) @@ -284,6 +284,9 @@ if test "$ISF_HAS_TTS" = "yes"; then AC_DEFINE(HAVE_TTS,1,[Have TTS functions.]) fi +# Check cynara liblaries +PKG_CHECK_MODULES(CYNARA, [cynara-client, cynara-creds-socket, cynara-session]) + # Check vconf library PKG_CHECK_MODULES(VCONF, [vconf], [ISF_HAS_VCONF=yes], diff --git a/ism/src/Makefile.am b/ism/src/Makefile.am index 2cd5ed0..6e0c49d 100644 --- a/ism/src/Makefile.am +++ b/ism/src/Makefile.am @@ -92,7 +92,8 @@ libsciminclude_HEADERS = scim.h \ isf_control.h \ isf_imcontrol_client.h \ ise_context.h \ - scim_visibility.h + scim_visibility.h \ + privilege_checker.h noinst_LTLIBRARIES = libltdlc.la @@ -141,10 +142,12 @@ libscim@SCIM_EPOCH@_la_SOURCES = \ scim_setup_module_efl.cpp \ isf_control.cpp \ isf_imcontrol_client.cpp \ - isf_query_utility.cpp + isf_query_utility.cpp \ + privilege_checker.cpp libscim@SCIM_EPOCH@_la_CXXFLAGS = @EFL_CFLAGS@ @TZPLATFORM_CONFIG_CFLAGS@\ @DLOG_CFLAGS@ \ + @CYNARA_CFLAGS@ \ @VCONF_CFLAGS@ libscim@SCIM_EPOCH@_la_LDFLAGS = -version-info $(SCIM_CURRENT):$(SCIM_REVISION):$(SCIM_AGE) \ @@ -156,6 +159,7 @@ libscim@SCIM_EPOCH@_la_LDFLAGS = -version-info $(SCIM_CURRENT):$(SCIM_REVISION) @LIBICONV@ \ @LTLIBINTL@ \ @EFL_LIBS@ \ + @CYNARA_LIBS@ \ @VCONF_LIBS@ \ @TZPLATFORM_CONFIG_LIBS@ \ -lstdc++ diff --git a/ism/src/privilege_checker.cpp b/ism/src/privilege_checker.cpp new file mode 100644 index 0000000..cb71ffc --- /dev/null +++ b/ism/src/privilege_checker.cpp @@ -0,0 +1,120 @@ +#include "privilege_checker.h" + +#include +#include + +#include +#include +#include +#include + +#include "scim.h" + +namespace +{ + +cynara *p_cynara = NULL; + +void +cynara_log (const char *string, int cynara_status) { + const int buflen = 255; + char buf[buflen]; + + int ret = cynara_strerror(cynara_status, buf, buflen); + if (ret != CYNARA_API_SUCCESS) { + strncpy(buf, "cynara_strerror failed", buflen); + buf[buflen - 1] = '\0'; + } + + SCIM_DEBUG_MAIN (cynara_status < 0 ? 1 : 3) << string << ": " << buf; +} + +} + +PrivilegeChecker::PrivilegeChecker (int sockfd) +{ + m_client = NULL; + m_session = NULL; + m_user = NULL; + m_sockfd = sockfd; +} + +PrivilegeChecker::~PrivilegeChecker () +{ + free (m_client); + free (m_session); + free (m_user); +} + +bool +PrivilegeChecker::initializeCreditionals () +{ + if (m_client) + return true; + + int ret; + int pid; + + ret = cynara_creds_socket_get_client (m_sockfd, CLIENT_METHOD_DEFAULT, &m_client); + cynara_log("cynara_creds_socket_get_client()", ret); + if (ret != CYNARA_API_SUCCESS) { + goto CLEANUP; + } + + ret = cynara_creds_socket_get_user (m_sockfd, USER_METHOD_DEFAULT, &m_user); + cynara_log("cynara_creds_socket_get_user()", ret); + if (ret != CYNARA_API_SUCCESS) { + goto CLEANUP; + } + + ret = cynara_creds_socket_get_pid (m_sockfd, &pid); + cynara_log("cynara_creds_socket_get_pid()", ret); + if (ret != CYNARA_API_SUCCESS) { + goto CLEANUP; + } + + m_session = cynara_session_from_pid (pid); + if (!m_session) { + SCIM_DEBUG_MAIN(1) << "cynara_session_from_pid(): failed"; + goto CLEANUP; + } + + return true; +CLEANUP: + free (m_client); + free (m_session); + free (m_user); + + m_client = NULL; + m_session = NULL; + m_user = NULL; + + return false; +} + + +bool +PrivilegeChecker::checkPrivilege (const char *privilege) +{ + if (!initializeCreditionals ()) + return false; + int ret = cynara_check (p_cynara, m_client, m_session, m_user, privilege); + cynara_log("cynara_check()", ret); + if (ret != CYNARA_API_ACCESS_ALLOWED) + return false; + return true; +} + +bool +isf_cynara_initialize () +{ + int ret = cynara_initialize (&p_cynara, NULL); + cynara_log("cynara_initialize()", ret); + return ret == CYNARA_API_SUCCESS; +} + +void +isf_cynara_finish () +{ + cynara_finish (p_cynara); +} diff --git a/ism/src/privilege_checker.h b/ism/src/privilege_checker.h new file mode 100644 index 0000000..77484f2 --- /dev/null +++ b/ism/src/privilege_checker.h @@ -0,0 +1,25 @@ +#ifndef __PRIVILEGE_CHECKER_H +#define __PRIVILEGE_CHECKER_H + +#define IMEMANAGER_PRIVILEGE "http://tizen.org/privilege/imemanager" + +class PrivilegeChecker { +public: + PrivilegeChecker (int sockfd); + ~PrivilegeChecker (); + + bool checkPrivilege (const char *privilege); + +private: + char *m_client; + char *m_session; + char *m_user; + int m_sockfd; + + bool initializeCreditionals (); +}; + +bool isf_cynara_initialize (); +void isf_cynara_finish (); + +#endif //__PRIVILEGE_CHECKER_H diff --git a/ism/src/scim_panel_agent.cpp b/ism/src/scim_panel_agent.cpp index 73df242..51b21ec 100644 --- a/ism/src/scim_panel_agent.cpp +++ b/ism/src/scim_panel_agent.cpp @@ -67,6 +67,7 @@ #include "scim_private.h" #include "scim.h" #include "scim_stl_map.h" +#include "privilege_checker.h" #ifdef LOG_TAG # undef LOG_TAG @@ -75,7 +76,6 @@ #define MIN_REPEAT_TIME 2.0 - EXAPI scim::CommonLookupTable g_isf_candidate_table; @@ -425,6 +425,7 @@ public: ~PanelAgentImpl () { delete_ise_context_buffer (); + isf_cynara_finish (); } void delete_ise_context_buffer (void) @@ -438,6 +439,9 @@ public: bool initialize (const String &config, const String &display, bool resident) { + if (!isf_cynara_initialize ()) + return false; + m_config_name = config; m_display_name = display; m_should_resident = resident; @@ -4044,10 +4048,16 @@ private: if (cmd == ISM_TRANS_CMD_GET_ACTIVE_ISE) get_active_ise (client_id); else if (cmd == ISM_TRANS_CMD_SET_ACTIVE_ISE_BY_UUID) { - set_active_ise_by_uuid (client_id); + if (client.get_privilege_checker ().checkPrivilege (IMEMANAGER_PRIVILEGE)) + set_active_ise_by_uuid (client_id); + else + SCIM_DEBUG_MAIN (1) << "Access denied to set active ise"; } else if (cmd == ISM_TRANS_CMD_SET_INITIAL_ISE_BY_UUID) { - set_initial_ise_by_uuid (client_id); + if (client.get_privilege_checker ().checkPrivilege (IMEMANAGER_PRIVILEGE)) + set_initial_ise_by_uuid (client_id); + else + SCIM_DEBUG_MAIN (1) << "Access denied to set initial ise"; } else if (cmd == ISM_TRANS_CMD_GET_ISE_LIST) get_ise_list (client_id); diff --git a/ism/src/scim_socket.cpp b/ism/src/scim_socket.cpp index 232b114..30cfde7 100644 --- a/ism/src/scim_socket.cpp +++ b/ism/src/scim_socket.cpp @@ -57,6 +57,7 @@ #include #include +#include "privilege_checker.h" #include "scim_private.h" #include "scim.h" @@ -783,7 +784,7 @@ private: }; Socket::Socket (int id) - : m_impl (new SocketImpl (id)) + : m_impl (new SocketImpl (id)), privilegeChecker (id) { } @@ -871,6 +872,12 @@ Socket::set_nonblock_mode () return m_impl->set_nonblock_mode (); } +PrivilegeChecker& +Socket::get_privilege_checker () const +{ + return privilegeChecker; +} + bool Socket::create (SocketFamily family) { diff --git a/ism/src/scim_socket.h b/ism/src/scim_socket.h index 3cb9250..2b62909 100644 --- a/ism/src/scim_socket.h +++ b/ism/src/scim_socket.h @@ -37,6 +37,8 @@ #ifndef __SCIM_SOCKET_H #define __SCIM_SOCKET_H +#include "privilege_checker.h" + namespace scim { /** @@ -192,6 +194,8 @@ class EXAPI Socket Socket (const Socket&); const Socket& operator = (const Socket&); + mutable PrivilegeChecker privilegeChecker; + public: /** * @brief Create a Socket object from an already created socket_id. @@ -282,6 +286,13 @@ public: */ int set_nonblock_mode (); + /** + * @brief Get the privilege checker member. + * + * @return privilege checker + */ + PrivilegeChecker& get_privilege_checker () const; + protected: /** diff --git a/packaging/isf.spec b/packaging/isf.spec index 15d718d..01fde45 100644 --- a/packaging/isf.spec +++ b/packaging/isf.spec @@ -38,6 +38,9 @@ BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: pkgconfig(db-util) BuildRequires: pkgconfig(capi-appfw-app-control) BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(cynara-client) +BuildRequires: pkgconfig(cynara-creds-socket) +BuildRequires: pkgconfig(cynara-session) BuildRequires: capi-appfw-package-manager-devel Requires(post): /sbin/ldconfig /usr/bin/vconftool Requires(postun): /sbin/ldconfig -- 2.7.4