Update of /cvsroot/mahogany/M/src/modules/spam
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3530/src/modules/spam

Modified Files:
        HeadersFilter.cpp 
Log Message:
moved the spam options dialog into the module (from src/gui/wxSpamOptions.cpp)

Index: HeadersFilter.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/modules/spam/HeadersFilter.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -b -u -2 -r1.4 -r1.5
--- HeadersFilter.cpp   11 Jul 2004 21:28:27 -0000      1.4
+++ HeadersFilter.cpp   11 Jul 2004 21:44:07 -0000      1.5
@@ -41,4 +41,6 @@
 #include "Address.h"
 
+#include "gui/wxOptionsPage.h"
+
 #include "SpamFilter.h"
 
@@ -50,4 +52,44 @@
 
 // ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+/// X-Spam-Status: Yes header?
+#define SPAM_TEST_SPAMASSASSIN _T("spamassassin")
+
+/// does the subject contain too many (unencoded) 8 bit chars?
+#define SPAM_TEST_SUBJ8BIT _T("subj8bit")
+
+/// does the subject contain too many capital letters?
+#define SPAM_TEST_SUBJCAPS _T("subjcaps")
+
+/// is the subject of the "...            xyz-12-foo"?
+#define SPAM_TEST_SUBJENDJUNK _T("subjendjunk")
+
+/// korean charset?
+#define SPAM_TEST_KOREAN _T("korean")
+
+/// suspicious X-Authentication-Warning header?
+#define SPAM_TEST_XAUTHWARN _T("xauthwarn")
+
+/// suspicious Received: headers?
+#define SPAM_TEST_RECEIVED _T("received")
+
+/// HTML contents at top level?
+#define SPAM_TEST_HTML _T("html")
+
+/// suspicious MIME structure?
+#define SPAM_TEST_MIME _T("badmime")
+
+/// executable attachment?
+#define SPAM_TEST_EXECUTABLE_ATTACHMENT _T("exeattach")
+
+/// no address in whitelist?
+#define SPAM_TEST_WHITE_LIST _T("whitelist")
+
+/// blacklisted by the RBL?
+#define SPAM_TEST_RBL _T("rbl")
+
+// ----------------------------------------------------------------------------
 // HeadersFilter class
 // ----------------------------------------------------------------------------
@@ -64,4 +106,6 @@
                               const String& param,
                               String *result);
+   virtual const wxChar *GetOptionPageIconName() const { return _T("spam"); }
+   virtual wxOptionsPage *CreateOptionPage(wxListOrNoteBook *notebook) const;
 
 
@@ -70,7 +114,324 @@
 
 IMPLEMENT_SPAM_FILTER(HeadersFilter,
-                      gettext_noop("Heuristic Headers Analyzer"),
+                      gettext_noop("Simple Heuristic Headers Analyzer"),
                       _T("(c) 2002-2004 Vadim Zeitlin <[EMAIL PROTECTED]>"));
 
