Add engine APIs and sample engine & tests 38/66338/1
authorKyungwook Tak <k.tak@samsung.com>
Tue, 22 Mar 2016 05:26:25 +0000 (14:26 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Mon, 18 Apr 2016 11:11:59 +0000 (20:11 +0900)
Change-Id: I7aaa58c201f5ace245b660c3203f149bd701dfab
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
25 files changed:
CMakeLists.txt
engine/CMakeLists.txt [new file with mode: 0644]
engine/content-screening/CMakeLists.txt [new file with mode: 0644]
engine/content-screening/resources/csret_cs_virus_signatures [new file with mode: 0644]
engine/content-screening/sample-engine.cpp [new file with mode: 0644]
engine/web-protection/CMakeLists.txt [new file with mode: 0644]
engine/web-protection/resources/csret_wp_risky_urls [new file with mode: 0644]
engine/web-protection/sample-engine.cpp [new file with mode: 0644]
packaging/csr-framework.spec
packaging/csr-test.manifest.in [new file with mode: 0644]
src/framework/service/logic.cpp
src/include/csr/engine-manager.h
src/include/csre/content-screening-engine-info.h [new file with mode: 0644]
src/include/csre/content-screening-types.h [new file with mode: 0644]
src/include/csre/content-screening.h [new file with mode: 0644]
src/include/csre/error.h [new file with mode: 0644]
src/include/csre/web-protection-engine-info.h [new file with mode: 0644]
src/include/csre/web-protection-types.h [new file with mode: 0644]
src/include/csre/web-protection.h [new file with mode: 0644]
test/CMakeLists.txt
test/resources/test_malware_file [new file with mode: 0644]
test/resources/test_normal_file [new file with mode: 0644]
test/resources/test_risky_file [new file with mode: 0644]
test/test-api-engine-content-screening.cpp [new file with mode: 0644]
test/test-api-engine-web-protection.cpp [new file with mode: 0644]

index 6b8e194..798e49a 100644 (file)
@@ -39,6 +39,8 @@ STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}")
 ADD_DEFINITIONS("-DSERVICE_NAME=\"${SERVICE_NAME}\"")
 ADD_DEFINITIONS("-DINCLUDE_INSTALL_DIR=\"${INCLUDE_INSTALL_DIR}\"")
 ADD_DEFINITIONS("-DBIN_DIR=\"${BIN_DIR}\"")
+ADD_DEFINITIONS("-DSAMPLE_ENGINE_WORKING_DIR=\"${SAMPLE_ENGINE_WORKING_DIR}\"")
+ADD_DEFINITIONS("-DTEST_DIR=\"${TEST_DIR}\"")
 
 IF (CMAKE_BUILD_TYPE MATCHES "DEBUG")
        ADD_DEFINITIONS("-DTIZEN_DEBUG_ENABLE")
@@ -49,12 +51,17 @@ SET(TARGET_CSR_SERVER ${SERVICE_NAME}-server)
 SET(TARGET_CSR_CLIENT ${SERVICE_NAME}-client)
 SET(TARGET_CSR_COMMON ${SERVICE_NAME}-common)
 SET(TARGET_CSR_TEST ${SERVICE_NAME}-test)
+SET(TARGET_CSR_CS_ENGINE_SAMPLE ${SERVICE_NAME}-cs-engine)
+SET(TARGET_CSR_WP_ENGINE_SAMPLE ${SERVICE_NAME}-wp-engine)
+SET(TARGET_CSR_ENGINE_TEST ${SERVICE_NAME}-engine-test)
 
 CONFIGURE_FILE(packaging/${SERVICE_NAME}.manifest.in ${SERVICE_NAME}.manifest @ONLY)
 CONFIGURE_FILE(packaging/${SERVICE_NAME}-client.manifest.in ${SERVICE_NAME}-client.manifest @ONLY)
 CONFIGURE_FILE(packaging/${SERVICE_NAME}-common.manifest.in ${SERVICE_NAME}-common.manifest @ONLY)
+CONFIGURE_FILE(packaging/${SERVICE_NAME}-test.manifest.in ${SERVICE_NAME}-test.manifest @ONLY)
 
 ADD_SUBDIRECTORY(src)
 ADD_SUBDIRECTORY(pkgconfig)
 ADD_SUBDIRECTORY(systemd)
 ADD_SUBDIRECTORY(test)
