|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- // SNFMilter.hpp
- // Copyright (C) 2007 ARM Research Labs, LLC.
- // See www.armresearch.com for the copyright terms.
- //
- // This file defines the SNFMilter configuration data structures and interface.
-
- #ifndef SNFMilterhpp_included
- #define SNFMilterhpp_included
-
- #include <libmilter/mfapi.h>
-
- #include <vector>
- #include <string>
- #include "MailHeaders.hpp"
- #include "timing.hpp"
- #include "threading.hpp"
-
- using namespace std;
-
- class snf_EngineHandler; // We must know that these exist.
- class snf_RulebaseHandler;
-
- // Connection types.
-
- enum SNFMilterSocketType {
- TCPMilterSocket = 1,
- UNIXMilterSocket = 2,
- NOMilterSocket = 3
- };
-
- // SNFMilterAction - What we can do.
-
- enum SNFMilterAction { // SNFMilter Actions
- Error = -1, // Error result.
- Allow = 0, // Process the message.
- Accept = 1, // White-List the message.
- Retry = 2, // Return Try Again (tmp fail)
- Reject = 3, // Reject the message.
- Discard = 4, // Silently discard.
- Quarantine = 5, // Store in quarantine.
- NoAction = 6, // Take no action.
- NMilterActions
- };
-
- //
- // Configuration.
- //
- const string AllowActionMnemonic = "0";
- const string AcceptActionMnemonic = "1";
- const string RetryActionMnemonic = "2";
- const string RejectActionMnemonic = "3";
- const string DiscardActionMnemonic = "4";
- const string QuarantineActionMnemonic = "5";
- const string NoActionMnemonic = "6";
-
- const string TCPMilterSocketMnemonic = "1";
- const string UNIXMilterSocketMnemonic = "2";
-
- const int ResultCodesCount = 256; // Number of valid result codes.
- const int MinErrorResultCode = 64; // Minimum result code for Error action.
- const int MaxErrorResultCode = 99; // Maximum result code for Error action.
- const int ConfigurationLifetime = 1000; // Config life time in ms.
- const bool PrependLocalReceivedHeader = true; // True to prepend local received headers
- // to the buffer to scan.
- const sfsistat FailSafeMilterResponse = SMFIS_CONTINUE; // Return value to libmilter
- // in case of error.
- const string::size_type MailBufferReserveSize = 65536; // Maximum amount of email message to scan.
- const string SMTPENDL = "\r\n"; // SMTP endline.
- const int ShutdownPeriods = 5; // Number of time periods to wait while
- // shutting down.
- const int ShutdownWaitPeriod_ms = 1000; // Time period duration for shutting down.
-
- const string UnknownExceptionMessage = "Unknown exception occurred."; // Logged when an unknown exception occurs.
-
- //
- // End of configuration.
- //
-
- // The SNFMilterEngine class provides up to date configuration data and
- // a scanning engine for the milter. It is presumed that at one of these objects
- // will be used in each message scan. They can be created, used, and destroyed,
- // or for a more optimized approach they can be created, used, stored in a pool,
- // and refreshed, and used again for a new scan. They should all be properly
- // destroyed before runLibMilter() returns.
- class SNFMilterEngine { // Milter config objec. One per scan.
- private:
-
- codedweller::Mutex ConfigMutex; // Configuration lock mutex.
-
- snf_RulebaseHandler* myRulebase; // Where is my rulebase?
- snf_EngineHandler* myEngine; // Where is my engine?
-
- // Configuration data.
- // IP scan actions
-
- SNFMilterAction WhiteAction; // Action for White IP.
- SNFMilterAction CautionAction; // Action for Caution IP.
- SNFMilterAction BlackAction; // Action for Black IP.
- SNFMilterAction TruncateAction; // Action for Truncate IP.
- SNFMilterAction NonZeroAction; // Action for nonzero scans.
-
- // Message scan actions
-
- SNFMilterAction ResultActions[ResultCodesCount]; // Array of possible scan actions.
-
- codedweller::Timeout ConfigurationCheckTime; // Timer for checking the configuration.
- string RunningConfiguration; // The current running config string.
- void readConfiguration(); // Parses the configuration.
- void checkConfiguration(); // Reload the config if it is old.
-
- public:
- SNFMilterEngine(snf_RulebaseHandler* R); // Construct the configuration.
- ~SNFMilterEngine(); // Destroy the configuration.
-
- void setResultAction(int Result, SNFMilterAction Action); // Set a result / action pair.
-
- SNFMilterAction scanIP(unsigned long int IP); // Scans an IP.
- SNFMilterAction scanMessage(const unsigned char* bfr, int length); // Scans a message.
- string XHeaders(); // Return X headers from last scan.
- };
-
- // The SNFMilterContext class maintains the context for a connection
- // from the MTA. There is one SNFMilterContext object for each
- // connection from the MTA. They can be created, used, and destroyed,
- // or for a more optimized approach they can be created, used, stored
- // in a pool, and refreshed, and used again for a new scan. They
- // should all be properly destroyed before runLibMilter() returns.
-
- class SNFMilterContext { // Milter connection context object.
- public:
-
- // Object states. The object transitions to the corresponding state
- // when a libmilter callback is invoked. The object is in the
- // Pooled state when the object is not being used.
- enum SNFMilterState {
- Pooled,
- Connect,
- Helo,
- EnvFrom,
- EnvRcpt,
- Data,
- Header,
- EOH,
- Body,
- EOM,
- Close,
- NMilterStates
- } State;
-
- SNFMilterContext(snf_RulebaseHandler *);
- ~SNFMilterContext();
-
- // Map the scan result to the libmilter return value.
- sfsistat
- smfisReturn(SNFMilterAction);
-
- // Scanning engine.
- SNFMilterEngine milterEngine;
-
- string getLocalReceivedHeader();
-
- // Connection data.
- struct SNFMilterConnectionData {
- string HostName;
- codedweller::IP4Address HostIP;
- string HostHelo;
-
- // Clear the object.
- void clear() {
- HostName.clear();
- HostIP = (long unsigned )0;
- HostHelo.clear();
- }
-
- } ConnectionData;
-
- // Message buffer.
- struct SNFMilterMessageData {
-
- // Buffer to hold the message.
- string MessageBuffer;
-
- // Sender address.
- string SenderAddress;
-
- // Constructor reserves memory to hold the message.
- SNFMilterMessageData(string::size_type reserveSize) {
- MessageBuffer.reserve(reserveSize);
- }
-
- // Clear the object.
- void clear() {
- MessageBuffer.clear();
- SenderAddress.clear();
- }
-
- } MessageData;
-
- };
-
- class SNFMilterContextPool { // SNFMilter Pool Manager
- private:
- codedweller::Mutex ContextAllocationControl; // Protects context allocation.
- vector<SNFMilterContext*> ContextPool; // Contains all created contexts.
- codedweller::ProductionQueue<SNFMilterContext*> AvailableContexts; // Contains all available contexts.
-
- snf_RulebaseHandler* myRulebase; // Rulebase handler.
-
- // Connection info.
- SNFMilterSocketType MilterSocketType;
- string MilterSocketPath;
- string MilterSocketGroup;
- string MilterSocketIP;
- int MilterSocketPort;
-
- public:
- SNFMilterContextPool(snf_RulebaseHandler* Rulebase); // Ctor needs a live rulebase handler.
- ~SNFMilterContextPool(); // Dtor gracefully discards contexts.
-
- SNFMilterSocketType getSocketType(); // Named pipe or TCP socket specified
- // in the configuration.
-
- string getSocketPath(); // Path of named pipe specified in
- // the configuration
-
- string getSocketGroup(); // Group specified for named pipe
- // in the conofiguration.
-
- string getSocketIP(); // IP (host) specified in the
- // configuration.
-
- int getSocketPort(); // TCP port specified in the
- // configuration
-
- SNFMilterContext* grab(); // Get an context to use.
- void drop(SNFMilterContext* E); // Drop an context after use.
- bool allUnused(); // Return true if no contexts are in use.
- void logThisError(string ContextName, int Code, string Text); // Log an error message.
- void logThisInfo(string ContextName, int Code, string Text); // Log an informational message.
-
- };
-
- // The runLibMilter function establishes the appropriate libmilter call backs and
- // accepts calls from the MTA via libmilter until it is told to quit. When it
- // is told to quit it gracefully closes down, reclaims any memory it allocated,
- // and returns.
-
- // The actual code for the runLibMilter() function call is found in SNFMilter.cpp.
-
- void runLibMilter(SNFMilterContextPool* Contexts, bool DebugMode); // Run the milter 'til it's done.
-
- #endif
|