#include <aul.h>
#include <Ecore.h>
#include <vconf.h>
+#include <stdatomic.h>
+#include <system_info.h>
+#include <cynara-client.h>
+#include <cynara-error.h>
+#include <cynara-session.h>
+#include <pthread.h>
#include "stt_engine.h"
#include "stt_defs.h"
#include "sttd_dbus.h"
#include "sttd_server.h"
#include "sttd_engine_agent.h"
+#include "stt_dlog.h"
#include "stte.h"
+static atomic_int g_feature_enabled = -1;
+static cynara *p_cynara = NULL;
+static pthread_mutex_t g_cynara_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static bool is_feature_enabled()
+{
+ if (1 == g_feature_enabled) {
+ return true;
+ }
+
+ if (0 == g_feature_enabled) {
+ SLOG(LOG_ERROR, TAG_STTD, "[ERROR] TTS feature NOT supported");
+ return false;
+ }
+
+ bool stt_supported = false;
+ if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool(STT_FEATURE_PATH, &stt_supported)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to get feature value");
+ return false;
+ }
+
+ bool mic_supported = false;
+ if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_bool(STT_MIC_FEATURE_PATH, &mic_supported)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to get feature value");
+ return false;
+ }
+
+ if (false == stt_supported || false == mic_supported) {
+ SLOG(LOG_ERROR, TAG_STTD, "[ERROR] STT NOT supported");
+ g_feature_enabled = 0;
+ return false;
+ }
+
+ g_feature_enabled = 1;
+ return true;
+}
+
+static bool initialize_privilege_checker()
+{
+ int ret = cynara_initialize(&p_cynara, NULL);
+ if (CYNARA_API_SUCCESS != ret)
+ SLOG(LOG_ERROR, TAG_STTD, "[ERROR] fail to initialize"); //LCOV_EXCL_LINE
+
+ return ret == CYNARA_API_SUCCESS;
+}
+
+static bool is_privilege_allowed(const char* uid, const char * privilege)
+{
+ FILE *fp = NULL;
+ char label_path[1024] = "/proc/self/attr/current";
+ char smack_label[1024] = {'\0',};
+
+ if (!p_cynara) {
+ return false;
+ }
+
+ fp = fopen(label_path, "r");
+ if (fp != NULL) {
+ if (0 >= fread(smack_label, 1, sizeof(smack_label), fp))
+
+ fclose(fp);
+ }
+
+ pid_t pid = getpid();
+ char *session = cynara_session_from_pid(pid);
+ int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
+ free(session);
+
+ if (ret != CYNARA_API_ACCESS_ALLOWED) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Client]cynara_check returned %d(Denied)", ret);
+ return false;
+ }
+ return true;
+}
+
+static void deinitialize_privilege_checker()
+{
+ if (p_cynara)
+ cynara_finish(p_cynara);
+ p_cynara = NULL;
+}
+
+static bool is_stt_privilege_allowed()
+{
+ pthread_mutex_lock(&g_cynara_mutex);
+ bool is_initialized = initialize_privilege_checker();
+ if (false == is_initialized) {
+ pthread_mutex_unlock(&g_cynara_mutex);
+ return false;
+ }
+
+ char uid[16];
+ snprintf(uid, 16, "%d", getuid());
+ bool is_allowed = is_privilege_allowed(uid, STT_PRIVILEGE_RECORDER);
+ deinitialize_privilege_checker();
+ if (false == is_allowed) {
+ pthread_mutex_unlock(&g_cynara_mutex);
+ return false;
+ }
+
+ pthread_mutex_unlock(&g_cynara_mutex);
+ return true;
+}
+
+static inline int check_feature_and_privilege()
+{
+ RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
+ RETV_IF(false == is_stt_privilege_allowed(), STTE_ERROR_PERMISSION_DENIED);
+
+ return STTE_ERROR_NONE;
+}
+
static bool __is_default_engine()
{
char* engine = NULL;
int stte_main(int argc, char**argv, stte_request_callback_s *callback)
{
SLOG(LOG_DEBUG, TAG_STTD, "===== Start engine");
-
- int ret = STTE_ERROR_NONE;
+ int ret = check_feature_and_privilege();
+ if (STTE_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "Precondition is not met (%s)", get_error_message(ret));
+ return ret;
+ }
if (!ecore_init()) {
SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to initialize Ecore");
int stte_send_result(stte_result_event_e event, const char* type, const char** result, int result_count,
const char* msg, void* time_info, void* user_data)
{
+ RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
+
if (NULL == type || NULL == result) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Invalid parameter");
}
- int ret = STTE_ERROR_NONE;
stt_engine_result_cb result_cb = NULL;
- ret = stt_engine_get_recognition_result_cb(&result_cb);
+ int ret = stt_engine_get_recognition_result_cb(&result_cb);
if (STTE_ERROR_NONE == ret && NULL != result_cb) {
ret = result_cb(event, type, result, result_count, msg, time_info, user_data);
} else {
int stte_send_error(stte_error_e error, const char* msg)
{
- int ret = STTE_ERROR_NONE;
- ret = sttd_engine_agent_send_error(error, msg);
+ RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
+
+ int ret = sttd_engine_agent_send_error(error, msg);
if (0 != ret) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info");
}
int stte_send_speech_status(stte_speech_status_e status, void* user_data)
{
- int ret = STTE_ERROR_NONE;
- ret = sttd_engine_agent_send_speech_status(status, user_data);
+ RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
+
+ int ret = sttd_engine_agent_send_speech_status(status, user_data);
if (0 != ret) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send speech status");
}
int stte_set_private_data_set_cb(stte_private_data_set_cb callback)
{
- int ret = STTE_ERROR_NONE;
+ int ret = check_feature_and_privilege();
+ if (STTE_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "Precondition is not met (%s)", get_error_message(ret));
+ return ret;
+ }
+
ret = stt_engine_set_private_data_set_cb(callback, NULL);
if (0 != ret) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data set callback");
int stte_set_private_data_requested_cb(stte_private_data_requested_cb callback)
{
- int ret = STTE_ERROR_NONE;
+ int ret = check_feature_and_privilege();
+ if (STTE_ERROR_NONE != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "Precondition is not met (%s)", get_error_message(ret));
+ return ret;
+ }
+
ret = stt_engine_set_private_data_requested_cb(callback, NULL);
if (0 != ret) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data requested callback");
int stte_set_audio_type_set_cb(stte_audio_type_cb callback, void* user_data)
{
SLOG(LOG_INFO, TAG_STTD, "[Server Info] Set audio type set callback");
+ RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
- int ret = STTE_ERROR_NONE;
- ret = stt_engine_set_audio_type_set_cb(callback, user_data);
+ int ret = stt_engine_set_audio_type_set_cb(callback, user_data);
if (0 != ret) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set audio type set");
}
int stte_unset_audio_type_set_cb(void)
{
SLOG(LOG_INFO, TAG_STTD, "[Server Info] Unset audio type set callback");
+ RETV_IF(false == is_feature_enabled(), STTE_ERROR_NOT_SUPPORTED);
- int ret = STTE_ERROR_NONE;
- ret = stt_engine_unset_audio_type_set_cb();
+ int ret = stt_engine_unset_audio_type_set_cb();
if (0 != ret) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset audio type set");
}