diff --git a/README b/README index 4dc26a8a65343116e3c054a8e8ab7cfab3d042a6..31f5d5db104a04710aac3d832251e336db863467 100644 --- a/README +++ b/README @@ -133,9 +133,9 @@ Extensions and their implementation status: include: full, but needs much more work vacation: almost complete, but no support for required References header imapflags: flag management works, but flags are not stored - variables: planned (* also amend previously implemented extensions) + variables: skeleton - notify: planned, mailto only (- very low priority) + notify: planned, first mailto only (- very low priority) All implemented extensions are like the engine itself currently very much experimental. Other extensions will be added as soon as the necessary diff --git a/configure.in b/configure.in index a07703a094a07d17af9d6113bcd3f9f7e562bb34..c7beb5c3702832cb3b86424ef3b27c4bfeb70f5f 100644 --- a/configure.in +++ b/configure.in @@ -68,6 +68,7 @@ src/lib-sieve/plugins/imapflags/Makefile src/lib-sieve/plugins/copy/Makefile src/lib-sieve/plugins/include/Makefile src/lib-sieve/plugins/body/Makefile +src/lib-sieve/plugins/variables/Makefile src/plugins/Makefile src/plugins/lda-sieve/Makefile src/sieve-bin/Makefile diff --git a/src/lib-sieve/Makefile.am b/src/lib-sieve/Makefile.am index bde0a0d222342d7988c6d07a74e9adc88cb13dc4..1ec16b8a8069cca3a7a9d4ff436c309b90a7d848 100644 --- a/src/lib-sieve/Makefile.am +++ b/src/lib-sieve/Makefile.am @@ -40,7 +40,8 @@ plugins = \ ./plugins/copy/libsieve_ext_copy.la \ ./plugins/imapflags/libsieve_ext_imapflags.la \ ./plugins/include/libsieve_ext_include.la \ - ./plugins/body/libsieve_ext_body.la + ./plugins/body/libsieve_ext_body.la \ + ./plugins/variables/libsieve_ext_variables.la libsieve_la_DEPENDENCIES = $(plugins) libsieve_la_LIBADD = $(plugins) diff --git a/src/lib-sieve/plugins/Makefile.am b/src/lib-sieve/plugins/Makefile.am index da2823df31b66fefb755a6ded4d47f0e5325f656..6db6a5e29fe0885afa1f32a56b20fd2394fa807d 100644 --- a/src/lib-sieve/plugins/Makefile.am +++ b/src/lib-sieve/plugins/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = vacation subaddress comparator-i-ascii-numeric relational regex imapflags copy include body +SUBDIRS = vacation subaddress comparator-i-ascii-numeric relational regex imapflags copy include body variables diff --git a/src/lib-sieve/plugins/variables/Makefile.am b/src/lib-sieve/plugins/variables/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..592a8eb63c5e2f03b71ff99fce2fe538174657be --- /dev/null +++ b/src/lib-sieve/plugins/variables/Makefile.am @@ -0,0 +1,12 @@ +noinst_LTLIBRARIES = libsieve_ext_variables.la + +AM_CPPFLAGS = \ + -I../../ \ + -I$(dovecot_incdir) \ + -I$(dovecot_incdir)/src/lib \ + -I$(dovecot_incdir)/src/lib-mail \ + -I$(dovecot_incdir)/src/lib-storage + +libsieve_ext_variables_la_SOURCES = \ + ext-variables.c + diff --git a/src/lib-sieve/plugins/variables/draft-ietf-sieve-variables-08.txt b/src/lib-sieve/plugins/variables/draft-ietf-sieve-variables-08.txt new file mode 100644 index 0000000000000000000000000000000000000000..bc44882ddd8a5c2a3dba8054f2e7dd79e7041af0 --- /dev/null +++ b/src/lib-sieve/plugins/variables/draft-ietf-sieve-variables-08.txt @@ -0,0 +1,898 @@ + + + + + + +Network Working Group K. T. Homme +Updates: 3028 +Document: draft-ietf-sieve-variables-08.txt University of Oslo +Expires Jun 18, 2006 18 Dec 2005 + + + + Sieve Extension: Variables + + + +Status of this Memo + + + This document is an Internet-Draft and is subject to all provisions + of section 3 of RFC 3978. By submitting this Internet-Draft, each + author represents that any applicable patent or other IPR claims of + which he or she is aware have been or will be disclosed, and any of + which he or she becomes aware will be disclosed, in accordance with + Section 6 of BCP 79. + + 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/ietf/1id-abstracts.txt. + + The list of Internet-Draft Shadow Directories can be accessed at + http://www.ietf.org/shadow.html. + + Distribution of this memo is unlimited. + + +Abstract + + In advanced mail filtering rule sets, it is useful to keep state or + configuration details across rules. This document updates the Sieve + filtering language (RFC 3028) with an extension to support variables. + The extension changes the interpretation of strings, adds an action + to store data in variables, and supplies a new test so that the value + of a string can be examined. + + + +Homme [Page 1] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + +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 + mail 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 + +0.2.1. Changes since -00 + +a) allow generic time zone names, without requiring implementations to + support it. added a "${timezone}" variable so that the user can + check if the implementation does support the time zone name he + wants. the default time zone was changed to localtime again. + +b) allow back references from :matches as well as :regex. + +c) added a section on implementation limits. + +d) clarified global scope so that it spans include. + +e) clarified that this draft only affects scripts which require + "variables". + +f) changed modifiers into being tagged arguments for SET, added + precedence table. + +g) added optional COMPARATOR to SET to solve the internationalisation + problem with :lower etc. + +h) the name of the variable being SET is passed in a string to conform + with overall Sieve grammar. this string is explicitly disallowed + from containing variable references. + + + + +Homme [Page 2] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + +0.2.2. Changes since -01 + +a) clarify that a character is a Unicode character. + +b) added paragraph warning against relying on Sieve for virus checking + to security section. + +c) added a paragraph defining constant string. + +d) added namespace to grammar. + +e) removed SETDATE. + +f) added wording and example requiring short-circuiting of test + evaluation. + + +0.2.3. Changes since -02 + +a) add references to Unicode and UTF-8, also more boilerplate + +b) fixed a meaningless example. + +c) changed term "numeric variables" to "numbered variables" to reduce + the chance of it being interpreted as variables holding integer + values. + +d) allow future extensions to access the raw string value. + +e) an unsuccessful match does NOT reset the numbered variables. + +f) added definition of "string :count" + +g) exceeding implementation limits on variable lengths should not make + scripts abort. + + +0.2.4. Changes since -03 + +a) clarify short-circuiting. + +b) editorial changes. + + +0.2.5. Changes since -04 + +a) the wildcards in :matches was changed from greedy to non-greedy to + better support "principle of least surprise". added example to + + + +Homme [Page 3] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + + illustrate the difference. + +b) add definition of "variable"; clarify grammar is based on [SIEVE]; + clarify role of namespaces; add informative references for [REGEX] + and [SPAMTEST]; add normative reference for [RELATIONAL] + +c) the use of unsupported numbered variables must be flagged as a + syntax error by implementations. + + +0.2.6. Changes since -00 (WG series) + +a) added example for string test + +b) moved introductory text for MODIFIER from 5.1 into 5.0 + +c) added Syntax line for MODIFIER. + +d) added comment to an example showing that the non-greedy "*" still + matches everything due to implicit anchors. + +e) added example of expansion of string with unbalanced braces. + +f) updated reference to [SPAMTEST]. + + +0.2.7. Changes since -01 + +a) moved References from appendix into the document itself. + +b) added example of SET with a comparator. + +c) changed "highest value" to the less ambiguous "largest value". + +d) updated reference to [UTF-8]. + +e) allow numbered variables in namespaces. + +f) change ${0} to mean the complete match. + + +0.2.8. Changes since -02 + +a) explicitly state compatibility with actions in base spec. + +b) "numbered variables" are now called "match variables". + + + + + +Homme [Page 4] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + +c) clarify definition of "match variable". + +d) it's not the whole namespace which should match the extension + keyword, only the first component. + +e) allow level 2 and above of the namespace specification to be all- + digit. + +f) combining :upper and :lower etc. is now a syntax error. + +g) allow SET to set variables in namespaces if the extension allows + it. + +0.2.9. Changes since -03 + +a) added two new modifiers, ":quoteregex" and ":quotewildcard". + +b) added wording about security implications of silent truncation. + +0.2.10. Changes since -04 + +a) fix buggy markup and add missing modifier to syntax description + +b) changed two "syntax error" (which really weren't) into just + "error". + +c) changed "Syntax:" into "Usage:" to mirror [SIEVE] convention. + +d) removed description of regex interaction and :quoteregex + +e) added note to clarify that ${0010} is the same as ${10}. + +f) changed name of document to align better with other extensions + (uses same format at 3431 and 3894) + +0.2.11. Changes since -05 + +a) removed "open issues" section. + +b) updated [RELATIONAL] reference + +0.2.12. Changes since -06 + +a) updated abstract to mention what this document extends. + +b) changed default scoping behaviour in anticipation of "include" + extension. + + + + +Homme [Page 5] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + +c) updated reference to RFC 2234. + +d) clarified whitespace stripping behaviour for "string" test. + +0.2.13. Changes since -07 + +a) Replaced reference to Unicode with reference to ISO 10646 and made + it informational rather than normative. + +b) Updated [ABNF] since it has been published. + +c) Removed the use of comparator with SET to affect case folding. + Restrict case modifiers to US ASCII. + +d) Mention in abstract that this draft updates RFC 3028. + +e) Clarify that match variables contain unmodified extracts from the + source value. + +f) Include "INBOX" in all mailbox names for consistency. + + +1. Introduction + + This is an extension to the Sieve language defined by [SIEVE]. It + adds support for storing and referencing named data. The mechanisms + detailed in this document will only apply to Sieve scripts that + include a require clause for the "variables" extension. The require + clauses themselves are not affected by this extension. + + Conventions for notations are as in [SIEVE] section 1.1, including + use of [KEYWORDS] and [ABNF]. The grammar builds on the grammar of + [SIEVE]. In this document, "character" means a character from the + ISO 10646 coded character set [ISO10646], which may consist of + multiple octets coded in [UTF-8], and "variable" is a named reference + to data stored or read back using the mechanisms of this extension. + + +2. Capability Identifier + + The capability string associated with the extension defined in this + document is "variables". + + +3. Interpretation of strings + + This extension changes the semantics of quoted-string, multi-line- + literal and multi-line-dotstuff found in [SIEVE] to enable the + + + +Homme [Page 6] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + + inclusion of the value of variables. + + When a string is evaluated, substrings matching variable-ref SHALL be + replaced by the value of variable-name. Only one pass through the + string SHALL be done. Variable names are case insensitive, so "foo" + and "FOO" refer to the same variable. Unknown variables are replaced + by the empty string. + + variable-ref = "${" [namespace] variable-name "}" + namespace = identifier "." *sub-namespace + sub-namespace = variable-name "." + variable-name = num-variable / identifier + num-variable = 1*DIGIT + + Examples: + "&%${}!" => unchanged, as the empty string is an illegal + identifier + "${doh!}" => unchanged, as "!" is illegal in identifiers + + The variable "company" holds the value "ACME". No other variables + are set. + + "${full}" => the empty string + "${company}" => "ACME" + "${BAD${Company}" => "${BADACME" + "${President, ${Company} Inc.}" + => "${President, ACME Inc.}" + + The expanded string MUST use the variable values which are current + when control reaches the statement the string is part of. + + Strings where no variable substitutions take place are referred to as + constant strings. Future extensions may specify that passing non- + constant strings as arguments to its actions or tests is an error. + + Namespaces are meant for future extensions which make internal state + available through variables. These variables SHOULD be put in a + namespace whose first component is the same as its capability string. + Such extensions SHOULD state which, if any, of the variables in its + namespace are modifiable with the "set" action. + + References to namespaces without a prior require statement for the + relevant extension MUST cause an error. + + Tests or actions in future extensions may need to access the + unexpanded version of the string argument and, e.g., do the expansion + after setting variables in its namespace. The design of the + implementation should allow this. + + + +Homme [Page 7] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + +3.1. Quoting + + The semantics of quoting using backslash are not changed: backslash + quoting is resolved before doing variable substitution. + + Examples: + "${fo\o}" => ${foo} => the expansion of variable foo. + "${fo\\o}" => ${fo\o} => illegal identifier => left verbatim. + "\${foo}" => ${foo} => the expansion of variable foo. + "\\${foo}" => \${foo} => a backslash character followed by the + expansion of variable foo. + + If it is required to include a character sequence such as "${beep}" + verbatim in a text literal, the user can define a variable to + circumvent expansion to the empty string. + + Example: + set "dollar" "$"; + set "text" "regarding ${dollar}{beep}"; + + +3.2. Match variables + + A "match variable" has a name consisting only of decimal digits and + has no namespace component. + + The decimal value of the match variable name will index the list of + matching strings from the most recently evaluated successful match of + type ":matches". The list is empty if no match has been successful. + + Note: Extra leading zeroes are allowed and ignored. + + The list will contain one string for each wildcard ("?" and "*") in + the match pattern. Each string holds the substring from the source + value that the corresponding wildcard expands to, possibly the empty + string. The wildcards match as little as possible (non-greedy + matching). + + The first string in the list has index 1. If the index is out of + range, the empty string will be substituted. Index 0 contains the + matched part of the source value. + + The interpreter MUST short-circuit tests, ie. not perform more tests + than necessary to find the result. Evaluation order MUST be left to + right. If a test has two or more list arguments, the implementation + is free to choose which to iterate over first. + + An extension describing a new match type (e.g., [REGEX]) MAY specify + + + +Homme [Page 8] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + + that match variables are set as a side effect when the match type is + used in a script which has enabled the "variables" extension. + + Example: + + require ["fileinto", "variables"]; + + if header :matches "List-ID" "*<*@*" { + fileinto "INBOX.lists.${2}"; stop; + } + + # Imagine the header + # Subject: [acme-users] [fwd] version 1.0 is out + if header :matches "Subject" "[*] *" { + # ${1} will hold "acme-users", + # ${2} will hold "[fwd] version 1.0 is out" + fileinfo "INBOX.lists.${1}"; stop; + } + + # Imagine the header + # To: coyote@ACME.Example.COM + if address :matches ["To", "Cc"] ["coyote@**.com", + "wile@**.com"] { + # ${0} is the matching address + # ${1} is always the empty string + # ${2} is part of the domain name ("ACME.Example") + fileinto "INBOX.business.${2}"; stop; + } else { + # Control wouldn't reach this block if any match was + # successful, so no match variables are set at this + # point. + } + + if anyof (true, address :domain :matches "To" "*.com") { + # The second test is never evaluated, so there are + # still no match variables set. + stop; + } + + +4. Action set + + Usage: set [MODIFIER] <name: string> <value: string> + + The "set" action stores the specified value in the variable + identified by name. The name MUST be a constant string and conform + to the syntax of variable-name. Match variables can not be set. A + namespace can not be used unless an extension explicitly allows its + + + +Homme [Page 9] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + + use in "set". An invalid name MUST be detected as a syntax error. + + Modifiers are applied on a value before it is stored in the variable. + See next section for details. + + Variables are only visible to the currently running script. Note: + Future extensions may provide different scoping rules for variables. + + Variable names are case insensitive. + + Example: + set "honorific" "Mr"; + set "first_name" "Wile"; + set "last_name" "Coyote"; + set "vacation" text: + Dear ${HONORIFIC} ${last_name}, + I'm out, please leave a message after the meep. + . + ; + + "set" does not affect the implicit keep. It is compatible with all + actions defined in [SIEVE]. + + +4.1. Modifiers + + Usage: ":lower" / ":upper" / ":lowerfirst" / ":upperfirst" / + ":quotewildcard" / ":length" + + Modifier names are case insensitive. Unknown modifiers MUST yield a + syntax error. More than one modifier can be specified, in which case + they are applied according to this precedence list, largest value + first: + + + + + + + + + + + + + + + + + + +Homme [Page 10] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + + +--------------------------------+ + | Precedence Modifier | + +--------------------------------+ + | 40 :lower | + | :upper | + +--------------------------------+ + | 30 :lowerfirst | + | :upperfirst | + +--------------------------------+ + | 20 :quotewildcard | + +--------------------------------+ + | 10 :length | + +--------------------------------+ + + It is an error to use two or more modifiers of the same precedence in + a single "set" action. + + Examples: + # The value assigned to the variable is printed after the arrow + set "a" "juMBlEd lETteRS"; => "juMBlEd lETteRS" + set :length "b" "${a}"; => "15" + set :lower "b" "${a}"; => "jumbled letters" + set :upperfirst "b" "${a}"; => "JuMBlEd lETteRS" + set :upperfirst :lower "b" "${a}"; => "Jumbled letters" + set :quotewildcard "b" "Rock*"; => "Rock\*" + + +4.1.1. Modifier ":length" + + The value is the decimal number of characters in the expansion, + converted to a string. + + +4.1.2. Modifier ":quotewildcard" + + This modifier adds the necessary quoting to ensure that the expanded + text will only match a literal occurence if used as a parameter to + :matches. Every character with special meaning ("*", "?" and "\") + is prefixed with "\" in the expansion. + +4.1.3. Case modifiers + + These modifiers change the letters of the text from upper to lower + case or vice versa. Characters other than "A"-"Z", "a"-"z" from US- + ASCII are left unchanged. + + + + + + +Homme [Page 11] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + +4.1.3.1. Modifier ":upper" + + All lower case letters are converted to their upper case counterpart. + + +4.1.3.2. Modifier ":lower" + + All upper case letters are converted to their lower case counterpart. + + +4.1.3.3. Modifier ":upperfirst" + + The first character of the string is converted to upper case if it is + a letter and set in lower case. The rest of the string is left + unchanged. + + +4.1.3.4. Modifier ":lowerfirst" + + The first character of the string is converted to lower case if it is + a letter and set in upper case. The rest of the string is left + unchanged. + + +5. Test string + + Usage: string [MATCH-TYPE] [COMPARATOR] + <source: string-list> <key-list: string-list> + + The "string" test evaluates to true if any of the source strings + matches any key. The type of match defaults to ":is". + + In the "string" test, both source and key-list are taken from the + script, not the message, and whitespace stripping MUST NOT be done + unless the script explicitly requests this through some future + mechanism. + + Example: + set "state" "${state} pending"; + if string :matches " ${state} " "* pending *" { + # the above test always succeeds + } + + The "relational" extension [RELATIONAL] adds a match type called + ":count". The count of a single string is 0 if it is the empty + string, or 1 otherwise. The count of a string list is the sum of the + counts of the member strings. + + + + +Homme [Page 12] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + +6. Implementation Limits + + An implementation of this draft MUST support at least 128 distinct + variables. The supported length of variable names MUST be at least + 32 characters. Each variable MUST be able to hold at least 4000 + characters. Attempts to set the variable to a value larger than what + the implementation supports SHOULD be reported as an error at + compile-time if possible. If the attempt is discovered during run- + time, the value SHOULD be truncated and it MUST NOT be treated as an + error. + + Match variables ${1} through ${9} MUST be supported. References to + higher indices than the implementation supports MUST be treated as a + syntax error which SHOULD be discovered at compile-time. + + +7. Security Considerations + + When match variables are used, and the author of the script isn't + careful, strings can contain arbitrary values controlled by the + sender of the mail. + + Since values stored by "set" which exceed implementation limits are + silently truncated, it's not appropriate to store large structures + with security implications in variables. + + The introduction of variables makes advanced decision making easier + to write, but since no looping construct is provided, all Sieve + scripts will terminate in an orderly manner. + + Sieve filtering should not be relied on as a security measure against + hostile mail messages. Sieve is designed to do simple, mostly static + tests, and is not suitable for use as a spam or virus checker, where + the perpetrator has a motivation to vary the format of the mail in + order to avoid filtering rules. See also [SPAMTEST]. + + +8. IANA Considerations + + The following template specifies the IANA registration of the + variables Sieve extension specified in this document: + + To: iana@iana.org + Subject: Registration of new Sieve extension + + Capability name: variables + Capability keyword: variables + Capability arguments: N/A + + + +Homme [Page 13] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + + Standards Track/IESG-approved experimental RFC number: + this RFC + Person and email address to contact for further information: + Kjetil Torgrim Homme + kjetilho@ifi.uio.no + + This information should be added to the list of sieve extensions + given on http://www.iana.org/assignments/sieve-extensions. + +9. Acknowledgments + + Thanks to Cyrus Daboo, Jutta Degener, Ned Freed, Lawrence Greenfield, + Jeffrey Hutzelman, Mark E. Mallett, Alexey Melnikov, Peder Stray and + Nigel Swinson for valuable feedback. + + +10. Author's Address + + Kjetil T. Homme + University of Oslo + PO Box 1080 + 0316 Oslo, Norway + + Phone: +47 9366 0091 + E-mail: kjetilho@ifi.uio.no + + +11. References + + +11.1. Normative references + + + [ABNF] Crocker, D. and Overell, P., "Augmented BNF for Syntax + Specifications: ABNF", RFC 4234, October 2005. + + [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", RFC 2119, March 1997. + + [RELATIONAL] Leiba, B. and Segmuller, W., "Sieve Extension: + Relational Tests", Work in Progress, draft-ietf- + sieve-3431bis-XX.txt + + [SIEVE] Guenther, P. and Showalter, T., "Sieve: An Email + Filtering Language", Work in Progress, draft-ietf- + sieve-3028bis-XX.txt + + + + + +Homme [Page 14] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + + [UTF-8] Yergeau, F., "UTF-8, a transformation format of + Unicode and ISO 10646", RFC 3629, November 2003. + + +11.2. Informative References + + + [ISO10646] ISO/IEC, "Information Technology - Universal Multiple- + Octet Coded Character Set (UCS) - Part 1: Architecture + and Basic Multilingual Plane", May 1993, with + amendments. + + [REGEX] Murchison, K., "Sieve Email Filtering -- Regular + Expression Extension", Work in Progress. + + [SPAMTEST] Daboo, C., "SIEVE Email Filtering: Spamtest and + VirusTest Extensions", RFC 3685, February 2004 + + +Appendix B. Intellectual Property Rights Statement + + The IETF takes no position regarding the validity or scope of any + intellectual property or other rights that might be claimed to + pertain 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 + proprietary rights by implementors or users of this specification can + be obtained from the IETF Secretariat. + + +Appendix C. Full Copyright Statement + + Copyright (C) The Internet Society (2005). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + + + +Homme [Page 15] + +Internet Draft Sieve Extension: Variables 18 Dec 2005 + + + 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. + + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain 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; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat 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 proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at ietf- + ipr@ietf.org. + + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + + + + + + + + + +Homme [Page 16] diff --git a/src/lib-sieve/plugins/variables/ext-variables.c b/src/lib-sieve/plugins/variables/ext-variables.c new file mode 100644 index 0000000000000000000000000000000000000000..9ce50ea54177a618ee8c9bf86fc0960840c2067c --- /dev/null +++ b/src/lib-sieve/plugins/variables/ext-variables.c @@ -0,0 +1,148 @@ +/* Extension variables + * ------------------- + * + * Authors: Stephan Bosch + * Specification: draft-ietf-sieve-variables-08.txt + * Implementation: skeleton + * Status: under development + * + */ + +#include "lib.h" +#include "unichar.h" + +#include "sieve-extensions.h" +#include "sieve-commands.h" +#include "sieve-validator.h" + +#include <ctype.h> + +/* Forward declarations */ + +static bool ext_variables_load(int ext_id); +static bool ext_variables_validator_load(struct sieve_validator *validator); + +/* Extension definitions */ + +static int ext_my_id; + +struct sieve_extension variables_extension = { + "variables", + ext_variables_load, + ext_variables_validator_load, + NULL, NULL, NULL, + SIEVE_EXT_DEFINE_NO_OPCODES, + NULL +}; + +static bool ext_variables_load(int ext_id) +{ + ext_my_id = ext_id; + return TRUE; +} + +/* New argument */ + +static bool arg_variable_string_validate + (struct sieve_validator *validator, struct sieve_ast_argument **arg, + struct sieve_command_context *context); + +const struct sieve_argument variable_string_argument = + { "@variable-string", NULL, arg_variable_string_validate, NULL, NULL }; + +static bool arg_variable_string_validate +(struct sieve_validator *validator, struct sieve_ast_argument **arg, + struct sieve_command_context *cmd) +{ + bool result = TRUE; + enum { ST_NONE, ST_OPEN, ST_VARIABLE, ST_CLOSE } + state = ST_NONE; + string_t *str = sieve_ast_argument_str(*arg); + string_t *tmpstr, *newstr = NULL; + const char *p, *mark, *strstart, *substart = NULL; + const char *strval = (const char *) str_data(str); + const char *strend = strval + str_len(str); + + T_FRAME( + tmpstr = t_str_new(32); + + p = strval; + strstart = p; + while ( result && p < strend ) { + switch ( state ) { + case ST_NONE: + if ( *p == '$' ) { + substart = p; + state = ST_OPEN; + } + p++; + break; + case ST_OPEN: + if ( *p == '{' ) { + state = ST_VARIABLE; + p++; + } else + state = ST_NONE; + break; + case ST_VARIABLE: + mark = p; + + if ( p < strend ) { + if (*p == '_' || isalpha(*p) ) { + p++; + + while ( p < strend && (*p == '_' || isalnum(*p)) ) { + p++; + } + } else if ( isdigit(*p) ) { + unsigned int num_variable = *p - '0'; + p++; + + while ( p < strend && isdigit(*p) ) { + num_variable = num_variable*10 + (*p - '0'); + p++; + } + } + } + + break; + case ST_CLOSE: + if ( *p == '}' ) { + /* We now know that the substitution is valid */ + + if ( newstr == NULL ) { + newstr = str_new(sieve_ast_pool((*arg)->ast), str_len(str)*2); + } + + str_append_n(newstr, strstart, substart-strstart); + str_append_str(newstr, tmpstr); + + strstart = p + 1; + substart = strstart; + } + state = ST_NONE; + p++; + } + } + ); + + if ( newstr != NULL ) { + if ( strstart != strend ) + str_append_n(newstr, strstart, strend-strstart); + + sieve_ast_argument_str_set(*arg, newstr); + } + + return sieve_validator_argument_activate_super + (validator, cmd, *arg, TRUE); +} + +/* Load extension into validator */ + +static bool ext_variables_validator_load + (struct sieve_validator *validator ATTR_UNUSED) +{ + sieve_validator_argument_override(validator, SAT_VAR_STRING, + &variable_string_argument); + return TRUE; +} diff --git a/src/lib-sieve/plugins/variables/variables.sieve b/src/lib-sieve/plugins/variables/variables.sieve new file mode 100644 index 0000000000000000000000000000000000000000..43681b5c9becf81046c6897742619ed69567d192 --- /dev/null +++ b/src/lib-sieve/plugins/variables/variables.sieve @@ -0,0 +1,3 @@ +require "variables"; + + diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c index 58c8bc2110bfd9207644525b429f33b5e38dbbf3..642214fb0ca0eb40283fe343e1cf46c8d900105b 100644 --- a/src/lib-sieve/sieve-extensions.c +++ b/src/lib-sieve/sieve-extensions.c @@ -61,6 +61,7 @@ extern const struct sieve_extension imapflags_extension; extern const struct sieve_extension copy_extension; extern const struct sieve_extension include_extension; extern const struct sieve_extension body_extension; +extern const struct sieve_extension variables_extension; const struct sieve_extension *sieve_core_extensions[] = { /* Preloaded 'extensions' */ @@ -78,7 +79,8 @@ const struct sieve_extension *sieve_core_extensions[] = { &vacation_extension, &subaddress_extension, &comparator_i_ascii_numeric_extension, &relational_extension, ®ex_extension, &imapflags_extension, - ©_extension, &include_extension, &body_extension + ©_extension, &include_extension, &body_extension, + &variables_extension }; const unsigned int sieve_core_extensions_count =