Apply cynara privilege checks 33/49733/8 submit/tizen/20151124.032134
authorOskar Świtalski <o.switalski@samsung.com>
Mon, 19 Oct 2015 07:24:29 +0000 (09:24 +0200)
committerJeongho Mok <jho.mok@samsung.com>
Fri, 20 Nov 2015 03:58:10 +0000 (19:58 -0800)
Check following privileges:
"http://tizen.org/privilege/volume.set"
"http://tizen.org/privilege/recorder"

Change-Id: I3ee682cef72dd8e47bd33cd5bdd2fe2100a7d9f0
Signed-off-by: Oskar Świtalski <o.switalski@samsung.com>
configure.ac
packaging/pulseaudio.spec
src/Makefile.am
src/pulsecore/cynara.c [new file with mode: 0644]
src/pulsecore/cynara.h [new file with mode: 0644]
src/pulsecore/protocol-native.c
src/pulsecore/pstream.c
src/pulsecore/pstream.h

index 6959f52..4cae56e 100644 (file)
@@ -1367,6 +1367,12 @@ else
     USE_PER_USER_ESOUND_SOCKET=0
 fi
 
+#### Cynara ####
+
+PKG_CHECK_MODULES(CYNARA, [cynara-client, cynara-creds-socket, cynara-session])
+AC_SUBST(CYNARA_CFLAGS)
+AC_SUBST(CYNARA_LIBS)
+
 #### PulseAudio system runtime dir ####
 
 PA_SYSTEM_RUNTIME_PATH="${localstatedir}/run/pulse"
index 1da7bd0..9381af6 100644 (file)
@@ -39,6 +39,9 @@ BuildRequires:    pkgconfig(tdb)
 BuildRequires:    pkgconfig(vconf)
 BuildRequires:    systemd-devel
 BuildRequires:    libcap-devel
+BuildRequires:    pkgconfig(cynara-client)
+BuildRequires:    pkgconfig(cynara-creds-socket)
+BuildRequires:    pkgconfig(cynara-session)
 %if %{with pulseaudio_dlog}
 BuildRequires:    pkgconfig(dlog)
 %endif
index ea8ded7..a916f15 100644 (file)
@@ -49,13 +49,14 @@ AM_CPPFLAGS = \
        -DPA_ALSA_PROFILE_SETS_DIR=\"$(alsaprofilesetsdir)\"
 AM_CFLAGS = \
        $(PTHREAD_CFLAGS) \
+       $(CYNARA_CFLAGS) \
        -DPA_SRCDIR=\"$(abs_srcdir)\" \
        -DPA_BUILDDIR=\"$(abs_builddir)\"
 AM_CXXFLAGS = $(AM_CFLAGS)
 SERVER_CFLAGS = -D__INCLUDED_FROM_PULSE_AUDIO
 
 AM_LIBADD = $(PTHREAD_LIBS) $(INTLLIBS)
-AM_LDADD = $(PTHREAD_LIBS) $(INTLLIBS)
+AM_LDADD = $(PTHREAD_LIBS) $(INTLLIBS) $(CYNARA_LIBS)
 AM_LDFLAGS = $(NODELETE_LDFLAGS)
 
 if HAVE_GCOV
@@ -1239,7 +1240,8 @@ libprotocol_http_la_SOURCES = pulsecore/protocol-http.c pulsecore/protocol-http.
 libprotocol_http_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
 libprotocol_http_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
 
-libprotocol_native_la_SOURCES = pulsecore/protocol-native.c pulsecore/protocol-native.h pulsecore/native-common.h
+libprotocol_native_la_SOURCES = pulsecore/protocol-native.c pulsecore/protocol-native.h pulsecore/native-common.h \
+pulsecore/cynara.c pulsecore/cynara.h
 libprotocol_native_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS)
 libprotocol_native_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
 libprotocol_native_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
