00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef _sendmail_milter_Milter_hh
00011 #define _sendmail_milter_Milter_hh
00012 #include <sys/types.h>
00013 #include <stdlib.h>
00014
00015 struct smfi_str;
00016 typedef struct smfi_str SMFICTX;
00017 class sockaddr;
00018
00019 namespace sendmail {
00020 namespace milter {
00021
00026 enum Decision {
00030 CONTINUE = 0,
00034 REJECT = 1,
00039 DISCARD = 2,
00044 ACCEPT = 3,
00049 TEMPFAIL = 4,
00050 };
00051
00052 class CallbackFactory;
00053
00060 class Milter {
00061 public:
00062
00072 Milter(const char* name, CallbackFactory* factory,
00073 const char* connection, int timeout = 1800);
00074 virtual ~Milter();
00075
00079 virtual const CallbackFactory& getCallbackFactory() const;
00080
00084 virtual CallbackFactory& getCallbackFactory();
00085
00089 virtual void start();
00090
00094 virtual void stop();
00095
00100 virtual void setDebug(int debug);
00101
00102 protected:
00103 virtual void _registerMilter(const char* name,
00104 CallbackFactory* factory,
00105 const char* connection,
00106 int timeout);
00107 };
00108
00113 class ConnectionCallbackInterface {
00114 public:
00115 virtual ~ConnectionCallbackInterface() {};
00116
00117 virtual Decision connect(const char* hostname,
00118 const struct sockaddr* hostaddr) = 0;
00119 virtual Decision helo(const char* helohost) = 0;
00120 virtual Decision close() = 0;
00121 };
00122
00127 class MessageCallbackInterface {
00128 public:
00129 virtual ~MessageCallbackInterface() {};
00130
00131 virtual Decision envelopeFrom(const char** argv) = 0;
00132 virtual Decision envelopeRcpt(const char** argv) = 0;
00133 virtual Decision header(const char* headerField,
00134 const char* headerValue) = 0;
00135 virtual Decision endOfHeaders() = 0;
00136 virtual Decision body(const unsigned char* bodyData,
00137 size_t length) = 0;
00138 virtual Decision endOfMessage() = 0;
00139 virtual Decision abortMessage() = 0;
00140 };
00141
00145 class CallbackInterface :
00146 virtual public ConnectionCallbackInterface,
00147 virtual public MessageCallbackInterface {
00148 public:
00149 virtual ~CallbackInterface() {};
00150 };
00151
00155 struct ContextHolder {
00156 SMFICTX* _context;
00157 };
00158
00163 class DataAccess :
00164 virtual protected ContextHolder
00165 {
00166 public:
00167 DataAccess();
00168 DataAccess(SMFICTX* context);
00169 virtual ~DataAccess();
00170
00176 virtual const char* getMacroValue(const char* macroName);
00177
00189 virtual void setReplyCode(const char* rCode,
00190 const char* xCode = NULL,
00191 const char* message = NULL);
00192 };
00193
00198 class MessageModification :
00199 virtual protected ContextHolder
00200 {
00201 public:
00202 MessageModification();
00203 MessageModification(SMFICTX* context);
00204 virtual ~MessageModification();
00205 virtual void addHeader(const char* headerField,
00206 const char* headerValue);
00207 virtual void changeHeader(const char* headerField,
00208 unsigned int headerIndex,
00209 const char* headerValue);
00210 virtual void deleteHeader(const char* headerField,
00211 unsigned int headerIndex);
00212 virtual void addRecipient(const char* recipient);
00213 virtual void deleteRecipient(const char* recipient);
00214 virtual void replaceBody(const unsigned char* bodyData,
00215 size_t length);
00216 };
00217
00222 class CallbackSkeleton :
00223 virtual public CallbackInterface,
00224 virtual public DataAccess,
00225 virtual public MessageModification,
00226 virtual protected ContextHolder
00227 {
00228 public:
00229 CallbackSkeleton(SMFICTX* context);
00230 ~CallbackSkeleton();
00231
00232 virtual Decision connect(const char* hostname,
00233 const struct sockaddr* hostaddr);
00234 virtual Decision helo(const char* helohost);
00235 virtual Decision close();
00236
00237 virtual Decision envelopeFrom(const char** argv);
00238 virtual Decision envelopeRcpt(const char** argv);
00239 virtual Decision header(const char* headerField,
00240 const char* headerValue);
00241 virtual Decision endOfHeaders();
00242 virtual Decision body(const unsigned char* bodyData,
00243 size_t length);
00244 virtual Decision endOfMessage();
00245 virtual Decision abortMessage();
00246 };
00247
00252 enum ModificationFlag {
00253 MOD_ADDHDRS = 0x00000001,
00254 MOD_CHGBODY = 0x00000002,
00255 MOD_ADDRCPT = 0x00000004,
00256 MOD_DELRCPT = 0x00000008,
00257 MOD_CHGHDRS = 0x00000010
00258 };
00259
00264 enum CallbackFlag {
00265 CALLBACK_CONNECT = 0x00000001,
00266 CALLBACK_HELO = 0x00000002,
00267 CALLBACK_ENVFROM = 0x00000004,
00268 CALLBACK_ENVRCPT = 0x00000008,
00269 CALLBACK_HEADER = 0x00000010,
00270 CALLBACK_EOH = 0x00000020,
00271 CALLBACK_BODY = 0x00000040,
00272 CALLBACK_EOM = 0x00000080,
00273 CALLBACK_ABORT = 0x00000100,
00274 CALLBACK_CLOSE = 0x00000200,
00275 };
00276
00282 class CallbackFactory {
00283 public:
00284 virtual ~CallbackFactory() {};
00285
00286 virtual CallbackInterface* newCallback(SMFICTX* context) = 0;
00287 virtual unsigned long getModificationFlags() const = 0;
00288 virtual unsigned long getCallbackFlags() const = 0;
00289 };
00290
00294 template<class C> class SimpleCallbackFactory :
00295 virtual public CallbackFactory {
00296 public:
00297 SimpleCallbackFactory() {
00298 };
00299
00300 virtual CallbackInterface* newCallback(SMFICTX* context) {
00301 return new C(context);
00302 };
00303
00304 virtual unsigned long getModificationFlags() const {
00305 return C::getModificationFlags();
00306 };
00307
00308 virtual unsigned long getCallbackFlags() const {
00309 return C::getCallbackFlags();
00310 };
00311 };
00312
00317 template<class C> class SimpleMilter :
00318 public Milter {
00319 public:
00320 typedef C CallbackType;
00321 typedef SimpleCallbackFactory<C> FactoryType;
00322
00323 SimpleMilter(const char* name, const char* connection,
00324 int timeout) :
00325 Milter(name, new FactoryType(), connection, timeout) {
00326 };
00327 };
00328
00329
00330 template<class C, class D = typename C::ConfigDataType> class SimpleCallbackFactory2 :
00331 virtual public CallbackFactory {
00332 public:
00333 typedef C CallbackType;
00334 typedef D ConfigDataType;
00335
00336 SimpleCallbackFactory2(const ConfigDataType& configData) :
00337 _configData(configData) {
00338 };
00339
00340 virtual CallbackInterface* newCallback(SMFICTX* context) {
00341 return new C(context, _configData);
00342 };
00343
00344 virtual unsigned long getModificationFlags() const {
00345 return C::getModificationFlags();
00346 };
00347
00348 virtual unsigned long getCallbackFlags() const {
00349 return C::getCallbackFlags();
00350 };
00351
00352 virtual const ConfigDataType& getConfigData() const {
00353 return _configData;
00354 };
00355
00356 virtual void setConfigData(const ConfigDataType& configData) {
00357 _configData = configData;
00358 };
00359
00360 protected:
00361 ConfigDataType _configData;
00362 };
00363
00364 template<class C, class D = typename C::ConfigDataType> class SimpleMilter2 :
00365 public Milter {
00366 public:
00367 typedef C CallbackType;
00368 typedef D ConfigDataType;
00369 typedef SimpleCallbackFactory2<C, D> FactoryType;
00370
00371 SimpleMilter2(const char* name, const char* connection,
00372 int timeout, const ConfigDataType& configData) :
00373 Milter(name, new FactoryType(configData), connection,
00374 timeout) {
00375 };
00376
00377 virtual const ConfigDataType& getConfigData() const {
00378
00379
00380
00381 const FactoryType* factory =
00382 dynamic_cast<const FactoryType*>(&getCallbackFactory());
00383 return factory->getConfigData();
00384 };
00385
00386 virtual void setConfigData(const ConfigDataType& configData) {
00387
00388
00389
00390 FactoryType* factory =
00391 dynamic_cast<FactoryType*>(&getCallbackFactory());
00392 factory->setConfigData(configData);
00393 };
00394 };
00395
00396 extern CallbackFactory* _callbackFactory;
00397
00398 }
00399 }
00400
00401 #endif
00402
00403
00404
00405
00406
00407
00408
00409