From 72477bab0fd82ee29274ac14f2ea0d5eae01e7ee Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sat, 17 Nov 2007 14:14:19 +0100
Subject: [PATCH] Created skeletons for regex and relational extensions. These
 are to be developed simultaneously with the match-type support in general.

---
 configure.in                                  |   2 +
 sieve/tests/match-type.sieve                  |   2 +-
 src/lib-sieve/plugins/Makefile.am             |   2 +-
 src/lib-sieve/plugins/regex/Makefile.am       |  12 +
 .../regex/draft-murchison-sieve-regex-07.txt  | 451 ++++++++++++++++++
 src/lib-sieve/plugins/regex/ext-regex.c       |  90 ++++
 src/lib-sieve/plugins/regex/regex.sieve       |   8 +
 src/lib-sieve/plugins/relational/Makefile.am  |  12 +
 .../plugins/relational/ext-relational.c       | 127 +++++
 .../plugins/relational/relational.sieve       |   8 +
 src/lib-sieve/plugins/relational/rfc3431.txt  | 451 ++++++++++++++++++
 src/lib-sieve/sieve-extensions.c              |   5 +-
 src/sieve-bin/Makefile.am                     |   4 +-
 13 files changed, 1170 insertions(+), 4 deletions(-)
 create mode 100644 src/lib-sieve/plugins/regex/Makefile.am
 create mode 100644 src/lib-sieve/plugins/regex/draft-murchison-sieve-regex-07.txt
 create mode 100644 src/lib-sieve/plugins/regex/ext-regex.c
 create mode 100644 src/lib-sieve/plugins/regex/regex.sieve
 create mode 100644 src/lib-sieve/plugins/relational/Makefile.am
 create mode 100644 src/lib-sieve/plugins/relational/ext-relational.c
 create mode 100644 src/lib-sieve/plugins/relational/relational.sieve
 create mode 100644 src/lib-sieve/plugins/relational/rfc3431.txt

diff --git a/configure.in b/configure.in
index 84112b6b8..20e146c89 100644
--- a/configure.in
+++ b/configure.in
@@ -62,6 +62,8 @@ src/lib-sieve/plugins/Makefile
 src/lib-sieve/plugins/vacation/Makefile
 src/lib-sieve/plugins/subaddress/Makefile
 src/lib-sieve/plugins/comparator-i-ascii-numeric/Makefile
+src/lib-sieve/plugins/relational/Makefile
+src/lib-sieve/plugins/regex/Makefile
 src/sieve-bin/Makefile
 stamp.h])
 