+ADD_SUBDIRECTORY(engine)
diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4ef0895
--- /dev/null
@@ -0,0 +1,20 @@
+# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    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.
+#
+# @file        CMakeLists.txt
+# @author      Kyungwook Tak (k.tak@samsung.com)
+# @brief       build sample engine of csr cs & wp
+#
+ADD_SUBDIRECTORY(content-screening)
+ADD_SUBDIRECTORY(web-protection)
diff --git a/engine/content-screening/CMakeLists.txt b/engine/content-screening/CMakeLists.txt
new file mode 100644 (file)
index 0000000..515080a
--- /dev/null
@@ -0,0 +1,45 @@
+# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    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.
+#
+# @file        CMakeLists.txt
+# @author      Kyungwook Tak (k.tak@samsung.com)
+# @brief       build sample engine of content screening
+#
+PKG_CHECK_MODULES(${TARGET_CSR_CS_ENGINE_SAMPLE}_DEP
+       REQUIRED
+)
+
+INCLUDE_DIRECTORIES(
+       ${PROJECT_SOURCE_DIR}/src/include
+       .
+       ${${TARGET_CSR_CS_ENGINE_SAMPLE}_DEP_INCLUDE_DIRS}
+)
+
+SET(${TARGET_CSR_CS_ENGINE_SAMPLE}_SRCS
+       sample-engine.cpp
+)
+
+ADD_LIBRARY(${TARGET_CSR_CS_ENGINE_SAMPLE} SHARED ${${TARGET_CSR_CS_ENGINE_SAMPLE}_SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_CSR_CS_ENGINE_SAMPLE}
+       PROPERTIES
+               COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden"
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_CSR_CS_ENGINE_SAMPLE}
+       ${${TARGET_CSR_CS_ENGINE_SAMPLE_DEP}_LIBRARIES}
+)
+
+INSTALL(TARGETS ${TARGET_CSR_CS_ENGINE_SAMPLE} DESTINATION ${SAMPLE_ENGINE_DIR})
+INSTALL(DIRECTORY resources/ DESTINATION ${SAMPLE_ENGINE_WORKING_DIR})
diff --git a/engine/content-screening/resources/csret_cs_virus_signatures b/engine/content-screening/resources/csret_cs_virus_signatures
new file mode 100644 (file)
index 0000000..e04a0d4
--- /dev/null
@@ -0,0 +1,19 @@
+data_version=1.0.0
+# data_version should be in the first line.
+# No space is allowed.
+
+# this starts a description of a new malware
+name=test_malware
+# LOW/MEDIUM/HIGH
+severity=HIGH
+# MALWARE/RISKY/GENERIC
+threat_type=MALWARE
+# detailed_url can be null
+detailed_url=http://detailedinfo.malware.com
+signature=X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
+
+name=test_risk
+severity=MEDIUM
+threat_type=RISKY
+detailed_url=
+signature=RISKY_MALWARE
diff --git a/engine/content-screening/sample-engine.cpp b/engine/content-screening/sample-engine.cpp
new file mode 100644 (file)
index 0000000..c3d8dd1
--- /dev/null
@@ -0,0 +1,793 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include "csre/content-screening.h"
+#include "csre/content-screening-engine-info.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define API __attribute__((visibility("default")))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PRIVATE_DB_NAME   "csret_cs_virus_signatures"
+#define PRIVATE_LOGO_FILE "vendor_logo.bmp"
+#define MAX_FILE_PATH_LEN 256
+#define MAX_NAME_LEN      64
+#define MAX_VERSION_LEN   32
+#define MAX_URL_LEN       256
+#define MAX_SIG_LEN       256
+
+#define VENDOR_NAME       "TEST_VENDOR"
+#define ENGINE_NAME       "TEST_LOCAL_TCS_ENGINE"
+#define ENGINE_VERSION    "0.0.1"
+
+typedef enum  __csret_cs_scan_on_cloud {
+       TCSE_SCAN_ON_CLOUD_OFF = 0,
+       TCSE_SCAN_ON_CLOUD_ON  = 1
+} csret_cs_scan_on_cloud_e;
+
+typedef struct __csret_cs_malware {
+       csre_cs_severity_level_e severity;
+       csre_cs_threat_type_e threat_type;
+       char malware_name[MAX_NAME_LEN];
+       char detailed_url[MAX_URL_LEN];
+       char signature[MAX_SIG_LEN];
+} csret_cs_malware_s;
+
+typedef struct __csret_cs_malware_list {
+       struct __csret_cs_malware_list *next;
+       csret_cs_malware_s malware;
+} csret_cs_malware_list_s;
+
+typedef struct __csret_cs_detected {
+       csret_cs_malware_s malware;
+       long timestamp;
+} csret_cs_detected_s;
+
+typedef struct __csret_cs_detected_list {
+       struct __csret_cs_detected_list *next;
+       csret_cs_detected_s *detected;
+} csret_cs_detected_list_s;
+
+typedef struct __csret_cs_context {
+       int scan_on_data;
+       csret_cs_detected_list_s *detected_list;
+} csret_cs_context_s;
+
+typedef struct __csret_cs_engine {
+       char vendor_name[MAX_NAME_LEN];
+       char engine_name[MAX_NAME_LEN];
+       unsigned char *vendor_logo_image;
+       unsigned int image_size;
+       char engine_version[MAX_VERSION_LEN];
+       char data_version[MAX_VERSION_LEN];
+} csret_cs_engine_s;
+
+typedef enum __csret_cs_internal_error {
+       CSRET_CS_ERROR_NO_SIGNATURE_FILE    = -0x0101,
+       CSRET_CS_ERROR_SIGNARUE_FILE_FORMAT = -0x0102,
+       CSRET_CS_ERROR_FILE_IO              = -0x0103
+} csret_cs_internal_error_e;
+
+//==============================================================================
+// static variables
+//==============================================================================
+static csret_cs_engine_s       *engine_info = nullptr;
+static csret_cs_malware_list_s *virus_sig   = nullptr;
+
+//==============================================================================
+// Utilities functions
+//==============================================================================
+
+char *csret_cs_extract_value(char *line, const char *key)
+{
+       if (line == nullptr || key == nullptr)
+               return nullptr;
+
+       auto found = strstr(line, key);
+       if (found == nullptr)
+               return nullptr;
+
+       auto value = found + strlen(key);
+
+       // remove end line char
+       for (auto current = found; current && *current; current++) {
+               if (*current == '\n') {
+                       *current = '\0';
+                       break;
+               }
+       }
+
+       return value;
+}
+
+int csret_cs_read_virus_signatures(const char *path)
+{
+       // virus_signature file format
+       // data_version=1.0.0 // it should be in the first line.
+       // # this line is a comment.
+       //
+       // name=test_malware // this starts a description of a new malware
+       // severity=HIGH  // LOW/MEDIUM/HIGH
+       // threat_type=MALWARE  // MALWARE/RISKY/GENERIC
+       // detailed_url=        // It can be null
+       // signature=X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
+       //
+       // name=test_risk
+       // severity=MEDIUM
+       // threat_type=RISKY
+       // detailed_url=
+       // signature=RISKY_MALWARE
+
+       csret_cs_malware_list_s *curr_sig = nullptr;
+
+       FILE *fp = fopen(path, "r");
+       if (fp == nullptr)
+               return CSRET_CS_ERROR_NO_SIGNATURE_FILE;
+
+       char *line = nullptr;
+       size_t len = 0;
+       ssize_t read;
+       while ((read = getline(&line, &len, fp)) != -1) {
+               if (line == nullptr || strlen(line) == 0)
+                       continue;
+
+               auto value = csret_cs_extract_value(line, "data_version=");
+
+               if (value != nullptr && engine_info != nullptr)
+                       strncpy(engine_info->data_version, value, sizeof(engine_info->data_version) - 1);
+
+               value = csret_cs_extract_value(line, "name=");
+
+               if (value != nullptr) {
+                       auto next_sig = (csret_cs_malware_list_s *) calloc(sizeof(csret_cs_malware_list_s), 1);
+
+                       if (curr_sig != nullptr)
+                               curr_sig->next = next_sig;
+                       else
+                               virus_sig = next_sig;
+
+                       curr_sig = next_sig;
+                       strncpy(curr_sig->malware.malware_name, value, sizeof(curr_sig->malware.malware_name) - 1);
+               }
+
+               value = csret_cs_extract_value(line, "severity=");
+
+               if (value != nullptr) {
+                       if (strcmp(value, "LOW") == 0)
+                               curr_sig->malware.severity = CSRE_CS_SEVERITY_LOW;
+                       else if (strcmp(value, "MEDIUM") == 0)
+                               curr_sig->malware.severity = CSRE_CS_SEVERITY_MEDIUM;
+                       else
+                               curr_sig->malware.severity = CSRE_CS_SEVERITY_HIGH;
+               }
+
+               value = csret_cs_extract_value(line, "threat_type=");
+
+               if (value != nullptr) {
+                       if (strcmp(value, "MALWARE") == 0)
+                               curr_sig->malware.threat_type = CSRE_CS_THREAT_MALWARE;
+                       else if (strcmp(value, "RISKY") == 0)
+                               curr_sig->malware.threat_type = CSRE_CS_THREAT_RISKY;
+                       else
+                               curr_sig->malware.threat_type = CSRE_CS_THREAT_GENERIC;
+               }
+
+               value = csret_cs_extract_value(line, "detailed_url=");
+
+               if (value != nullptr)
+                       strncpy(curr_sig->malware.detailed_url, value, sizeof(curr_sig->malware.detailed_url) - 1);
+
+               value = csret_cs_extract_value(line, "signature=");
+
+               if (value != nullptr)
+                       strncpy(curr_sig->malware.signature, value, sizeof(curr_sig->malware.signature) - 1);
+       }
+
+       free(line);
+       fclose(fp);
+       return CSRE_ERROR_NONE;
+}
+
+
+int csret_cs_read_binary_by_file(FILE *file, unsigned char **data, unsigned int *len)
+{
+       unsigned char *buffer;
+       long int fileLen;
+       int read;
+       int index = 0;
+
+       if (!file)
+               return CSRE_ERROR_FILE_NOT_FOUND;
+
+       //Get file length
+       fseek(file, 0, SEEK_END);
+       fileLen = ftell(file);
+
+       if (fileLen <= 0)
+               return CSRET_CS_ERROR_FILE_IO;
+
+       fseek(file, 0, SEEK_SET);
+       //Allocate memory
+       buffer = (unsigned char *)calloc(fileLen + 1, 1);
+
+       if (!buffer)
+               return CSRE_ERROR_OUT_OF_MEMORY;
+
+       //Read file contents into buffer
+       while ((read = fread(buffer + index, 1, fileLen, file)) > 0)
+               index += read;
+
+       fclose(file);
+
+       if (index != fileLen) {
+               free(buffer);
+               return CSRET_CS_ERROR_FILE_IO;
+       }
+
+       *data = buffer;
+       *len = fileLen;
+       return CSRE_ERROR_NONE;
+}
+
+int csret_cs_read_binary(const char *path, unsigned char **data, unsigned int *len)
+{
+       FILE *file = fopen(path, "rb");
+       return csret_cs_read_binary_by_file(file, data, len);
+}
+
+int csret_cs_read_binary_by_fd(int file_descriptor, unsigned char **data, unsigned int *len)
+{
+       FILE *file = fdopen(file_descriptor, "rb");
+       return csret_cs_read_binary_by_file(file, data, len);
+}
+
+long csret_cs_get_timestamp()
+{
+       unsigned long time_in_micros;
+       struct timeval tv;
+       gettimeofday(&tv, nullptr);
+       time_in_micros = 1000000 * tv.tv_sec + tv.tv_usec;
+       return time_in_micros;
+}
+
+int csret_cs_init_engine(const char *root_dir)
+{
+       int ret = CSRE_ERROR_NONE;
+       char logo_file_name[MAX_FILE_PATH_LEN] = {0, };
+       engine_info = (csret_cs_engine_s *) calloc(sizeof(csret_cs_engine_s), 1);
+
+       if (engine_info == nullptr)
+               return CSRE_ERROR_OUT_OF_MEMORY;
+
+       snprintf(engine_info->vendor_name, MAX_NAME_LEN, "%s", VENDOR_NAME);
+       snprintf(engine_info->engine_name, MAX_NAME_LEN, "%s", ENGINE_NAME);
+       snprintf(engine_info->engine_version, MAX_VERSION_LEN, "%s", ENGINE_VERSION);
+       snprintf(logo_file_name, MAX_FILE_PATH_LEN, "%s/%s", root_dir, PRIVATE_LOGO_FILE);
+       ret = csret_cs_read_binary(logo_file_name, &(engine_info->vendor_logo_image),
+                                                       &(engine_info->image_size));
+
+       if (ret == CSRE_ERROR_FILE_NOT_FOUND) {
+               engine_info->vendor_logo_image = nullptr;
+               engine_info->image_size = 0;
+               ret = CSRE_ERROR_NONE;
+       }
+
+       return ret;
+}
+
+int csret_cs_compare_data(const unsigned char *data, unsigned int data_len,
+                                          const char *virus_signature, unsigned int sig_len)
+{
+       unsigned int i, j;
+
+       if (data_len < sig_len)
+               return -1;
+
+       for (i = 0; i <= (data_len - sig_len); i++) {
+               for (j = 0; j < sig_len; j++) {
+                       if (data[i + j] == (unsigned char) virus_signature[j])
+                               continue;
+                       else
+                               break;
+               }
+
+               if (j == sig_len)
+                       return 0; // matched
+       }
+
+       return -1;
+}
+
+int csret_cs_detect_malware(csret_cs_context_s *context, const unsigned char *data, unsigned int length,
+                                                csret_cs_detected_s **pdetected)
+{
+       char *virus_signature = nullptr;
+       csret_cs_detected_s *detected = nullptr;
+       int ret = CSRE_ERROR_NONE;
+
+       if (context == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (data == nullptr || pdetected == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       if (virus_sig == nullptr)
+               return CSRE_ERROR_ENGINE_NOT_ACTIVATED;
+
+       // comare data with virus signature
+       csret_cs_malware_list_s *curr_sig = virus_sig;
+
+       while (curr_sig != nullptr) {
+               virus_signature = curr_sig->malware.signature;
+
+               if (csret_cs_compare_data(data, length, virus_signature, strlen(virus_signature)) == 0) { // detected
+                       //printf("..csret_cs_detect_malware: detected signature=%s\n", virus_signature);
+                       // create new detected
+                       detected = (csret_cs_detected_s *)calloc(sizeof(csret_cs_detected_s), 1);
+
+                       if (detected == nullptr)
+                               return CSRE_ERROR_OUT_OF_MEMORY;
+
+                       // set detected into context
+                       csret_cs_detected_list_s *last = (csret_cs_detected_list_s *) calloc(sizeof(csret_cs_detected_list_s), 1);
+
+                       if (last == nullptr) {
+                               free(detected);
+                               return CSRE_ERROR_OUT_OF_MEMORY;
+                       }
+
+                       last->detected = detected;
+                       csret_cs_detected_list_s *curr = context->detected_list;
+
+                       while (curr != nullptr && curr->next != nullptr) curr = curr->next; // move to the last
+
+                       curr = last;
+                       // set values into detected
+                       detected->malware.severity = curr_sig->malware.severity;
+                       detected->malware.threat_type = curr_sig->malware.threat_type;
+                       snprintf(detected->malware.malware_name, MAX_NAME_LEN, "%s", curr_sig->malware.malware_name);
+                       snprintf(detected->malware.detailed_url, MAX_URL_LEN, "%s", curr_sig->malware.detailed_url);
+                       detected->timestamp = csret_cs_get_timestamp();
+                       break; // return the first malware in test engine.
+               }
+
+               curr_sig = curr_sig->next;
+       }
+
+       // set detected into context
+       csret_cs_detected_list_s *last = (csret_cs_detected_list_s *) calloc(sizeof(csret_cs_detected_list_s), 1);
+
+       if (last == nullptr)
+               return CSRE_ERROR_OUT_OF_MEMORY;
+
+       last->detected = detected;
+       csret_cs_detected_list_s *curr = context->detected_list;
+
+       while (curr != nullptr && curr->next != nullptr) curr = curr->next; // move to the last
+
+       curr = last;
+       *pdetected = detected;
+
+       return ret;
+}
+
+//==============================================================================
+// Main function related
+//==============================================================================
+
+API
+int csre_cs_context_create(const char *engine_root_dir, csre_cs_context_h *phandle)
+{
+       int ret = CSRE_ERROR_NONE;
+       char sig_file[MAX_FILE_PATH_LEN] = {0, };
+
+       if (phandle == nullptr || engine_root_dir == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       csret_cs_context_s *context = (csret_cs_context_s *)calloc(sizeof(csret_cs_context_s), 1);
+
+       if (context == nullptr)
+               return CSRE_ERROR_OUT_OF_MEMORY;
+
+       if (engine_info == nullptr) {
+               ret = csret_cs_init_engine(engine_root_dir);
+
+               if (ret != CSRE_ERROR_NONE)
+                       return ret;
+       }
+
+       if (virus_sig == nullptr) {
+               snprintf(sig_file, sizeof(sig_file), "%s/%s", engine_root_dir, PRIVATE_DB_NAME);
+               ret = csret_cs_read_virus_signatures(sig_file);
+
+               if (ret != CSRE_ERROR_NONE && ret != CSRET_CS_ERROR_NO_SIGNATURE_FILE)
+                       return ret;
+       }
+
+       *phandle = (csre_cs_context_h) context;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_context_destroy(csre_cs_context_h handle)
+{
+       if (handle == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       csret_cs_context_s *context = (csret_cs_context_s *)handle;
+       csret_cs_detected_list_s *curr = nullptr;
+       csret_cs_detected_list_s *prev = nullptr;
+       curr = context->detected_list;
+
+       while (curr != nullptr) {
+               if (curr->detected != nullptr)
+                       free(curr->detected);
+
+               prev = curr;
+               curr = curr->next;
+               free(prev);
+       }
+
+       free(context);
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_set_scan_on_cloud(csre_cs_context_h handle)
+{
+       if (handle == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       csret_cs_context_s *context = (csret_cs_context_s *)handle;
+       context->scan_on_data = TCSE_SCAN_ON_CLOUD_ON;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_scan_data(csre_cs_context_h handle,
+                                         const unsigned char *data,
+                                         size_t length,
+                                         csre_cs_detected_h *pdetected)
+{
+       int ret = CSRE_ERROR_NONE;
+       csret_cs_detected_s *detected = nullptr;
+
+       if (handle == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       csret_cs_context_s *context = (csret_cs_context_s *)handle;
+
+       if (context->scan_on_data == TCSE_SCAN_ON_CLOUD_ON) {
+               //ignored in this engine implementation.
+       }
+
+       ret = csret_cs_detect_malware(context, data, length, &detected);
+
+       if (ret != CSRE_ERROR_NONE)
+               return ret;
+
+       *pdetected = (csre_cs_detected_h) detected;
+       return ret;
+}
+
+API
+int csre_cs_scan_file(csre_cs_context_h handle,
+                                         const char *file_path,
+                                         csre_cs_detected_h *pdetected)
+{
+       int fd = open(file_path, O_RDONLY);
+
+       if (fd < 0)
+               return CSRE_ERROR_FILE_NOT_FOUND;
+
+       return csre_cs_scan_file_by_fd(handle, fd, pdetected);
+}
+
+API
+int csre_cs_scan_file_by_fd(csre_cs_context_h handle,
+                                                       int file_descriptor,
+                                                       csre_cs_detected_h *pdetected)
+{
+       csret_cs_detected_s *detected = nullptr;
+       unsigned char *data;
+       unsigned int data_len;
+       int ret = CSRE_ERROR_NONE;
+
+       if (handle == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (file_descriptor < 0)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       csret_cs_context_s *context = (csret_cs_context_s *)handle;
+
+       if (context->scan_on_data == TCSE_SCAN_ON_CLOUD_ON) {
+               //ignored in this engine implementation.
+       }
+
+       ret = csret_cs_read_binary_by_fd(file_descriptor, &data, &data_len);
+       if (ret != CSRE_ERROR_NONE)
+               return ret;
+
+       ret = csret_cs_detect_malware(context, data, data_len, &detected);
+
+       if (ret != CSRE_ERROR_NONE) {
+               if (data)
+                       free(data);
+               return ret;
+       }
+
+       *pdetected = (csre_cs_detected_h) detected;
+
+       return CSRE_ERROR_NONE;
+}
+
+//==============================================================================
+// Result related
+//==============================================================================
+API
+int csre_cs_detected_get_severity(csre_cs_detected_h detected, csre_cs_severity_level_e *pseverity)
+{
+       csret_cs_detected_s *pdetected = nullptr;
+
+       if (detected == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (pseverity == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       pdetected = (csret_cs_detected_s *) detected;
+       *pseverity = pdetected->malware.severity;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_detected_get_threat_type(csre_cs_detected_h detected,
+                                                                        csre_cs_threat_type_e *pthreat_type)
+{
+       csret_cs_detected_s *pdetected = nullptr;
+
+       if (detected == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (pthreat_type == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       pdetected = (csret_cs_detected_s *) detected;
+       *pthreat_type = pdetected->malware.threat_type;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_detected_get_malware_name(csre_cs_detected_h detected, const char **malware_name)
+{
+       csret_cs_detected_s *pdetected = nullptr;
+
+       if (detected == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (malware_name == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       pdetected = (csret_cs_detected_s *) detected;
+       *malware_name = pdetected->malware.malware_name;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_detected_get_detailed_url(csre_cs_detected_h detected, const char **detailed_url)
+{
+       csret_cs_detected_s *pdetected = nullptr;
+
+       if (detected == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (detailed_url == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       pdetected = (csret_cs_detected_s *) detected;
+       *detailed_url = pdetected->malware.detailed_url;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_detected_get_timestamp(csre_cs_detected_h detected, long *timestamp)
+{
+       csret_cs_detected_s *pdetected = nullptr;
+
+       if (detected == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (timestamp == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       pdetected = (csret_cs_detected_s *) detected;
+       *timestamp = pdetected->timestamp;
+       return CSRE_ERROR_NONE;
+}
+
+//==============================================================================
+// Engine information related
+//==============================================================================
+API
+int csre_cs_engine_get_info(csre_cs_engine_h *pengine)
+{
+       if (pengine == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *pengine = (csre_cs_engine_h)engine_info;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_engine_get_vendor(csre_cs_engine_h engine, const char **vendor)
+{
+       csret_cs_engine_s *eng = (csret_cs_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (vendor == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *vendor = eng->vendor_name;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_engine_get_name(csre_cs_engine_h engine, const char **engine_name)
+{
+       csret_cs_engine_s *eng = (csret_cs_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (engine_name == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *engine_name = eng->engine_name;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_engine_get_vendor_logo(csre_cs_engine_h engine, unsigned char **vendor_logo_image,
+                                                                  unsigned int *image_size)
+{
+       csret_cs_engine_s *eng = (csret_cs_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (vendor_logo_image == nullptr || image_size == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *vendor_logo_image = eng->vendor_logo_image;
+       *image_size = eng->image_size;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_engine_get_version(csre_cs_engine_h engine, const char **version)
+{
+       csret_cs_engine_s *eng = (csret_cs_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (version == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *version = eng->engine_version;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_engine_get_data_version(csre_cs_engine_h engine, const char **version)
+{
+       csret_cs_engine_s *eng = (csret_cs_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (version == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *version = eng->data_version;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_engine_get_activated(csre_cs_engine_h engine, csre_cs_activated_e *pactivated)
+{
+       csret_cs_engine_s *eng = (csret_cs_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (pactivated == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       if (virus_sig == nullptr)
+               *pactivated = CSRE_CS_NOT_ACTIVATED;
+       else
+               *pactivated = CSRE_CS_ACTIVATED;
+
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_cs_engine_get_api_version(csre_cs_engine_h engine, const char **version)
+{
+       csret_cs_engine_s *eng = (csret_cs_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (version == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *version = CSRE_CS_API_VERSION;
+       return CSRE_ERROR_NONE;
+}
+
+
+//==============================================================================
+// Error related
+//==============================================================================
+API
+int csre_cs_get_error_string(int error_code, const char **string)
+{
+       if (string == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       switch (error_code) {
+       case CSRET_CS_ERROR_NO_SIGNATURE_FILE:
+               *string = "CSRET_CS_ERROR_NO_SIGNATURE_FILE";
+               break;
+
+       case CSRET_CS_ERROR_SIGNARUE_FILE_FORMAT:
+               *string = "CSRET_CS_ERROR_SIGNARUE_FILE_FORMAT";
+               break;
+
+       case CSRET_CS_ERROR_FILE_IO:
+               *string = "CSRET_CS_ERROR_FILE_IO";
+               break;
+
+       default:
+               *string = "UNDEFINED ERROR CODE";
+               break;
+       }
+
+       return CSRE_ERROR_NONE;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/engine/web-protection/CMakeLists.txt b/engine/web-protection/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1383766
--- /dev/null
@@ -0,0 +1,45 @@
+# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    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.
+#
+# @file        CMakeLists.txt
+# @author      Kyungwook Tak (k.tak@samsung.com)
+# @brief       build sample engine of csr web protection
+#
+PKG_CHECK_MODULES(${TARGET_CSR_WP_ENGINE_SAMPLE}_DEP
+       REQUIRED
+)
+
+INCLUDE_DIRECTORIES(
+       ${PROJECT_SOURCE_DIR}/src/include
+       .
+       ${${TARGET_CSR_WP_ENGINE_SAMPLE}_DEP_INCLUDE_DIRS}
+)
+
+SET(${TARGET_CSR_WP_ENGINE_SAMPLE}_SRCS
+       sample-engine.cpp
+)
+
+ADD_LIBRARY(${TARGET_CSR_WP_ENGINE_SAMPLE} SHARED ${${TARGET_CSR_WP_ENGINE_SAMPLE}_SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_CSR_WP_ENGINE_SAMPLE}
+       PROPERTIES
+               COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden"
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_CSR_WP_ENGINE_SAMPLE}
+       ${${TARGET_CSR_WP_ENGINE_SAMPLE_DEP}_LIBRARIES}
+)
+
+INSTALL(TARGETS ${TARGET_CSR_WP_ENGINE_SAMPLE} DESTINATION ${SAMPLE_ENGINE_DIR})
+INSTALL(DIRECTORY resources/ DESTINATION ${SAMPLE_ENGINE_WORKING_DIR})
diff --git a/engine/web-protection/resources/csret_wp_risky_urls b/engine/web-protection/resources/csret_wp_risky_urls
new file mode 100644 (file)
index 0000000..0b5ad1a
--- /dev/null
@@ -0,0 +1,15 @@
+data_version=1.0.0
+# data_version should be in the first line.
+# No space is allowed.
+
+# this starts a description of a new risky url
+url=highrisky.test.com
+# LOW/MEDIUM/HIGH
+risk_level=HIGH
+
+url=mediumrisky.test.com
+risk_level=MEDIUM
+
+url=lowrisky.test.com
+risk_level=LOW
+
diff --git a/engine/web-protection/sample-engine.cpp b/engine/web-protection/sample-engine.cpp
new file mode 100644 (file)
index 0000000..ec35f71
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include "csre/web-protection.h"
+#include "csre/web-protection-engine-info.h"
+
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+
+#define API __attribute__((visibility("default")))
+
+#define PRIVATE_DB_NAME   "csret_wp_risky_urls"
+#define PRIVATE_LOGO_FILE "vendor_logo.bmp"
+#define MAX_FILE_PATH_LEN 256
+#define MAX_NAME_LEN      64
+#define MAX_VERSION_LEN   32
+#define MAX_URL_LEN       256
+
+#define VENDOR_NAME       "TEST_VENDOR"
+#define ENGINE_NAME       "TEST_LOCAL_TWP_ENGINE"
+#define ENGINE_VERSION    "0.0.1"
+
+typedef struct __csret_wp_risky_url {
+       char url[MAX_URL_LEN];
+       csre_wp_risk_level_e risk_level;
+} csret_wp_risky_url_s;
+
+typedef struct __csret_wp_risky_url_list {
+       struct __csret_wp_risky_url_list   *next;
+       csret_wp_risky_url_s               *risky_url;
+} csret_wp_risky_url_list_s;
+
+typedef struct __csret_wp_context {
+       csret_wp_risky_url_list_s *detected_list;
+} csret_wp_context_s;
+
+typedef struct __csret_wp_engine {
+       char           vendor_name[MAX_NAME_LEN];
+       char           engine_name[MAX_NAME_LEN];
+       unsigned char *vendor_logo_image;
+       unsigned int   image_size;
+       char           engine_version[MAX_VERSION_LEN];
+       char           data_version[MAX_VERSION_LEN];
+} csret_wp_engine_s;
+
+typedef enum __csret_wp_internal_error {
+       CSRET_WP_ERROR_NO_RISKY_URL_FILE    = -0x0101,
+       CSRET_WP_ERROR_FILE_IO              = -0x0103
+} csret_wp_internal_error_e;
+
+//==============================================================================
+// static variables
+//==============================================================================
+static csret_wp_engine_s         *engine_info = nullptr;
+static csret_wp_risky_url_list_s *risky_urls  = nullptr;
+
+//==============================================================================
+// Utilities functions
+//==============================================================================
+char *csret_wp_extract_value(char *line, const char *key)
+{
+       if (line == nullptr || key == nullptr)
+               return nullptr;
+
+       auto found = strstr(line, key);
+       if (found == nullptr)
+               return nullptr;
+
+       auto value = found + strlen(key);
+
+       // remove end line char
+       for (auto current = found; current && *current; current++) {
+               if (*current == '\n') {
+                       *current = '\0';
+                       break;
+               }
+       }
+
+       return value;
+}
+
+int csret_wp_read_risky_urls(const char *path)
+{
+       // csret_wp_risky_urls file format
+       // data_version=1.0.0 // it should be in the first line.
+       // # this line is a comment.
+       //
+       // url=highrisky.test.com // this starts a description of a new risky url
+       // risk_level=HIGH  // LOW/MEDIUM/HIGH
+       //
+       // url=midiumrisky.test.com
+       // risk_level=MEDIUM
+       FILE *fp;
+       char *line = nullptr;
+       size_t len = 0;
+       ssize_t read;
+       char *value;
+       csret_wp_risky_url_list_s *curr_url = nullptr;
+       csret_wp_risky_url_list_s *next_url = nullptr;
+       fp = fopen(path, "r");
+
+       if (fp == nullptr)
+               return CSRET_WP_ERROR_NO_RISKY_URL_FILE;
+
+       while ((read = getline(&line, &len, fp)) != -1) {
+               if (line == nullptr || strlen(line) == 0)
+                       continue;
+
+               value = csret_wp_extract_value(line, "data_version=");
+
+               if (value != nullptr && engine_info != nullptr)
+                       snprintf(engine_info->data_version, MAX_VERSION_LEN, "%s", value);
+
+               value = csret_wp_extract_value(line, "url=");
+
+               if (value != nullptr) {
+                       next_url = (csret_wp_risky_url_list_s *) calloc(sizeof(csret_wp_risky_url_list_s), 1);
+                       next_url->risky_url = (csret_wp_risky_url_s *) calloc(sizeof(csret_wp_risky_url_s), 1);
+
+                       if (curr_url != nullptr) curr_url->next = next_url;
+                       else                 risky_urls = next_url;
+
+                       curr_url = next_url;
+                       snprintf(curr_url->risky_url->url, MAX_URL_LEN, "%s", value);
+               }
+
+               value = csret_wp_extract_value(line, "risk_level=");
+
+               if (value != nullptr) {
+                       if (strcmp(value, "LOW") == 0)
+                               curr_url->risky_url->risk_level = CSRE_WP_RISK_LOW;
+                       else if (strcmp(value, "MEDIUM") == 0)
+                               curr_url->risky_url->risk_level = CSRE_WP_RISK_MEDIUM;
+                       else if (strcmp(value, "HIGH") == 0)
+                               curr_url->risky_url->risk_level = CSRE_WP_RISK_HIGH;
+                       else
+                               curr_url->risky_url->risk_level = CSRE_WP_RISK_UNVERIFIED;
+               }
+       }
+
+       free(line);
+       fclose(fp);
+       return CSRE_ERROR_NONE;
+}
+
+
+int csret_wp_csret_wp_read_binary_by_file(FILE *file, unsigned char **data, unsigned int *len)
+{
+       unsigned char *buffer;
+       long int fileLen;
+       int read;
+       int index = 0;
+
+       if (!file)
+               return CSRET_WP_ERROR_FILE_IO;
+
+       //Get file length
+       fseek(file, 0, SEEK_END);
+       fileLen = ftell(file);
+
+       if (fileLen <= 0)
+               return CSRET_WP_ERROR_FILE_IO;
+
+       fseek(file, 0, SEEK_SET);
+       //Allocate memory
+       buffer = (unsigned char *)calloc(fileLen + 1, 1);
+
+       if (!buffer)
+               return CSRE_ERROR_OUT_OF_MEMORY;
+
+       //Read file contents into buffer
+       while ((read = fread(buffer + index, 1, fileLen, file)) > 0)
+               index += read;
+
+       fclose(file);
+
+       if (index != fileLen) {
+               free(buffer);
+               return CSRET_WP_ERROR_FILE_IO;
+       }
+
+       *data = buffer;
+       *len = fileLen;
+       return CSRE_ERROR_NONE;
+}
+
+int csret_wp_read_binary(const char *path, unsigned char **data, unsigned int *len)
+{
+       FILE *file = fopen(path, "rb");
+       return csret_wp_csret_wp_read_binary_by_file(file, data, len);
+}
+
+
+int csret_wp_init_engine(const char *root_dir)
+{
+       int ret = CSRE_ERROR_NONE;
+       char logo_file_name[MAX_FILE_PATH_LEN] = {0, };
+       engine_info = (csret_wp_engine_s *) calloc(sizeof(csret_wp_engine_s), 1);
+
+       if (engine_info == nullptr)
+               return CSRE_ERROR_OUT_OF_MEMORY;
+
+       snprintf(engine_info->vendor_name, MAX_NAME_LEN, "%s", VENDOR_NAME);
+       snprintf(engine_info->engine_name, MAX_NAME_LEN, "%s", ENGINE_NAME);
+       snprintf(engine_info->engine_version, MAX_VERSION_LEN, "%s", ENGINE_VERSION);
+       snprintf(logo_file_name, MAX_FILE_PATH_LEN, "%s/%s", root_dir, PRIVATE_LOGO_FILE);
+       ret = csret_wp_read_binary(logo_file_name, &(engine_info->vendor_logo_image),
+                                                       &(engine_info->image_size));
+
+       if (ret == CSRET_WP_ERROR_FILE_IO) {
+               engine_info->vendor_logo_image = nullptr;
+               engine_info->image_size = 0;
+               ret = CSRE_ERROR_NONE;
+       }
+
+       return ret;
+}
+
+
+//==============================================================================
+// Main function related
+//==============================================================================
+API
+int csre_wp_context_create(const char *engine_root_dir, csre_wp_context_h *phandle)
+{
+       int ret = CSRE_ERROR_NONE;
+       char url_file[MAX_FILE_PATH_LEN] = {0, };
+
+       if (phandle == nullptr || engine_root_dir == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       csret_wp_context_s *context = (csret_wp_context_s *)calloc(sizeof(csret_wp_context_s), 1);
+
+       if (context == nullptr)
+               return CSRE_ERROR_OUT_OF_MEMORY;
+
+       if (engine_info == nullptr) {
+               ret = csret_wp_init_engine(engine_root_dir);
+
+               if (ret != CSRE_ERROR_NONE)
+                       return ret;
+       }
+
+       if (risky_urls == nullptr) {
+               snprintf(url_file, MAX_FILE_PATH_LEN, "%s/%s", engine_root_dir, PRIVATE_DB_NAME);
+               ret = csret_wp_read_risky_urls(url_file);
+
+               if (ret != CSRE_ERROR_NONE && ret != CSRET_WP_ERROR_NO_RISKY_URL_FILE)
+                       return ret;
+       }
+
+       *phandle = (csre_wp_context_h) context;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_wp_context_destroy(csre_wp_context_h handle)
+{
+       if (handle == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       csret_wp_context_s *context = (csret_wp_context_s *)handle;
+       csret_wp_risky_url_list_s *curr = nullptr;
+       csret_wp_risky_url_list_s *prev = nullptr;
+       curr = context->detected_list;
+
+       while (curr != nullptr) {
+               if (curr->risky_url != nullptr)
+                       free(curr->risky_url);
+
+               prev = curr;
+               curr = curr->next;
+               free(prev);
+       }
+
+       free(context);
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_wp_check_url(csre_wp_context_h handle, const char *url, csre_wp_check_result_h *presult)
+{
+       int ret = CSRE_ERROR_NONE;
+       char *risky_url = nullptr;
+       csret_wp_risky_url_s *detected = nullptr;
+
+       if (handle == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (url == nullptr || presult == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       if (risky_urls == nullptr)
+               return CSRE_ERROR_ENGINE_NOT_ACTIVATED;
+
+       csret_wp_context_s *context = (csret_wp_context_s *)handle;
+       // create new detected
+       detected = (csret_wp_risky_url_s *)calloc(sizeof(csret_wp_risky_url_s), 1);
+
+       if (detected == nullptr)
+               return CSRE_ERROR_OUT_OF_MEMORY;
+
+       snprintf(detected->url, MAX_URL_LEN, "%s", url);
+       // set detected into context
+       csret_wp_risky_url_list_s *last = (csret_wp_risky_url_list_s *) calloc(sizeof(csret_wp_risky_url_list_s), 1);
+
+       if (last == nullptr) {
+               free(detected);
+               return CSRE_ERROR_OUT_OF_MEMORY;
+       }
+
+       last->risky_url = detected;
+       csret_wp_risky_url_list_s *curr = context->detected_list;
+
+       while (curr != nullptr && curr->next != nullptr) curr = curr->next; // move to the last
+
+       curr = last;
+       // check url
+       csret_wp_risky_url_list_s *curr_url = risky_urls;
+
+       while (curr_url != nullptr) {
+               risky_url = curr_url->risky_url->url;
+
+               if (strstr(url, risky_url) != nullptr) { // found
+                       detected->risk_level = curr_url->risky_url->risk_level;
+                       break; // return the first risky url info in test engine
+               }
+
+               curr_url = curr_url->next;
+       }
+
+       if (detected->risk_level == 0)
+               detected->risk_level = CSRE_WP_RISK_UNVERIFIED;
+
+       *presult = (csre_wp_check_result_h) detected;
+       return ret;
+}
+
+
+//==============================================================================
+// Result related
+//==============================================================================
+API
+int csre_wp_result_get_risk_level(csre_wp_check_result_h result, csre_wp_risk_level_e *plevel)
+{
+       csret_wp_risky_url_s *detected = nullptr;
+
+       if (result == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (plevel == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       detected = (csret_wp_risky_url_s *) result;
+       *plevel = detected->risk_level;
+       return CSRE_ERROR_NONE;
+}
+
+//==============================================================================
+// Engine information related
+//==============================================================================
+API
+int csre_wp_engine_get_info(csre_wp_engine_h *pengine)
+{
+       if (pengine == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *pengine = (csre_wp_engine_h)engine_info;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_wp_engine_get_vendor(csre_wp_engine_h engine, const char **vendor)
+{
+       csret_wp_engine_s *eng = (csret_wp_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (vendor == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *vendor = eng->vendor_name;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_wp_engine_get_name(csre_wp_engine_h engine, const char **name)
+{
+       csret_wp_engine_s *eng = (csret_wp_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (name == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *name = eng->engine_name;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_wp_engine_get_vendor_logo(csre_wp_engine_h engine, unsigned char **vendor_logo_image,
+                                                                  unsigned int *image_size)
+{
+       csret_wp_engine_s *eng = (csret_wp_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (vendor_logo_image == nullptr || image_size == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *vendor_logo_image = eng->vendor_logo_image;
+       *image_size = eng->image_size;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_wp_engine_get_version(csre_wp_engine_h engine, const char **version)
+{
+       csret_wp_engine_s *eng = (csret_wp_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (version == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *version = eng->engine_version;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_wp_engine_get_data_version(csre_wp_engine_h engine, const char **version)
+{
+       csret_wp_engine_s *eng = (csret_wp_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (version == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *version = eng->data_version;
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_wp_engine_get_activated(csre_wp_engine_h engine, csre_wp_activated_e *pactivated)
+{
+       csret_wp_engine_s *eng = (csret_wp_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (pactivated == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       if (risky_urls == nullptr)
+               *pactivated = CSRE_WP_NOT_ACTIVATED;
+       else
+               *pactivated = CSRE_WP_ACTIVATED;
+
+       return CSRE_ERROR_NONE;
+}
+
+API
+int csre_wp_engine_get_api_version(csre_wp_engine_h engine, const char **version)
+{
+       csret_wp_engine_s *eng = (csret_wp_engine_s *) engine;
+
+       if (eng == nullptr)
+               return CSRE_ERROR_INVALID_HANDLE;
+
+       if (version == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       *version = CSRE_WP_API_VERSION;
+       return CSRE_ERROR_NONE;
+}
+
+//==============================================================================
+// Error related
+//==============================================================================
+API
+int csre_wp_get_error_string(int error_code, const char **string)
+{
+       if (string == nullptr)
+               return CSRE_ERROR_INVALID_PARAMETER;
+
+       switch (error_code) {
+       case CSRET_WP_ERROR_NO_RISKY_URL_FILE:
+               *string = "CSRET_WP_ERROR_NO_RISKY_URL_FILE";
+               break;
+
+       case CSRET_WP_ERROR_FILE_IO:
+               *string = "CSRET_WP_ERROR_FILE_IO";
+               break;
+
+       default:
+               *string = "UNDEFINED ERROR CODE";
+               break;
+       }
+
+       return CSRE_ERROR_NONE;
+}
index 27887cb..96b06d8 100644 (file)
@@ -16,10 +16,13 @@ Requires:      lib%{name}-common = %{version}-%{release}
 General purpose content screening and reputation solution. Can scan
 file contents and checking url to prevent malicious items.
 
-%global service_name csr
-%global bin_dir      %{_bindir}
-%global sbin_dir     /sbin
-%global ro_data_dir  %{_datadir}
+%global service_name              csr
+%global bin_dir                   %{_bindir}
+%global sbin_dir                  /sbin
+%global ro_data_dir               %{_datadir}
+%global sample_engine_working_dir /opt/share/%{service_name}/engine
+%global sample_engine_dir         %{_libdir}
+%global test_dir                  /opt/share/%{service_name}-test
 
 %package -n lib%{name}-common
 Summary: Common library package for %{name}
@@ -75,7 +78,10 @@ test program of csr-framework
     -DVERSION=%{version} \
     -DINCLUDE_INSTALL_DIR:PATH=%{_includedir} \
     -DBIN_DIR:PATH=%{bin_dir} \
-    -DSYSTEMD_UNIT_DIR=%{_unitdir}
+    -DSYSTEMD_UNIT_DIR=%{_unitdir} \
+    -DSAMPLE_ENGINE_WORKING_DIR:PATH=%{sample_engine_working_dir} \
+    -DSAMPLE_ENGINE_DIR:PATH=%{sample_engine_dir} \
+    -DTEST_DIR:PATH=%{test_dir}
 
 make %{?jobs:-j%jobs}
 
@@ -133,6 +139,11 @@ fi
 %{_unitdir}/sockets.target.wants/%{service_name}.socket
 %{_unitdir}/%{service_name}.socket
 
+# sample engine related files
+%{sample_engine_dir}/lib%{service_name}-cs-engine.so
+%{sample_engine_dir}/lib%{service_name}-wp-engine.so
+%{sample_engine_working_dir}
+
 %files -n lib%{name}-common
 %defattr(-,root,root,-)
 %manifest %{service_name}-common.manifest
@@ -159,6 +170,9 @@ fi
 
 %files test
 %defattr(-,root,root,-)
+%manifest %{service_name}-test.manifest
 %{ro_data_dir}/license/%{name}-test
 %{ro_data_dir}/license/%{name}-test.BSL-1.0
 %{bin_dir}/%{service_name}-test
+# test resources
+%{test_dir}
diff --git a/packaging/csr-test.manifest.in b/packaging/csr-test.manifest.in
new file mode 100644 (file)
index 0000000..7aa1942
--- /dev/null
@@ -0,0 +1,17 @@
+<manifest>
+       <define>
+               <domain name="@SERVICE_NAME@-test" />
+               <request>
+                       <smack request="device::sys_logging" type="rw" />
+                       <smack request="device::app_logging" type="rw" />
+                       <smack request="sys-assert::core" type="rwxat" />
+                       <smack request="systemd" type="rx" />
+                       <smack request="csr" type="rwxat" />
+               </request>
+               <permit>
+               </permit>
+       </define>
+       <request>
+               <domain name="@SERVICE_NAME@-test" />
+       </request>
+</manifest>
index 0332cb9..803b7ca 100644 (file)
@@ -79,12 +79,16 @@ std::pair<CommandId, MessageBuffer> Logic::getRequestInfo(const RawBuffer &data)
 
 RawBuffer Logic::scanFile(const std::string &filepath)
 {
+       (void) filepath;
+
        DEBUG("Scan file[" << filepath << "] by engine");
        return MessageBuffer::Serialize(CSR_ERROR_NONE).pop();
 }
 
 RawBuffer Logic::checkUrl(const std::string &url)
 {
+       (void) url;
+
        DEBUG("CHeck url[" << url << "] by engine");
        return MessageBuffer::Serialize(CSR_ERROR_NONE).pop();
 }
index 94d13e0..4099dd8 100644 (file)
@@ -61,8 +61,6 @@ typedef enum {
  * @retval #CSR_ERROR_ENGINE_NOT_ACTIVATED Engine is not activated
  * @retval #CSR_ERROR_ENGINE_INTERNAL      Engine Internal error
  * @retval #CSR_ERROR_UNKNOWN              Error with unknown reason
- *
- * @see csr_context_create()
  */
 int csr_get_selected_engine(csr_engine_id_e id, csr_engine_h *engine);
 
@@ -80,7 +78,7 @@ int csr_get_selected_engine(csr_engine_id_e id, csr_engine_h *engine);
  * @retval #CSR_ERROR_ENGINE_INTERNAL      Engine Internal error
  * @retval #CSR_ERROR_UNKNOWN              Error with unknown reason
  *
- * @see csr_get_engine_info()
+ * @see csr_get_selected_engine()
  */
 int csr_engine_get_vendor(csr_engine_h engine, char **vendor);
 
@@ -98,7 +96,7 @@ int csr_engine_get_vendor(csr_engine_h engine, char **vendor);
  * @retval #CSR_ERROR_ENGINE_INTERNAL      Engine Internal error
  * @retval #CSR_ERROR_UNKNOWN              Error with unknown reason
  *
- * @see csr_get_engine_info()
+ * @see csr_get_selected_engine()
  */
 int csr_engine_get_name(csr_engine_h engine, char **name);
 
@@ -117,7 +115,7 @@ int csr_engine_get_name(csr_engine_h engine, char **name);
  * @retval #CSR_ERROR_ENGINE_INTERNAL      Engine Internal error
  * @retval #CSR_ERROR_UNKNOWN              Error with unknown reason
  *
- * @see csr_get_engine_info()
+ * @see csr_get_selected_engine()
  */
 int csr_engine_get_version(csr_engine_h engine, char **version);
 
@@ -136,7 +134,7 @@ int csr_engine_get_version(csr_engine_h engine, char **version);
  * @retval #CSR_ERROR_ENGINE_INTERNAL      Engine Internal error
  * @retval #CSR_ERROR_UNKNOWN              Error with unknown reason
  *
- * @see csr_get_engine_info()
+ * @see csr_get_selected_engine()
  */
 int csr_engine_get_data_version(csr_engine_h engine, char **version);
 
@@ -154,7 +152,7 @@ int csr_engine_get_data_version(csr_engine_h engine, char **version);
  * @retval #CSR_ERROR_ENGINE_INTERNAL      Engine Internal error
  * @retval #CSR_ERROR_UNKNOWN              Error with unknown reason
  *
- * @see csr_get_engine_info()
+ * @see csr_get_selected_engine()
  */
 int csr_engine_get_activated(csr_engine_h engine, csr_activated_e *pactivated);
 
diff --git a/src/include/csre/content-screening-engine-info.h b/src/include/csre/content-screening-engine-info.h
new file mode 100644 (file)
index 0000000..aa3bd7b
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file        content-screening-engine-info.h
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief       Interface for engine management on engine
+ */
+#ifndef __CSRE_CS_ENGINE_INFO_H_
+#define __CSRE_CS_ENGINE_INFO_H_
+
+#include "csre/error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct __csre_cs_engine_h *csre_cs_engine_h;
+
+/**
+ * @brief State of engine activation
+ */
+typedef enum {
+       CSRE_CS_NOT_ACTIVATED = 0x01,  /**< Engine is not activated */
+       CSRE_CS_ACTIVATED     = 0x02   /**< Engine is activated */
+} csre_cs_activated_e;
+
+/**
+ * @brief Gets the handle of a selected engine information.
+ *
+ * @param[in]  id       Engine identifier to get handle.
+ * @param[out] pengine  A pointer of the engine information handle.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    pengine is invalid
+ * @retval #CSRE_ERROR_ENGINE_NOT_SELECTED  No engine selected
+ * @retval #CSRE_ERROR_ENGINE_NOT_ACTIVATED Engine is not activated
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ */
+int csre_cs_engine_get_info(csre_cs_engine_h *engine);
+
+/**
+ * @brief returns the engine API version.
+ *
+ * @param[in]  engine   The engine information handle.
+ * @param[out] version  A pointer of the API version string. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    api_ver is invalid
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                  Engine defined error
+ *
+ * @see csre_cs_get_engine_info()
+ */
+int csre_cs_engine_get_api_version(csre_cs_engine_h engine, const char **version);
+
+/**
+ * @brief Extracts an vendor name from the engine information handle.
+ *
+ * @param[in]  engine  The engine information handle.
+ * @param[out] vendor  A pointer of the engine's vendor name. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    engine_vendor is invalid
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_cs_get_engine_info()
+ */
+int csre_cs_engine_get_vendor(csre_cs_engine_h engine, const char **vendor);
+
+/**
+ * @brief Extracts an engine name from the engine information handle.
+ *
+ * @param[in]  engine  The engine information handle.
+ * @param[out] name    A pointer of the engine's name. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    engine_name is invalid
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_cs_get_engine_info()
+ */
+int csre_cs_engine_get_name(csre_cs_engine_h engine, const char **name);
+
+/**
+ * @brief Extracts an engine version from the engine information handle.
+ *
+ * @param[in]  engine   An engine information handle.
+ * @param[out] version  A pointer of the engine's version. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    engine_version is invalid
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_cs_get_engine_info()
+ */
+int csre_cs_engine_get_version(csre_cs_engine_h engine, const char **version);
+
+/**
+ * @brief Extracts an engine's data version from the engine information handle.
+ *
+ * @param[in]  engine   The engine information handle.
+ * @param[out] version  A pointer of the data version. It can be null. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    engine_version is invalid
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_cs_get_engine_info()
+ */
+int csre_cs_engine_get_data_version(csre_cs_engine_h engine, const char **version);
+
+/**
+ * @brief Extracts the state of engine activation from the engine information handle.
+ *
+ * @param[in]  engine      The engine information handle.
+ * @param[out] pactivated  A pointer of the engine state.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    pactivated is invalid
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_cs_get_engine_info()
+ */
+int csre_cs_engine_get_activated(csre_cs_engine_h engine, csre_cs_activated_e *pactivated);
+
+/**
+ * @brief Extracts an vendor logo image from the engine information handle.
+ *
+ * @details If log image is provided, the vendor logo is shown in a popup. The format
+ *          of the logo image should be jpeg, gif, bmp or png.
+ *
+ * @param[in]  engine             The engine information handle.
+ * @param[out] vendor_logo_image  A pointer of the vendor logo image. A caller should not
+ *                                free it.
+ * @param[out] image_size         Size of log image.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    vendor_logo_imgage or image_size is invalid
+ * @retval #CSRE_ERROR_NO_DATA              No vendor logo image
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                  Engine defined error
+ *
+ * @see csre_cs_get_engine_info()
+ */
+int csre_cs_engine_get_vendor_logo(csre_cs_engine_h engine, unsigned char** vendor_logo_image, unsigned int* image_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/csre/content-screening-types.h b/src/include/csre/content-screening-types.h
new file mode 100644 (file)
index 0000000..cde14af
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file        content-screening-types.h
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief       Types for content-screening engine
+ */
+#ifndef __CSRE_CONTENT_SCREENING_TYPES_H_
+#define __CSRE_CONTENT_SCREENING_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Content screening engine API version.
+ */
+#define CSRE_CS_API_VERSION "1.0"
+
+/**
+ * CSR CS engine's context handle.
+ */
+typedef struct csre_cs_context_s* csre_cs_context_h;
+
+/**
+ * CSR CS engine's detected malware info handle.
+ */
+typedef struct csre_cs_detected_s* csre_cs_detected_h;
+
+/**
+ * @brief Severity level of an detected malware
+ */
+typedef enum {
+       CSRE_CS_SEVERITY_LOW    = 0x01,  /**< Low Severity. Process with a warning log. */
+       CSRE_CS_SEVERITY_MEDIUM = 0x02,  /**< Medium Severity. Prompt the user before processing. Ask the user if the user wants the application to process the data. */
+       CSRE_CS_SEVERITY_HIGH   = 0x03   /**< High Severity. Do not process the data and prompt user for removal. */
+} csre_cs_severity_level_e;
+
+/**
+ * @brief the type of a threat detected
+ */
+typedef enum {
+       CSRE_CS_THREAT_MALWARE = 0x00,  /**< Malware. */
+       CSRE_CS_THREAT_RISKY   = 0x01,  /**< It's not a malware but still risky. */
+       CSRE_CS_THREAT_GENERIC = 0x02   /**< Generic threat */
+} csre_cs_threat_type_e;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/csre/content-screening.h b/src/include/csre/content-screening.h
new file mode 100644 (file)
index 0000000..7b17f0b
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file        content-screening.h
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief       Interface for content-screening engine
+ */
+#ifndef __CSRE_CONTENT_SCREENING_API_H_
+#define __CSRE_CONTENT_SCREENING_API_H_
+
+#include "csre/content-screening-types.h"
+#include "csre/error.h"
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//==============================================================================
+// Main function related
+//==============================================================================
+/**
+ * @brief Initializes and returns a Tizen Malware Screening engine API handle.
+ *
+ * @details A Malware Screening engine interface handle (or CSR CS engine handle) is
+ *          obtained using the csre_cs_context_create() function. The engine handle is
+ *          required for subsequent CSR CS engine API calls. The csre_cs_context_destroy()
+ *          function releases/closes the engine handle. Multiple handles can be obtained
+ *          using csre_cs_context_create().
+ *
+ * @param[in]  engine_root_dir  A root directory where an engine exists. It is a absolute
+ *                              path and it doesn't end with '/'.
+ * @param[out] phandle          A pointer of CSR CS Engine context handle.
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE               Successful
+ * @retval #CSRE_CS_ERROR_INVALID_PARAMETER  phandle is invalid
+ * @retval #CSRE_CS_ERROR_OUT_OF_MEMORY      Not enough memory
+ * @retval #CSRE_CS_ERROR_UNKNOWN            Error with unknown reason
+ * @retval -0x0100~-0xFF00                   Engine defined error
+ *
+ * @see csre_cs_context_destroy()
+ */
+int csre_cs_context_create(const char *engine_root_dir, csre_cs_context_h* phandle);
+
+/**
+ * @brief Releases all system resources associated with a Tizen Malware Screening engine
+ *        API handle.
+ *
+ * @details The handle is one returned by the csre_cs_context_create() function.
+ *
+ * @param[in] handle CSR CS Engine context handle returned by csre_cs_context_create().
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE             Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE   Invalid handle
+ * @retval #CSRE_CS_ERROR_UNKNOWN          Error with unknown reason
+ * @retval -0x0100~-0xFF00                 Engine defined error
+ *
+ * @see csre_cs_context_create()
+ */
+int csre_cs_context_destroy(csre_cs_context_h handle);
+
+/**
+ * @brief Sets a database which is used in scanning.
+ *
+ * @details If a database is not set or an engine does not support "scanning on cloud",
+ *          the scanning will be done in a local device.
+ *
+ * @param[in] handle    CSR CS context handle returned by csre_cs_context_create().
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE                  Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE        Invalid handle
+ * @retval #CSRE_CS_ERROR_UNKNOWN               Error with unknown reason
+ */
+int csre_cs_set_scan_on_cloud(csre_cs_context_h handle);
+
+/**
+ * @brief Main function for caller to scan a data buffer for malware.
+ *
+ * @param[in]  handle     CSR CS Engine context handle returned by
+ *                        csre_cs_context_create().
+ * @param[in]  data       A scan target data.
+ * @param[in]  length     A size of a scan target data.
+ * @param[out] pdetected  A pointer of the detected malware handle. It can be null when
+ *                        no malware detected.
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE                 Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE       Invalid handle
+ * @retval #CSRE_CS_ERROR_OUT_OF_MEMORY        Not enough memory
+ * @retval #CSRE_CS_ERROR_INVALID_PARAMETER    data or presult is invalid
+ * @retval #CSRE_CS_ERROR_ENGINE_NOT_ACTIVATED Engine is not activated
+ * @retval #CSRE_CS_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                     Engine defined error
+ *
+ * @see csre_cs_context_create()
+ * @see csre_cs_scan_file()
+ * @see csre_cs_scan_file_by_fd()
+ */
+int csre_cs_scan_data(csre_cs_context_h handle,
+                    const unsigned char *data,
+                    size_t length,
+                    csre_cs_detected_h *pdetected);
+
+/**
+ * @brief Main function for caller to scan a file specified by file path for malware.
+ *
+ * @param[in]  handle     CSR CS Engine context handle returned by
+ *                        csre_cs_context_create().
+ * @param[in]  file_path  A path of scan target file.
+ * @param[out] pdetected  A pointer of the detected malware handle. It can be null when
+ *                        no malware detected.
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE                 Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE       Invalid handle
+ * @retval #CSRE_CS_ERROR_OUT_OF_MEMORY        Not enough memory
+ * @retval #CSRE_CS_ERROR_INVALID_PARAMETER    file_path or presult is invalid
+ * @retval #CSRE_CS_ERROR_ENGINE_NOT_ACTIVATED Engine is not activated
+ * @retval #CSRE_CS_ERROR_PERMISSION_DENIED    Access denied
+ * @retval #CSRE_CS_ERROR_FILE_NOT_FOUND       File not found
+ * @retval #CSRE_CS_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                     Engine defined error
+ *
+ * @see csre_cs_context_create()
+ * @see csre_cs_scan_data()
+ * @see csre_cs_scan_file_by_fd()
+ */
+int csre_cs_scan_file(csre_cs_context_h handle,
+                  const char *file_path,
+                  csre_cs_detected_h *pdetected);
+
+/**
+ * @brief Main function for caller to scan a file specified by file descriptor for malware.
+ *
+ * @details  The file is opened in readonly by another processe and its file descriptor
+ *           is delivered to the engine. This is useful in case of an insufficient
+ *           permission of a server process with scanning function. The client with
+ *           permission to a file opens the file and deliver its descriptor to a server
+ *           with an insufficient permission.
+ *
+ * @param[in]  handle           CSR CS Engine context handle returned by
+ *                              csre_cs_context_create().
+ * @param[in]  file_descriptor  A file descriptor of scan target file.
+ * @param[out] pdetected        A pointer of the detected malware handle. It can be null
+ *                              when no malware detected.
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE                 Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE       Invalid handle
+ * @retval #CSRE_CS_ERROR_OUT_OF_MEMORY        Not enough memory
+ * @retval #CSRE_CS_ERROR_INVALID_PARAMETER    presult is invalid
+ * @retval #CSRE_CS_ERROR_ENGINE_NOT_ACTIVATED Engine is not activated
+ * @retval #CSRE_CS_ERROR_PERMISSION_DENIED    Access denied
+ * @retval #CSRE_CS_ERROR_FILE_NOT_FOUND       File not found
+ * @retval #CSRE_CS_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                     Engine defined error
+ *
+ * @see csre_cs_context_create()
+ * @see csre_cs_scan_data()
+ * @see csre_cs_scan_file()
+ */
+int csre_cs_scan_file_by_fd(csre_cs_context_h handle,
+                  int file_descriptor,
+                  csre_cs_detected_h *pdetected);
+
+//==============================================================================
+// Result related
+//==============================================================================
+
+/**
+ * @brief Extracts the severity of a detected malware from the detected malware handle.
+ *
+ * @param[in]  detected    A detected malware handle.
+ * @param[out] pseverity  A pointer of the severity of a detected malware.
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE                 Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE       Invalid detected malware handle
+ * @retval #CSRE_CS_ERROR_INVALID_PARAMETER    pseverity is invalid.
+ * @retval #CSRE_CS_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                     Engine defined error
+ *
+ * @see csre_cs_result_get_detected_by_idx()
+ * @see csre_cs_result_get_detected_most_severe()
+ */
+int csre_cs_detected_get_severity(csre_cs_detected_h detected, csre_cs_severity_level_e* pseverity);
+
+
+/**
+ * @brief Extracts the threat type of a detected malware from the detected malware handle.
+ *
+ * @param[in]  detected      A detected malware handle.
+ * @param[out] pthreat_type  A pointer of the threat type of a detected malware.
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE                 Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE       Invalid detected malware handle
+ * @retval #CSRE_CS_ERROR_INVALID_PARAMETER    pharmful_type is invalid.
+ * @retval #CSRE_CS_ERROR_UNKNOWN              Error with unknown reason
+ */
+int csre_cs_detected_get_threat_type(csre_cs_detected_h detected, csre_cs_threat_type_e* pthreat_type);
+
+/**
+ * @brief Extracts the name of a detected malware from the detected malware handle.
+ *
+ * @param[in]  detected  A detected malware handle.
+ * @param[out] name      A pointer of the name of a detected malware. A caller should not
+ *                       free it.
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE                 Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE       Invalid detected malware handle
+ * @retval #CSRE_CS_ERROR_INVALID_PARAMETER    malware_name is invalid.
+ * @retval #CSRE_CS_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                     Engine defined error
+ *
+ * @see csre_cs_result_get_detected_by_idx()
+ * @see csre_cs_result_get_detected_most_severe()
+ */
+int csre_cs_detected_get_malware_name(csre_cs_detected_h detected, const char** name);
+
+/**
+ * @brief Extracts an url that contains detailed information on vendor's web site from the
+ *        detected malware handle.
+ *
+ * @param[in]  detected      A detected malware handle.
+ * @param[out] detailed_url  A pointer of an url that contains detailed information on
+ *                           vendor's web site. It can be null if a vendor doesn't provide
+ *                           this information. A caller should not free this string.
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE                 Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE       Invalid detected malware handle
+ * @retval #CSRE_CS_ERROR_INVALID_PARAMETER    malware_name is invalid.
+ * @retval #CSRE_CS_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                     Engine defined error
+ */
+int csre_cs_detected_get_detailed_url(csre_cs_detected_h detected, const char** detailed_url);
+
+/**
+ * @brief Extracts the time stamp when a malware is detected from the detected malware
+ *        handle.
+ *
+ * @param[in]  detected   A detected malware handle.
+ * @param[out] timestamp  A pointer of the time stamp in millisecond when a malware is
+ *                        detected. A caller should not free it.
+ *
+ * @return #CSRE_CS_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_CS_ERROR_NONE                 Successful
+ * @retval #CSRE_CS_ERROR_INVALID_HANDLE       Invalid detected malware handle
+ * @retval #CSRE_CS_ERROR_INVALID_PARAMETER    timestamp is invalid
+ * @retval #CSRE_CS_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                     Engine defined error
+ */
+int csre_cs_detected_get_timestamp(csre_cs_detected_h detected, long* timestamp);
+
+/**
+ * @brief Get the error string for a given engine-defined error code.
+ *
+ * @details The error strings are managed by the engine, therefore a caller should not
+ *          free it.
+ *
+ * @param[in]  error_code  an error code including an engine-defined error.
+ * @param[out] string      A pointer of the error string.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    error_code or error_string is invalid
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                  Engine defined error
+ */
+int csre_cs_get_error_string(int error_code, const char** string);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/csre/error.h b/src/include/csre/error.h
new file mode 100644 (file)
index 0000000..4f0bd4c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file        error.h
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef __CSRE_ERROR_H_
+#define __CSRE_ERROR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Enumeration for CSR CS Engine Errors.
+ */
+typedef enum {
+       CSRE_ERROR_NONE                  =  0x00,  /**< Successful */
+       CSRE_ERROR_INVALID_PARAMETER     = -0x01,  /**< Invalid parameter */
+       CSRE_ERROR_OUT_OF_MEMORY         = -0x02,  /**< Out of memory */
+       CSRE_ERROR_INVALID_HANDLE        = -0x03,  /**< The given handle is invalid */
+       CSRE_ERROR_ENGINE_NOT_ACTIVATED  = -0x04,  /**< Engine is not activated*/
+       CSRE_ERROR_PERMISSION_DENIED     = -0x05,  /**< Access denied */
+       CSRE_ERROR_FILE_NOT_FOUND        = -0x06,  /**< File not found */
+       CSRE_ERROR_NO_DATA               = -0x07,  /**< Data not found */
+       CSRE_ERROR_UNKNOWN               = -0xFF,  /**< The error with unknown reason */
+       // -0x0100~-0xFF00 are reserved for engine defined errors.
+} csre_error_e;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/csre/web-protection-engine-info.h b/src/include/csre/web-protection-engine-info.h
new file mode 100644 (file)
index 0000000..cade082
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file        web-protection-engine-info.h
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief       Interface for engine management on engine
+ */
+#ifndef __CSRE_WEB_PROTECTION_ENGINE_INFO_H_
+#define __CSRE_WEB_PROTECTION_ENGINE_INFO_H_
+
+#include "csre/error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct csre_wp_engine_s *csre_wp_engine_h;
+
+/**
+ * @brief State of engine activation
+ */
+typedef enum {
+       CSRE_WP_NOT_ACTIVATED = 0x01,  /**< Engine is not activated */
+       CSRE_WP_ACTIVATED     = 0x02   /**< Engine is activated */
+} csre_wp_activated_e;
+
+/**
+ * @brief Gets the handle of a selected engine information.
+ *
+ * @param[in]  id       Engine identifier to get handle.
+ * @param[out] pengine  A pointer of the engine information handle.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    pengine is invalid
+ * @retval #CSRE_ERROR_ENGINE_NOT_SELECTED  No engine selected
+ * @retval #CSRE_ERROR_ENGINE_NOT_ACTIVATED Engine is not activated
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ */
+int csre_wp_engine_get_info(csre_wp_engine_h *engine);
+
+/**
+ * @brief returns the engine API version.
+ *
+ * @param[in]  engine   The engine information handle.
+ * @param[out] version  A pointer of the API version string. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    api_ver is invalid
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                  Engine defined error
+ *
+ * @see csre_wp_engine_get_info()
+ */
+int csre_wp_engine_get_api_version(csre_wp_engine_h engine, const char **version);
+
+/**
+ * @brief Extracts an vendor name from the engine information handle.
+ *
+ * @param[in]  engine  The engine information handle.
+ * @param[out] vendor  A pointer of the engine's vendor name. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    engine_vendor is invalid
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_wp_engine_get_info()
+ */
+int csre_wp_engine_get_vendor(csre_wp_engine_h engine, const char **vendor);
+
+/**
+ * @brief Extracts an engine name from the engine information handle.
+ *
+ * @param[in]  engine  The engine information handle.
+ * @param[out] name    A pointer of the engine's name. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    engine_name is invalid
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_wp_engine_get_info()
+ */
+int csre_wp_engine_get_name(csre_wp_engine_h engine, const char **name);
+
+/**
+ * @brief Extracts an engine version from the engine information handle.
+ *
+ * @param[in]  engine   An engine information handle.
+ * @param[out] version  A pointer of the engine's version. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    engine_version is invalid
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_wp_engine_get_info()
+ */
+int csre_wp_engine_get_version(csre_wp_engine_h engine, const char **version);
+
+/**
+ * @brief Extracts an engine's data version from the engine information handle.
+ *
+ * @param[in]  engine   The engine information handle.
+ * @param[out] version  A pointer of the data version. It can be null. A caller should not free it.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    engine_version is invalid
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_wp_engine_get_info()
+ */
+int csre_wp_engine_get_data_version(csre_wp_engine_h engine, const char **version);
+
+/**
+ * @brief Extracts the state of engine activation from the engine information handle.
+ *
+ * @param[in]  engine      The engine information handle.
+ * @param[out] pactivated  A pointer of the engine state.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    pactivated is invalid
+ * @retval #CSRE_ERROR_ENGINE_INTERNAL      Engine Internal error
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ *
+ * @see csre_wp_engine_get_info()
+ */
+int csre_wp_engine_get_activated(csre_wp_engine_h engine, csre_wp_activated_e *pactivated);
+
+/**
+ * @brief Extracts an vendor logo image from the engine information handle.
+ *
+ * @details If log image is provided, the vendor logo is shown in a popup. The format
+ *          of the logo image should be jpeg, gif, bmp or png.
+ *
+ * @param[in]  engine             The engine information handle.
+ * @param[out] vendor_logo_image  A pointer of the vendor logo image. A caller should not
+ *                                free it.
+ * @param[out] image_size         Size of log image.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid engine information handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    vendor_logo_imgage or image_size is invalid
+ * @retval #CSRE_ERROR_NO_DATA              No vendor logo image
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                  Engine defined error
+ *
+ * @see csre_wp_engine_get_info()
+ */
+int csre_wp_engine_get_vendor_logo(csre_wp_engine_h engine, unsigned char** vendor_logo_image, unsigned int* image_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/csre/web-protection-types.h b/src/include/csre/web-protection-types.h
new file mode 100644 (file)
index 0000000..bde52b7
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file        web-protection-types.h
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef __CSRE_WEB_PROTECTION_TYPES_H_
+#define __CSRE_WEB_PROTECTION_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief TWP(Tizen Web Screening) Engine API version.
+ */
+#define CSRE_WP_API_VERSION "1.0"
+
+/**
+ * TWP Engine context handle.
+ */
+typedef struct csre_wp_context_s* csre_wp_context_h;
+
+/**
+ * TWP Engine's check result handle.
+ */
+typedef struct csre_wp_check_result_s* csre_wp_check_result_h;
+
+/**
+ * @brief Risk level of a url
+ */
+typedef enum {
+       CSRE_WP_RISK_LOW        = 0x01,  /**< Risk Low. */
+       CSRE_WP_RISK_UNVERIFIED = 0x02,  /**< Risk Unverified. There is no information about the url.*/
+       CSRE_WP_RISK_MEDIUM     = 0x03,  /**< Risk Medium. Prompt the user before processing. Ask the user if they want the application to process the url. */
+       CSRE_WP_RISK_HIGH       = 0x04   /**< High Risk.Do not process the url and just notify the user */
+} csre_wp_risk_level_e;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/csre/web-protection.h b/src/include/csre/web-protection.h
new file mode 100644 (file)
index 0000000..e4cf560
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file        web-protection.h
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#ifndef __CSRE_WEB_PROTECTION_API_H_
+#define __CSRE_WEB_PROTECTION_API_H_
+
+#include "csre/web-protection-types.h"
+#include "csre/error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//==============================================================================
+// Main function related
+//==============================================================================
+/**
+ * @brief Initializes and returns a Tizen Web Screening engine API handle.
+ *
+ * @details A Web Screening engine interface handle (or CSR WP engine handle) is obtained
+ *          using the csre_wp_context_create() function. The engine handle is required
+ *          for subsequent CSR WP engine API calls. The csre_wp_context_destroy() function
+ *          releases/closes the engine handle. Multiple handles can be obtained using
+ *          csre_wp_context_create().
+ *
+ * @param[in]  engine_root_dir  A root directory where an engine exists. It is a absolute
+ *                              path and it doesn't end with '/'.
+ * @param[out] phandle          A pointer of CSR WP Engine context handle.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE               Successful
+ * @retval #CSRE_ERROR_INVALID_PARAMETER  phandle is invalid
+ * @retval #CSRE_ERROR_OUT_OF_MEMORY      Not enough memory
+ * @retval #CSRE_ERROR_UNKNOWN            Error with unknown reason
+ * @retval -0x0100~-0xFF00                Engine defined error
+ *
+ * @see csre_wp_context_destroy()
+ */
+int csre_wp_context_create(const char *engine_root_dir, csre_wp_context_h* phandle);
+
+/**
+ * @brief Releases all system resources associated with a CSR WP engine API handle.
+ *
+ * @details The handle is one returned by the csre_wp_context_create() function.
+ *
+ * @param[in] handle CSR WP Engine context handle returned by csre_wp_context_create().
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE             Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE   Invalid handle
+ * @retval #CSRE_ERROR_UNKNOWN          Error with unknown reason
+ * @retval -0x0100~-0xFF00              Engine defined error
+ *
+ * @see csre_wp_context_create()
+ */
+int csre_wp_context_destroy(csre_wp_context_h handle);
+
+/**
+ * @brief Main function for caller to check URL reputation against the engine vendor's
+ *        database.
+ *
+ * @details  Checks whether accessing the URL is risky or not and returns a result handle
+ *           with the Risk level for the URL. The system resources associated with the
+ *           result handle will be released when csre_wp_context_destroy is called.
+ *
+ * @param[in]  handle   CSR WP Engine context handle returned by csre_wp_context_create().
+ * @param[in]  url      URL to check.
+ * @param[out] presult  A pointer of the result handle with the Risk level for the URL.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid handle
+ * @retval #CSRE_ERROR_OUT_OF_MEMORY        Not enough memory
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    URL is invalid
+ * @retval #CSRE_ERROR_ENGINE_NOT_ACTIVATED Engine is not activated
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                  Engine defined error
+ *
+ * @see csre_wp_context_create()
+ */
+int csre_wp_check_url(csre_wp_context_h handle, const char *url, csre_wp_check_result_h *presult);
+
+/**
+ * @brief Extracts a risk level of the url from the result handle.
+ *
+ * @param[in]  result  A result handle returned by csre_wp_check_url().
+ * @param[out] plevel  A pointer of the risk level for the given URL.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_HANDLE       Invalid result handle
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    plevel is invalid
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                  Engine defined error
+ *
+ * @see csre_wp_check_url()
+ */
+int csre_wp_result_get_risk_level(csre_wp_check_result_h result, csre_wp_risk_level_e* plevel);
+
+/**
+ * @brief Get the error string for a given engine-defined error code.
+ *
+ * @details The error strings are managed by the engine, therefore a caller should not
+ *          free it.
+ *
+ * @param[in]  error_code  an error code including an engine-defined error.
+ * @param[out] string      A pointer of the error string.
+ *
+ * @return #CSRE_ERROR_NONE on success, otherwise a negative error value
+ *
+ * @retval #CSRE_ERROR_NONE                 Successful
+ * @retval #CSRE_ERROR_INVALID_PARAMETER    error_code or error_string is invalid
+ * @retval #CSRE_ERROR_UNKNOWN              Error with unknown reason
+ * @retval -0x0100~-0xFF00                  Engine defined error
+ */
+int csre_wp_get_error_string(int error_code, const char** string);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 00f4a82..fa338b9 100644 (file)
@@ -28,6 +28,8 @@ SET(${TARGET_CSR_TEST}_SRCS
        test-api-content-screening.cpp
        test-api-engine-manager.cpp
        test-api-web-protection.cpp
+       test-api-engine-content-screening.cpp
+       test-api-engine-web-protection.cpp
        test-main.cpp
 )
 
@@ -41,9 +43,12 @@ ADD_EXECUTABLE(${TARGET_CSR_TEST} ${${TARGET_CSR_TEST}_SRCS})
 
 TARGET_LINK_LIBRARIES(${TARGET_CSR_TEST}
        ${TARGET_CSR_CLIENT}
+       ${TARGET_CSR_CS_ENGINE_SAMPLE}
+       ${TARGET_CSR_WP_ENGINE_SAMPLE}
        ${${TARGET_CSR_TEST}_DEP_LIBRARIES}
        boost_unit_test_framework
        -ldl
 )
 
-INSTALL (TARGETS ${TARGET_CSR_TEST} DESTINATION ${BIN_DIR})
+INSTALL(TARGETS ${TARGET_CSR_TEST} DESTINATION ${BIN_DIR})
+INSTALL(DIRECTORY resources/ DESTINATION ${TEST_DIR})
diff --git a/test/resources/test_malware_file b/test/resources/test_malware_file
new file mode 100644 (file)
index 0000000..0591f12
--- /dev/null
@@ -0,0 +1 @@
+aabbccX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*112233
diff --git a/test/resources/test_normal_file b/test/resources/test_normal_file
new file mode 100644 (file)
index 0000000..33efc37
--- /dev/null
@@ -0,0 +1 @@
+abcd1234dfdfdf334dfdi8ffndsfdfdsfdasfagdfvdfdfafadfasdfsdfe
diff --git a/test/resources/test_risky_file b/test/resources/test_risky_file
new file mode 100644 (file)
index 0000000..c0808a1
--- /dev/null
@@ -0,0 +1 @@
+aabbccRISKY_MALWARE112233
diff --git a/test/test-api-engine-content-screening.cpp b/test/test-api-engine-content-screening.cpp
new file mode 100644 (file)
index 0000000..ad61b5e
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file        test-api-engine-content-screening.cpp
+ * @author      Kyungwook Tak (k.tak@samsung.com)
+ * @version     1.0
+ * @brief       CSR Content screening Engine API test
+ */
+#include <csre/content-screening.h>
+#include <csre/content-screening-engine-info.h>
+
+#include <cstring>
+#include <cstdio>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <boost/test/unit_test.hpp>
+
+#define CHECK_IS_NULL(ptr)     BOOST_REQUIRE(ptr == nullptr)
+#define CHECK_IS_NOT_NULL(ptr) BOOST_REQUIRE(ptr != nullptr)
+
+#define TEST_FILE_NORMAL   TEST_DIR "/test_normal_file"
+#define TEST_FILE_MALWARE  TEST_DIR "/test_malware_file"
+#define TEST_FILE_RISKY    TEST_DIR "/test_risky_file"
+
+namespace {
+
+inline void checkDetected(csre_cs_detected_h detected,
+               csre_cs_severity_level_e expected_severity,
+               csre_cs_threat_type_e expected_threat_type,
+               const char *expected_malware_name,
+               const char *expected_detailed_url,
+               long expected_timestamp)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       CHECK_IS_NOT_NULL(detected);
+
+       csre_cs_severity_level_e severity;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_detected_get_severity(detected, &severity));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       BOOST_REQUIRE_MESSAGE(severity == expected_severity,
+               "severity isn't expected value. "
+               "val: " << severity << " expected: " << expected_severity);
+
+       csre_cs_threat_type_e threat_type;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_detected_get_threat_type(detected, &threat_type));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       BOOST_REQUIRE_MESSAGE(threat_type == expected_threat_type,
+               "threat type isn't expected value. "
+               "val: " << threat_type << " expected: " << expected_threat_type);
+
+       const char *malware_name = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_detected_get_malware_name(detected, &malware_name));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+
+       if (expected_malware_name != nullptr) {
+               CHECK_IS_NOT_NULL(malware_name);
+               BOOST_REQUIRE_MESSAGE(
+                       (strlen(malware_name) == strlen(expected_malware_name) &&
+                               memcmp(malware_name, expected_malware_name, strlen(malware_name)) == 0),
+                       "malware_name isn't expected value. "
+                               "val: " << malware_name << " expected: " << expected_malware_name);
+       }
+
+       const char *detailed_url = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_detected_get_detailed_url(detected, &detailed_url));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+
+       if (expected_detailed_url != nullptr) {
+               CHECK_IS_NOT_NULL(detailed_url);
+               BOOST_REQUIRE_MESSAGE(
+                       (strlen(detailed_url) == strlen(expected_detailed_url) &&
+                               memcmp(detailed_url, expected_detailed_url, strlen(detailed_url)) == 0),
+                       "detailed_url isn't expected value. "
+                               "val: " << detailed_url << " expected: " << expected_detailed_url);
+
+       }
+
+       long timestamp;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_detected_get_timestamp(detected, &timestamp));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+
+       if (expected_timestamp != 0)
+               BOOST_REQUIRE_MESSAGE(timestamp == expected_timestamp,
+                       "timestamp isn't expected value. "
+                               "val: " << timestamp << " expected: " << expected_timestamp);
+}
+
+class ContextPtr {
+public:
+       ContextPtr() : m_context(nullptr) {}
+       ContextPtr(csre_cs_context_h context) : m_context(context) {}
+       virtual ~ContextPtr()
+       {
+               int ret = csre_cs_context_destroy(m_context);
+               BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       }
+
+       csre_cs_context_h get(void)
+       {
+               return m_context;
+       }
+
+private:
+       csre_cs_context_h m_context;
+};
+
+class ScopedFile {
+public:
+       explicit ScopedFile(const std::string &file)
+       {
+               int fd = open(file.c_str(), O_RDONLY);
+               BOOST_REQUIRE_MESSAGE(fd > 0,
+                       "Cannot open file: " << file << " with errno: " << errno);
+
+               m_fd = fd;
+       }
+
+       virtual ~ScopedFile()
+       {
+               close(m_fd);
+       }
+
+       int getFd(void)
+       {
+               return m_fd;
+       }
+
+private:
+       int m_fd;
+};
+
+using ScopedContext = std::unique_ptr<ContextPtr>;
+
+inline ScopedContext makeScopedContext(csre_cs_context_h context)
+{
+       return ScopedContext(new ContextPtr(context));
+}
+
+inline csre_cs_engine_h getEngineHandle(void)
+{
+       csre_cs_engine_h engine;
+       int ret = CSRE_ERROR_UNKNOWN;
+
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_engine_get_info(&engine));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(engine);
+
+       return engine;
+}
+
+inline ScopedContext getContextHandleWithDir(const char *dir)
+{
+       csre_cs_context_h context;
+       int ret = CSRE_ERROR_UNKNOWN;
+
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_context_create(dir, &context));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(context);
+
+       return makeScopedContext(context);
+}
+
+inline ScopedContext getContextHandle(void)
+{
+       return getContextHandleWithDir(SAMPLE_ENGINE_WORKING_DIR);
+}
+
+}
+
+BOOST_AUTO_TEST_SUITE(API_ENGINE_CONTENT_SCREENING)
+
+BOOST_AUTO_TEST_CASE(context_create_destroy)
+{
+       auto context = getContextHandle();
+       (void)context;
+}
+
+BOOST_AUTO_TEST_CASE(scan_data_clear)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       const char *data = "abcd1234dfdfdf334dfdi8ffndsfdfdsfdasfagdfvdfdfafadfasdfsdfe";
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_data(
+               context,
+               reinterpret_cast<const unsigned char *>(data),
+               strlen(data),
+               &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NULL(detected);
+}
+
+BOOST_AUTO_TEST_CASE(scan_data_high)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       const char *data =
+               "aabbccX5O!P%@AP[4\\PZX54(P^)7CC)7}$"
+               "EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*112233";
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_data(
+               context,
+               reinterpret_cast<const unsigned char *>(data),
+               strlen(data),
+               &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(detected);
+
+       checkDetected(detected,
+               CSRE_CS_SEVERITY_HIGH,
+               CSRE_CS_THREAT_MALWARE,
+               "test_malware",
+               "http://detailedinfo.malware.com",
+               0);
+}
+
+BOOST_AUTO_TEST_CASE(scan_data_medium)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       const char *data = "aabbccRISKY_MALWARE112233";
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_data(
+               context,
+               reinterpret_cast<const unsigned char *>(data),
+               strlen(data),
+               &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(detected);
+
+       checkDetected(detected,
+               CSRE_CS_SEVERITY_MEDIUM,
+               CSRE_CS_THREAT_RISKY,
+               "test_risk",
+               nullptr,
+               0);
+}
+
+BOOST_AUTO_TEST_CASE(scan_file_normal)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_file(context, TEST_FILE_NORMAL, &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NULL(detected);
+}
+
+BOOST_AUTO_TEST_CASE(scan_file_normal_on_cloud)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_set_scan_on_cloud(context));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_file(context, TEST_FILE_NORMAL, &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NULL(detected);
+}
+
+BOOST_AUTO_TEST_CASE(scan_file_malware)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_file(context, TEST_FILE_MALWARE, &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(detected);
+
+       checkDetected(detected,
+               CSRE_CS_SEVERITY_HIGH,
+               CSRE_CS_THREAT_MALWARE,
+               "test_malware",
+               "http://detailedinfo.malware.com",
+               0);
+}
+
+BOOST_AUTO_TEST_CASE(scan_file_risky)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_file(context, TEST_FILE_RISKY, &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(detected);
+
+       checkDetected(detected,
+               CSRE_CS_SEVERITY_MEDIUM,
+               CSRE_CS_THREAT_RISKY,
+               "test_risk",
+               nullptr,
+               0);
+}
+
+BOOST_AUTO_TEST_CASE(scan_file_by_fd_normal)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       ScopedFile f(TEST_FILE_NORMAL);
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_file_by_fd(context, f.getFd(), &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NULL(detected);
+}
+
+BOOST_AUTO_TEST_CASE(scan_file_by_fd_malware)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       ScopedFile f(TEST_FILE_MALWARE);
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_file_by_fd(context, f.getFd(), &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(detected);
+
+       checkDetected(detected,
+               CSRE_CS_SEVERITY_HIGH,
+               CSRE_CS_THREAT_MALWARE,
+               "test_malware",
+               "http://detailedinfo.malware.com",
+               0);
+}
+
+BOOST_AUTO_TEST_CASE(scan_file_by_fd_risky)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       ScopedFile f(TEST_FILE_RISKY);
+
+       csre_cs_detected_h detected;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_scan_file_by_fd(context, f.getFd(), &detected));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(detected);
+
+       checkDetected(detected,
+               CSRE_CS_SEVERITY_MEDIUM,
+               CSRE_CS_THREAT_RISKY,
+               "test_risk",
+               nullptr,
+               0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+BOOST_AUTO_TEST_SUITE(API_ENGINE_CONTENT_SCREENING_ERR_STRING)
+
+BOOST_AUTO_TEST_CASE(positive)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+
+       const char *string = nullptr;
+
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_get_error_string(ret, &string));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(string);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+BOOST_AUTO_TEST_SUITE(API_ENGINE_CONTENT_SCREENING_ENGINE_INFO)
+
+BOOST_AUTO_TEST_CASE(get_engine_info)
+{
+       auto handle = getEngineHandle();
+       (void)handle;
+}
+
+BOOST_AUTO_TEST_CASE(get_vendor)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       const char *vendor = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_engine_get_vendor(handle, &vendor));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+}
+
+BOOST_AUTO_TEST_CASE(get_vendor_logo)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       unsigned char *vendor_logo_image = nullptr;
+       unsigned int size = 0;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_engine_get_vendor_logo(handle, &vendor_logo_image, &size));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+}
+
+BOOST_AUTO_TEST_CASE(get_version)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       const char *version = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_engine_get_version(handle, &version));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(version);
+}
+
+BOOST_AUTO_TEST_CASE(get_data_version)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       const char *version = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_engine_get_data_version(handle, &version));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(version);
+}
+
+BOOST_AUTO_TEST_CASE(get_engine_activated)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       csre_cs_activated_e activated;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_engine_get_activated(handle, &activated));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+}
+
+BOOST_AUTO_TEST_CASE(get_api_version)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       const char *version = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_cs_engine_get_api_version(handle, &version));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       BOOST_REQUIRE(memcmp(version, CSRE_CS_API_VERSION, strlen(version)) == 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/test-api-engine-web-protection.cpp b/test/test-api-engine-web-protection.cpp
new file mode 100644 (file)
index 0000000..a5fcef7
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/*
+ * @file        test-api-engine-web-protection.cpp
+ * @author      Kyungwook Tak (k.tak@samsung.com)
+ * @version     1.0
+ * @brief       CSR Content screening Engine API test
+ */
+#include <csre/web-protection.h>
+#include <csre/web-protection-engine-info.h>
+
+#include <unordered_map>
+#include <string>
+
+#include <boost/test/unit_test.hpp>
+
+#define CHECK_IS_NULL(ptr)     BOOST_REQUIRE(ptr == nullptr)
+#define CHECK_IS_NOT_NULL(ptr) BOOST_REQUIRE(ptr != nullptr)
+
+namespace {
+
+struct Result {
+       csre_wp_risk_level_e risk_level;
+
+       Result(csre_wp_risk_level_e r) : risk_level(r) {}
+};
+
+std::unordered_map<std::string, Result> ExpectedResult = {
+       {"http://normal.test.com",      Result(CSRE_WP_RISK_UNVERIFIED)},
+       {"http://highrisky.test.com",   Result(CSRE_WP_RISK_HIGH)},
+       {"http://mediumrisky.test.com", Result(CSRE_WP_RISK_MEDIUM)},
+       {"http://lowrisky.test.com",    Result(CSRE_WP_RISK_LOW)}
+};
+
+inline void checkResult(csre_wp_check_result_h &result, const Result &expected)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       CHECK_IS_NOT_NULL(result);
+
+       csre_wp_risk_level_e risk_level;
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_result_get_risk_level(result, &risk_level));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       BOOST_REQUIRE_MESSAGE(risk_level == expected.risk_level,
+               "risk level isn't expected value. "
+                       "val: " << risk_level << " expected: " << expected.risk_level);
+}
+
+class ContextPtr {
+public:
+       ContextPtr() : m_context(nullptr) {}
+       ContextPtr(csre_wp_context_h context) : m_context(context) {}
+       virtual ~ContextPtr()
+       {
+               int ret = csre_wp_context_destroy(m_context);
+               BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       }
+
+       csre_wp_context_h get(void)
+       {
+               return m_context;
+       }
+
+private:
+       csre_wp_context_h m_context;
+};
+
+using ScopedContext = std::unique_ptr<ContextPtr>;
+
+inline ScopedContext makeScopedContext(csre_wp_context_h context)
+{
+       return ScopedContext(new ContextPtr(context));
+}
+
+inline csre_wp_engine_h getEngineHandle(void)
+{
+       csre_wp_engine_h engine;
+       int ret = CSRE_ERROR_UNKNOWN;
+
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_engine_get_info(&engine));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(engine);
+
+       return engine;
+}
+
+inline ScopedContext getContextHandleWithDir(const char *dir)
+{
+       csre_wp_context_h context;
+       int ret = CSRE_ERROR_UNKNOWN;
+
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_context_create(dir, &context));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(context);
+
+       return makeScopedContext(context);
+}
+
+inline ScopedContext getContextHandle(void)
+{
+       return getContextHandleWithDir(SAMPLE_ENGINE_WORKING_DIR);
+}
+
+}
+
+BOOST_AUTO_TEST_SUITE(API_ENGINE_WEB_PROTECTION)
+
+BOOST_AUTO_TEST_CASE(context_create_destroy)
+{
+       auto handle = getContextHandle();
+       (void)handle;
+}
+
+BOOST_AUTO_TEST_CASE(check_url)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto contextPtr = getContextHandle();
+       auto context = contextPtr->get();
+
+       for (const auto &pair : ExpectedResult) {
+               csre_wp_check_result_h result;
+               BOOST_REQUIRE_NO_THROW(ret = csre_wp_check_url(context, pair.first.c_str(), &result));
+
+               BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+               checkResult(result, pair.second);
+       }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+BOOST_AUTO_TEST_SUITE(API_ENGINE_WEB_PROTECTION_ERR_STRING)
+
+BOOST_AUTO_TEST_CASE(positive)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+
+       const char *string = nullptr;
+
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_get_error_string(ret, &string));
+
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(string);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+BOOST_AUTO_TEST_SUITE(API_ENGINE_WEB_PROTECTION_ENGINE_INFO)
+
+BOOST_AUTO_TEST_CASE(get_engine_info)
+{
+       auto handle = getEngineHandle();
+       (void)handle;
+}
+
+BOOST_AUTO_TEST_CASE(get_vendor)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       const char *vendor = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_engine_get_vendor(handle, &vendor));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+}
+
+BOOST_AUTO_TEST_CASE(get_vendor_logo)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       unsigned char *vendor_logo_image = nullptr;
+       unsigned int size = 0;
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_engine_get_vendor_logo(handle, &vendor_logo_image, &size));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+}
+
+BOOST_AUTO_TEST_CASE(get_version)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       const char *version = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_engine_get_version(handle, &version));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(version);
+}
+
+BOOST_AUTO_TEST_CASE(get_data_version)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       const char *version = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_engine_get_data_version(handle, &version));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       CHECK_IS_NOT_NULL(version);
+}
+
+BOOST_AUTO_TEST_CASE(get_engine_activated)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       csre_wp_activated_e activated;
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_engine_get_activated(handle, &activated));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+}
+
+BOOST_AUTO_TEST_CASE(get_api_version)
+{
+       int ret = CSRE_ERROR_UNKNOWN;
+       auto handle = getEngineHandle();
+
+       const char *version = nullptr;
+       BOOST_REQUIRE_NO_THROW(ret = csre_wp_engine_get_api_version(handle, &version));
+       BOOST_REQUIRE(ret == CSRE_ERROR_NONE);
+       BOOST_REQUIRE(memcmp(version, CSRE_WP_API_VERSION, strlen(version)) == 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()