Browse code

clamav-for-windows draft

aCaB authored on 2010/06/26 06:29:57
Showing 7 changed files
... ...
@@ -61,6 +61,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sigtool", "sigtool.vcproj",
61 61
 		{3AD5B16C-340A-40AC-96AD-6017B941A316} = {3AD5B16C-340A-40AC-96AD-6017B941A316}
62 62
 	EndProjectSection
63 63
 EndProject
64
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clamav-for-windows", "clamav-for-windows.vcproj", "{AF1A81DA-5AF3-4D09-BF27-220D539381C7}"
65
+	ProjectSection(ProjectDependencies) = postProject
66
+		{3AD5B16C-340A-40AC-96AD-6017B941A316} = {3AD5B16C-340A-40AC-96AD-6017B941A316}
67
+	EndProjectSection
68
+EndProject
64 69
 Global
65 70
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
66 71
 		Debug|Win32 = Debug|Win32
... ...
@@ -189,6 +194,10 @@ Global
189 189
 		{38B89BC0-6C00-4ABB-A179-24FEE81D1890}.Release|Win32.Build.0 = Release|Win32
190 190
 		{38B89BC0-6C00-4ABB-A179-24FEE81D1890}.Release|x64.ActiveCfg = Release|x64
191 191
 		{38B89BC0-6C00-4ABB-A179-24FEE81D1890}.Release|x64.Build.0 = Release|x64
192
+		{AF1A81DA-5AF3-4D09-BF27-220D539381C7}.Debug|Win32.ActiveCfg = Debug|Win32
193
+		{AF1A81DA-5AF3-4D09-BF27-220D539381C7}.Debug|x64.ActiveCfg = Debug|x64
194
+		{AF1A81DA-5AF3-4D09-BF27-220D539381C7}.Release|Win32.ActiveCfg = Release|Win32
195
+		{AF1A81DA-5AF3-4D09-BF27-220D539381C7}.Release|x64.ActiveCfg = Release|x64
192 196
 	EndGlobalSection
193 197
 	GlobalSection(SolutionProperties) = preSolution
194 198
 		HideSolutionNode = FALSE
