2 Copyright (c) 2014, McAfee, Inc.
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
9 Redistributions of source code must retain the above copyright notice, this list
10 of conditions and the following disclaimer.
12 Redistributions in binary form must reproduce the above copyright notice, this
13 list of conditions and the following disclaimer in the documentation and/or other
14 materials provided with the distribution.
16 Neither the name of McAfee, Inc. nor the names of its contributors may be used
17 to endorse or promote products derived from this software without specific prior
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include "TCSErrorCodes.h"
44 #define TCS_CONSTRUCT_ERRCODE(m, e) (((m) << 24) | (e))
46 #define PLUGIN_PATH "/opt/usr/share/sec_plugin/libengine.so"
49 typedef TCSLIB_HANDLE (*FuncLibraryOpen)(void);
50 typedef int (*FuncLibraryClose)(TCSLIB_HANDLE hLib);
51 typedef TCSErrorCode (*FuncGetLastError)(TCSLIB_HANDLE hLib);
52 typedef int (*FuncScanData)(TCSLIB_HANDLE hLib, TCSScanParam *pParam, TCSScanResult *pResult);
53 typedef int (*FuncScanFile)(TCSLIB_HANDLE hLib, char const *pszFileName, int iDataType,
54 int iAction, int iCompressFlag, TCSScanResult *pResult);
55 typedef int (*FuncScanFileEx)(TCSLIB_HANDLE hLib, char const *pszFileName, int iDataType,
56 int iAction, int iCompressFlag,
57 void *pPrivate, int (*pfCallBack)(void *pPrivate, int iReason, void *pParam),
58 TCSScanResult *pResult);
59 typedef char const* (*FuncGetVersion)();
60 typedef char const* (*FuncGetInfo)();
62 typedef struct PluginContext_struct
66 FuncLibraryOpen pfLibraryOpen;
67 FuncLibraryClose pfLibraryClose;
68 FuncGetLastError pfGetLastError;
69 FuncScanData pfScanData;
70 FuncScanFile pfScanFile;
71 FuncScanFileEx pfScanFileEx;
72 FuncGetVersion pfGetVersion;
73 FuncGetInfo pfGetInfo;
74 pthread_mutex_t mutex;
77 typedef struct ThreadScanFileData_struct
85 int (*pfCallBack)(void *pPrivate, int iReason, void *pParam);
88 typedef struct ThreadScanData_struct
94 static PluginContext *LoadPlugin(void);
97 TCSLIB_HANDLE TCSLibraryOpen(void)
99 PluginContext *pCtx = NULL;
101 DDBG("%s", "tcs lib open\n");
105 if (pCtx->pfLibraryOpen == NULL)
108 return INVALID_TCSLIB_HANDLE;
110 DDBG("%s", "call to TCSPLibraryOpen\n");
111 pCtx->hLib = (*pCtx->pfLibraryOpen)();
112 if (pCtx->hLib == INVALID_TCSLIB_HANDLE)
114 DDBG("%s", "failed to open engine\n");
115 if (pCtx->pPlugin != NULL)
116 dlclose(pCtx->pPlugin);
121 pthread_mutex_init(&(pCtx->mutex), NULL);
122 return (TCSLIB_HANDLE) pCtx;
126 return INVALID_TCSLIB_HANDLE;
130 int TCSGetVersion(TCSLIB_HANDLE hLib, TCSVerInfo *pVerInfo)
132 PluginContext *pCtx = (PluginContext *) hLib;
134 if (pCtx == NULL || pCtx->pfGetVersion == NULL)
139 if (pVerInfo == NULL)
144 strncpy(pVerInfo->szFrameworkVer, TCS_FRAMEWORK_VERSION, TCS_VER_MAX);
146 char const *pPluginVer = (*pCtx->pfGetVersion)();
148 if (pPluginVer != NULL)
149 strncpy(pVerInfo->szPluginVer, pPluginVer, TCS_VER_MAX - 1);
151 strncpy(pVerInfo->szPluginVer, "NULL", TCS_VER_MAX - 1);
153 pVerInfo->szPluginVer[TCS_VER_MAX - 1] = '\0';
155 DDBG("%s %s %s\n", "Framework|Plugin version = ",
156 pVerInfo->szFrameworkVer, pVerInfo->szPluginVer);
161 int TCSGetInfo(TCSLIB_HANDLE hLib, char *pszInfo)
163 PluginContext *pCtx = (PluginContext *) hLib;
165 if (pCtx == NULL || pCtx->pfGetInfo == NULL)
175 char const *pszInfoPlugin = (*pCtx->pfGetInfo)();
177 if (pszInfoPlugin != NULL)
178 strncpy(pszInfo, pszInfoPlugin, TCS_META_MAX - 1);
180 strncpy(pszInfo, "NULL", TCS_META_MAX - 1);
182 pszInfo[TCS_META_MAX - 1] = '\0';
187 int TCSLibraryClose(TCSLIB_HANDLE hLib)
190 PluginContext *pCtx = NULL;
192 if (hLib == INVALID_TCSLIB_HANDLE)
195 pCtx = (PluginContext *) hLib;
196 if (pCtx->pfLibraryClose == NULL)
199 pthread_mutex_lock(&(pCtx->mutex));
200 iRet = (*pCtx->pfLibraryClose)(pCtx->hLib);
202 if (pCtx->pPlugin != NULL)
204 dlclose(pCtx->pPlugin);
205 pCtx->pPlugin = NULL;
208 pthread_mutex_unlock(&(pCtx->mutex));
209 pthread_mutex_destroy(&(pCtx->mutex));
216 TCSErrorCode TCSGetLastError(TCSLIB_HANDLE hLib)
218 PluginContext *pCtx = (PluginContext *) hLib;
220 if (pCtx == NULL || pCtx->pfGetLastError == NULL)
222 return TCS_CONSTRUCT_ERRCODE(TCS_ERROR_MODULE_GENERIC,
223 TCS_ERROR_NOT_IMPLEMENTED);
226 pthread_mutex_lock(&(pCtx->mutex));
227 TCSErrorCode errorCode = (*pCtx->pfGetLastError)(pCtx->hLib);
228 pthread_mutex_unlock(&(pCtx->mutex));
234 int TCSScanData(TCSLIB_HANDLE hLib, TCSScanParam *pParam, TCSScanResult *pResult)
236 PluginContext *pCtx = (PluginContext *) hLib;
238 if (pCtx == NULL || pCtx->pfScanData == NULL)
242 return (*pCtx->pfScanData)(pCtx->hLib, pParam, pResult);
246 int TCSScanFile(TCSLIB_HANDLE hLib, char const *pszFileName, int iDataType,
247 int iAction, int iCompressFlag, TCSScanResult *pResult)
249 PluginContext *pCtx = (PluginContext *) hLib;
251 if (pCtx == NULL || pCtx->pfScanFile == NULL)
255 return (*pCtx->pfScanFile)(pCtx->hLib, pszFileName, iDataType, iAction, iCompressFlag, pResult);
258 int TCSScanFileEx(TCSLIB_HANDLE hLib, char const *pszFileName, int iDataType,
259 int iAction, int iCompressFlag, void *pPrivate,
260 int (*pfCallBack)(void *pPrivate, int iReason, void *pParam),
261 TCSScanResult *pResult)
263 PluginContext *pCtx = (PluginContext *) hLib;
265 if (pCtx == NULL || pCtx->pfScanFile == NULL)
269 return (*pCtx->pfScanFileEx)(pCtx->hLib, pszFileName, iDataType, iAction, iCompressFlag,
270 pPrivate, pfCallBack, pResult);
273 int TCSScanAsyncCreateThread(void *pfWorkerFunc, void *pThreadData)
281 if (pthread_attr_init(&attr) != 0)
284 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
287 if (pthread_create(&thread, &attr, pfWorkerFunc, pThreadData) != 0)
290 if (pthread_attr_destroy(&attr) != 0)
300 void *TCSScanDataAsyncWorker(void *pTData)
302 ThreadScanData *pThreadData;
303 pThreadData = (ThreadScanData *) pTData;
305 PluginContext *pCtx = (PluginContext *) pThreadData->hLib;
306 TCSScanParam *pTCSScanParam = pThreadData->pParam;
312 if (pCtx == NULL || pCtx->pfScanFile == NULL)
314 DDBG("%s", "failed to open engine\n");
315 pTCSScanParam->pfCallBack(pTCSScanParam->pPrivate, TCS_CB_SCANFINISH, NULL);
319 TCSScanResult Result;
321 pthread_mutex_lock(&(pCtx->mutex));
323 iRet = TCSScanData(pThreadData->hLib, pTCSScanParam, &Result);
325 pthread_mutex_unlock(&(pCtx->mutex));
328 pTCSScanParam->pfCallBack(pTCSScanParam->pPrivate, TCS_CB_SCANFINISH, NULL);
330 pTCSScanParam->pfCallBack(pTCSScanParam->pPrivate, TCS_CB_SCANFINISH, &Result);
334 free(pThreadData->pParam);
341 int TCSScanDataAsync(TCSLIB_HANDLE hLib, TCSScanParam *pParam)
343 ThreadScanData *pThreadData = calloc(1, sizeof(ThreadScanData));
349 if (pThreadData == NULL)
352 pThreadData->pParam = malloc(sizeof(TCSScanParam));
354 if (pThreadData->pParam == 0)
357 pThreadData->hLib = hLib;
358 memcpy(pThreadData->pParam, pParam, sizeof(TCSScanParam));
360 if (TCSScanAsyncCreateThread(TCSScanDataAsyncWorker, (void *) pThreadData) != 0)
369 if (pThreadData != NULL)
371 free(pThreadData->pParam);
379 void *TCSScanFileAsyncWorker(void *pTData)
381 ThreadScanFileData *pThreadData;
382 pThreadData = (ThreadScanFileData *) pTData;
384 PluginContext *pCtx = (PluginContext *) pThreadData->hLib;
390 if (pCtx == NULL || pCtx->pfScanFile == NULL)
392 DDBG("%s", "failed to open engine\n");
393 pThreadData->pfCallBack(pThreadData->pPrivate, TCS_CB_SCANFINISH, NULL);
397 TCSScanResult Result;
399 pthread_mutex_lock(&(pCtx->mutex));
401 iRet = TCSScanFileEx(pThreadData->hLib, pThreadData->pszFileName, pThreadData->iDataType,
402 pThreadData->iAction, pThreadData->iCompressFlag, pThreadData->pPrivate,
403 pThreadData->pfCallBack, &Result);
405 pthread_mutex_unlock(&(pCtx->mutex));
408 pThreadData->pfCallBack(pThreadData->pPrivate, TCS_CB_SCANFINISH, NULL);
410 pThreadData->pfCallBack(pThreadData->pPrivate, TCS_CB_SCANFINISH, &Result);
414 free(pThreadData->pszFileName);
421 int TCSScanFileAsync(TCSLIB_HANDLE hLib, char const *pszFileName, int iDataType,
422 int iAction, int iCompressFlag, void *pPrivate,
423 int (*pfCallBack)(void *pPrivate, int iReason, void *pParam))
425 ThreadScanFileData *pThreadData = calloc(1, sizeof(ThreadScanFileData));
431 if (pThreadData == NULL || pszFileName == NULL)
434 pThreadData->hLib = hLib;
435 pThreadData->pszFileName = strdup(pszFileName);
436 pThreadData->iDataType = iDataType;
437 pThreadData->iAction = iAction;
438 pThreadData->iCompressFlag = iCompressFlag;
439 pThreadData->pPrivate = pPrivate;
440 pThreadData->pfCallBack = pfCallBack;
442 if (pThreadData->pszFileName == NULL)
445 if (TCSScanAsyncCreateThread(TCSScanFileAsyncWorker, pThreadData) != 0)
454 if (pThreadData != NULL)
456 free(pThreadData->pszFileName);
464 static PluginContext *LoadPlugin(void)
466 PluginContext *pCtx = NULL;
467 void *pTmp = dlopen(PLUGIN_PATH, RTLD_LAZY);
468 DDBG("%s", "load plugin\n");
471 FuncLibraryOpen TmpLibraryOpen;
472 FuncLibraryClose TmpLibraryClose;
473 FuncGetLastError TmpGetLastError;
474 FuncScanData TmpScanData;
475 FuncScanFile TmpScanFile;
476 FuncScanFileEx TmpScanFileEx;
477 FuncGetVersion TmpGetVersion;
478 FuncGetInfo TmpGetInfo;
482 TmpLibraryOpen = dlsym(pTmp, "TCSPLibraryOpen");
483 DDBG("%s", "load api TCSPLibraryOpen\n");
484 if (TmpLibraryOpen == NULL)
486 DDBG("Failed to load TCSPLibraryOpen in %s\n", PLUGIN_PATH);
491 TmpLibraryClose = dlsym(pTmp, "TCSPLibraryClose");
492 if (TmpLibraryClose == NULL)
494 DDBG("Failed to load TCSPLibraryClose in %s\n", PLUGIN_PATH);
499 TmpGetLastError = dlsym(pTmp, "TCSPGetLastError");
500 if (TmpGetLastError == NULL)
502 DDBG("Failed to load TCSPGetLastError in %s\n", PLUGIN_PATH);
507 TmpScanData = dlsym(pTmp, "TCSPScanData");
508 if (TmpScanData == NULL)
510 DDBG("Failed to load TCSPScanData in %s\n", PLUGIN_PATH);
515 TmpScanFile = dlsym(pTmp, "TCSPScanFile");
516 if (TmpScanFile == NULL)
518 DDBG("Failed to load TCSPScanFile in %s\n", PLUGIN_PATH);
523 TmpScanFileEx = dlsym(pTmp, "TCSPScanFileEx");
524 if (TmpScanFileEx == NULL)
526 DDBG("Failed to load TCSPScanFileEx in %s\n", PLUGIN_PATH);
531 TmpGetVersion = dlsym(pTmp, "TCSPGetVersion");
532 if(TmpGetVersion == NULL)
534 DDBG("Failed to load TCSPGetVersion in %s\n", PLUGIN_PATH);
539 TmpGetInfo = dlsym(pTmp, "TCSPGetInfo");
540 if(TmpGetInfo == NULL)
542 DDBG("Failed to load TCSPGetInfo in %s\n", PLUGIN_PATH);
547 pCtx = (PluginContext *) malloc(sizeof(PluginContext));
553 pCtx->pPlugin = pTmp;
554 pCtx->pfLibraryOpen = TmpLibraryOpen;
555 pCtx->pfLibraryClose = TmpLibraryClose;
556 pCtx->pfGetLastError = TmpGetLastError;
557 pCtx->pfScanData = TmpScanData;
558 pCtx->pfScanFile = TmpScanFile;
559 pCtx->pfScanFileEx = TmpScanFileEx;
560 pCtx->pfGetVersion = TmpGetVersion;
561 pCtx->pfGetInfo = TmpGetInfo;
567 DDBG("No plugin found. %s\n", dlerror());