+
+// ----------------------------------------------------------------------------
+// SpamOption and derived classes, used by HeadersOptionsPage
+// ----------------------------------------------------------------------------
+
+typedef scoped_array<wxOptionsPage::FieldInfo> ArrayFieldInfo;
+
+/*
+   Represents a single spam option.
+
+   This is an ABC, derived classes below are for the concrete options.
+ */
+class SpamOption
+{
+public:
+   /// Is it on or off by default?
+   virtual bool DefaultValue() const = 0;
+
+   /// The token used in spam filter string for this option
+   virtual const wxChar *Token() const = 0;
+
+   /// The name of the profile entry used to pass the value to config dialog
+   virtual const wxChar *TempProfileEntryName() const = 0;
+
+   /// The label of the correponding checkbox in the dialog
+   virtual const wxChar *DialogLabel() const = 0;
+
+   /// The number of entries created by BuildFields()
+   virtual size_t GetEntriesCount() const { return 1; }
+
+   /// Initialize the entries needed by this option in fieldInfo
+   virtual size_t BuildFieldInfo(ArrayFieldInfo& fields, size_t n) const
+   {
+      wxOptionsPage::FieldInfo& info = fields[n];
+      info.label = DialogLabel();
+      info.flags = wxOptionsPage::Field_Bool;
+      info.enable = -1;
+
+      return 1;
+   }
+
+   /// Is it currently active/checked?
+   bool m_active;
+};
+
+
+class SpamOptionAssassin : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return true; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_SPAMASSASSIN; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpamAssassin"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("Been tagged as spam by Spam&Assassin"); }
+};
+
+
+class SpamOption8Bit : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return true; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_SUBJ8BIT; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("Spam8BitSubject"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("Too many &8 bit characters in subject"); }
+};
+
+
+class SpamOptionCaps : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return true; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_SUBJCAPS; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpamCapsSubject"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("Only &capitals in subject"); }
+};
+
+
+class SpamOptionJunkSubject : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return true; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_SUBJENDJUNK; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("JunkEndSubject"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("&Junk at end of subject"); }
+};
+
+
+class SpamOptionKorean : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return true; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_KOREAN; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpamKoreanCharset"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("&Korean charset"); }
+};
+
+class SpamOptionExeAttach : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return true; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_EXECUTABLE_ATTACHMENT; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpamExeAttachment"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("E&xecutable attachment"); }
+
+   virtual size_t GetEntriesCount() const { return 2; }
+   virtual size_t BuildFieldInfo(ArrayFieldInfo& fields, size_t n) const
+   {
+      size_t count = SpamOption::BuildFieldInfo(fields, n);
+      wxOptionsPage::FieldInfo& info = fields[n + count];
+      info.label = gettext_noop(
+            "(beware: this will not catch all dangerous attachments!)");
+      info.flags = wxOptionsPage::Field_Message;
+      info.enable = -1;
+
+      return count + 1;
+   }
+};
+
+class SpamOptionXAuth : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return false; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_XAUTHWARN; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpamXAuthWarning"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("X-Authentication-&Warning header"); }
+};
+
+
+class SpamOptionReceived : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return false; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_RECEIVED; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpamReceived"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("Suspicious \"&Received\" headers"); }
+};
+
+
+class SpamOptionHtml : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return false; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_HTML; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpamHtml"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("Only &HTML content"); }
+};
+
+
+class SpamOptionMime : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return false; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_MIME; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpamMime"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("Unusual &MIME structure"); }
+};
+
+
+class SpamOptionWhiteList : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return false; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_WHITE_LIST; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpameWhiteList"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("No match in &whitelist"); }
+};
+
+
+#ifdef USE_RBL
+
+class SpamOptionRbl : public SpamOption
+{
+public:
+   virtual bool DefaultValue() const { return false; }
+   virtual const wxChar *Token() const
+      { return SPAM_TEST_RBL; }
+   virtual const wxChar *TempProfileEntryName() const
+      { return _T("SpamIsInRBL"); }
+   virtual const wxChar *DialogLabel() const
+      { return gettext_noop("Been &blacklisted by RBL"); }
+};
+
+#endif // USE_RBL
+
+// ----------------------------------------------------------------------------
+// HeadersOptionsPage
+// ----------------------------------------------------------------------------
+
+class HeadersOptionsPage : public wxOptionsPageDynamic
+{
+public:
+   HeadersOptionsPage(wxListOrNoteBook *notebook);
+
+   virtual void FromString(const String &source);
+   virtual String ToString();
+
+   virtual bool TransferDataToWindow();
+   virtual bool TransferDataFromWindow();
+
+private:
+   ConfigValueDefault *GetConfigValues();
+   FieldInfo *GetFieldInfo();
+
+   void SetDefaults();
+   void SetFalse();
+
+   void WriteProfile(Profile *profile);
+   void ReadProfile(Profile *profile);
+   void DeleteProfile(Profile *profile);
+
+   size_t GetConfigEntryCount();
+
+   scoped_array<ConfigValueDefault> m_configValues;
+   ArrayFieldInfo m_fieldInfo;
+
+   SpamOptionAssassin m_checkSpamAssassin;
+   SpamOption *PickAssassin() { return &m_checkSpamAssassin; }
+
+   SpamOption8Bit m_check8bit;
+   SpamOption *Pick8bit() { return &m_check8bit; }
+
+   SpamOptionCaps m_checkCaps;
+   SpamOption *PickCaps() { return &m_checkCaps; }
+
+   SpamOptionJunkSubject m_checkJunkSubj;
+   SpamOption *PickJunkSubject() { return &m_checkJunkSubj; }
+
+   SpamOptionKorean m_checkKorean;
+   SpamOption *PickKorean() { return &m_checkKorean; }
+
+   SpamOptionExeAttach m_checkExeAttach;
+   SpamOption *PickExeAttach() { return &m_checkExeAttach; }
+
+   SpamOptionXAuth m_checkXAuthWarn;
+   SpamOption *PickXAuthWarn() { return &m_checkXAuthWarn; }
+
+   SpamOptionReceived m_checkReceived;
+   SpamOption *PickReceived() { return &m_checkReceived; }
+
+   SpamOptionHtml m_checkHtml;
+   SpamOption *PickHtml() { return &m_checkHtml; }
+
+   SpamOptionMime m_checkMime;
+   SpamOption *PickMime() { return &m_checkMime; }
+
+   SpamOptionWhiteList m_whitelist;
+   SpamOption *PickWhiteList() { return &m_whitelist; }
+
+#ifdef USE_RBL
+   SpamOptionRbl m_checkRBL;
+   SpamOption *PickRBL() { return &m_checkRBL; }
+#endif // USE_RBL
+
+   // the number of entries in controls/config arrays we need, initially 0 but
+   // computed by GetConfigEntryCount() when it is called for the first time
+   size_t m_nEntries;
+
+
+   typedef SpamOption *(HeadersOptionsPage::*PickMember)();
+   static const PickMember ms_members[];
+   static const size_t ms_count;
+
+   class Iterator
+   {
+   public:
+      Iterator(HeadersOptionsPage *container)
+         : m_container(container), m_index(0) {}
+
+      SpamOption *operator->()
+      {
+         return (m_container->*HeadersOptionsPage::ms_members[m_index])();
+      }
+      void operator++() { if ( !IsEnd() ) m_index++; }
+      bool IsEnd() { return m_index == HeadersOptionsPage::ms_count; }
+      size_t Index() { return m_index; }
+
+   private:
+      HeadersOptionsPage *m_container;
+      size_t m_index;
+   };
+
+   friend class HeadersOptionsPage::Iterator;
+};
+
+
 // ============================================================================
 // HeadersFilter implementation