diff --git a/src/pulsecore/cynara.c b/src/pulsecore/cynara.c
new file mode 100644 (file)
index 0000000..d1dd3e6
--- /dev/null
@@ -0,0 +1,95 @@
+#include <pulsecore/cynara.h>
+
+#include <config.h>
+#include <pulsecore/log.h>
+
+#include <cynara-creds-socket.h>
+#include <cynara-client.h>
+#include <cynara-session.h>
+
+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';
+    }
+    if (cynara_status < 0)
+        pa_log_error("%s: %s", string, buf);
+    else
+        pa_log_debug("%s: %s", string, buf);
+}
+
+bool cynara_check_privilege(int fd, const char *privilege) {
+    cynara *p_cynara = NULL;
+    cynara_configuration *p_conf = NULL;
+
+    int ret = 0;
+    int result = false;
+
+    char *user = NULL;
+    char *client = NULL;
+    char *session = NULL;
+    int pid = 0;
+
+    ret = cynara_configuration_create(&p_conf);
+    cynara_log("cynara_configuration_create()", ret);
+    if (ret != CYNARA_API_SUCCESS) {
+        goto CLEANUP;
+    }
+
+    ret = cynara_configuration_set_cache_size(p_conf, 0);
+    cynara_log("cynara_configuration_set_cache_size()", ret);
+    if (ret != CYNARA_API_SUCCESS) {
+        goto CLEANUP;
+    }
+
+    ret = cynara_initialize(&p_cynara, p_conf);
+    cynara_log("cynara_initialize()", ret);
+    if (ret != CYNARA_API_SUCCESS) {
+        goto CLEANUP;
+    }
+
+    ret = cynara_creds_socket_get_user(fd, USER_METHOD_DEFAULT, &user);
+    cynara_log("cynara_creds_socket_get_user()", ret);
+    if (ret != CYNARA_API_SUCCESS) {
+        goto CLEANUP;
+    }
+
+    ret = cynara_creds_socket_get_pid(fd, &pid);
+    cynara_log("cynara_creds_socket_get_pid()", ret);
+    if (ret != CYNARA_API_SUCCESS) {
+        goto CLEANUP;
+    }
+
+    ret = cynara_creds_socket_get_client(fd, CLIENT_METHOD_DEFAULT, &client);
+    cynara_log("cynara_creds_socket_get_client()", ret);
+    if (ret != CYNARA_API_SUCCESS) {
+        goto CLEANUP;
+    }
+
+    session = cynara_session_from_pid(pid);
+    if (session == NULL) {
+        pa_log_error("cynara_session_from_pid(): failed");
+        goto CLEANUP;
+    }
+
+
+    pa_log_debug("cynara credentials - client: %s, session: %s, user: %s, privilege: %s", client, session, user, privilege);
+
+    ret = cynara_check(p_cynara, client, session, user, privilege);
+    cynara_log("cynara_check()", ret);
+    if (ret == CYNARA_API_ACCESS_ALLOWED) {
+        result = true;
+    }
+
+CLEANUP:
+    cynara_configuration_destroy(p_conf);
+    cynara_finish(p_cynara);
+    free(user);
+    free(session);
+    free(client);
+    return result;
+}
diff --git a/src/pulsecore/cynara.h b/src/pulsecore/cynara.h
new file mode 100644 (file)
index 0000000..1c75c5a
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdbool.h>
+
+#define VOLUME_SET_PRIVILEGE "http://tizen.org/privilege/volume.set"
+#define RECORDER_PRIVILEGE "http://tizen.org/privilege/recorder"
+
+void cynara_log(const char *string, int cynara_status);
+bool cynara_check_privilege(int fd, const char *privilege);
index c5d3d30..eb2f39a 100644 (file)
 
 #include "protocol-native.h"
 