195 199
new file mode 100644
... ...
@@ -0,0 +1,371 @@
0
+<?xml version="1.0" encoding="Windows-1252"?>
1
+<VisualStudioProject
2
+	ProjectType="Visual C++"
3
+	Version="9.00"
4
+	Name="clamav-for-windows"
5
+	ProjectGUID="{AF1A81DA-5AF3-4D09-BF27-220D539381C7}"
6
+	RootNamespace="clamavforwindows"
7
+	Keyword="Win32Proj"
8
+	TargetFrameworkVersion="196613"
9
+	>
10
+	<Platforms>
11
+		<Platform
12
+			Name="Win32"
13
+		/>
14
+		<Platform
15
+			Name="x64"
16
+		/>
17
+	</Platforms>
18
+	<ToolFiles>
19
+	</ToolFiles>
20
+	<Configurations>
21
+		<Configuration
22
+			Name="Debug|Win32"
23
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
24
+			IntermediateDirectory="$(SolutionDir)build\$(PlatformName)\$(ProjectName)\$(ConfigurationName)"
25
+			ConfigurationType="2"
26
+			CharacterSet="2"
27
+			>
28
+			<Tool
29
+				Name="VCPreBuildEventTool"
30
+			/>
31
+			<Tool
32
+				Name="VCCustomBuildTool"
33
+			/>
34
+			<Tool
35
+				Name="VCXMLDataGeneratorTool"
36
+			/>
37
+			<Tool
38
+				Name="VCWebServiceProxyGeneratorTool"
39
+			/>
40
+			<Tool
41
+				Name="VCMIDLTool"
42
+			/>
43
+			<Tool
44
+				Name="VCCLCompilerTool"
45
+				Optimization="0"
46
+				AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)..\libclamav&quot;;&quot;$(SolutionDir)compat&quot;;&quot;$(SolutionDir)3rdparty\zlib&quot;;&quot;$(SolutionDir)3rdparty\pthreads&quot;;&quot;$(SolutionDir)..&quot;"
47
+				PreprocessorDefinitions="WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;_BIND_TO_CURRENT_VCLIBS_VERSION=1"
48
+				MinimalRebuild="true"
49
+				BasicRuntimeChecks="3"
50
+				RuntimeLibrary="3"
51
+				UsePrecompiledHeader="0"
52
+				WarningLevel="3"
53
+				DebugInformationFormat="3"
54
+				CompileAs="1"
55
+				DisableSpecificWarnings="4996"
56
+			/>
57
+			<Tool
58
+				Name="VCManagedResourceCompilerTool"
59
+			/>
60
+			<Tool
61
+				Name="VCResourceCompilerTool"
62
+			/>
63
+			<Tool
64
+				Name="VCPreLinkEventTool"
65
+			/>
66
+			<Tool
67
+				Name="VCLinkerTool"
68
+				OutputFile="$(OutDir)\clamav.dll"
69
+				LinkIncremental="1"
70
+				GenerateDebugInformation="true"
71
+				SubSystem="2"
72
+				TargetMachine="1"
73
+			/>
74
+			<Tool
75
+				Name="VCALinkTool"
76
+			/>
77
+			<Tool
78
+				Name="VCManifestTool"
79
+			/>
80
+			<Tool
81
+				Name="VCXDCMakeTool"
82
+			/>
83
+			<Tool
84
+				Name="VCBscMakeTool"
85
+			/>
86
+			<Tool
87
+				Name="VCFxCopTool"
88
+			/>
89
+			<Tool
90
+				Name="VCAppVerifierTool"
91
+			/>
92
+			<Tool
93
+				Name="VCPostBuildEventTool"
94
+			/>
95
+		</Configuration>
96
+		<Configuration
97
+			Name="Release|Win32"
98
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
99
+			IntermediateDirectory="$(SolutionDir)build\$(PlatformName)\$(ProjectName)\$(ConfigurationName)"
100
+			ConfigurationType="2"
101
+			CharacterSet="2"
102
+			WholeProgramOptimization="1"
103
+			>
104
+			<Tool
105
+				Name="VCPreBuildEventTool"
106
+			/>
107
+			<Tool
108
+				Name="VCCustomBuildTool"
109
+			/>
110
+			<Tool
111
+				Name="VCXMLDataGeneratorTool"
112
+			/>
113
+			<Tool
114
+				Name="VCWebServiceProxyGeneratorTool"
115
+			/>
116
+			<Tool
117
+				Name="VCMIDLTool"
118
+			/>
119
+			<Tool
120
+				Name="VCCLCompilerTool"
121
+				Optimization="2"
122
+				EnableIntrinsicFunctions="true"
123
+				AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)..\libclamav&quot;;&quot;$(SolutionDir)compat&quot;;&quot;$(SolutionDir)3rdparty\zlib&quot;;&quot;$(SolutionDir)3rdparty\pthreads&quot;;&quot;$(SolutionDir)..&quot;"
124
+				PreprocessorDefinitions="WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;_BIND_TO_CURRENT_VCLIBS_VERSION=1"
125
+				RuntimeLibrary="2"
126
+				EnableFunctionLevelLinking="true"
127
+				UsePrecompiledHeader="0"
128
+				WarningLevel="3"
129
+				DebugInformationFormat="3"
130
+				CompileAs="1"
131
+				DisableSpecificWarnings="4996"
132
+			/>
133
+			<Tool
134
+				Name="VCManagedResourceCompilerTool"
135
+			/>
136
+			<Tool
137
+				Name="VCResourceCompilerTool"
138
+			/>
139
+			<Tool
140
+				Name="VCPreLinkEventTool"
141
+			/>
142
+			<Tool
143
+				Name="VCLinkerTool"
144
+				OutputFile="$(OutDir)\clamav.dll"
145
+				LinkIncremental="1"
146
+				GenerateDebugInformation="true"
147
+				SubSystem="2"
148
+				OptimizeReferences="2"
149
+				EnableCOMDATFolding="2"
150
+				TargetMachine="1"
151
+			/>
152
+			<Tool
153
+				Name="VCALinkTool"
154
+			/>
155
+			<Tool
156
+				Name="VCManifestTool"
157
+			/>
158
+			<Tool
159
+				Name="VCXDCMakeTool"
160
+			/>
161
+			<Tool
162
+				Name="VCBscMakeTool"
163
+			/>
164
+			<Tool
165
+				Name="VCFxCopTool"
166
+			/>
167
+			<Tool
168
+				Name="VCAppVerifierTool"
169
+			/>
170
+			<Tool
171
+				Name="VCPostBuildEventTool"
172
+			/>
173
+		</Configuration>
174
+		<Configuration
175
+			Name="Debug|x64"
176
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
177
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
178
+			ConfigurationType="2"
179
+			CharacterSet="2"
180
+			>
181
+			<Tool
182
+				Name="VCPreBuildEventTool"
183
+			/>
184
+			<Tool
185
+				Name="VCCustomBuildTool"
186
+			/>
187
+			<Tool
188
+				Name="VCXMLDataGeneratorTool"
189
+			/>
190
+			<Tool
191
+				Name="VCWebServiceProxyGeneratorTool"
192
+			/>
193
+			<Tool
194
+				Name="VCMIDLTool"
195
+				TargetEnvironment="3"
196
+			/>
197
+			<Tool
198
+				Name="VCCLCompilerTool"
199
+				Optimization="0"
200
+				AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)..\libclamav&quot;;&quot;$(SolutionDir)compat&quot;;&quot;$(SolutionDir)3rdparty\zlib&quot;;&quot;$(SolutionDir)3rdparty\pthreads&quot;;&quot;$(SolutionDir)..&quot;"
201
+				PreprocessorDefinitions="WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;_BIND_TO_CURRENT_VCLIBS_VERSION=1"
202
+				MinimalRebuild="true"
203
+				BasicRuntimeChecks="3"
204
+				RuntimeLibrary="3"
205
+				UsePrecompiledHeader="0"
206
+				WarningLevel="3"
207
+				DebugInformationFormat="3"
208
+				CompileAs="1"
209
+				DisableSpecificWarnings="4996"
210
+			/>
211
+			<Tool
212
+				Name="VCManagedResourceCompilerTool"
213
+			/>
214
+			<Tool
215
+				Name="VCResourceCompilerTool"
216
+			/>
217
+			<Tool
218
+				Name="VCPreLinkEventTool"
219
+			/>
220
+			<Tool
221
+				Name="VCLinkerTool"
222
+				OutputFile="$(OutDir)\clamav.dll"
223
+				LinkIncremental="1"
224
+				GenerateDebugInformation="true"
225
+				SubSystem="2"
226
+				TargetMachine="17"
227
+			/>
228
+			<Tool
229
+				Name="VCALinkTool"
230
+			/>
231
+			<Tool
232
+				Name="VCManifestTool"
233
+			/>
234
+			<Tool
235
+				Name="VCXDCMakeTool"
236
+			/>
237
+			<Tool
238
+				Name="VCBscMakeTool"
239
+			/>
240
+			<Tool
241
+				Name="VCFxCopTool"
242
+			/>
243
+			<Tool
244
+				Name="VCAppVerifierTool"
245
+			/>
246
+			<Tool
247
+				Name="VCPostBuildEventTool"
248
+			/>
249
+		</Configuration>
250
+		<Configuration
251
+			Name="Release|x64"
252
+			OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
253
+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
254
+			ConfigurationType="2"
255
+			CharacterSet="2"
256
+			WholeProgramOptimization="1"
257
+			>
258
+			<Tool
259
+				Name="VCPreBuildEventTool"
260
+			/>
261
+			<Tool
262
+				Name="VCCustomBuildTool"
263
+			/>
264
+			<Tool
265
+				Name="VCXMLDataGeneratorTool"
266
+			/>
267
+			<Tool
268
+				Name="VCWebServiceProxyGeneratorTool"
269
+			/>
270
+			<Tool
271
+				Name="VCMIDLTool"
272
+				TargetEnvironment="3"
273
+			/>
274
+			<Tool
275
+				Name="VCCLCompilerTool"
276
+				Optimization="2"
277
+				EnableIntrinsicFunctions="true"
278
+				AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)..\libclamav&quot;;&quot;$(SolutionDir)compat&quot;;&quot;$(SolutionDir)3rdparty\zlib&quot;;&quot;$(SolutionDir)3rdparty\pthreads&quot;;&quot;$(SolutionDir)..&quot;"
279
+				PreprocessorDefinitions="WIN32_LEAN_AND_MEAN;HAVE_CONFIG_H;_BIND_TO_CURRENT_VCLIBS_VERSION=1"
280
+				RuntimeLibrary="2"
281
+				EnableFunctionLevelLinking="true"
282
+				UsePrecompiledHeader="0"
283
+				WarningLevel="3"
284
+				DebugInformationFormat="3"
285
+				CompileAs="1"
286
+				DisableSpecificWarnings="4996"
287
+			/>
288
+			<Tool
289
+				Name="VCManagedResourceCompilerTool"
290
+			/>
291
+			<Tool
292
+				Name="VCResourceCompilerTool"
293
+			/>
294
+			<Tool
295
+				Name="VCPreLinkEventTool"
296
+			/>
297
+			<Tool
298
+				Name="VCLinkerTool"
299
+				OutputFile="$(OutDir)\clamav.dll"
300
+				LinkIncremental="1"
301
+				GenerateDebugInformation="true"
302
+				SubSystem="2"
303
+				OptimizeReferences="2"
304
+				EnableCOMDATFolding="2"
305
+				TargetMachine="17"
306
+			/>
307
+			<Tool
308
+				Name="VCALinkTool"
309
+			/>
310
+			<Tool
311
+				Name="VCManifestTool"
312
+			/>
313
+			<Tool
314
+				Name="VCXDCMakeTool"
315
+			/>
316
+			<Tool
317
+				Name="VCBscMakeTool"
318
+			/>
319
+			<Tool
320
+				Name="VCFxCopTool"
321
+			/>
322
+			<Tool
323
+				Name="VCAppVerifierTool"
324
+			/>
325
+			<Tool
326
+				Name="VCPostBuildEventTool"
327
+			/>
328
+		</Configuration>
329
+	</Configurations>
330
+	<References>
331
+	</References>
332
+	<Files>
333
+		<Filter
334
+			Name="Source Files"
335
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
336
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
337
+			>
338
+			<File
339
+				RelativePath=".\clamav-for-windows\interface.c"
340
+				>
341
+			</File>
342
+			<File
343
+				RelativePath=".\clamav-for-windows\main.c"
344
+				>
345
+			</File>
346
+			<Filter
347
+				Name="shared"
348
+				>
349
+				<File
350
+					RelativePath="..\shared\output.c"
351
+					>
352
+				</File>
353
+			</Filter>
354
+		</Filter>
355
+		<Filter
356
+			Name="Header Files"
357
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
358
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
359
+			>
360
+		</Filter>
361
+		<Filter
362
+			Name="Resource Files"
363
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
364
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
365
+			>
366
+		</Filter>
367
+	</Files>
368
+	<Globals>
369
+	</Globals>
370
+</VisualStudioProject>
0 371
new file mode 100644
... ...
@@ -0,0 +1,308 @@
0
+/*
1
+ * Copyright (C) 2010 Sourcefire, Inc.
2
+ * Authors: aCaB <acab@clamav.net>
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License version 2.1 as published by the Free Software Foundation.
7
+ *
8
+ * This library is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
+ * Lesser General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU Lesser General Public
14
+ * License along with this library; if not, write to the Free Software
15
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
16
+ * USA
17
+ */
18
+
19
+// Template for 3rd party engines to integrate with Immunet
20
+// TODO: Replace <MOD> with engine specific name
21
+/*
22
+Engine/API Requirements:
23
+
24
+ R1) Ability to invoke scans
25
+
26
+		- with callbacks where callback is invoked several times (even during scanning a single PE file). The scan engine could invoke callbacks during the following states:
27
+			- state 1: after unpacking (if packed)
28
+			- state 2: after emulation (if emulation is supported)
29
+			- state 3: after scan is complete
30
+			- state 4: after requested action is performed (only in case of infection)
31
+			For archive, installers, compound files the callback should be invoked for each file. Each file may cause the callback to be invoked more than once.
32
+
33
+		- without callbacks, it should be possible to retrieve additional information about file that was scanned
34
+			i) infections found after the scan (ex: using MOD_SCAN_INFO_LIST)
35
+			ii) Unpacked file (in case the original file was packed)
36
+		  There probably will be some settings to limit large memory usage in this case. For example, if a large archive file with 1000 infected files
37
+		  is scanned, it may be unrealistic to return information for all the files. Probably MAX_INFECTION_COUNT setting will exist to limit passing
38
+		  back such information
39
+
40
+  R2) The callbacks should be asynchronous (i.e. a separate thread with same engine instance should be able to scan a file without waiting
41
+	  even when the first file callback has not returned
42
+	  Use case: Typically, in callback it is expected to make connection to the cloud before taking action. Since, the cloud query can take few ms, it
43
+	  should be possible for another thread with same engine instance to scan a separate file without any interference.
44
+
45
+  R3) The disinfection/delete should be supported asynchronously. The engine should be able to perform state 1 to state 3 in sequence and state 4 
46
+	  could be performed at a later stage.
47
+	  Use case: In case of system scans, drive scans there is a good chance that more than one infection is found. Instead of asking user each time
48
+	  a list can be generated in the end giving the user the choice to take action. If the user chooses to disinfect/delete the disinfection action
49
+	  should happen without performing any additional scan.
50
+		  
51
+  R4) The definitions should ideally not consume more than 30MB in memory
52
+
53
+  R5) The scan engine should ideally not consume more than 50ms for scanning individual files in most cases
54
+*/
55
+#ifndef _CLAM_SCAN_API_H
56
+#define _CLAM_SCAN_API_H
57
+
58
+#define CLAMAPI __declspec(dllexport)
59
+
60
+#ifndef CALL_CONVENTION
61
+#define CALL_CONVENTION __cdecl
62
+#endif
63
+
64
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65
+// TODO: define constants like type of malware, type of object, error code etc here
66
+
67
+#define CLAMAPI_SUCCESS	0
68
+#define CLAMAPI_FAILURE	1
69
+
70
+#define CLAMAPI_OBJECT_TYPE_FILE 1
71
+
72
+#define CLAM_OPTION_SCAN_MODE 0x0
73
+#define CLAM_SCAN_FULL 0x0
74
+#define CLAM_SCAN_LIGHT  0x1
75
+
76
+#define CLAMAPI_DISINFECT_ONLY 0x10
77
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
78
+// An example structure that external module should fill. This can be used by Immunet interface either during callback
79
+// or once the scan API function has completed
80
+// TODO: Add any fields as required
81
+
82
+typedef struct _CLAM_SCAN_INFO
83
+{
84
+	// size of this structure
85
+	int cbSize;
86
+
87
+	// Based on this type, pObject field is interpreted
88
+	// ex: stream in a compound object, file in an archive, embedded file in installer etc
89
+	int objectType;
90
+
91
+	// archive flags. In case the file being scanned is archive file set the flags accordingly
92
+	int archiveFlags;
93
+
94
+	// compressionFlags flags. In case the file being scanned is packed set the flags accordingly
95
+	int compressionFlags;
96
+
97
+	// installerFlags flags. In case the file being scanned is an installer (MSI, NSIS etc) set the flags accordingly
98
+	int installerFlags;
99
+
100
+	// path to the file being scanned (C:\test.zip)
101
+	const wchar_t *pObjectPath;
102
+
103
+	// path of inner file relative to file being scanned
104
+	// valid only for certain object types (ex: installers, compound objects, archive files etc
105
+	const wchar_t *pInnerObjectPath;
106
+
107
+	// a state machine kind of variable
108
+	// If a callback is registered, it can be called during any one of the following states
109
+	// unpack complete -> emulation complete -> scan complete -> action result complete
110
+	int scanStatus;
111
+
112
+	// status code corresponding to scanStatus
113
+	int errorCode;
114
+
115
+	// interpretation could depend on objectType. Maybe just base pointer to file loaded in memory.
116
+	// Can this work for all cases?
117
+	void *pObject;
118
+
119
+	// size of object
120
+	unsigned long objectLength;
121
+
122
+	// type of threat (adware, malware etc)
123
+	int threatType;
124
+
125
+	// threatname
126
+	const wchar_t *pThreatName;
127
+}CLAM_SCAN_INFO, *PCLAM_SCAN_INFO;
128
+
129
+// list of CLAM_SCAN_INFO items
130
+// Typical use: If no callback is registered and an archive file is scanned, this list corresponds to each infected file found
131
+typedef struct _CLAM_SCAN_INFO_LIST
132
+{
133
+	// number of CLAM_SCAN_INFO structures present
134
+	int cbCount;
135
+
136
+	// pointer to first CLAM_SCAN_INFO structure
137
+	PCLAM_SCAN_INFO pInfoList;
138
+}CLAM_SCAN_INFO_LIST, *PCLAM_SCAN_INFO_LIST;
139
+
140
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
141
+// Callback prototypes
142
+
143
+/*
144
+ * MANDATORY SUPPORT
145
+ * callback that can be registered to be invoked by the scan engine
146
+ * Parameters: 
147
+ * INPUT @param pObjectInfo : all relevant information of the file being scanned
148
+ * OUTPUT @param scanAction : action to be taken as determined by callback
149
+ * INPUT @param context : any context to be passed to scan callback
150
+ */
151
+typedef void (CALL_CONVENTION *CLAM_SCAN_CALLBACK)(const CLAM_SCAN_INFO *pObjectInfo, int *scanAction, void *context);
152
+
153
+/*
154
+ * OPTIONAL SUPPORT
155
+ * callback that can be registered to be invoked by the scan engine
156
+ * Parameters: 
157
+ * INPUT @param objectType : object type
158
+ * INPUT @param pObjectName : name of object (typically filename)
159
+ * INPUT @param pPassword : input buffer to hold password
160
+ * INPUT/OUTPUT @param pPasswordLen : on input consists of length of password buffer. The callback fills this with actual length.
161
+ * INPUT @param context : any context to be passed to scan callback
162
+ */
163
+typedef void (CALL_CONVENTION *CLAM_PASSWORD_CALLBACK)(int objectType, const wchar_t *pObjectName, wchar_t *pPassword, int *pPasswordLen, void *context);
164
+
165
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
166
+// Function prototypes
167
+
168
+#ifdef __cplusplus
169
+extern "C" {
170
+#endif
171
+
172
+// In future this can be extended to C++ style interface
173
+// CCLAMScanner refers to Scanner instance
174
+#define CClamAVScanner void
175
+
176
+/*
177
+ * MANDATORY SUPPORT
178
+ * Load scan engine defs
179
+ * Parameters: 
180
+ * INPUT @param pEnginesFolder : path where defs are located
181
+ * INPUT @param pLicenseKey : license key blob
182
+ */
183
+int CLAMAPI Scan_Initialize(const wchar_t *pEnginesFolder, const wchar_t *pLicenseKey);
184
+
185
+/*
186
+ * MANDATORY SUPPORT
187
+ * Unload scan engine defs, which were loaded using Scan_Initialize
188
+ * Parameters: None
189
+ */
190
+int CLAMAPI Scan_Uninitialize();
191
+
192
+/*
193
+ * MANDATORY SUPPORT
194
+ * Create scan engine instance. 
195
+ * The engine instances should have the ability to be shared across threads
196
+ * If synchronization is not done internally, it should be identified as such
197
+ * OUTPUT @param ppScanner : location to hold opaque object
198
+ */
199
+int CLAMAPI Scan_CreateInstance(CClamAVScanner **ppScanner);
200
+
201
+/*
202
+ * MANDATORY SUPPORT
203
+ * Destroy scan engine instance. 
204
+ * INPUT @param pScanner : opaque object
205
+ */
206
+int CLAMAPI Scan_DestroyInstance(CClamAVScanner *pScanner);
207
+
208
+/*
209
+ * MANDATORY SUPPORT
210
+ * Set callback that is invoked when file is being scanned
211
+ * The callback can be invoked multiple times while scanning a file
212
+ *	- state 1: after unpacking (if packed)
213
+ *	- state 2: after emulation (if emulation is supported)
214
+ *	- state 3: after scan is complete
215
+ *	- state 4: after requested action is performed (only in case of infection)
216
+ * For archive, installers, compound files the callback should be invoked for each file. Each file can cause the callback to be invoked more than once.
217
+ * INPUT @param pScanner : opaque object
218
+ * INPUT @param pfnCallback : callback function
219
+ * INPUT @param pContext : context to be passed to callback function
220
+ */
221
+int CLAMAPI Scan_SetScanCallback(CClamAVScanner *pScanner, CLAM_SCAN_CALLBACK pfnCallback, void *pContext);
222
+
223
+/*
224
+ * OPTIONAL SUPPORT. Required only if password callbacks are supported
225
+ * Set callback that is invoked if the file to be scanned requires password input
226
+ * INPUT @param pScanner : opaque object
227
+ * INPUT @param pfnCallback : callback function
228
+ * INPUT @param pContext : context to be passed to callback function
229
+ */
230
+int CLAMAPI Scan_SetPasswordCallback(CClamAVScanner *pScanner, CLAM_PASSWORD_CALLBACK pfnCallback, void *pContext);
231
+
232
+/*
233
+ * MANDATORY SUPPORT
234
+ * Scan object using path
235
+ * INPUT @param pScanner : opaque object
236
+ * INPUT @param pObjectPath : path to object
237
+ * INPUT @param objectType : object type
238
+ * INPUT @param action : attempt cleanup (default action is taken if this is not set and no callback is registered)
239
+ * INPUT @param impersonatePID : impersonate the process (incase file is not accessible to current thread)
240
+ * OUTPUT @param pScanStatus : indicates status of scan
241
+ * OUTPUT @param pInfoList : list containing additional information about file that was scanned
242
+ */
243
+int CLAMAPI Scan_ScanObject(CClamAVScanner *pScanner, const wchar_t *pObjectPath, int objectType, int action, int impersonatePID, int *pScanStatus, PCLAM_SCAN_INFO_LIST *pInfoList);
244
+
245
+/*
246
+ * MANDATORY SUPPORT
247
+ * Scan object using object handle
248
+ * INPUT @param pScanner : opaque object
249
+ * INPUT @param pObject : handle to object
250
+ * INPUT @param objectType : object type
251
+ * INPUT @param action : attempt cleanup (default action is taken if this is not set and no callback is registered)
252
+ * INPUT @param impersonatePID : impersonate the process (incase file is not accessible to current thread)
253
+ * OUTPUT @param pScanStatus : indicates status of scan
254
+ * OUTPUT @param pInfoList : list containing additional information about file that was scanned
255
+ */
256
+int CLAMAPI Scan_ScanObjectByHandle(CClamAVScanner *pScanner, const void *pObject, int objectType, int action, int impersonatePID, int *pScanStatus, PCLAM_SCAN_INFO_LIST *pInfoList);
257
+
258
+/*
259
+ * OPTIONAL SUPPORT
260
+ * Scan object in memory
261
+ * INPUT @param pScanner : opaque object
262
+ * INPUT @param pObject : handle to object
263
+ * INPUT @param objectSize : size of object in memory
264
+ * INPUT @param objectType : object type
265
+ * INPUT @param action : attempt cleanup (default action is taken if this is not set and no callback is registered)
266
+ * INPUT @param impersonatePID : impersonate the process (incase file is not accessible to current thread)
267
+ * OUTPUT @param pScanStatus : indicates status of scan
268
+ * OUTPUT @param pInfoList : list containing additional information about file that was scanned
269
+ */
270
+int CLAMAPI Scan_ScanObjectInMemory(CClamAVScanner *pScanner, const void *pObject, unsigned int objectSize, int objectType, int action, int impersonatePID, int *pScanStatus, PCLAM_SCAN_INFO_LIST *pInfoList);
271
+
272
+/*
273
+ * MANDATORY SUPPORT
274
+ * Destroy memory allocated when malicious objects are found during scan
275
+ * INPUT @param pScanner : opaque object
276
+ * INPUT/OUTPUT @param pInfoList : list to be freed
277
+ */
278
+int CLAMAPI Scan_DeleteScanInfo(CClamAVScanner *pScanner, PCLAM_SCAN_INFO_LIST pInfoList);
279
+
280
+/*
281
+ * Get integer based scanning options
282
+ * ex: License Expiration Time, Count of DB signatures, Last updated time for DB, Major, Minor version of scan library
283
+ * INPUT @param scanner : opaque object
284
+ * INPUT @param option : option enum
285
+ * INPUT @param value : location to store value
286
+ * INPUT @param inputLength : size of input buffer
287
+ * OUTPUT @param outLength : mimimum size require to store data
288
+ */
289
+int CLAMAPI Scan_GetOption(CClamAVScanner *pScanner, int option, void *value, unsigned long inputLength, unsigned long *outLength);
290
+
291
+/*
292
+ * Set integer based scanning options
293
+ * ex: scan Archives, scan packed samples, scan e-mail databases, scan installers
294
+ * INPUT @param pScanner : opaque object
295
+ * INPUT @param option : option enum
296
+ * INPUT @param value : location to store value
297
+ * INPUT @param inputLength : size of input value
298
+ */
299
+int CLAMAPI Scan_SetOption(CClamAVScanner *pScanner, int option, void *value, unsigned long inputLength);
300
+
301
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
302
+
303
+#ifdef __cplusplus
304
+}; /* extern "C" */
305
+#endif
306
+
307
+#endif /* _CLAM_SCAN_API_H */
0 308
new file mode 100644
... ...
@@ -0,0 +1,264 @@
0
+/*
1
+ * Copyright (C) 2010 Sourcefire, Inc.
2
+ * Authors: aCaB <acab@clamav.net>
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License version 2.1 as published by the Free Software Foundation.
7
+ *
8
+ * This library is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
+ * Lesser General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU Lesser General Public
14
+ * License along with this library; if not, write to the Free Software
15
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
16
+ * USA
17
+ */
18
+
19
+#if HAVE_CONFIG_H
20
+#include "clamav-config.h"
21
+#endif
22
+
23
+#include "clamav.h"
24
+#include "shared/output.h"
25
+#include "clscanapi.h"
26
+#include "interface.h"
27
+
28
+#define FMT(s) s"\n"
29
+#define FAIL(fmt, ...) do { logg(FMT(fmt), __VA_ARGS__); return CLAMAPI_FAILURE; } while(0)
30
+#define WIN() do { logg("%s completed successfully\n", __FUNCTION__); return CLAMAPI_SUCCESS; } while(0)
31
+
32
+struct cl_engine *engine = NULL;
33
+HANDLE engine_mutex;
34
+HANDLE engine_event;
35
+unsigned int engine_refcnt;
36
+
37
+BOOL interface_setup(void) {
38
+    if(cl_init(CL_INIT_DEFAULT))
39
+	return FALSE;
40
+    if(!(engine_mutex = CreateMutex(NULL, FALSE, NULL)))
41
+	return FALSE;
42
+    if(!(engine_event = CreateEvent(NULL, TRUE, TRUE, NULL)))
43
+	return FALSE;
44
+
45
+    logg_verbose = 1;
46
+    logg_nowarn = 0;
47
+    logg_lock = 0;
48
+    logg_time = 1;
49
+    logg_size = -1;
50
+    logg_file = "C:\\clam4win.log";
51
+    logg("ClamAV support initialized\n");
52
+    return TRUE;
53
+}
54
+
55
+#define lock_engine()(WaitForSingleObject(engine_mutex, INFINITE) == WAIT_FAILED)
56
+#define unlock_engine() do {ReleaseMutex(engine_mutex);} while(0)
57
+
58
+static void free_engine_and_unlock(void) {
59
+    cl_engine_free(engine);
60
+    engine = NULL;
61
+    unlock_engine();
62
+}
63
+
64
+int CLAMAPI Scan_Initialize(const wchar_t *pEnginesFolder, const wchar_t *pLicenseKey) {
65
+    char dbdir[PATH_MAX];
66
+    BOOL cant_convert;
67
+    int ret;
68
+
69
+    if(lock_engine())
70
+	FAIL("Engine mutex fail");
71
+    if(engine) {
72
+	unlock_engine();
73
+	FAIL("Already initialized");
74
+    }
75
+    if(!(engine = cl_engine_new())) {
76
+	unlock_engine();
77
+	FAIL("Not enough memory for a new engine");
78
+    }
79
+    if(!WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, pEnginesFolder, -1, dbdir, sizeof(dbdir), NULL, &cant_convert) || cant_convert) {
80
+	free_engine_and_unlock();
81
+	FAIL("Can't translate pEnginesFolder");
82
+    }
83
+    if((ret = cl_load(dbdir, engine, NULL, CL_DB_STDOPT)) != CL_SUCCESS) {
84
+	free_engine_and_unlock();
85
+	FAIL("Failed to load database: %s", cl_strerror(ret));
86
+    }
87
+    if((ret = cl_engine_compile(engine))) {
88
+	free_engine_and_unlock();
89
+	FAIL("Failed to compile engine: %s", cl_strerror(ret));
90
+    }
91
+    engine_refcnt = 0;
92
+    unlock_engine();
93
+    WIN();
94
+}
95
+
96
+int CLAMAPI Scan_Uninitialize(void) {
97
+    if(lock_engine())
98
+	FAIL("Engine mutex fail");
99
+    if(!engine) {
100
+	unlock_engine();
101
+	FAIL("Attempted to uninit a NULL engine");
102
+    }
103
+    if(engine_refcnt) {
104
+	volatile unsigned int refs = engine_refcnt;
105
+	unlock_engine();
106
+	FAIL("Attempted to uninit the engine with %u active instances", engine_refcnt);
107
+    }
108
+    free_engine_and_unlock();
109
+    WIN();
110
+}
111
+
112
+typedef struct {
113
+    CLAM_SCAN_CALLBACK scancb;
114
+    void *scancb_ctx;
115
+    void *callback2;
116
+    int scanmode;
117
+} instance;
118
+
119
+int CLAMAPI Scan_CreateInstance(CClamAVScanner **ppScanner) {
120
+    instance *inst = calloc(1, sizeof(*inst));
121
+    if(!inst)
122
+	FAIL("CreateInstance: OOM");
123
+    if(lock_engine()) {
124
+	free(inst);
125
+	FAIL("Failed to lock engine");
126
+    }
127
+    if(!engine) {
128
+	free(inst);
129
+	unlock_engine();
130
+	FAIL("Create instance called with no engine");
131
+    }
132
+    engine_refcnt++;
133
+    ResetEvent(engine_event);
134
+    unlock_engine();
135
+    *ppScanner = (CClamAVScanner *)inst;
136
+    WIN();
137
+}
138
+
139
+int CLAMAPI Scan_DestroyInstance(CClamAVScanner *pScanner) {
140
+    free(pScanner);
141
+    if(lock_engine())
142
+	FAIL("Failed to lock engine");
143
+    if(!engine) {
144
+	unlock_engine();
145
+	FAIL("Destroy instance called with no engine");
146
+    }
147
+    if(!--engine_refcnt)
148
+	SetEvent(engine_event);
149
+    unlock_engine();
150
+    WIN();
151
+}
152
+
153
+int CLAMAPI Scan_SetScanCallback(CClamAVScanner *pScanner, CLAM_SCAN_CALLBACK pfnCallback, void *pContext) {
154
+    instance *inst = (instance *)pScanner;
155
+    inst->scancb = pfnCallback;
156
+    inst->scancb_ctx = pContext;
157
+    WIN();
158
+}
159
+
160
+int CLAMAPI Scan_SetOption(CClamAVScanner *pScanner, int option, void *value, unsigned long inputLength) {
161
+    instance *inst = (instance *)pScanner;
162
+    switch(option) {
163
+	case CLAM_OPTION_SCAN_MODE: {
164
+	    int newmode;
165
+	    if(inputLength != sizeof(int))
166
+		FAIL("Bad scanmode value size: %lu", inputLength);
167
+	    memcpy(&newmode, value, sizeof(int)); /* not sure about alignment */
168
+	    if(newmode != CLAM_SCAN_FULL && newmode != CLAM_SCAN_LIGHT)
169
+		FAIL("Bad scanmode: %d", newmode);
170
+	    inst->scanmode = newmode;
171
+	    WIN();
172
+	}
173
+	default:
174
+	    FAIL("Unsupported option: %d", option);
175
+    }
176
+}
177
+
178
+int CLAMAPI Scan_GetOption(CClamAVScanner *pScanner, int option, void *value, unsigned long inputLength, unsigned long *outLength) {
179
+    instance *inst = (instance *)pScanner;
180
+    switch(option) {
181
+	case CLAM_OPTION_SCAN_MODE:
182
+	    *outLength = sizeof(int);
183
+	    if(inputLength < sizeof(int)) {
184
+		FAIL("Bad scanmode value size: inputLength");
185
+	    }
186
+	    memcpy(value, &inst->scanmode, sizeof(int));
187
+	    WIN();
188
+
189
+	default:
190
+	    FAIL("Unsupported option");
191
+    }
192
+}
193
+
194
+#define CLAM_LIGHT_OPTS (CL_SCAN_STDOPT & ~(CL_SCAN_ARCHIVE | CL_SCAN_MAIL | CL_SCAN_ELF))
195
+#define MAX_VIRNAME_LEN 1024
196
+
197
+int CLAMAPI Scan_ScanObject(CClamAVScanner *pScanner, const wchar_t *pObjectPath, int objectType, int action, int impersonatePID, int *pScanStatus, PCLAM_SCAN_INFO_LIST *pInfoList) {
198
+    HANDLE fhdl;
199
+    int res;
200
+
201
+    if(objectType != CLAMAPI_OBJECT_TYPE_FILE)
202
+	FAIL("Unsupported object type: %d", objectType);
203
+
204
+    if((fhdl = CreateFileW(pObjectPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL)) == INVALID_HANDLE_VALUE)
205
+	FAIL("open() failed");
206
+
207
+    res = Scan_ScanObjectByHandle(pScanner, &fhdl, objectType, action, impersonatePID, pScanStatus, pInfoList);
208
+
209
+    CloseHandle(fhdl);
210
+    return res;
211
+}
212
+
213
+int CLAMAPI Scan_ScanObjectByHandle(CClamAVScanner *pScanner, const void *pObject, int objectType, int action, int impersonatePID, int *pScanStatus, PCLAM_SCAN_INFO_LIST *pInfoList) {
214
+    instance *inst = (instance *)pScanner;
215
+    HANDLE duphdl, self;
216
+    char *virname;
217
+    int fd, res;
218
+
219
+    if(objectType != CLAMAPI_OBJECT_TYPE_FILE)
220
+	FAIL("Unsupported object type: %d", objectType);
221
+
222
+    *pInfoList = calloc(1, sizeof(CLAM_SCAN_INFO_LIST) + sizeof(CLAM_SCAN_INFO) + MAX_VIRNAME_LEN);
223
+    if(!*pInfoList)
224
+	FAIL("ScanByHandle: OOM");
225
+
226
+    self = GetCurrentProcess();
227
+    if(!DuplicateHandle(self, *(HANDLE *)pObject, self, &duphdl, GENERIC_READ, FALSE, 0)) {
228
+	free(*pInfoList);
229
+	FAIL("Duplicate handle failed");
230
+    }
231
+
232
+    if((fd = _open_osfhandle((intptr_t)duphdl, _O_RDONLY)) == -1) {
233
+	CloseHandle(duphdl);
234
+	free(*pInfoList);
235
+	FAIL("open handle failed");
236
+    }
237
+
238
+    res = cl_scandesc(fd, &virname, NULL, engine, (inst->scanmode == CLAM_SCAN_FULL) ? CL_SCAN_STDOPT : CLAM_LIGHT_OPTS);
239
+
240
+    close(fd);
241
+
242
+    if(res == CL_VIRUS) {
243
+	PCLAM_SCAN_INFO scaninfo = (PCLAM_SCAN_INFO)(*pInfoList + 1);
244
+	wchar_t *wvirname = (wchar_t *)(scaninfo + 1);
245
+
246
+	(*pInfoList)->cbCount = 1;
247
+	scaninfo->cbSize = sizeof(*scaninfo);
248
+	scaninfo->objectType = objectType;
249
+	scaninfo->pObjectPath = L"FIXME";
250
+	scaninfo->scanStatus = 3;
251
+	scaninfo->pThreatName = wvirname;
252
+	if(!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, virname, -1, wvirname, MAX_VIRNAME_LEN))
253
+	    scaninfo->pThreatName = L"INFECTED";
254
+	logg("FOUND: %s", virname);
255
+    }
256
+    WIN();
257
+}
258
+
259
+
260
+int CLAMAPI Scan_DeleteScanInfo(CClamAVScanner *pScanner, PCLAM_SCAN_INFO_LIST pInfoList) {
261
+    free(pInfoList);
262
+    WIN();
263
+}
0 264
new file mode 100644
... ...
@@ -0,0 +1,25 @@
0
+/*
1
+ * Copyright (C) 2010 Sourcefire, Inc.
2
+ * Authors: aCaB <acab@clamav.net>
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License version 2.1 as published by the Free Software Foundation.
7
+ *
8
+ * This library is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
+ * Lesser General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU Lesser General Public
14
+ * License along with this library; if not, write to the Free Software
15
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
16
+ * USA
17
+ */
18
+
19
+#ifndef __INTERFACE_H
20
+#define __INTERFACE_H
21
+
22
+BOOL interface_setup(void);
23
+
24
+#endif
0 25
\ No newline at end of file
1 26
new file mode 100644
... ...
@@ -0,0 +1,37 @@
0
+/*
1
+ * Copyright (C) 2010 Sourcefire, Inc.
2
+ * Authors: aCaB <acab@clamav.net>
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License version 2.1 as published by the Free Software Foundation.
7
+ *
8
+ * This library is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
+ * Lesser General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU Lesser General Public
14
+ * License along with this library; if not, write to the Free Software
15
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
16
+ * USA
17
+ */
18
+
19
+#if HAVE_CONFIG_H
20
+#include "clamav-config.h"
21
+#endif
22
+
23
+#include "interface.h"
24
+
25
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {
26
+	switch (ul_reason_for_call)
27
+	{
28
+	case DLL_PROCESS_ATTACH:
29
+	    return interface_setup();
30
+	case DLL_THREAD_ATTACH:
31
+	case DLL_THREAD_DETACH:
32
+	case DLL_PROCESS_DETACH:
33
+		break;
34
+	}
35
+	return TRUE;
36
+}
... ...
@@ -59,6 +59,9 @@ char *strptime(const char *s, const char *format, struct tm *tm);
59 59
 #define closesocket w32_closesocket
60 60
 #define getservbyname w32_getservbyname
61 61
 #define getaddrinfo w32_getaddrinfo
62
+#ifdef gai_strerror
63
+#undef gai_strerror
64
+#endif
62 65
 #define gai_strerror w32_strerror
63 66
 #define freeaddrinfo w32_freeaddrinfo
64 67
 #define inet_ntop w32_inet_ntop