@@ -1071,2 +1432,233 @@
 }
 
+// ----------------------------------------------------------------------------
+// HeadersFilter configuration
+// ----------------------------------------------------------------------------
+
+wxOptionsPage *
+HeadersFilter::CreateOptionPage(wxListOrNoteBook *notebook) const
+{
+   return new HeadersOptionsPage(notebook);
+}
+
+// ============================================================================
+// HeadersOptionsPage
+// ============================================================================
+
+const HeadersOptionsPage::PickMember HeadersOptionsPage::ms_members[] =
+{
+   &HeadersOptionsPage::PickAssassin,
+   &HeadersOptionsPage::Pick8bit,
+   &HeadersOptionsPage::PickCaps,
+   &HeadersOptionsPage::PickJunkSubject,
+   &HeadersOptionsPage::PickKorean,
+   &HeadersOptionsPage::PickExeAttach,
+   &HeadersOptionsPage::PickXAuthWarn,
+   &HeadersOptionsPage::PickReceived,
+   &HeadersOptionsPage::PickHtml,
+   &HeadersOptionsPage::PickMime,
+   &HeadersOptionsPage::PickWhiteList,
+#ifdef USE_RBL
+   &HeadersOptionsPage::PickRBL,
+#endif // USE_RBL
+};
+
+const size_t
+   HeadersOptionsPage::ms_count = WXSIZEOF(HeadersOptionsPage::ms_members);
+
+
+HeadersOptionsPage::HeadersOptionsPage(wxListOrNoteBook *notebook)
+                  : wxOptionsPageDynamic(notebook)
+{
+   m_nEntries = 0;
+
+   Create
+   (
+      notebook,
+      gettext_noop("Headers filter"),
+      mApplication->GetProfile(),
+      GetFieldInfo(),
+      GetConfigValues(),
+      GetConfigEntryCount(),
+      0,
+      -1,
+      notebook->GetPageCount()
+   );
+}
+
+bool HeadersOptionsPage::TransferDataToWindow()
+{
+   WriteProfile(mApplication->GetProfile());
+
+   return wxOptionsPageDynamic::TransferDataToWindow();
+}
+
+bool HeadersOptionsPage::TransferDataFromWindow()
+{
+   bool rc = wxOptionsPageDynamic::TransferDataFromWindow();
+   if ( rc )
+      ReadProfile(mApplication->GetProfile());
+
+   DeleteProfile(mApplication->GetProfile());
+
+   return rc;
+}
+
+size_t HeadersOptionsPage::GetConfigEntryCount()
+{
+   if ( !m_nEntries )
+   {
+      // sum up the entries of all option
+      for ( HeadersOptionsPage::Iterator option(this);
+            !option.IsEnd();
+            ++option )
+      {
+         m_nEntries += option->GetEntriesCount();
+      }
+
+      // +1 for the explanation text in the beginning
+      m_nEntries++;
+   }
+
+   return m_nEntries;
+}
+
+void HeadersOptionsPage::SetDefaults()
+{
+   for ( HeadersOptionsPage::Iterator option(this); !option.IsEnd(); ++option )
+   {
+      option->m_active = option->DefaultValue();
+   }
+}
+
+void HeadersOptionsPage::SetFalse()
+{
+   for ( HeadersOptionsPage::Iterator option(this); !option.IsEnd(); ++option )
+   {
+      option->m_active = false;
+   }
+}
+
+void HeadersOptionsPage::FromString(const String &source)
+{
+   if ( source.empty() )
+   {
+      SetDefaults();
+      return;
+   }
+
+   SetFalse();
+
+   const wxArrayString tests = strutil_restore_array(source);
+
+   const size_t count = tests.GetCount();
+   for ( size_t token = 0; token < count; token++ )
+   {
+      const wxString& actual = tests[token];
+
+      HeadersOptionsPage::Iterator option(this);
+      while ( !option.IsEnd() )
+      {
+         if ( actual == option->Token() )
+         {
+            option->m_active = true;
+            break;
+         }
+
+         ++option;
+      }
+
+      if ( option.IsEnd() )
+      {
+         FAIL_MSG(String::Format(_T("Unknown spam test \"%s\""), actual.c_str()));
+      }
+   }
+}
+
+String HeadersOptionsPage::ToString()
+{
+   String result;
+
+   for ( HeadersOptionsPage::Iterator option(this); !option.IsEnd(); ++option )
+   {
+      if ( option->m_active )
+      {
+         if ( !result.empty() )
+            result += _T(':');
+
+         result += option->Token();
+      }
+   }
+
+   return result;
+}
+
+void HeadersOptionsPage::WriteProfile(Profile *profile)
+{
+   for ( HeadersOptionsPage::Iterator option(this);
+      !option.IsEnd(); ++option )
+   {
+      profile->writeEntry(option->TempProfileEntryName(), option->m_active);
+   }
+}
+
+void HeadersOptionsPage::ReadProfile(Profile *profile)
+{
+   for ( HeadersOptionsPage::Iterator option(this); !option.IsEnd(); ++option )
+   {
+      option->m_active = profile->readEntry(
+         option->TempProfileEntryName(), 0l) != 0l;
+   }
+}
+
+void HeadersOptionsPage::DeleteProfile(Profile *profile)
+{
+   for ( HeadersOptionsPage::Iterator option(this); !option.IsEnd(); ++option )
+   {
+      profile->DeleteEntry(option->TempProfileEntryName());
+   }
+}
+
+ConfigValueDefault *HeadersOptionsPage::GetConfigValues()
+{
+   // ConfigValueDefault doesn't have default ctor, so use this hack knowing
+   // that ConfigValueNone has exactly the same binary layout as ValueDefault
+   m_configValues.reset(new ConfigValueNone[GetConfigEntryCount()]);
+
+   size_t n = 1;
+   for ( HeadersOptionsPage::Iterator option(this); !option.IsEnd(); ++option )
+   {
+      ConfigValueDefault& value = m_configValues[n];
+      value = ConfigValueDefault
+              (
+                  option->TempProfileEntryName(),
+                  option->DefaultValue()
+              );
+      n += option->GetEntriesCount();
+   }
+
+   return m_configValues.get();
+}
+
+wxOptionsPage::FieldInfo *HeadersOptionsPage::GetFieldInfo()
+{
+   m_fieldInfo.reset(new wxOptionsPage::FieldInfo[GetConfigEntryCount()]);
+
+   m_fieldInfo[0].label
+      = gettext_noop("Mahogany may use several heuristic tests to detect spam.\n"
+                     "Please choose the ones you'd like to be used by checking\n"
+                     "the corresponding entries.\n"
+                     "\n"
+                     "So the message is considered to be spam if it has...");
+   m_fieldInfo[0].flags = wxOptionsPage::Field_Message;
+   m_fieldInfo[0].enable = -1;
+
+   size_t n = 1;
+   for ( HeadersOptionsPage::Iterator option(this); !option.IsEnd(); ++option )
+   {
+      n += option->BuildFieldInfo(m_fieldInfo, n);
+   }
+
+   return m_fieldInfo.get();
+}
+



-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to