From: segwon Date: Mon, 31 Oct 2016 04:18:28 +0000 (+0900) Subject: Addition the Access Control module for mobile and wearable. X-Git-Tag: accepted/tizen/common/20161102.122129^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=af0377e06a796849f02f3249251a1ae6eae9d381;p=platform%2Fcore%2Fconvergence%2Fd2d-conv-manager.git Addition the Access Control module for mobile and wearable. Signed-off-by: segwon Change-Id: I1e3efecec1e93e6c2cde1354ea25a07814373a66 --- diff --git a/common/Types.h b/common/Types.h index b9cc30b..481e819 100644 --- a/common/Types.h +++ b/common/Types.h @@ -97,43 +97,43 @@ enum request_type { REQ_SUPPORT, }; -#define CONV_JSON_SERVICE_PATH "service" -#define CONV_JSON_SERVICE_DATA "data" -#define CONV_JSON_SERVICE_TYPE "type" - -#define CONV_JSON_DESCRIPTION "description" -#define CONV_JSON_PAYLOAD "payload" -#define CONV_JSON_SERVICE "service" -#define CONV_JSON_CHANNEL "channel" -#define CONV_JSON_IS_LOCAL "is_local" -#define CONV_JSON_DEVICE "device" -#define CONV_JSON_TYPE "type" -#define CONV_JSON_DISCOVERY_SERVICE_TYPE "service_type" -#define CONV_JSON_DISCOVERY_SERVICE_INFO "service_info" -#define CONV_JSON_REQ_ID "req_id" - -#define CONV_JSON_SERVICE_DATA_PATH NULL -#define CONV_JSON_SERVICE_DATA_NAME "name" -#define CONV_JSON_SERVICE_DATA_VERSION CONV_SERVICE_VERSION -#define CONV_JSON_SERVICE_DATA_TYPE "type" -#define CONV_JSON_SERVICE_DATA_ID "id" -#define CONV_JSON_SERVICE_DATA_URI CONV_SERVICE_ID - -#define CONV_TYPE_APP_TO_APP_COMMUNICATION 0 -#define CONV_TYPE_REMOVE_APP_CONTROL 1 - -#define CONV_DISCOVERY_MIN_VALUE 5 -#define CONV_DISCOVERY_MAX_VALUE 60 - -#define CONV_DISCOVERY_ERROR -1 -#define CONV_DISCOVERY_SUCCESS 0 -#define CONV_DISCOVERY_FINISHED 1 -#define CONV_DISCOVERY_DEVICE_LOST 2 - -#define CONV_JSON_DEVICE_ID CONV_DEVICE_ID -#define CONV_JSON_DEVICE_NAME CONV_DEVICE_NAME -#define CONV_JSON_DEVICE_TYPE CONV_DEVICE_TYPE -#define CONV_JSON_DEVICE_ADDRESS "host_address" +#define CONV_JSON_SERVICE_PATH "service" +#define CONV_JSON_SERVICE_DATA "data" +#define CONV_JSON_SERVICE_TYPE "type" + +#define CONV_JSON_DESCRIPTION "description" +#define CONV_JSON_PAYLOAD "payload" +#define CONV_JSON_SERVICE "service" +#define CONV_JSON_CHANNEL "channel" +#define CONV_JSON_IS_LOCAL "is_local" +#define CONV_JSON_DEVICE "device" +#define CONV_JSON_TYPE "type" +#define CONV_JSON_DISCOVERY_SERVICE_TYPE "service_type" +#define CONV_JSON_DISCOVERY_SERVICE_INFO "service_info" +#define CONV_JSON_REQ_ID "req_id" + +#define CONV_JSON_SERVICE_DATA_PATH NULL +#define CONV_JSON_SERVICE_DATA_NAME "name" +#define CONV_JSON_SERVICE_DATA_VERSION CONV_SERVICE_VERSION +#define CONV_JSON_SERVICE_DATA_TYPE "type" +#define CONV_JSON_SERVICE_DATA_ID "id" +#define CONV_JSON_SERVICE_DATA_URI CONV_SERVICE_ID + +#define CONV_TYPE_APP_TO_APP_COMMUNICATION 0 +#define CONV_TYPE_REMOVE_APP_CONTROL 1 + +#define CONV_DISCOVERY_MIN_VALUE 5 +#define CONV_DISCOVERY_MAX_VALUE 60 + +#define CONV_DISCOVERY_ERROR -1 +#define CONV_DISCOVERY_SUCCESS 0 +#define CONV_DISCOVERY_FINISHED 1 +#define CONV_DISCOVERY_DEVICE_LOST 2 + +#define CONV_JSON_DEVICE_ID CONV_DEVICE_ID +#define CONV_JSON_DEVICE_NAME CONV_DEVICE_NAME +#define CONV_JSON_DEVICE_TYPE CONV_DEVICE_TYPE +#define CONV_JSON_DEVICE_ADDRESS "host_address" enum ApplicationState { APP_COMM_STATE_NONE = 0, @@ -150,53 +150,62 @@ enum AccessControlState { }; // smartview app to app communication service -#define CONV_JSON_CHANNEL_ID "channel_id" -#define CONV_JSON_URI "uri" -#define CONV_JSON_RESULT_TYPE "result_type" -#define CONV_JSON_READ_TYPE "read_type" -#define CONV_JSON_MESSAGE "message_smartview" -#define CONV_JSON_CLIENT "client" -#define CONV_JSON_PAYLOAD_SIZE "payload_size_smartview" -#define CONV_JSON_EVENT "event" -#define CONV_JSON_FROM "from" -#define CONV_JSON_IS_HOST "isHost" -#define CONV_JSON_CONNECT_TIME "connectTime" -#define CONV_JSON_CLIENT_ID "clientId" -#define CONV_JSON_CHANNEL_URI "channelUri" -#define CONV_JSON_CLIENT_LIST "client_list" -#define CONV_JSON_ERROR_MESSAGE "error_message" -#define CONV_JSON_CLIENT_IS_HOST "client_is_host" -#define CONV_JSON_CLIENT_CONNECT_TIME "client_connect_time" -#define CONV_JSON_CLIENT_CLIENT_ID "client_id" -#define CONV_JSON_SECURE_MODE "secure_mode" - -#define CONV_JSON_ON_START "onStart" -#define CONV_JSON_ON_CONNECT "onConnect" -#define CONV_JSON_ON_STOP "onStop" -#define CONV_JSON_ON_DISCONNECT "onDisconnect" -#define CONV_JSON_ON_MESSAGE "onMessage" -#define CONV_JSON_ON_ERROR "onError" - -#define CONV_JSON_ON_CLIENT_CONNECT "onClientConnect" -#define CONV_JSON_ON_CLIENT_DISCONNECT "onClientDisconnect" - -#define CONV_JSON_ON_PUBLISH "onPublish" -#define CONV_JSON_ON_READ "onRead" - -#define CONV_JSON_GET_CLIENTS "getClients" +#define CONV_JSON_CHANNEL_ID "channel_id" +#define CONV_JSON_URI "uri" +#define CONV_JSON_RESULT_TYPE "result_type" +#define CONV_JSON_READ_TYPE "read_type" +#define CONV_JSON_MESSAGE "message_smartview" +#define CONV_JSON_CLIENT "client" +#define CONV_JSON_PAYLOAD_SIZE "payload_size_smartview" +#define CONV_JSON_EVENT "event" +#define CONV_JSON_FROM "from" +#define CONV_JSON_IS_HOST "isHost" +#define CONV_JSON_CONNECT_TIME "connectTime" +#define CONV_JSON_CLIENT_ID "clientId" +#define CONV_JSON_CHANNEL_URI "channelUri" +#define CONV_JSON_CLIENT_LIST "client_list" +#define CONV_JSON_ERROR_MESSAGE "error_message" +#define CONV_JSON_CLIENT_IS_HOST "client_is_host" +#define CONV_JSON_CLIENT_CONNECT_TIME "client_connect_time" +#define CONV_JSON_CLIENT_CLIENT_ID "client_id" +#define CONV_JSON_SECURE_MODE "secure_mode" + +#define CONV_JSON_ON_START "onStart" +#define CONV_JSON_ON_CONNECT "onConnect" +#define CONV_JSON_ON_STOP "onStop" +#define CONV_JSON_ON_DISCONNECT "onDisconnect" +#define CONV_JSON_ON_MESSAGE "onMessage" +#define CONV_JSON_ON_ERROR "onError" + +#define CONV_JSON_ON_CLIENT_CONNECT "onClientConnect" +#define CONV_JSON_ON_CLIENT_DISCONNECT "onClientDisconnect" + +#define CONV_JSON_ON_PUBLISH "onPublish" +#define CONV_JSON_ON_READ "onRead" + +#define CONV_JSON_GET_CLIENTS "getClients" // remote app control service -#define CONV_JSON_APP_CONTROL "app_control" -#define CONV_JSON_REPLY "reply" -#define CONV_JSON_REQUEST_TYPE "request_type" -#define CONV_JSON_ACCESS_REQUEST_RESULT "access_request_result" -#define CONV_JSON_APP_CONTROL_REPLY "app_control_reply" -#define CONV_JSON_APP_CONTROL_REQUEST "app_control_request" -#define CONV_JSON_APP_CONTROL_RESULT "app_control_result" - -#define CONV_LAUNCH_REQUEST "LAUNCH_REQUEST" -#define CONV_ACCESS_CONTROL_REQUEST "ACL_REQUEST" -#define CONV_ACCESS_CONTROL_PERMITTED "PERMITTED" -#define CONV_ACCESS_CONTROL_DENIED "DENIED" +#define CONV_JSON_APP_CONTROL "app_control" +#define CONV_JSON_REPLY "reply" +#define CONV_JSON_REQUEST_TYPE "request_type" +#define CONV_JSON_ACCESS_REQUEST_TYPE "access_request_type" +#define CONV_JSON_ACCESS_REQUEST_RESULT "access_request_result" +#define CONV_JSON_PASSCODE "passcode" +#define CONV_JSON_APP_CONTROL_REPLY "app_control_reply" +#define CONV_JSON_APP_CONTROL_REQUEST "app_control_request" +#define CONV_JSON_APP_CONTROL_RESULT "app_control_result" + +#define CONV_LAUNCH_REQUEST "LAUNCH_REQUEST" +#define CONV_ACCESS_CONTROL_REQUEST "ACL_REQUEST" +#define CONV_ACCESS_CONTROL_PERMITTED "PERMITTED" +#define CONV_ACCESS_CONTROL_DENIED "DENIED" + +#define CONV_ACCESS_CONTROL_PASSCODE_REQUEST "PASSCODE_REQUEST" +#define CONV_ACCESS_CONTROL_PASSCODE_RESPONSE "PASSCODE_RESPONSE" +#define CONV_ACCESS_CONTROL_PASSCODE_CANCEL "PASSCODE_CANCEL" +#define CONV_ACCESS_CONTROL_PASSCODE_RIGHT "PASSCODE_RIGHT" +#define CONV_ACCESS_CONTROL_PASSCODE_WRONG "PASSCODE_WRONG" +#define CONV_ACCESS_CONTROL_PASSCODE_REJECTED "PASSCODE_REHECTED" #endif diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 1c62c67..2b28974 100755 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -13,7 +13,7 @@ FILE(GLOB DAEMON_SRCS ${DAEMON_SRCS} discovery_provider/iotcon/*.cpp) FILE(GLOB DAEMON_SRCS ${DAEMON_SRCS} discovery_provider/smartview/*.cpp) FILE(GLOB DAEMON_SRCS ${DAEMON_SRCS} ../msf_tizen_client/src/*.cpp) -SET(provider_deps "glib-2.0 dlog json-glib-1.0 iotcon capi-appfw-app-manager iotcon vconf capi-network-bluetooth capi-network-wifi-direct capi-appfw-application bundle capi-network-connection cynara-creds-gdbus cynara-client cynara-session capi-appfw-package-manager") +SET(provider_deps "glib-2.0 dlog json-glib-1.0 iotcon capi-appfw-app-manager iotcon vconf capi-network-bluetooth capi-network-wifi-direct capi-appfw-application bundle capi-network-connection cynara-creds-gdbus cynara-client cynara-session capi-appfw-package-manager sqlite3 syspopup-caller") SET(provider_deps "${provider_deps} openssl libwebsockets libcurl nsd-dns-sd") # Mobile profile IF("${PROFILE}" STREQUAL "mobile") @@ -24,6 +24,7 @@ ENDIF("${PROFILE}" STREQUAL "mobile") # TV profile IF("${PROFILE}" STREQUAL "tv") ADD_DEFINITIONS("-D_TV_") + SET(provider_deps "${provider_deps} acl-proxy-api") ENDIF("${PROFILE}" STREQUAL "tv") pkg_check_modules(daemon_pkgs REQUIRED ${provider_deps}) diff --git a/daemon/access_control/ACLManager.cpp b/daemon/access_control/ACLManager.cpp new file mode 100644 index 0000000..591f646 --- /dev/null +++ b/daemon/access_control/ACLManager.cpp @@ -0,0 +1,363 @@ +#include "ACLManager.h" +#include "Log.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DB_FILE_NAME "ACCESS_DEVICES.db" + +typedef struct { + conv::acl_manager::PopupCallback callback; + void *userdata; +} usercallback_info; + +usercallback_info *info = NULL; + +static char passcode[5]; + +ACLResult conv::acl_manager::PasscodeChecker (char *input_passcode) +{ + bool isShowPopup = false; + const char *app_id = "org.tizen.d2d-conv-syspopup"; + + int ret = app_manager_is_running(app_id, &isShowPopup); + if (ret != APP_MANAGER_ERROR_NONE){ + _D("app_manager_is_running() is error."); + return ACLResult_Error; + } + + if(isShowPopup == true) { + _D("org.tizen.d2d-conv-syspopup is running."); + + if (!strcmp(passcode, input_passcode)){ + _D("correct"); + return ACLResult_OK; + + } else { + _D("incorrect"); + return ACLResult_Error; + } + + } else { + _D("org.tizen.d2d-conv-syspopup is closed."); + return ACLResult_Close; + } +} + +void CreatePasscode() +{ + char token[64] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + srand((unsigned int)time(NULL)); + + for (int i=0; i<4; i++) { + int random_num = rand() % 63; + passcode[i] = token[random_num]; + } + + passcode[4] = '\0'; +} + +static void LaunchPasscodeInputPopupCallback(app_control_h request, app_control_h reply, app_control_result_e result_e, void *user_data) +{ + usercallback_info *info = (usercallback_info *)user_data; + + int result = -1; + char *passcode; + + char *reply_message; + app_control_get_extra_data(reply, "REPLY_MESSAGE", &reply_message); + + if (!strcmp(reply_message, "CONNECT")) { + result = ACLResult_Connect; + app_control_get_extra_data(reply, "PASSCODE", &passcode); + } else if (!strcmp(reply_message, "CANCEL")) { + result = ACLResult_Cancel; + } else if (!strcmp(reply_message, "CLOSE")) { + result = ACLResult_Close; + } + + info->callback(info->userdata, result, passcode); +} + +void conv::acl_manager::LaunchPasscodeInputPopup(PopupCallback callback, void *userdata) +{ + bundle *b = NULL; + b = bundle_create(); + bundle_add(b, "TYPE", "PASSCODE_INPUT_POPUP"); + + char *popup_name = "d2d-conv-syspopup"; + int ret = syspopup_launch(popup_name, b); + if (ret != 0) { + _E("syspopup_launch Error (%d).", ret); + } + + bundle_free(b); + + info = (usercallback_info *)malloc(sizeof(usercallback_info)*1); + info->callback = callback; + info->userdata = userdata; + + app_control_h app_control; + app_control_create(&app_control); + app_control_set_app_id(app_control, "org.tizen.d2d-conv-syspopup"); + app_control_add_extra_data(app_control, "MESSAGE", "REGIST_CALLBACK"); + app_control_send_launch_request(app_control, LaunchPasscodeInputPopupCallback, info); + app_control_destroy(app_control); +} + +void conv::acl_manager::LaunchPasscodeShowPopup(const char *deviceName) +{ + CreatePasscode(); + + bundle *b = NULL; + b = bundle_create(); + bundle_add(b, "TYPE", "PASSCODE_SHOW_POPUP"); + bundle_add(b, "DATA_PASSCODE", passcode); + bundle_add(b, "DATA_DEVICE_NAME", deviceName); + + char *popup_name = "d2d-conv-syspopup"; + int ret = syspopup_launch(popup_name, b); + if (ret != 0) { + _E("syspopup_launch Error (%d).", ret); + } + + bundle_free(b); +} + +static void LaunchToast(char *type) +{ + app_control_h app_control; + app_control_create(&app_control); + app_control_set_app_id(app_control, "org.tizen.d2d-conv-syspopup"); + app_control_add_extra_data(app_control, "MESSAGE", type); + app_control_send_launch_request(app_control, LaunchPasscodeInputPopupCallback, info); + app_control_destroy(app_control); +} + +void conv::acl_manager::LaunchPopupCancelToast() +{ + LaunchToast((char*)"CANCEL"); +} + +void conv::acl_manager::LaunchPasscodeWrongToast() +{ + LaunchToast((char*)"WRONG_PASSCODE"); +} + +void conv::acl_manager::LaunchAccessAllowedToast() +{ + LaunchToast((char*)"ACCESS_ALLOWED"); +} + +void conv::acl_manager::LaunchAccessRejectedToast() +{ + LaunchToast((char*)"REJECTED"); +} + +static int database_initialize(sqlite3 **database, sqlite3_stmt **stmt, const char *query) +{ + int ret = sqlite3_open(DB_FILE_NAME, &(*database)); + if (ret != SQLITE_OK) { + _E("Open the database is fail. (%d: %s)", ret, sqlite3_errmsg(*database)); + return ret; + } + + const char *create_table_query = "create table if not exists DEVICES_INFO(MAC_ADDRESS text(100) NOT NULL PRIMARY KEY, DEVICE_NAME text(50) NOT NULL, IP_ADDRESS text(50) NOT NULL, ACL_STATE int NOT NULL);"; + ret = sqlite3_exec(*database, create_table_query, NULL, NULL, NULL); + if (ret != SQLITE_OK) { + _E("Create the database table is fail. (%d: %s)", ret, sqlite3_errmsg(*database)); + sqlite3_close(*database); + return ret; + } + + while (true) { + ret = sqlite3_exec(*database, "BEGIN IMMEDIATE TRANSACTION", NULL, NULL, NULL); + if (ret != SQLITE_BUSY) { + if (ret == SQLITE_ERROR) { + _E("Transaction begin is fail. (%d: %s)", ret, sqlite3_errmsg(*database)); + sqlite3_close(*database); + return ret; + } + break; + } + } + + ret = sqlite3_prepare(*database, query, -1, &(*stmt), NULL); + if (ret != SQLITE_OK) { + _E("Statement prepare is fail. (%d: %s)", ret, sqlite3_errmsg(*database)); + return ret; + } + + ret = sqlite3_reset(*stmt); + if (ret != SQLITE_OK) { + _E("Statement reset is fail. (%d: %s)", ret, sqlite3_errmsg(*database)); + return ret; + } + + ret = sqlite3_clear_bindings(*stmt); + if (ret != SQLITE_OK) { + _E("Statement binding clear is fail. (%d: %s)", ret, sqlite3_errmsg(*database)); + return ret; + } + + return SQLITE_OK; +} + +static int database_finalize(sqlite3 *database, sqlite3_stmt *stmt) +{ + int ret = sqlite3_finalize(stmt); + if (ret != SQLITE_OK) { + _E("Statement free is fail. (%d: %s)", ret, sqlite3_errmsg(database)); + sqlite3_close(database); + return ret; + } + + while (true) { + ret = sqlite3_exec(database, "COMMIT TRANSACTION", NULL, NULL, NULL); + if (ret != SQLITE_BUSY) { + if(ret == SQLITE_ERROR) { + _E("Transaction commit is fail. (%d: %s)", ret, sqlite3_errmsg(database)); + sqlite3_close(database); + return ret; + } + break; + } + } + + ret = sqlite3_close(database); + if (ret != SQLITE_OK) { + _E("Close the database is fail. (%d: %s)", ret, sqlite3_errmsg(database)); + return ret; + } + + return SQLITE_OK; +} + +ACLResult conv::acl_manager::SetDeviceInfoAndACL(const char* MacAddress, const char* deviceName, const char* deviceIP, ACManagerPolicy deviceState) +{ + sqlite3 *database = NULL; + sqlite3_stmt *stmt = NULL; + const char *insert_device_info_query = "insert into DEVICES_INFO (MAC_ADDRESS, DEVICE_NAME, IP_ADDRESS, ACL_STATE) values (?, ?, ?, ?);"; + + int ret = database_initialize(&database, &stmt, insert_device_info_query); + if (ret != SQLITE_OK) { + return ACLResult_Error; + } + + ret = sqlite3_bind_text(stmt, 1, MacAddress, strlen(MacAddress), SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + _E("Statement binding the MacAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database)); + } + + ret = sqlite3_bind_text(stmt, 2, deviceName, strlen(deviceName), SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + _E("Statement binding the deviceName text is fail. (%d: %s)", ret, sqlite3_errmsg(database)); + } + + ret = sqlite3_bind_text(stmt, 3, deviceIP, strlen(deviceIP), SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + _E("Statement binding the deviceIP text is fail. (%d: %s)", ret, sqlite3_errmsg(database)); + } + + ret = sqlite3_bind_int(stmt, 4, deviceState); + if (ret != SQLITE_OK) { + _E("Statement binding the deviceState integer is fail. (%d: %s)", ret, sqlite3_errmsg(database)); + } + + ret = sqlite3_step(stmt); + if (ret != SQLITE_OK) { + _E("Statement step is fail. (%d: %s)", ret, sqlite3_errmsg(database)); + } + + ret = database_finalize(database, stmt); + if(ret != SQLITE_OK){ + return ACLResult_Error; + } + + return ACLResult_OK; +} + + +ACLResult conv::acl_manager::GetACLState (const char *MacAddress, ACManagerPolicy *AclState) +{ + sqlite3 *database = NULL; + sqlite3_stmt *stmt = NULL; + const char *get_acl_state_query = "select ACL_STATE from DEVICES_INFO where MAC_ADDRESS=?;"; + + int ret = database_initialize(&database, &stmt, get_acl_state_query); + if (ret != SQLITE_OK) { + return ACLResult_Error; + } + + if(database == NULL) { + _E("DATABASE is NULL"); + } + _E("DATABASE is not NULL"); + + + ret = sqlite3_bind_text(stmt, 1, MacAddress, strlen(MacAddress), SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + _E("MacAddress Bind fail. (%d: %s)", ret, sqlite3_errmsg(database)); + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + *AclState = static_cast (sqlite3_column_int(stmt, 0)); + } + + ret = database_finalize(database, stmt); + if(ret != SQLITE_OK){ + return ACLResult_Error; + } + + return ACLResult_OK; +} + +ACLResult conv::acl_manager::AddACLDevice (const char *MacAddress, const char *deviceName, const char *deviceIP, ACManagerPolicy *AclState) +{ + if (AclState == NULL || MacAddress == NULL || deviceName == NULL || deviceIP == NULL) { + return ACLResult_Error; + } + + *AclState = ACMANAGER_POLICY_U2; + + int ret = conv::acl_manager::GetACLState(MacAddress, AclState); + if (ret != ACLResult_OK) { + return ACLResult_Error; + } + + return ACLResult_OK; +} + +static ACLResult PrintDatabase () +{ + sqlite3 *database = NULL; + sqlite3_stmt *stmt = NULL; + const char *get_table_info_all_query = "select MAC_ADDRESS, DEVICE_NAME, DEVICE_IP, ACL_STATE from DEVICES_INFO;"; + + int ret = database_initialize(&database, &stmt, get_table_info_all_query); + if (ret != SQLITE_OK) { + return ACLResult_Error; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + char *MacAddress = (char *)sqlite3_column_text(stmt, 0); + char *DeviceName = (char *)sqlite3_column_text(stmt, 1); + char *DeviceIP = (char *)sqlite3_column_text(stmt, 2); + ACManagerPolicy AclState = static_cast (sqlite3_column_int(stmt, 3)); + _I("MacAddress:%s, DeviceName:%s, IP:%s, State:%d", MacAddress, DeviceName, DeviceIP, AclState); + } + + ret = database_finalize(database, stmt); + if(ret != SQLITE_OK){ + return ACLResult_Error; + } + + return ACLResult_OK; +} \ No newline at end of file diff --git a/daemon/access_control/ACLManager.h b/daemon/access_control/ACLManager.h new file mode 100644 index 0000000..a33d458 --- /dev/null +++ b/daemon/access_control/ACLManager.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONV_ACL_MANAGER_H__ +#define __CONV_ACL_MANAGER_H__ + +typedef enum ACManagerPolicy { + ACMANAGER_POLICY_P = 0, /* allowed/permitted */ + ACMANAGER_POLICY_D, /* denied */ + ACMANAGER_POLICY_U, /* undecided - TV */ + ACMANAGER_POLICY_U2, /* undecided - Mobile + wearable */ +} ACManagerPolicy ; + +typedef enum ACLResult { + ACLResult_OK = 0, /* error none */ + ACLResult_Error, /* error */ + ACLResult_Connect, /* connect */ + ACLResult_Cancel, /* cancel */ + ACLResult_Close, /* close */ +} ACLResult; + +namespace conv { + namespace acl_manager { + + typedef void (*PopupCallback)(void *userdata, int result, char *passcode); + + void LaunchPasscodeShowPopup(const char *deviceName); + void LaunchPasscodeInputPopup(PopupCallback callback, void *userdata); + + void LaunchPopupCancelToast(); + void LaunchPasscodeWrongToast(); + void LaunchAccessAllowedToast(); + void LaunchAccessRejectedToast(); + + ACLResult PasscodeChecker (char *input_passcode); + + ACLResult GetACLState(const char *MacAddress, ACManagerPolicy *AclState); + ACLResult AddACLDevice(const char *MacAddress, const char *deviceName, const char *deviceIP, ACManagerPolicy *AclState); + ACLResult SetDeviceInfoAndACL(const char* MacAddress, const char* deviceName, const char* deviceIP, ACManagerPolicy deviceState); + } +} + +#endif /* End of __CONV_ACL_MANAGER_H__ */ diff --git a/daemon/service_provider/RemoteAppControlServiceProvider.cpp b/daemon/service_provider/RemoteAppControlServiceProvider.cpp index 4546b5e..09fcb04 100755 --- a/daemon/service_provider/RemoteAppControlServiceProvider.cpp +++ b/daemon/service_provider/RemoteAppControlServiceProvider.cpp @@ -20,6 +20,13 @@ #include "RemoteAppControlServiceProvider.h" #include "../ClientManager.h" #include "../Util.h" +#if defined(_TV_) +#include +#else +#include "../access_control/ACLManager.h" + +using namespace conv::acl_manager; +#endif using namespace std; @@ -200,18 +207,80 @@ static void _app_control_cb(app_control_h request, app_control_h reply, app_cont static int __access_control(iotcon_request_h request, iotcon_attributes_h attributes) { string policy; + char *deviceName; _D("Access Request Handling"); int ret = iotcon_attributes_get_str(attributes, CONV_JSON_DEVICE_NAME, &deviceName); IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret); -#if defined(_TV_) - _D("TV:Always returns PERMITTED"); - policy = CONV_ACCESS_CONTROL_PERMITTED; -#else - _D("Always returns PERMITTED"); - policy = CONV_ACCESS_CONTROL_PERMITTED; + char *hostAddress; + ret = iotcon_request_get_host_address(request, &hostAddress); + IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_request_get_host_address() Fail(%d)", ret); + + string hostAddressString(hostAddress); + string ip = conv::util::getIpAddress(hostAddressString); + + char macAddress[127] = {0,}; + + IF_FAIL_RETURN_TAG(conv::util::getPeerMac(ip, -1, macAddress), CONV_ERROR_INVALID_PARAMETER, _E, "getPeerMac failed"); + + _D("Device Name : %s, Device IP : %s, Mac : %s", deviceName, ip.c_str(), macAddress); + + char *access_request_type = NULL; + ret = iotcon_attributes_get_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, &access_request_type); + _D("Access Request : %s", access_request_type); + IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_representation_get_attributes() Fail(%d)", ret); + + if(!strcmp(CONV_ACCESS_CONTROL_REQUEST, access_request_type)) { + + ACManagerPolicy acManagerPolicy = ACMANAGER_POLICY_U; + IF_FAIL_RETURN_TAG(AddACLDevice(macAddress, deviceName, ip.c_str(), &acManagerPolicy) == ACLResult_OK, CONV_ERROR_INVALID_OPERATION, _E, "AddACLDevice failed"); + + if (acManagerPolicy == ACMANAGER_POLICY_P) { + _D("PERMITTED"); + policy = CONV_ACCESS_CONTROL_PERMITTED; + } else if (acManagerPolicy == ACMANAGER_POLICY_D) { + _D("DENIED"); + policy = CONV_ACCESS_CONTROL_DENIED; + } else if (acManagerPolicy == ACMANAGER_POLICY_U){ + _D("UNDECIDED"); + policy = CONV_ACCESS_CONTROL_DENIED; + } +#if !defined(_TV_) + else if (acManagerPolicy == ACMANAGER_POLICY_U2) { + _D("UNDECIDED"); + conv::acl_manager::LaunchPasscodeShowPopup(deviceName); + policy = CONV_ACCESS_CONTROL_PASSCODE_REQUEST; + } +#endif + _D("acManagerPolicy:%d", acManagerPolicy); + + } +#if !defined(_TV_) + else if (!strcmp(CONV_ACCESS_CONTROL_PASSCODE_RESPONSE, access_request_type)) { + + char *input_passcode; + ret = iotcon_attributes_get_str(attributes, CONV_JSON_PASSCODE, &input_passcode); + IF_FAIL_RETURN_TAG(ret == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_PARAMETER, _E, "iotcon_attributes_get_str() Fail(%d)", ret); + + ret = conv::acl_manager::PasscodeChecker(input_passcode); + if (ret == ACLResult_OK) { + policy = CONV_ACCESS_CONTROL_PASSCODE_RIGHT; + SetDeviceInfoAndACL(macAddress, deviceName, ip.c_str(), ACMANAGER_POLICY_P); + conv::acl_manager::LaunchAccessAllowedToast(); + } else if (ret == ACLResult_Error){ + policy = CONV_ACCESS_CONTROL_PASSCODE_WRONG; + } else if (ret == ACLResult_Close) { + policy = CONV_ACCESS_CONTROL_PASSCODE_REJECTED; + } + + } else if (!strcmp(CONV_ACCESS_CONTROL_PASSCODE_CANCEL, access_request_type)) { + + _D("Access Cancel Handling"); + policy = CONV_ACCESS_CONTROL_DENIED; + conv::acl_manager::LaunchPopupCancelToast(); + } #endif iotcon_response_result_e result; result = IOTCON_RESPONSE_OK; @@ -366,7 +435,6 @@ void conv::RemoteAppControlServiceProvider::__iotcon_request_cb(iotcon_resource_ _send_response(request, NULL, IOTCON_RESPONSE_ERROR); return; } - _D("request type : %d", type); if (IOTCON_REQUEST_PUT == type) { @@ -441,6 +509,8 @@ int conv::RemoteAppControlServiceProvider::release() return CONV_ERROR_NONE; } +static void passcode_popup_callback(void *user_data, int result, char *passcode); + //callback function handles reply from access control request static void __on_access_response(iotcon_remote_resource_h resource, iotcon_error_e err, iotcon_request_type_e request_type, iotcon_response_h response, void *user_data) @@ -481,20 +551,82 @@ static void __on_access_response(iotcon_remote_resource_h resource, iotcon_error } if (!strcmp(CONV_ACCESS_CONTROL_PERMITTED, accessControlResult)) { + _D("__on_access_response PERMITTED"); conv::Json result; svcInfo->accessControlState = ACCESS_CONTROL_STATE_PERMITTED; - _D("__on_access_response PERMITTED"); sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_NONE, svcInfo->registeredRequest); return; - } else { + + } +#if !defined(_TV_) + else if (!strcmp(CONV_ACCESS_CONTROL_PASSCODE_REQUEST, accessControlResult)) { + _D("__on_access_response PASSCODE REQUEST"); + conv::acl_manager::LaunchPasscodeInputPopup(passcode_popup_callback, svcInfo); + return; + + } else if (!strcmp(CONV_ACCESS_CONTROL_PASSCODE_RIGHT, accessControlResult)) { + _D("__on_access_response PASSCODE RIGHT"); + conv::acl_manager::LaunchAccessAllowedToast(); + conv::Json result; + svcInfo->accessControlState = ACCESS_CONTROL_STATE_PERMITTED; + sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_NONE, svcInfo->registeredRequest); + return; + + } else if (!strcmp(CONV_ACCESS_CONTROL_PASSCODE_WRONG, accessControlResult)) { + _D("__on_access_response PASSCODE WRONG"); + conv::acl_manager::LaunchPasscodeWrongToast(); + return; + + } else if (!strcmp(CONV_ACCESS_CONTROL_PASSCODE_REJECTED, accessControlResult)) { + _D("__on_access_response PASSCODE REJECTED"); + conv::acl_manager::LaunchAccessRejectedToast(); conv::Json result; svcInfo->accessControlState = ACCESS_CONTROL_STATE_DENIED; + sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest); + return; + + } +#endif + else { _D("__on_access_response DENIED"); + conv::Json result; + svcInfo->accessControlState = ACCESS_CONTROL_STATE_DENIED; sendResponse(result, CONV_JSON_ON_START, CONV_ERROR_INVALID_OPERATION, svcInfo->registeredRequest); return; } } +#if !defined(_TV_) +static void passcode_popup_callback(void *user_data, int result, char *passcode) +{ + conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast(user_data); + + iotcon_representation_h representation; + iotcon_representation_create(&representation); + + iotcon_attributes_h attributes; + iotcon_attributes_create(&attributes); + + if (result == ACLResult_Cancel) { + iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST); + iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_PASSCODE_CANCEL); + iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)svcInfo->deviceName.c_str()); + + } else if (result == ACLResult_Connect) { + iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST); + iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_PASSCODE_RESPONSE); + iotcon_attributes_add_str(attributes, CONV_JSON_PASSCODE, passcode); + iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)svcInfo->deviceName.c_str()); + } + + iotcon_representation_set_attributes(representation, attributes); + svcInfo->iotconInfoObj.iotconRepresentationHandle = representation; + iotcon_attributes_destroy(attributes); + + iotcon_remote_resource_put(svcInfo->iotconInfoObj.iotconResourceHandle, representation, NULL, __on_access_response, svcInfo); +} +#endif + int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj) { _D("communcation/start requested"); @@ -542,7 +674,8 @@ int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj) iotcon_attributes_h attributes; iotcon_attributes_create(&attributes); - iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char *)CONV_ACCESS_CONTROL_REQUEST); + iotcon_attributes_add_str(attributes, CONV_JSON_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST); + iotcon_attributes_add_str(attributes, CONV_JSON_ACCESS_REQUEST_TYPE, (char*)CONV_ACCESS_CONTROL_REQUEST); iotcon_attributes_add_str(attributes, CONV_JSON_DEVICE_NAME, (char*)svcInfo->deviceName.c_str()); iotcon_representation_set_attributes(representation, attributes); diff --git a/packaging/d2d-conv-manager.spec b/packaging/d2d-conv-manager.spec index 3f6e362..c4dd57c 100755 --- a/packaging/d2d-conv-manager.spec +++ b/packaging/d2d-conv-manager.spec @@ -37,13 +37,16 @@ BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(capi-appfw-package-manager) BuildRequires: pkgconfig(nsd-dns-sd) BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(syspopup-caller) BuildRequires: openssl BuildRequires: openssl-devel BuildRequires: curl BuildRequires: libcurl-devel %if "%{?BUILD_PROFILE}" == "tv" - +BuildRequires: pkgconfig(acl-proxy-api) +BuildRequires: pkgconfig(securestorage-client) %endif %define _userdatadir /opt/usr/data/d2d-conv-manager