You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. // SNFMultiDLL.cpp
  2. // Copyright (C) ARM Research Labs, LLC
  3. //
  4. // Provides a full SNFMulti engine with dynamic scanner allocation.
  5. #ifdef WIN32
  6. // Required because threading.hpp includes windows.h.
  7. #include <winsock2.h>
  8. #endif
  9. #include <windows.h>
  10. #include <stdexcept>
  11. #include <cmath>
  12. #include "../SNFMulti/snfmulti.hpp"
  13. using namespace std;
  14. const char* SNF_DLL_VERSION = "SNFMulti DLL Version 3.0 Build: " __DATE__ " " __TIME__;
  15. const int snf_ERROR_NO_HANDLE = -1;
  16. const int snf_ERROR_SCAN_FAILED = -2;
  17. const int snf_ERROR_EXCEPTION = -3;
  18. const double snf_ReputationMehResult = 0.0; /* Don't know or don't care */
  19. const double snf_ReputationBadResult = 1.0; /* IP is pure evil */
  20. const double snf_ReputationGoodResult = -1.0; /* IP is pure good */
  21. ////////////////////////////////////////////////////////////////////////////////
  22. // Here we define the interface provided by this DLL.
  23. #define EXP __declspec(dllexport)
  24. extern "C" {
  25. BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ); // Main DLL setup function.
  26. EXP int setThrottle(int Threads); // Set scan thread limit.
  27. EXP int startupSNF(char* Path); // Start SNF with configuration.
  28. EXP int startupSNFAuthenticated(char* Path, char* Lic, char* Auth); // Start SNF with conf & auth.
  29. EXP int shutdownSNF(); // Shutdown SNF.
  30. EXP int testIP(unsigned long int IPToCheck); // Test the IP for a GBUdb range.
  31. EXP double getIPReputation(unsigned long int IPToCheck); // Get reputation figure for IP.
  32. EXP int scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup); // Scan msgBuffer, name, setup time.
  33. EXP int scanFile(char* FilePath, int Setup); // Scan msgFile, setup time.
  34. EXP int getScanXHeaders(int ScanHandle, char** Bfr, int* Length); // Get result & XHeaders.
  35. EXP int getScanXMLLog(int ScanHandle, char** Bfr, int* Length); // Get result & XML Log.
  36. EXP int getScanClassicLog(int ScanHandle, char** Bfr, int* Length); // Get result & Classic Log.
  37. EXP int getScanResult(int ScanHandle); // Get just the scan result.
  38. EXP int closeScan(int ScanHandle); // Close the scan result.
  39. }
  40. ////////////////////////////////////////////////////////////////////////////////
  41. // Here are the guts of the engine.
  42. //
  43. // A ScannerInstance encapsulates an snf_EngineHandler and buffers for the
  44. // scan results. The buffers can safely be passed back to the calling app.
  45. class ScannerInstance : public snf_EngineHandler { // Scanner Instance.
  46. private:
  47. int Ordinal; // Instance ordinal.
  48. int ScanResult; // Current scan result.
  49. string ScanXHeaders; // Buffered X-Headers.
  50. char* ScanXHeadersPtr; // Buffered X-Headers pointer.
  51. int ScanXHeadersLength; // Buffered X-Headers length.
  52. string ScanXMLLog; // Buffered XML Log.
  53. char* ScanXMLLogPtr; // Buffered XML Log pointer.
  54. int ScanXMLLogLength; // Buffered XML Log length.
  55. string ScanClassicLog; // Buffered Classic Log.
  56. char* ScanClassicLogPtr; // Buffered Classic Log pointer.
  57. int ScanClassicLogLength; // Buffered Classic Log length.
  58. void clearBuffers(); // Clears the buffers & result.
  59. public:
  60. ScannerInstance(snf_RulebaseHandler* RBH, int N); // Initialize w/ Rulebase & Ordinal
  61. ~ScannerInstance(); // Cleanup before going away.
  62. int scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup); // Scan message buffer, give handle.
  63. int scanFile(char* FilePath, int Setup); // Scan message file, give handle.
  64. int getScanXHeaders(char** Bfr, int* Length); // Return scan result & X headers.
  65. int getScanXMLLog(char** Bfr, int* Length); // Return scan result & XML log.
  66. int getScanClassicLog(char** Bfr, int* Length); // Return scan result & Classic log.
  67. int getScanResult(); // Return scan result.
  68. };
  69. const int XHeaderReserve = 4096; // Space to reserve for X headers.
  70. const int XMLLogReserve = 4096; // Space to reserve for XML log data.
  71. const int ClassicReserve = 4096; // Space to reserve for Classic log data.
  72. ScannerInstance::ScannerInstance(snf_RulebaseHandler* RBH, int N) : // Initialize.
  73. Ordinal(N), // Ordinal as assigned.
  74. ScanResult(snf_ERROR_UNKNOWN), // No good result yet.
  75. ScanXHeaders(XHeaderReserve, '\0'), // Pre-allocate some space for our
  76. ScanXMLLog(XMLLogReserve, '\0'), // result caching buffers (strings)
  77. ScanClassicLog(ClassicReserve, '\0') { // so we might not have to later.
  78. clearBuffers(); // Clear the buffers.
  79. open(RBH); // Open the engine handler.
  80. }
  81. ScannerInstance::~ScannerInstance() { // When shutting down
  82. close(); // close the engine handler
  83. clearBuffers(); // and clear the buffers.
  84. Ordinal = -1; // Invalidate our handle.
  85. }
  86. // In the C world, 0 cannot be a handle, so when we return a "handle" from
  87. // our scanXX() methods we must convert the scanner's ordinal into a "handle"
  88. // by adding 1. Later on when we get a scanner by it's handle, that function
  89. // reverses the conversion by subtracting 1 from the handle to get the ordinal.
  90. int ScannerInstance::
  91. scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup) { // Scan a message buffer.
  92. try { // Prepare to capture exceptions.
  93. clearBuffers(); // Clear the buffers first.
  94. ScanResult = scanMessage(Bfr, Length, Name, Setup); // Scan and capture the result.
  95. } // Translate exceptions into
  96. catch(snf_EngineHandler::FileError& e) { // result codes and capture them.
  97. ScanResult = snf_ERROR_MSG_FILE;
  98. }
  99. catch(snf_EngineHandler::XHDRError& e) {
  100. ScanResult = snf_ERROR_MSG_FILE;
  101. }
  102. catch(snf_EngineHandler::BadMatrix& e) {
  103. ScanResult = snf_ERROR_BAD_MATRIX;
  104. }
  105. catch(snf_EngineHandler::MaxEvals& e) {
  106. ScanResult = snf_ERROR_MAX_EVALS;
  107. }
  108. catch(snf_EngineHandler::AllocationError& e) {
  109. ScanResult = snf_ERROR_ALLOCATION;
  110. }
  111. catch(...) {
  112. ScanResult = snf_ERROR_UNKNOWN;
  113. }
  114. return (Ordinal + 1); // Return our handle.
  115. }
  116. int ScannerInstance::
  117. scanFile(char* FilePath, int Setup) { // Scan a message file.
  118. try { // Prepare to capture exceptions.
  119. clearBuffers(); // Clear the buffers first.
  120. ScanResult = scanMessageFile(FilePath, Setup); // Scan and capture the result.
  121. } // Translate exceptions into
  122. catch(snf_EngineHandler::FileError& e) { // result codes and capture them.
  123. ScanResult = snf_ERROR_MSG_FILE;
  124. }
  125. catch(snf_EngineHandler::XHDRError& e) {
  126. ScanResult = snf_ERROR_MSG_FILE;
  127. }
  128. catch(snf_EngineHandler::BadMatrix& e) {
  129. ScanResult = snf_ERROR_BAD_MATRIX;
  130. }
  131. catch(snf_EngineHandler::MaxEvals& e) {
  132. ScanResult = snf_ERROR_MAX_EVALS;
  133. }
  134. catch(snf_EngineHandler::AllocationError& e) {
  135. ScanResult = snf_ERROR_ALLOCATION;
  136. }
  137. catch(...) {
  138. ScanResult = snf_ERROR_UNKNOWN;
  139. }
  140. return (Ordinal + 1); // Return our handle.
  141. }
  142. void ScannerInstance::clearBuffers() { // Clear the buffers.
  143. ScanXHeaders.clear(); // Clear the buffer strings
  144. ScanXHeadersPtr = 0; // zero their pointers and
  145. ScanXHeadersLength = 0; // zero their lengths.
  146. ScanXMLLog.clear();
  147. ScanXMLLogPtr = 0;
  148. ScanXMLLogLength = 0;
  149. ScanClassicLog.clear();
  150. ScanClassicLogPtr = 0;
  151. ScanClassicLogLength = 0;
  152. ScanResult = snf_ERROR_UNKNOWN;
  153. }
  154. int ScannerInstance::getScanXHeaders(char** Bfr, int* Length) { // Return the result & X headers.
  155. if(0 == ScanXHeadersPtr) { // If we haven't already then
  156. ScanXHeaders = getXHDRs(); // capture the data.
  157. ScanXHeadersLength = ScanXHeaders.length();
  158. ScanXHeadersPtr = const_cast<char*>(ScanXHeaders.c_str());
  159. }
  160. *Bfr = ScanXHeadersPtr; // Pass the pointer and
  161. *Length = ScanXHeadersLength; // length back to the caller.
  162. return ScanResult; // Return the scan result.
  163. }
  164. int ScannerInstance::getScanXMLLog(char** Bfr, int* Length) { // Return the result & XML log.
  165. if(0 == ScanXMLLogPtr) { // If we haven't already then
  166. ScanXMLLog = getXMLLog(); // capture the data.
  167. ScanXMLLogPtr = const_cast<char*>(ScanXMLLog.c_str());
  168. ScanXMLLogLength = ScanXMLLog.length();
  169. }
  170. *Bfr = ScanXMLLogPtr; // Pass the pointer and
  171. *Length = ScanXMLLogLength; // length back to the caller.
  172. return ScanResult; // Return the scan result.
  173. }
  174. int ScannerInstance::getScanClassicLog(char** Bfr, int* Length) { // Return the result & Classic log.
  175. if(0 == ScanClassicLogPtr) { // If we haven't already then
  176. ScanClassicLog = getClassicLog(); // capture the data.
  177. ScanClassicLogPtr = const_cast<char*>(ScanClassicLog.c_str());
  178. ScanClassicLogLength = ScanClassicLog.length();
  179. }
  180. *Bfr = ScanClassicLogPtr; // Pass the pointer and
  181. *Length = ScanClassicLogLength; // length back to the caller.
  182. return ScanResult; // Return the scan result.
  183. }
  184. int ScannerInstance::getScanResult() { // Return the scan result only.
  185. return ScanResult; // Just like that.
  186. }
  187. // The snfScannerPool starts up and shuts down the rulebase engine and keeps
  188. // track of the ScannerInstances.
  189. class snfScannerPool { // Dynamically allocated scanner pool.
  190. private:
  191. codedweller::Mutex myMutex; // Protect the state of the pool.
  192. snf_RulebaseHandler* myRulebaseHandler; // This is our rulebase manager.
  193. vector<ScannerInstance*> ScannerPool; // This is a collection of scanners.
  194. codedweller::ProductionQueue<ScannerInstance*> AvailableScanners; // This is the available scanners queue.
  195. unsigned int ScanThreadLimit; // Maximum number of concurrent threads.
  196. public:
  197. snfScannerPool(); // This is how we are constructed.
  198. ~snfScannerPool(); // This is how we are destroyed.
  199. void Throttle(int ThreadLimit); // Set a Scan Thread Limit.
  200. void startup(char* ConfigurationPath); // Startup the engine w/ config.
  201. void startupAuthenticated(char* Path, char* Lic, char* Auth); // Startup engine w/ full auth.
  202. void shutdown(); // Shutdown the engine.
  203. int testIP(unsigned long int IPToCheck); // Test an IP against gbudb.
  204. double getIPReputation(unsigned long int IPToCheck); // This is how we get IP reps.
  205. ScannerInstance* grabScanner(); // Get a new (available) scanner.
  206. ScannerInstance* getScanner(int ScanHandle); // What scanner goes with this handle?
  207. void dropScanner(ScannerInstance* S); // When done with a scanner, drop it.
  208. };
  209. snfScannerPool Scanners; // Call our local pool "Scanners".
  210. snfScannerPool::snfScannerPool() : // When created, our
  211. myRulebaseHandler(0), // rulebase handler is 0.
  212. ScanThreadLimit(0) {} // There is no limit.
  213. snfScannerPool::~snfScannerPool() { // When destroyed we must
  214. shutdown(); // shutdown if needed.
  215. }
  216. void snfScannerPool::Throttle(int ThreadLimit) { // Set a scanner thread limit.
  217. ThreadLimit = (0 > ThreadLimit) ? 0 : ThreadLimit; // Throttle will be 0 or above.
  218. ScanThreadLimit = ThreadLimit;
  219. }
  220. void snfScannerPool::startup(char* ConfigurationPath) { // Start the engine with this config.
  221. codedweller::ScopeMutex StateIsInFlux(myMutex); // Protect our state data.
  222. if(myRulebaseHandler) return; // If we are started, do nothing.
  223. myRulebaseHandler = new snf_RulebaseHandler(); // Create a new rulebase handler.
  224. myRulebaseHandler->PlatformVersion(SNF_DLL_VERSION); // Record our version identification.
  225. myRulebaseHandler->open(ConfigurationPath, "", ""); // Open the rulebase with the config.
  226. }
  227. void snfScannerPool::startupAuthenticated(char* Path, char* Lic, char* Auth) { // Startup engine w/ full auth.
  228. codedweller::ScopeMutex StateIsInFlux(myMutex); // Protect our state data.
  229. if(myRulebaseHandler) return; // If we are started, do nothing.
  230. myRulebaseHandler = new snf_RulebaseHandler(); // Create a new rulebase handler.
  231. myRulebaseHandler->PlatformVersion(SNF_DLL_VERSION); // Record our version identification.
  232. myRulebaseHandler->open(Path, Lic, Auth); // Open rulebase with full auth.
  233. }
  234. void snfScannerPool::shutdown() { // Shutdown the engine.
  235. codedweller::ScopeMutex StateIsInFlux(myMutex); // Protect our state data.
  236. if(
  237. 0 == ScannerPool.size() &&
  238. 0 == AvailableScanners.size() &&
  239. 0 == myRulebaseHandler
  240. ) return; // If we are down don't bother.
  241. if(ScannerPool.size() != AvailableScanners.size()) throw false; // If some scanners are in use throw!
  242. for(
  243. vector<ScannerInstance*>::iterator iS = ScannerPool.begin(); // Destroy all of the scanner
  244. iS != ScannerPool.end(); // instances in the pool.
  245. iS++) delete (*iS);
  246. ScannerPool.clear(); // Empty the pool of pointers.
  247. while(0 < AvailableScanners.size()) AvailableScanners.take(); // Empty the available scanners.
  248. if(myRulebaseHandler) { // Safely destroy the rulebase handler.
  249. myRulebaseHandler->close(); // Close it first,
  250. delete myRulebaseHandler; // then delete it,
  251. myRulebaseHandler = 0; // then forget about it.
  252. }
  253. }
  254. int snfScannerPool::testIP(unsigned long int IPToCheck) { // This is how we test IPs.
  255. codedweller::ScopeMutex StayAsYouAre(myMutex); // Hold things steady while we do this.
  256. if(0 == myRulebaseHandler) return snf_ERROR_NO_HANDLE; // If we have no engine, punt!
  257. IPTestRecord Tester(IPToCheck); // Make up a test record for this IP.
  258. myRulebaseHandler->performIPTest(Tester); // Run it past the engine.
  259. return static_cast<int>(Tester.R); // IPRange is an enum, so use as an int.
  260. }
  261. double snfScannerPool::getIPReputation(unsigned long int IPToCheck) { // This is how we get IP reps.
  262. codedweller::ScopeMutex StayAsYouAre(myMutex); // Hold things steady while we do this.
  263. if(0 == myRulebaseHandler) return snf_ERROR_NO_HANDLE; // If we have no engine, punt!
  264. IPTestRecord Tester(IPToCheck); // Make up a test record for this IP.
  265. myRulebaseHandler->performIPTest(Tester); // Run it past the engine.
  266. // Now that we have a result from the engine let's translate the result.
  267. double Reputation = snf_ReputationMehResult; // Reputation figures are precise.
  268. switch(Tester.G.Flag()) { // Flags get priority in our translation.
  269. case Good: Reputation = snf_ReputationGoodResult; break; // A good flag means the IP is pure good.
  270. case Bad: Reputation = snf_ReputationBadResult; break; // A bad flag means the IP is pure evil.
  271. case Ignore: Reputation = snf_ReputationMehResult; break; // An ignore flag means we don't care.
  272. default: { // Ugly means we calculate the reputation
  273. Reputation = // figure from the statistics. Start by
  274. sqrt(fabs(Tester.G.Probability() * Tester.G.Confidence())); // combining the c & p figures then
  275. if(0 > Tester.G.Probability()) Reputation *= -1.0; // flip the sign if p is negative.
  276. }
  277. }
  278. return Reputation; // This is what we say about this IP.
  279. }
  280. // In order to balance off speed and safety we control access when starting
  281. // up, shutting down, or getting a new scanner. The grabScanner operation is
  282. // usually very fast.
  283. //
  284. // The the calling application behaves properly it will never attempt a scan
  285. // while attempting to shutdown, and will never attempt to shutdown while it
  286. // is performing a scan. If this conflict does occur then one of two cases
  287. // arise:
  288. //
  289. // The shutdown() thread grabs the mutex before the grabScanner() thread,
  290. // the engine is shutdown, then the grabScanner() thread finds the engine
  291. // is down and cannot return a scanner.
  292. //
  293. // The grabScanner() thread gets the mutex before the shutdown() thread,
  294. // a scanner is allocated, and the shutdown() thread discovers an imabalance
  295. // in the number of Available scanners and the number of scanners in the pool.
  296. // When it discovers that it will throw false and the C interface function will
  297. // return an error.
  298. ScannerInstance* snfScannerPool::grabScanner() { // Get the next available scanner.
  299. codedweller::ScopeMutex FreezeOurState(myMutex); // Don't change while I'm doing this.
  300. if(0 == myRulebaseHandler) return 0; // If we're not alive return nothing.
  301. if(1 > AvailableScanners.size()) { // No scanners? See about making one.
  302. if(
  303. 0 == ScanThreadLimit || // If there is no limit OR
  304. ScanThreadLimit > ScannerPool.size() // we have room for more scanners
  305. ) { // then we can make another one:
  306. ScannerInstance* NewScanner =
  307. new ScannerInstance(myRulebaseHandler, ScannerPool.size()); // Start up a new scanner and
  308. ScannerPool.push_back(NewScanner); // add it to the pool.
  309. AvailableScanners.give(NewScanner); // Make the new scanner available.
  310. } // If we have reached the limit on
  311. } // scanners we will wait for one.
  312. return AvailableScanners.take(); // Get a scanner from the pool.
  313. }
  314. // Since handles are one bigger than the ordinal (so 0 isn't a handle)
  315. // we must convert the ScanHandle we're given into a proper ordinal so
  316. // we can match the scanner's position in the pool. The reverse happens
  317. // upon scan requestes.
  318. ScannerInstance* snfScannerPool::getScanner(int ScanHandle) { // Get the scanner for this handle.
  319. ScannerInstance* S = 0; // We're gonna get a scanner.
  320. try { S = ScannerPool.at(ScanHandle - 1); } // Safely get the scanner at Ordinal.
  321. catch(...) { return 0; } // If something goes wrong, no scanner.
  322. return S; // Return the scanner we got.
  323. }
  324. void snfScannerPool::dropScanner(ScannerInstance* S) { // When done with a scanner, drop it.
  325. if( // If :
  326. 0 != S && // - we have a good scanner pointer and
  327. 0 != myRulebaseHandler // - we are not dead yet
  328. ) AvailableScanners.give(S); // then make the scanner available.
  329. }
  330. ////////////////////////////////////////////////////////////////////////////////
  331. // Interface Functions
  332. BOOL WINAPI DLLMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ) {
  333. try {
  334. switch(wDataSeg) { // Handle setup & teardown msgs.
  335. case DLL_PROCESS_ATTACH: // If the DLL is being loaded
  336. return true; // return true. Nothing to do yet.
  337. break;
  338. case DLL_PROCESS_DETACH: // If the DLL is being dropped
  339. Scanners.shutdown(); // be sure we are shut down first.
  340. break;
  341. default: // For all other messages (thread stuff)
  342. return true; // we'll just return ok because
  343. break; // we don't have any of that here.
  344. }
  345. }
  346. catch(...) {}; // Do not throw exceptions.
  347. // We won't actually get here but we
  348. return false; // want to make the compiler happy :-)
  349. }
  350. EXP int setThrottle(int Threads) { // Set scan thread limit.
  351. try {
  352. Scanners.Throttle(Threads); // Set the throttle limit
  353. }
  354. catch(...) { return snf_ERROR_EXCEPTION; }
  355. return Threads; // and return the value.
  356. }
  357. EXP int startupSNF(char* Path) { // Start the engine.
  358. try { // Use a try block to translate
  359. Scanners.startup(Path); // exceptions into result codes.
  360. }
  361. catch(snf_RulebaseHandler::AuthenticationError &e) { // Catch and translage exceptions.
  362. return snf_ERROR_RULE_AUTH;
  363. }
  364. catch(snf_RulebaseHandler::AllocationError& e) {
  365. return snf_ERROR_ALLOCATION;
  366. }
  367. catch(snf_RulebaseHandler::FileError& e) {
  368. return snf_ERROR_RULE_FILE;
  369. }
  370. catch(...) {
  371. return snf_ERROR_EXCEPTION;
  372. }
  373. return snf_SUCCESS; // No exceptions, All happy :-)
  374. }
  375. EXP int startupSNFAuthenticated(char* Path, char* Lic, char* Auth) { // Start SNF with conf & auth.
  376. try { // Use a try block to translate
  377. Scanners.startupAuthenticated(Path, Lic, Auth); // exceptions into result codes.
  378. }
  379. catch(snf_RulebaseHandler::AuthenticationError &e) { // Catch and translage exceptions.
  380. return snf_ERROR_RULE_AUTH;
  381. }
  382. catch(snf_RulebaseHandler::AllocationError& e) {
  383. return snf_ERROR_ALLOCATION;
  384. }
  385. catch(snf_RulebaseHandler::FileError& e) {
  386. return snf_ERROR_RULE_FILE;
  387. }
  388. catch(...) {
  389. return snf_ERROR_EXCEPTION;
  390. }
  391. return snf_SUCCESS; // No exceptions, All happy :-)
  392. }
  393. EXP int shutdownSNF() { // Shut down the engine.
  394. try { // Use a try block to translate
  395. Scanners.shutdown(); // exceptions into result codes.
  396. }
  397. catch(snf_RulebaseHandler::AuthenticationError &e) { // Catch and translage exceptions.
  398. return snf_ERROR_RULE_AUTH;
  399. }
  400. catch(snf_RulebaseHandler::AllocationError& e) {
  401. return snf_ERROR_ALLOCATION;
  402. }
  403. catch(snf_RulebaseHandler::FileError& e) {
  404. return snf_ERROR_RULE_FILE;
  405. }
  406. catch(...) {
  407. return snf_ERROR_EXCEPTION;
  408. }
  409. return snf_SUCCESS; // No exceptions, All happy :-)
  410. }
  411. EXP int testIP(unsigned long int IPToCheck) { // Test the IP for a GBUdb range.
  412. int Result = snf_ERROR_EXCEPTION; // On panics return this.
  413. try {
  414. Result = Scanners.testIP(IPToCheck); // Testing an IP is easy.
  415. }
  416. catch(...) {} // Do not throw exceptions.
  417. return Result; // Return the result.
  418. }
  419. EXP double getIPReputation(unsigned long int IPToCheck) { // Get reputation figure for IP.
  420. double Result = snf_ReputationMehResult; // On panics return this.
  421. try {
  422. Result = Scanners.getIPReputation(IPToCheck); // Getting an IP rep is easy.
  423. }
  424. catch(...) {} // Do not throw exceptions.
  425. return Result; // Return the result.
  426. }
  427. EXP int scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup) { // Scan a message.
  428. ScannerInstance* myScanner = 0; // We need a scanner.
  429. try { myScanner = Scanners.grabScanner(); } // Safely get a scanner.
  430. catch(...) { return snf_ERROR_NO_HANDLE; } // If that fails, we're done.
  431. int ScannerHandle = snf_ERROR_NO_HANDLE; // We will return a handle.
  432. try { ScannerHandle = myScanner->scanBuffer(Bfr, Length, Name, Setup); } // Perform the scan.
  433. catch(...) { // If we get an unhandled
  434. Scanners.dropScanner(myScanner); // exception then drop the
  435. return snf_ERROR_SCAN_FAILED; // scanner and return the failure.
  436. } // If all goes well then
  437. return ScannerHandle; // return our scanner's handle.
  438. }
  439. EXP int scanFile(char* FilePath, int Setup) {
  440. ScannerInstance* myScanner = 0; // We need a scanner.
  441. try { myScanner = Scanners.grabScanner(); } // Safely get a scanner.
  442. catch(...) { return snf_ERROR_NO_HANDLE; } // If that fails, we're done.
  443. int ScannerHandle = snf_ERROR_NO_HANDLE; // We will return a handle.
  444. try { ScannerHandle = myScanner->scanFile(FilePath, Setup); } // Perform the scan.
  445. catch(...) { // If we get an unhandled
  446. Scanners.dropScanner(myScanner); // exception then drop the
  447. return snf_ERROR_SCAN_FAILED; // scanner and return the failure.
  448. } // If all goes well then
  449. return ScannerHandle; // return our scanner's handle.
  450. }
  451. EXP int getScanXHeaders(int ScanHandle, char** Bfr, int* Length) { // Return the XHeaders for a scan.
  452. ScannerInstance* myScanner = 0; // We need the scanner.
  453. try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
  454. catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't, we're broken.
  455. if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
  456. int Result = snf_ERROR_EXCEPTION; // On panic return this error code.
  457. try {
  458. Result = myScanner->getScanXHeaders(Bfr, Length); // If we can, get our data.
  459. }
  460. catch(...) {} // Do not throw exceptions.
  461. return Result; // Return our result.
  462. }
  463. EXP int getScanXMLLog(int ScanHandle, char** Bfr, int* Length) { // Return the XML Log for a scan.
  464. ScannerInstance* myScanner = 0; // We need the scanner.
  465. try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
  466. catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't, we're broken.
  467. if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
  468. int Result = snf_ERROR_EXCEPTION; // On panic return this error code.
  469. try {
  470. Result = myScanner->getScanXMLLog(Bfr, Length); // If we can, get our data.
  471. }
  472. catch(...) {} // Do not throw exceptions.
  473. return Result; // Return our result.
  474. }
  475. EXP int getScanClassicLog(int ScanHandle, char** Bfr, int* Length) { // Return the classic log for a scan.
  476. ScannerInstance* myScanner = 0; // We need the scanner.
  477. try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
  478. catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't we're broken.
  479. if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
  480. int Result = snf_ERROR_EXCEPTION; // On panic return this error code.
  481. try {
  482. Result = myScanner->getScanClassicLog(Bfr, Length); // If we can, get our data.
  483. }
  484. catch(...) {} // Do not throw exceptions.
  485. return Result; // Return our result.
  486. }
  487. EXP int getScanResult(int ScanHandle) { // Return just the scan result.
  488. ScannerInstance* myScanner = 0; // We need the scanner.
  489. try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
  490. catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't we're broken.
  491. if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
  492. return myScanner->getScanResult(); // If we can, get our data.
  493. }
  494. EXP int closeScan(int ScanHandle) { // Return the scanner to the pool.
  495. ScannerInstance* myScanner = 0; // We need the scanner.
  496. try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
  497. catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't we're broken.
  498. if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
  499. try { Scanners.dropScanner(myScanner); } // If we can then drop the scanner.
  500. catch(...) { return snf_ERROR_EXCEPTION; } // Convert exceptions to a panic code.
  501. return snf_SUCCESS; // If all ok then return success.
  502. }