選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

SNFMilter.hpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // SNFMilter.hpp
  2. // Copyright (C) 2007 ARM Research Labs, LLC.
  3. // See www.armresearch.com for the copyright terms.
  4. //
  5. // This file defines the SNFMilter configuration data structures and interface.
  6. #ifndef SNFMilterhpp_included
  7. #define SNFMilterhpp_included
  8. #include <libmilter/mfapi.h>
  9. #include <vector>
  10. #include <string>
  11. #include "MailHeaders.hpp"
  12. #include "timing.hpp"
  13. #include "threading.hpp"
  14. using namespace std;
  15. class snf_EngineHandler; // We must know that these exist.
  16. class snf_RulebaseHandler;
  17. // Connection types.
  18. enum SNFMilterSocketType {
  19. TCPMilterSocket = 1,
  20. UNIXMilterSocket = 2,
  21. NOMilterSocket = 3
  22. };
  23. // SNFMilterAction - What we can do.
  24. enum SNFMilterAction { // SNFMilter Actions
  25. Error = -1, // Error result.
  26. Allow = 0, // Process the message.
  27. Accept = 1, // White-List the message.
  28. Retry = 2, // Return Try Again (tmp fail)
  29. Reject = 3, // Reject the message.
  30. Discard = 4, // Silently discard.
  31. Quarantine = 5, // Store in quarantine.
  32. NoAction = 6, // Take no action.
  33. NMilterActions
  34. };
  35. //
  36. // Configuration.
  37. //
  38. const string AllowActionMnemonic = "0";
  39. const string AcceptActionMnemonic = "1";
  40. const string RetryActionMnemonic = "2";
  41. const string RejectActionMnemonic = "3";
  42. const string DiscardActionMnemonic = "4";
  43. const string QuarantineActionMnemonic = "5";
  44. const string NoActionMnemonic = "6";
  45. const string TCPMilterSocketMnemonic = "1";
  46. const string UNIXMilterSocketMnemonic = "2";
  47. const int ResultCodesCount = 64; // Number of valid result codes.
  48. const int ConfigurationLifetime = 1000; // Config life time in ms.
  49. const bool PrependLocalReceivedHeader = true; // True to prepend local received headers
  50. // to the buffer to scan.
  51. const sfsistat FailSafeMilterResponse = SMFIS_CONTINUE; // Return value to libmilter
  52. // in case of error.
  53. const string::size_type MailBufferReserveSize = 65536; // Maximum amount of email message to scan.
  54. const string SMTPENDL = "\r\n"; // SMTP endline.
  55. const int ShutdownPeriods = 5; // Number of time periods to wait while
  56. // shutting down.
  57. const int ShutdownWaitPeriod_ms = 1000; // Time period duration for shutting down.
  58. const string UnknownExceptionMessage = "Unknown exception occurred."; // Logged when an unknown exception occurs.
  59. //
  60. // End of configuration.
  61. //
  62. // The SNFMilterEngine class provides up to date configuration data and
  63. // a scanning engine for the milter. It is presumed that at one of these objects
  64. // will be used in each message scan. They can be created, used, and destroyed,
  65. // or for a more optimized approach they can be created, used, stored in a pool,
  66. // and refreshed, and used again for a new scan. They should all be properly
  67. // destroyed before runLibMilter() returns.
  68. class SNFMilterEngine { // Milter config objec. One per scan.
  69. private:
  70. Mutex ConfigMutex; // Configuration lock mutex.
  71. snf_RulebaseHandler* myRulebase; // Where is my rulebase?
  72. snf_EngineHandler* myEngine; // Where is my engine?
  73. // Configuration data.
  74. // IP scan actions
  75. SNFMilterAction WhiteAction; // Action for White IP.
  76. SNFMilterAction CautionAction; // Action for Caution IP.
  77. SNFMilterAction BlackAction; // Action for Black IP.
  78. SNFMilterAction TruncateAction; // Action for Truncate IP.
  79. SNFMilterAction NonZeroAction; // Action for nonzero scans.
  80. // Message scan actions
  81. SNFMilterAction ResultActions[ResultCodesCount]; // Array of possible scan actions.
  82. Timeout ConfigurationCheckTime; // Timer for checking the configuration.
  83. string RunningConfiguration; // The current running config string.
  84. void readConfiguration(); // Parses the configuration.
  85. void checkConfiguration(); // Reload the config if it is old.
  86. public:
  87. SNFMilterEngine(snf_RulebaseHandler* R); // Construct the configuration.
  88. ~SNFMilterEngine(); // Destroy the configuration.
  89. void setResultAction(int Result, SNFMilterAction Action); // Set a result / action pair.
  90. SNFMilterAction scanIP(unsigned long int IP); // Scans an IP.
  91. SNFMilterAction scanMessage(const unsigned char* bfr, int length); // Scans a message.
  92. string XHeaders(); // Return X headers from last scan.
  93. };
  94. // The SNFMilterContext class maintains the context for a connection
  95. // from the MTA. There is one SNFMilterContext object for each
  96. // connection from the MTA. They can be created, used, and destroyed,
  97. // or for a more optimized approach they can be created, used, stored
  98. // in a pool, and refreshed, and used again for a new scan. They
  99. // should all be properly destroyed before runLibMilter() returns.
  100. class SNFMilterContext { // Milter connection context object.
  101. public:
  102. // Object states. The object transitions to the corresponding state
  103. // when a libmilter callback is invoked. The object is in the
  104. // Pooled state when the object is not being used.
  105. enum SNFMilterState {
  106. Pooled,
  107. Connect,
  108. Helo,
  109. EnvFrom,
  110. EnvRcpt,
  111. Data,
  112. Header,
  113. EOH,
  114. Body,
  115. EOM,
  116. Close,
  117. NMilterStates
  118. } State;
  119. SNFMilterContext(snf_RulebaseHandler *);
  120. ~SNFMilterContext();
  121. // Map the scan result to the libmilter return value.
  122. sfsistat
  123. smfisReturn(SNFMilterAction);
  124. // Scanning engine.
  125. SNFMilterEngine milterEngine;
  126. string getLocalReceivedHeader();
  127. // Connection data.
  128. struct SNFMilterConnectionData {
  129. string HostName;
  130. IP4Address HostIP;
  131. string HostHelo;
  132. // Clear the object.
  133. void clear() {
  134. HostName.clear();
  135. HostIP = (long unsigned )0;
  136. HostHelo.clear();
  137. }
  138. } ConnectionData;
  139. // Message buffer.
  140. struct SNFMilterMessageData {
  141. // Buffer to hold the message.
  142. string MessageBuffer;
  143. // Sender address.
  144. string SenderAddress;
  145. // Constructor reserves memory to hold the message.
  146. SNFMilterMessageData(string::size_type reserveSize) {
  147. MessageBuffer.reserve(reserveSize);
  148. }
  149. // Clear the object.
  150. void clear() {
  151. MessageBuffer.clear();
  152. SenderAddress.clear();
  153. }
  154. } MessageData;
  155. };
  156. class SNFMilterContextPool { // SNFMilter Pool Manager
  157. private:
  158. Mutex ContextAllocationControl; // Protects context allocation.
  159. vector<SNFMilterContext*> ContextPool; // Contains all created contexts.
  160. ProductionQueue<SNFMilterContext*> AvailableContexts; // Contains all available contexts.
  161. snf_RulebaseHandler* myRulebase; // Rulebase handler.
  162. // Connection info.
  163. SNFMilterSocketType MilterSocketType;
  164. string MilterSocketPath;
  165. string MilterSocketGroup;
  166. string MilterSocketIP;
  167. int MilterSocketPort;
  168. public:
  169. SNFMilterContextPool(snf_RulebaseHandler* Rulebase); // Ctor needs a live rulebase handler.
  170. ~SNFMilterContextPool(); // Dtor gracefully discards contexts.
  171. SNFMilterSocketType getSocketType(); // Named pipe or TCP socket specified
  172. // in the configuration.
  173. string getSocketPath(); // Path of named pipe specified in
  174. // the configuration
  175. string getSocketGroup(); // Group specified for named pipe
  176. // in the conofiguration.
  177. string getSocketIP(); // IP (host) specified in the
  178. // configuration.
  179. int getSocketPort(); // TCP port specified in the
  180. // configuration
  181. SNFMilterContext* grab(); // Get an context to use.
  182. void drop(SNFMilterContext* E); // Drop an context after use.
  183. bool allUnused(); // Return true if no contexts are in use.
  184. void logThisError(string ContextName, int Code, string Text); // Log an error message.
  185. void logThisInfo(string ContextName, int Code, string Text); // Log an informational message.
  186. };
  187. // The runLibMilter function establishes the appropriate libmilter call backs and
  188. // accepts calls from the MTA via libmilter until it is told to quit. When it
  189. // is told to quit it gracefully closes down, reclaims any memory it allocated,
  190. // and returns.
  191. // The actual code for the runLibMilter() function call is found in SNFMilter.cpp.
  192. void runLibMilter(SNFMilterContextPool* Contexts, bool DebugMode); // Run the milter 'til it's done.
  193. #endif