--- /dev/null
+#
+# Copyright (c) 2013, McAfee, Inc.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this list
+# of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice, this
+# list of conditions and the following disclaimer in the documentation and/or other
+# materials provided with the distribution.
+#
+# Neither the name of McAfee, Inc. nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific prior
+# written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+Tizen Content Screening Framework
+=====================================
+Following steps to create Tizen content screening framework library:
+- cd framework (change your current folder to 'framework')
+- make distclean; make
+- The library can be found inside 'lib'
+
+Tizen Content Screening Test Suite
+=====================================
+Following steps to create test suite
+- cd test (change your current folder to 'test')
+- make distclean; make
+
+Tizen Web Protection Test Suite
+=====================================
+Following steps to create test suite
+- cd test (change your current folder to 'test')
+- make distclean; make -f WPMakefile
+
+Porting
+=====================================
+TCS_CC: use this environment variable to specify your cross compiler
+TCS_LD: use this environment variable to specify your cross linker
+TCS_AR: use this environment variable to specify your cross ar
+PORT: x86, arm
+CFLAGS: use this environment variable to specify your compiler specific compiling flags
+LD_FLAGS: use this environment variable to specify your linker specific linker flags or libraries
+
+Example for Tizen 2.0.18 Emulator:
+export PORT=x86
+export SDK_HOME=${HOME}/tizen-sdk
+export CFLAGS="-I$SDK_HOME/platforms/tizen2.0/rootstraps/tizen-emulator-2.0.cpp.partner/usr/include"
+export LD_FLAGS="-B $SDK_HOME/platforms/tizen2.0/rootstraps/tizen-emulator-2.0.cpp.partner/usr/lib -L$SDK_HOME/platforms/tizen2.0/rootstraps/tizen-emulator-2.0.cpp.partner/lib -L$SDK_HOME/platforms/tizen2.0/rootstraps/tizen-emulator-2.0.cpp.partner/usr/lib -lc-2.13 -lpthread-2.13 -lc_nonshared"
+export TCS_CC="$SDK_HOME/tools/i386-linux-gnueabi-gcc-4.5/bin/i386-linux-gnueabi-gcc"
+export TCS_LD="$SDK_HOME/tools/i386-linux-gnueabi-gcc-4.5/bin/i386-linux-gnueabi-gcc"
+export TCS_AR="$SDK_HOME/tools/i386-linux-gnueabi-gcc-4.5/bin/i386-linux-gnueabi-ar"
+
+
--- /dev/null
+#
+# Copyright (c) 2013, McAfee, Inc.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this list
+# of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice, this
+# list of conditions and the following disclaimer in the documentation and/or other
+# materials provided with the distribution.
+#
+# Neither the name of McAfee, Inc. nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific prior
+# written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+OUTDIR = lib
+TARGET = $(OUTDIR)/libsecfw.so
+SRCDIR = .
+INCLUDE = -I. $(TCS_INC) -I../plugin
+LD_FLAGS := $(LD_FLAGS) -ldl
+
+ifeq ($(TCS_CC), )
+ CC = gcc
+else
+ CC = $(TCS_CC)
+endif
+ifeq ($(TCS_LD), )
+ LD = ld
+else
+ LD = $(TCS_LD)
+endif
+ifeq ($(TCS_AR), )
+ AR = ar
+else
+ AR = $(TCS_AR)
+endif
+
+ifeq ($(TCS_CFG), release)
+ CFLAGS := -O3 -fPIC $(INCLUDE) -DUNIX $(CFLAGS)
+else
+ CFLAGS := -g -fPIC $(INCLUDE) -DUNIX -DDEBUG $(CFLAGS)
+endif
+
+CFLAGS := $(CFLAGS) $(PKCL_CFLAGS) $(TCS_CFLAGS)
+
+SOURCES = $(SRCDIR)/TCSImpl.c $(SRCDIR)/TWPImpl.c
+
+OBJECTS = $(OUTDIR)/TCSImpl.o $(OUTDIR)/TWPImpl.o
+
+MKDEP = mkdep -f .depend
+
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c
+ $(CC) $(CFLAGS) -o $(OUTDIR)/$*.o -c $(SRCDIR)/$*.c
+
+all: $(OUTDIR) .depend $(TARGET)
+
+.depend: $(SOURCES)
+ $(MKDEP) $(CFLAGS) $(SOURCES)
+
+$(TARGET): $(OBJECTS)
+ $(LD) -shared -Wl,-zdefs -o $(TARGET) $(OBJECTS) $(LD_FLAGS)
+
+# $(AR) -cr $(TARGET) $(OBJECTS)
+
+$(OUTDIR):
+ @mkdir $(OUTDIR)
+
+distclean: clean
+ @rm -f .depend
+ @rm -rf $(OUTDIR)
+
+clean:
+ @rm -f $(TARGET)
+ @rm -f $(OBJECTS) *~
+ @rm -f *.bb *.bbg *.da *.gcov
+
+-include .depend
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef TCSERRORCODES_H
+#define TCSERRORCODES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * \file TCSErrorCodes.h
+ * \brief TCS Error Code Header File
+ *
+ * This file provides the TCS error code definition.
+ */
+
+#define TCS_ERROR_MODULE_GENERIC 1 /* A generic error code. */
+
+#define TCS_ERROR_CANCELLED 1 /* Operations cancelled. */
+
+#define TCS_ERROR_DATA_ACCESS 2 /* Unable to access data. */
+
+#define TCS_ERROR_INVALID_PARAM 3 /* Invalid parameter. */
+
+#define TCS_ERROR_INSUFFICIENT_RES 4 /* Insufficient resource. */
+
+#define TCS_ERROR_INTERNAL 5 /* Unexpected internal error. */
+
+#define TCS_ERROR_INVALID_HANDLE 6 /* Invalid handle. */
+
+#define TCS_ERROR_NOT_IMPLEMENTED 7 /* Specified functionality is not implemented in the TCS plug-in. (e.g. repair) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TCSERRORCODES_H */
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <malloc.h>
+
+#include "TCSImpl.h"
+#include "TCSErrorCodes.h"
+
+
+#define TCS_CONSTRUCT_ERRCODE(m, e) (((m) << 24) | (e))
+
+#if defined(DEBUG)
+#define DEBUG_LOG(_fmt_, _param_...) { \
+ printf("[TCS] %s,%d: " _fmt_, __FILE__, __LINE__, ##_param_); \
+ }
+#else
+#define DEBUG_LOG(_fmt_, _param_...)
+#endif
+
+
+#define PLUGIN_PATH "/opt/usr/share/sec_plugin/libengine.so"
+
+
+typedef TCSLIB_HANDLE (*FuncLibraryOpen)(void);
+typedef int (*FuncLibraryClose)(TCSLIB_HANDLE hLib);
+typedef TCSErrorCode (*FuncGetLastError)(TCSLIB_HANDLE hLib);
+typedef int (*FuncScanData)(TCSLIB_HANDLE hLib, TCSScanParam *pParam, TCSScanResult *pResult);
+typedef int (*FuncScanFile)(TCSLIB_HANDLE hLib, char const *pszFileName, int iDataType,
+ int iAction, int iCompressFlag, TCSScanResult *pResult);
+
+
+typedef struct PluginContext_struct
+{
+ TCSLIB_HANDLE hLib;
+ void *pPlugin;
+ FuncLibraryOpen pfLibraryOpen;
+ FuncLibraryClose pfLibraryClose;
+ FuncGetLastError pfGetLastError;
+ FuncScanData pfScanData;
+ FuncScanFile pfScanFile;
+} PluginContext;
+
+
+static PluginContext *LoadPlugin(void);
+
+
+TCSLIB_HANDLE TCSLibraryOpen(void)
+{
+ PluginContext *pCtx = NULL;
+
+ DEBUG_LOG("%s", "tcs lib open\n");
+ pCtx = LoadPlugin();
+ if (pCtx != NULL)
+ {
+ if (pCtx->pfLibraryOpen == NULL)
+ {
+ free(pCtx);
+ return INVALID_TCSLIB_HANDLE;
+ }
+ DEBUG_LOG("%s", "call to TCSPLibraryOpen\n");
+ pCtx->hLib = (*pCtx->pfLibraryOpen)();
+ if (pCtx->hLib == INVALID_TCSLIB_HANDLE)
+ {
+ DEBUG_LOG("%s", "failed to open engine\n");
+ if (pCtx->pPlugin != NULL)
+ dlclose(pCtx->pPlugin);
+ free(pCtx);
+ }
+ else
+ {
+ return (TCSLIB_HANDLE) pCtx;
+ }
+ }
+
+ return INVALID_TCSLIB_HANDLE;
+}
+
+int TCSLibraryClose(TCSLIB_HANDLE hLib)
+{
+ int iRet = -1;
+ PluginContext *pCtx = NULL;
+
+ if (hLib == INVALID_TCSLIB_HANDLE)
+ return iRet;
+
+ pCtx = (PluginContext *) hLib;
+ if (pCtx->pfLibraryClose == NULL)
+ return iRet;
+
+ iRet = (*pCtx->pfLibraryClose)(pCtx->hLib);
+ if (pCtx->pPlugin != NULL)
+ dlclose(pCtx->pPlugin);
+
+ free(pCtx);
+
+ return iRet;
+}
+
+
+TCSErrorCode TCSGetLastError(TCSLIB_HANDLE hLib)
+{
+ PluginContext *pCtx = (PluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfGetLastError == NULL)
+ {
+ return TCS_CONSTRUCT_ERRCODE(TCS_ERROR_MODULE_GENERIC,
+ TCS_ERROR_NOT_IMPLEMENTED);
+ }
+ return (*pCtx->pfGetLastError)(pCtx->hLib);
+}
+
+
+int TCSScanData(TCSLIB_HANDLE hLib, TCSScanParam *pParam, TCSScanResult *pResult)
+{
+ PluginContext *pCtx = (PluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfScanData == NULL)
+ {
+ return -1;
+ }
+ return (*pCtx->pfScanData)(pCtx->hLib, pParam, pResult);
+}
+
+
+int TCSScanFile(TCSLIB_HANDLE hLib, char const *pszFileName, int iDataType,
+ int iAction, int iCompressFlag, TCSScanResult *pResult)
+{
+ PluginContext *pCtx = (PluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfScanFile == NULL)
+ {
+ return -1;
+ }
+ return (*pCtx->pfScanFile)(pCtx->hLib, pszFileName, iDataType, iAction, iCompressFlag, pResult);
+}
+
+
+static PluginContext *LoadPlugin(void)
+{
+ PluginContext *pCtx = NULL;
+ void *pTmp = dlopen(PLUGIN_PATH, RTLD_LAZY);
+ DEBUG_LOG("%s", "load plugin\n");
+ if (pTmp != NULL)
+ {
+ FuncLibraryOpen TmpLibraryOpen;
+ FuncLibraryClose TmpLibraryClose;
+ FuncGetLastError TmpGetLastError;
+ FuncScanData TmpScanData;
+ FuncScanFile TmpScanFile;
+
+ do
+ {
+ TmpLibraryOpen = dlsym(pTmp, "TCSPLibraryOpen");
+ DEBUG_LOG("%s", "load api TCSPLibraryOpen\n");
+ if (TmpLibraryOpen == NULL)
+ {
+ DEBUG_LOG("Failed to load TCSPLibraryOpen in %s\n", PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpLibraryClose = dlsym(pTmp, "TCSPLibraryClose");
+ if (TmpLibraryClose == NULL)
+ {
+ DEBUG_LOG("Failed to load TCSPLibraryClose in %s\n", PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpGetLastError = dlsym(pTmp, "TCSPGetLastError");
+ if (TmpGetLastError == NULL)
+ {
+ DEBUG_LOG("Failed to load TCSPGetLastError in %s\n", PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpScanData = dlsym(pTmp, "TCSPScanData");
+ if (TmpScanData == NULL)
+ {
+ DEBUG_LOG("Failed to load TCSPScanData in %s\n", PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpScanFile = dlsym(pTmp, "TCSPScanFile");
+ if (TmpScanFile == NULL)
+ {
+ DEBUG_LOG("Failed to load TCSPScanFile in %s\n", PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ pCtx = (PluginContext *) malloc(sizeof(PluginContext));
+ if (pCtx == NULL)
+ {
+ dlclose(pTmp);
+ break;
+ }
+ pCtx->pPlugin = pTmp;
+ pCtx->pfLibraryOpen = TmpLibraryOpen;
+ pCtx->pfLibraryClose = TmpLibraryClose;
+ pCtx->pfGetLastError = TmpGetLastError;
+ pCtx->pfScanData = TmpScanData;
+ pCtx->pfScanFile = TmpScanFile;
+ } while(0);
+ }
+ else
+ {
+ DEBUG_LOG("No plugin found.\n");
+ }
+
+ return pCtx;
+}
+
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef TCSIMPL_H
+#define TCSIMPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \file TCSImpl.h
+ * \brief TCS Header File
+ *
+ * This file provides the Tizen Content Screen API functions.
+ */
+
+#define TCS_SA_SCANONLY 1 /* Instructs the scan functions to perform scanning only. */
+
+#define TCS_SA_SCANREPAIR 2 /* Instructs the scan functions to carry out both
+ scanning and repair/removal of detected malware. */
+
+#define TCS_CB_DETECTED 1 /* Informs the caller a malicious code has been
+ detected in the scan target. The callback data
+ argument pParam is set to point to a TCSDetected
+ structure. */
+
+#define TCS_DTYPE_UNKNOWN 0 /* Scan for malicious content in an unknown data
+ type. This data type should be used when the
+ other types are not appropriate. */
+
+#define TCS_DTYPE_HTML 1 /* Scan for malicious content in HTML. */
+
+#define TCS_DTYPE_URL 2 /* Scan for URL with malicious content.
+ url-string format should conform to the
+ Uniform Resource Locators (RFC 1738)
+ specification. */
+
+#define TCS_DTYPE_EMAIL 3 /* Scan for email-address with malicious intent.
+ email-string format should conform with
+ the Internet E-mail address format
+ (RFC 822) specification. */
+
+#define TCS_DTYPE_PHONE 4 /* Scan for phone number with malicious intent.
+ phone-number string consists of the numeric
+ characters '0' through '9', and the
+ '#' and '*' characters. */
+
+#define TCS_DTYPE_JAVA 5 /* Scan for malicious Java code. */
+
+#define TCS_DTYPE_JAVAS 6 /* Scan for malicious Java code. */
+
+#define TCS_DTYPE_TEXT 7 /* Scan text data for malicious content. */
+
+#define TCS_VTYPE_MALWARE 1 /* Malware type. */
+
+#define TCS_SC_USER 1 /* Detected malware is harmful to the user. */
+
+#define TCS_SC_TERMINAL 2 /* Detected malware is harmful to the terminal. */
+
+#define TCS_BC_LEVEL0 0 /* Process with a warning. This severity level may
+ be assigned to data previously considered malicious. */
+
+#define TCS_BC_LEVEL1 1 /* Prompt the user before processing. Ask the user
+ if they want the application to process the data. */
+
+#define TCS_BC_LEVEL2 2 /* Do not process the data. */
+
+#define TCS_BC_LEVEL3 3 /* Do not process the data and prompt user for removal.
+ If the content is stored on the terminal,
+ prompt the user for permission before removal. */
+
+#define TCS_BC_LEVEL4 4 /* Do not process the data and automatically remove if stored. */
+
+
+/*==================================================================================================
+ MACROS
+==================================================================================================*/
+
+/**
+ * Helper macro to get error module.
+ */
+#define TCS_ERRMODULE(e) (((e) >> 24) & 0xff)
+
+/**
+ * Helper macro to get error code.
+ */
+#define TCS_ERRCODE(e) ((e) & 0x00ffffff)
+
+/*==================================================================================================
+ STRUCTURES AND OTHER TYPEDEFS
+==================================================================================================*/
+
+/**
+ * Dummy data structure to avoid unexpected data type casting.
+ */
+struct TCSLibHandle_struct {int iDummy;};
+
+/**
+ * TCS library handle type.
+ */
+typedef struct TCSLibHandle_struct *TCSLIB_HANDLE;
+
+#define INVALID_TCSLIB_HANDLE ((TCSLIB_HANDLE) 0) /* Invalid Content Screening library interface handle. */
+
+/**
+ * error code type.
+ */
+typedef unsigned long TCSErrorCode;
+
+/**
+ * Support 64 bits data / file locating
+ */
+typedef long long TCSOffset;
+
+/**
+ * The calling application specifies scan
+ * parameters using the TCSScanParam structure. The information
+ * contained in the structure provides the scan functions with:
+ * - scan action type (iAction)
+ * - the scan data type (iDataType)
+ * - data pointer to the scan target (pPrivate)
+ * - callback function to retrieve the data size in bytes (pfGetSize)
+ * - callback function to resize the scan data (pfSetSize)
+ * - callback function used by the scan functions to retrieve a
+ * block of scan data (pfRead)
+ * - callback function used to write to the scan data (pfWrite)
+ * - callback function for status/progress reporting (pfCallBack)
+ */
+typedef struct TCSScanParam_struct
+{
+ int iAction; /* The scan-action specifies the type of scanning to be performed on supplied scan data. */
+
+ int iDataType; /* The calling application specifies the data type/format of the data to be scanned using this variable. */
+
+ int iCompressFlag; /* 0 - decompression disabled, 1 - decompression enabled. */
+
+ void *pPrivate; /* Pointer (or handle) to an application object being scanned.
+ The scan functions do not perform direct memory I/O using this data
+ pointer/handle. The data pointer/handle is simply passed back to the caller when
+ performing data read/write using caller specified I/O functions. Also the private
+ data is passed back to the caller using the pfCallback function if it is set. */
+
+ TCSOffset (*pfGetSize)(void *pPrivate); /* Used by the scan functions
+ to obtain the scan target data size (in bytes) from the caller.
+
+ This is a synchronous API.
+ [in] pPrivate Pointer (or handle) to an application object being scanned.
+
+ return - Return Type (int)
+ The size (in bytes) of the data to be scanned.
+ */
+
+ int (*pfSetSize)(void *pPrivate, TCSOffset uSize); /* Called by the scan
+ functions to resize the scanned data to a given size (in bytes) during
+ repair/clean. The resize function pointer needs to be set if the scan-action
+ (iAction) is set to TCS_SA_SCANREPAIR.
+
+ This is a synchronous API.
+
+ @param[in] pPrivate Pointer (or handle) to an application object being scanned.
+ @param[in] uSize The size (in bytes) of the repaired data.
+
+ @return Return Type (int)
+ The size (in bytes) of the application data.
+ Not equal to the value of uSize indicating this call fails.
+ */
+
+ unsigned int (*pfRead)(void *pPrivate, TCSOffset uOffset, void *pBuffer,
+ unsigned int uCount); /* Used for reading a specified
+ amount of application data during scanning/analysis.
+
+ This is a synchronous API.
+
+ @param[in] pPrivate Pointer (or handle) to an application object being scanned.
+ @param[in] uOffset Read from the offset in the application data.
+ @param[out] pBuffer The buffer used to store the read data.
+ @param[in] uCount The size (in bytes) of the data to be read.
+
+ @return Return Type (int)
+ The size (in bytes) of the read data.
+ Not equal to the value of uCount indicating this call fails.
+ */
+
+ unsigned int (*pfWrite)(void *pPrivate, TCSOffset uOffset, void const *pBuffer,
+ unsigned int uCount); /* The scan functions use the
+ given function to write a specified amount of data to the scanned object as a part
+ of the repair process. The function pointer needs to be set if the scan action
+ (iAction) is set to TCS_SA_SCANREPAIR.
+
+ This is a synchronous API.
+
+ @param[in] pPrivate Pointer (or handle) to an application object being scanned.
+ @param[in] uOffset Write data from the offset in the application data.
+ @param[in] pBuffer The buffer hold the data to be written.
+ @param[in] uCount The size (in bytes) of the data to be written.
+
+ @return Return Type (int)
+ The size (in bytes) of the written data.
+ Not equal to the value of uCount indicating this call fails.
+ */
+
+ int (*pfCallBack)(void *pPrivate, int iReason, void *pParam); /* This callback
+ function is set by the caller to be notified to each detected malware while
+ scanning is in process. If specified (not NULL), the scan functions call the
+ specified function with the information (e.g. TCS_CB_DETECTED) for each malware
+ detected in the content/data during scanning.
+
+ This is a synchronous API.
+
+ @param[in] pPrivate Pointer (or handle) to an application object being scanned.
+ @param[in] iReason Reason of this callback.
+ @param[in] pParam The data for specified callback reason respectively.
+
+ @return Return Type (int)
+ The scanning process continues if the callback function returns 0. If a negative
+ value (e.g. -1) is returned, the scanning process is aborted and control is
+ returned to the caller.
+ */
+} TCSScanParam;
+
+/**
+ * Detected malicious code/content information structure.
+ */
+typedef struct TCSDetected_struct
+{
+ struct TCSDetected_struct *pNext; /* Pointer to next malware found, NULL if at the end of list. */
+
+ char const *pszName; /* Detected malware name. */
+ char const *pszVariant; /* Detected malware's variant name. pszName and
+ pszVariant report detected malicious code/content and variant names. The maximum
+ string length for both strings is 64 characters and each is terminated by a null
+ character ('\\0') - the maximum buffer size for both strings is 65 bytes.
+
+ pszVariant is set to an empty string ("\0") if the detected malware is not a
+ variant. */
+
+ unsigned int uType; /* Detected malware type. \see TCS_VTYPE_MALWARE */
+ unsigned int uAction; /* Bit-field specifying severity, class and behavior level.
+
+ Included in the TCSDetected structure is a bit-field variable containing malware
+ severity flags and client application behavior levels.
+
+ The scan functions set the TCS_SC_USER flag if the scanned object/data contains
+ malware harmful to the user. TCS_SC_TERMINAL flag is set if the malware is
+ harmful to the terminal itself. Both TCS_SC_USER and TCS_SC_TERMINAL flags are
+ set if the malware is harmful to both the user and the terminal.
+
+ The application behavior level specifies what to do with the data/object
+ containing the detected malware.
+
+ When multiple behavior level codes are found in a scanned data/object, the
+ calling application would be expected to act with the highest behavior level.
+ For example, if both TCS_BC_LEVEL0 and TCS_BC_LEVEL3 were reported, the application
+ would need to take on TCS_BC_LEVEL3 action. */
+
+ char const *pszFileName; /* Path of the infected file. The pszFileName field
+ report, if not NULL, the complete file path of the infected content. If the scan
+ functions have the ability to scan/analyze inside archives, then the path
+ reported in pszFileName would be composed of multiple paths separated by the '|'
+ character. The first path of the sequence is the real file system path of the
+ currently scanned file, for TCSScanFile(), or empty for TCSScanData(). No
+ assumption should be made on the path name separator used for the archive
+ components of the path (the ones following the first). Only the first component,
+ if not empty, is the real file path of the currently scanned content. */
+} TCSDetected;
+
+/**
+ * Detected malware information is returned to the caller in the TCSScanResult
+ * structure provided by the caller. The TCSScanResult structure contains a pointer
+ * to a structure that contains scan result information and a pointer to a function
+ * used to remove the scan result resource. The memory used to hold the scan result
+ * is allocated by the scan functions and freed by calling the function pointed by the
+ * pfFreeResult pointer. The detected malware information includes the malware
+ * information which had been reported via the callback (pfCallback) function during
+ * scanning.
+ *
+ * \code
+ * int ScanAppData( ... )
+ * {
+ * TCSScanResult scanResult;
+ * .
+ * .
+ * if (TCSScanData(hScanner, &scanParam, &scanResult) == 0)
+ * {
+ * .
+ * .
+ * scanResult.pfFreeResult( &scanResult );
+ * }
+ * .
+ * .
+ * }
+ * \endcode
+ */
+typedef struct TCSScanResult_struct
+{
+ int iNumDetected; /* Number of malware found. */
+ TCSDetected *pDList; /* Detected malware list. */
+ void (*pfFreeResult)(struct TCSScanResult_struct *pResult); /* Function pointer
+ used to free reported scan result.
+
+ This is a synchronous API.
+ \param[in] pResult Pointer to data structure in which detected scan result
+ information is stored.
+
+ \return None
+ */
+} TCSScanResult;
+
+/*==================================================================================================
+ FUNCTION PROTOTYPES
+==================================================================================================*/
+
+/**
+ * \brief Initializes and returns a Tizen Content Screening library
+ * interface handle.
+ *
+ * A Content Screening library interface handle (or TCS library handle) is
+ * obtained using the TCSLibraryOpen() function. The library handle is required for
+ * subsequent TCS API calls. The TCSLibraryClose() function releases/closes the library
+ * handle. Multiple library handles can be obtained using TCSLibraryOpen().
+ *
+ * This is a synchronous API.
+ *
+ * \return Return Type (TCSLIB_HANDLE) \n
+ * TCS library interface handle - on success. \n
+ * INVALID_TCSLIB_HANDLE - on failure. \n
+ */
+TCSLIB_HANDLE TCSLibraryOpen(void);
+
+/**
+ * \brief Releases system resources associated with an TCS API library
+ * handle returned by the TCSLibraryOpen() function.
+ *
+ * This is a synchronous API.
+ *
+ * \param[in] hLib TCS library handle returned by TCSLibraryOpen().
+ *
+ * \return Return Type (int) \n
+ * 0 - on success. \n
+ * -1 - on failure. \n
+ */
+int TCSLibraryClose(TCSLIB_HANDLE hLib);
+
+/**
+ * \brief Returns the last error code associated with the given
+ * TCS library handle.
+ *
+ * Once the TCS library handle has been successfully obtained from TCSLibraryOpen(),
+ * TCSGetLastError() can be used to retrieve the last TCS error that occurred. All TCS
+ * API functions return zero (= 0) or a valid object pointer if successful, and -1
+ * or a null object handle (e.g. INVALID_TCSSCAN_HANDLE) in case of an error. The
+ * TCSGetLastError() function is used to retrieve error information when a TCS
+ * function fails.
+ *
+ * This is a synchronous API.
+ *
+ * \param[in] hLib TCS library handle returned by TCSLibraryOpen().
+ *
+ * \return Return Type (TCSErrorCode) \n
+ * Last error code set by the TCS library. The TCSErrorCode data type is defined as a
+ * 32-bit unsigned integer which contains both component and an error code (see
+ * Figure about TCS Error Code Format). Two macros are available to extract the error
+ * module and the error code. Call TCS_ERRMODULE(error-code) to get the error module,
+ * and TCS_ERRCODE(error-code) to get the error code (where error-code is the value
+ * returned by TCSGetLastError()).
+ *
+ * TCS library call sequence with a call to the TCSGetLastError() function:
+ *
+ */
+TCSErrorCode TCSGetLastError(TCSLIB_HANDLE hLib);
+
+/**
+ * \brief TCSScanData() is used to scan a data buffer for malware. The caller
+ * specifies a scanner action, scan target data type, set I/O functions to access
+ * the data, and an optional callback function for information retrieval. The result
+ * of the data scanning is returned in a caller provided data structure.
+ *
+ * This is a synchronous API.
+ *
+ * \param[in] hLib instance handle obtained from a call to the TCSLibraryOpen()
+ * function.
+ * \param[in] pParam Pointer to a structure containing data scan parameters.
+ * \param[out] pResult Pointer to a structure containing data scan
+ * results.
+ *
+ * \return Return Type (int) \n
+ * 0 - on success. \n
+ * -1 - on failure and error code is set. \n
+ *
+ */
+int TCSScanData(TCSLIB_HANDLE hLib, TCSScanParam *pParam, TCSScanResult *pResult);
+
+/**
+ * \brief TCSScanFile() is used to scan a file for malware. The caller specifies a
+ * file name, a scanner action, and scan target data type. The scan result is
+ * returned in a caller provided data structure.
+ *
+ * This is a synchronous API.
+ *
+ * \param[in] hLib instance handle obtained from a call to the
+ * TCSLibraryOpen() function.
+ * \param[in] pszFileName Name of file to scan. The file name must include the
+ * absolute path.
+ * \param[in] iDataType Type of data contained in the file. This is used to
+ * perform data type specific scans on files.
+ * \param[in] iAction Type of scanning to perform on file.
+ * \param[out] pResult Pointer to a structure containing data scan results.
+ *
+ * \return Return Type (int) \n
+ * 0 - on success. \n
+ * -1 - on failure and error code is set. \n
+ */
+int TCSScanFile(TCSLIB_HANDLE hLib, char const *pszFileName, int iDataType,
+ int iAction, int iCompressFlag, TCSScanResult *pResult);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TCSIMPL_H */
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include <unistd.h>
+#include <dlfcn.h>
+#include <malloc.h>
+
+#include "TWPImpl.h"
+
+
+#define SITE_PLUGIN_PATH "/opt/usr/share/sec_plugin/libwpengine.so"
+
+#if defined(DEBUG)
+#define DEBUG_LOG(_fmt_, _param_...) { \
+ printf("[TCS] %s,%d: " _fmt_, __FILE__, __LINE__, ##_param_); \
+ }
+#else
+#define DEBUG_LOG(_fmt_, _param_...)
+#endif
+
+
+typedef TWP_RESULT (*FuncInitLibrary)(TWPAPIInit *pApiInit);
+typedef void (*FuncUninitLibrary)(void);
+typedef TWP_RESULT (*FuncConfigurationCreate)(TWPConfiguration *pConfigure, TWPConfigurationHandle *phConfigure);
+typedef TWP_RESULT (*FuncConfigurationDestroy)(TWPConfigurationHandle *hConfigure);
+typedef TWP_RESULT (*FuncLookupUrls)(TWPConfigurationHandle hConfigure, TWPRequest *pRequest, int iRedirUrl,
+ const char **ppUrls, unsigned int uCount, TWPResponseHandle *phResponse);
+typedef TWP_RESULT (*FuncResponseWrite)(TWPResponseHandle hResponse, const void *pData, unsigned uLength);
+typedef TWP_RESULT (*FuncResponseGetUrlRatingByIndex)(TWPResponseHandle hResponse, unsigned int iIndex,
+ TWPUrlRatingHandle *hRating);
+typedef TWP_RESULT (*FuncResponseGetUrlRatingByUrl)(TWPResponseHandle hResponse, const char *pUrl,
+ unsigned int iUrlLength, TWPUrlRatingHandle *hRating);
+typedef TWP_RESULT (*FuncResponseGetRedirUrlFor)(TWPResponseHandle hResponse, TWPUrlRatingHandle hRating,
+ TWPPolicyHandle hPolicy, char **ppUrl, unsigned int *puLength);
+typedef TWP_RESULT (*FuncResponseGetUrlRatingsCount)(TWPResponseHandle hResponse, unsigned int *puCount);
+typedef TWP_RESULT (*FuncResponseDestroy)(TWPResponseHandle *handle_response);
+typedef TWP_RESULT (*FuncPolicyCreate)(TWPConfigurationHandle hCfg, TWPCategories *pCategories, unsigned int uCount,
+ TWPPolicyHandle *phPolicy);
+typedef TWP_RESULT (*FuncPolicyValidate)(TWPPolicyHandle hPolicy, TWPUrlRatingHandle hRating, int *piViolated);
+typedef TWP_RESULT (*FuncPolicyGetViolations)(TWPPolicyHandle hPolicy, TWPUrlRatingHandle hRating,
+ TWPCategories **ppViolated, unsigned *puLength);
+typedef TWP_RESULT (*FuncPolicyDestroy)(TWPPolicyHandle *hPolicy);
+typedef TWP_RESULT (*FuncUrlRatingGetScore)(TWPUrlRatingHandle hRating, int *piScore);
+typedef TWP_RESULT (*FuncUrlRatingGetUrl)(TWPUrlRatingHandle hRating, const char **ppUrl,
+ unsigned int *puLength);
+typedef TWP_RESULT (*FuncUrlRatingGetDLAUrl)(TWPUrlRatingHandle hRating, const char **ppDlaUrl,
+ unsigned int *puLength);
+typedef TWP_RESULT (*FuncUrlRatingHasCategory)(TWPUrlRatingHandle hRating, TWPCategories Category,
+ int *piPresent);
+typedef TWP_RESULT (*FuncUrlRatingGetCategories)(TWPUrlRatingHandle hRating, TWPCategories **ppCategories,
+ unsigned int *puLength);
+
+
+typedef struct SitePluginContext_struct
+{
+ void *pPlugin;
+ FuncUninitLibrary pfUninitLibrary;
+ FuncInitLibrary pfInitLibrary;
+ FuncConfigurationCreate pfConfigurationCreate;
+ FuncConfigurationDestroy pfConfigurationDestroy;
+ FuncLookupUrls pfLookupUrls;
+ FuncResponseWrite pfResponseWrite;
+ FuncResponseGetUrlRatingByIndex pfResponseGetUrlRatingByIndex;
+ FuncResponseGetUrlRatingByUrl pfResponseGetUrlRatingByUrl;
+ FuncResponseGetRedirUrlFor pfResponseGetRedirUrlFor;
+ FuncResponseGetUrlRatingsCount pfResponseGetUrlRatingsCount;
+ FuncResponseDestroy pfResponseDestroy;
+ FuncPolicyCreate pfPolicyCreate;
+ FuncPolicyValidate pfPolicyValidate;
+ FuncPolicyGetViolations pfPolicyGetViolations;
+ FuncPolicyDestroy pfPolicyDestroy;
+ FuncUrlRatingGetScore pfUrlRatingGetScore;
+ FuncUrlRatingGetUrl pfUrlRatingGetUrl;
+ FuncUrlRatingGetDLAUrl pfUrlRatingGetDLAUrl;
+ FuncUrlRatingHasCategory pfUrlRatingHasCategory;
+ FuncUrlRatingGetCategories pfUrlRatingGetCategories;
+} SitePluginContext;
+
+
+static SitePluginContext *LoadPlugin(void);
+
+
+TWPLIB_HANDLE TWPInitLibrary(TWPAPIInit *pApiInit)
+{
+ SitePluginContext *pCtx = NULL;
+
+ pCtx = LoadPlugin();
+ if (pCtx != NULL)
+ {
+ if (pCtx->pfInitLibrary != NULL &&
+ (*pCtx->pfInitLibrary)(pApiInit) == TWP_SUCCESS)
+ return (TWPLIB_HANDLE) pCtx;
+
+ TWPUninitLibrary((TWPLIB_HANDLE) pCtx);
+ return INVALID_TWPLIB_HANDLE;
+ }
+
+ return INVALID_TWPLIB_HANDLE;
+}
+
+void TWPUninitLibrary(TWPLIB_HANDLE hLib)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx != NULL)
+ {
+ if (pCtx->pfUninitLibrary != NULL)
+ (*pCtx->pfUninitLibrary)();
+ if (pCtx->pPlugin != NULL)
+ dlclose(pCtx->pPlugin);
+ free(pCtx);
+ }
+}
+
+TWP_RESULT TWPConfigurationCreate(TWPLIB_HANDLE hLib, TWPConfiguration *pConfigure,
+ TWPConfigurationHandle *phConfigure)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfConfigurationCreate == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfConfigurationCreate)(pConfigure, phConfigure);
+}
+
+TWP_RESULT TWPConfigurationDestroy(TWPLIB_HANDLE hLib, TWPConfigurationHandle *hConfigure)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfConfigurationDestroy == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfConfigurationDestroy)(hConfigure);
+}
+
+TWP_RESULT TWPLookupUrls(TWPLIB_HANDLE hLib, TWPConfigurationHandle hConfigure, TWPRequest *pRequest,
+ int iRedirUrl, const char **ppUrls, unsigned int uCount, TWPResponseHandle *phResponse)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfLookupUrls == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfLookupUrls)(hConfigure, pRequest, iRedirUrl, ppUrls, uCount, phResponse);
+}
+
+TWP_RESULT TWPResponseWrite(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, const void *pData, unsigned uLength)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfResponseWrite == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfResponseWrite)(hResponse, pData, uLength);
+}
+
+TWP_RESULT TWPResponseGetUrlRatingByIndex(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, unsigned int uIndex,
+ TWPUrlRatingHandle *hRating)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfResponseGetUrlRatingByIndex == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfResponseGetUrlRatingByIndex)(hResponse, uIndex, hRating);
+}
+
+TWP_RESULT TWPResponseGetUrlRatingByUrl(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, const char *pUrl,
+ unsigned int uUrlLength, TWPUrlRatingHandle *hRating)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfResponseGetUrlRatingByUrl == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfResponseGetUrlRatingByUrl)(hResponse, pUrl, uUrlLength, hRating);
+}
+
+TWP_RESULT TWPResponseGetRedirUrlFor(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, TWPUrlRatingHandle hRating,
+ TWPPolicyHandle hPolicy, char **ppUrl, unsigned int *puLength)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfResponseGetRedirUrlFor == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfResponseGetRedirUrlFor)(hResponse, hRating, hPolicy, ppUrl, puLength);
+}
+
+TWP_RESULT TWPResponseGetUrlRatingsCount(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, unsigned int *puCount)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfResponseGetUrlRatingsCount == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfResponseGetUrlRatingsCount)(hResponse, puCount);
+}
+
+TWP_RESULT TWPResponseDestroy(TWPLIB_HANDLE hLib, TWPResponseHandle *hResponse)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfResponseDestroy == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfResponseDestroy)(hResponse);
+}
+
+TWP_RESULT TWPPolicyCreate(TWPLIB_HANDLE hLib, TWPConfigurationHandle hCfg, TWPCategories *pCategories,
+ unsigned int uCount, TWPPolicyHandle *phPolicy)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfPolicyCreate == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfPolicyCreate)(hCfg, pCategories, uCount, phPolicy);
+}
+
+TWP_RESULT TWPPolicyValidate(TWPLIB_HANDLE hLib, TWPPolicyHandle hPolicy, TWPUrlRatingHandle hRating, int *piViolated)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfPolicyValidate == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfPolicyValidate)(hPolicy, hRating, piViolated);
+}
+
+TWP_RESULT TWPPolicyGetViolations(TWPLIB_HANDLE hLib, TWPPolicyHandle hPolicy, TWPUrlRatingHandle hRating,
+ TWPCategories **ppViolated, unsigned *puLength)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfPolicyGetViolations == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfPolicyGetViolations)(hPolicy, hRating, ppViolated, puLength);
+}
+
+TWP_RESULT TWPPolicyDestroy(TWPLIB_HANDLE hLib, TWPPolicyHandle *hPolicy)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfPolicyDestroy == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfPolicyDestroy)(hPolicy);
+}
+
+TWP_RESULT TWPUrlRatingGetScore(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, int *piScore)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfUrlRatingGetScore == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfUrlRatingGetScore)(hRating, piScore);
+}
+
+TWP_RESULT TWPUrlRatingGetUrl(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, char **ppUrl,
+ unsigned int *puLength)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfUrlRatingGetUrl == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfUrlRatingGetUrl)(hRating, (const char **) ppUrl, puLength);
+}
+
+TWP_RESULT TWPUrlRatingGetDLAUrl(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, char **ppDlaUrl,
+ unsigned int *puLength)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfUrlRatingGetDLAUrl == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfUrlRatingGetDLAUrl)(hRating, (const char **) ppDlaUrl, puLength);
+}
+
+TWP_RESULT TWPUrlRatingHasCategory(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, TWPCategories Category,
+ int *piPresent)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfUrlRatingHasCategory == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfUrlRatingHasCategory)(hRating, Category, piPresent);
+}
+
+TWP_RESULT TWPUrlRatingGetCategories(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, TWPCategories **ppCategories,
+ unsigned int *puLength)
+{
+ SitePluginContext *pCtx = (SitePluginContext *) hLib;
+
+ if (pCtx == NULL || pCtx->pfUrlRatingGetCategories == NULL)
+ return TWP_NOT_IMPLEMENTED;
+
+ return (*pCtx->pfUrlRatingGetCategories)(hRating, ppCategories, puLength);
+}
+
+static SitePluginContext *LoadPlugin(void)
+{
+ SitePluginContext *pCtx = NULL;
+ void *pTmp = dlopen(SITE_PLUGIN_PATH, RTLD_LAZY);
+ DEBUG_LOG("%s", "load site plugin\n");
+ if (pTmp != NULL)
+ {
+ FuncUninitLibrary TmpUninitLibrary;
+ FuncInitLibrary TmpInitLibrary;
+ FuncConfigurationCreate TmpConfigurationCreate;
+ FuncConfigurationDestroy TmpConfigurationDestroy;
+ FuncLookupUrls TmpLookupUrls;
+ FuncResponseWrite TmpResponseWrite;
+ FuncResponseGetUrlRatingByIndex TmpResponseGetUrlRatingByIndex;
+ FuncResponseGetUrlRatingByUrl TmpResponseGetUrlRatingByUrl;
+ FuncResponseGetRedirUrlFor TmpResponseGetRedirUrlFor;
+ FuncResponseGetUrlRatingsCount TmpResponseGetUrlRatingsCount;
+ FuncResponseDestroy TmpResponseDestroy;
+ FuncPolicyCreate TmpPolicyCreate;
+ FuncPolicyValidate TmpPolicyValidate;
+ FuncPolicyGetViolations TmpPolicyGetViolations;
+ FuncPolicyDestroy TmpPolicyDestroy;
+ FuncUrlRatingGetScore TmpUrlRatingGetScore;
+ FuncUrlRatingGetUrl TmpUrlRatingGetUrl;
+ FuncUrlRatingGetDLAUrl TmpUrlRatingGetDLAUrl;
+ FuncUrlRatingHasCategory TmpUrlRatingHasCategory;
+ FuncUrlRatingGetCategories TmpUrlRatingGetCategories;
+
+ do
+ {
+ TmpInitLibrary = dlsym(pTmp, "TWPPInitLibrary");
+ DEBUG_LOG("%s", "load api TWPPInitLibrary\n");
+ if (TmpInitLibrary == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPInitLibrary in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpUninitLibrary = dlsym(pTmp, "TWPPUninitLibrary");
+ DEBUG_LOG("%s", "load api TWPPUninitLibrary\n");
+ if (TmpUninitLibrary == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPUninitLibrary in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpConfigurationCreate = dlsym(pTmp, "TWPPConfigurationCreate");
+ DEBUG_LOG("%s", "load api TWPPConfigurationCreate\n");
+ if (TmpConfigurationCreate == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPConfigurationCreate in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpConfigurationDestroy = dlsym(pTmp, "TWPPConfigurationDestroy");
+ DEBUG_LOG("%s", "load api TWPPConfigurationDestroy\n");
+ if (TmpConfigurationDestroy == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPConfigurationDestroy in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpLookupUrls = dlsym(pTmp, "TWPPLookupUrls");
+ DEBUG_LOG("%s", "load api TWPPLookupUrls\n");
+ if (TmpLookupUrls == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPLookupUrls in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpResponseWrite = dlsym(pTmp, "TWPPResponseWrite");
+ DEBUG_LOG("%s", "load api TWPPResponseWrite\n");
+ if (TmpResponseWrite == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPResponseWrite in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpResponseGetUrlRatingByIndex = dlsym(pTmp, "TWPPResponseGetUrlRatingByIndex");
+ DEBUG_LOG("%s", "load api TWPPResponseGetUrlRatingByIndex\n");
+ if (TmpResponseGetUrlRatingByIndex == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPResponseGetUrlRatingByIndex in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpResponseGetUrlRatingByUrl = dlsym(pTmp, "TWPPResponseGetUrlRatingByUrl");
+ DEBUG_LOG("%s", "load api TWPPResponseGetUrlRatingByUrl\n");
+ if (TmpResponseGetUrlRatingByUrl == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPResponseGetUrlRatingByUrl in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpResponseGetRedirUrlFor = dlsym(pTmp, "TWPPResponseGetRedirUrlFor");
+ DEBUG_LOG("%s", "load api TWPPResponseGetRedirUrlFor\n");
+ if (TmpResponseGetRedirUrlFor == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPResponseGetRedirUrlFor in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpResponseGetUrlRatingsCount = dlsym(pTmp, "TWPPResponseGetUrlRatingsCount");
+ DEBUG_LOG("%s", "load api TWPPResponseGetUrlRatingsCount\n");
+ if (TmpResponseGetUrlRatingsCount == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPResponseGetUrlRatingsCount in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpResponseDestroy = dlsym(pTmp, "TWPPResponseDestroy");
+ DEBUG_LOG("%s", "load api TWPPResponseDestroy\n");
+ if (TmpResponseDestroy == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPResponseDestroy in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpPolicyCreate = dlsym(pTmp, "TWPPPolicyCreate");
+ DEBUG_LOG("%s", "load api TWPPPolicyCreate\n");
+ if (TmpPolicyCreate == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPPolicyCreate in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpPolicyValidate = dlsym(pTmp, "TWPPPolicyValidate");
+ DEBUG_LOG("%s", "load api TWPPPolicyValidate\n");
+ if (TmpPolicyValidate == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPPolicyValidate in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpPolicyGetViolations = dlsym(pTmp, "TWPPPolicyGetViolations");
+ DEBUG_LOG("%s", "load api TWPPPolicyGetViolations\n");
+ if (TmpPolicyGetViolations == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPPolicyGetViolations in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpPolicyDestroy = dlsym(pTmp, "TWPPPolicyDestroy");
+ DEBUG_LOG("%s", "load api TWPPPolicyDestroy\n");
+ if (TmpPolicyDestroy == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPPolicyDestroy in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpUrlRatingGetScore = dlsym(pTmp, "TWPPUrlRatingGetScore");
+ DEBUG_LOG("%s", "load api TWPPUrlRatingGetScore\n");
+ if (TmpUrlRatingGetScore == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPUrlRatingGetScore in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpUrlRatingGetUrl = dlsym(pTmp, "TWPPUrlRatingGetUrl");
+ DEBUG_LOG("%s", "load api TWPPUrlRatingGetUrl\n");
+ if (TmpUrlRatingGetUrl == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPUrlRatingGetUrl in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpUrlRatingGetDLAUrl = dlsym(pTmp, "TWPPUrlRatingGetDLAUrl");
+ DEBUG_LOG("%s", "load api TWPPUrlRatingGetDLAUrl\n");
+ if (TmpUrlRatingGetDLAUrl == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPUrlRatingGetDLAUrl in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpUrlRatingHasCategory = dlsym(pTmp, "TWPPUrlRatingHasCategory");
+ DEBUG_LOG("%s", "load api TWPPUrlRatingHasCategory\n");
+ if (TmpUrlRatingHasCategory == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPUrlRatingHasCategory in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ TmpUrlRatingGetCategories = dlsym(pTmp, "TWPPUrlRatingGetCategories");
+ DEBUG_LOG("%s", "load api TWPPUrlRatingGetCategories\n");
+ if (TmpUrlRatingGetCategories == NULL)
+ {
+ DEBUG_LOG("Failed to load TWPPUrlRatingGetCategories in %s\n", SITE_PLUGIN_PATH);
+ dlclose(pTmp);
+ break;
+ }
+
+ pCtx = (SitePluginContext *) malloc(sizeof(SitePluginContext));
+ if (pCtx == NULL)
+ {
+ dlclose(pTmp);
+ break;
+ }
+
+ pCtx->pPlugin = pTmp;
+ pCtx->pfUninitLibrary = TmpUninitLibrary;
+ pCtx->pfInitLibrary = TmpInitLibrary;
+ pCtx->pfConfigurationCreate = TmpConfigurationCreate;
+ pCtx->pfConfigurationDestroy = TmpConfigurationDestroy;
+ pCtx->pfLookupUrls = TmpLookupUrls;
+ pCtx->pfResponseWrite = TmpResponseWrite;
+ pCtx->pfResponseGetUrlRatingByIndex = TmpResponseGetUrlRatingByIndex;
+ pCtx->pfResponseGetUrlRatingByUrl = TmpResponseGetUrlRatingByUrl;
+ pCtx->pfResponseGetRedirUrlFor = TmpResponseGetRedirUrlFor;
+ pCtx->pfResponseGetUrlRatingsCount = TmpResponseGetUrlRatingsCount;
+ pCtx->pfResponseDestroy = TmpResponseDestroy;
+ pCtx->pfPolicyCreate = TmpPolicyCreate;
+ pCtx->pfPolicyValidate = TmpPolicyValidate;
+ pCtx->pfPolicyGetViolations = TmpPolicyGetViolations;
+ pCtx->pfPolicyDestroy = TmpPolicyDestroy;
+ pCtx->pfUrlRatingGetScore = TmpUrlRatingGetScore;
+ pCtx->pfUrlRatingGetUrl = TmpUrlRatingGetUrl;
+ pCtx->pfUrlRatingGetDLAUrl = TmpUrlRatingGetDLAUrl;
+ pCtx->pfUrlRatingHasCategory = TmpUrlRatingHasCategory;
+ pCtx->pfUrlRatingGetCategories = TmpUrlRatingGetCategories;
+ } while(0);
+ }
+ else
+ {
+ DEBUG_LOG("No plugin found.\n");
+ }
+
+ return pCtx;
+}
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef TWPIMPL_H
+#define TWPIMPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \file TWPImpl.h
+ * \brief TWP Header File
+ *
+ * This file provides the Tizen Web Protection API functions.
+ */
+
+typedef long unsigned int TWPMallocSizeT; /* Size unit */
+
+struct TWPLibHandle_struct {int iDummy;};
+
+typedef struct TWPLibHandle_struct *TWPLIB_HANDLE;
+
+#define TWPAPI_VERSION 1 /* SDK version */
+
+#define TWPCONFIG_VERSION 1 /* Configure version */
+
+#define TWPREQUEST_VERSION 1 /* Request version */
+
+#define INVALID_TWPLIB_HANDLE ((TWPLIB_HANDLE) 0) /* Invalid web protection library interface handle. */
+
+/**
+ * Result code used by TWP_RESULT
+ */
+typedef enum
+{
+ TWP_SUCCESS = 0,
+ TWP_ERROR = 1,
+ TWP_NOMEM = 2,
+ TWP_INVALID_HANDLE = 3,
+ TWP_INVALID_PARAMETER = 4,
+ TWP_INVALID_VERSION = 5,
+ TWP_INVALID_RESPONSE = 6,
+ TWP_NO_DATA = 7,
+ TWP_NOT_IMPLEMENTED = 500
+} TWP_RESULT;
+
+/**
+ * Web site category definitions
+ */
+typedef enum
+{
+ TWP_Artcultureheritage,
+ TWP_Alcohol,
+ TWP_Anonymizers,
+ TWP_Anonymizingutilities,
+ TWP_Business,
+ TWP_Chat,
+ TWP_Publicinformation,
+ TWP_Potentialcriminalactivities,
+ TWP_Drugs,
+ TWP_Educationreference,
+ TWP_Entertainment,
+ TWP_Extreme,
+ TWP_Financebanking,
+ TWP_Gambling,
+ TWP_Games,
+ TWP_Governmentmilitary,
+ TWP_Potentialhackingcomputercrime,
+ TWP_Health,
+ TWP_Humorcomics,
+ TWP_Discrimination,
+ TWP_Instantmessaging,
+ TWP_Stocktrading,
+ TWP_Internetradiotv,
+ TWP_Jobsearch,
+ TWP_Informationsecurity,
+ TWP_E_RESERVED_1,
+ TWP_Mobilephone,
+ TWP_Mediadownloads,
+ TWP_Malicioussites,
+ TWP_E_RESERVED_2,
+ TWP_Nudity,
+ TWP_Nonprofitadvocacyngo,
+ TWP_Generalnews,
+ TWP_Onlineshopping,
+ TWP_Provocativeattire,
+ TWP_P2pfilesharing,
+ TWP_Politicsopinion,
+ TWP_Personalpages,
+ TWP_Portalsites,
+ TWP_Remoteaccess,
+ TWP_Religionideology,
+ TWP_Resourcesharing,
+ TWP_Searchengines,
+ TWP_Sports,
+ TWP_Streamingmedia,
+ TWP_Sharewarefreeware,
+ TWP_Pornography,
+ TWP_Spywareadwarekeyloggers,
+ TWP_Tobacco,
+ TWP_Travel,
+ TWP_Violence,
+ TWP_Webads,
+ TWP_Weapons,
+ TWP_Webmail,
+ TWP_Webphone,
+ TWP_Auctionsclassifieds,
+ TWP_Forumbulletinboards,
+ TWP_Profanity,
+ TWP_Schoolcheatinginformation,
+ TWP_Sexualmaterials,
+ TWP_Gruesomecontent,
+ TWP_Visualsearchengine,
+ TWP_Technicalbusinessforums,
+ TWP_Gamblingrelated,
+ TWP_Messaging,
+ TWP_Gamecartoonviolence,
+ TWP_Phishing,
+ TWP_Personalnetworkstorage,
+ TWP_Spamurls,
+ TWP_Interactivewebapplications,
+ TWP_Fashionbeauty,
+ TWP_Softwarehardware,
+ TWP_Potentialillegalsoftware,
+ TWP_Contentserver,
+ TWP_Internetservices,
+ TWP_Mediasharing,
+ TWP_Incidentalnudity,
+ TWP_Marketingmerchandising,
+ TWP_Parkeddomain,
+ TWP_Pharmacy,
+ TWP_Restaurants,
+ TWP_Realestate,
+ TWP_Recreationhobbies,
+ TWP_Blogswiki,
+ TWP_Digitalpostcards,
+ TWP_Historicalrevisionism,
+ TWP_Technicalinformation,
+ TWP_Datingpersonals,
+ TWP_Motorvehicles,
+ TWP_Professionalnetworking,
+ TWP_Socialnetworking,
+ TWP_Texttranslators,
+ TWP_Webmeetings,
+ TWP_Forkids,
+ TWP_E_RESERVED_3,
+ TWP_Moderated,
+ TWP_Textspokenonly,
+ TWP_Controversialopinions,
+ TWP_Residentialipaddresses,
+ TWP_Browserexploits,
+ TWP_Consumerprotection,
+ TWP_Illegaluk,
+ TWP_Majorglobalreligions,
+ TWP_Maliciousdownloads,
+ TWP_Potentiallyunwantedprograms,
+
+ TWP_LastCategoryPlaceholder = 128,
+ TWP_OverallPhishing = 129,
+ TWP_OverallRiskHigh = 130,
+ TWP_OverallRiskMedium = 131,
+ TWP_OverallRiskMinimal = 132,
+ TWP_OverallRiskUnverified = 137,
+ TWP_OverallMcAfeeSecure = 138,
+ TWP_LastAttributePlaceholder = 160,
+} TWPCategories;
+
+/**
+ * Risk level
+ */
+typedef enum
+{
+ TWP_Minimal,
+ TWP_Unverified,
+ TWP_Medium,
+ TWP_High,
+} TWPRiskLevel;
+
+/**
+ * Score range
+ */
+typedef enum
+{
+ TWP_MinimalLow = 0,
+ TWP_MinimalHigh = 14,
+ TWP_UnverifiedLow = 15,
+ TWP_UnverifiedHigh = 29,
+ TWP_MediumLow = 30,
+ TWP_MediumHigh = 49,
+ TWP_HighLow= 50,
+ TWP_HighHigh = 127
+} TWPScoreRange;
+
+/**
+ * HTTP submit method
+ */
+typedef enum
+{
+ TWPPOST,
+} TWPSubmitMethod;
+
+/* forward declaration */
+struct TWPRequest;
+typedef struct TWPConfiguration *TWPConfigurationHandle;
+typedef struct TWPResponse* TWPResponseHandle;
+typedef struct TWPUrlRating *TWPUrlRatingHandle;
+typedef struct TWPPolicy *TWPPolicyHandle;
+typedef void *(*TWPFnMemAlloc)(TWPMallocSizeT size);
+typedef void (*TWPFnMemFree)(void *address);
+typedef long (*TWPFnRandom)(void);
+typedef TWP_RESULT (*TWPFnRequestSetUrl)(struct TWPRequest *request, const char *url,
+ unsigned int length);
+typedef TWP_RESULT (*TWPFnRequestSetMethod)(struct TWPRequest *request, TWPSubmitMethod method);
+typedef TWP_RESULT (*TWPFnRequestSend)(struct TWPRequest *request, TWPResponseHandle response,
+ const void *data, unsigned int length);
+typedef TWP_RESULT (*TWPFnRequestReceive)(struct TWPRequest *request, void *buffer,
+ unsigned int buffer_length, unsigned int *length);
+
+/**
+ * Initialize data requested by SDK initialization
+ */
+typedef struct TWPAPIInit
+{
+ int api_version;
+ TWPFnMemAlloc memallocfunc;
+ TWPFnMemFree memfreefunc;
+} TWPAPIInit;
+
+/**
+ * Configuration which enable caller to customize the SDK
+ */
+typedef struct TWPConfiguration
+{
+ int config_version; /* Configuration version */
+ const char *client_id; /* Client id for cloud to qualify */
+ const char *client_key; /* Corresponding key for specific client for validation from cloud */
+ const char *host; /* Host name for cloud where SDK send request to, set to NULL for SDK to use default settings in plug-in */
+ int secure_connection; /* 1 - use secured connection (HTTPS), 0 - not secured connection. */
+ int skip_dla; /* 1 - disable DLA lookup, 0 - enable DLA lookup */
+ int obfuscate_request; /* 1 - obfuscate request data, 0 - do not obfuscate request data */
+ TWPFnRandom randomfunc; /* Caller customized random function */
+} TWPConfiguration;
+
+/**
+ * Request for SDK to check URL against cloud database
+ */
+typedef struct TWPRequest
+{
+ int request_version; /* Request version */
+ TWPFnRequestSetUrl seturlfunc; /* Callback for SDK to set URL from SDK */
+ TWPFnRequestSetMethod setmethodfunc; /* Callback for SDK to set HTTP request method */
+ TWPFnRequestSend sendfunc; /* Callback for SDK to send HTTP request */
+ TWPFnRequestReceive receivefunc; /* Callback for SDK to receive HTTP response, if caller set it to be NULL,
+ SDK will assume the HTTP request will be handled in a-synchronized manner */
+} TWPRequest;
+
+/**
+ * \brief
+ * Initialize SDK
+ *
+ * This is a synchronized API
+ *
+ * \param[in] pApiInit API initialization data structure.
+ *
+ * \return TWP_RESULT
+ */
+TWPLIB_HANDLE TWPInitLibrary(TWPAPIInit *pApiInit);
+
+/**
+ * \brief
+ * Uninitialize SDK
+ *
+ * This is a synchronized API
+ *
+ */
+void TWPUninitLibrary(TWPLIB_HANDLE hLib);
+
+/**
+ * \brief
+ * Create TWP configuration to customize SDK
+ *
+ * This is a synchronized API
+ *
+ * \param[in] pConfigure caller configurations
+ * \param[out] phConfigure created configuration for SDK
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPConfigurationCreate(TWPLIB_HANDLE hLib, TWPConfiguration *pConfigure, TWPConfigurationHandle *phConfigure);
+
+/**
+ * \brief
+ * Release the configuration resources allocated by TWPConfigurationCreate
+ *
+ * This is a synchronized API
+ *
+ * \param[in] hConfigure configuration to be destroyed
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPConfigurationDestroy(TWPLIB_HANDLE hLib, TWPConfigurationHandle *hConfigure);
+
+/**
+ * \brief
+ * Main function for caller to check URL reputation against the cloud database
+ *
+ * This can be a synchronized API or a-synchronized API depends on the configuration from caller
+ *
+ * Synchronous mode
+ * In this synchronous operation mode, the function invokes TWPRequest::sendfunc and
+ * TWPRequest::receivefunc, one right after the other, expecting the entire HTTP
+ * transaction to be completed between the calls. Upon successful completion, the
+ * phResponse will point to a valid response handle that can be used to analyze results.
+ *
+ * Asynchronous mode
+ * In the asynchronous mode, the function invokes TWPRequest::sendfunc and returns
+ * immediately with TWP_SUCCESS. Upon completion, phResponse is NULL. The application
+ * is supposed to complete the HTTP transaction while calling TWPResponseWrite as
+ * response data becomes available. When all data was read, TWPResponseWrite must
+ * be called again with zero data length to signal the end transaction.
+ *
+ * \param[in] hConfigure Configuration of caller
+ * \param[in] pRequest Request data structure for SDK to check with cloud
+ * \param[in] iRedirUrl 1 indicating instruct the cloud server to provide a landing page
+ * URL to which blocked URLs can be redirected.
+ * \param[in] ppUrls An array of 7 bit ASCII character strings representing URLs to obtain
+ * the rating for.
+ *
+ * Note: All URLs have to be normalized before submission (see RFC 3986) and
+ * pynicoded if required.
+ * \param[in] uCount Length of the ppUrls array.
+ * \param[out] phResponse For synchronous requests, a pointer to the location where the
+ * response object handle will be stored upon completion. It can be NULL for
+ * asynchronous requests.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPLookupUrls(TWPLIB_HANDLE hLib, TWPConfigurationHandle hConfigure, TWPRequest *pRequest,
+ int iRedirUrl, const char **ppUrls, unsigned int uCount, TWPResponseHandle *phResponse);
+
+/**
+ * \brief
+ * In asynchronous mode, caller will call this API to write received HTTP response data
+ * to SDK. Writing with zero data length will be taken as end of HTTP transaction for
+ * SDK.
+ *
+ * This is a synchronized API
+ *
+ * \param[in] hResponse Response handle for SDK to keep track on HTTP transaction.
+ * \param[in] pData Received HTTP response data chunk.
+ * \param[in] uLength Length of the HTTP response data.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPResponseWrite(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, const void *pData, unsigned uLength);
+
+/**
+ * \brief
+ * Get web site rating by its index in URL list in the response which comply to
+ * the URL list order passed by caller in TWPLookupUrls().
+ *
+ * This is a synchronized API
+ *
+ * \param[in] hResponse Response handle created based on cloud response.
+ * \param[in] iIndex Index of the web site in request list.
+ * \param[out] phRating Rating of the specified web site.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPResponseGetUrlRatingByIndex(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, unsigned int uIndex,
+ TWPUrlRatingHandle *phRating);
+
+/**
+ * \brief
+ * Get web site rating by its URL string.
+ *
+ * This is a synchronized API
+ *
+ * \param[in] hResponse Response handle created based on cloud response.
+ * \param[in] pUrl URL string
+ * \param[in] iUrlLength URL string length
+ * \param[out] hRating Rating of the specified web site
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPResponseGetUrlRatingByUrl(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, const char *pUrl,
+ unsigned int uUrlLength, TWPUrlRatingHandle *hRating);
+
+/**
+ * \brief
+ * Get the redirection URL for blocked URL to display to user.
+ *
+ * Blocking pages can be used by application that want to block users
+ * from navigating to a URL that violates one of the defined policies.
+ * The returned string must be deallocated by the application using
+ * TWPAPIInit::TWPFnMemFree function.
+ *
+ * \param[in] hResponse Response handle created based on cloud response.
+ * \param[in] hRating Rating handle resolved from cloud response.
+ * \param[in] hPolicy Policy handle created by caller.
+ * \param[out] ppUrl Redirection URL.
+ * \param[ou] puLength Length of redirection URL
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPResponseGetRedirUrlFor(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, TWPUrlRatingHandle hRating,
+ TWPPolicyHandle hPolicy, char **ppUrl, unsigned int *puLength);
+
+/**
+ * \brief
+ * Get the rating count of specified response.
+ *
+ * \param[in] hResponse Response handle created based on cloud response.
+ * \param[out] puCount Rating count.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPResponseGetUrlRatingsCount(TWPLIB_HANDLE hLib, TWPResponseHandle hResponse, unsigned int *puCount);
+
+/**
+ * \brief
+ * Release resource for response handle.
+ *
+ * \param[in] hResponse Response handle created based on cloud response.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPResponseDestroy(TWPLIB_HANDLE hLib, TWPResponseHandle *hResponse);
+
+/**
+ * \brief
+ * Create the policy (set of web site categories) caller want to check.
+ *
+ * \param[in] hCfg configuration handle
+ * \param[in] pCategories Web site category list
+ * \param[in] uCount Category list length.
+ * \param[out] phPolicy Policy handle.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPPolicyCreate(TWPLIB_HANDLE hLib, TWPConfigurationHandle hCfg, TWPCategories *pCategories, unsigned int uCount, TWPPolicyHandle *hPolicy);
+
+/**
+ * \brief
+ * Compare the categories assigned by security vendor to the URL represented
+ * by hRating with the categories assigned to the policy handle.
+ *
+ * \param[in] hPolicy Polcy handle
+ * \param[in] hRating Rating for specific URL
+ * \param[out] piVialated non-zero if intersection found between the policy and URL rating categories.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPPolicyValidate(TWPLIB_HANDLE hLib, TWPPolicyHandle hPolicy, TWPUrlRatingHandle hRating, int *piViolated);
+
+/**
+ * \brief
+ * Retrieves all categories common between the policy and URL rating.
+ *
+ * \param[in] hPolicy Policy handle.
+ * \param[in] hRating URL rating handle.
+ * \param[out] ppViolated An array of all common categories. This array is allocated by using
+ * TWPAPIInit::memallocfunc and has to be deallocated by the caller.
+ * \param[out] puLength Length of violation array.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPPolicyGetViolations(TWPLIB_HANDLE hLib, TWPPolicyHandle hPolicy, TWPUrlRatingHandle hRating,
+ TWPCategories **ppViolated, unsigned *puLength);
+
+/**
+ * \brief
+ * Release resource for policy handle.
+ *
+ * \param[in] phPolicy Pointer to policy handle.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPPolicyDestroy(TWPLIB_HANDLE hLib, TWPPolicyHandle *hPolicy);
+
+/**
+ * \brief
+ * Get score from URL rating data structure which is assigned by security vendor.
+ *
+ * \param[in] hRating Rating handle.
+ * \param[out] piScore URL score.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPUrlRatingGetScore(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, int *piScore);
+
+/**
+ * \brief
+ * Get corresponding URL from rating handle.
+ *
+ * \param[in] hRating Rating handle.
+ * \param[out] ppUrl A pointer to a NULL terminated string representing
+ * the URL. The string is valid as long as the URL rating
+ * handle is valid.
+ * \param[out] puLength An optional pointer to the length of URL string.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPUrlRatingGetUrl(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, char **ppUrl,
+ unsigned int *puLength);
+
+/**
+ * \brief
+ * Get DLA (Deep Link Analysis) URL
+ *
+ * \param[in] hRating Rating handle.
+ * \param[out] ppDlaUrl A ponit to a NULL terminated string representing
+ * the DLA URL. This string is valid as long as the URL rating
+ * handle is valid.
+ * \param[out] puLength Length of DLA URL string.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPUrlRatingGetDLAUrl(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, char **ppDlaUrl,
+ unsigned int *puLength);
+
+/**
+ * \brief
+ * Determine whether the URL rating object has the specified category.
+ *
+ * \param[in] hRating Rating handle.
+ * \param[in] Category Category enum value.
+ * \param[out] piPresent Non-zero value indicating exists.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPUrlRatingHasCategory(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, TWPCategories Category,
+ int *piPresent);
+
+/**
+ * \brief
+ * Retrives categories assigned by security vendor for the rated URL.
+ *
+ * \param[in] hRating Rating handle.
+ * \param[out] ppCategories The pointer to a variable that contains the address
+ * of the category list.
+ * \param[out] puLength Length of category list.
+ *
+ * \return TWP_RESULT
+ */
+TWP_RESULT TWPUrlRatingGetCategories(TWPLIB_HANDLE hLib, TWPUrlRatingHandle hRating, TWPCategories **ppCategories,
+ unsigned int *puLength);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
--- /dev/null
+#
+# Copyright (c) 2013, McAfee, Inc.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this list
+# of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice, this
+# list of conditions and the following disclaimer in the documentation and/or other
+# materials provided with the distribution.
+#
+# Neither the name of McAfee, Inc. nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific prior
+# written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+OUTDIR=bin
+SRCDIR=.
+
+ifeq ($(TCS_CC), )
+ CC = gcc
+else
+ CC = $(TCS_CC)
+endif
+ifeq ($(TCS_LD), )
+ LD = gcc
+else
+ LD = $(TCS_LD)
+endif
+
+TCS_HEADER_FILE_PATH=../../framework
+
+CFLAGS := $(CFLAGS) -fPIC -g -Wall -O3 -I$(SRCDIR)/port -I$(SRCDIR)/tests -I$(TCS_HEADER_FILE_PATH)
+ifeq ($(LD_FLAGS), )
+LDFLAGS= $(LD_FLAGS) -lc -pthread -L../../framework/lib -lsecfw -ldl
+else
+LDFLAGS= $(LD_FLAGS) -lc -L../../framework/lib -lsecfw -ldl
+endif
+
+TARGET=$(OUTDIR)/tcstest
+
+SOURCES=$(SRCDIR)/TCSTest.c \
+ $(SRCDIR)/TCSTestUtils.c \
+ $(SRCDIR)/SampleInfo.c
+OBJECTS=$(OUTDIR)/TCSTest.o \
+ $(OUTDIR)/TCSTestUtils.o \
+ $(OUTDIR)/SampleInfo.o
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c
+ $(CC) $(CFLAGS) -o $(OUTDIR)/$*.o -c $(SRCDIR)/$*.c
+
+$(TARGET): $(OUTDIR) $(OBJECTS) $(SOURCES)
+ $(LD) -o $(TARGET) $(OBJECTS) $(LDFLAGS)
+
+all: $(TARGET)
+
+$(OUTDIR):
+ @mkdir $(OUTDIR)
+
+clean:
+ @rm -rf $(OUTDIR)
+
+distclean: clean
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "stdlib.h"
+#include "TCSTest.h"
+#include "TCSImpl.h"
+
+#include "SampleInfo.h"
+
+
+/*
+ * Maximum sample file name length.
+ */
+#define MAX_SAMPLE_NAME_LEN 128
+
+#define MAX_INFECTED_NUM 3
+
+
+typedef struct SampleInfo_struct
+{
+ enum ENUM_MALWARE_TEST_TYPES eTestType;
+ char szName[TCS_MAX_MALWARE_NAME_LEN];
+ char szVariant[TCS_MAX_MALWARE_NAME_LEN];
+ unsigned int uSeverity;
+ unsigned int uBehavior;
+ unsigned int uType;
+ char szInfectedFileName[MAX_SAMPLE_NAME_LEN];
+ char szBenignFileName[MAX_SAMPLE_NAME_LEN];
+} SampleInfo;
+
+
+static SampleInfo Samples[][MAX_INFECTED_NUM] =
+{
+ {
+ {
+ MALWARE_TTYPE_BUFFER,
+ BUFFER_MALWARE_NAME,
+ BUFFER_VARIANT_NAME,
+ BUFFER_SEVERITY_CLASS,
+ BUFFER_BEHAVIOR_CLASS,
+ BUFFER_MALWARE_TYPE,
+ BUFFER_FILE_NAME_1,
+ BUFFER_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ },
+ {
+ {
+ MALWARE_TTYPE_HTML,
+ HTML_MALWARE_NAME,
+ HTML_VARIANT_NAME,
+ HTML_SEVERITY_CLASS,
+ HTML_BEHAVIOR_CLASS,
+ HTML_MALWARE_TYPE,
+ HTML_FILE_NAME_1,
+ HTML_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ },
+ {
+ {
+ MALWARE_TTYPE_URL,
+ URL_MALWARE_NAME,
+ URL_VARIANT_NAME,
+ URL_SEVERITY_CLASS,
+ URL_BEHAVIOR_CLASS,
+ URL_MALWARE_TYPE,
+ URL_FILE_NAME_1,
+ URL_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ },
+ {
+ {
+ MALWARE_TTYPE_EMAIL,
+ EMAIL_MALWARE_NAME,
+ EMAIL_VARIANT_NAME,
+ EMAIL_SEVERITY_CLASS,
+ EMAIL_BEHAVIOR_CLASS,
+ EMAIL_MALWARE_TYPE,
+ EMAIL_FILE_NAME_1,
+ EMAIL_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ },
+ {
+ {
+ MALWARE_TTYPE_PHONE,
+ PHONE_MALWARE_NAME,
+ PHONE_VARIANT_NAME,
+ PHONE_SEVERITY_CLASS,
+ PHONE_BEHAVIOR_CLASS,
+ PHONE_MALWARE_TYPE,
+ PHONE_FILE_NAME_1,
+ PHONE_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ },
+ {
+ {
+ MALWARE_TTYPE_TEXT,
+ TEXT_MALWARE_NAME,
+ TEXT_VARIANT_NAME,
+ TEXT_SEVERITY_CLASS,
+ TEXT_BEHAVIOR_CLASS,
+ TEXT_MALWARE_TYPE,
+ TEXT_FILE_NAME_1,
+ TEXT_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ },
+ {
+ {
+ MALWARE_TTYPE_JAVA,
+ JAVA_MALWARE_NAME,
+ JAVA_VARIANT_NAME,
+ JAVA_SEVERITY_CLASS,
+ JAVA_BEHAVIOR_CLASS,
+ JAVA_MALWARE_TYPE,
+ JAVA_FILE_NAME_1,
+ JAVA_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ },
+ {
+ {
+ MALWARE_TTYPE_MULTIPLE,
+ MULTIPLE0_MALWARE_NAME,
+ MULTIPLE0_VARIANT_NAME,
+ MULTIPLE0_SEVERITY_CLASS,
+ MULTIPLE0_BEHAVIOR_CLASS,
+ MULTIPLE0_MALWARE_TYPE,
+ MULTIPLE0_FILE_NAME_1,
+ MULTIPLE0_FILE_NAME_0
+ },
+ {
+ MALWARE_TTYPE_MULTIPLE,
+ MULTIPLE1_MALWARE_NAME,
+ MULTIPLE1_VARIANT_NAME,
+ MULTIPLE1_SEVERITY_CLASS,
+ MULTIPLE1_BEHAVIOR_CLASS,
+ MULTIPLE1_MALWARE_TYPE,
+ MULTIPLE1_FILE_NAME_1,
+ MULTIPLE1_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ },
+ {
+ {
+ MALWARE_TTYPE_JAVAS,
+ JAVAS_MALWARE_NAME,
+ JAVAS_VARIANT_NAME,
+ JAVAS_SEVERITY_CLASS,
+ JAVAS_BEHAVIOR_CLASS,
+ JAVAS_MALWARE_TYPE,
+ JAVAS_FILE_NAME_1,
+ JAVAS_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ },
+ {
+ {
+ MALWARE_TTYPE_COMPRESS,
+ COMPRESS_MALWARE_NAME,
+ COMPRESS_VARIANT_NAME,
+ COMPRESS_SEVERITY_CLASS,
+ COMPRESS_BEHAVIOR_CLASS,
+ COMPRESS_MALWARE_TYPE,
+ COMPRESS_FILE_NAME_1,
+ COMPRESS_FILE_NAME_0
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ },
+ {
+ -1, "", "", 0, 0, 0, "", ""
+ }
+ }
+};
+
+
+static SampleInfo *SampleGetInfo(int iType, int iIndex)
+{
+ int i;
+ int n = (int) (sizeof(Samples) / (sizeof(SampleInfo) * MAX_INFECTED_NUM));
+
+ for (i = 0; i < n; i++)
+ {
+ if (Samples[i][0].eTestType == iType)
+ return &Samples[i][iIndex];
+ }
+
+ return NULL;
+}
+
+
+const char *SampleGetMalName(int iType, int iIndex)
+{
+
+ return SampleGetInfo(iType, iIndex)->szName;
+}
+
+
+const char *SampleGetVarName(int iType, int iIndex)
+{
+
+ return SampleGetInfo(iType, iIndex)->szVariant;
+}
+
+
+unsigned int SampleGetSeverity(int iType, int iIndex)
+{
+
+ return SampleGetInfo(iType, iIndex)->uSeverity;
+}
+
+
+unsigned int SampleGetMalType(int iType, int iIndex)
+{
+
+ return SampleGetInfo(iType, iIndex)->uType;
+}
+
+
+unsigned int SampleGetBehavior(int iType, int iIndex)
+{
+
+ return SampleGetInfo(iType, iIndex)->uBehavior;
+}
+
+
+const char *SampleGetInfectedFileName(int iType)
+{
+
+ return SampleGetInfo(iType, 0)->szInfectedFileName;
+}
+
+
+const char *SampleGetBenignFileName(int iType)
+{
+
+ return SampleGetInfo(iType, 0)->szBenignFileName;
+}
+
+
+int SampleGetCount(int iType)
+{
+ int i = 0;
+
+ while (SampleGetInfo(iType, i)->eTestType == iType)
+ i++;
+
+ return i;
+}
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef SAMPLE_INFO_H
+#define SAMPLE_INFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TCS_MAX_MALWARE_NAME_LEN 64
+
+#define MALWARE_1_0_0 "Malware-fortest-1.0.0"
+#define MALWARE_1_1_0 "Malware-fortest-1.1.0"
+#define MALWARE_1_2_0 "Malware-fortest-1.2.0"
+#define MALWARE_1_3_0 "Malware-fortest-1.3.0"
+#define MALWARE_1_4_0 "Malware-fortest-1.4.0"
+#define MALWARE_1_5_0 "Malware-fortest-1.5.0"
+#define MALWARE_1_6_0 "Malware-fortest-1.6.0"
+#define MALWARE_1_7_0 "Malware-fortest-1.7.0"
+#define MALWARE_1_8_0 "Malware-fortest-1.8.0"
+#define MALWARE_1_9_0 "Malware-fortest-1.9.0"
+
+#define VARIANT_1_0_0 "Variant-fortest-1.0.0"
+#define VARIANT_1_1_0 "Variant-fortest-1.1.0"
+#define VARIANT_1_2_0 "Variant-fortest-1.2.0"
+#define VARIANT_1_3_0 "Variant-fortest-1.3.0"
+#define VARIANT_1_4_0 "Variant-fortest-1.4.0"
+#define VARIANT_1_5_0 "Variant-fortest-1.5.0"
+#define VARIANT_1_6_0 "Variant-fortest-1.6.0"
+#define VARIANT_1_7_0 "Variant-fortest-1.7.0"
+#define VARIANT_1_8_0 "Variant-fortest-1.8.0"
+#define VARIANT_1_9_0 "Variant-fortest-1.9.0"
+
+#define BUFFER_MALWARE_NAME MALWARE_1_6_0
+#define BUFFER_VARIANT_NAME VARIANT_1_6_0
+#define BUFFER_SEVERITY_CLASS TCS_SC_USER
+#define BUFFER_BEHAVIOR_CLASS TCS_BC_LEVEL1
+#define BUFFER_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define BUFFER_FILE_NAME_1 "tcs-testfile-1.buf"
+#define BUFFER_FILE_NAME_0 "tcs-testfile-0.buf"
+
+#define HTML_MALWARE_NAME MALWARE_1_0_0
+#define HTML_VARIANT_NAME VARIANT_1_0_0
+#define HTML_SEVERITY_CLASS TCS_SC_USER
+#define HTML_BEHAVIOR_CLASS TCS_BC_LEVEL0
+#define HTML_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define HTML_FILE_NAME_1 "tcs-testfile-1.html"
+#define HTML_FILE_NAME_0 "tcs-testfile-0.html"
+
+#define URL_MALWARE_NAME MALWARE_1_1_0
+#define URL_VARIANT_NAME VARIANT_1_1_0
+#define URL_SEVERITY_CLASS TCS_SC_USER
+#define URL_BEHAVIOR_CLASS TCS_BC_LEVEL1
+#define URL_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define URL_FILE_NAME_1 "tcs-testfile-1.url"
+#define URL_FILE_NAME_0 "tcs-testfile-0.url"
+
+#define EMAIL_MALWARE_NAME MALWARE_1_2_0
+#define EMAIL_VARIANT_NAME VARIANT_1_2_0
+#define EMAIL_SEVERITY_CLASS TCS_SC_TERMINAL
+#define EMAIL_BEHAVIOR_CLASS TCS_BC_LEVEL2
+#define EMAIL_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define EMAIL_FILE_NAME_1 "tcs-testfile-1.email"
+#define EMAIL_FILE_NAME_0 "tcs-testfile-0.email"
+
+#define PHONE_MALWARE_NAME MALWARE_1_3_0
+#define PHONE_VARIANT_NAME VARIANT_1_3_0
+#define PHONE_SEVERITY_CLASS TCS_SC_TERMINAL
+#define PHONE_BEHAVIOR_CLASS TCS_BC_LEVEL3
+#define PHONE_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define PHONE_FILE_NAME_1 "tcs-testfile-1.phone"
+#define PHONE_FILE_NAME_0 "tcs-testfile-0.phone"
+
+#define TEXT_MALWARE_NAME MALWARE_1_4_0
+#define TEXT_VARIANT_NAME VARIANT_1_4_0
+#define TEXT_SEVERITY_CLASS TCS_SC_TERMINAL
+#define TEXT_BEHAVIOR_CLASS TCS_BC_LEVEL4
+#define TEXT_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define TEXT_FILE_NAME_1 "tcs-testfile-1.txt"
+#define TEXT_FILE_NAME_0 "tcs-testfile-0.txt"
+
+#define JAVA_MALWARE_NAME MALWARE_1_7_0
+#define JAVA_VARIANT_NAME VARIANT_1_7_0
+#define JAVA_SEVERITY_CLASS TCS_SC_USER
+#define JAVA_BEHAVIOR_CLASS TCS_BC_LEVEL0
+#define JAVA_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define JAVA_FILE_NAME_1 "tcs-testfile-1.class"
+#define JAVA_FILE_NAME_0 "tcs-testfile-0.class"
+
+#define MULTIPLE0_MALWARE_NAME MALWARE_1_5_0
+#define MULTIPLE0_VARIANT_NAME VARIANT_1_5_0
+#define MULTIPLE0_SEVERITY_CLASS TCS_SC_USER
+#define MULTIPLE0_BEHAVIOR_CLASS TCS_BC_LEVEL0
+#define MULTIPLE0_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define MULTIPLE0_FILE_NAME_1 "tcs-testfile-1.multiple"
+#define MULTIPLE0_FILE_NAME_0 "tcs-testfile-0.multiple"
+
+#define MULTIPLE1_MALWARE_NAME MALWARE_1_6_0
+#define MULTIPLE1_VARIANT_NAME VARIANT_1_6_0
+#define MULTIPLE1_SEVERITY_CLASS TCS_SC_USER
+#define MULTIPLE1_BEHAVIOR_CLASS TCS_BC_LEVEL1
+#define MULTIPLE1_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define MULTIPLE1_FILE_NAME_1 "tcs-testfile-1.multiple"
+#define MULTIPLE1_FILE_NAME_0 "tcs-testfile-0.multiple"
+
+#define JAVAS_MALWARE_NAME MALWARE_1_8_0
+#define JAVAS_VARIANT_NAME VARIANT_1_8_0
+#define JAVAS_SEVERITY_CLASS TCS_SC_USER
+#define JAVAS_BEHAVIOR_CLASS TCS_BC_LEVEL2
+#define JAVAS_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define JAVAS_FILE_NAME_1 "tcs-testfile-1.js"
+#define JAVAS_FILE_NAME_0 "tcs-testfile-0.js"
+
+#define COMPRESS_MALWARE_NAME MALWARE_1_9_0
+#define COMPRESS_VARIANT_NAME VARIANT_1_9_0
+#define COMPRESS_SEVERITY_CLASS TCS_SC_USER
+#define COMPRESS_BEHAVIOR_CLASS TCS_BC_LEVEL2
+#define COMPRESS_MALWARE_TYPE TCS_VTYPE_MALWARE
+#define COMPRESS_FILE_NAME_1 "tcs-testfile-1.z"
+#define COMPRESS_FILE_NAME_0 "tcs-testfile-0.z"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SAMPLE_INFO_H */
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+#include "TCSImpl.h"
+#include "TCSErrorCodes.h"
+
+#include "TCSTest.h"
+
+
+/* Test cases. */
+static void TCSStartup(void);
+static void TCSCleanup(void);
+static void TCSLibraryOpen_0001(void);
+static void TCSLibraryOpen_0002(void);
+static void TCSLibraryOpen_0003(void);
+static void TCSLibraryOpen_0004(void);
+static void TCSGetLastError_0001(void);
+static void TCSLibraryClose_0001(void);
+
+static void TCSScanData_0001(void);
+static void TCSScanData_0002(void);
+static void TCSScanData_0003(void);
+static void TCSScanData_0004(void);
+static void TCSScanData_0005(void);
+static void TCSScanData_0006(void);
+static void TCSScanData_0007(void);
+static void TCSScanData_0008(void);
+static void TCSScanData_0009(void);
+static void TCSScanData_0010(void);
+static void TCSScanData_0011(void);
+static void TCSScanData_0012(void);
+static void TCSScanData_0013(void);
+static void TCSScanData_0014(void);
+static void TCSScanData_0015(void);
+static void TCSScanData_0016(void);
+static void TCSScanData_0017(void);
+static void TCSScanData_0018(void);
+static void TCSScanData_0019(void);
+static void TCSScanData_0020(void);
+static void TCSScanData_0021(void);
+static void TCSScanData_0022(void);
+static void TCSScanData_0023(void);
+static void TCSScanData_0024(void);
+static void TCSScanData_0025(void);
+static void TCSScanData_0026(void);
+static void TCSScanData_0027(void);
+static void TCSScanData_0028(void);
+static void TCSScanData_0029(void);
+static void TCSScanData_0030(void);
+static void TCSScanData_0031(void);
+static void TCSScanData_0032(void);
+static void TCSScanData_0033(void);
+static void TCSScanData_0034(void);
+static void TCSScanData_0035(void);
+static void TCSScanData_0036(void);
+static void TCSScanData_0037(void);
+static void TCSScanData_0038(void);
+static void TCSScanData_0039(void);
+static void TCSScanData_0040(void);
+static void TCSScanData_0041(void);
+static void TCSScanData_0042(void);
+static void TCSScanData_0043(void);
+static void TCSScanData_0044(void);
+static void TCSScanData_0045(void);
+static void TCSScanData_0046(void);
+static void TCSScanData_0047(void);
+static void TCSScanData_0048(void);
+static void TCSScanData_0049(void);
+static void TCSScanData_0050(void);
+static void TCSScanData_0051(void);
+static void TCSScanData_0052(void);
+
+static void TCSScanFile_0001(void);
+static void TCSScanFile_0002(void);
+static void TCSScanFile_0003(void);
+static void TCSScanFile_0004(void);
+static void TCSScanFile_0005(void);
+static void TCSScanFile_0006(void);
+static void TCSScanFile_0007(void);
+static void TCSScanFile_0008(void);
+static void TCSScanFile_0009(void);
+static void TCSScanFile_0010(void);
+static void TCSScanFile_0011(void);
+static void TCSScanFile_0012(void);
+static void TCSScanFile_0013(void);
+static void TCSScanFile_0014(void);
+static void TCSScanFile_0015(void);
+static void TCSScanFile_0016(void);
+static void TCSScanFile_0017(void);
+static void TCSScanFile_0018(void);
+static void TCSScanFile_0019(void);
+static void TCSScanFile_0020(void);
+static void TCSScanFile_0021(void);
+static void TCSScanFile_0022(void);
+static void TCSScanFile_0023(void);
+static void TCSScanFile_0024(void);
+static void TCSScanFile_0025(void);
+static void TCSScanFile_0026(void);
+static void TCSScanFile_0027(void);
+static void TCSScanFile_0028(void);
+static void TCSScanFile_0029(void);
+static void TCSScanFile_0030(void);
+static void TCSScanFile_0031(void);
+static void TCSScanFile_0032(void);
+static void TCSScanFile_0033(void);
+static void TCSScanFile_0034(void);
+
+static void TestCases(void);
+
+
+extern int TestCasesCount;
+extern int Success;
+extern int Failures;
+
+
+int main(int argc, char **argv)
+{
+
+ TCSStartup();
+ TestCases();
+ TCSCleanup();
+
+ return 0;
+}
+
+
+static void TestCases(void)
+{
+ TCSLibraryOpen_0001();
+ TCSLibraryOpen_0002();
+ TCSLibraryOpen_0003();
+ TCSLibraryOpen_0004();
+
+ TCSGetLastError_0001();
+
+ TCSLibraryClose_0001();
+
+ TCSScanData_0001();
+ TCSScanData_0002();
+ TCSScanData_0003();
+ TCSScanData_0004();
+ TCSScanData_0005();
+ TCSScanData_0006();
+ TCSScanData_0007();
+ TCSScanData_0008();
+ TCSScanData_0009();
+ TCSScanData_0010();
+ TCSScanData_0011();
+ TCSScanData_0012();
+ TCSScanData_0013();
+ TCSScanData_0014();
+ TCSScanData_0015();
+ TCSScanData_0016();
+ TCSScanData_0017();
+ TCSScanData_0018();
+ TCSScanData_0019();
+ TCSScanData_0020();
+ TCSScanData_0021();
+ TCSScanData_0022();
+ TCSScanData_0023();
+ TCSScanData_0024();
+ TCSScanData_0025();
+ TCSScanData_0026();
+ TCSScanData_0027();
+ TCSScanData_0028();
+ TCSScanData_0029();
+ TCSScanData_0030();
+ TCSScanData_0031();
+ TCSScanData_0032();
+ TCSScanData_0033();
+ TCSScanData_0034();
+ TCSScanData_0035();
+ TCSScanData_0036();
+ TCSScanData_0037();
+ TCSScanData_0038();
+ TCSScanData_0039();
+ TCSScanData_0040();
+ TCSScanData_0041();
+ TCSScanData_0042();
+ TCSScanData_0043();
+ TCSScanData_0044();
+ TCSScanData_0045();
+ TCSScanData_0046();
+ TCSScanData_0047();
+ TCSScanData_0048();
+ TCSScanData_0049();
+ TCSScanData_0050();
+ TCSScanData_0051();
+ TCSScanData_0052();
+
+ TCSScanFile_0001();
+ TCSScanFile_0002();
+ TCSScanFile_0003();
+ TCSScanFile_0004();
+ TCSScanFile_0005();
+ TCSScanFile_0006();
+ TCSScanFile_0007();
+ TCSScanFile_0008();
+ TCSScanFile_0009();
+ TCSScanFile_0010();
+ TCSScanFile_0011();
+ TCSScanFile_0012();
+ TCSScanFile_0013();
+ TCSScanFile_0014();
+ TCSScanFile_0015();
+ TCSScanFile_0016();
+ TCSScanFile_0017();
+ TCSScanFile_0018();
+ TCSScanFile_0019();
+ TCSScanFile_0020();
+ TCSScanFile_0021();
+ TCSScanFile_0022();
+ TCSScanFile_0023();
+ TCSScanFile_0024();
+ TCSScanFile_0025();
+ TCSScanFile_0026();
+ TCSScanFile_0027();
+ TCSScanFile_0028();
+ TCSScanFile_0029();
+ TCSScanFile_0030();
+ TCSScanFile_0031();
+ TCSScanFile_0032();
+ TCSScanFile_0033();
+ TCSScanFile_0034();
+}
+
+
+static void TCSLibraryOpen_0001(void)
+{
+ TestCase TestCtx;
+ TCSLIB_HANDLE hLib;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ TEST_ASSERT((hLib = TCSLibraryOpen()) != INVALID_TCSLIB_HANDLE);
+ TESTCASEDTOR(&TestCtx);
+ TCSLibraryClose(hLib);
+}
+
+
+static void TCSLibraryOpen_0002(void)
+{
+ int iErr;
+ TestCase TestCtx;
+ TCSLIB_HANDLE hLib;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+
+ BackupEngine();
+ system("rm -f /opt/usr/share/sec_plugin/libengine.so");
+
+ TEST_ASSERT((hLib = TCSLibraryOpen()) == INVALID_TCSLIB_HANDLE);
+ iErr = TCSGetLastError(hLib);
+ TEST_ASSERT(TCS_ERRMODULE(iErr) == TCS_ERROR_MODULE_GENERIC);
+ TEST_ASSERT(TCS_ERRCODE(iErr) == TCS_ERROR_NOT_IMPLEMENTED);
+ TESTCASEDTOR(&TestCtx);
+
+ RestoreEngine();
+}
+
+
+static void TCSGetLastError_0001(void)
+{
+ int iErr;
+ TestCase TestCtx;
+
+ BackupEngine();
+ system("rm -f /opt/usr/share/sec_plugin/libengine.so");
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ iErr = TCSGetLastError(INVALID_TCSLIB_HANDLE);
+ TEST_ASSERT(TCS_ERRMODULE(iErr) == TCS_ERROR_MODULE_GENERIC);
+ TEST_ASSERT(TCS_ERRCODE(iErr) == TCS_ERROR_NOT_IMPLEMENTED);
+ TESTCASEDTOR(&TestCtx);
+
+ RestoreEngine();
+}
+
+
+static void TCSScanData_0052(void)
+{
+ TestCase TestCtx;
+ TCSScanParam SP = {0};
+ TCSScanResult SR= {0};
+
+ BackupEngine();
+ system("rm -f /opt/usr/share/sec_plugin/libengine.so");
+
+ SP.iAction = TCS_SA_SCANONLY;
+ SP.iDataType = TCS_DTYPE_UNKNOWN;
+ SP.iCompressFlag = 1;
+ SP.pPrivate = NULL;
+ SP.pfGetSize = NULL;
+ SP.pfSetSize = NULL;
+ SP.pfRead = NULL;
+ SP.pfWrite = NULL;
+ SP.pfCallBack = NULL;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ TEST_ASSERT(TCSScanData(INVALID_TCSLIB_HANDLE, &SP, &SR) == -1);
+ TESTCASEDTOR(&TestCtx);
+
+ RestoreEngine();
+}
+
+
+static void TCSScanFile_0034(void)
+{
+ TestCase TestCtx;
+ TCSScanResult SR = {0};
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ TEST_ASSERT(TCSScanFile(INVALID_TCSLIB_HANDLE, "file",
+ TCS_DTYPE_UNKNOWN, TCS_SA_SCANONLY, 1, &SR) == -1);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TCSLibraryClose_0001(void)
+{
+ TestCase TestCtx;
+ TCSLIB_HANDLE hLib;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ TEST_ASSERT((hLib = TCSLibraryOpen()) != INVALID_TCSLIB_HANDLE)
+ TEST_ASSERT(TCSLibraryClose(hLib) == 0);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TCSScanData_0001(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_BUFFER, BENIGN_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0002(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_BUFFER, BENIGN_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0003(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_BUFFER, INFECTED_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0004(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_BUFFER, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0005(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_HTML, BENIGN_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0006(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_HTML, BENIGN_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0007(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_HTML, INFECTED_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0008(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_HTML, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0009(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_URL, BENIGN_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0010(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_URL, BENIGN_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0011(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_URL, INFECTED_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0012(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_URL, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0013(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_EMAIL, BENIGN_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0014(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_EMAIL, BENIGN_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0015(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_EMAIL, INFECTED_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0016(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_EMAIL, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0017(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_PHONE, BENIGN_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0018(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_PHONE, BENIGN_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0019(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_PHONE, INFECTED_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0020(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_PHONE, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0021(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_JAVA, BENIGN_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0022(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_JAVA, BENIGN_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0023(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_JAVA, INFECTED_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0024(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_JAVA, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0025(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_JAVAS, BENIGN_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0026(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_JAVAS, BENIGN_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0027(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_JAVAS, INFECTED_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0028(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_JAVAS, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0029(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_TEXT, BENIGN_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0030(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_TEXT, BENIGN_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0031(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_TEXT, INFECTED_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0032(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_TEXT, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0033(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_MULTIPLE, INFECTED_DATA,
+ TCS_SA_SCANONLY, NULL);
+}
+
+
+static void TCSScanData_0034(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_MULTIPLE, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbScanCallback);
+}
+
+
+static void TCSScanData_0035(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_BUFFER, INFECTED_DATA,
+ TCS_SA_SCANREPAIR, &CbScanCallback);
+}
+
+
+static void TCSScanData_0036(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_HTML, INFECTED_DATA,
+ TCS_SA_SCANREPAIR, &CbScanCallback);
+}
+
+
+static void TCSScanData_0037(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_URL, INFECTED_DATA,
+ TCS_SA_SCANREPAIR, &CbScanCallback);
+}
+
+
+static void TCSScanData_0038(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_EMAIL, INFECTED_DATA,
+ TCS_SA_SCANREPAIR, &CbScanCallback);
+}
+
+
+static void TCSScanData_0039(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_PHONE, INFECTED_DATA,
+ TCS_SA_SCANREPAIR, &CbScanCallback);
+}
+
+
+static void TCSScanData_0040(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_JAVA, INFECTED_DATA,
+ TCS_SA_SCANREPAIR, &CbScanCallback);
+}
+
+
+static void TCSScanData_0041(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_TEXT, INFECTED_DATA,
+ TCS_SA_SCANREPAIR, &CbScanCallback);
+}
+
+
+static void TCSScanData_0042(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_MULTIPLE, INFECTED_DATA,
+ TCS_SA_SCANREPAIR, &CbScanCallback);
+}
+
+
+static void TCSScanData_0043(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_BUFFER, INFECTED_DATA,
+ TCS_SA_SCANONLY, &CbAbortCallback);
+}
+
+
+static void TCSScanData_0044(void)
+{
+
+ TestScanData(__FUNCTION__, MALWARE_TTYPE_BUFFER, INFECTED_DATA,
+ TCS_SA_SCANREPAIR, &CbScanCallback);
+}
+
+
+static void TCSScanData_0045(void)
+{
+ TestCase TestCtx;
+ TCSScanParam SP = {0};
+ TCSScanResult SR= {0};
+
+ SP.iAction = TCS_SA_SCANONLY;
+ SP.iDataType = TCS_DTYPE_UNKNOWN;
+ SP.iCompressFlag = 1;
+ SP.pPrivate = NULL;
+ SP.pfGetSize = NULL;
+ SP.pfSetSize = NULL;
+ SP.pfRead = NULL;
+ SP.pfWrite = NULL;
+ SP.pfCallBack = NULL;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ TEST_ASSERT(TCSScanData(INVALID_TCSLIB_HANDLE, &SP, &SR) == -1);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TCSScanData_0046(void)
+{
+ TestCase TestCtx;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ ConScanData(&TestCtx, TCS_SA_SCANONLY);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TCSScanData_0047(void)
+{
+ TestCase TestCtx;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ ConScanData(&TestCtx, TCS_SA_SCANREPAIR);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TCSScanData_0048(void)
+{
+
+ TestScanDataEx(__FUNCTION__, MALWARE_TTYPE_COMPRESS, BENIGN_DATA,
+ TCS_SA_SCANONLY, 1, &CbScanCallback);
+}
+
+
+static void TCSScanData_0049(void)
+{
+
+ TestScanDataEx(__FUNCTION__, MALWARE_TTYPE_COMPRESS, BENIGN_DATA,
+ TCS_SA_SCANONLY, 0, &CbScanCallback);
+}
+
+
+static void TCSScanData_0050(void)
+{
+
+ TestScanDataEx(__FUNCTION__, MALWARE_TTYPE_COMPRESS, INFECTED_DATA,
+ TCS_SA_SCANONLY, 1, &CbScanCallback);
+}
+
+
+static void TCSScanData_0051(void)
+{
+
+ TestScanDataEx(__FUNCTION__, MALWARE_TTYPE_COMPRESS, INFECTED_DATA,
+ TCS_SA_SCANONLY, 0, &CbScanCallback);
+}
+
+
+static void TCSScanFile_0001(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_BUFFER, BENIGN_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0002(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_BUFFER, INFECTED_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0003(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_HTML, BENIGN_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0004(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_HTML, INFECTED_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0005(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_URL, BENIGN_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0006(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_URL, INFECTED_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0007(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_EMAIL, BENIGN_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0008(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_EMAIL, INFECTED_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0009(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_PHONE, BENIGN_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0010(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_PHONE, INFECTED_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0011(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_JAVA, BENIGN_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0012(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_JAVA, INFECTED_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0013(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_TEXT, BENIGN_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0014(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_TEXT, INFECTED_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0015(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_MULTIPLE, INFECTED_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0016(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_BUFFER, INFECTED_DATA, TCS_SA_SCANREPAIR);
+}
+
+
+static void TCSScanFile_0017(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_HTML, INFECTED_DATA, TCS_SA_SCANREPAIR);
+}
+
+
+static void TCSScanFile_0018(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_URL, INFECTED_DATA, TCS_SA_SCANREPAIR);
+}
+
+
+static void TCSScanFile_0019(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_EMAIL, INFECTED_DATA, TCS_SA_SCANREPAIR);
+}
+
+
+static void TCSScanFile_0020(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_PHONE, INFECTED_DATA, TCS_SA_SCANREPAIR);
+}
+
+
+static void TCSScanFile_0021(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_JAVA, INFECTED_DATA, TCS_SA_SCANREPAIR);
+}
+
+
+static void TCSScanFile_0022(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_TEXT, INFECTED_DATA, TCS_SA_SCANREPAIR);
+}
+
+
+static void TCSScanFile_0023(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_MULTIPLE, INFECTED_DATA,
+ TCS_SA_SCANREPAIR);
+}
+
+
+static void TCSScanFile_0024(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_BUFFER, INFECTED_DATA, TCS_SA_SCANREPAIR);
+}
+
+
+static void TCSScanFile_0025(void)
+{
+ TestCase TestCtx;
+ TCSScanResult SR = {0};
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ TEST_ASSERT(TCSScanFile(INVALID_TCSLIB_HANDLE, "file",
+ TCS_DTYPE_UNKNOWN, TCS_SA_SCANONLY, 1, &SR) == -1);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TCSScanFile_0026(void)
+{
+ TestCase TestCtx;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ ConScanFile(&TestCtx, TCS_SA_SCANONLY);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TCSScanFile_0027(void)
+{
+ TestCase TestCtx;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ ConScanFile(&TestCtx, TCS_SA_SCANREPAIR);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TCSScanFile_0028(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_JAVAS, BENIGN_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0029(void)
+{
+
+ TestScanFile(__FUNCTION__, MALWARE_TTYPE_JAVAS, INFECTED_DATA, TCS_SA_SCANONLY);
+}
+
+
+static void TCSScanFile_0030(void)
+{
+
+ TestScanFileEx(__FUNCTION__, MALWARE_TTYPE_COMPRESS, BENIGN_DATA, TCS_SA_SCANONLY, 1);
+}
+
+
+static void TCSScanFile_0031(void)
+{
+
+ TestScanFileEx(__FUNCTION__, MALWARE_TTYPE_COMPRESS, INFECTED_DATA, TCS_SA_SCANONLY, 1);
+}
+
+
+static void TCSScanFile_0032(void)
+{
+
+ TestScanFileEx(__FUNCTION__, MALWARE_TTYPE_COMPRESS, BENIGN_DATA, TCS_SA_SCANONLY, 0);
+}
+
+
+static void TCSScanFile_0033(void)
+{
+
+ TestScanFileEx(__FUNCTION__, MALWARE_TTYPE_COMPRESS, INFECTED_DATA, TCS_SA_SCANONLY, 0);
+}
+
+
+static void TCSStartup(void)
+{
+ extern int TestCasesCount;
+ extern int Success;
+ extern int Failures;
+
+ TestCasesCount = 0;
+ Success = 0;
+ Failures = 0;
+ CreateTestDirs();
+}
+
+
+static void TCSCleanup(void)
+{
+ LOG_OUT("@@@@@@@@@@@@@@@@@@@@@@@@\n");
+ LOG_OUT("Test done: %d executed, %d passed, %d failure\n", TestCasesCount, Success, Failures);
+ DestoryTestDirs();
+}
+
+
+static void TCSLibraryOpen_0003(void)
+{
+ TCSLIB_HANDLE hLib = INVALID_TCSLIB_HANDLE;
+ TestCase TestCtx;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+ /* pre-condition is stub library */
+ BackupEngine();
+ system("rm -f /opt/usr/share/sec_plugin/libengine.so");
+
+ TEST_ASSERT((hLib = TCSLibraryOpen()) == INVALID_TCSLIB_HANDLE);
+ RestoreEngine();
+
+ TEST_ASSERT((hLib = TCSLibraryOpen()) != INVALID_TCSLIB_HANDLE);
+ TCSLibraryClose(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TCSLibraryOpen_0004(void)
+{
+ TCSLIB_HANDLE hLib = INVALID_TCSLIB_HANDLE;
+ TestCase TestCtx;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__, 0, 0, 0, NULL);
+
+ TEST_ASSERT((hLib = TCSLibraryOpen()) != INVALID_TCSLIB_HANDLE);
+
+ BackupEngine();
+ system("rm -f /opt/usr/share/sec_plugin/libengine.so");
+ TCSLibraryClose(hLib);
+
+ TEST_ASSERT((hLib = TCSLibraryOpen()) == INVALID_TCSLIB_HANDLE);
+
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
--- /dev/null
+#ifndef TCSTEST_H
+#define TCSTEST_H
+
+
+#include <setjmp.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TEST_SUITE_VERSION "0.0.1"
+
+/* Immediate value definitions. */
+#define MAX_TEST_NUM 128
+
+/* Test content polarities */
+#define BENIGN_DATA 0
+#define INFECTED_DATA 1
+
+/* Maximum CS API name length. */
+#define MAX_TCS_API_NAME_LEN 128
+
+/* Content backup directory before repairing test. */
+#define TCS_BACKUP_CONTENT_DIR "contents_bak"
+
+/* Content directory for testing. */
+#define TCS_TEST_CONTENT_DIR "contents_test"
+
+/* Default maximum number of threads for concurrency test. */
+#define MAX_TEST_THREADS 10
+
+/* Default maximum concurrency test timeout (in seconds). */
+#define DEFAULT_CONCURRENCY_TEST_TIMEOUT 30
+
+/* Sleep interval for thread context switch. */
+#define SLEEP_INTERVAL 500
+
+
+/* Output methods. */
+#define LOG_OUT(fmt, x...) printf("Log:"fmt, ##x)
+
+#define TRY_TEST { \
+ int _ret_ = setjmp(JmpBuf); \
+ if (_ret_ == 1) { \
+ Failures++; \
+ } else { \
+
+#define FAIL_TEST longjmp(JmpBuf, 1);
+
+#define TESTCASECTOR(_ctx_, _api_, _testtype_, _polarity_, _action_, _callback_) \
+ TRY_TEST \
+ TestCaseCtor(_ctx_, _api_, _testtype_, _polarity_, _action_, _callback_);
+
+#define TESTCASECTOREX(_ctx_, _api_, _testtype_, _polarity_, _action_, _flag_, _callback_) \
+ TRY_TEST \
+ TestCaseCtorEx(_ctx_, _api_, _testtype_, _polarity_, _action_, _flag_, _callback_);
+
+#define TESTCASEDTOR(_ctx_) \
+ TestCaseDtor(_ctx_); \
+ } \
+} \
+
+/* Test assert method. */
+#define TEST_ASSERT(cond) if (!(cond)) {LOG_OUT("Test failed!! at : %s, %d\n", __FILE__, __LINE__); FAIL_TEST}
+
+#define ELEMENT_NUM(ary) (sizeof(ary) / sizeof((ary)[0]))
+
+#define TEST_CONSTRUCT_ERRCODE(m, e) (((m) << 24) | (e))
+
+
+/* Test content file types */
+enum ENUM_MALWARE_TEST_TYPES
+{
+ MALWARE_TTYPE_BUFFER = 0,
+ MALWARE_TTYPE_HTML,
+ MALWARE_TTYPE_URL,
+ MALWARE_TTYPE_EMAIL,
+ MALWARE_TTYPE_PHONE,
+ MALWARE_TTYPE_TEXT,
+ MALWARE_TTYPE_JAVA,
+ MALWARE_TTYPE_MULTIPLE,
+ MALWARE_TTYPE_JAVAS,
+ MALWARE_TTYPE_COMPRESS,
+ MALWARE_TTYPE_MAX
+};
+
+typedef int (*PFScan)(void *pPrivate, int nReason, void *pParam);
+
+/**
+ * Test case information data
+ */
+typedef struct TestCase_struct
+{
+ char szAPIName[MAX_TCS_API_NAME_LEN]; /* TCS API names */
+ int iInfected; /* Index of infected malware passed in pfCallback. */
+ int iTestType; /* Sample type. */
+ int iPolarity; /* INFECTED_DATA - Infected, BENIGN_DATA - Benign
+ otherwise undefined. */
+ int iAction;
+ int iCompressFlag;
+ int iNotImplTestFlag; /* 1 - repair not implemented test flag, otherwise not. */
+ int *pFlags;
+ PFScan pfCallback;
+
+ pthread_mutex_t MutexCon; /* Concurrency test communication stuff. */
+ pthread_cond_t CondCon; /* Concurrency test communication stuff. */
+} TestCase;
+
+/**
+ * Concurrency test data
+ */
+typedef struct ConTestContext_struct
+{
+ TestCase *pTestCtx;
+ int iCid; /* Concurrency test id. */
+
+ /* Report concurrency test status. 1 - success, -1 - failure, 0 - running. */
+ int iConTestRet;
+} ConTestContext;
+
+
+/*
+ * Very simple/thin porting layer
+ *
+ * Test malware informations. Malware names to be tested should be
+ * prepared in compiling time. Please see the porting guide for test
+ * suite.
+ */
+extern const char *SampleGetMalName(int iType, int iIndex);
+extern const char *SampleGetVarName(int iType, int iIndex);
+extern const char *SampleGetBenignFileName(int iType);
+extern const char *SampleGetInfectedFileName(int iType);
+extern unsigned int SampleGetSeverity(int iType, int iIndex);
+extern unsigned int SampleGetBehavior(int iType, int iIndex);
+extern unsigned int SampleGetMalType(int iType, int iIndex);
+extern int SampleGetCount(int iType);
+
+/* Test framework */
+extern int CbScanCallback(void *pPrivate, int nReason, void *pParam);
+extern int CbAbortCallback(void *pPrivate, int nReason, void *pParam);
+extern void TestCaseCtor(TestCase *pCtx, const char *pszAPI, int iTestType,
+ int iPolarity, int iAction, PFScan pfCallback);
+extern void TestCaseDtor(TestCase *pCtx);
+extern void TestScanFile(const char *pszFunc, int iTType, int iPolarity,
+ int iAction);
+extern void TestScanData(const char *pszFunc, int iTType, int iPolarity,
+ int iAction, PFScan pfCallback);
+extern void TestScanFileEx(const char *pszFunc, int iTType, int iPolarity,
+ int iAction, int iCompressFlag);
+extern void TestScanDataEx(const char *pszFunc, int iTType, int iPolarity,
+ int iAction, int iCompressFlag, PFScan pfCallback);
+extern void ConScanFile(TestCase *pCtx, int iAction);
+extern void ConScanData(TestCase *pCtx, int iAction);
+extern int DetectRepairFunc(void);
+extern int CreateTestDirs(void);
+extern void DestoryTestDirs(void);
+extern int DetectStubLibrary(void);
+extern int IsStubTest();
+extern int IsTestRepair();
+extern void RestoreEngine();
+extern void BackupEngine();
+
+extern jmp_buf JmpBuf;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TCSTEST_H */
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "TCSErrorCodes.h"
+#include "TCSImpl.h"
+#include "TCSTest.h"
+
+/* Concurrency test macros. */
+#define CONTEST_START \
+{\
+ int iTestRet = 1;
+
+#define CONTEST_ERROR \
+ CONTEST_ASSERT(0)
+
+#define CONTEST_ASSERT(condition) \
+if (!(condition)) \
+{ \
+ LOG_OUT("test failed: %s,%d\n", __FILE__, __LINE__); \
+ iTestRet = -1; \
+}
+
+#define CONTEST_RETURN(ret) \
+ ret = iTestRet; \
+}
+
+#define CONTEST_RELEASE(con_test_ctx) \
+ ReleaseTestObject(con_test_ctx, iTestRet);\
+}
+
+#define TCS_ACTION_CLASS(a) ((a) & 0xff)
+#define TCS_ACTION_BEHAVIOR(a) (((a) >> 8) & 0xff)
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define CONTENTS_ROOT "contents"
+#define CONTENTS_TMP "tmp"
+
+
+/**
+ * Scan context
+ */
+typedef struct ScanContext_struct
+{
+ /* Test status */
+ TestCase *pCurrentTestCase;
+ char *pData;
+ unsigned int uSize;
+} ScanContext;
+
+
+/**
+ * Concurrency Scan context
+ */
+typedef struct ConScanContext_struct
+{
+ /* Test status */
+ int iTestType;
+ int iInfected;
+ int iPolarity;
+ int iTestRet;
+ int *pFlags;
+ char *pData;
+ unsigned int uSize;
+} ConScanContext;
+
+
+pthread_mutex_t g_Mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t g_Cond = PTHREAD_COND_INITIALIZER;
+
+
+static int ScanBufferProc(TestCase *pCtx, char *pData, int iDataLen);
+static int SaveTestContents(void);
+static int LoadTestContents(void);
+static char *GetBackupDir(void);
+static void PutBackupDir(char *pszBackupDir);
+static char *GetSamplePath(TestCase *pCtx);
+static void PutSamplePath(char *pszSamplePath);
+static int GetSampleDataType(int iTType);
+static char *LoadFile(char const *pszFileName, int *piSize);
+static void PutLoadedFile(char *pData);
+static void ReportTestCase(TestCase *pCtx);
+static TCSOffset CbScanGetSize(void *pPrivate);
+static unsigned int CbScanRead(void *pPrivate, TCSOffset uOffset,
+ void *pBuffer, unsigned int uSize);
+static unsigned int CbScanWrite(void *pPrivate, TCSOffset uOffset,
+ void const *pBuffer, unsigned int uSize);
+static int CbScanSetSize(void *pPrivate, TCSOffset uSize);
+static void CheckDetected(TestCase *pCtx, TCSDetected *pFound);
+static void CheckDetectedList(TestCase *pCtx, TCSScanResult *pSR);
+static int ScanBuffer(TestCase *pCtx);
+static int ScanFile(TestCase *pCtx);
+static char *GetTestRoot(void);
+static void PutTestRoot(char *pszRoot);
+static int BufferCompare(const char *pBuffer1, const char *pBuffer2, int iLen);
+static int FileCompare(const char *pszFile1, const char *pszFile2);
+static int VerifyRepairData(TestCase *pCtx, const char *pRepairedBuffer,
+ int iRepairedLen);
+static int VerifyRepairFile(TestCase *pCtx);
+static void PutBenignSamplePath(char *pszPath);
+static char *GetBenignSamplePath(int iTType);
+static int Infected(TestCase *pCtx, char *pData, int iDataLen);
+static int InfectedFile(TestCase *pCtx, const char *pszPath);
+static void TestCaseCtorEx(TestCase *pCtx, const char *pszAPI, int iTestType,
+ int iPolarity, int iAction, int iCompressFlag,
+ PFScan pfCallback);
+static void CallSys(const char *pszCmd);
+
+/* Concurrency test functions. */
+static char *ConGetSampleDir(int iCid);
+static void ConPutSampleDir(char *pszDir);
+static void ConCreateSampleDirs(void);
+static void ConDestorySampleDirs(void);
+static char *ConGetSamplePath(int iTType, int iPolarity, int iCid);
+static void ConPutSamplePath(char *pszSamplePath);
+static void ConTestCaseCtor(ConTestContext *pConCtx, int iCid, TestCase *pCtx);
+static void ConTestCaseDtor(ConTestContext *pConCtx);
+
+static int ConWaitOnTestCond(ConTestContext *pConCtxAry);
+static void ReleaseTestObject(ConTestContext *pConCtx, int iResult);
+
+static int ConCheckDetected(int iTType, TCSDetected *pFound, int *pFlags);
+static int ConCheckDetectedList(int iTType, TCSScanResult *pSR, int *pFlags);
+static int ConVerifyRepairData(int iTType, int iCompressFlag, const char *pRepairedBuffer,
+ int iRepairedLen);
+static int ConVerifyRepairFile(char *pszSamplePath, int iTType, int iCompressFlag);
+
+static TCSOffset ConCbScanGetSize(void *pPrivate);
+static unsigned int ConCbScanRead(void *pPrivate, TCSOffset uOffset,
+ void *pBuffer, unsigned int uSize);
+static unsigned int ConCbScanWrite(void *pPrivate, TCSOffset uOffset,
+ void const *pBuffer, unsigned int uSize);
+static int ConCbScanSetSize(void *pPrivate, TCSOffset uSize);
+static int ConCbScanCallback(void *pPrivate, int nReason, void *pParam);
+static void ConScanDataProc(ConTestContext *pConCtx, int iAction);
+static void *ConScanDataSCProc(void *pConCtxParam);
+static void *ConScanDataSRProc(void *pConCtxParam);
+
+static int ConTestSuccess(ConTestContext *pConCtxAry);
+static int ConTestComplete(ConTestContext *pConCtxAry);
+
+static void ConScanFileProc(ConTestContext *pConCtx, int iAction);
+static void *ConScanFileSCProc(void *pConCtxParam);
+static void *ConScanFileSRProc(void *pConCtxParam);
+static int ConInfectedFile(int iType, int iCompressFlag, const char *pszPath);
+static int ConInfected(int iType, int iCompressFlag, char *pData, int iDataLen);
+
+
+int TestCasesCount = 0;
+int Success = 0;
+int Failures = 0;
+jmp_buf JmpBuf;
+
+
+static char *LoadFile(char const *pszFileName, int *piSize)
+{
+ FILE *pFile = NULL;
+ char *pData = NULL;
+
+ if ((pFile = fopen(pszFileName, "rb")) == NULL)
+ return NULL;
+
+ fseek(pFile, 0, SEEK_END);
+ *piSize = (long) ftell(pFile);
+ fseek(pFile, 0, SEEK_SET);
+ if ((pData = (char *) malloc(*piSize + 1)) == NULL)
+ {
+ fclose(pFile);
+ return NULL;
+ }
+ if (fread(pData, 1, (size_t) *piSize, pFile) != *piSize)
+ {
+ free(pData);
+ fclose(pFile);
+ return NULL;
+ }
+ fclose(pFile);
+ pData[*piSize] = '\0';
+
+ return pData;
+}
+
+
+static void PutLoadedFile(char *pData)
+{
+
+ if (pData != NULL)
+ free(pData);
+}
+
+
+/**
+ * Output for test case result.
+ */
+static void ReportTestCase(TestCase *pCtx)
+{
+ char *pszTmp;
+
+ LOG_OUT("@@@@@@@@@@@@@@@@@@@@@@@@\n");
+
+ LOG_OUT("@ID: TC_SEC_CS_%s\n", pCtx->szAPIName);
+ pszTmp = strchr(pCtx->szAPIName, '_');
+ *pszTmp = 0;
+ LOG_OUT("@API Name: %s\n", pCtx->szAPIName);
+ *pszTmp = '_';
+
+ TestCasesCount++;
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+static TCSOffset CbScanGetSize(void *pPrivate)
+{
+ ScanContext *pCtx = (ScanContext *) pPrivate;
+
+ return pCtx->uSize;
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+static unsigned int CbScanRead(void *pPrivate, TCSOffset uOffset,
+ void *pBuffer, unsigned int uSize)
+{
+ unsigned int uRead = 0;
+ ScanContext *pCtx = (ScanContext *) pPrivate;
+
+ if (uOffset < pCtx->uSize)
+ {
+ if ((uRead = pCtx->uSize - uOffset) > uSize)
+ uRead = uSize;
+ }
+ if (uRead)
+ memcpy(pBuffer, pCtx->pData + uOffset, uRead);
+
+ return uRead;
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+static unsigned int CbScanWrite(void *pPrivate, TCSOffset uOffset,
+ void const *pBuffer, unsigned int uSize)
+{
+ unsigned int uWrite = 0;
+ ScanContext *pCtx = (ScanContext *) pPrivate;
+
+ if (uOffset < pCtx->uSize)
+ {
+ if ((uWrite = pCtx->uSize - uOffset) > uSize)
+ uWrite = uSize;
+ }
+ if (uWrite)
+ memcpy(pCtx->pData + uOffset, pBuffer, uWrite);
+
+ return uWrite;
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+static int CbScanSetSize(void *pPrivate, TCSOffset uSize)
+{
+
+ return 0;
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+int CbScanCallback(void *pPrivate, int nReason, void *pParam)
+{
+ ScanContext *pCtx = (ScanContext *) pPrivate;
+ const char *pszMalName = NULL, *pszVarName = NULL;
+ int i, iTType = pCtx->pCurrentTestCase->iTestType;
+ int n = SampleGetCount(iTType);
+
+ /*
+ * Fix this is important since pParam could be different
+ * if the nReason is not DETECTED.
+ */
+ if (nReason != TCS_CB_DETECTED)
+ return 0;
+ TEST_ASSERT(nReason == TCS_CB_DETECTED);
+ TEST_ASSERT(pCtx->pCurrentTestCase->iPolarity == INFECTED_DATA);
+
+ pCtx->pCurrentTestCase->iInfected++;
+
+ for (i = 0; i < n; i++)
+ {
+ if (pCtx->pCurrentTestCase->pFlags[i])
+ continue;
+
+ pszMalName = SampleGetMalName(iTType, i);
+ if (pszMalName != NULL)
+ {
+ TEST_ASSERT(((TCSDetected *) pParam)->pszName != NULL);
+ if (((TCSDetected *) pParam)->pszName == NULL ||
+ strcmp(((TCSDetected *) pParam)->pszName, pszMalName) != 0)
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ pszVarName = SampleGetVarName(iTType, i);
+ if (pszVarName != NULL)
+ {
+ TEST_ASSERT(((TCSDetected *) pParam)->pszVariant != NULL);
+ if (((TCSDetected *) pParam)->pszVariant == NULL ||
+ strcmp(((TCSDetected *) pParam)->pszVariant, pszVarName) != 0)
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ TEST_ASSERT(TCS_ACTION_CLASS(((TCSDetected *) pParam)->uAction) ==
+ SampleGetSeverity(iTType, i));
+
+ TEST_ASSERT(TCS_ACTION_BEHAVIOR(((TCSDetected *) pParam)->uAction) ==
+ SampleGetBehavior(iTType, i));
+
+ pCtx->pCurrentTestCase->pFlags[i] = 1;
+ break;
+ }
+
+ TEST_ASSERT(i != n);
+
+ return 0;
+}
+
+
+/**
+ * The difference between ScanFile and ScanBuffer is:
+ * ScanBuffer is the helper function to test scan data.
+ */
+static int ScanBuffer(TestCase *pCtx)
+{
+ int iFSize;
+ char *pData, *pszFilePath;
+
+ if ((pszFilePath = GetSamplePath(pCtx)) == NULL)
+ return -1;
+
+ if ((pData = LoadFile(pszFilePath, &iFSize)) == NULL)
+ {
+ PutSamplePath(pszFilePath);
+ return -1;
+ }
+
+ TEST_ASSERT(ScanBufferProc(pCtx, pData, iFSize) == 0);
+ PutLoadedFile(pData);
+ PutSamplePath(pszFilePath);
+
+ return 0;
+}
+
+
+/**
+ * Scan file test helper function.
+ */
+static int ScanFile(TestCase *pCtx)
+{
+ int iErr, iExpected = SampleGetCount(pCtx->iTestType);
+ TCSScanResult SR;
+ TCSLIB_HANDLE hLib;
+ char *pszFilePath;
+
+ if ((pszFilePath = GetSamplePath(pCtx)) == NULL)
+ return -1;
+
+ hLib = TCSLibraryOpen();
+ if (hLib == INVALID_TCSLIB_HANDLE)
+ {
+ PutSamplePath(pszFilePath);
+ return -1;
+ }
+
+ if (iExpected > 0)
+ {
+ pCtx->pFlags = (int *) calloc(iExpected, sizeof(int));
+ if (pCtx->pFlags == NULL)
+ TEST_ASSERT(0);
+ }
+ else
+ pCtx->pFlags = NULL;
+
+ if (pCtx->iAction == TCS_SA_SCANREPAIR && IsTestRepair() == 0)
+ {
+ TEST_ASSERT(TCSScanFile(hLib, pszFilePath,
+ GetSampleDataType(pCtx->iTestType),
+ pCtx->iAction, pCtx->iCompressFlag, &SR) == -1);
+ iErr = TCSGetLastError(hLib);
+ TEST_ASSERT(TCS_ERRMODULE(iErr) == TCS_ERROR_MODULE_GENERIC);
+ TEST_ASSERT(TCS_ERRCODE(iErr) == TCS_ERROR_NOT_IMPLEMENTED);
+ }
+ else
+ {
+ TEST_ASSERT(TCSScanFile(hLib, pszFilePath,
+ GetSampleDataType(pCtx->iTestType),
+ pCtx->iAction, pCtx->iCompressFlag, &SR) == 0);
+ if (pCtx->pFlags)
+ memset(pCtx->pFlags, 0, sizeof(int) * iExpected);
+
+
+ if (pCtx->iAction == TCS_SA_SCANONLY)
+ {
+ if (pCtx->iPolarity == INFECTED_DATA)
+ {
+ if (pCtx->iTestType == MALWARE_TTYPE_COMPRESS &&
+ pCtx->iCompressFlag == 0)
+ /* Not suppose to detect when compress flag is
+ * set to 0 for compressed samples. */
+ {
+ TEST_ASSERT(SR.iNumDetected == 0);
+ }
+ else
+ {
+ TEST_ASSERT(SR.iNumDetected == SampleGetCount(pCtx->iTestType));
+ if (SR.iNumDetected == SampleGetCount(pCtx->iTestType))
+ CheckDetectedList(pCtx, &SR);
+ }
+ }
+ else
+ {
+ TEST_ASSERT(SR.iNumDetected == 0);
+ }
+ }
+ else
+ {
+ /* Verify */
+ TEST_ASSERT(VerifyRepairFile(pCtx) == 0);
+ }
+ if (*SR.pfFreeResult != NULL)
+ (*SR.pfFreeResult)(&SR);
+ }
+
+ if (pCtx->pFlags)
+ free(pCtx->pFlags);
+
+ TCSLibraryClose(hLib);
+ PutSamplePath(pszFilePath);
+
+ return 0;
+}
+
+
+/**
+ * Helper function for detected one malware.
+ */
+static void CheckDetected(TestCase *pCtx, TCSDetected *pFound)
+{
+ const char *pszMalName = NULL, *pszVarName = NULL;
+ int i, iTType = pCtx->iTestType, n = SampleGetCount(iTType);
+
+ for (i = 0; i < n; i++)
+ {
+ if (pCtx->pFlags[i])
+ continue;
+
+ pszMalName = SampleGetMalName(iTType, i);
+ if (pszMalName != NULL)
+ {
+ TEST_ASSERT(pFound->pszName != NULL);
+ if (pFound->pszName == NULL ||
+ strcmp(pFound->pszName, pszMalName) != 0)
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ pszVarName = SampleGetVarName(iTType, i);
+ if (pszVarName != NULL)
+ {
+ TEST_ASSERT(pFound->pszVariant != NULL);
+ if (pFound->pszVariant == NULL ||
+ strcmp(pFound->pszVariant, pszVarName) != 0)
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ TEST_ASSERT(TCS_ACTION_CLASS(pFound->uAction) ==
+ SampleGetSeverity(iTType, i));
+
+ TEST_ASSERT(TCS_ACTION_BEHAVIOR(pFound->uAction) ==
+ SampleGetBehavior(iTType, i));
+
+ pCtx->pFlags[i] = 1;
+ break;
+ }
+
+ TEST_ASSERT(i != n);
+}
+
+
+/**
+ * Helper function for detected malware list checking.
+ */
+static void CheckDetectedList(TestCase *pCtx, TCSScanResult *pSR)
+{
+ TCSDetected *pFound = pSR->pDList;
+
+ while (pFound != NULL)
+ {
+ CheckDetected(pCtx, pFound);
+ pFound = pFound->pNext;
+ }
+}
+
+
+/**
+ * Helper function for data scan, see ScanBuffer()
+ */
+static int ScanBufferProc(TestCase *pCtx, char *pData, int iDataLen)
+{
+ TCSLIB_HANDLE hLib;
+ TCSScanParam SP = {0};
+ TCSScanResult SR = {0};
+ ScanContext ScanCtx = {0};
+ int iErr, iExpected = SampleGetCount(pCtx->iTestType);
+
+ hLib = TCSLibraryOpen();
+ if (hLib == INVALID_TCSLIB_HANDLE)
+ return -1;
+
+ ScanCtx.pData = pData;
+ ScanCtx.uSize = (unsigned int) iDataLen;
+ ScanCtx.pCurrentTestCase = pCtx;
+
+ if (iExpected > 0)
+ {
+ pCtx->pFlags = (int *) calloc(iExpected, sizeof(int));
+ if (pCtx->pFlags == NULL)
+ TEST_ASSERT(0);
+ }
+ else
+ pCtx->pFlags = NULL;
+
+ SP.iAction = pCtx->iAction;
+ SP.iDataType = GetSampleDataType(pCtx->iTestType);
+ SP.iCompressFlag = pCtx->iCompressFlag;
+ SP.pPrivate = &ScanCtx;
+ SP.pfGetSize = CbScanGetSize;
+ SP.pfSetSize = CbScanSetSize;
+ SP.pfRead = CbScanRead;
+ SP.pfWrite = CbScanWrite;
+ SP.pfCallBack = pCtx->pfCallback;
+
+ if (pCtx->pfCallback == &CbAbortCallback)
+ {
+ TEST_ASSERT(TCSScanData(hLib, &SP, &SR) == -1);
+ iErr = TCSGetLastError(hLib);
+ }
+ else if (pCtx->iAction == TCS_SA_SCANREPAIR && IsTestRepair() == 0)
+ {
+ TEST_ASSERT(TCSScanData(hLib, &SP, &SR) == -1);
+ iErr = TCSGetLastError(hLib);
+ TEST_ASSERT(TCS_ERRMODULE(iErr) == TCS_ERROR_MODULE_GENERIC);
+ TEST_ASSERT(TCS_ERRCODE(iErr) == TCS_ERROR_NOT_IMPLEMENTED);
+ }
+ else
+ {
+ TEST_ASSERT(TCSScanData(hLib, &SP, &SR) == 0);
+ if (pCtx->pFlags)
+ memset(pCtx->pFlags, 0, sizeof(int) * iExpected);
+
+ /* Make sure pfCallback is called as expected. */
+ if (pCtx->pfCallback == &CbScanCallback &&
+ pCtx->iAction == TCS_SA_SCANONLY &&
+ pCtx->iPolarity == INFECTED_DATA)
+ {
+ if (pCtx->iTestType == MALWARE_TTYPE_COMPRESS &&
+ pCtx->iCompressFlag == 0)
+ /* Not suppose to detect virus when compress flag is
+ * disabled for compress test sample */
+ {
+ TEST_ASSERT(SR.iNumDetected == 0);
+ }
+ else
+ {
+ TEST_ASSERT(pCtx->iInfected == iExpected);
+ }
+ }
+
+ if (pCtx->iAction == TCS_SA_SCANONLY)
+ {
+ if (pCtx->iPolarity == INFECTED_DATA)
+ {
+ if (pCtx->iTestType == MALWARE_TTYPE_COMPRESS &&
+ pCtx->iCompressFlag == 0)
+ /* Not suppose to detect virus when compress flag is
+ * disabled for compress test sample */
+ {
+ TEST_ASSERT(SR.iNumDetected == 0);
+ }
+ else
+ {
+ TEST_ASSERT(SR.iNumDetected == iExpected);
+ if (SR.iNumDetected == iExpected)
+ CheckDetectedList(pCtx, &SR);
+ }
+ }
+ else
+ {
+ TEST_ASSERT(SR.iNumDetected == 0);
+ }
+ }
+ else
+ {
+ TEST_ASSERT(VerifyRepairData(pCtx, ScanCtx.pData,
+ ScanCtx.uSize) == 0);
+ }
+
+ if (*SR.pfFreeResult)
+ (*SR.pfFreeResult)(&SR);
+ }
+
+ if (pCtx->pFlags)
+ free(pCtx->pFlags);
+
+ TCSLibraryClose(hLib);
+
+ return 0;
+}
+
+
+/**
+ * Abort test callback helper function for data scan.
+ */
+int CbAbortCallback(void *pPrivate, int nReason, void *pParam)
+{
+
+ return -1;
+}
+
+
+int CreateTestDirs(void)
+{
+ int iLen, iRet = -1;
+ char *pszCommand, *pszRoot = GetTestRoot(), *pszEnv, *pszBackup;
+
+ if (pszRoot != NULL)
+ {
+ pszBackup = GetBackupDir();
+ if (pszBackup != NULL)
+ {
+ iLen = MAX(strlen(pszRoot) * 2, strlen(pszBackup));
+ iLen += 64; /* Reserved for "mkdir -p", "cp -f " */
+ pszCommand = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszCommand != NULL)
+ {
+ snprintf(pszCommand, iLen, "mkdir -p %s", pszRoot);
+ CallSys(pszCommand);
+ pszCommand[0] = 0;
+
+ snprintf(pszCommand, iLen, "mkdir -p %s", pszBackup);
+ CallSys(pszCommand);
+ pszCommand[0] = 0;
+
+ pszEnv = getenv("TCS_CONTENT_PATH");
+ if (pszEnv == NULL)
+ pszEnv = "./";
+ if (pszEnv[strlen(pszEnv) - 1] == '/')
+ snprintf(pszCommand, iLen, "cp -f %s* %s", pszEnv, pszRoot);
+ else
+ snprintf(pszCommand, iLen, "cp -f %s/* %s", pszEnv, pszRoot);
+ CallSys(pszCommand);
+
+ free(pszCommand);
+
+ iRet = 0;
+ }
+ PutBackupDir(pszBackup);
+ }
+ PutTestRoot(pszRoot);
+ }
+
+ return iRet;
+}
+
+
+void DestoryTestDirs(void)
+{
+ int iLen, iEnvLen;
+ char *pszCommand, *pszEnv = getenv("TCS_CONTENT_PATH");
+
+ if (pszEnv == NULL || strlen(pszEnv) == 0)
+ pszEnv = "./";
+ iEnvLen = strlen(pszEnv);
+ iLen = iEnvLen;
+ iLen += 72; /* Reserved for "rm -rf" and PID */
+ pszCommand = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszCommand != NULL)
+ {
+ if (pszEnv[iEnvLen - 1] == '/')
+ snprintf(pszCommand, iLen, "rm -rf %s%d", pszEnv, (int) getpid());
+ else
+ snprintf(pszCommand, iLen, "rm -rf %s/%d", pszEnv, (int) getpid());
+ CallSys(pszCommand);
+ free(pszCommand);
+ }
+}
+
+
+/**
+ * Test framework helper function: get content files' root path.
+ */
+static char *GetTestRoot(void)
+{
+ int iLen, iEnvLen;
+ char *pszRoot = NULL, *pszEnv = getenv("TCS_CONTENT_PATH");
+
+ if (pszEnv != NULL &&
+ (iEnvLen = strlen(pszEnv)) > 0)
+ {
+ iLen = iEnvLen;
+ iLen += 64; /* Reserved 64 bytes for PID. */
+ iLen += strlen(TCS_TEST_CONTENT_DIR);
+ pszRoot = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszRoot != NULL)
+ {
+ if (pszEnv[iEnvLen - 1] != '/')
+ snprintf(pszRoot, iLen, "%s/%d/%s", pszEnv, (int) getpid(),
+ TCS_TEST_CONTENT_DIR);
+ else
+ snprintf(pszRoot, iLen, "%s%d/%s", pszEnv, (int) getpid(),
+ TCS_TEST_CONTENT_DIR);
+ }
+ }
+ else
+ {
+ iLen = sizeof("./") + 64; /* Reserved 64 bytes for PID. */
+ pszRoot = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszRoot != NULL)
+ {
+ snprintf(pszRoot, iLen, "./%d", (int) getpid());
+ }
+ }
+
+ return pszRoot;
+}
+
+
+static void PutTestRoot(char *pszRoot)
+{
+
+ if (pszRoot != NULL)
+ free(pszRoot);
+}
+
+
+void TestCaseCtor(TestCase *pCtx, const char *pszAPI, int iTestType,
+ int iPolarity, int iAction, PFScan pfCallback)
+{
+
+ TestCaseCtorEx(pCtx, pszAPI, iTestType, iPolarity, iAction, 1, pfCallback);
+}
+
+
+/**
+ * Test case constructor.
+ */
+static void TestCaseCtorEx(TestCase *pCtx, const char *pszAPI, int iTestType,
+ int iPolarity, int iAction, int iCompressFlag,
+ PFScan pfCallback)
+{
+
+ strncpy(pCtx->szAPIName, pszAPI, sizeof(pCtx->szAPIName) - 1);
+ pCtx->iInfected = 0;
+ pCtx->iTestType = iTestType;
+ pCtx->iPolarity = iPolarity;
+ pCtx->iAction = iAction;
+ pCtx->iCompressFlag = iCompressFlag;
+ pCtx->pfCallback = pfCallback;
+ pCtx->pFlags = NULL;
+ TEST_ASSERT(SaveTestContents() == 0);
+}
+
+
+/**
+ * Test case destructor.
+ */
+void TestCaseDtor(TestCase *pCtx)
+{
+
+ ReportTestCase(pCtx);
+ TEST_ASSERT(LoadTestContents() == 0);
+ Success++;
+}
+
+
+static char *GetBackupDir(void)
+{
+ int iLen, iEnvLen;
+ char *pszEnv = getenv("TCS_CONTENT_PATH"), *pszPath;
+
+ if (pszEnv == NULL || strlen(pszEnv) == 0)
+ pszEnv = "./";
+ iEnvLen = strlen(pszEnv);
+ iLen = iEnvLen;
+ iLen += strlen(TCS_BACKUP_CONTENT_DIR);
+ iLen += 64; /* Reserved for slash char and PID. */
+ pszPath = (char *) calloc(iLen + 1, sizeof(char));
+
+ if (pszPath)
+ {
+ if (pszEnv[iEnvLen - 1] == '/')
+ snprintf(pszPath, iLen, "%s%d/%s", pszEnv, (int) getpid(),
+ TCS_BACKUP_CONTENT_DIR);
+ else
+ snprintf(pszPath, iLen, "%s/%d/%s", pszEnv, (int) getpid(),
+ TCS_BACKUP_CONTENT_DIR);
+ }
+
+ return pszPath;
+}
+
+
+static void PutBackupDir(char *pszBackupDir)
+{
+
+ if (pszBackupDir != NULL)
+ free(pszBackupDir);
+}
+
+
+static int SaveTestContents(void)
+{
+ int iLen = 0, iRet = -1;
+ char *pszRoot = NULL, *pszCommand = NULL, *pszBackupDir = GetBackupDir();
+
+ if (pszBackupDir != NULL)
+ {
+ pszRoot = GetTestRoot();
+ if (pszRoot != NULL)
+ {
+ iLen = strlen(pszBackupDir);
+ iLen += strlen(pszRoot);
+ iLen += 32; /* Reserved for unix commmand. */
+
+ pszCommand = (char *) calloc(iLen, sizeof(char));
+ if (pszCommand != NULL)
+ {
+ snprintf(pszCommand, iLen - sizeof(char), "cp -f %s/* %s/",
+ pszRoot, pszBackupDir);
+
+ CallSys(pszCommand);
+ free(pszCommand);
+ iRet = 0;
+ }
+
+ PutTestRoot(pszRoot);
+ }
+
+ PutBackupDir(pszBackupDir);
+ }
+
+ return iRet;
+}
+
+
+static int LoadTestContents(void)
+{
+ int iLen = 0, iRet = -1;
+ char *pszRoot = NULL, *pszCommand = NULL, *pszBackupDir = GetBackupDir();
+
+ if (pszBackupDir != NULL)
+ {
+ pszRoot = GetTestRoot();
+ if (pszRoot != NULL)
+ {
+ iLen = strlen(pszBackupDir);
+ iLen += strlen(pszRoot);
+ iLen += 32; /* Reserved for unix command. */
+
+ pszCommand = (char *) calloc(iLen, sizeof(char));
+ if (pszCommand != NULL)
+ {
+ snprintf(pszCommand, iLen - sizeof(char), "cp -f %s/* %s/",
+ pszBackupDir, pszRoot);
+
+ CallSys(pszCommand);
+ free(pszCommand);
+ iRet = 0;
+ }
+ PutTestRoot(pszRoot);
+ }
+
+ PutBackupDir(pszBackupDir);
+ }
+
+ return iRet;
+}
+
+
+static char *GetSamplePath(TestCase *pCtx)
+{
+ const char *pszSampleFileName;
+ char *pszSamplePath = NULL, *pszRoot = GetTestRoot();
+ int iLen, iTType = pCtx->iTestType, iPolarity = pCtx->iPolarity;
+ char *pwd = getenv("PWD");
+
+ if (pszRoot != NULL)
+ {
+ pszSampleFileName = (iPolarity == INFECTED_DATA ?
+ SampleGetInfectedFileName(iTType) :
+ SampleGetBenignFileName(iTType));
+
+ iLen = strlen(pszRoot);
+ iLen += strlen(pszSampleFileName);
+ iLen++; /* Reserved for slash char. */
+ iLen += strlen(pwd) + 3;
+
+ pszSamplePath = (char *) calloc(iLen + 1, sizeof(char));
+
+ if (pszSamplePath != NULL)
+ {
+ if (pszRoot[strlen(pszRoot) - 1] == '/')
+ snprintf(pszSamplePath, iLen, "%s/%s%s", pwd, pszRoot, pszSampleFileName);
+ else
+ snprintf(pszSamplePath, iLen, "%s/%s/%s", pwd, pszRoot, pszSampleFileName);
+ }
+
+ PutTestRoot(pszRoot);
+ }
+
+ return pszSamplePath;
+}
+
+
+static void PutSamplePath(char *pszSamplePath)
+{
+
+ if (pszSamplePath != NULL)
+ free(pszSamplePath);
+}
+
+
+static int GetSampleDataType(int iTType)
+{
+ switch (iTType)
+ {
+ case MALWARE_TTYPE_BUFFER:
+ return TCS_DTYPE_UNKNOWN;
+ case MALWARE_TTYPE_HTML:
+ return TCS_DTYPE_HTML;
+ case MALWARE_TTYPE_URL:
+ return TCS_DTYPE_URL;
+ case MALWARE_TTYPE_EMAIL:
+ return TCS_DTYPE_EMAIL;
+ case MALWARE_TTYPE_PHONE:
+ return TCS_DTYPE_PHONE;
+ case MALWARE_TTYPE_TEXT:
+ return TCS_DTYPE_TEXT;
+ case MALWARE_TTYPE_JAVA:
+ return TCS_DTYPE_JAVA;
+ case MALWARE_TTYPE_JAVAS:
+ return TCS_DTYPE_JAVAS;
+ case MALWARE_TTYPE_MULTIPLE:
+ return TCS_DTYPE_UNKNOWN;
+ case MALWARE_TTYPE_COMPRESS:
+ return TCS_DTYPE_UNKNOWN;
+ default:
+ return 0; /* Unlikely be here. */
+ }
+}
+
+
+void TestScanData(const char *pszFunc, int iTType, int iPolarity,
+ int iAction, PFScan pfCallback)
+{
+ TestCase TestCtx;
+
+ TESTCASECTOREX(&TestCtx, pszFunc, iTType, iPolarity, iAction, 1, pfCallback);
+ ScanBuffer(&TestCtx);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+void TestScanFile(const char *pszFunc, int iTType, int iPolarity, int iAction)
+{
+ TestCase TestCtx;
+
+ TESTCASECTOREX(&TestCtx, pszFunc, iTType, iPolarity, iAction, 1, NULL);
+ TEST_ASSERT(ScanFile(&TestCtx) == 0);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+void TestScanDataEx(const char *pszFunc, int iTType, int iPolarity,
+ int iAction, int iCompressFlag, PFScan pfCallback)
+{
+ TestCase TestCtx;
+
+ TESTCASECTOREX(&TestCtx, pszFunc, iTType, iPolarity, iAction,
+ iCompressFlag, pfCallback);
+ TEST_ASSERT(ScanBuffer(&TestCtx) == 0);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+void TestScanFileEx(const char *pszFunc, int iTType, int iPolarity,
+ int iAction, int iCompressFlag)
+{
+ TestCase TestCtx;
+
+ TESTCASECTOREX(&TestCtx, pszFunc, iTType, iPolarity,
+ iAction, iCompressFlag, NULL);
+ TEST_ASSERT(ScanFile(&TestCtx) == 0);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static int BufferCompare(const char *pBuffer1, const char *pBuffer2, int iLen)
+{
+
+ return memcmp(pBuffer1, pBuffer2, iLen);
+}
+
+
+static int FileCompare(const char *pszFile1, const char *pszFile2)
+{
+ int iLen1 = 0, iLen2 = 0, iRet = -1;
+ char *pBuffer1 = NULL, *pBuffer2 = NULL;
+
+ pBuffer1 = LoadFile(pszFile1, &iLen1);
+ if (pBuffer1 != NULL)
+ {
+ pBuffer2 = LoadFile(pszFile2, &iLen2);
+ if (pBuffer2 != NULL)
+ {
+ if (iLen1 != iLen2)
+ iRet = iLen1 - iLen2;
+
+ iRet = BufferCompare(pBuffer1, pBuffer2, iLen1);
+ PutLoadedFile(pBuffer2);
+ }
+ PutLoadedFile(pBuffer1);
+ }
+
+ return iRet;
+}
+
+
+static int ConInfectedFile(int iType, int iCompressFlag, const char *pszPath)
+{
+ int iRet = -1;
+ TCSScanResult SR = {0};
+ TCSLIB_HANDLE hLib = INVALID_TCSLIB_HANDLE;
+
+ hLib = TCSLibraryOpen();
+ if (hLib == INVALID_TCSLIB_HANDLE)
+ return -1;
+ iRet = TCSScanFile(hLib, pszPath, GetSampleDataType(iType),
+ TCS_SA_SCANONLY, iCompressFlag, &SR);
+ if (iRet != 0)
+ {
+ TCSLibraryClose(hLib);
+ return -1;
+ }
+ iRet = SR.iNumDetected;
+ if (SR.pfFreeResult != NULL)
+ SR.pfFreeResult(&SR);
+ TCSLibraryClose(hLib);
+
+ return iRet;
+}
+
+
+static int ConInfected(int iType, int iCompressFlag, char *pData, int iDataLen)
+{
+ int iRet = -1;
+ TCSScanParam SP = {0};
+ TCSScanResult SR = {0};
+ ScanContext ScanCtx = {0};
+ TCSLIB_HANDLE hLib = INVALID_TCSLIB_HANDLE;
+
+ ScanCtx.pData = pData;
+ ScanCtx.uSize = (unsigned int) iDataLen;
+
+ SP.iAction = TCS_SA_SCANONLY;
+ SP.iDataType = GetSampleDataType(iType);
+ SP.iCompressFlag = iCompressFlag;
+ SP.pPrivate = &ScanCtx;
+ SP.pfGetSize = CbScanGetSize;
+ SP.pfSetSize = CbScanSetSize;
+ SP.pfRead = CbScanRead;
+ SP.pfWrite = CbScanWrite;
+ SP.pfCallBack = NULL;
+
+ hLib = TCSLibraryOpen();
+ if (hLib == INVALID_TCSLIB_HANDLE)
+ return -1;
+ iRet = TCSScanData(hLib, &SP, &SR);
+ if (iRet != 0)
+ {
+ TCSLibraryClose(hLib);
+ return -1;
+ }
+ iRet = SR.iNumDetected;
+ if (SR.pfFreeResult != NULL)
+ SR.pfFreeResult(&SR);
+ TCSLibraryClose(hLib);
+
+ return iRet;
+}
+
+
+static int InfectedFile(TestCase *pCtx, const char *pszPath)
+{
+ int iRet = -1;
+ TCSScanResult SR = {0};
+ TCSLIB_HANDLE hLib = INVALID_TCSLIB_HANDLE;
+
+ hLib = TCSLibraryOpen();
+ TEST_ASSERT(hLib != INVALID_TCSLIB_HANDLE);
+ TEST_ASSERT(TCSScanFile(hLib, pszPath,
+ GetSampleDataType(pCtx->iTestType),
+ TCS_SA_SCANONLY, pCtx->iCompressFlag, &SR) == 0);
+ iRet = SR.iNumDetected;
+ if (SR.pfFreeResult != NULL)
+ SR.pfFreeResult(&SR);
+ TCSLibraryClose(hLib);
+
+ return iRet;
+}
+
+
+static int Infected(TestCase *pCtx, char *pData, int iDataLen)
+{
+ int iRet = -1;
+ TCSScanParam SP = {0};
+ TCSScanResult SR = {0};
+ ScanContext ScanCtx = {0};
+ TCSLIB_HANDLE hLib = INVALID_TCSLIB_HANDLE;
+
+ ScanCtx.pData = pData;
+ ScanCtx.uSize = (unsigned int) iDataLen;
+ ScanCtx.pCurrentTestCase = pCtx;
+
+ SP.iAction = TCS_SA_SCANONLY;
+ SP.iDataType = GetSampleDataType(pCtx->iTestType);
+ SP.iCompressFlag = pCtx->iCompressFlag;
+ SP.pPrivate = &ScanCtx;
+ SP.pfGetSize = CbScanGetSize;
+ SP.pfSetSize = CbScanSetSize;
+ SP.pfRead = CbScanRead;
+ SP.pfWrite = CbScanWrite;
+ SP.pfCallBack = NULL;
+
+ hLib = TCSLibraryOpen();
+ TEST_ASSERT(hLib != INVALID_TCSLIB_HANDLE);
+ TEST_ASSERT(TCSScanData(hLib, &SP, &SR) == 0);
+ iRet = SR.iNumDetected;
+ if (SR.pfFreeResult != NULL)
+ SR.pfFreeResult(&SR);
+ TCSLibraryClose(hLib);
+
+ return iRet;
+}
+
+
+static int VerifyRepairData(TestCase *pCtx, const char *pRepairedBuffer,
+ int iRepairedLen)
+{
+
+ return Infected(pCtx, pRepairedBuffer, iRepairedLen);
+}
+
+
+static int VerifyRepairFile(TestCase *pCtx)
+{
+
+ return InfectedFile(pCtx, GetSamplePath(pCtx));
+}
+
+
+static void ConTestCaseCtor(ConTestContext *pConCtx, int iCid, TestCase *pCtx)
+{
+
+ pConCtx->pTestCtx = pCtx;
+ pConCtx->iCid = iCid;
+ pConCtx->iConTestRet = 0; /* running. */
+}
+
+
+static void ConTestCaseDtor(ConTestContext *pConCtx)
+{
+
+}
+
+
+static char *GetBenignSamplePath(int iTType)
+{
+ int iLen, iRootLen;
+ char *pszSamplePath = NULL, *pszRoot = GetTestRoot();
+ const char *pszSampleFileName = NULL;
+
+ if (pszRoot != NULL)
+ {
+ pszSampleFileName = SampleGetBenignFileName(iTType);
+ iRootLen = strlen(pszRoot);
+ iLen = iRootLen;
+ iLen += strlen(pszSampleFileName);
+ iLen += 2; /* Slash char and \0 */
+
+ pszSamplePath = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszSamplePath != NULL)
+ {
+ if (pszRoot[iRootLen - 1] == '/')
+ snprintf(pszSamplePath, iLen, "%s%s", pszRoot, pszSampleFileName);
+ else
+ snprintf(pszSamplePath, iLen, "%s/%s", pszRoot, pszSampleFileName);
+ }
+ PutTestRoot(pszRoot);
+ }
+
+ return pszSamplePath;
+}
+
+
+static void PutBenignSamplePath(char *pszPath)
+{
+ if (pszPath != NULL)
+ free(pszPath);
+}
+
+
+static int ConVerifyRepairData(int iTType, int iCompressFlag, const char *pRepairedBuffer,
+ int iRepairedLen)
+{
+
+ return ConInfected(iTType, iCompressFlag, pRepairedBuffer, iRepairedLen);
+}
+
+
+static int ConVerifyRepairFile(char *pszSamplePath, int iTType, int iCompressFlag)
+{
+
+ return ConInfectedFile(iTType, iCompressFlag, pszSamplePath);
+}
+
+
+static int ConTestComplete(ConTestContext *pConCtxAry)
+{
+ int i;
+
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ {
+ if (pConCtxAry[i].iConTestRet == 0)
+ return 0; /* not complete */
+ }
+
+ return 1; /* Complete */
+}
+
+
+static int ConTestSuccess(ConTestContext *pConCtxAry)
+{
+ int i;
+
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ {
+ if (pConCtxAry[i].iConTestRet != 1)
+ return 0; /* failure */
+ }
+
+ return 1; /* success */
+}
+
+
+static void ReleaseTestObject(ConTestContext *pConCtx, int iResult)
+{
+
+ pthread_mutex_lock(&g_Mutex);
+ pConCtx->iConTestRet = iResult;
+ pthread_cond_broadcast(&g_Cond);
+ pthread_mutex_unlock(&g_Mutex);
+}
+
+
+static int ConCheckDetected(int iTType, TCSDetected *pFound, int *pFlags)
+{
+ const char *pszMalName = NULL, *pszVarName = NULL;
+ int i, n = SampleGetCount(iTType), iRet = 0;
+
+ for (i = 0; i < n; i++)
+ {
+ if (pFlags[i])
+ continue;
+
+ pszMalName = SampleGetMalName(iTType, i);
+ if (pszMalName != NULL)
+ {
+ if (pFound->pszName == NULL ||
+ strcmp(pFound->pszName, pszMalName) != 0)
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ pszVarName = SampleGetVarName(iTType, i);
+ if (pszVarName != NULL)
+ {
+ if (pFound->pszVariant == NULL ||
+ strcmp(pFound->pszVariant, pszVarName) != 0)
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ if (TCS_ACTION_CLASS(pFound->uAction) != SampleGetSeverity(iTType, i))
+ iRet = -1;
+
+ if (TCS_ACTION_BEHAVIOR(pFound->uAction) != SampleGetBehavior(iTType, i))
+ iRet = -1;
+
+ pFlags[i] = 1;
+ break;
+ }
+
+ if (i >= n)
+ iRet = -1;
+
+ return iRet;
+}
+
+
+static int ConCheckDetectedList(int iTType, TCSScanResult *pSR, int *pFlags)
+{
+ int iRet = 0;
+ TCSDetected *pFound = pSR->pDList;
+
+ while (pFound != NULL)
+ {
+ iRet = ConCheckDetected(iTType, pFound, pFlags);
+ if (iRet == -1)
+ break;
+ pFound = pFound->pNext;
+ }
+
+ return iRet;
+}
+
+
+static void *ConScanDataSCProc(void *pConCtxParam)
+{
+ ConTestContext *pConCtx = (ConTestContext *) pConCtxParam;
+
+ ConScanDataProc(pConCtx, TCS_SA_SCANONLY);
+
+ return NULL;
+}
+
+
+static void *ConScanDataSRProc(void *pConCtxParam)
+{
+ ConTestContext *pConCtx = (ConTestContext *) pConCtxParam;
+
+ ConScanDataProc(pConCtx, TCS_SA_SCANREPAIR);
+
+ return NULL;
+}
+
+
+static void ConScanDataProc(ConTestContext *pConCtx, int iAction)
+{
+ TCSLIB_HANDLE hLib;
+ TCSScanParam SP;
+ TCSScanResult SR = {0};
+ ConScanContext ScanCtx = {0};
+ char *pszSamplePath = NULL, *pData;
+ int i, j, iDataLen = 0, iCid= pConCtx->iCid, iOldType, iExpected;
+ int *pFlags;
+
+ CONTEST_START
+
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &iOldType);
+
+ i = MALWARE_TTYPE_BUFFER;
+ for (i = MALWARE_TTYPE_BUFFER; i < MALWARE_TTYPE_MULTIPLE; i++)
+ {
+ if ((iExpected = SampleGetCount(i)) > 0)
+ {
+ pFlags = (int *) malloc(sizeof(int) * iExpected);
+ if (pFlags == NULL)
+ CONTEST_ERROR
+ }
+ else
+ pFlags = NULL;
+
+ for (j = BENIGN_DATA; j <= INFECTED_DATA; j++)
+ {
+ hLib = TCSLibraryOpen();
+ if (hLib != INVALID_TCSLIB_HANDLE)
+ {
+ /* Test benign data. */
+ pszSamplePath = ConGetSamplePath(i, j, iCid);
+ pData = LoadFile(pszSamplePath, &iDataLen);
+
+ ConPutSamplePath(pszSamplePath);
+ ScanCtx.pData = pData;
+ ScanCtx.uSize = (unsigned int) iDataLen;
+ ScanCtx.iTestType = i;
+ ScanCtx.iInfected = 0;
+ ScanCtx.iPolarity = j;
+ ScanCtx.iTestRet = 1;
+ ScanCtx.pFlags = pFlags;
+
+ SP.iAction = iAction;
+ SP.iDataType = GetSampleDataType(i);
+ SP.pPrivate = &ScanCtx;
+ SP.pfGetSize = ConCbScanGetSize;
+ SP.pfSetSize = ConCbScanSetSize;
+ SP.pfRead = ConCbScanRead;
+ SP.pfWrite = ConCbScanWrite;
+ SP.pfCallBack = ConCbScanCallback;
+
+ if (pFlags)
+ memset(pFlags, 0, sizeof(int) * iExpected);
+
+ if (TCSScanData(hLib, &SP, &SR) == 0)
+ {
+ if (pFlags)
+ memset(pFlags, 0, sizeof(int) * iExpected);
+
+ if (j == BENIGN_DATA)
+ {
+ CONTEST_ASSERT(SR.iNumDetected == 0)
+ }
+ else
+ {
+ if (iAction == TCS_SA_SCANONLY)
+ {
+ CONTEST_ASSERT(SR.iNumDetected == iExpected &&
+ ConCheckDetectedList(i, &SR, pFlags) == 0)
+ }
+ else /* Repair */
+ {
+ CONTEST_ASSERT(ConVerifyRepairData(i, pConCtx->pTestCtx->iCompressFlag,
+ ScanCtx.pData, ScanCtx.uSize) == 0)
+ }
+ }
+
+ CONTEST_ASSERT(ScanCtx.iTestRet == 1)
+ (*SR.pfFreeResult)(&SR);
+ }
+ else
+ {
+ CONTEST_ERROR
+ }
+
+ PutLoadedFile(pData);
+
+ TCSLibraryClose(hLib);
+ }
+ else
+ {
+ CONTEST_ERROR
+ }
+
+ pthread_testcancel();
+ usleep(SLEEP_INTERVAL);
+ pthread_testcancel();
+ }
+
+ if (pFlags)
+ free(pFlags);
+ }
+ CONTEST_RELEASE(pConCtx);
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+static TCSOffset ConCbScanGetSize(void *pPrivate)
+{
+ ConScanContext *pCtx = (ConScanContext *) pPrivate;
+
+ return pCtx->uSize;
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+static unsigned int ConCbScanRead(void *pPrivate, TCSOffset uOffset,
+ void *pBuffer, unsigned int uSize)
+{
+ unsigned int uRead = 0;
+ ConScanContext *pCtx = (ConScanContext *) pPrivate;
+
+ if (uOffset < pCtx->uSize)
+ {
+ if ((uRead = pCtx->uSize - uOffset) > uSize)
+ uRead = uSize;
+ }
+ if (uRead)
+ memcpy(pBuffer, pCtx->pData + uOffset, uRead);
+
+ return uRead;
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+static unsigned int ConCbScanWrite(void *pPrivate, TCSOffset uOffset,
+ void const *pBuffer, unsigned int uSize)
+{
+ unsigned int uWrite = 0;
+ ConScanContext *pCtx = (ConScanContext *) pPrivate;
+
+ if (uOffset < pCtx->uSize)
+ {
+ if ((uWrite = pCtx->uSize - uOffset) > uSize)
+ uWrite = uSize;
+ }
+ if (uWrite)
+ memcpy(pCtx->pData + uOffset, pBuffer, uWrite);
+
+ return uWrite;
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+static int ConCbScanSetSize(void *pPrivate, TCSOffset uSize)
+{
+
+ return 0;
+}
+
+
+/**
+ * Callback helper for data scan, please reference API
+ * specification for more information about data scan.
+ */
+static int ConCbScanCallback(void *pPrivate, int nReason, void *pParam)
+{
+ ConScanContext *pCtx = (ConScanContext *) pPrivate;
+ const char *pszMalName = NULL, *pszVarName = NULL;
+ int i, iTType = pCtx->iTestType, n = SampleGetCount(iTType);
+
+ CONTEST_START
+
+ /*
+ * Fix this is important since pParam could be different
+ * if the nReason is not DETECTED.
+ */
+ if (nReason != TCS_CB_DETECTED)
+ return 0;
+
+ CONTEST_ASSERT(nReason == TCS_CB_DETECTED)
+ CONTEST_ASSERT(pCtx->iPolarity == INFECTED_DATA)
+
+ pCtx->iInfected++;
+
+ for (i = 0; i < n; i++)
+ {
+ if (pCtx->pFlags[i])
+ continue;
+
+ pszMalName = SampleGetMalName(iTType, i);
+ if (pszMalName != NULL)
+ {
+ CONTEST_ASSERT(pParam != NULL);
+ CONTEST_ASSERT(((TCSDetected *) pParam)->pszName != NULL);
+ if (((TCSDetected *) pParam)->pszName == NULL ||
+ strcmp(((TCSDetected *) pParam)->pszName, pszMalName) != 0)
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ pszVarName = SampleGetVarName(iTType, i);
+ if (pszVarName != NULL)
+ {
+ CONTEST_ASSERT(((TCSDetected *) pParam)->pszVariant != NULL);
+ if (((TCSDetected *) pParam)->pszVariant == NULL ||
+ strcmp(((TCSDetected *) pParam)->pszVariant, pszVarName) != 0)
+ continue;
+ }
+ else
+ {
+ continue;
+ }
+ CONTEST_ASSERT(TCS_ACTION_CLASS(((TCSDetected *) pParam)->uAction) ==
+ SampleGetSeverity(iTType, i));
+
+ CONTEST_ASSERT(TCS_ACTION_BEHAVIOR(((TCSDetected *) pParam)->uAction) ==
+ SampleGetBehavior(iTType, i));
+
+ pCtx->pFlags[i] = 1;
+ break;
+ }
+
+ CONTEST_ASSERT(i != n);
+
+ CONTEST_RETURN(pCtx->iTestRet)
+
+ return 0;
+}
+
+
+void ConScanData(TestCase *pCtx, int iAction)
+{
+ int i, iRet = 0;
+ ConTestContext ConCtxs[MAX_TEST_THREADS];
+ pthread_t Threads[MAX_TEST_THREADS];
+
+ /* Prepare for concurrency tests. */
+ ConCreateSampleDirs();
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ ConTestCaseCtor(&ConCtxs[i], i + 1, pCtx);
+
+ /* Concurrency tests. */
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ {
+ if (iAction == TCS_SA_SCANONLY)
+ pthread_create(&Threads[i], NULL, ConScanDataSCProc, &ConCtxs[i]);
+ else
+ pthread_create(&Threads[i], NULL, ConScanDataSRProc, &ConCtxs[i]);
+ }
+
+ /* Wait for all tests completed. */
+ iRet = ConWaitOnTestCond(&ConCtxs[0]);
+ if (iRet == ETIMEDOUT)
+ {
+ usleep(SLEEP_INTERVAL);
+ /* Cancel them all, if timeout. */
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ {
+ pthread_cancel(Threads[i]);
+ /* Wait for cancelling. */
+ usleep(SLEEP_INTERVAL);
+ }
+ }
+
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ pthread_join(Threads[i], NULL);
+
+ /* Check test result. */
+ TEST_ASSERT(ConTestSuccess(&ConCtxs[0]) == 1);
+
+ /* Release concurrency tests. */
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ ConTestCaseDtor(&ConCtxs[i]);
+ ConDestorySampleDirs();
+}
+
+
+static void *ConScanFileSCProc(void *pConCtxParam)
+{
+ ConTestContext *pConCtx = (ConTestContext *) pConCtxParam;
+
+ ConScanFileProc(pConCtx, TCS_SA_SCANONLY);
+
+ return NULL;
+}
+
+
+static void *ConScanFileSRProc(void *pConCtxParam)
+{
+ ConTestContext *pConCtx = (ConTestContext *) pConCtxParam;
+
+ ConScanFileProc(pConCtx, TCS_SA_SCANREPAIR);
+
+ return NULL;
+}
+
+
+static void ConScanFileProc(ConTestContext *pConCtx, int iAction)
+{
+ TCSLIB_HANDLE hLib;
+ TCSScanResult SR = {0};
+ char *pszSamplePath = NULL;
+ int i, j, iOldType, iCid = pConCtx->iCid, iExpected;
+ int *pFlags;
+
+ CONTEST_START
+
+ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &iOldType);
+
+ for (i = MALWARE_TTYPE_BUFFER; i < MALWARE_TTYPE_MULTIPLE; i++)
+ {
+ if ((iExpected = SampleGetCount(i)) > 0)
+ {
+ pFlags = (int *) malloc(sizeof(int) * iExpected);
+ if (pFlags == NULL)
+ CONTEST_ERROR
+ }
+ else
+ pFlags = NULL;
+
+ for (j = BENIGN_DATA; j <= INFECTED_DATA; j++)
+ {
+ hLib = TCSLibraryOpen();
+ if (hLib != INVALID_TCSLIB_HANDLE)
+ {
+ /* Test benign data. */
+ pszSamplePath = ConGetSamplePath(i, j, iCid);
+
+ if (TCSScanFile(hLib, pszSamplePath, GetSampleDataType(i),
+ iAction, pConCtx->pTestCtx->iCompressFlag, &SR) == 0)
+ {
+ if (pFlags)
+ memset(pFlags, 0, sizeof(int) * iExpected);
+
+ if (j == BENIGN_DATA)
+ {
+ CONTEST_ASSERT(SR.iNumDetected == 0)
+ }
+ else
+ {
+ if (iAction == TCS_SA_SCANONLY)
+ {
+ CONTEST_ASSERT(SR.iNumDetected == iExpected &&
+ ConCheckDetectedList(i, &SR, pFlags) == 0)
+ }
+ else /* Repair */
+ {
+ CONTEST_ASSERT(ConVerifyRepairFile(pszSamplePath, i,
+ pConCtx->pTestCtx->iCompressFlag) == 0)
+ }
+ }
+
+ (*SR.pfFreeResult)(&SR);
+ }
+ else
+ {
+ CONTEST_ERROR
+ }
+ ConPutSamplePath(pszSamplePath);
+ TCSLibraryClose(hLib);
+ }
+ else
+ {
+ CONTEST_ERROR
+ }
+
+ pthread_testcancel();
+ usleep(SLEEP_INTERVAL);
+ pthread_testcancel();
+ }
+
+ if (pFlags)
+ free(pFlags);
+ }
+
+ CONTEST_RELEASE(pConCtx)
+}
+
+
+static int ConWaitOnTestCond(ConTestContext *pConCtxAry)
+{
+ int iRet;
+ struct timeval Now;
+ struct timespec Timeout;
+
+ gettimeofday(&Now, NULL);
+ Timeout.tv_sec = Now.tv_sec + DEFAULT_CONCURRENCY_TEST_TIMEOUT;
+ Timeout.tv_nsec = Now.tv_usec * 1000;
+ iRet = 0;
+
+ pthread_mutex_lock(&g_Mutex);
+ while (ConTestComplete(pConCtxAry) != 1 && iRet != ETIMEDOUT)
+ iRet = pthread_cond_timedwait(&g_Cond, &g_Mutex, &Timeout);
+ pthread_mutex_unlock(&g_Mutex);
+
+ return iRet;
+}
+
+
+void ConScanFile(TestCase *pCtx, int iAction)
+{
+ int i, iRet = 0;
+ ConTestContext ConCtxs[MAX_TEST_THREADS];
+ pthread_t Threads[MAX_TEST_THREADS];
+
+ /* Prepare for concurrency tests. */
+ ConCreateSampleDirs();
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ ConTestCaseCtor(&ConCtxs[i], i + 1, pCtx);
+
+ /* Concurrency tests. */
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ {
+ if (iAction == TCS_SA_SCANONLY)
+ pthread_create(&Threads[i], NULL, ConScanFileSCProc, &ConCtxs[i]);
+ else
+ pthread_create(&Threads[i], NULL, ConScanFileSRProc, &ConCtxs[i]);
+ }
+ /* Wait for all tests completed. */
+ iRet = ConWaitOnTestCond(&ConCtxs[0]);
+ if (iRet == ETIMEDOUT)
+ {
+ usleep(SLEEP_INTERVAL);
+ /* Cancel them all, if timeout. */
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ {
+ pthread_cancel(Threads[i]);
+ /* Wait for cancelling. */
+ usleep(SLEEP_INTERVAL);
+ }
+ }
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ pthread_join(Threads[i], NULL);
+
+ /* Check test result. */
+ TEST_ASSERT(ConTestSuccess(ConCtxs) == 1);
+
+ /* Release concurrency tests. */
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ ConTestCaseDtor(&ConCtxs[i]);
+ ConDestorySampleDirs();
+}
+
+
+static char *ConGetSampleDir(int iCid)
+{
+ int iLen;
+ char *pszDir = NULL, *pszRoot = GetTestRoot();
+
+ if (pszRoot != NULL)
+ {
+ iLen = strlen(pszRoot);
+ iLen++; /* Reserved for slash char. */
+ iLen += 64; /* Reserved for thread id. */
+
+ pszDir = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszDir != NULL)
+ {
+ if (pszRoot[strlen(pszRoot) - 1] == '/')
+ snprintf(pszDir, iLen, "%s%s/t-%d", pszRoot, CONTENTS_ROOT, iCid);
+ else
+ snprintf(pszDir, iLen, "%s/%s/t-%d", pszRoot, CONTENTS_ROOT, iCid);
+ }
+ PutTestRoot(pszRoot);
+ }
+
+ return pszDir;
+}
+
+
+static void ConPutSampleDir(char *pszDir)
+{
+ if (pszDir != NULL)
+ free(pszDir);
+}
+
+
+static void ConCreateSampleDirs(void)
+{
+ int i, iLen, iRootLen;
+ char *pszRoot = GetTestRoot(), *pszCommand;
+
+ if (pszRoot != NULL)
+ {
+ for (i = 0; i < MAX_TEST_THREADS; i++)
+ {
+ iRootLen = strlen(pszRoot);
+ iLen = iRootLen * 2;
+ iLen += 72; /* Reserved for "mkdir t-" , "cp -f "*/
+ pszCommand = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszCommand)
+ {
+ if (pszRoot[iRootLen - 1] == '/')
+ snprintf(pszCommand, iLen, "mkdir -p %s%st-%d", pszRoot, CONTENTS_ROOT, i + 1);
+ else
+ snprintf(pszCommand, iLen, "mkdir -p %s/%s/t-%d", pszRoot, CONTENTS_ROOT, i + 1);
+ CallSys(pszCommand);
+
+ pszCommand[0] = 0;
+ if (pszRoot[iRootLen - 1] == '/')
+ snprintf(pszCommand, iLen, "cp -f %s*.* %s%s/t-%d/",
+ pszRoot, pszRoot, CONTENTS_ROOT, i + 1);
+ else
+ snprintf(pszCommand, iLen, "cp -f %s/*.* %s/%s/t-%d/",
+ pszRoot, pszRoot, CONTENTS_ROOT, i + 1);
+ CallSys(pszCommand);
+
+ free(pszCommand);
+ pszCommand = NULL;
+ }
+ }
+ PutTestRoot(pszRoot);
+ }
+}
+
+
+static void ConDestorySampleDirs(void)
+{
+ int iLen, iRootLen;
+ char *pszRoot = GetTestRoot(), *pszCommand;
+
+ if (pszRoot != NULL)
+ {
+ iRootLen = strlen(pszRoot);
+ iLen = iRootLen;
+ iLen += 72; /* "rm -rf "*/
+ pszCommand = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszCommand)
+ {
+ if (pszRoot[iRootLen - 1] == '/')
+ snprintf(pszCommand, iLen, "rm -rf %s%s/t-*", pszRoot, CONTENTS_ROOT);
+ else
+ snprintf(pszCommand, iLen, "rm -rf %s/%s/t-*", pszRoot, CONTENTS_ROOT);
+ CallSys(pszCommand);
+
+ free(pszCommand);
+ pszCommand = NULL;
+ }
+ PutTestRoot(pszRoot);
+ }
+}
+
+
+static char *ConGetSamplePath(int iTType, int iPolarity, int iCid)
+{
+ int iLen, iDirLen;
+ const char *pszSampleFileName;
+ char *pszSamplePath = NULL, *pszDir = ConGetSampleDir(iCid);
+ char *pwd = getenv("PWD");
+
+ if (pszDir != NULL)
+ {
+ pszSampleFileName = (iPolarity == INFECTED_DATA ?
+ SampleGetInfectedFileName(iTType) :
+ SampleGetBenignFileName(iTType));
+
+ iDirLen = strlen(pszDir);
+ iLen = iDirLen;
+ iLen += strlen(pszSampleFileName);
+ iLen++; /* Reserved for slash char. */
+ iLen++; /* Reserved for \0. */
+ iLen += strlen(pwd) + 1;
+
+ pszSamplePath = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszSamplePath != NULL)
+ {
+ if (pszDir[iDirLen - 1] == '/')
+ snprintf(pszSamplePath, iLen, "%s/%s%s", pwd, pszDir, pszSampleFileName);
+ else
+ snprintf(pszSamplePath, iLen, "%s/%s/%s", pwd, pszDir, pszSampleFileName);
+ }
+ ConPutSampleDir(pszDir);
+ }
+
+ return pszSamplePath;
+}
+
+
+static void ConPutSamplePath(char *pszSamplePath)
+{
+
+ if (pszSamplePath != NULL)
+ free(pszSamplePath);
+}
+
+
+int DetectRepairFunc(void)
+{
+ int iRet = 0; /* Not support by default. */
+ TCSScanResult SR = {0};
+ char *pszTestSamplePath;
+ TCSLIB_HANDLE hLib = INVALID_TCSLIB_HANDLE;
+
+ hLib = TCSLibraryOpen();
+ if (hLib != INVALID_TCSLIB_HANDLE)
+ {
+ pszTestSamplePath = GetBenignSamplePath(MALWARE_TTYPE_BUFFER);
+ if (pszTestSamplePath != NULL)
+ {
+ if (TCSScanFile(hLib, pszTestSamplePath,
+ GetSampleDataType(MALWARE_TTYPE_BUFFER),
+ TCS_SA_SCANREPAIR, 1, &SR) == 0)
+ {
+ (*SR.pfFreeResult)(&SR);
+ iRet = 1; /* Supported. */
+ }
+
+ PutBenignSamplePath(pszTestSamplePath);
+ }
+ TCSLibraryClose(hLib);
+ }
+
+ return iRet;
+}
+
+
+int IsTestRepair()
+{
+ const char *pszType = getenv("TCS_SCAN_TYPE");
+ if (pszType != NULL)
+ return atoi(pszType);
+
+ return 0;
+}
+
+
+void BackupEngine()
+{
+ char *pszRoot = GetTestRoot(), *pszCommand;
+
+ if (pszRoot != NULL)
+ {
+ asprintf(&pszCommand, "mkdir %s/backup", pszRoot);
+ CallSys(pszCommand);
+ free(pszCommand);
+
+ asprintf(&pszCommand, "cp -f /opt/usr/share/sec_plugin/libengine.so %s/backup", pszRoot);
+ CallSys(pszCommand);
+ free(pszCommand);
+
+ PutTestRoot(pszRoot);
+ }
+}
+
+
+void RestoreEngine()
+{
+ char *pszRoot = GetTestRoot(), *pszCommand;
+
+ if (pszRoot != NULL)
+ {
+ asprintf(&pszCommand, "cp -f %s/backup/libengine.so /opt/usr/share/sec_plugin/", pszRoot);
+ CallSys(pszCommand);
+ free(pszCommand);
+
+ PutTestRoot(pszRoot);
+ }
+}
+
+
+static void CallSys(const char *pszCmd)
+{
+ int iRet = system(pszCmd);
+ if (iRet != 0)
+ {
+ // LOG_OUT("system returns %d for command %s\n", iRet, pszCmd);
+ }
+}
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include "TWPImpl.h"
+
+#include "XMHttp.h"
+#include "TWPTest.h"
+#include "UrlInfo.h"
+
+/* Test cases. */
+static void TWPStartup(void);
+static void TWPCleanup(void);
+static void TWPInitLibrary_0001(void);
+static void TWPInitLibrary_0002(void);
+static void TWPInitLibrary_0003(void);
+static void TWPInitLibrary_0004(void);
+static void TWPConfigurationCreate_0001(void);
+static void TWPConfigurationCreate_0002(void);
+static void TWPConfigurationCreate_0003(void);
+static void TWPPolicyCreate_0001(void);
+static void TWPPolicyCreate_0002(void);
+static void TWPPolicyCreate_0003(void);
+static void TWPLookupUrls_0001(void);
+static void TWPLookupUrls_0002(void);
+static void TWPLookupUrls_0003(void);
+static void TWPLookupUrls_0004(void);
+static void TWPLookupUrls_0005(void);
+static void TWPGetUrlRating_0001(void);
+static void TWPGetUrlRating_0002(void);
+static void TWPGetUrlRating_0003(void);
+static void TWPGetUrlRating_0004(void);
+static void TWPGetUrlRating_0005(void);
+static void TWPGetUrlRating_0006(void);
+static void TWPGetUrlRatingsCount_0001(void);
+static void TWPGetUrlRatingsCount_0002(void);
+static void TWPGetRedirUrlFor_0001(void);
+static void TWPGetRedirUrlFor_0002(void);
+static void TWPPolicyValidate_0001(void);
+static void TWPPolicyValidate_0002(void);
+static void TWPPolicyValidate_0003(void);
+static void TWPPolicyGetViolations_0001(void);
+static void TWPPolicyGetViolations_0002(void);
+static void TWPPolicyGetViolations_0003(void);
+static void TWPRatingGetScore_0001(void);
+static void TWPRatingGetScore_0002(void);
+static void TWPRatingGetUrl_0001(void);
+static void TWPRatingGetUrl_0002(void);
+static void TWPRatingGetDLAUrl_0001(void);
+static void TWPRatingGetDLAUrl_0002(void);
+static void TWPRatingHasCategory_0001(void);
+static void TWPRatingHasCategory_0002(void);
+static void TWPRatingHasCategory_0003(void);
+static void TWPRatingGetCategories_0001(void);
+static void TWPRatingGetCategories_0002(void);
+static void TWPRatingGetCategories_0003(void);
+
+static void TestCases(void);
+
+
+extern int TestCasesCount;
+extern int Success;
+extern int Failures;
+extern TWPResponseHandle hAResponse;
+
+TWPAPIInit Init;
+TWPConfiguration Cfg;
+TRequest Request;
+
+
+int main(int argc, char **argv)
+{
+ TWPStartup();
+ TestCases();
+ TWPCleanup();
+
+ return 0;
+}
+
+
+static void TestCases(void)
+{
+ TWPInitLibrary_0001();
+ TWPInitLibrary_0002();
+ TWPInitLibrary_0003();
+ TWPInitLibrary_0004();
+ TWPConfigurationCreate_0001();
+ TWPConfigurationCreate_0002();
+ TWPConfigurationCreate_0003();
+ TWPPolicyCreate_0001();
+ TWPPolicyCreate_0002();
+ TWPPolicyCreate_0003();
+ TWPLookupUrls_0001();
+ TWPLookupUrls_0002();
+ TWPLookupUrls_0003();
+ TWPLookupUrls_0004();
+ TWPLookupUrls_0005();
+ TWPGetUrlRating_0001();
+ TWPGetUrlRating_0002();
+ TWPGetUrlRating_0003();
+ TWPGetUrlRating_0004();
+ TWPGetUrlRating_0005();
+ TWPGetUrlRating_0006();
+ TWPGetUrlRatingsCount_0001();
+ TWPGetUrlRatingsCount_0002();
+ TWPGetRedirUrlFor_0001();
+ TWPGetRedirUrlFor_0002();
+ TWPPolicyValidate_0001();
+ TWPPolicyValidate_0002();
+ TWPPolicyValidate_0003();
+ TWPPolicyGetViolations_0001();
+ TWPPolicyGetViolations_0002();
+ TWPPolicyGetViolations_0003();
+ TWPRatingGetScore_0001();
+ TWPRatingGetScore_0002();
+ TWPRatingGetUrl_0001();
+ TWPRatingGetUrl_0002();
+ TWPRatingGetDLAUrl_0001();
+ TWPRatingGetDLAUrl_0002();
+ TWPRatingHasCategory_0001();
+ TWPRatingHasCategory_0002();
+ TWPRatingHasCategory_0003();
+ TWPRatingGetCategories_0001();
+ TWPRatingGetCategories_0002();
+ TWPRatingGetCategories_0003();
+}
+
+
+static void TWPInitLibrary_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib = INVALID_TWPLIB_HANDLE;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TESTCASEDTOR(&TestCtx);
+ TWPUninitLibrary(hLib);
+}
+
+
+static void TWPInitLibrary_0002(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+
+ RemoveEngine();
+
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) == INVALID_TWPLIB_HANDLE);
+ TESTCASEDTOR(&TestCtx);
+
+ RestoreEngine();
+}
+
+
+static void TWPInitLibrary_0003(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+
+ RemoveEngine();
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) == INVALID_TWPLIB_HANDLE);
+ RestoreEngine();
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TWPUninitLibrary(hLib);
+
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPInitLibrary_0004(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TWPUninitLibrary(hLib);
+ RemoveEngine();
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) == INVALID_TWPLIB_HANDLE);
+ TESTCASEDTOR(&TestCtx);
+ RestoreEngine();
+}
+
+
+static void TWPConfigurationCreate_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPConfigurationCreate_0002(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, NULL, &hCfg) != TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPConfigurationCreate_0003(void)
+{
+ TestCase TestCtx;
+ TWPConfigurationHandle hCfg;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT(TWPConfigurationCreate(INVALID_TWPLIB_HANDLE, NULL, &hCfg) != TWP_SUCCESS);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPPolicyCreate_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPPolicyHandle hPolicy;
+ TWPConfigurationHandle hCfg;
+ TWPCategories Categories[1] =
+ {
+ TWP_Artcultureheritage,
+ };
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyCreate(hLib, hCfg, Categories, ELEMENT_NUM(Categories), &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(hPolicy != NULL);
+ TEST_ASSERT(TWPPolicyDestroy(hLib, &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPPolicyCreate_0002(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPPolicyHandle hPolicy;
+ TWPConfigurationHandle hCfg;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyCreate(hLib, hCfg, NULL, 0, &hPolicy) != TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPPolicyCreate_0003(void)
+{
+ TestCase TestCtx;
+ TWPPolicyHandle hPolicy;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT(TWPPolicyCreate(INVALID_TWPLIB_HANDLE, NULL, NULL, 0, &hPolicy) != TWP_SUCCESS);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPLookupUrls_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0, ppUrls,
+ ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPLookupUrls_0002(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ NULL, 0, &hResponse) != TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPLookupUrls_0003(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TRequest ARequest = Request;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ ARequest.Request.receivefunc = NULL;
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &ARequest, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseWrite(hLib, hAResponse, ARequest.ResponseBody, ARequest.ResponseLength) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseWrite(hLib, hAResponse, "", 0) == TWP_SUCCESS);
+ TEST_ASSERT(hAResponse != NULL);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hAResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPLookupUrls_0004(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0, ppUrls,
+ ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPLookupUrls_0005(void)
+{
+ TestCase TestCtx;
+ TWPResponseHandle hResponse;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+
+ RemoveEngine();
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT(TWPLookupUrls(INVALID_TWPLIB_HANDLE, NULL, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetUrlRating_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByIndex(hLib, hResponse, 0, &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetUrlRating_0002(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, URL_0_0,
+ strlen(URL_0_0), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetUrlRating_0003(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, NULL, 0, &hRating) != TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetUrlRating_0004(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByIndex(hLib, hResponse, 0, &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetUrlRating_0005(void)
+{
+ TestCase TestCtx;
+ TWPUrlRatingHandle hRating;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ /* pre-condition is stub library */
+ RemoveEngine();
+ TEST_ASSERT(TWPResponseGetUrlRatingByIndex(INVALID_TWPLIB_HANDLE,
+ NULL, 0, &hRating) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetUrlRating_0006(void)
+{
+ TestCase TestCtx;
+ TWPUrlRatingHandle hRating;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ /* pre-condition is stub library */
+ RemoveEngine();
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(INVALID_TWPLIB_HANDLE, NULL,
+ NULL, 0, &hRating) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetUrlRatingsCount_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[] =
+ {
+ URL_0_0,
+ URL_1_0
+ };
+ unsigned int uCount = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByIndex(hLib, hResponse, 0, &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseGetUrlRatingsCount(hLib, hResponse, &uCount) == TWP_SUCCESS);
+ TEST_ASSERT(uCount == ELEMENT_NUM(ppUrls));
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetUrlRatingsCount_0002(void)
+{
+ unsigned int uCount;
+ TestCase TestCtx;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ /* pre-condition is stub library */
+ RemoveEngine();
+ TEST_ASSERT(TWPResponseGetUrlRatingsCount(INVALID_TWPLIB_HANDLE,
+ NULL, &uCount) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetRedirUrlFor_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_3_0
+ };
+ char *pUrl = NULL;
+ unsigned int uLength = 0;
+ TWPPolicyHandle hPolicy;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 1,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByIndex(hLib, hResponse, 0, &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(hRating != NULL);
+ TEST_ASSERT(TWPPolicyCreate(hLib, hCfg, CATEGORIES_0_0_1, ELEMENT_NUM(CATEGORIES_0_0_1), &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(hPolicy != NULL);
+ TEST_ASSERT(TWPResponseGetRedirUrlFor(hLib, hResponse, hRating, hPolicy, &pUrl, &uLength) == TWP_SUCCESS);
+ TEST_ASSERT(pUrl != NULL);
+ free(pUrl);
+ TEST_ASSERT(TWPPolicyDestroy(hLib, &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPGetRedirUrlFor_0002(void)
+{
+ TestCase TestCtx;
+ TWPPolicyHandle hPolicy = NULL;
+ char *pUrl = NULL;
+ unsigned int uLength = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ /* pre-condition is stub library */
+ RemoveEngine();
+ TEST_ASSERT(TWPResponseGetRedirUrlFor(INVALID_TWPLIB_HANDLE,
+ NULL, NULL, hPolicy, &pUrl, &uLength) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPPolicyValidate_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+ TWPPolicyHandle hPolicy;
+ int iViolated = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyCreate(hLib, hCfg, CATEGORIES_0_0_1, ELEMENT_NUM(CATEGORIES_0_0_1), &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyValidate(hLib, hPolicy, hRating, &iViolated) == TWP_SUCCESS);
+ TEST_ASSERT(iViolated == 1);
+ TEST_ASSERT(TWPPolicyDestroy(hLib, &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPPolicyValidate_0002(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+ TWPPolicyHandle hPolicy;
+ int iViolated = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyCreate(hLib, hCfg, CATEGORIES_0_0_0, ELEMENT_NUM(CATEGORIES_0_0_0), &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyValidate(hLib, hPolicy, hRating, &iViolated) == TWP_SUCCESS);
+ TEST_ASSERT(iViolated == 0);
+ TEST_ASSERT(TWPPolicyDestroy(hLib, &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPPolicyValidate_0003(void)
+{
+ TestCase TestCtx;
+ int iViolated = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ RemoveEngine();
+ TEST_ASSERT(TWPPolicyValidate(INVALID_TWPLIB_HANDLE,
+ NULL, NULL, &iViolated) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPPolicyGetViolations_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+ TWPPolicyHandle hPolicy;
+ TWPCategories *pViolated = NULL;
+ unsigned int uLength = 0;
+ int i;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyCreate(hLib, hCfg, CATEGORIES_0_0_2, ELEMENT_NUM(CATEGORIES_0_0_2), &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyGetViolations(hLib, hPolicy, hRating, &pViolated, &uLength) == TWP_SUCCESS);
+ TEST_ASSERT(uLength == ELEMENT_NUM(VIOLATIONS_0_0_2));
+ for (i = 0; i < uLength; i++)
+ {
+ TEST_ASSERT(pViolated[i] == VIOLATIONS_0_0_2[i]);
+ }
+ free(pViolated);
+ TEST_ASSERT(TWPPolicyDestroy(hLib, &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPPolicyGetViolations_0002(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+ TWPPolicyHandle hPolicy;
+ TWPCategories *pViolated = NULL;
+ unsigned int uLength = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyCreate(hLib, hCfg, CATEGORIES_0_0_0, ELEMENT_NUM(CATEGORIES_0_0_0), &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPPolicyGetViolations(hLib, hPolicy, hRating, &pViolated, &uLength) == TWP_SUCCESS);
+ TEST_ASSERT(uLength == 0);
+ TEST_ASSERT(pViolated == NULL);
+ TEST_ASSERT(TWPPolicyDestroy(hLib, &hPolicy) == TWP_SUCCESS);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPPolicyGetViolations_0003(void)
+{
+ TestCase TestCtx;
+ TWPCategories *pViolated = NULL;
+ unsigned int uLength = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ RemoveEngine();
+ TEST_ASSERT(TWPPolicyGetViolations(INVALID_TWPLIB_HANDLE, NULL, NULL,
+ &pViolated, &uLength) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingGetScore_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+ int iScore;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPUrlRatingGetScore(hLib, hRating, &iScore) == TWP_SUCCESS);
+ TEST_ASSERT(iScore == SCORE_0_0);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingGetScore_0002(void)
+{
+ TestCase TestCtx;
+ int iScore;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ RemoveEngine();
+ TEST_ASSERT(TWPUrlRatingGetScore(INVALID_TWPLIB_HANDLE, NULL, &iScore) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingGetUrl_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+ char *pUrl;
+ unsigned int uLength = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPUrlRatingGetUrl(hLib, hRating, &pUrl, &uLength) == TWP_SUCCESS);
+ TEST_ASSERT(strcmp(pUrl, ppUrls[0]) == 0);
+ TEST_ASSERT(uLength == strlen(ppUrls[0]));
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingGetUrl_0002(void)
+{
+ TestCase TestCtx;
+ char *pUrl;
+ unsigned int uLength = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ RemoveEngine();
+ TEST_ASSERT(TWPUrlRatingGetUrl(INVALID_TWPLIB_HANDLE, NULL, &pUrl, &uLength) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingGetDLAUrl_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_2_0
+ };
+ char *pUrl;
+ unsigned int uLength = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPUrlRatingGetDLAUrl(hLib, hRating, &pUrl, &uLength) == TWP_SUCCESS);
+ TEST_ASSERT(pUrl != NULL);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingGetDLAUrl_0002(void)
+{
+ TestCase TestCtx;
+ char *pUrl;
+ unsigned int uLength = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ RemoveEngine();
+ TEST_ASSERT(TWPUrlRatingGetDLAUrl(INVALID_TWPLIB_HANDLE, NULL, &pUrl, &uLength) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingHasCategory_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+ int iPresent = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPUrlRatingHasCategory(hLib, hRating, CATEGORY_0_0_1, &iPresent) == TWP_SUCCESS);
+ TEST_ASSERT(iPresent == 1);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingHasCategory_0002(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+ int iPresent = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPUrlRatingHasCategory(hLib, hRating, CATEGORY_0_0_0, &iPresent) == TWP_SUCCESS);
+ TEST_ASSERT(iPresent == 0);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingHasCategory_0003(void)
+{
+ TestCase TestCtx;
+ int iPresent = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ RemoveEngine();
+ TEST_ASSERT(TWPUrlRatingHasCategory(INVALID_TWPLIB_HANDLE, NULL, CATEGORY_0_0_0, &iPresent) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingGetCategories_0001(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_0_0
+ };
+ TWPCategories *pCategories;
+ unsigned int uLength;
+ int i;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPUrlRatingGetCategories(hLib, hRating, &pCategories, &uLength) == TWP_SUCCESS);
+ TEST_ASSERT(uLength == ELEMENT_NUM(CATEGORIES_0_0_1));
+ for (i = 0; i < uLength; i++)
+ {
+ TEST_ASSERT(pCategories[i] == CATEGORIES_0_0_1[i]);
+ }
+ free(pCategories);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingGetCategories_0002(void)
+{
+ TestCase TestCtx;
+ TWPLIB_HANDLE hLib;
+ TWPConfigurationHandle hCfg;
+ TWPResponseHandle hResponse;
+ TWPUrlRatingHandle hRating;
+ const char *ppUrls[1] =
+ {
+ URL_1_0
+ };
+ TWPCategories *pCategories = NULL;
+ unsigned int uLength = 0;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ TEST_ASSERT((hLib = TWPInitLibrary(&Init)) != INVALID_TWPLIB_HANDLE);
+ TEST_ASSERT(TWPConfigurationCreate(hLib, &Cfg, &hCfg) == TWP_SUCCESS);
+ TEST_ASSERT(hCfg != NULL);
+ TEST_ASSERT(TWPLookupUrls(hLib, hCfg, (TWPRequest *) &Request, 0,
+ ppUrls, ELEMENT_NUM(ppUrls), &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(hResponse != NULL);
+ TEST_ASSERT(TWPResponseGetUrlRatingByUrl(hLib, hResponse, ppUrls[0], strlen(ppUrls[0]), &hRating) == TWP_SUCCESS);
+ TEST_ASSERT(TWPUrlRatingGetCategories(hLib, hRating, &pCategories, &uLength) == TWP_SUCCESS);
+ TEST_ASSERT(pCategories != NULL);
+ TEST_ASSERT(TWPResponseDestroy(hLib, &hResponse) == TWP_SUCCESS);
+ TEST_ASSERT(TWPConfigurationDestroy(hLib, &hCfg) == TWP_SUCCESS);
+ TWPUninitLibrary(hLib);
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPRatingGetCategories_0003(void)
+{
+ TestCase TestCtx;
+ TWPCategories *pCategories;
+ unsigned int uLength;
+
+ TESTCASECTOR(&TestCtx, __FUNCTION__);
+ RemoveEngine();
+ TEST_ASSERT(TWPUrlRatingGetCategories(INVALID_TWPLIB_HANDLE, NULL, &pCategories, &uLength) != TWP_SUCCESS);
+ RestoreEngine();
+ TESTCASEDTOR(&TestCtx);
+}
+
+
+static void TWPStartup(void)
+{
+ extern int TestCasesCount;
+ extern int Success;
+ extern int Failures;
+
+ TestCasesCount = 0;
+ Success = 0;
+ Failures = 0;
+
+ Init.api_version = TWPAPI_VERSION;
+ Init.memallocfunc = (TWPFnMemAlloc) malloc;
+ Init.memfreefunc = free;
+
+ srandom(time(NULL));
+
+ Cfg.config_version = TWPCONFIG_VERSION;
+ Cfg.client_id = "SamsungTizen";
+ Cfg.client_key = "{3353DFB5-6978-43E7-AFBE-E3B251B4C303}";
+ Cfg.host = NULL;
+ Cfg.secure_connection = 0;
+ Cfg.skip_dla = 0;
+ Cfg.obfuscate_request = 1;
+ Cfg.randomfunc = GenerateRandomNumber;
+
+ Request.Request.request_version = TWPREQUEST_VERSION;
+ Request.Request.seturlfunc = CbSetUrl;
+ Request.Request.setmethodfunc = CbSetMethod;
+ Request.Request.sendfunc = CbSend;
+ Request.Request.receivefunc = CbRecv;
+
+ CreateTestDirs();
+}
+
+
+static void TWPCleanup(void)
+{
+ LOG_OUT("@@@@@@@@@@@@@@@@@@@@@@@@\n");
+ LOG_OUT("Test done: %d executed, %d passed, %d failure\n", TestCasesCount, Success, Failures);
+
+ if (Request.hHttp != INVALID_XM_HTTP_HANDLE)
+ XmHttpClose(Request.hHttp);
+
+ DestoryTestDirs();
+}
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef TWPTEST_H
+#define TWPTEST_H
+
+
+#include <setjmp.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TEST_SUITE_VERSION "0.0.1"
+
+/* Immediate value definitions. */
+#define MAX_TEST_NUM 128
+
+/* Maximum WP API name length. */
+#define MAX_TWP_API_NAME_LEN 128
+
+/* Output methods. */
+#define LOG_OUT(fmt, x...) printf("Log:"fmt, ##x)
+
+#define TRY_TEST { \
+ int _ret_ = setjmp(WPJmpBuf); \
+ if (_ret_ == 1) { \
+ Failures++; \
+ } else { \
+
+#define FAIL_TEST longjmp(WPJmpBuf, 1);
+
+#define TESTCASECTOR(_ctx_, _api_) \
+ TRY_TEST \
+ TestCaseCtor(_ctx_, _api_);
+
+#define TESTCASEDTOR(_ctx_) \
+ TestCaseDtor(_ctx_); \
+ } \
+} \
+
+/* Test assert method. */
+#define TEST_ASSERT(cond) if (!(cond)) {LOG_OUT("Test failed!! at : %s, %d\n", __FILE__, __LINE__); FAIL_TEST}
+
+#define ELEMENT_NUM(ary) (sizeof(ary) / sizeof((ary)[0]))
+
+/* Content directory for testing. */
+#define TWP_TEST_CONTENT_DIR "contents_test"
+
+/* Content backup directory. */
+#define TWP_BACKUP_CONTENT_DIR "contents_bak"
+
+
+/**
+ * Test case information data
+ */
+typedef struct TestCase_struct
+{
+ char szAPIName[MAX_TWP_API_NAME_LEN]; /* TWP API names */
+} TestCase;
+
+/**
+ * Test request data structure
+ */
+typedef struct TRequest
+{
+ TWPRequest Request;
+ const char *pszUrl;
+ size_t ResponseLength;
+ char *ResponseBody;
+ XM_HTTP_HANDLE hHttp;
+ char *pData;
+ unsigned int uLength;
+ unsigned int uRead;
+ size_t ResponseBytesRead;
+} TRequest;
+
+
+/*
+ * Very simple/thin porting layer
+ */
+
+/* Test framework */
+extern void TestCaseCtor(TestCase *pCtx, const char *pszAPI);
+extern void TestCaseDtor(TestCase *pCtx);
+extern void RestoreEngine();
+extern void RemoveEngine();
+extern void BackupEngine();
+
+extern TWP_RESULT CbSend(struct TWPRequest *pRequest, TWPResponseHandle hResponse,
+ const void *pData, unsigned int uLength);
+extern TWP_RESULT CbRecv(struct TWPRequest *pRequest, void *pBuffer, unsigned int uBufferLength,
+ unsigned int *puLength);
+extern TWP_RESULT CbSetUrl(struct TWPRequest *pRequest, const char *pszUrl, unsigned int uLength);
+extern TWP_RESULT CbSetMethod(struct TWPRequest *pRequest, TWPSubmitMethod Method);
+extern long GenerateRandomNumber();
+extern void DestoryTestDirs(void);
+extern int CreateTestDirs(void);
+
+extern jmp_buf WPJmpBuf;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TWPTEST_H */
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "TWPImpl.h"
+#include "XMHttp.h"
+#include "TWPTest.h"
+
+
+#if !defined(MIN)
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+
+static void ReportTestCase(TestCase *pCtx);
+static void CallSys(const char *pszCmd);
+static void PutTestRoot(char *pszRoot);
+static char *GetTestRoot(void);
+static char *GetBackupDir(void);
+static void PutBackupDir(char *pszBackupDir);
+
+
+int TestCasesCount = 0;
+int Success = 0;
+int Failures = 0;
+jmp_buf WPJmpBuf;
+TWPResponseHandle hAResponse = NULL;
+
+
+/**
+ * Output for test case result.
+ */
+static void ReportTestCase(TestCase *pCtx)
+{
+ char *pszTmp;
+
+ LOG_OUT("@@@@@@@@@@@@@@@@@@@@@@@@\n");
+
+ LOG_OUT("@ID: TC_SEC_WP_%s\n", pCtx->szAPIName);
+ pszTmp = strchr(pCtx->szAPIName, '_');
+ *pszTmp = 0;
+ LOG_OUT("@API Name: %s\n", pCtx->szAPIName);
+ *pszTmp = '_';
+
+ TestCasesCount++;
+}
+
+
+/**
+ * Test case constructor.
+ */
+void TestCaseCtor(TestCase *pCtx, const char *pszAPI)
+{
+
+ strncpy(pCtx->szAPIName, pszAPI, sizeof(pCtx->szAPIName) - 1);
+}
+
+
+/**
+ * Test case destructor.
+ */
+void TestCaseDtor(TestCase *pCtx)
+{
+
+ ReportTestCase(pCtx);
+ Success++;
+
+ extern TRequest Request;
+ if (Request.ResponseBody != NULL)
+ free(Request.ResponseBody);
+
+ Request.pszUrl = NULL;
+ Request.ResponseLength = 0;
+ Request.ResponseBody = NULL;
+
+ Request.pData = NULL;
+ Request.uLength = 0;
+ Request.uRead = 0;
+ Request.ResponseBytesRead = 0;
+}
+
+
+void BackupEngine()
+{
+ char *pszRoot = GetTestRoot(), *pszCommand;
+
+ if (pszRoot != NULL)
+ {
+ asprintf(&pszCommand, "mkdir %s/backup", pszRoot);
+ CallSys(pszCommand);
+ free(pszCommand);
+
+ asprintf(&pszCommand, "cp -f /opt/usr/share/sec_plugin/libwpengine.so %s/backup", pszRoot);
+ CallSys(pszCommand);
+ free(pszCommand);
+
+ PutTestRoot(pszRoot);
+ }
+}
+
+
+void RestoreEngine()
+{
+ char *pszRoot = GetTestRoot(), *pszCommand;
+
+ if (pszRoot != NULL)
+ {
+ asprintf(&pszCommand, "cp -f %s/backup/libwpengine.so /opt/usr/share/sec_plugin/", pszRoot);
+ CallSys(pszCommand);
+ free(pszCommand);
+
+ PutTestRoot(pszRoot);
+ }
+}
+
+
+void RemoveEngine()
+{
+ char *pszRoot = GetTestRoot(), *pszCommand;
+
+ BackupEngine();
+ if (pszRoot != NULL)
+ {
+ asprintf(&pszCommand, "rm -f /opt/usr/share/sec_plugin/libwpengine.so");
+ CallSys(pszCommand);
+ free(pszCommand);
+ }
+}
+
+
+long GenerateRandomNumber()
+{
+
+ return rand();
+}
+
+
+TWP_RESULT CbSetUrl(struct TWPRequest *pRequest, const char *pszUrl, unsigned int uLength)
+{
+ TRequest *pCtx = (TRequest *) pRequest;
+
+ // LOG_OUT("url is: %s\n", pszUrl);
+ if (pCtx->pszUrl != NULL)
+ free((void *) pCtx->pszUrl);
+ pCtx->pszUrl = strdup(pszUrl);
+
+ return pCtx->pszUrl ? TWP_SUCCESS : TWP_NOMEM;
+}
+
+
+TWP_RESULT CbSetMethod(struct TWPRequest *pRequest, TWPSubmitMethod Method)
+{
+
+ return Method == TWPPOST ? TWP_SUCCESS : TWP_INVALID_PARAMETER;
+}
+
+
+static int CbHttpWrite(void *pPrivate, void const *pData, int iSize)
+{
+ TRequest *pCtx = (TRequest *) pPrivate;
+ char *pTmp = NULL;
+
+ // LOG_OUT("[http] recv data\n");
+ pTmp = (char *) realloc(pCtx->ResponseBody, pCtx->ResponseLength + iSize);
+ if (pTmp == NULL)
+ {
+ LOG_OUT("failed to alloc mem\n");
+ return 0;
+ }
+
+ pCtx->ResponseBody = pTmp;
+ memcpy(pCtx->ResponseBody + pCtx->ResponseLength, pData, iSize);
+ pCtx->ResponseLength += iSize;
+
+ return iSize;
+}
+
+
+static int CbHttpRead(void *pPrivate, void *pData, int iSize)
+{
+ TRequest *pCtx = (TRequest *) pPrivate;
+ unsigned int uToRead = MIN(iSize, pCtx->uLength - pCtx->uRead);
+
+ // LOG_OUT("[http] send data\n");
+
+ memcpy(pData, pCtx->pData + pCtx->uRead, uToRead);
+
+ return (int) uToRead;
+}
+
+
+static long CbHttpGetSize(void *pPrivate)
+{
+ TRequest *pCtx = (TRequest *) pPrivate;
+
+ // LOG_OUT("[http] get size\n");
+
+ return (long) (pCtx->uLength - pCtx->uRead);
+}
+
+
+static TWP_RESULT HttpSend(TRequest *pCtx, const void *pData, unsigned int uLength)
+{
+ int iRet;
+ XmHttpCallbacks HttpCb;
+
+ if (pCtx->hHttp == INVALID_XM_HTTP_HANDLE)
+ {
+ pCtx->hHttp = XmHttpOpen();
+ if (pCtx->hHttp == NULL)
+ return TWP_NOMEM;
+ }
+
+ HttpCb.pfWrite = CbHttpWrite;
+ HttpCb.pfRead = CbHttpRead;
+ HttpCb.pfGetSize = CbHttpGetSize;
+
+ pCtx->pData = (char *) pData;
+ pCtx->uLength = uLength;
+
+ iRet = XmHttpExec(pCtx->hHttp, "POST", pCtx->pszUrl, &HttpCb, pCtx);
+
+ return iRet == 0 ? TWP_SUCCESS : TWP_ERROR;
+}
+
+
+TWP_RESULT CbSend(struct TWPRequest *pRequest, TWPResponseHandle hResponse,
+ const void *pData, unsigned int uLength)
+{
+
+ // For a-sync call
+ hAResponse = hResponse;
+ return HttpSend((TRequest *) pRequest, pData, uLength);
+}
+
+
+TWP_RESULT CbRecv(struct TWPRequest *pRequest, void *pBuffer, unsigned int uBufferLength,
+ unsigned int *puLength)
+{
+ TRequest* pCtx = (TRequest*) pRequest;
+ size_t BytesToCopy = 0;
+
+ if ( pCtx->ResponseBytesRead < pCtx->ResponseLength )
+ {
+ BytesToCopy = uBufferLength < (pCtx->ResponseLength - pCtx->ResponseBytesRead) ? uBufferLength : (pCtx->ResponseLength - pCtx->ResponseBytesRead);
+ memcpy(pBuffer, (void*) (pCtx->ResponseBody + pCtx->ResponseBytesRead), BytesToCopy);
+ pCtx->ResponseBytesRead += BytesToCopy;
+ }
+
+ *puLength = (int) BytesToCopy;
+
+ return TWP_SUCCESS;
+}
+
+
+static void CallSys(const char *pszCmd)
+{
+ int iRet = 0;
+ iRet = system(pszCmd);
+ if (iRet != 0)
+ {
+ // LOG_OUT("failed to exe command: %x\n", (int) pszCmd);
+ }
+}
+
+
+/**
+ * Test framework helper function: get content files' root path.
+ */
+static char *GetTestRoot(void)
+{
+ int iLen, iEnvLen;
+ char *pszRoot = NULL, *pszEnv = getenv("TWP_CONTENT_PATH");
+
+ if (pszEnv != NULL &&
+ (iEnvLen = strlen(pszEnv)) > 0)
+ {
+ iLen = iEnvLen;
+ iLen += 64; /* Reserved 64 bytes for PID. */
+ iLen += strlen(TWP_TEST_CONTENT_DIR);
+ pszRoot = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszRoot != NULL)
+ {
+ if (pszEnv[iEnvLen - 1] != '/')
+ snprintf(pszRoot, iLen, "%s/%d/%s", pszEnv, (int) getpid(),
+ TWP_TEST_CONTENT_DIR);
+ else
+ snprintf(pszRoot, iLen, "%s%d/%s", pszEnv, (int) getpid(),
+ TWP_TEST_CONTENT_DIR);
+ }
+ }
+ else
+ {
+ iLen = sizeof("./") + 64; /* Reserved 64 bytes for PID. */
+ pszRoot = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszRoot != NULL)
+ {
+ snprintf(pszRoot, iLen, "./%d", (int) getpid());
+ }
+ }
+
+ return pszRoot;
+}
+
+
+static void PutTestRoot(char *pszRoot)
+{
+
+ if (pszRoot != NULL)
+ free(pszRoot);
+}
+
+
+int CreateTestDirs(void)
+{
+ int iLen, iRet = -1;
+ char *pszCommand, *pszRoot = GetTestRoot(), *pszEnv, *pszBackup;
+
+ if (pszRoot != NULL)
+ {
+ pszBackup = GetBackupDir();
+ if (pszBackup != NULL)
+ {
+ iLen = MAX(strlen(pszRoot) * 2, strlen(pszBackup));
+ iLen += 64; /* Reserved for "mkdir -p", "cp -f " */
+ pszCommand = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszCommand != NULL)
+ {
+ snprintf(pszCommand, iLen, "mkdir -p %s", pszRoot);
+ CallSys(pszCommand);
+ pszCommand[0] = 0;
+
+ snprintf(pszCommand, iLen, "mkdir -p %s", pszBackup);
+ CallSys(pszCommand);
+ pszCommand[0] = 0;
+
+ pszEnv = getenv("TWP_CONTENT_PATH");
+ if (pszEnv == NULL)
+ pszEnv = "./";
+ if (pszEnv[strlen(pszEnv) - 1] == '/')
+ snprintf(pszCommand, iLen, "cp -f %s* %s", pszEnv, pszRoot);
+ else
+ snprintf(pszCommand, iLen, "cp -f %s/* %s", pszEnv, pszRoot);
+ CallSys(pszCommand);
+
+ free(pszCommand);
+
+ iRet = 0;
+ }
+ PutBackupDir(pszBackup);
+ }
+ PutTestRoot(pszRoot);
+ }
+
+ return iRet;
+}
+
+
+void DestoryTestDirs(void)
+{
+ int iLen, iEnvLen;
+ char *pszCommand, *pszEnv = getenv("TWP_CONTENT_PATH");
+
+ if (pszEnv == NULL || strlen(pszEnv) == 0)
+ pszEnv = "./";
+ iEnvLen = strlen(pszEnv);
+ iLen = iEnvLen;
+ iLen += 72; /* Reserved for "rm -rf" and PID */
+ pszCommand = (char *) calloc(iLen + 1, sizeof(char));
+ if (pszCommand != NULL)
+ {
+ if (pszEnv[iEnvLen - 1] == '/')
+ snprintf(pszCommand, iLen, "rm -rf %s%d", pszEnv, (int) getpid());
+ else
+ snprintf(pszCommand, iLen, "rm -rf %s/%d", pszEnv, (int) getpid());
+ CallSys(pszCommand);
+ free(pszCommand);
+ }
+}
+
+
+static char *GetBackupDir(void)
+{
+ int iLen, iEnvLen;
+ char *pszEnv = getenv("TWP_CONTENT_PATH"), *pszPath;
+
+ if (pszEnv == NULL || strlen(pszEnv) == 0)
+ pszEnv = "./";
+ iEnvLen = strlen(pszEnv);
+ iLen = iEnvLen;
+ iLen += strlen(TWP_BACKUP_CONTENT_DIR);
+ iLen += 64; /* Reserved for slash char and PID. */
+ pszPath = (char *) calloc(iLen + 1, sizeof(char));
+
+ if (pszPath)
+ {
+ if (pszEnv[iEnvLen - 1] == '/')
+ snprintf(pszPath, iLen, "%s%d/%s", pszEnv, (int) getpid(),
+ TWP_BACKUP_CONTENT_DIR);
+ else
+ snprintf(pszPath, iLen, "%s/%d/%s", pszEnv, (int) getpid(),
+ TWP_BACKUP_CONTENT_DIR);
+ }
+
+ return pszPath;
+}
+
+
+static void PutBackupDir(char *pszBackupDir)
+{
+
+ if (pszBackupDir != NULL)
+ free(pszBackupDir);
+}
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef URL_INFO_H
+#define URL_INFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_CATEGORIES 8
+
+#define URL_0_0 "http://www.screensavers.com"
+#define URL_1_0 "http://www.google.com"
+#define URL_2_0 "http://www.targetingnow.com/delivery"
+#define URL_3_0 "www.zcrack.com"
+
+TWPCategories CATEGORIES_0_0_1[2] =
+{
+ TWP_Malicioussites,
+ TWP_OverallRiskHigh
+};
+
+TWPCategories CATEGORIES_0_0_0[2] =
+{
+ TWP_Pharmacy,
+ TWP_Restaurants
+};
+
+TWPCategories CATEGORIES_0_0_2[2] =
+{
+ TWP_Malicioussites,
+ TWP_OverallRiskHigh
+};
+
+TWPCategories VIOLATIONS_0_0_2[2] =
+{
+ TWP_Malicioussites,
+ TWP_OverallRiskHigh
+};
+
+#define SCORE_0_0 127
+#define CATEGORY_0_0_0 TWP_Pharmacy
+#define CATEGORY_0_0_1 TWP_OverallRiskHigh
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* URL_INFO_H */
+
--- /dev/null
+#
+# Copyright (c) 2013, McAfee, Inc.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this list
+# of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice, this
+# list of conditions and the following disclaimer in the documentation and/or other
+# materials provided with the distribution.
+#
+# Neither the name of McAfee, Inc. nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific prior
+# written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+OUTDIR=bin
+SRCDIR=.
+
+ifeq ($(TCS_CC), )
+ CC = gcc
+else
+ CC = $(TCS_CC)
+endif
+ifeq ($(TCS_LD), )
+ LD = gcc
+else
+ LD = $(TCS_LD)
+endif
+
+TWP_HEADER_FILE_PATH=../../framework
+
+CFLAGS=-fstack-protector-all -fPIC -g -Wall -O3 -I$(SRCDIR) -I$(TWP_HEADER_FILE_PATH)
+LDFLAGS= -lc -pthread -L../../framework/lib -lsecfw -ldl
+
+TARGET=$(OUTDIR)/twptest
+
+SOURCES=$(SRCDIR)/TWPTest.c \
+ $(SRCDIR)/TWPTestUtils.c \
+ $(SRCDIR)/XMHttp.c \
+ $(SRCDIR)/XMPHttp.c
+OBJECTS=$(OUTDIR)/TWPTest.o \
+ $(OUTDIR)/TWPTestUtils.o \
+ $(OUTDIR)/XMHttp.o \
+ $(OUTDIR)/XMPHttp.o
+
+$(OUTDIR)/%.o: $(SRCDIR)/%.c
+ $(CC) $(CFLAGS) -o $(OUTDIR)/$*.o -c $(SRCDIR)/$*.c
+
+$(TARGET): $(OUTDIR) $(OBJECTS) $(SOURCES)
+ $(LD) -o $(TARGET) $(OBJECTS) $(LDFLAGS)
+
+all: $(TARGET)
+
+$(OUTDIR):
+ @mkdir $(OUTDIR)
+
+clean:
+ @rm -rf $(OUTDIR)
+
+distclean: clean
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <malloc.h>
+
+#include "XMPHttp.h"
+
+
+typedef struct XmHttpCtx_struct
+{
+ XmPHttpCtx PCtx;
+} XmHttpCtx;
+
+
+XM_HTTP_HANDLE XmHttpOpen()
+{
+ XmHttpCtx *pCtx;
+
+ if ((pCtx = (XmHttpCtx *) malloc(sizeof(XmHttpCtx))) == NULL)
+ return INVALID_XM_HTTP_HANDLE;
+ if (XmPHttpInit(&pCtx->PCtx) < 0)
+ {
+ free(pCtx);
+ return INVALID_XM_HTTP_HANDLE;
+ }
+
+ return (XM_HTTP_HANDLE) pCtx;
+}
+
+
+void XmHttpClose(XM_HTTP_HANDLE hHTTP)
+{
+ XmHttpCtx *pCtx = (XmHttpCtx *) hHTTP;
+
+ XmPHttpCleanup(&pCtx->PCtx);
+ free(pCtx);
+}
+
+
+int XmHttpExec(XM_HTTP_HANDLE hHTTP, char const *pszMethod, char const *pszURL,
+ XmHttpCallbacks *pHCB, void *pPrivate)
+{
+ XmHttpCtx *pCtx = (XmHttpCtx *) hHTTP;
+
+ return XmPHttpExec(&pCtx->PCtx, pszMethod, pszURL, pHCB, pPrivate);
+}
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#if !defined(_XMHTTP_H)
+#define _XMHTTP_H
+
+#if defined(__cplusplus)
+#define EXTERNC_BEGIN extern "C" {
+#define EXTERNC_END }
+#define EXTERNC extern "C"
+#else
+#define EXTERNC_BEGIN
+#define EXTERNC_END
+#define EXTERNC
+#endif
+
+#define XMHANDLE(n) struct n##_struct { int iDummy; }; typedef struct n##_struct *n
+
+XMHANDLE(XM_HTTP_HANDLE);
+
+#define INVALID_XM_HTTP_HANDLE ((XM_HTTP_HANDLE) 0)
+
+typedef struct XmHttpCallbacks_struct
+{
+ int (*pfWrite)(void *pPrivate, void const *pData, int iSize);
+ int (*pfRead)(void *pPrivate, void *pData, int iSize);
+ long (*pfGetSize)(void *pPrivate);
+} XmHttpCallbacks;
+
+
+EXTERNC_BEGIN;
+
+XM_HTTP_HANDLE XmHttpOpen();
+void XmHttpClose(XM_HTTP_HANDLE hHTTP);
+int XmHttpExec(XM_HTTP_HANDLE hHTTP, char const *pszMethod, char const *pszURL,
+ XmHttpCallbacks *pHCB, void *pPrivate);
+
+EXTERNC_END;
+
+#endif
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdarg.h>
+
+#include <XMPHttp.h>
+
+#define XME_HTTP_TIMEOUT 11300
+#define XME_HTTP_SELECT 11301
+#define XME_HTTP_SKREAD 11302
+#define XME_HTTP_SKWRITE 11303
+#define XME_HTTP_SETSOCKOPT 11003
+#define XME_HTTP_DISCONNECT 11005
+#define XME_HTTP_UNKNOWN_HOST 11006
+#define XME_HTTP_CONNECT 11007
+
+#define SOCK_STD_CONTIMEO 60
+#define SOCK_STD_RCVTIMEO 60
+#define SOCK_STD_SNDTIMEO 60
+#define HTTP_DEFAULT_PORT 80
+#define HTTPS_DEFAULT_PORT 443
+#define CONTLEN_HEADER "Content-Length:"
+#define CONTENC_HEADER "Transfer-Encoding:"
+#define CHUNKED_ENCODED(s) (strcasecmp(s, "chunked") == 0)
+#define XM_HTTP_HEADERS "XM_HTTP_HEADERS"
+#define XM_HTTP_VERSION "XM_HTTP_VERSION"
+#define XM_SKRECV_TIMEO "XM_NET_RECVTIMEO"
+#define XM_SKSEND_TIMEO "XM_NET_SENDTIMEO"
+#define XM_SKCONN_TIMEO "XM_NET_CONNTIMEO"
+
+
+#define SSTREAM_BUFFER_SIZE 4096
+
+#define URL_PROTO_HTTP 1
+#define URL_PROTO_HTTPS 2
+
+#if !defined(INADDR_NONE)
+#define INADDR_NONE ((XmUInt32) -1)
+#endif
+
+#define URL_PARSE_INIT { 0, NULL, 0, NULL, NULL }
+
+#define PHTTP_MIN(a, b) ((a) < (b) ? (a): (b))
+#define PHTTP_SKIPSPACE(p) for(; *(p) == ' ' || *(p) == '\t'; (p)++)
+#define PHTTP_CSTRSIZE(s) (sizeof(s) - 1)
+
+#define PHTTP_DBGPRINT(c, args) do { if ((c)->iPHttpDebug) XmPHttpDbgPrintf args; } while (0)
+
+#define PHTTP_ENVGET(c, s) getenv(s)
+#define PHTTP_ENVFREE(e) free(e)
+
+
+#define INVALID_SOCKET (-1)
+#define closesocket(s) close(s)
+#define PHTTP_INPROGRESS(SockFd) (errno == EINPROGRESS || errno == EWOULDBLOCK)
+
+typedef int SOCKET;
+
+
+struct PHttpUrl
+{
+ int iProto;
+ char const *pszHost;
+ int iPort;
+ char const *pszDoc;
+ char const *pszUrl;
+};
+
+struct SStream
+{
+ XmPHttpCtx *pCtx;
+ SOCKET SockFd;
+ int iReadTimeo, iWriteTimeo;
+ int iIndex;
+ int iInBuffer;
+ char Buffer[SSTREAM_BUFFER_SIZE];
+};
+
+
+static int XmPHttpDbgPrintf(char const *pszFmt, ...)
+{
+ int iPrintRes;
+ va_list Args;
+
+ va_start(Args, pszFmt);
+ iPrintRes = vfprintf(stderr, pszFmt, Args);
+ va_end(Args);
+
+ return iPrintRes;
+}
+
+static int XmPHttpGetIntEnv(XmPHttpCtx *pCtx, char const *pszVar, int iDefault)
+{
+ int iValue = iDefault;
+ char *pszValue;
+
+ if ((pszValue = (char *) PHTTP_ENVGET(pCtx, pszVar)) != NULL)
+ {
+ PHTTP_DBGPRINT(pCtx, ("[phttp] %s environment is '%s'\n", pszVar, pszValue));
+
+ iValue = atoi(pszValue);
+ PHTTP_ENVFREE(pszValue);
+ }
+
+ return iValue;
+}
+
+static int XmPHttpSkBlocking(SOCKET SockFd, int iOn)
+{
+ int iFlags, iError;
+
+ if ((iFlags = fcntl(SockFd, F_GETFL, 0)) == -1)
+ return -XME_HTTP_SETSOCKOPT;
+ if (iOn)
+ iError = fcntl(SockFd, F_SETFL, iFlags & ~O_NONBLOCK);
+ else
+ iError = fcntl(SockFd, F_SETFL, iFlags | O_NONBLOCK);
+
+ return iError == -1 ? -XME_HTTP_SETSOCKOPT: 0;
+}
+
+static int XmPHttpSkConnect(SOCKET SockFd, struct sockaddr *pAddr, int iAddrSize,
+ int iTimeout)
+{
+ int iError;
+
+ if ((iError = XmPHttpSkBlocking(SockFd, 0)) < 0)
+ return iError;
+ if (connect(SockFd, pAddr, iAddrSize) != 0)
+ {
+ struct timeval TV;
+ fd_set FdSet;
+
+ if (!PHTTP_INPROGRESS(SockFd))
+ return -XME_HTTP_CONNECT;
+ FD_ZERO(&FdSet);
+ FD_SET(SockFd, &FdSet);
+ TV.tv_sec = iTimeout;
+ TV.tv_usec = 0;
+ if (select((int) SockFd + 1, NULL, &FdSet, NULL, &TV) < 0)
+ return -XME_HTTP_SELECT;
+ if (!FD_ISSET(SockFd, &FdSet))
+ return -XME_HTTP_TIMEOUT;
+ }
+
+ return XmPHttpSkBlocking(SockFd, 1);
+}
+
+static int XmPHttpSkRead(SOCKET SockFd, void *pData, int iSize, int iTimeout)
+{
+ int iRead;
+ struct timeval TV;
+ fd_set FdSet;
+
+ FD_ZERO(&FdSet);
+ FD_SET(SockFd, &FdSet);
+ TV.tv_sec = iTimeout;
+ TV.tv_usec = 0;
+ if (select((int) SockFd + 1, &FdSet, NULL, NULL, &TV) < 0)
+ return -XME_HTTP_SELECT;
+ if (!FD_ISSET(SockFd, &FdSet))
+ return -XME_HTTP_TIMEOUT;
+ if ((iRead = recv(SockFd, pData, iSize, 0)) < 0)
+ return -XME_HTTP_SKREAD;
+ else if (iRead == 0)
+ return -XME_HTTP_DISCONNECT;
+
+ return iRead;
+}
+
+static int XmPHttpSkWrite(SOCKET SockFd, void const *pData, int iSize, int iTimeout)
+{
+ int iWrite;
+ struct timeval TV;
+ fd_set FdSet;
+
+ FD_ZERO(&FdSet);
+ FD_SET(SockFd, &FdSet);
+ TV.tv_sec = iTimeout;
+ TV.tv_usec = 0;
+ if (select((int) SockFd + 1, NULL, &FdSet, NULL, &TV) < 0)
+ return -XME_HTTP_SELECT;
+ if (!FD_ISSET(SockFd, &FdSet))
+ return -XME_HTTP_TIMEOUT;
+ if ((iWrite = send(SockFd, pData, iSize, 0)) < 0)
+ return -XME_HTTP_SKWRITE;
+
+ return iWrite;
+}
+
+static SOCKET XmPHttpSocket(XmPHttpCtx *pCtx)
+{
+ SOCKET SockFd;
+
+ if ((SockFd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+ {
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Socket creation failed\n"));
+ return INVALID_SOCKET;
+ }
+
+ return SockFd;
+}
+
+int XmPHttpInit(XmPHttpCtx *pCtx)
+{
+ pCtx->iPHttpDebug = 0;
+ pCtx->iPHttpConnTimeo = XmPHttpGetIntEnv(pCtx, XM_SKCONN_TIMEO, SOCK_STD_CONTIMEO);
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Library initialization succeeded\n"));
+
+ return 0;
+}
+
+void XmPHttpCleanup(XmPHttpCtx *pCtx)
+{
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Library cleanup done\n"));
+}
+
+static struct SStream *XmPHttpStreamAttach(XmPHttpCtx *pCtx, SOCKET SockFd)
+{
+ struct SStream *pStream;
+
+ if ((pStream = (struct SStream *) malloc(sizeof(struct SStream))) == NULL)
+ return NULL;
+
+ pStream->pCtx = pCtx;
+ pStream->SockFd = SockFd;
+ pStream->iIndex = 0;
+ pStream->iInBuffer = 0;
+ pStream->iReadTimeo = XmPHttpGetIntEnv(pCtx, XM_SKRECV_TIMEO, SOCK_STD_RCVTIMEO);
+ pStream->iWriteTimeo = XmPHttpGetIntEnv(pCtx, XM_SKSEND_TIMEO, SOCK_STD_SNDTIMEO);
+
+ return pStream;
+}
+
+static void XmPHttpStreamClose(struct SStream *pStream)
+{
+ closesocket(pStream->SockFd);
+ PHTTP_DBGPRINT(pStream->pCtx, ("[phttp] Socket closed: sock=%u\n", pStream->SockFd));
+ free(pStream);
+}
+
+static int XmPHttpStreamBRefil(struct SStream *pStream)
+{
+ XmPHttpCtx *pCtx = pStream->pCtx;
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Reading socket: sock=%u\n", pStream->SockFd));
+ pStream->iIndex = 0;
+
+ pStream->iInBuffer = XmPHttpSkRead(pStream->SockFd, pStream->Buffer,
+ SSTREAM_BUFFER_SIZE, pStream->iReadTimeo);
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Socket read done: sock=%u recv=%d\n", pStream->SockFd,
+ pStream->iInBuffer));
+ if (pStream->iInBuffer < 0)
+ PHTTP_DBGPRINT(pCtx, ("[phttp] error is %d\n", (unsigned int) -pStream->iInBuffer));
+
+ return pStream->iInBuffer;
+}
+
+static char *XmPHttpRdLine(char *pszLine, int iSize, struct SStream *pStream)
+{
+ int iLnSize, iTxSize;
+ XmPHttpCtx *pCtx = pStream->pCtx;
+ char *pszNL;
+
+ for (iLnSize = 0, iSize--; iLnSize < iSize;)
+ {
+ if (pStream->iIndex >= pStream->iInBuffer &&
+ XmPHttpStreamBRefil(pStream) <= 0)
+ break;
+
+ if ((pszNL = (char *) memchr(pStream->Buffer + pStream->iIndex, '\n',
+ pStream->iInBuffer - pStream->iIndex)) != NULL)
+ {
+ iTxSize = PHTTP_MIN(iSize - iLnSize,
+ (int) (pszNL - (pStream->Buffer + pStream->iIndex) + 1));
+ memcpy(pszLine + iLnSize, pStream->Buffer + pStream->iIndex, iTxSize);
+ pStream->iIndex += iTxSize;
+ iLnSize += iTxSize;
+ break;
+ }
+ else
+ {
+ iTxSize = PHTTP_MIN(iSize - iLnSize, pStream->iInBuffer - pStream->iIndex);
+ memcpy(pszLine + iLnSize, pStream->Buffer + pStream->iIndex, iTxSize);
+ pStream->iIndex += iTxSize;
+ iLnSize += iTxSize;
+ }
+ }
+
+ if (iLnSize == 0)
+ return NULL;
+
+ for (; iLnSize > 0 && (pszLine[iLnSize - 1] == '\r' ||
+ pszLine[iLnSize - 1] == '\n'); iLnSize--);
+ pszLine[iLnSize] = '\0';
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Line read: sock=%u\n"
+ "\t'%s'\n", pStream->SockFd, pszLine));
+
+ return pszLine;
+}
+
+static int XmPHttpRead(char *pData, int iSize, struct SStream *pStream)
+{
+ int iRead = 0, iRxSize;
+ XmPHttpCtx *pCtx = pStream->pCtx;
+
+ if (pStream->iIndex < pStream->iInBuffer)
+ {
+ iRxSize = PHTTP_MIN(iSize, pStream->iInBuffer - pStream->iIndex);
+ memcpy(pData, pStream->Buffer + pStream->iIndex, iRxSize);
+ pStream->iIndex += iRxSize;
+ iRead += iRxSize;
+ }
+ while (iRead < iSize)
+ {
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Reading socket: sock=%u\n", pStream->SockFd));
+
+ iRxSize = XmPHttpSkRead(pStream->SockFd, pData + iRead,
+ iSize - iRead, pStream->iReadTimeo);
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Socket read done: sock=%u recv=%d\n", pStream->SockFd,
+ iRxSize));
+ if (iRxSize < 0)
+ break;
+ iRead += iRxSize;
+ }
+
+ return iRead;
+}
+
+static int XmPHttpPrintf(struct SStream *pStream, char const *pszFmt, ...)
+{
+ int iSize, iSent, iTxSize;
+ XmPHttpCtx *pCtx = pStream->pCtx;
+ va_list Args;
+ char szBuffer[4096];
+
+ va_start(Args, pszFmt);
+
+ iSize = vsnprintf(szBuffer, sizeof(szBuffer) - 1, pszFmt, Args);
+
+ va_end(Args);
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Sending ...\n"
+ "(\n"
+ "%s"
+ ")\n", szBuffer));
+ for (iSent = 0; iSent < iSize;)
+ {
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Writing socket: sock=%u\n", pStream->SockFd));
+
+ iTxSize = XmPHttpSkWrite(pStream->SockFd, szBuffer + iSent,
+ iSize - iSent, pStream->iWriteTimeo);
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Socket write done: sock=%u send=%d\n", pStream->SockFd,
+ iTxSize));
+ if (iTxSize < 0)
+ break;
+ iSent += iTxSize;
+ }
+
+ return iSize;
+}
+
+static int XmPHttpWrite(char const *pData, int iSize, struct SStream *pStream)
+{
+ int iSent, iTxSize;
+ XmPHttpCtx *pCtx = pStream->pCtx;
+
+ for (iSent = 0; iSent < iSize;)
+ {
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Writing socket: sock=%u\n", pStream->SockFd));
+
+ iTxSize = XmPHttpSkWrite(pStream->SockFd, pData + iSent,
+ iSize - iSent, pStream->iWriteTimeo);
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Socket write done: sock=%u send=%d\n", pStream->SockFd,
+ iTxSize));
+ if (iTxSize < 0)
+ break;
+ iSent += iTxSize;
+ }
+
+ return iSize;
+}
+
+static struct SStream *XmPHttpConnect(XmPHttpCtx *pCtx, char const *pszServer, int iPort)
+{
+ int iError;
+ SOCKET SockFd;
+ struct hostent *pHE;
+ struct SStream *pStream;
+ struct in_addr InAddr;
+ struct sockaddr_in SAIn;
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Resolving server name: server='%s'\n", pszServer));
+ if ((InAddr.s_addr = inet_addr(pszServer)) == INADDR_NONE)
+ {
+ if ((pHE = gethostbyname(pszServer)) == NULL)
+ {
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Server name resolve error: server='%s'\n", pszServer));
+ return NULL;
+ }
+
+ memcpy(&InAddr.s_addr, pHE->h_addr_list[0], pHE->h_length);
+ }
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Server name resolved: server='%s'\n", pszServer));
+
+ if ((SockFd = XmPHttpSocket(pCtx)) == INVALID_SOCKET)
+ return NULL;
+
+ memset(&SAIn, 0, sizeof(SAIn));
+ memcpy(&SAIn.sin_addr, &InAddr.s_addr, 4);
+ SAIn.sin_port = htons((short int) iPort);
+ SAIn.sin_family = AF_INET;
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Connecting to remote server: server='%s'\n", pszServer));
+ if ((iError = XmPHttpSkConnect(SockFd, (struct sockaddr *) &SAIn, sizeof(SAIn),
+ pCtx->iPHttpConnTimeo)) < 0)
+ {
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Connect failed: server='%s'\n", pszServer));
+ closesocket(SockFd);
+ return NULL;
+ }
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Connect succeeded: server='%s'\n", pszServer));
+
+ if ((pStream = XmPHttpStreamAttach(pCtx, SockFd)) == NULL)
+ {
+ closesocket(SockFd);
+ return NULL;
+ }
+
+ return pStream;
+}
+
+static int XmPHttpSendRequest(struct SStream *pStream, char const *pszServer,
+ char const *pszReq, char const *pszDoc,
+ char const * const *ppszHdrs,
+ XmHttpCallbacks *pHCB, void *pPrivate)
+{
+ int i, iCurr;
+ long lReqSize, lRead;
+ XmPHttpCtx *pCtx = pStream->pCtx;
+ char *pszHttpVer;
+ char TxBuff[512];
+
+ if ((lReqSize = pHCB->pfGetSize(pPrivate)) < 0)
+ return -1;
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Outbound data length retrieved: size=%ld\n",
+ lReqSize));
+
+ pszHttpVer = (char *) PHTTP_ENVGET(pCtx, XM_HTTP_VERSION);
+ if (XmPHttpPrintf(pStream, "%s %s %s\r\n", pszReq, pszDoc,
+ pszHttpVer != NULL ? pszHttpVer: "HTTP/1.0") < 0 ||
+ XmPHttpPrintf(pStream, "Host: %s\r\n", pszServer) < 0)
+ {
+ PHTTP_ENVFREE(pszHttpVer);
+ return -1;
+ }
+ PHTTP_ENVFREE(pszHttpVer);
+ if (ppszHdrs)
+ for (i = 0; ppszHdrs[i]; i++)
+ if (XmPHttpPrintf(pStream, "%s\r\n", ppszHdrs[i]) < 0)
+ return -1;
+
+ if (XmPHttpPrintf(pStream, "Content-Length: %ld\r\n\r\n", lReqSize) < 0)
+ return -1;
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Reading and sending outbound data: sock=%u\n",
+ pStream->SockFd));
+ for (lRead = 0; lRead < lReqSize;)
+ {
+ iCurr = (int) PHTTP_MIN(lReqSize - lRead, sizeof(TxBuff));
+ if (pHCB->pfRead(pPrivate, TxBuff, iCurr) != iCurr ||
+ XmPHttpWrite(TxBuff, iCurr, pStream) != iCurr)
+ return -1;
+ lRead += iCurr;
+ }
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Outbound data sent: sock=%u\n", pStream->SockFd));
+
+ return 0;
+}
+
+static void XmPHttpParseInit(struct PHttpUrl *pPU)
+{
+ memset(pPU, 0, sizeof(*pPU));
+}
+
+static int XmPHttpParseUrl(XmPHttpCtx *pCtx, struct PHttpUrl *pPU, char const *pszUrl)
+{
+ char *pszDUrl = strdup(pszUrl), *pszTmp;
+
+ if (pszDUrl == NULL)
+ {
+ return -1;
+ }
+
+ memset(pPU, 0, sizeof(*pPU));
+ pPU->pszUrl = pszDUrl;
+ if (!strncasecmp(pszDUrl, "http://", 7))
+ pPU->iProto = URL_PROTO_HTTP, pszDUrl += 7, pPU->iPort = HTTP_DEFAULT_PORT;
+ else if (!strncasecmp(pszDUrl, "https://", 8))
+ pPU->iProto = URL_PROTO_HTTPS, pszDUrl += 8, pPU->iPort = HTTPS_DEFAULT_PORT;
+ else
+ pPU->iProto = URL_PROTO_HTTP, pPU->iPort = HTTP_DEFAULT_PORT;
+
+ pPU->pszHost = pszDUrl;
+
+ if ((pszTmp = strchr(pszDUrl, ':')) != NULL)
+ {
+ *pszTmp++ = '\0';
+ if (!isdigit(*pszTmp))
+ {
+ free((char *) pPU->pszUrl);
+ memset(pPU, 0, sizeof(*pPU));
+ return -1;
+ }
+ pPU->iPort = atoi(pszTmp);
+ pszDUrl = pszTmp;
+ }
+
+ if ((pszTmp = strchr(pszDUrl, '/')) != NULL)
+ {
+ pPU->pszDoc = strdup(pszTmp);
+ *pszTmp++ = '\0';
+ }
+ else
+ pPU->pszDoc = strdup("/");
+
+ if (pPU->pszDoc == NULL)
+ {
+ free((char *) pPU->pszUrl);
+ memset(pPU, 0, sizeof(*pPU));
+ return -1;
+ }
+
+ return 0;
+}
+
+static void XmPHttpParseFree(struct PHttpUrl *pPU)
+{
+ free((char *) pPU->pszUrl);
+ free((char *) pPU->pszDoc);
+ memset(pPU, 0, sizeof(*pPU));
+}
+
+static int XmPHttpReadChunked(struct SStream *pStream, XmHttpCallbacks *pHCB,
+ void *pPrivate)
+{
+ int iCkSize;
+ // XmPHttpCtx *pCtx = pStream->pCtx;
+ char RxBuff[512];
+
+ do
+ {
+ if (!XmPHttpRdLine(RxBuff, sizeof(RxBuff) - 1, pStream))
+ return -1;
+ if (!sscanf(RxBuff, "%d", &iCkSize))
+ return -1;
+ if (iCkSize)
+ {
+ int iSize, iRead;
+
+ for (iSize = 0; iSize < iCkSize;)
+ {
+ iRead = PHTTP_MIN(iCkSize - iSize, sizeof(RxBuff));
+ if (XmPHttpRead(RxBuff, iRead, pStream) != iRead)
+ return -1;
+ if (pHCB && pHCB->pfWrite &&
+ pHCB->pfWrite(pPrivate, RxBuff, iRead) != iRead)
+ return -1;
+ iSize += iRead;
+ }
+ }
+ } while (iCkSize);
+ while (XmPHttpRdLine(RxBuff, sizeof(RxBuff) - 1, pStream))
+ if (strlen(RxBuff) == 0)
+ break;
+
+ return 0;
+}
+
+static int XmPHttpReadResponse(struct SStream *pStream, XmHttpCallbacks *pHCB,
+ void *pPrivate)
+{
+ int iHttpRCode, iChunked = 0, iValidRCode;
+ long lContLen = -1;
+ char *pszValue;
+ XmPHttpCtx *pCtx = pStream->pCtx;
+ char szBuffer[512];
+
+ if (!XmPHttpRdLine(szBuffer, sizeof(szBuffer) - 1, pStream))
+ return -1;
+
+ PHTTP_DBGPRINT(pCtx, ("[phttp] HTTP response: sock=%u resp='%s'\n", pStream->SockFd, szBuffer));
+ if (!sscanf(szBuffer, "%*s %d %*s", &iHttpRCode))
+ {
+ PHTTP_DBGPRINT(pCtx, ("[phttp] Wrong HTTP response: sock=%u resp='%s'\n", pStream->SockFd, szBuffer));
+ return -1;
+ }
+
+ // printf("[XMPHTTP] : HTTP CODE = %d\n", iHttpRCode);
+ iValidRCode = iHttpRCode == 200 || iHttpRCode == 204;
+ if ((iHttpRCode >= 100 && iHttpRCode < 200) || iHttpRCode == 204 || iHttpRCode == 304)
+ lContLen = 0;
+
+ while (XmPHttpRdLine(szBuffer, sizeof(szBuffer) - 1, pStream) != NULL)
+ {
+ PHTTP_DBGPRINT(pCtx, ("[phttp] HTTP header: sock=%u hdr='%s'\n", pStream->SockFd, szBuffer));
+ if (strlen(szBuffer) == 0)
+ break;
+ if (!strncasecmp(szBuffer, CONTLEN_HEADER, PHTTP_CSTRSIZE(CONTLEN_HEADER)))
+ {
+ pszValue = szBuffer + PHTTP_CSTRSIZE(CONTLEN_HEADER);
+ PHTTP_SKIPSPACE(pszValue);
+ lContLen = atol(pszValue);
+ }
+ else if (!strncasecmp(szBuffer, CONTENC_HEADER, PHTTP_CSTRSIZE(CONTENC_HEADER)))
+ {
+ pszValue = szBuffer + PHTTP_CSTRSIZE(CONTENC_HEADER);
+ PHTTP_SKIPSPACE(pszValue);
+ iChunked = CHUNKED_ENCODED(pszValue);
+ }
+ }
+ if (lContLen >= 0)
+ {
+ int iRead;
+ long lSize;
+
+ for (lSize = 0; lSize < lContLen;)
+ {
+ iRead = (int) PHTTP_MIN(lContLen - lSize, sizeof(szBuffer));
+ if (XmPHttpRead(szBuffer, iRead, pStream) != iRead)
+ return -1;
+ if (iValidRCode && pHCB->pfWrite &&
+ pHCB->pfWrite(pPrivate, szBuffer, iRead) != iRead)
+ return -1;
+ lSize += iRead;
+ }
+ }
+ else if (iChunked)
+ {
+ if (XmPHttpReadChunked(pStream, iValidRCode ? pHCB: NULL, pPrivate) < 0)
+ return -1;
+ }
+ else
+ {
+ int iRead;
+ long lSize;
+
+ for (lSize = 0;;)
+ {
+ if ((iRead = XmPHttpRead(szBuffer, sizeof(szBuffer), pStream)) <= 0)
+ break;
+ if (iValidRCode && pHCB->pfWrite &&
+ pHCB->pfWrite(pPrivate, szBuffer, iRead) != iRead)
+ return -1;
+ lSize += iRead;
+ }
+ }
+
+ return iValidRCode ? 0: -1;
+}
+
+static char **XmPHttpHdrSplit(char const *pszStr)
+{
+ int i, j, k, iNumStrs;
+ void *pMemBlk;
+ char **ppszPtrs;
+ char *pszDupStr;
+
+ for (i = 0, iNumStrs = 1; pszStr[i]; i++)
+ if (pszStr[i] == '|')
+ iNumStrs++;
+ if ((pMemBlk = malloc(i + 1 +
+ (iNumStrs + 1) * sizeof(char *))) == NULL)
+ return NULL;
+ ppszPtrs = (char **) pMemBlk;
+ pszDupStr = (char *) pMemBlk + (iNumStrs + 1) * sizeof(char *);
+ memcpy(pszDupStr, pszStr, i + 1);
+ for (i = j = 0, k = -1; pszDupStr[i]; i++)
+ if (pszDupStr[i] == '|')
+ {
+ if (k >= 0)
+ ppszPtrs[j++] = pszDupStr + k;
+ pszDupStr[i] = '\0';
+ k = -1;
+ }
+ else if (k < 0)
+ k = i;
+ if (k >= 0)
+ ppszPtrs[j++] = pszDupStr + k;
+ ppszPtrs[j] = NULL;
+
+ return ppszPtrs;
+}
+
+int XmPHttpExec(XmPHttpCtx *pCtx, char const *pszMethod, char const *pszUrl,
+ XmHttpCallbacks *pHCB, void *pPrivate)
+{
+ char *pszEnv = NULL;
+ char **ppszHdrs = NULL;
+ struct SStream *pStream;
+ struct PHttpUrl PU;
+
+ XmPHttpParseInit(&PU);
+ if (XmPHttpParseUrl(pCtx, &PU, pszUrl) < 0)
+ return -1;
+ if ((pStream = XmPHttpConnect(pCtx, PU.pszHost, PU.iPort)) == NULL)
+ {
+
+ XmPHttpParseFree(&PU);
+ return -1;
+ }
+ if ((pszEnv = (char *) PHTTP_ENVGET(pCtx, XM_HTTP_HEADERS)) != NULL &&
+ (ppszHdrs = XmPHttpHdrSplit(pszEnv)) == NULL)
+ {
+
+ PHTTP_ENVFREE(pszEnv);
+ XmPHttpStreamClose(pStream);
+ XmPHttpParseFree(&PU);
+ return -1;
+ }
+ PHTTP_ENVFREE(pszEnv);
+
+ if (XmPHttpSendRequest(pStream, PU.pszHost, pszMethod, PU.pszDoc,
+ (char const * const *) ppszHdrs, pHCB, pPrivate) < 0 ||
+ XmPHttpReadResponse(pStream, pHCB, pPrivate) < 0)
+ {
+
+ if (ppszHdrs != NULL)
+ free(ppszHdrs);
+ XmPHttpStreamClose(pStream);
+ XmPHttpParseFree(&PU);
+ return -1;
+ }
+ free(ppszHdrs);
+ XmPHttpStreamClose(pStream);
+ XmPHttpParseFree(&PU);
+
+ return 0;
+}
+
--- /dev/null
+/*
+ Copyright (c) 2013, McAfee, Inc.
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list
+ of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+ Neither the name of McAfee, Inc. nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#if !defined(_XMPOSIXHTTP_H)
+#define _XMPOSIXHTTP_H
+
+#include "XMHttp.h"
+
+
+typedef struct XmPHttpCtx_struct
+{
+ int iPHttpConnTimeo;
+ int iPHttpDebug;
+} XmPHttpCtx;
+
+
+EXTERNC_BEGIN;
+
+int XmPHttpInit(XmPHttpCtx *pCtx);
+void XmPHttpCleanup(XmPHttpCtx *pCtx);
+int XmPHttpExec(XmPHttpCtx *pCtx, char const *pszMethod, char const *pszUrl,
+ XmHttpCallbacks *pHCB, void *pPrivate);
+
+EXTERNC_END;
+
+#endif
+