diff --git a/sieve/tests/match-type.sieve b/sieve/tests/match-type.sieve
index 10e9e659e..737885be3 100644
--- a/sieve/tests/match-type.sieve
+++ b/sieve/tests/match-type.sieve
@@ -1,4 +1,4 @@
-if address :is :comparator "i;octet" :domain "from" "STEPHAN" {
+if address :contains :comparator "i;ascii-casemap" :localpart "from" "STEPHAN" {
 	discard;
 
 	if address :contains :domain :comparator "i;octet" "from" "drunksnipers.com" {
diff --git a/src/lib-sieve/plugins/Makefile.am b/src/lib-sieve/plugins/Makefile.am
index 49ac9a23d..020741cea 100644
--- a/src/lib-sieve/plugins/Makefile.am
+++ b/src/lib-sieve/plugins/Makefile.am
@@ -1 +1 @@
-SUBDIRS = vacation subaddress comparator-i-ascii-numeric
+SUBDIRS = vacation subaddress comparator-i-ascii-numeric relational regex
diff --git a/src/lib-sieve/plugins/regex/Makefile.am b/src/lib-sieve/plugins/regex/Makefile.am
new file mode 100644
index 000000000..a60a112a8
--- /dev/null
+++ b/src/lib-sieve/plugins/regex/Makefile.am
@@ -0,0 +1,12 @@
+noinst_LIBRARIES = lib_ext_regex.a
+
+AM_CPPFLAGS = \
+	-I../../ \
+	-I$(dovecot_incdir) \
+	-I$(dovecot_incdir)/src/lib \
+	-I$(dovecot_incdir)/src/lib-mail \
+	-I$(dovecot_incdir)/src/lib-storage 
+
+lib_ext_regex_a_SOURCES = \
+	ext-regex.c
+
diff --git a/src/lib-sieve/plugins/regex/draft-murchison-sieve-regex-07.txt b/src/lib-sieve/plugins/regex/draft-murchison-sieve-regex-07.txt
new file mode 100644
index 000000000..e5ee1b1a5
--- /dev/null
+++ b/src/lib-sieve/plugins/regex/draft-murchison-sieve-regex-07.txt
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+
+Internet Draft                                               K. Murchison
+Category: Standards Track                              Oceana Matrix Ltd.
+Expires: May 23, 2004                                    18 November 2003
+
+
+            Sieve Email Filtering -- Regular Expression Extension
+
+                    <draft-murchison-sieve-regex-07.txt>
+
+Status of this Memo
+
+    This document is an Internet-Draft and is subject to all provisions
+    of Section 10 of RFC2026.
+
+    Internet-Drafts are working documents of the Internet Engineering
+    Task Force (IETF), its areas, and its working groups.  Note that
+    other groups may also distribute working documents as
+    Internet-Drafts.
+
+    Internet-Drafts are draft documents valid for a maximum of six months
+    and may be updated, replaced, or obsoleted by other documents at any
+    time.  It is inappropriate to use Internet-Drafts as reference
+    material or to cite them other than as "work in progress."
+
+    The list of current Internet-Drafts can be accessed at
+    http://www.ietf.org/1id-abstracts.html
+
+    The list of Internet-Draft Shadow Directories can be accessed at
+    http://www.ietf.org/shadow.html
+
+Copyright Notice
+
+    Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+
+Abstract
+
+    In some cases, it is desirable to have a string matching mechanism
+    which is more powerful than a simple exact match, a substring match
+    or a glob-style wildcard match.  The regular expression matching
+    mechanism defined in this draft should allow users to isolate just
+    about any string or address in a message header or envelope.
+
+
+
+
+
+
+
+
+
+Expires: May 23, 2004         Murchison                         [Page 1]
+
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
+
+
+                           Table of Contents
+
+
+
+0.     Meta-information on this draft  . . . . . . . . . . . . . . .   3
+
+0.1.   Discussion  . . . . . . . . . . . . . . . . . . . . . . . . .   3
+
+0.2.   Noted Changes Since -06 . . . . . . . . . . . . . . . . . . .   3
+
+0.3.   Open Issues . . . . . . . . . . . . . . . . . . . . . . . . .   3
+
+1.     Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   4
+
+2.     Capability Identifier . . . . . . . . . . . . . . . . . . . .   4
+
+3.     Regex Match Type  . . . . . . . . . . . . . . . . . . . . . .   4
+
+4.     Security Considerations . . . . . . . . . . . . . . . . . . .   6
+
+5.     IANA Considerations . . . . . . . . . . . . . . . . . . . . .   6
+
+6.     Normative References  . . . . . . . . . . . . . . . . . . . .   7
+
+7.     Acknowledgments . . . . . . . . . . . . . . . . . . . . . . .   7
+
+8.     Intellectual Property Statement . . . . . . . . . . . . . . .   7
+
+9.     Author's Address  . . . . . . . . . . . . . . . . . . . . . .   8
+
+10.    Full Copyright Statement  . . . . . . . . . . . . . . . . . .   8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires: May 23, 2004         Murchison                         [Page 2]
+
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
+
+
+
+0.     Meta-information on this draft
+
+    This information is intended to facilitate discussion.  It will be
+    removed when this document leaves the Internet-Draft stage.
+
+
+0.1.   Discussion
+
+    This draft is intended to be an extension to the Sieve mail filtering
+    language, available from the RFC repository as
+    <ftp://ftp.ietf.org/rfc/rfc3028.txt>.
+
+    This draft and the Sieve language itself are being discussed on the
+    MTA Filters mailing list at <ietf-mta-filters@imc.org>.  Subscription
+    requests can be sent to <ietf-mta-filters-request@imc.org> (send an
+    email message with the word "subscribe" in the body).  More
+    information on the mailing list along with a WWW archive of back
+    messages is available at <http://www.imc.org/ietf-mta-filters/>.
+
+
+0.2.   Noted Changes Since -06
+
+    Added more open issues.
+
+    Added IANA considerations.
+
+    Editorial changes.
+
+
+0.3.   Open Issues
+
+    The major open issue with this draft is what to do, if anything,
+    about localization/internationalization.  Are [POSIX.2] collating
+    sequences and character equivalents sufficient?  Should we reference
+    the unicode technical specification?  Should we punt and publish the
+    document as experimental?
+
+    Should we allow shorthands such as \b (word boundary) and \w (word
+    character)?
+
+    Should we allow backreferences (useful for matching double words,
+    etc.)?
+
+    Should we integrate with variables, so that $1, $2, ...  correspond
+    to the first, second, ... groups within the regex?
+
+
+
+
+
+Expires: May 23, 2004         Murchison                         [Page 3]
+
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
+
+
+1.  Introduction
+
+    This is an extension to the Sieve language defined by [SIEVE] for
+    comparing strings to regular expressions.
+
+    Conventions for notations are as in [SIEVE] section 1.1, including
+    use of [KEYWORDS].
+
+
+2.  Capability Identifier
+
+    The capability string associated with the extension defined in this
+    document is "regex".
+
+
+3.  Regex Match Type
+
+    Commands that support matching may take the optional tagged argument
+    ":regex" to specify that a regular expression match should be
+    performed.  The ":regex" match type is subject to the same rules and
+    restrictions as the standard match types defined in [SIEVE].  For
+    convenience, the "MATCH-TYPE" syntax element defined in [SIEVE] is
+    augmented here as follows:
+
+         MATCH-TYPE  =/  ":regex"
+
+    Example:
+
+          require "regex";
+
+          # Try to catch unsolicited email.
+          if anyof (
+            # if a message is not to me (with optional +detail),
+            not address :regex ["to", "cc", "bcc"]
+              "me(\\+.*)?@company\\.com",
+
+            # or the subject is all uppercase (no lowercase)
+            header :regex :comparator "i;octet" "subject"
+              "^[^[:lower:]]+$" ) {
+
+            discard;     # junk it
+          }
+
+    The ":regex" match type is compatible with both the "i;octet" and
+    "i;ascii-casemap" comparators and may be used with them.
+
+    Implementations MUST support extended regular expressions (EREs) as
+    defined by [POSIX.2].  Any regular expression not defined by
+
+
+
+Expires: May 23, 2004         Murchison                         [Page 4]
+
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
+
+
+    [POSIX.2], as well as [POSIX.2] basic regular expressions, word
+    boundaries and backreferences are not supported by this extension.
+    Implementations SHOULD reject regular expressions that are
+    unsupported by this specification as a syntax error.
+
+    The following table provides a brief summary of the regular
+    expressions that MUST be supported.  This table is presented here
+    only as a guideline.  [POSIX.2] should be used as the definitive
+    reference.
+
+
+    +------------+-----------------------------------------------------+
+    | Expression |  Pattern                                            |
+    +------------+-----------------------------------------------------+
+    |                Items to match a single character                 |
+    +------------+-----------------------------------------------------+
+    |     .      |  Match any single character except newline.         |
+    |    [ ]     |  Bracket expression.  Match any one of the enclosed |
+    |            |  characters.  A hypen (-) indicates a range of      |
+    |            |  consecutive characters.                            |
+    |   [^  ]    |  Negated bracket expression.  Match any one         |
+    |            |  character NOT in the enclosed list.  A hypen (-)   |
+    |            |  indicates a range of consecutive characters.       |
+    |    \\      |  Escape the following special character (match      |
+    |            |  the literal character).  Undefined for other       |
+    |            |  characters.                                        |
+    |            |  NOTE: Unlike [POSIX.2], a double-backslash is      |
+    |            |  required as per section 2.4.2 of [SIEVE].          |
+    +------------+-----------------------------------------------------+
+    |   Items to be used within a bracket expression (localization)    |
+    +------------+-----------------------------------------------------+
+    |   [: :]    |  Character class (alnum, alpha, blank, cntrl,       |
+    |            |  digit, graph, lower, print, punct, space,          |
+    |            |  upper, xdigit).                                    |
+    |   [= =]    |  Character equivalents.                             |
+    |   [. .]    |  Collating sequence.                                |
+    +------------+-----------------------------------------------------+
+    |  Quantifiers - Items to count the preceding regular expression   |
+    +------------+-----------------------------------------------------+
+    |     ?      |  Match zero or one instances.                       |
+    |     *      |  Match zero or more instances.                      |
+    |     +      |  Match one or more instances.                       |
+    |   {n,m}    |  Match any number of instances between              |
+    |            |  n and m (inclusive).  {n} matches exactly n        |
+    |            |  instances.  {n,} matches n or more instances.      |
+    +------------+-----------------------------------------------------+
+
+
+
+
+
+Expires: May 23, 2004         Murchison                         [Page 5]
+
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
+
+
+    +------------+-----------------------------------------------------+
+    | Expression |  Pattern                                            |
+    +------------+-----------------------------------------------------+
+    |              Anchoring - Items to match positions                |
+    +------------+-----------------------------------------------------+
+    |     ^      |  Match the beginning of the line or string.         |
+    |     $      |  Match the end of the line or string.               |
+    +------------+-----------------------------------------------------+
+    |                        Other constructs                          |
+    +------------+-----------------------------------------------------+
+    |     |      |  Alternation.  Match either of the separated        |
+    |            |  regular expressions.                               |
+    |    ( )     |  Group the enclosed regular expression(s).          |
+    +------------+-----------------------------------------------------+
+
+
+4.  Security Considerations
+
+    Security considerations are discussed in [SIEVE].  It is believed
+    that this extension doesn't introduce any additional security
+    concerns.
+
+    However, a poor implementation COULD introduce security problems
+    ranging from degradation of performance to denial of service.  If an
+    implementation uses a third-party regular expression library, that
+    library should be checked for potentially problematic regular
+    expressions, such as "(.*)*".
+
+
+5.  IANA Considerations
+
+    The following template specifies the IANA registration of the Sieve
+    extension specified in this document:
+
+    To: iana@iana.org
+    Subject: Registration of new Sieve extension
+
+    Capability name: regex
+    Capability keyword: regex
+    Capability arguments: N/A
+    Standards Track/IESG-approved experimental RFC number: this RFC
+    Person and email address to contact for further information:
+
+    Kenneth Murchison
+    ken@oceana.com
+
+    This information should be added to the list of sieve extensions
+    given on http://www.iana.org/assignments/sieve-extensions.
+
+
+
+Expires: May 23, 2004         Murchison                         [Page 6]
+
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
+
+
+6.
+    Normative References
+
+     [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
+         Requirement Levels", RFC 2119, March 1997.
+
+
+     [SIEVE] Showalter, T., "Sieve: A Mail Filtering Language",
+         RFC 3028, January 2001.
+
+
+     [POSIX.2], "Portable Operating System Interface (POSIX). Part 2,
+         Shell and utilities", National Institute of Standards and
+         Technology (U.S.).
+
+
+
+7.  Acknowledgments
+
+    Thanks to Tim Showalter, Alexey Melnikov, Tony Hansen, Phil Pennock,
+    Jutta Degener and Ned Freed for their help with this document.
+
+
+8.  Intellectual Property Statement
+
+    The IETF takes no position regarding the validity or scope of any
+    intellectual property or other rights that might be claimed to per­
+    tain to the implementation or use of the technology described in
+    this document or the extent to which any license under such rights
+    might or might not be available; neither does it represent that it
+    has made any effort to identify any such rights.  Information on the
+    IETF's procedures with respect to rights in standards-track and
+    standards-related documentation can be found in BCP-11.  Copies of
+    claims of rights made available for publication and any assurances
+    of licenses to be made available, or the result of an attempt made
+    to obtain a general license or permission for the use of such pro­
+    prietary rights by implementors or users of this specification can
+    be obtained from the IETF Secretariat.
+
+    The IETF invites any interested party to bring to its attention any
+    copyrights, patents or patent applications, or other proprietary
+    rights which may cover technology that may be required to practice
+    this standard.  Please address the information to the IETF Executive
+    Director.
+
+
+
+
+
+
+
+Expires: May 23, 2004         Murchison                         [Page 7]
+
+Internet Draft          Sieve -- Regex Extension       November 18, 2004
+
+
+9.  Author's Address
+
+    Kenneth Murchison
+    Oceana Matrix Ltd.
+    21 Princeton Place
+    Orchard Park, NY  14127
+
+    Phone: (716) 662-8973
+
+    EMail: ken@oceana.com
+
+
+10.
+    Full Copyright Statement
+
+    Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+    This document and translations of it may be copied and furnished to
+    others, and derivative works that comment on or otherwise explain it
+    or assist in its implmentation may be prepared, copied, published and
+    distributed, in whole or in part, without restriction of any kind,
+    provided that the above copyright notice and this paragraph are
+    included on all such copies and derivative works.  However, this
+    document itself may not be modified in any way, such as by removing
+    the copyright notice or references to the Internet Society or other
+    Internet organizations, except as needed for the  purpose of
+    developing Internet standards in which case the procedures for
+    copyrights defined in the Internet Standards process must be followed,
+    or as required to translate it into languages other than English.
+
+    The limited permissions granted above are perpetual and will not be
+    revoked by the Internet Society or its successors or assigns.
+
+    This document and the information contained herein is provided on an
+    "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
+    ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+    INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+    INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+    WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+Expires: May 23, 2004         Murchison                         [Page 8]
diff --git a/src/lib-sieve/plugins/regex/ext-regex.c b/src/lib-sieve/plugins/regex/ext-regex.c
new file mode 100644
index 000000000..6a379acfa
--- /dev/null
+++ b/src/lib-sieve/plugins/regex/ext-regex.c
@@ -0,0 +1,90 @@
+/* Extension regex 
+ * --------------------
+ *
+ * Author: Stephan Bosch
+ * Specification: draft-murchison-sieve-regex-07
+ * Implementation: 
+ * Status: under development
+ * 
+ */
+
+#include "sieve-common.h"
+
+#include "sieve-code.h"
+#include "sieve-extensions.h"
+#include "sieve-commands.h"
+#include "sieve-match-types.h"
+#include "sieve-validator.h"
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+/* Forward declarations */
+
+static bool ext_regex_load(int ext_id);
+static bool ext_regex_validator_load(struct sieve_validator *validator);
+static bool ext_regex_interpreter_load
+	(struct sieve_interpreter *interpreter);
+
+/* Extension definitions */
+
+static int ext_my_id;
+
+const struct sieve_extension regex_extension = { 
+	"regex", 
+	ext_regex_load,
+	ext_regex_validator_load,
+	NULL, 
+	ext_regex_interpreter_load,  
+	NULL, 
+	NULL
+};
+
+static bool ext_regex_load(int ext_id)
+{
+	ext_my_id = ext_id;
+
+	return TRUE;
+}
+
+/* Actual extension implementation */
+
+
+/* Extension access structures */
+
+extern const struct sieve_match_type_extension regex_match_extension;
+
+const struct sieve_match_type regex_match_type = {
+	"regex",
+	SIEVE_MATCH_TYPE_CUSTOM,
+	&regex_match_extension,
+	0
+};
+
+const struct sieve_match_type_extension regex_match_extension = { 
+	&regex_extension,
+	&regex_match_type, 
+	NULL
+};
+
+/* Load extension into validator */
+
+static bool ext_regex_validator_load(struct sieve_validator *validator)
+{
+	sieve_match_type_register
+		(validator, &regex_match_type, ext_my_id); 
+
+	return TRUE;
+}
+
+/* Load extension into interpreter */
+
+static bool ext_regex_interpreter_load
+	(struct sieve_interpreter *interpreter)
+{
+	sieve_match_type_extension_set
+		(interpreter, ext_my_id, &regex_match_extension);
+
+	return TRUE;
+}
+
+
diff --git a/src/lib-sieve/plugins/regex/regex.sieve b/src/lib-sieve/plugins/regex/regex.sieve
new file mode 100644
index 000000000..437a77b90
--- /dev/null
+++ b/src/lib-sieve/plugins/regex/regex.sieve
@@ -0,0 +1,8 @@
+require "regex";
+
+if address :regex :comparator "i;ascii-casemap" "from" "sirius(\\+.*)?@drunksnipers\\.com" {
+	keep;
+	stop;
+}
+
+discard;
diff --git a/src/lib-sieve/plugins/relational/Makefile.am b/src/lib-sieve/plugins/relational/Makefile.am
new file mode 100644
index 000000000..35db8634f
--- /dev/null
+++ b/src/lib-sieve/plugins/relational/Makefile.am
@@ -0,0 +1,12 @@
+noinst_LIBRARIES = lib_ext_relational.a
+
+AM_CPPFLAGS = \
+	-I../../ \
+	-I$(dovecot_incdir) \
+	-I$(dovecot_incdir)/src/lib \
+	-I$(dovecot_incdir)/src/lib-mail \
+	-I$(dovecot_incdir)/src/lib-storage 
+
+lib_ext_relational_a_SOURCES = \
+	ext-relational.c
+
diff --git a/src/lib-sieve/plugins/relational/ext-relational.c b/src/lib-sieve/plugins/relational/ext-relational.c
new file mode 100644
index 000000000..4687f15af
--- /dev/null
+++ b/src/lib-sieve/plugins/relational/ext-relational.c
@@ -0,0 +1,127 @@
+/* Extension relational 
+ * --------------------
+ *
+ * Author: Stephan Bosch
+ * Specification: RFC 3431
+ * Implementation: 
+ * Status: under development
+ * 
+ */
+
+/* Syntax:
+ *   MATCH-TYPE =/ COUNT / VALUE
+ *   COUNT = ":count" relational-match
+ *   VALUE = ":value" relational-match
+ *   relational-match = DQUOTE ( "gt" / "ge" / "lt"
+ *                             / "le" / "eq" / "ne" ) DQUOTE
+ */ 
+
+#include "sieve-common.h"
+
+#include "sieve-code.h"
+#include "sieve-extensions.h"
+#include "sieve-commands.h"
+#include "sieve-match-types.h"
+#include "sieve-validator.h"
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+
+/* Forward declarations */
+
+static bool ext_relational_load(int ext_id);
+static bool ext_relational_validator_load(struct sieve_validator *validator);
+static bool ext_relational_interpreter_load
+	(struct sieve_interpreter *interpreter);
+
+/* Extension definitions */
+
+static int ext_my_id;
+
+const struct sieve_extension relational_extension = { 
+	"relational", 
+	ext_relational_load,
+	ext_relational_validator_load,
+	NULL, 
+	ext_relational_interpreter_load,  
+	NULL, 
+	NULL
+};
+
+static bool ext_relational_load(int ext_id)
+{
+	ext_my_id = ext_id;
+
+	return TRUE;
+}
+
+/* Actual extension implementation */
+
+
+/* Extension access structures */
+
+enum ext_relational_match_type {
+  RELATIONAL_VALUE,
+  RELATIONAL_COUNT
+};
+
+extern const struct sieve_match_type_extension relational_match_extension;
+
+const struct sieve_match_type value_match_type = {
+	"value",
+	SIEVE_MATCH_TYPE_CUSTOM,
+	&relational_match_extension,
+	RELATIONAL_VALUE
+};
+
+const struct sieve_match_type count_match_type = {
+	"count",
+	SIEVE_MATCH_TYPE_CUSTOM,
+	&relational_match_extension,
+	RELATIONAL_COUNT
+};
+
+static const struct sieve_match_type *ext_relational_get_match 
+	(unsigned int code)
+{
+	switch ( code ) {
+	case RELATIONAL_VALUE:
+		return &value_match_type;
+	case RELATIONAL_COUNT:
+		return &count_match_type;
+	default:
+		break;
+	}
+	
+	return NULL;
+}
+
+const struct sieve_match_type_extension relational_match_extension = { 
+	&relational_extension,
+	NULL, 
+	ext_relational_get_match
+};
+
+/* Load extension into validator */
+
+static bool ext_relational_validator_load(struct sieve_validator *validator)
+{
+	sieve_match_type_register
+		(validator, &value_match_type, ext_my_id); 
+	sieve_match_type_register
+		(validator, &count_match_type, ext_my_id); 
+
+	return TRUE;
+}
+
+/* Load extension into interpreter */
+
+static bool ext_relational_interpreter_load
+	(struct sieve_interpreter *interpreter)
+{
+	sieve_match_type_extension_set
+		(interpreter, ext_my_id, &relational_match_extension);
+
+	return TRUE;
+}
+
+
diff --git a/src/lib-sieve/plugins/relational/relational.sieve b/src/lib-sieve/plugins/relational/relational.sieve
new file mode 100644
index 000000000..51179a38c
--- /dev/null
+++ b/src/lib-sieve/plugins/relational/relational.sieve
@@ -0,0 +1,8 @@
+require ["comparator-i;ascii-numeric", "relational"];
+
+if header :value "gt" :comparator "i;ascii-numeric" "x-spam-score" "2" {
+	discard;
+	stop;
+}
+
+keep;
diff --git a/src/lib-sieve/plugins/relational/rfc3431.txt b/src/lib-sieve/plugins/relational/rfc3431.txt
new file mode 100644
index 000000000..2bf17bdbb
--- /dev/null
+++ b/src/lib-sieve/plugins/relational/rfc3431.txt
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+Network Working Group                                       W. Segmuller
+Request for Comment: 3431                IBM T.J. Watson Research Center
+Category: Standards Track                                  December 2002
+
+
+                   Sieve Extension: Relational Tests
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+Abstract
+
+   This document describes the RELATIONAL extension to the Sieve mail
+   filtering language defined in RFC 3028.  This extension extends
+   existing conditional tests in Sieve to allow relational operators.
+   In addition to testing their content, it also allows for testing of
+   the number of entities in header and envelope fields.
+
+1 Introduction
+
+   Sieve [SIEVE] is a language for filtering e-mail messages at the time
+   of final delivery.  It is designed to be implementable on either a
+   mail client or mail server.  It is meant to be extensible, simple,
+   and independent of access protocol, mail architecture, and operating
+   system.  It is suitable for running on a mail server where users may
+   not be allowed to execute arbitrary programs, such as on black box
+   Internet Messages Access Protocol (IMAP) servers, as it has no
+   variables, loops, nor the ability to shell out to external programs.
+
+   The RELATIONAL extension provides relational operators on the
+   address, envelope, and header tests.  This extension also provides a
+   way of counting the entities in a message header or address field.
+
+   With this extension, the sieve script may now determine if a field is
+   greater than or less than a value instead of just equivalent.  One
+   use is for the x-priority field: move messages with a priority
+   greater than 3 to the "work on later" folder.  Mail could also be
+   sorted by the from address.  Those userids that start with 'a'-'m' go
+   to one folder, and the rest go to another folder.
+
+
+
+Segmuller                   Standards Track                     [Page 1]
+
+RFC 3431           Sieve Extension: Relational Tests       December 2002
+
+
+   The sieve script can also determine the number of fields in the
+   header, or the number of addresses in a recipient field.  For
+   example:  are there more than 5 addresses in the to and cc fields.
+
+2 Conventions used in this document
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in BCP 14, RFC 2119.
+
+   Conventions for notations are as in [SIEVE] section 1.1, including
+   the use of [KEYWORDS] and "Syntax:" label for the definition of
+   action and tagged arguments syntax, and the use of [ABNF].
+
+   The capability string associated with extension defined in this
+   document is "relational".
+
+3 Comparators
+
+   This document does not define any comparators or exempt any
+   comparators from the require clause.  Any comparator used, other than
+   "i;octet" and "i;ascii-casemap", MUST be declared a require clause as
+   defined in [SIEVE].
+
+   The "i;ascii-numeric" comparator, as defined in [ACAP], MUST be
+   supported for any implementation of this extension.  The comparator
+   "i;ascii-numeric" MUST support at least 32 bit unsigned integers.
+
+   Larger integers MAY be supported.  Note: the "i;ascii-numeric"
+   comparator does not support negative numbers.
+
+4 Match Type
+
+   This document defines two new match types.  They are the VALUE match
+   type and the COUNT match type.
+
+     The syntax is:
+
+        MATCH-TYPE =/ COUNT / VALUE
+
+        COUNT = ":count" relational-match
+
+        VALUE = ":value" relational-match
+
+        relational-match = DQUOTE ( "gt" / "ge" / "lt"
+                                    / "le" / "eq" / "ne" ) DQUOTE
+
+
+
+
+
+Segmuller                   Standards Track                     [Page 2]
+
+RFC 3431           Sieve Extension: Relational Tests       December 2002
+
+
+4.1  Match Type Value
+
+   The VALUE match type does a relational comparison between strings.
+
+   The VALUE match type may be used with any comparator which returns
+   sort information.
+
+   Leading and trailing white space MUST be removed from the value of
+   the message for the comparison.  White space is defined as
+
+                             SP / HTAB / CRLF
+
+   A value from the message is considered the left side of the relation.
+   A value from the test expression, the key-list for address, envelope,
+   and header tests, is the right side of the relation.
+
+   If there are multiple values on either side or both sides, the test
+   is considered true, if any pair is true.
+
+4.2  Match Type Count
+
+   The COUNT match type first determines the number of the specified
+   entities in the message and does a relational comparison of the
+   number of entities to the values specified in the test expression.
+
+   The COUNT match type SHOULD only be used with numeric comparators.
+
+   The Address Test counts the number of recipients in the specified
+   fields.  Group names are ignored.
+
+   The Envelope Test counts the number of recipients in the specified
+   envelope parts.  The envelope "to" will always have only one entry,
+   which is the address of the user for whom the sieve script is
+   running.  There is no way a sieve script can determine if the message
+   was actually sent to someone else using this test.  The envelope
+   "from" will be 0 if the MAIL FROM is blank, or 1 if MAIL FROM is not
+   blank.
+
+   The Header Test counts the total number of instances of the specified
+   fields.  This does not count individual addresses in the "to", "cc",
+   and other recipient fields.
+
+   In all cases, if more than one field name is specified, the counts
+   for all specified fields are added together to obtain the number for
+   comparison.  Thus, specifying ["to", "cc"] in an address COUNT test,
+   comparing the total number of "to" and "cc" addresses; if separate
+   counts are desired, they must be done in two comparisons, perhaps
+   joined by "allof" or "anyof".
+
+
+
+Segmuller                   Standards Track                     [Page 3]
+
+RFC 3431           Sieve Extension: Relational Tests       December 2002
+
+
+5 Security Considerations
+
+   Security considerations are discussed in [SIEVE].
+
+   An implementation MUST ensure that the test for envelope "to" only
+   reflects the delivery to the current user.  It MUST not be possible
+   for a user to determine if this message was delivered to someone else
+   using this test.
+
+6 Example
+
+   Using the message:
+
+      received: ...
+      received: ...
+      subject: example
+      to: foo@example.com.invalid, baz@example.com.invalid
+      cc: qux@example.com.invalid
+
+   The test:
+
+        address :count "ge" :comparator "i;ascii-numeric" ["to", "cc"]
+      ["3"]
+
+      would be true and the test
+
+         anyof ( address :count "ge" :comparator "i;ascii-numeric"
+                         ["to"] ["3"],
+                 address :count "ge" :comparator "i;ascii-numeric"
+                         ["cc"] ["3"] )
+
+      would be false.
+
+      To check the number of received fields in the header, the
+      following test may be used:
+
+         header :count "ge" :comparator "i;ascii-numeric"
+                        ["received"] ["3"]
+
+      This would return false.  But
+
+         header :count "ge" :comparator "i;ascii-numeric"
+                          ["received", "subject"] ["3"]
+
+      would return true.
+
+
+
+
+
+
+Segmuller                   Standards Track                     [Page 4]
+
+RFC 3431           Sieve Extension: Relational Tests       December 2002
+
+
+   The test:
+
+         header :count "ge" :comparator "i;ascii-numeric"
+                       ["to", "cc"] ["3"]
+
+   will always return false on an RFC 2822 compliant message [RFC2822],
+   since a message can have at most one "to" field and at most one "cc"
+   field.  This test counts the number of fields, not the number of
+   addresses.
+
+7 Extended Example
+
+   require ["relational", "comparator-i;ascii-numeric"];
+
+   if header :value "lt" :comparator "i;ascii-numeric"
+             ["x-priority"] ["3"]
+   {
+      fileinto "Priority";
+   }
+
+   elseif address :count "gt" :comparator "i;ascii-numeric"
+              ["to"] ["5"]
+   {
+      # everything with more than 5 recipients in the "to" field
+      # is considered SPAM
+      fileinto "SPAM";
+   }
+
+   elseif address :value "gt" :all :comparator "i;ascii-casemap"
+              ["from"] ["M"]
+   {
+      fileinto "From N-Z";
+   } else {
+      fileinto "From A-M";
+   }
+
+   if allof ( address :count "eq" :comparator "i;ascii-numeric"
+                      ["to", "cc"] ["1"] ,
+              address :all :comparator "i;ascii-casemap"
+                      ["to", "cc"] ["me@foo.example.com.invalid"]
+   {
+      fileinto "Only me";
+   }
+
+
+
+
+
+
+
+
+Segmuller                   Standards Track                     [Page 5]
+
+RFC 3431           Sieve Extension: Relational Tests       December 2002
+
+
+8 IANA Considerations
+
+   The following template specifies the IANA registration of the Sieve
+   extension specified in this document:
+
+   To: iana@iana.org
+   Subject: Registration of new Sieve extension
+
+   Capability name: RELATIONAL
+   Capability keyword: relational
+   Capability arguments: N/A
+   Standards Track/IESG-approved experimental RFC number: this RFC
+   Person and email address to contact for further information:
+    Wolfgang Segmuller
+    IBM T.J. Watson Research Center
+    30 Saw Mill River Rd
+    Hawthorne, NY 10532
+
+    Email: whs@watson.ibm.com
+
+   This information should be added to the list of sieve extensions
+   given on http://www.iana.org/assignments/sieve-extensions.
+
+9 References
+
+9.1 Normative References
+
+   [SIEVE]     Showalter, T., "Sieve: A Mail Filtering Language", RFC
+               3028, January 2001.
+
+   [Keywords]  Bradner, S., "Key words for use in RFCs to Indicate
+               Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [ABNF]      Crocker, D., "Augmented BNF for Syntax Specifications:
+               ABNF", RFC 2234, November 1997.
+
+   [RFC2822]   Resnick, P., "Internet Message Format", RFC 2822, April
+               2001.
+
+9.2 Non-Normative References
+
+   [ACAP]      Newman, C. and J. G. Myers, "ACAP -- Application
+               Configuration Access Protocol", RFC 2244, November 1997.
+
+
+
+
+
+
+
+
+Segmuller                   Standards Track                     [Page 6]
+
+RFC 3431           Sieve Extension: Relational Tests       December 2002
+
+
+10 Author's Address
+
+   Wolfgang Segmuller
+   IBM T.J. Watson Research Center
+   30 Saw Mill River Rd
+   Hawthorne, NY  10532
+
+   EMail: whs@watson.ibm.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Segmuller                   Standards Track                     [Page 7]
+
+RFC 3431           Sieve Extension: Relational Tests       December 2002
+
+
+11 Full Copyright Statement
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Segmuller                   Standards Track                     [Page 8]
+
diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c
index 4f4638a75..bb6a4cb1c 100644
--- a/src/lib-sieve/sieve-extensions.c
+++ b/src/lib-sieve/sieve-extensions.c
@@ -46,6 +46,8 @@ extern const struct sieve_extension envelope_extension;
 extern const struct sieve_extension vacation_extension;
 extern const struct sieve_extension subaddress_extension;
 extern const struct sieve_extension comparator_i_ascii_numeric_extension;
+extern const struct sieve_extension relational_extension;
+extern const struct sieve_extension regex_extension;
 
 const struct sieve_extension *sieve_core_extensions[] = {
 	&comparator_extension, &match_type_extension, &address_part_extension, 
@@ -54,7 +56,8 @@ const struct sieve_extension *sieve_core_extensions[] = {
 	
 	/* 'Plugins' */
 	&vacation_extension, &subaddress_extension, 
-	&comparator_i_ascii_numeric_extension
+	&comparator_i_ascii_numeric_extension, 
+	&relational_extension, &regex_extension
 };
 
 const unsigned int sieve_core_extensions_count =
diff --git a/src/sieve-bin/Makefile.am b/src/sieve-bin/Makefile.am
index b998313b7..6f86fd3df 100644
--- a/src/sieve-bin/Makefile.am
+++ b/src/sieve-bin/Makefile.am
@@ -17,7 +17,9 @@ plugin_dir = \
 plugins = \
 	$(plugin_dir)/vacation/lib_ext_vacation.a \
 	$(plugin_dir)/subaddress/lib_ext_subaddress.a \
-	$(plugin_dir)/comparator-i-ascii-numeric/lib_ext_comparator-i-ascii-numeric.a
+	$(plugin_dir)/comparator-i-ascii-numeric/lib_ext_comparator-i-ascii-numeric.a \
+	$(plugin_dir)/relational/lib_ext_relational.a \
+	$(plugin_dir)/regex/lib_ext_regex.a
 
 sievec_LDFLAGS = -export-dynamic -Wl,--start-group 
 sieve_test_LDFLAGS = -export-dynamic -Wl,--start-group
-- 
GitLab