+#ifdef __TIZEN__
+#include <pulsecore/cynara.h>
+#include <pulsecore/iochannel.h>
+#endif
+
 /* #define PROTOCOL_NATIVE_DEBUG */
 
 /* Kick a client if it doesn't authenticate within this time */
@@ -2453,6 +2458,14 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin
     pa_idxset *formats = NULL;
     uint32_t i;
 
+    #ifdef __TIZEN__
+    int fd = pa_iochannel_get_send_fd(pa_pstream_get_iochannel(pa_native_connection_get_pstream(c)));
+    if (!cynara_check_privilege(fd, RECORDER_PRIVILEGE)) {
+        pa_pstream_send_simple_ack(c->pstream, tag);
+        return;
+    }
+    #endif
+
     pa_native_connection_assert_ref(c);
     pa_assert(t);
 
@@ -3003,6 +3016,14 @@ static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint3
     struct timeval tv, now;
     uint32_t idx;
 
+    #ifdef __TIZEN__
+    int fd = pa_iochannel_get_send_fd(pa_pstream_get_iochannel(pa_native_connection_get_pstream(c)));
+    if (!cynara_check_privilege(fd, RECORDER_PRIVILEGE)) {
+        pa_pstream_send_simple_ack(c->pstream, tag);
+        return;
+    }
+    #endif
+
     pa_native_connection_assert_ref(c);
     pa_assert(t);
 
@@ -3841,6 +3862,14 @@ static void command_set_volume(
     const char *name = NULL;
     const char *client_name;
 
+    #ifdef __TIZEN__
+    int fd = pa_iochannel_get_send_fd(pa_pstream_get_iochannel(pa_native_connection_get_pstream(c)));
+    if (!cynara_check_privilege(fd, VOLUME_SET_PRIVILEGE)) {
+        pa_pstream_send_simple_ack(c->pstream, tag);
+        return;
+    }
+    #endif
+
     pa_native_connection_assert_ref(c);
     pa_assert(t);
 
@@ -3936,6 +3965,14 @@ static void command_set_volume_ramp(
     const char *name = NULL;
     const char *client_name;
 
+    #ifdef __TIZEN__
+    int fd = pa_iochannel_get_send_fd(pa_pstream_get_iochannel(pa_native_connection_get_pstream(c)));
+    if (!cynara_check_privilege(fd, VOLUME_SET_PRIVILEGE)) {
+        pa_pstream_send_simple_ack(c->pstream, tag);
+        return;
+    }
+    #endif
+
     pa_native_connection_assert_ref(c);
     pa_assert(t);
 
@@ -4002,6 +4039,14 @@ static void command_set_mute(
     pa_source_output *so = NULL;
     const char *name = NULL, *client_name;
 
+    #ifdef __TIZEN__
+    int fd = pa_iochannel_get_send_fd(pa_pstream_get_iochannel(pa_native_connection_get_pstream(c)));
+    if (!cynara_check_privilege(fd, VOLUME_SET_PRIVILEGE)) {
+        pa_pstream_send_simple_ack(c->pstream, tag);
+        return;
+    }
+    #endif
+
     pa_native_connection_assert_ref(c);
     pa_assert(t);
 
index 190fc9a..0e8f7ee 100644 (file)
@@ -1038,3 +1038,9 @@ bool pa_pstream_get_shm(pa_pstream *p) {
 
     return p->use_shm;
 }
+
+#ifdef __TIZEN__
+pa_iochannel *pa_pstream_get_iochannel(pa_pstream *p) {
+    return p->io;
+}
+#endif
index deb2bc3..79ac135 100644 (file)
@@ -66,4 +66,8 @@ bool pa_pstream_is_pending(pa_pstream *p);
 void pa_pstream_enable_shm(pa_pstream *p, bool enable);
 bool pa_pstream_get_shm(pa_pstream *p);
 
+#ifdef __TIZEN__
+pa_iochannel *pa_pstream_get_iochannel(pa_pstream *p);
+#endif
+
 #endif