Addition the Access Control module for mobile and wearable. 56/94456/5
authorsegwon <segwon.han@samsung.com>
Mon, 31 Oct 2016 04:18:28 +0000 (13:18 +0900)
committersegwon <segwon.han@samsung.com>
Tue, 1 Nov 2016 06:43:45 +0000 (15:43 +0900)
Signed-off-by: segwon <segwon.han@samsung.com>
Change-Id: I1e3efecec1e93e6c2cde1354ea25a07814373a66

common/Types.h
daemon/CMakeLists.txt
daemon/access_control/ACLManager.cpp [new file with mode: 0644]
daemon/access_control/ACLManager.h [new file with mode: 0644]
daemon/service_provider/RemoteAppControlServiceProvider.cpp
packaging/d2d-conv-manager.spec

index b9cc30b..481e819 100644 (file)
@@ -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
index 1c62c67..2b28974 100755 (executable)
@@ -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 (file)
index 0000000..591f646
--- /dev/null
@@ -0,0 +1,363 @@
+#include "ACLManager.h"
+#include "Log.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sqlite3.h>
+#include <syspopup_caller.h>
+#include <bundle_internal.h>
+#include <app_control.h>
+#include <app_manager.h>
+
+#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<ACManagerPolicy> (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<ACManagerPolicy> (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 (file)
index 0000000..a33d458
--- /dev/null
@@ -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__ */
index 4546b5e..09fcb04 100755 (executable)
 #include "RemoteAppControlServiceProvider.h"
 #include "../ClientManager.h"
 #include "../Util.h"
+#if defined(_TV_)
+#include <RemoteACLInterface.h>
+#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<conv::RemoteAppControlServiceInfo*>(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);
index 3f6e362..c4dd57c 100755 (executable)
@@ -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