From: r.tyminski Date: Thu, 5 Oct 2017 14:28:12 +0000 (+0200) Subject: Packaging changes. X-Git-Tag: submit/tizen/20171011.123005~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5ac9efeaad04b6d20da986066f610a4d060c9451;p=platform%2Fcore%2Fsecurity%2Ftef-optee_client.git Packaging changes. Adding manifest. Setting root of tee fs to /opt. Little spec cleanup. Adding udev and service configuration. Set SYS_TA_PATH to /usr/lib/tastore Some fixes for cynara usage. Change-Id: I2fe99d30d88cc1776380a83308b656445d61cf8f --- 5ac9efeaad04b6d20da986066f610a4d060c9451 diff --cc libteec/Makefile index 5de229c,5de229c..ec8801f --- a/libteec/Makefile +++ b/libteec/Makefile @@@ -27,7 -27,7 +27,7 @@@ TEEC_INCLUDES := TEEC_CFLAGS := $(addprefix -I, $(TEEC_INCLUDES)) $(CFLAGS) -D_GNU_SOURCE \ -DDEBUGLEVEL_$(CFG_TEE_CLIENT_LOG_LEVEL) \ -- -DBINARY_PREFIX=\"TEEC\" ++ -DBINARY_PREFIX=\"TEEC\" -DTEEC_LOG_FILE=\"$(TEEC_LOG_FILE)\" TEEC_LFLAGS := -lpthread TEEC_LIBRARY := $(OUT_DIR)/$(LIB_MAJ_MIN) diff --cc packaging/optee-client.spec index 72223aa,ebc62d7..0000000 deleted file mode 100644,100644 --- a/packaging/optee-client.spec +++ /dev/null @@@ -1,57 -1,85 +1,0 @@@ --%define major_version 2 --%define minor_version 4 -- - Name: optee-client - Summary: Library for applications which use OPTEE functions. - Version: %{major_version}.%{minor_version} -Name: tef-optee -Summary: TEF TrustZone OpTEE backend -Version: %{major_version}.%{minor_version}.0 --Release: 1%{?dist} --Group: Security/Testing --License: BSD-2-Clause --URL: N/A --Source0: %{name}-%{version}.tar.gz - Provides: libteec -Source1: %{name}.manifest -ExclusiveArch: armv6l armv7hl armv7l aarch64 -Provides: %{name} -- --BuildRequires: make - BuildRequires: pkgconfig(cynara-client) - BuildRequires: pkgconfig(cynara-creds-socket) - BuildRequires: pkgconfig(cynara-session) - BuildRequires: pkgconfig(security-manager) - BuildRequires: pkgconfig(security-privilege-manager) - BuildRequires: pkgconfig(libtzplatform-config) -BuildRequires: cmake - -%{?systemd_requires} - -%define bin_dir %{?TZ_SYS_BIN:%TZ_SYS_BIN}%{!?TZ_SYS_BIN:%_bindir} -%define udev_dir %_libdir/udev/rules.d/ -%define build_udev_dir %{buildroot}/%{udev_dir} -%define build_unit_dir %{buildroot}%{_unitdir} - -%define smack_domain_name System - -%define compile_param CROSS_COMPILE="" MAJOR_VERSION="%{major_version}" MINOR_VERSION="%{minor_version}" -- --%description - Library for applications which use OPTEE functions. -TEF Trustzone OpTEE provides daemon to support OpTEE OS solution. - -%package -n %{name}-client -Summary: TEF TrustZone OpTEE Client contains a libteec library. -Group: Security/Libraries -License: BSD-2-Clause -Provides: %{name}-client - -BuildRequires: make - -%description -n %{name}-client -TEF TrustZone OpTEE Client contains a libteec library, which is tef-libteec backend. -- --%prep --%setup -q -cp -a %{SOURCE1} . -- --%build - make build CROSS_COMPILE="" MAJOR_VERSION=%{major_version} MINOR_VERSION=%{minor_version} CFLAGS='-fPIC -D_GNU_SOURCE -DTEEC_LOAD_PATH="\"\"" -I%{_includedir}/cynara -L%{_libdir}' -export TEE_FS_SUBPATH="/opt/data" TEE_FS_PATH="/opt/data/tee" -make %{compile_param} build - -cd systemd -cmake . \ - -DUDEV_RULES_DIR=%{build_udev_dir} \ - -DSYSTEMD_UNIT_DIR=%{build_unit_dir} \ - -DSYSTEMD_CFG_BIN_DIR=%{bin_dir} \ - -DSMACK_DOMAIN_NAME=%{smack_domain_name} -cd - -- --%install - make CROSS_COMPILE="" MAJOR_VERSION=%{major_version} MINOR_VERSION=%{minor_version} DESTDIR=%{buildroot}/%{_prefix} install -make %{compile_param} DESTDIR=%{buildroot}/%{_prefix}/ LIBDIR=%{_lib}/tef/optee install -- - if [ "%{_libdir}" == "%{_exec_prefix}/lib64" ] - then - mkdir -p %{buildroot}/%{_libdir} - cp -f %{buildroot}/usr/lib/libteec.so* %{buildroot}/%{_libdir}/ - rm -rf %{buildroot}/usr/lib - fi -rm -rf %{buildroot}/%{_includedir} -cd systemd -make install -cd - -- - rm -rf %{buildroot}%{_libdir}/debug -%post -./usr/sbin/tef-update.sh optee - -%postun -./usr/sbin/tef-update.sh -- --%files - %defattr(-, root, root, -) -%license LICENSE --%{_bindir}/tee-supplicant - %{_libdir}/libteec.so* - %{_includedir}/tee_client_api.h - %{_includedir}/tee_client_api_extensions.h - %{_includedir}/teec_trace.h - - %post - ln -sf %{_libdir}/libteec.so.%{version} %{_libdir}/libteec.so.%{major_version} - ln -sf %{_libdir}/libteec.so.%{major_version} %{_libdir}/libteec.so -%{_unitdir}/tef-optee.service -%{udev_dir}/90-teedaemon.rules -- - /sbin/ldconfig -%files -n %{name}-client -%license LICENSE -%defattr(-, root, root, -) -%{_libdir}/tef/optee/libteec.so* -- --%changelog diff --cc packaging/tef-optee-client.manifest index 0000000,0000000..86dbb26 new file mode 100644 --- /dev/null +++ b/packaging/tef-optee-client.manifest @@@ -1,0 -1,0 +1,5 @@@ ++ ++ ++ ++ ++ diff --cc packaging/tef-optee-client.spec index 0000000,0000000..f9d7d00 new file mode 100644 --- /dev/null +++ b/packaging/tef-optee-client.spec @@@ -1,0 -1,0 +1,90 @@@ ++%define major_version 2 ++%define minor_version 4 ++ ++Name: tef-optee-client ++Summary: TEF TrustZone OpTEE backend ++Version: %{major_version}.%{minor_version}.0 ++Release: 1%{?dist} ++Group: Security/Libraries ++License: BSD-2-Clause ++URL: N/A ++Source0: %{name}-%{version}.tar.gz ++Source1: %{name}.manifest ++ExclusiveArch: armv6l armv7hl armv7l aarch64 ++Provides: %{name} ++ ++BuildRequires: make ++BuildRequires: pkgconfig(cynara-client) ++BuildRequires: pkgconfig(cynara-creds-socket) ++BuildRequires: pkgconfig(cynara-session) ++BuildRequires: pkgconfig(security-manager) ++BuildRequires: pkgconfig(security-privilege-manager) ++BuildRequires: pkgconfig(libtzplatform-config) ++BuildRequires: cmake ++Requires: tef-libteec ++ ++%{?systemd_requires} ++ ++%define bin_dir %{?TZ_SYS_BIN:%TZ_SYS_BIN}%{!?TZ_SYS_BIN:%_bindir} ++%define udev_dir %_libdir/udev/rules.d/ ++%define build_udev_dir %{buildroot}/%{udev_dir} ++%define build_unit_dir %{buildroot}%{_unitdir} ++%define optee_libteec /%{_lib}/tef/optee ++ ++%define smack_domain_name System ++ ++%define compile_param CROSS_COMPILE="" MAJOR_VERSION="%{major_version}" MINOR_VERSION="%{minor_version}" CFLAGS='-fPIC -D_GNU_SOURCE -I%{_includedir}/cynara' ++ ++%description ++TEF Trustzone OpTEE provides daemon to support OpTEE OS solution and libteec library, ++which is tef-libteec backend. ++ ++%prep ++%setup -q ++cp -a %{SOURCE1} . ++ ++%build ++export TEE_FS_SUBPATH="/opt/data" TEE_FS_PATH="/opt/data/tee" TEEC_LOAD_PATH="\/" TEEC_LOG_FILE="/opt/data/var.log" CFG_TEE_CLIENT_LOG_LEVEL=4 CFG_TEE_SUPP_LOG_LEVEL=4 CFG_TA_TEST_PATH=n ++make %{compile_param} build ++ ++cd systemd ++cmake . \ ++ -DUDEV_RULES_DIR=%{build_udev_dir} \ ++ -DSYSTEMD_UNIT_DIR=%{build_unit_dir} \ ++ -DSYSTEMD_CFG_BIN_DIR=%{bin_dir} \ ++ -DSMACK_DOMAIN_NAME=%{smack_domain_name} ++cd - ++ ++%install ++make %{compile_param} DESTDIR=%{buildroot} LIBDIR=%{optee_libteec} install ++ ++mkdir %{buildroot}/%{_prefix} ++mv %{buildroot}/%{optee_libteec}/libteec.so.%{major_version}.%{minor_version} %{buildroot}/%{optee_libteec}/libteec.so.%{version} ++mv %{buildroot}/bin %{buildroot}/%{_prefix} ++cd systemd ++make install ++cd - ++ ++rm -rf %{buildroot}/include ++rm -rf %{buildroot}/%{_libdir}/debug ++rm -rf %{buildroot}/%{optee_libteec}/libteec.so.%{major_version} %{buildroot}/%{optee_libteec}/libteec.so ++ ++%post ++mkdir -p -m 774 %{_libdir}/tastore ++chown root:security_fw %{_libdir}/tastore ++ ++#./usr/sbin/tef-update.sh optee ++ln -sf %{optee_libteec}/libteec.so.%{version} %{optee_libteec}/libteec.so.%{major_version} ++ln -sf %{optee_libteec}/libteec.so.%{major_version} %{optee_libteec}/libteec.so ++ ++%postun ++./usr/sbin/tef-update.sh ++ ++%files ++%license LICENSE ++%{_bindir}/tee-supplicant ++%{_unitdir}/tef-optee.service ++%{udev_dir}/90-teedaemon.rules ++%{optee_libteec}/libteec.so.%{version} ++ ++%changelog diff --cc systemd/tef-optee.service.in index 0000000,5b7498a..086ed4f mode 000000,100644..100644 --- a/systemd/tef-optee.service.in +++ b/systemd/tef-optee.service.in @@@ -1,0 -1,12 +1,13 @@@ + [Unit] + Description=TEF OpTEE Daemon + DefaultDependencies=no + After=opt.mount + + + [Service] + User=root -Group=root ++Group=security_fw + SmackProcessLabel=@SMACK_DOMAIN_NAME@ + ExecStart=@SYSTEMD_CFG_BIN_DIR@/tee-supplicant + RuntimeDirectory=@SERVICE_NAME@ ++StandardOutput=journal diff --cc tee-supplicant/Makefile index d59b5cb,2ff37d7..73f9936 --- a/tee-supplicant/Makefile +++ b/tee-supplicant/Makefile @@@ -19,8 -19,7 +19,9 @@@ TEES_SRCS := tee_supplicant.c tee_supp_fs.c \ rpmb.c \ handle.c \ + security.c \ - unix_socket.c ++ unix_socket.c \ + ../../libteec/src/teec_trace.c ifeq ($(CFG_GP_SOCKETS),y) @@@ -49,7 -48,7 +50,7 @@@ TEES_INCLUDES := ${CURDIR}/../libteec/ TEES_CFLAGS := $(addprefix -I, $(TEES_INCLUDES)) $(CFLAGS) \ -DDEBUGLEVEL_$(CFG_TEE_SUPP_LOG_LEVEL) \ -DBINARY_PREFIX=\"TEES\" --TEES_CFLAGS += -DTEE_FS_SUBPATH=\"$(TEE_FS_SUBPATH)\" -DTEE_FS_PATH=\"$(TEE_FS_PATH)\" ++TEES_CFLAGS += -DTEE_FS_SUBPATH=\"$(TEE_FS_SUBPATH)\" -DTEE_FS_PATH=\"$(TEE_FS_PATH)\" -DTEEC_LOAD_PATH=\"$(TEEC_LOAD_PATH)\" ifeq ($(CFG_GP_SOCKETS),y) TEES_CFLAGS += -DCFG_GP_SOCKETS=1 endif diff --cc tee-supplicant/src/security.c index 2c0bb75,0000000..e7c7034 mode 100644,000000..100644 --- a/tee-supplicant/src/security.c +++ b/tee-supplicant/src/security.c @@@ -1,279 -1,0 +1,279 @@@ +/* + * Copyright (c) 2017, Samsung Electronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include "security.h" +#include +#include +#include +#include + + +/* Global instance of cynara. Get it by function get_cynara_instance, DO NOT USE IT directly! */ +static cynara *p_cynara = NULL; + +#define CYNARA_CACHE_SIZE 100U +#define RETURN_UNLOCK(ret, mtx) {pthread_mutex_unlock(&mtx); return ret; } + +static const char* system_ta_paths[] = { + SYS_TA_PATH, +}; + +pthread_mutex_t cynara_mutex = PTHREAD_MUTEX_INITIALIZER; + +const size_t n_sys_ta_paths = sizeof(system_ta_paths)/sizeof(system_ta_paths[0]); + + +/* Call it before locking cynara */ +static cynara* get_cynara_instance() +{ + if (p_cynara == NULL) { + pthread_mutex_lock(&cynara_mutex); + int ret = -1; + cynara_configuration *p_conf = NULL; + + ret = cynara_configuration_create(&p_conf); + if (ret != CYNARA_API_SUCCESS) { + EMSG("Cynara configuration initialization failed"); + RETURN_UNLOCK(NULL, cynara_mutex); + } + + ret = cynara_configuration_set_cache_size(p_conf, CYNARA_CACHE_SIZE); + if (ret != CYNARA_API_SUCCESS) { + EMSG("Set cynara cache size failed"); + RETURN_UNLOCK(NULL, cynara_mutex); + } + + ret = cynara_initialize(&p_cynara, p_conf); + if (ret != CYNARA_API_SUCCESS) { + p_cynara = NULL; + EMSG("Cynara initialize faied"); + RETURN_UNLOCK(NULL, cynara_mutex); + } + + RETURN_UNLOCK(p_cynara, cynara_mutex); + } + + return p_cynara; +} + + +static bool file_exists(const char* fname) +{ + return access(fname, F_OK) == 0; +} + + +static bool get_ca_full_path_from_fd(int caFd, char* path) +{ + + pid_t ca_pid = -1; + int ret = -1; + + char ca_path[MAX_PATH_LENGTH] = {0}; + + enum tzplatform_variable ids[] = {TZ_USER_APP, TZ_SYS_RW_APP, TZ_SYS_RO_APP}; + const size_t N_IDS = sizeof(ids)/sizeof(*ids); + + struct ucred ucred; + int len = sizeof(struct ucred); + + if (getsockopt(caFd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) { + EMSG("Can't get client's uid"); + return false; + } + + struct tzplatform_context *ctx; + if (tzplatform_context_create(&ctx) != 0) { + EMSG("Can not create tizen context"); + return false; + } + + if (tzplatform_context_set_user(ctx, ucred.uid) != 0) { + EMSG("Can not set user for context"); + tzplatform_context_destroy(ctx); + return false; + } + + for (int i = 0; i < N_IDS; ++i) { + strncpy(ca_path, tzplatform_context_getenv(ctx, ids[i]), MAX_PATH_LENGTH); + if (strlen(ca_path) > 0) break; + } + + ret = readlink(ca_path, path, MAX_PATH_LENGTH); + + if (ret == -1) { + EMSG("readlink() failed"); + tzplatform_context_destroy(ctx); + return false; + } + + tzplatform_context_destroy(ctx); + return true; +} + + +bool find_requested_ta(int ca_fd, const char* ta_name, char** allowed_path) +{ + int ret; + char* pkg_id_ca; + *allowed_path = NULL; + + ret = security_manager_identify_app_from_socket(ca_fd, &pkg_id_ca, NULL); + + if (ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT) { + DMSG("Owner of socket has no pkgid"); + + char ta_full_path[MAX_PATH_LENGTH] = {0}; + + /* Check if any of system ta directories contains our ta */ + for (int i = 0; i < n_sys_ta_paths; ++i) { + snprintf(ta_full_path, MAX_PATH_LENGTH, "%s/%s", system_ta_paths[i], ta_name); + + if (file_exists(ta_full_path)) { + *allowed_path = (char*)calloc(strlen(system_ta_paths[i])+1, sizeof(**allowed_path)); + strcpy(*allowed_path, system_ta_paths[i]); + return true; + } + + memset(ta_full_path, 0, MAX_PATH_LENGTH); + } + + return false; + } + + if (ret != SECURITY_MANAGER_SUCCESS) { + EMSG("security_manager_identify_app_from_socket failed with CA"); + return false; + } + + free(pkg_id_ca); + + char ca_pkg_path[MAX_PATH_LENGTH]; + if (!get_ca_full_path_from_fd(ca_fd, ca_pkg_path)) { + EMSG("Error while loading client's path"); + return false; + } + + strncat(ca_pkg_path, TA_LOCAL_PATH, MAX_PATH_LENGTH - strlen(ca_pkg_path)); + char ta_full_path[MAX_PATH_LENGTH] = {0}; + snprintf(ta_full_path, MAX_PATH_LENGTH, "%s/%s", ca_pkg_path, ta_name); + + if (!file_exists(ta_full_path)) { + EMSG("TA %s not found in res/tee/", ta_name); + return false; + } + + return true; +} + + +bool client_has_cynara_permission(int ca_fd, const char *privelege) +{ + cynara *cynara = get_cynara_instance(); + if (cynara == NULL) { + EMSG("Cynara is not initialized"); + return false; + } + + int ret = -1; + char *user = NULL; + char *session = NULL; + char *label = NULL; + pid_t ca_pid = -1; + + pthread_mutex_lock(&cynara_mutex); + + ret = cynara_creds_socket_get_client(ca_fd, CLIENT_METHOD_SMACK, &label); + if (ret != CYNARA_API_SUCCESS) { + EMSG("Couldn't get smack label of the client. Error code: %d", ret); + goto exit_error3; + } + + ret = cynara_creds_socket_get_pid(ca_fd, &ca_pid); + if (ret != CYNARA_API_SUCCESS) { + EMSG("Couldn't get pid of the client. Error code: %d", ret); + goto exit_error2; + } + + session = cynara_session_from_pid(ca_pid); + if (!session) { + EMSG("Couldn't get client's cynara session."); + goto exit_error2; + } + - ret = cynara_creds_socket_get_user(ca_fd, CLIENT_METHOD_SMACK, &user); ++ ret = cynara_creds_socket_get_user(ca_fd, USER_METHOD_DEFAULT, &user); + if (ret != CYNARA_API_SUCCESS) { + EMSG("Couldn't get user. Error code: %d", ret); + goto exit_error1; + } + + ret = cynara_check(cynara, label, session, user, privelege); + if (ret == CYNARA_API_ACCESS_DENIED) { + EMSG("Cynara access denied."); + goto exit_error0; + } else + if (ret != CYNARA_API_ACCESS_ALLOWED) { + EMSG("Error during cynara_check(). Error code: %d", ret); + goto exit_error0; + } + + + ret = cynara_finish(cynara); + if (ret != CYNARA_API_SUCCESS) { + EMSG("Cynara finish failed with error code %d", ret); + } + + free(session); + free(label); + free(user); + pthread_mutex_unlock(&cynara_mutex); + + return true; + +exit_error0: + free(user); + +exit_error1: + free(session); + +exit_error2: + free(label); + +exit_error3: + pthread_mutex_unlock(&cynara_mutex); + + return false; +} diff --cc tee-supplicant/src/security.h index a5f0944,0000000..2c661a0 mode 100644,000000..100644 --- a/tee-supplicant/src/security.h +++ b/tee-supplicant/src/security.h @@@ -1,74 -1,0 +1,74 @@@ +/* + * Copyright (c) 2017, Samsung Electronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + + +#ifndef SECURITY_H +#define SECURITY_H + +#include + +#define MAX_PATH_LENGTH 100 +#define MAX_OPENED_FD 5 + +#ifdef __cplusplus +extern "C" { +#endif + - #define SYS_TA_PATH "/usr/lib/optee_armtz" ++#define SYS_TA_PATH "/usr/lib/tastore" +#define TA_LOCAL_PATH "/res/tee" + +/** + * This function try to find TA by its name in allowed for client (given by + * socket's file descriptor) by security policies directories. + * + * @param ca_fd File descriptor to opened socket for client. + * @param ta_name Name of ta to connect for. + * @param allowed_ta_path Out parameter, if function returns true, it + * contains found path to TA with given name, + * otherwise pointer is NULL. + * User must free it after use. + * @return true if TA was found, otherwise false. + */ +bool find_requested_ta(int ca_fd, const char* ta_name, char** allowed_ta_path); + +/** + * Check if client given by socket file descriptor has Tizen permission + * for use TEE. + * + * @param ca_fd File descriptor to opened socket for client. + * @param privelege Privilege to check for. + * @return true if client has permission, otherwise false. + */ +bool client_has_cynara_permission(int ca_fd, const char* privilege); + +#ifdef __cplusplus +} +#endif + + +#endif /* SECURITY_H */ diff --cc tee-supplicant/src/unix_socket.c index d370dc4,0000000..7bfc2d4 mode 100644,000000..100644 --- a/tee-supplicant/src/unix_socket.c +++ b/tee-supplicant/src/unix_socket.c @@@ -1,172 -1,0 +1,173 @@@ +/* + * Copyright (c) 2017, Samsung Electronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + + +#include "unix_socket.h" ++#include +#include +#include +#include + +#define WAIT_SEC 10 +#define SOCK_PATH_PREFIX "/tmp/" + +int open_socket_for_ca(const char *ca_id, struct sock_data* open_sockets[]) +{ + int sockfd = -1; + int newsockfd = -1; + int portno = 0; + int free_index = -1; + + char path[MAX_PATH_LENGTH] = {0}; + sprintf(path, SOCK_PATH_PREFIX"%s", ca_id); + + if (access(path, F_OK) == -1) { + DMSG("Socket file doesn't exist. Creating"); + close_socket_by_addr(path, open_sockets); + } + + /* check if this socket already open and find first free place in array */ + for (int i = 0; i < MAX_TA_NUMBER; ++i) { + if (open_sockets[i] == NULL && free_index == -1) free_index = i; + if (open_sockets[i] && strcmp(path, open_sockets[i]->addr) == 0) { + DMSG("Socket already exists"); + return open_sockets[i]->fd; + } + } + + if (free_index < 0 || free_index >= MAX_TA_NUMBER) { + EMSG("Limit of simultaneously opened TA is reached"); + return -1; + } + + struct sockaddr_un serv_addr; + int ret = -1; + + sockfd = socket(AF_UNIX, SOCK_STREAM, portno); + if (sockfd < 0) { + EMSG("Couldn't open socket"); + return sockfd; + } + + bzero((char*) &serv_addr, sizeof(serv_addr)); + + serv_addr.sun_family = AF_UNIX; + strncpy(serv_addr.sun_path, path, sizeof(serv_addr) - 1); + + int yes = 1; + ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); + if (ret < 0) { + EMSG("Configure socket error: %s", strerror(errno)); + return ret; + } + + ret = bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)); + if (ret < 0) { + EMSG("Binding of socket adress failed with error: %s", strerror(errno)); + return ret; + } + + char mode[] = "0777"; + int imode = strtol(mode, NULL, 8); + ret = chmod(path, imode); + if (ret != 0) { + EMSG("Error changing permission for socket: %s", strerror(errno)); + return -1; + } + + listen(sockfd, N_CONNECTIONS); + + DMSG("Waiting for accept..."); + + /* Set timeout for waiting for connection from client */ + struct timeval tv; + tv.tv_sec = WAIT_SEC; + tv.tv_usec = 0; + fd_set fds; + + FD_ZERO(&fds); + FD_SET(sockfd, &fds); + + ret = select(sockfd + 1, &fds, NULL, NULL, &tv); + if (ret == -1) { + EMSG("ERROR of select socket: %s", strerror(errno)); + close(newsockfd); + close(sockfd); + unlink(path); + return -1; + } + + if (ret == 0) { + EMSG("Server timeout"); + close(newsockfd); + close(sockfd); + unlink(path); + return -1; + } + + newsockfd = accept(sockfd, NULL, NULL); + if (newsockfd < 0) { + EMSG("Open socket failed"); + } + + open_sockets[free_index] = (struct sock_data*)malloc(sizeof(struct sock_data)); + open_sockets[free_index]->addr = (char*)calloc(strlen(path), sizeof(char)); + strcpy(open_sockets[free_index]->addr, path); + open_sockets[free_index]->fd = newsockfd; + open_sockets[free_index]->parent_fd = sockfd; + + return newsockfd; +} + +int close_socket_by_addr(const char* path, struct sock_data* open_sockets[]) +{ + int index = -1; + + for (int i = 0; i < MAX_TA_NUMBER; ++i) { + if (open_sockets[i] && strcmp(open_sockets[i]->addr, path) == 0) { + index = i; + break; + } + } + + if (index < 0 || index >= MAX_TA_NUMBER) { + EMSG("Could't find socket %s", path); + return -1; + } + + close(open_sockets[index]->fd); + close(open_sockets[index]->parent_fd); + unlink(open_sockets[index]->addr); + + free(open_sockets[index]->addr); + open_sockets[index]->addr = NULL; + free(open_sockets[index]); + open_sockets[index] = NULL; + + return 0; +}