rfc5260.txt (25735B)
1 2 3 4 5 6 7 Network Working Group N. Freed 8 Request for Comments: 5260 Sun Microsystems 9 Category: Standards Track July 2008 10 11 12 Sieve Email Filtering: Date and Index Extensions 13 14 Status of This Memo 15 16 This document specifies an Internet standards track protocol for the 17 Internet community, and requests discussion and suggestions for 18 improvements. Please refer to the current edition of the "Internet 19 Official Protocol Standards" (STD 1) for the standardization state 20 and status of this protocol. Distribution of this memo is unlimited. 21 22 Abstract 23 24 This document describes the "date" and "index" extensions to the 25 Sieve email filtering language. The "date" extension gives Sieve the 26 ability to test date and time values in various ways. The "index" 27 extension provides a means to limit header and address tests to 28 specific instances of header fields when header fields are repeated. 29 30 Table of Contents 31 32 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2 33 2. Conventions Used in This Document . . . . . . . . . . . . . . 2 34 3. Capability Identifiers . . . . . . . . . . . . . . . . . . . . 3 35 4. Date Test . . . . . . . . . . . . . . . . . . . . . . . . . . 3 36 4.1. Zone and Originalzone Arguments . . . . . . . . . . . . . 4 37 4.2. Date-part Argument . . . . . . . . . . . . . . . . . . . . 4 38 4.3. Comparator Interactions with Date-part Arguments . . . . . 5 39 4.4. Examples . . . . . . . . . . . . . . . . . . . . . . . . . 6 40 5. Currentdate Test . . . . . . . . . . . . . . . . . . . . . . . 6 41 5.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . . 6 42 6. Index Extension . . . . . . . . . . . . . . . . . . . . . . . 7 43 6.1. Example . . . . . . . . . . . . . . . . . . . . . . . . . 8 44 7. Security Considerations . . . . . . . . . . . . . . . . . . . 8 45 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 46 9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 9 47 9.1. Normative References . . . . . . . . . . . . . . . . . . . 9 48 9.2. Informative References . . . . . . . . . . . . . . . . . . 10 49 Appendix A. Julian Date Conversions . . . . . . . . . . . . . . . 11 50 Appendix B. Acknowledgements . . . . . . . . . . . . . . . . . . 12 51 52 53 54 55 56 57 58 Freed Standards Track [Page 1] 59 60 RFC 5260 Sieve Date and Index Extensions July 2008 61 62 63 1. Introduction 64 65 Sieve [RFC5228] is a language for filtering email messages at or 66 around the time of final delivery. It is designed to be 67 implementable on either a mail client or mail server. It is meant to 68 be extensible, simple, and independent of access protocol, mail 69 architecture, and operating system. It is suitable for running on a 70 mail server where users may not be allowed to execute arbitrary 71 programs, such as on black box Internet Message Access Protocol 72 [RFC3501] servers, as it does not have user-controlled loops or the 73 ability to run external programs. 74 75 The "date" extension provides a new date test to extract and match 76 date/time information from structured header fields. The date test 77 is similar in concept to the address test specified in [RFC5228], 78 which performs similar operations on addresses in header fields. 79 80 The "date" extension also provides a currentdate test that operates 81 on the date and time when the Sieve script is executed. 82 83 Some header fields containing date/time information, e.g., Received:, 84 naturally occur more than once in a single header. In such cases it 85 is useful to be able to restrict the date test to some subset of the 86 fields that are present. For example, it may be useful to apply a 87 date test to the last (earliest) Received: field. Additionally, it 88 may also be useful to apply similar restrictions to either the header 89 or address tests specified in [RFC5228]. 90 91 For this reason, this specification also defines an "index" 92 extension. This extension adds two additional tagged arguments 93 :index and :last to the header, address, and date tests. If present, 94 these arguments specify which occurrence of the named header field is 95 to be tested. 96 97 2. Conventions Used in This Document 98 99 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 100 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 101 document are to be interpreted as described in RFC 2119 [RFC2119]. 102 103 The terms used to describe the various components of the Sieve 104 language are taken from Section 1.1 of [RFC5228]. Section 2 of the 105 same document describes basic Sieve language syntax and semantics. 106 The date-time syntactic element defined using ABNF notation [RFC5234] 107 in [RFC3339] is also used here. 108 109 110 111 112 113 114 Freed Standards Track [Page 2] 115 116 RFC 5260 Sieve Date and Index Extensions July 2008 117 118 119 3. Capability Identifiers 120 121 The capability strings associated with the two extensions defined in 122 this document are "date" and "index". 123 124 4. Date Test 125 126 Usage: date [<":zone" <time-zone: string>> / ":originalzone"] 127 [COMPARATOR] [MATCH-TYPE] <header-name: string> 128 <date-part: string> <key-list: string-list> 129 130 The date test matches date/time information derived from headers 131 containing [RFC2822] date-time values. The date/time information is 132 extracted from the header, shifted to the specified time zone, and 133 the value of the given date-part is determined. The test returns 134 true if the resulting string matches any of the strings specified in 135 the key-list, as controlled by the comparator and match keywords. 136 The date test returns false unconditionally if the specified header 137 field does not exist, the field exists but does not contain a 138 syntactically valid date-time specification, the date-time isn't 139 valid according to the rules of the calendar system (e.g., January 140 32nd, February 29 in a non-leap year), or the resulting string fails 141 to match any key-list value. 142 143 The type of match defaults to ":is" and the default comparator is 144 "i;ascii-casemap". 145 146 Unlike the header and address tests, the date test can only be 147 applied to a single header field at a time. If multiple header 148 fields with the same name are present, only the first field that is 149 found is used. (Note, however, that this behavior can be modified 150 with the "index" extension defined below.) These restrictions 151 simplify the test and keep the meaning clear. 152 153 The "relational" extension [RFC5231] adds a match type called 154 ":count". The count of a date test is 1 if the specified field 155 exists and contains a valid date; 0, otherwise. 156 157 Implementations MUST support extraction of RFC 2822 date-time 158 information that either makes up the entire header field (e.g., as it 159 does in a standard Date: header field) or appears at the end of a 160 header field following a semicolon (e.g., as it does in a standard 161 Received: header field). Implementations MAY support extraction of 162 date and time information in RFC2822 or other formats that appears in 163 other positions in header field content. In the case of a field 164 containing more than one date or time value, the last one that 165 appears SHOULD be used. 166 167 168 169 170 Freed Standards Track [Page 3] 171 172 RFC 5260 Sieve Date and Index Extensions July 2008 173 174 175 4.1. Zone and Originalzone Arguments 176 177 The :originalzone argument specifies that the time zone offset 178 originally in the extracted date-time value should be retained. The 179 :zone argument specifies a specific time zone offset that the date- 180 time value is to be shifted to prior to testing. It is an error to 181 specify both :zone and :originalzone. 182 183 The value of time-zone MUST be an offset relative to UTC with the 184 following syntax: 185 186 time-zone = ( "+" / "-" ) 4DIGIT 187 188 The "+" or "-" indicates whether the time-of-day is ahead of (i.e., 189 east of) or behind (i.e., west of) UTC. The first two digits 190 indicate the number of hours difference from Universal Time, and the 191 last two digits indicate the number of minutes difference from 192 Universal Time. Note that this agrees with the RFC 2822 format for 193 time zone offsets, not the ISO 8601 format. 194 195 If both the :zone and :originalzone arguments are omitted, the local 196 time zone MUST be used. 197 198 4.2. Date-part Argument 199 200 The date-part argument specifies a particular part of the resulting 201 date/time value to match against the key-list. Possible case- 202 insensitive values are: 203 204 "year" => the year, "0000" .. "9999". 205 "month" => the month, "01" .. "12". 206 "day" => the day, "01" .. "31". 207 "date" => the date in "yyyy-mm-dd" format. 208 "julian" => the Modified Julian Day, that is, the date 209 expressed as an integer number of days since 210 00:00 UTC on November 17, 1858 (using the Gregorian 211 calendar). This corresponds to the regular 212 Julian Day minus 2400000.5. Sample routines to 213 convert to and from modified Julian dates are 214 given in Appendix A. 215 "hour" => the hour, "00" .. "23". 216 "minute" => the minute, "00" .. "59". 217 "second" => the second, "00" .. "60". 218 "time" => the time in "hh:mm:ss" format. 219 "iso8601" => the date and time in restricted ISO 8601 format. 220 "std11" => the date and time in a format appropriate 221 for use in a Date: header field [RFC2822]. 222 223 224 225 226 Freed Standards Track [Page 4] 227 228 RFC 5260 Sieve Date and Index Extensions July 2008 229 230 231 "zone" => the time zone in use. If the user specified a 232 time zone with ":zone", "zone" will 233 contain that value. If :originalzone is specified 234 this value will be the original zone specified 235 in the date-time value. If neither argument is 236 specified the value will be the server's default 237 time zone in offset format "+hhmm" or "-hhmm". An 238 offset of 0 (Zulu) always has a positive sign. 239 "weekday" => the day of the week expressed as an integer between 240 "0" and "6". "0" is Sunday, "1" is Monday, etc. 241 242 The restricted ISO 8601 format is specified by the date-time ABNF 243 production given in [RFC3339], Section 5.6, with the added 244 restrictions that the letters "T" and "Z" MUST be in upper case, and 245 a time zone offset of zero MUST be represented by "Z" and not 246 "+00:00". 247 248 4.3. Comparator Interactions with Date-part Arguments 249 250 Not all comparators are suitable with all date-part arguments. In 251 general, the date-parts can be compared and tested for equality with 252 either "i;ascii-casemap" (the default) or "i;octet", but there are 253 two exceptions: 254 255 julian This is an integer, and may or may not have leading zeros. 256 As such, "i;ascii-numeric" is almost certainly the best 257 comparator to use with it. 258 259 std11 This is provided as a means to obtain date/time values in a 260 format appropriate for inclusion in email header fields. The 261 wide range of possible syntaxes for a std11 date/time -- 262 which implementations of this extension are free to use when 263 composing a std11 string -- makes this format a poor choice 264 for comparisons. Nevertheless, if a comparison must be 265 performed, this is case-insensitive, and therefore "i;ascii- 266 casemap" needs to be used. 267 268 "year", "month", "day", "hour", "minute", "second" and "weekday" all 269 use fixed-width string representations of integers, and can therefore 270 be compared with "i;octet", "i;ascii-casemap", and "i;ascii-numeric" 271 with equivalent results. 272 273 "date" and "time" also use fixed-width string representations of 274 integers, and can therefore be compared with "i;octet" and "i;ascii- 275 casemap"; however, "i;ascii-numeric" can't be used with it, as 276 "i;ascii-numeric" doesn't allow for non-digit characters. 277 278 279 280 281 282 Freed Standards Track [Page 5] 283 284 RFC 5260 Sieve Date and Index Extensions July 2008 285 286 287 4.4. Examples 288 289 The Date: field can be checked to test when the sender claims to have 290 created the message and act accordingly: 291 292 require ["date", "relational", "fileinto"]; 293 if allof(header :is "from" "boss@example.com", 294 date :value "ge" :originalzone "date" "hour" "09", 295 date :value "lt" :originalzone "date" "hour" "17") 296 { fileinto "urgent"; } 297 298 Testing the initial Received: field can provide an indication of when 299 a message was actually received by the local system: 300 301 require ["date", "relational", "fileinto"]; 302 if anyof(date :is "received" "weekday" "0", 303 date :is "received" "weekday" "6") 304 { fileinto "weekend"; } 305 306 5. Currentdate Test 307 308 Usage: currentdate [":zone" <time-zone: string>] 309 [COMPARATOR] [MATCH-TYPE] 310 <date-part: string> 311 <key-list: string-list> 312 313 The currentdate test is similar to the date test, except that it 314 operates on the current date/time rather than a value extracted from 315 the message header. In particular, the ":zone" and date-part 316 arguments are the same as those in the date test. 317 318 All currentdate tests in a single Sieve script MUST refer to the same 319 point in time during execution of the script. 320 321 The :count value of a currentdate test is always 1. 322 323 5.1. Examples 324 325 The simplest use of currentdate is to have an action that only 326 operates at certain times. For example, a user might want to have 327 messages redirected to their pager after business hours and on 328 weekends: 329 330 331 332 333 334 335 336 337 338 Freed Standards Track [Page 6] 339 340 RFC 5260 Sieve Date and Index Extensions July 2008 341 342 343 require ["date", "relational"]; 344 if anyof(currentdate :is "weekday" "0", 345 currentdate :is "weekday" "6", 346 currentdate :value "lt" "hour" "09", 347 currentdate :value "ge" "hour" "17") 348 { redirect "pager@example.com"; } 349 350 Currentdate can be used to set up vacation [RFC5230] responses in 351 advance and to stop response generation automatically: 352 353 require ["date", "relational", "vacation"]; 354 if allof(currentdate :value "ge" "date" "2007-06-30", 355 currentdate :value "le" "date" "2007-07-07") 356 { vacation :days 7 "I'm away during the first week in July."; } 357 358 Currentdate may also be used in conjunction with the variables 359 extension to pass time-dependent arguments to other tests and 360 actions. The following Sieve places messages in a folder named 361 according to the current month and year: 362 363 require ["date", "variables", "fileinto"]; 364 if currentdate :matches "month" "*" { set "month" "${1}"; } 365 if currentdate :matches "year" "*" { set "year" "${1}"; } 366 fileinto "${month}-${year}"; 367 368 Finally, currentdate can be used in conjunction with the editheader 369 extension to insert a header-field containing date/time information: 370 371 require ["variables", "date", "editheader"]; 372 if currentdate :matches "std11" "*" 373 {addheader "Processing-date" "${0}";} 374 375 6. Index Extension 376 377 The "index" extension, if specified, adds optional :index and :last 378 arguments to the header, address, and date tests as follows: 379 380 Syntax: date [":index" <fieldno: number> [":last"]] 381 [<":zone" <time-zone: string>> / ":originalzone"] 382 [COMPARATOR] [MATCH-TYPE] <header-name: string> 383 <date-part: string> <key-list: string-list> 384 385 386 Syntax: header [":index" <fieldno: number> [":last"]] 387 [COMPARATOR] [MATCH-TYPE] 388 <header-names: string-list> <key-list: string-list> 389 390 391 392 393 394 Freed Standards Track [Page 7] 395 396 RFC 5260 Sieve Date and Index Extensions July 2008 397 398 399 Syntax: address [":index" <fieldno: number> [":last"]] 400 [ADDRESS-PART] [COMPARATOR] [MATCH-TYPE] 401 <header-list: string-list> <key-list: string-list> 402 403 If :index <fieldno> is specified, the attempts to match a value are 404 limited to the header field fieldno (beginning at 1, the first named 405 header field). If :last is also specified, the count is backwards; 1 406 denotes the last named header field, 2 the second to last, and so on. 407 Specifying :last without :index is an error. 408 409 :index only counts separate header fields, not multiple occurrences 410 within a single field. In particular, :index cannot be used to test 411 a specific address in an address list contained within a single 412 header field. 413 414 Both header and address allow the specification of more than one 415 header field name. If more than one header field name is specified, 416 all the named header fields are counted in the order specified by the 417 header-list. 418 419 6.1. Example 420 421 Mail delivery may involve multiple hops, resulting in the Received: 422 field containing information about when a message first entered the 423 local administrative domain being the second or subsequent field in 424 the message. As long as the field offset is consistent, it can be 425 tested: 426 427 # Implement the Internet-Draft cutoff date check assuming the 428 # second Received: field specifies when the message first 429 # entered the local email infrastructure. 430 require ["date", "relational", "index"]; 431 if date :value "gt" :index 2 :zone "-0500" "received" 432 "iso8601" "2007-02-26T09:00:00-05:00", 433 { redirect "aftercutoff@example.org"; } 434 435 7. Security Considerations 436 437 The facilities defined here, like the facilities in the base Sieve 438 specification, operate on message header information that can easily 439 be forged. Note, however, that some fields are inherently more 440 reliable than others. For example, the Date: field is typically 441 inserted by the message sender and can be altered at any point. By 442 contrast, the uppermost Received: field is typically inserted by the 443 local mail system and is therefore difficult for the sender or an 444 intermediary to falsify. 445 446 447 448 449 450 Freed Standards Track [Page 8] 451 452 RFC 5260 Sieve Date and Index Extensions July 2008 453 454 455 Use of the currentdate test makes script behavior inherently less 456 predictable and harder to analyze. This may have consequences for 457 systems that use script analysis to try and spot problematic scripts. 458 459 All of the security considerations given in the base Sieve 460 specification also apply to these extensions. 461 462 8. IANA Considerations 463 464 The following templates specify the IANA registrations of the two 465 Sieve extensions specified in this document: 466 467 To: iana@iana.org 468 Subject: Registration of new Sieve extensions 469 470 Capability name: date 471 Description: The "date" extension gives Sieve the ability 472 to test date and time values. 473 RFC number: RFC 5260 474 Contact address: Sieve discussion list <ietf-mta-filters@imc.org> 475 476 Capability name: index 477 Description: The "index" extension provides a means to 478 limit header and address tests to specific 479 instances when more than one field of a 480 given type is present. 481 RFC number: RFC 5260 482 Contact address: Sieve discussion list <ietf-mta-filters@imc.org> 483 484 9. References 485 486 9.1. Normative References 487 488 [CALGO199] Tantzen, R., "Algorithm 199: Conversions Between Calendar 489 Date and Julian Day Number", Collected Algorithms from 490 CACM 199. 491 492 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 493 Requirement Levels", BCP 14, RFC 2119, March 1997. 494 495 [RFC2822] Resnick, P., "Internet Message Format", RFC 2822, 496 April 2001. 497 498 [RFC3339] Klyne, G., Ed. and C. Newman, "Date and Time on the 499 Internet: Timestamps", RFC 3339, July 2002. 500 501 [RFC5228] Guenther, P. and T. Showalter, "Sieve: An Email Filtering 502 Language", RFC 5228, January 2008. 503 504 505 506 Freed Standards Track [Page 9] 507 508 RFC 5260 Sieve Date and Index Extensions July 2008 509 510 511 [RFC5231] Segmuller, W. and B. Leiba, "Sieve Email Filtering: 512 Relational Extension", RFC 5231, January 2008. 513 514 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 515 Specifications: ABNF", STD 68, RFC 5234, January 2008. 516 517 9.2. Informative References 518 519 [RFC3501] Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 520 4rev1", RFC 3501, March 2003. 521 522 [RFC5230] Showalter, T. and N. Freed, "Sieve Email Filtering: 523 Vacation Extension", RFC 5230, January 2008. 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 Freed Standards Track [Page 10] 563 564 RFC 5260 Sieve Date and Index Extensions July 2008 565 566 567 Appendix A. Julian Date Conversions 568 569 The following C routines show how to translate day/month/year 570 information to and from modified Julian dates. These routines are 571 straightforward translations of the Algol routines specified in CACM 572 Algorithm 199 [CALGO199]. 573 574 Given the day, month, and year, jday returns the modified Julian 575 date. 576 577 int jday(int year, int month, int day) 578 { 579 int j, c, ya; 580 581 if (month > 2) 582 month -= 3; 583 else 584 { 585 month += 9; 586 year--; 587 } 588 c = year / 100; 589 ya = year - c * 100; 590 return (c * 146097 / 4 + ya * 1461 / 4 + (month * 153 + 2) / 5 + 591 day + 1721119); 592 } 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 Freed Standards Track [Page 11] 619 620 RFC 5260 Sieve Date and Index Extensions July 2008 621 622 623 Given j, the modified Julian date, jdate returns the day, month, and 624 year. 625 626 void jdate(int j, int *year, int *month, int *day) 627 { 628 int y, m, d; 629 630 j -= 1721119; 631 y = (j * 4 - 1) / 146097; 632 j = j * 4 - y * 146097 - 1; 633 d = j / 4; 634 j = (d * 4 + 3) / 1461; 635 d = d * 4 - j * 1461 + 3; 636 d = (d + 4) / 4; 637 m = (d * 5 - 3) / 153; 638 d = d * 5 - m * 153 - 3; 639 *day = (d + 5) / 5; 640 *year = y * 100 + j; 641 if (m < 10) 642 *month = m + 3; 643 else 644 { 645 *month = m - 9; 646 *year += 1; 647 } 648 } 649 650 Appendix B. Acknowledgements 651 652 Dave Cridland contributed the text describing the proper comparators 653 to use with different date-parts. Cyrus Daboo, Frank Ellerman, 654 Alexey Melnikov, Chris Newman, Dilyan Palauzov, and Aaron Stone 655 provided helpful suggestions and corrections. 656 657 Author's Address 658 659 Ned Freed 660 Sun Microsystems 661 800 Royal Oaks 662 Monrovia, CA 91016-6347 663 USA 664 665 Phone: +1 909 457 4293 666 EMail: ned.freed@mrochek.com 667 668 669 670 671 672 673 674 Freed Standards Track [Page 12] 675 676 RFC 5260 Sieve Date and Index Extensions July 2008 677 678 679 Full Copyright Statement 680 681 Copyright (C) The IETF Trust (2008). 682 683 This document is subject to the rights, licenses and restrictions 684 contained in BCP 78, and except as set forth therein, the authors 685 retain all their rights. 686 687 This document and the information contained herein are provided on an 688 "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS 689 OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND 690 THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS 691 OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF 692 THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED 693 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 694 695 Intellectual Property 696 697 The IETF takes no position regarding the validity or scope of any 698 Intellectual Property Rights or other rights that might be claimed to 699 pertain to the implementation or use of the technology described in 700 this document or the extent to which any license under such rights 701 might or might not be available; nor does it represent that it has 702 made any independent effort to identify any such rights. Information 703 on the procedures with respect to rights in RFC documents can be 704 found in BCP 78 and BCP 79. 705 706 Copies of IPR disclosures made to the IETF Secretariat and any 707 assurances of licenses to be made available, or the result of an 708 attempt made to obtain a general license or permission for the use of 709 such proprietary rights by implementers or users of this 710 specification can be obtained from the IETF on-line IPR repository at 711 http://www.ietf.org/ipr. 712 713 The IETF invites any interested party to bring to its attention any 714 copyrights, patents or patent applications, or other proprietary 715 rights that may cover technology that may be required to implement 716 this standard. Please address the information to the IETF at 717 ietf-ipr@ietf.org. 718 719 720 721 722 723 724 725 726 727 728 729 730 Freed Standards Track [Page 13] 731